ROOT logo
#ifndef __CINT__
# include <TFile.h>
# include <TString.h>
# include <TError.h>
# include <TSystem.h>
# include <fstream>
#else
class TFile;
class TString;
#endif


struct ExtractProd
{
  TString fTmp;
  TString fPath;
  TString fPass;
  TString fRuns;
  Bool_t  fDebug;

  ExtractProd() 
    : fTmp(""), fPath(""), fPass(""), fRuns(""), fDebug(false)
  {
  }
  
  Bool_t Run(const TString& name, Bool_t mc=false, ULong_t minSize=1000000)
  {
    fTmp = "prod";
    gSystem->TempFileName(fTmp);
    gSystem->Unlink(fTmp);
    gSystem->mkdir(fTmp);
    if (fDebug) Info("", "TMP=%s", fTmp.Data());

    fPath = "";
    fPass = "";
    fRuns = "";
    TString job;
    if (!GetJobUrl(name, mc, job)) return false;
    
    if (!GetRuns(job, mc, minSize)) return false;

    if (!fPass.IsNull()) fPass.Append("/");
    Printf("alien://%s?pattern=%s*/AliESDs.root&runs=%s", 
	   fPath.Data(), fPass.Data(), fRuns.Data());

    gSystem->Unlink(fTmp);
    return true;
  }
  Bool_t GetJobUrl(const TString& name, Bool_t mc, TString& url)
  {
    url = "";
    TString index("raw.jsp");
    if (!Download((mc ? "job_details.jsp" : "production/raw.jsp"), index))
	return false;
    
    std::ifstream in(index.Data());
    TString line;
    TString tgt(Form("<td class=\"table_row\">%s</td>", name.Data()));
    do { 
      line.ReadLine(in);
      if (!line.Contains(tgt)) continue;
      line.ReadLine(in);
      Int_t first = line.Index("href=\"");
      Int_t last  = line.Index("\"", first+7);
      url = line(first+6,last-first-6);
      break;
      
    } while (!in.eof());
    in.close();
    
    if (url.IsNull()) { 
      Error("GetJobUrl", "Production %s not found", name.Data());
      return false;
    }

    return true;
  }
  Bool_t GetRuns(const TString& url, Bool_t mc, ULong_t minSize)
  {
    TString index("job");
    if (!Download(Form("%s%s", (mc ? "" : "raw/"), url.Data()), index)) 
      return false;

    std::ifstream in(index.Data());
    TString tgt1(mc ? "window.open" : "runDetails");
    TString line  = "";
    do { 
      line.ReadLine(in);
      if (!line.Contains(tgt1)) continue;
      Int_t   first = -1;
      Int_t   last  = -1;
      if (!mc) { 
	first = line.Index(tgt1);
	last  = line.Index(")", first+tgt1.Length()+1);
      }
      else { 
	Int_t tmp = line.Index(">");
	first = line.Index(">", tmp+1);
	last  = line.Index("<", first);
      }
      if (first == kNPOS || last == kNPOS) { 
	Error("GetDir", "Failed to get directory from %s", line.Data());
	return false;
      }
      first += (mc ? 1 : tgt1.Length()+1);
      last  -= first;
      TString srun  = line(first, last);
      ULong_t runNo = srun.Atoll();
      if (fDebug) Info("", "Got run %lu (%s)", runNo, srun.Data());

      if (!GetSize(in, runNo, mc, minSize)) continue;
      if (!GetDir(in, runNo, mc))           continue;

      if (!fRuns.IsNull()) fRuns.Append(",");
      fRuns.Append(Form("%lu", runNo));
    } while (!in.eof());
    in.close();
    if (fRuns.IsNull()) return false;

    return true;
  }
  Bool_t GetSize(std::istream& in, ULong_t runNo, 
		 Bool_t mc, ULong_t minSize=100000)
  {
    TString line;
    TString tgt2(mc ? "table_row_right" : "ESDs size");
    Int_t   cnt = 0;
    do {
      line.ReadLine(in);
      if (!line.Contains(tgt2)) continue;
      cnt++;
      if (mc && cnt < 3) continue;
      if (!mc) line.ReadLine(in);
      if (fDebug) Info("", line);

      TString ssiz;
      if (mc) { 
	Int_t first       = line.Index(">");
	Int_t last        = line.Index("<",first+1);
	if (first == kNPOS || last == kNPOS) { 
	  Error("GetDir", "Failed to get directory from %s", line.Data());
	  return false;
	}
	ssiz = line(first+1, last-first-1);
      }
      else {
	for (Int_t i = 0; i < line.Length(); i++) { 
	  if (line[i] == '<') break;
	  if (line[i] == ' ' || line[i] == '\t' || line[i] == ',') continue;
	  ssiz.Append(line[i]);
	}
      }
      Long_t size = ssiz.Atoll();
      if (fDebug) Info("", "Got run %lu %lu" , runNo, size);
      if (size < 0) {
	Error("GetSize", "Failed to extract size for run %lu", runNo);
	return false;
      }
      if (ULong_t(size) < minSize) {
	Warning("GetSize","Run %lu does not have enough events %lu",runNo,size);
	return false;
      }
      break;
    } while (!in.eof());
    return true;
  }
  Bool_t GetDir(std::istream& in, ULong_t runNo, Bool_t mc)
  {
    TString line;
    TString tgt3("/catalogue/index.jsp");
    do { 
      line.ReadLine(in);
      // Info("", "line=%s", line.Data());
      if (!line.Contains(tgt3)) continue;
      if (fDebug) Info("", line);
      Int_t tmp         = mc ? line.Index(">")+1 : 0;
      Int_t first       = line.Index(">", tmp);
      Int_t last        = line.Index("<",first+1);
      if (first == kNPOS || last == kNPOS) { 
	Error("GetDir", "Failed to get directory from %s", line.Data());
	return false;
      }
      
      TString dir = line(first+1,last-first-1);
	
      if (fDebug) Info("", "Got run %lu %s", runNo, dir.Data());
      TString path, pass;
      if (!GetPathPass(dir, runNo, path, pass)) return false;
      
      if (fDebug) Info("", "Got run %lu %s %s", runNo,path.Data(),pass.Data());

      if      (fPath.IsNull()) fPath = path;
      else if (!fPath.EqualTo(path)) { 
	Warning("GetDir", "Run %lu location %s not %s", 
	      runNo, path.Data(), fPath.Data());
	return false;
      }

      if      (fPass.IsNull()) fPass = pass;
      else if (!fPass.EqualTo(pass)) { 
	Warning("GetDir", "Run %lu pass %s not %s", 
	      runNo, pass.Data(), fPass.Data());
	return false;
      }
      break;
    } while (!in.eof());
    return true;
  }
  Bool_t GetPathPass(const TString& dir, ULong_t run, 
		     TString& path, TString& pass) 
  {
    Int_t first = dir.Index(Form("%lu", run));
    Int_t last  = dir.Index("/", first);
    if (last == kNPOS) last = dir.Length();
    if (first == kNPOS) { 
      Error("GetPathPass", "Run number %lu not in path %s", run, dir.Data());
      return false;
    }
    while (dir[first-1] == '0') first--;
    path = dir(0, first);
    pass = dir(last+1,dir.Length()-last-1);
    return true;
  }
  Bool_t Download(const TString& url, TString& out)
  {
    const TString base("http://alimonitor.cern.ch");
    out = Form("%s/%s", fTmp.Data(), out.Data());
    TString cmd(Form("wget -q \"%s/%s\" -O \"%s\"", 
		     base.Data(), url.Data(), out.Data()));
    if (fDebug) Info("Download", "%s", cmd.Data());
    Int_t ret = gSystem->Exec(cmd.Data());
    if (ret != 0)  {
      Error("Download", "Failed to get %s/%s -> %s", 
	    base.Data(), url.Data(), out.Data());
      return false;
    }
    return true;
  }
};

 ExtractProd.C:1
 ExtractProd.C:2
 ExtractProd.C:3
 ExtractProd.C:4
 ExtractProd.C:5
 ExtractProd.C:6
 ExtractProd.C:7
 ExtractProd.C:8
 ExtractProd.C:9
 ExtractProd.C:10
 ExtractProd.C:11
 ExtractProd.C:12
 ExtractProd.C:13
 ExtractProd.C:14
 ExtractProd.C:15
 ExtractProd.C:16
 ExtractProd.C:17
 ExtractProd.C:18
 ExtractProd.C:19
 ExtractProd.C:20
 ExtractProd.C:21
 ExtractProd.C:22
 ExtractProd.C:23
 ExtractProd.C:24
 ExtractProd.C:25
 ExtractProd.C:26
 ExtractProd.C:27
 ExtractProd.C:28
 ExtractProd.C:29
 ExtractProd.C:30
 ExtractProd.C:31
 ExtractProd.C:32
 ExtractProd.C:33
 ExtractProd.C:34
 ExtractProd.C:35
 ExtractProd.C:36
 ExtractProd.C:37
 ExtractProd.C:38
 ExtractProd.C:39
 ExtractProd.C:40
 ExtractProd.C:41
 ExtractProd.C:42
 ExtractProd.C:43
 ExtractProd.C:44
 ExtractProd.C:45
 ExtractProd.C:46
 ExtractProd.C:47
 ExtractProd.C:48
 ExtractProd.C:49
 ExtractProd.C:50
 ExtractProd.C:51
 ExtractProd.C:52
 ExtractProd.C:53
 ExtractProd.C:54
 ExtractProd.C:55
 ExtractProd.C:56
 ExtractProd.C:57
 ExtractProd.C:58
 ExtractProd.C:59
 ExtractProd.C:60
 ExtractProd.C:61
 ExtractProd.C:62
 ExtractProd.C:63
 ExtractProd.C:64
 ExtractProd.C:65
 ExtractProd.C:66
 ExtractProd.C:67
 ExtractProd.C:68
 ExtractProd.C:69
 ExtractProd.C:70
 ExtractProd.C:71
 ExtractProd.C:72
 ExtractProd.C:73
 ExtractProd.C:74
 ExtractProd.C:75
 ExtractProd.C:76
 ExtractProd.C:77
 ExtractProd.C:78
 ExtractProd.C:79
 ExtractProd.C:80
 ExtractProd.C:81
 ExtractProd.C:82
 ExtractProd.C:83
 ExtractProd.C:84
 ExtractProd.C:85
 ExtractProd.C:86
 ExtractProd.C:87
 ExtractProd.C:88
 ExtractProd.C:89
 ExtractProd.C:90
 ExtractProd.C:91
 ExtractProd.C:92
 ExtractProd.C:93
 ExtractProd.C:94
 ExtractProd.C:95
 ExtractProd.C:96
 ExtractProd.C:97
 ExtractProd.C:98
 ExtractProd.C:99
 ExtractProd.C:100
 ExtractProd.C:101
 ExtractProd.C:102
 ExtractProd.C:103
 ExtractProd.C:104
 ExtractProd.C:105
 ExtractProd.C:106
 ExtractProd.C:107
 ExtractProd.C:108
 ExtractProd.C:109
 ExtractProd.C:110
 ExtractProd.C:111
 ExtractProd.C:112
 ExtractProd.C:113
 ExtractProd.C:114
 ExtractProd.C:115
 ExtractProd.C:116
 ExtractProd.C:117
 ExtractProd.C:118
 ExtractProd.C:119
 ExtractProd.C:120
 ExtractProd.C:121
 ExtractProd.C:122
 ExtractProd.C:123
 ExtractProd.C:124
 ExtractProd.C:125
 ExtractProd.C:126
 ExtractProd.C:127
 ExtractProd.C:128
 ExtractProd.C:129
 ExtractProd.C:130
 ExtractProd.C:131
 ExtractProd.C:132
 ExtractProd.C:133
 ExtractProd.C:134
 ExtractProd.C:135
 ExtractProd.C:136
 ExtractProd.C:137
 ExtractProd.C:138
 ExtractProd.C:139
 ExtractProd.C:140
 ExtractProd.C:141
 ExtractProd.C:142
 ExtractProd.C:143
 ExtractProd.C:144
 ExtractProd.C:145
 ExtractProd.C:146
 ExtractProd.C:147
 ExtractProd.C:148
 ExtractProd.C:149
 ExtractProd.C:150
 ExtractProd.C:151
 ExtractProd.C:152
 ExtractProd.C:153
 ExtractProd.C:154
 ExtractProd.C:155
 ExtractProd.C:156
 ExtractProd.C:157
 ExtractProd.C:158
 ExtractProd.C:159
 ExtractProd.C:160
 ExtractProd.C:161
 ExtractProd.C:162
 ExtractProd.C:163
 ExtractProd.C:164
 ExtractProd.C:165
 ExtractProd.C:166
 ExtractProd.C:167
 ExtractProd.C:168
 ExtractProd.C:169
 ExtractProd.C:170
 ExtractProd.C:171
 ExtractProd.C:172
 ExtractProd.C:173
 ExtractProd.C:174
 ExtractProd.C:175
 ExtractProd.C:176
 ExtractProd.C:177
 ExtractProd.C:178
 ExtractProd.C:179
 ExtractProd.C:180
 ExtractProd.C:181
 ExtractProd.C:182
 ExtractProd.C:183
 ExtractProd.C:184
 ExtractProd.C:185
 ExtractProd.C:186
 ExtractProd.C:187
 ExtractProd.C:188
 ExtractProd.C:189
 ExtractProd.C:190
 ExtractProd.C:191
 ExtractProd.C:192
 ExtractProd.C:193
 ExtractProd.C:194
 ExtractProd.C:195
 ExtractProd.C:196
 ExtractProd.C:197
 ExtractProd.C:198
 ExtractProd.C:199
 ExtractProd.C:200
 ExtractProd.C:201
 ExtractProd.C:202
 ExtractProd.C:203
 ExtractProd.C:204
 ExtractProd.C:205
 ExtractProd.C:206
 ExtractProd.C:207
 ExtractProd.C:208
 ExtractProd.C:209
 ExtractProd.C:210
 ExtractProd.C:211
 ExtractProd.C:212
 ExtractProd.C:213
 ExtractProd.C:214
 ExtractProd.C:215
 ExtractProd.C:216
 ExtractProd.C:217
 ExtractProd.C:218
 ExtractProd.C:219
 ExtractProd.C:220
 ExtractProd.C:221
 ExtractProd.C:222
 ExtractProd.C:223
 ExtractProd.C:224
 ExtractProd.C:225
 ExtractProd.C:226
 ExtractProd.C:227
 ExtractProd.C:228
 ExtractProd.C:229
 ExtractProd.C:230
 ExtractProd.C:231
 ExtractProd.C:232
 ExtractProd.C:233
 ExtractProd.C:234
 ExtractProd.C:235
 ExtractProd.C:236
 ExtractProd.C:237
 ExtractProd.C:238
 ExtractProd.C:239
 ExtractProd.C:240
 ExtractProd.C:241