CMS 3D CMS Logo

CmsShowSearchFiles.cc
Go to the documentation of this file.
1 #include <stdexcept>
2 #include <iostream>
3 #include <fstream>
4 #include <cstdlib>
5 #include <set>
6 #include "TGClient.h"
7 #include "TGHtml.h"
8 #include "TGButton.h"
9 #include "TGMenu.h"
10 #include "TGLabel.h"
11 #include "TGTextEntry.h"
12 #include "TPluginManager.h"
13 #include "TUrl.h"
14 #include "TSocket.h"
15 #include "TSystem.h"
16 #include "TVirtualX.h"
17 #include "TPRegexp.h"
21 
22 class FWHtml : public TGHtml {
23 public:
24  FWHtml(const TGWindow* p, int w, int h, int id = -1) : TGHtml(p, w, h, id) {}
25 
26  int IsVisited(const char* iCheck) override {
27  std::string check(GetBaseUri());
28  check += iCheck;
29  int value = m_visited.find(check) == m_visited.end() ? kFALSE : kTRUE;
30  return value;
31  }
32  void addToVisited(const char* iToVisit) { m_visited.insert(iToVisit); }
33 
34 private:
35  std::set<std::string> m_visited;
36 };
37 
38 const static unsigned int s_columns = 3;
39 const static char* const s_prefixes[][s_columns] = {{"http://", "Web site known by you", nullptr},
40  {"file:", "Local file [you must type full path name]", nullptr},
41  {"dcap://", "dCache [FNAL]", nullptr},
42  {"rfio://", "Castor [CERN]", nullptr}
43 
44 };
45 
46 static const std::string s_httpPrefix("http:");
47 static const std::string s_filePrefix("file:");
48 static const std::string s_rootPostfix(".root");
49 
50 namespace {
51  float getURLResponseTime(const char* url) {
52  TString com = "ping -q -c 1 -n " + TString(url) + "| tail -n 1";
53  FILE* p = gSystem->OpenPipe(com, "r");
54  TString l;
55  l.Gets(p);
56  gSystem->ClosePipe(p);
57 
58  TPMERegexp re("([\\d\\.]+)");
59  if (re.Match(l))
60  return re[1].Atof();
61  else
62  return -1;
63  }
64 } // namespace
65 
67  const char* filename, const char* windowname, const TGWindow* p, UInt_t w, UInt_t h)
68  : TGTransientFrame(gClient->GetDefaultRoot(), p, w, h) {
69  TGVerticalFrame* vf = new TGVerticalFrame(this);
70  this->AddFrame(vf, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 5, 5, 5, 5));
71  TGHorizontalFrame* urlFrame = new TGHorizontalFrame(this);
72  vf->AddFrame(urlFrame, new TGLayoutHints(kLHintsExpandX, 5, 0, 5, 5));
73 
74  TGLabel* urlLabel = new TGLabel(urlFrame, "URL");
75  urlFrame->AddFrame(urlLabel, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 1, 1, 1, 1));
76  m_choosePrefix = new TGTextButton(urlFrame, "Choose Prefix");
77  urlFrame->AddFrame(m_choosePrefix, new TGLayoutHints(kLHintsLeft, 1, 1, 1, 1));
78 
79  m_file = new TGTextEntry(urlFrame);
80  urlFrame->AddFrame(m_file, new TGLayoutHints(kLHintsExpandX, 1, 0, 1, 1));
81  m_file->Connect("TextChanged(const char*)", "CmsShowSearchFiles", this, "fileEntryChanged(const char*)");
82  m_file->Connect("ReturnPressed()", "CmsShowSearchFiles", this, "updateBrowser()");
83 
84  m_webFile = new FWHtml(vf, 1, 1);
85  m_webFile->Connect("MouseDown(const char*)", "CmsShowSearchFiles", this, "hyperlinkClicked(const char*)");
86  vf->AddFrame(m_webFile, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 1, 1, 1, 1));
87 
88  TGHorizontalFrame* buttonFrame = new TGHorizontalFrame(vf);
89  vf->AddFrame(buttonFrame, new TGLayoutHints(kLHintsExpandX, 1, 10, 1, 10));
90 
91  m_openButton = new TGTextButton(buttonFrame, "Open");
92  buttonFrame->AddFrame(m_openButton, new TGLayoutHints(kLHintsRight, 5, 5, 1, 1));
93  m_openButton->SetEnabled(kFALSE);
94  m_openButton->Connect("Clicked()", "CmsShowSearchFiles", this, "openClicked()");
95 
96  TGTextButton* cancel = new TGTextButton(buttonFrame, "Cancel");
97  buttonFrame->AddFrame(cancel, new TGLayoutHints(kLHintsRight, 5, 5, 1, 1));
98  cancel->Connect("Clicked()", "CmsShowSearchFiles", this, "UnmapWindow()");
99 
100  SetWindowName(windowname);
101  float x1 = getURLResponseTime("lxplus.cern.ch");
102  float x2 = getURLResponseTime("uaf.t2.ucsd.edu");
103  // printf("timtes %f %f \n", x1, x2); fflush(stdout);
104 
106  if (x1 > 0 && x1 < x2)
107  path = Form("http://fireworks.web.cern.ch/fireworks/%d/", fireworks::supportedDataFormatsVersion()[0]);
108  else if (x2 > 0)
109  path = Form("http://uaf.t2.ucsd.edu/fireworks/%d/", fireworks::supportedDataFormatsVersion()[0]);
110 
111  if (!path.empty())
112  fwLog(fwlog::kInfo) << "Search files at " << path << "." << std::endl;
113 
114  sendToWebBrowser(path);
115 
116  MapSubwindows();
117  Layout();
118  m_prefixMenu = nullptr;
119  m_choosePrefix->Connect("Clicked()", "CmsShowSearchFiles", this, "showPrefixes()");
120 }
121 
123 
124 //______________________________________________________________________________
125 
127  // printf ("pref chosen %d \n", iIndex);
128  m_file->SetText(m_prefixes[iIndex].c_str(), kFALSE);
129  m_openButton->SetEnabled(kFALSE);
130 
131  if (m_prefixComplete[iIndex]) {
132  //gClient->NeedRedraw(this);
133  gClient->NeedRedraw(m_choosePrefix);
134  gClient->NeedRedraw(m_webFile);
135  gClient->ProcessEventsFor(this);
136  updateBrowser();
137  } else {
138  std::string p;
139  sendToWebBrowser(p);
140  }
141 }
142 
143 //______________________________________________________________________________
144 
145 void CmsShowSearchFiles::fileEntryChanged(const char* iFileName) {
146  std::string fileName = iFileName;
147  size_t index = fileName.find_last_of(".");
148  std::string postfix;
149  if (index != std::string::npos) {
150  postfix = fileName.substr(index, std::string::npos);
151  }
152  if (postfix == s_rootPostfix) {
153  m_openButton->SetEnabled(kTRUE);
154  } else {
155  m_openButton->SetEnabled(kFALSE);
156  }
157 }
158 
159 //______________________________________________________________________________
160 
162  std::string n = m_file->GetText();
163  sendToWebBrowser(n);
164 }
165 
166 //______________________________________________________________________________
167 
168 void CmsShowSearchFiles::hyperlinkClicked(const char* iLink) {
169  m_file->SetText(iLink, kTRUE);
170 
171  m_webFile->addToVisited(iLink);
172  std::string fileName = iLink;
173  size_t index = fileName.find_last_of(".");
174  std::string postfix = fileName.substr(index, std::string::npos);
175 
176  if (postfix != s_rootPostfix) {
177  updateBrowser();
178  } else {
179  openClicked();
180  }
181 }
182 
183 //______________________________________________________________________________
184 
186  m_openCalled = true;
187  this->UnmapWindow();
188 }
189 
190 //______________________________________________________________________________
191 
193  if (nullptr == m_prefixMenu) {
194  m_prefixMenu = new TGPopupMenu(this);
195  const char* const(*itEnd)[s_columns] = s_prefixes + sizeof(s_prefixes) / sizeof(const char * [3]);
196  int index = 0;
197  for (const char* const(*it)[s_columns] = s_prefixes; it != itEnd; ++it, ++index) {
198  //only add the protocols this version of the code actually can load
199  std::string prefix = std::string((*it)[0]).substr(0, std::string((*it)[0]).find_first_of(":") + 1);
200  if (s_httpPrefix == prefix || s_filePrefix == prefix ||
201  (gPluginMgr->FindHandler("TSystem", prefix.c_str()) &&
202  gPluginMgr->FindHandler("TSystem", prefix.c_str())->CheckPlugin() != -1)) {
203  m_prefixMenu->AddEntry((std::string((*it)[0]) + " (" + ((*it)[1]) + ")").c_str(), index);
204  m_prefixes.push_back((*it)[0]);
205  m_prefixComplete.push_back(nullptr != (*it)[2]);
206  }
207  }
208  m_prefixMenu->Connect("Activated(Int_t)", "CmsShowSearchFiles", this, "prefixChoosen(Int_t)");
209  }
210  m_prefixMenu->PlaceMenu(m_choosePrefix->GetX(), m_choosePrefix->GetY(), true, true);
211 }
212 
213 //______________________________________________________________________________
214 
215 //Copied from TGHtmlBrowser
216 static std::string readRemote(const char* url) {
217  // Read (open) remote files.
218 
219  char* buf = nullptr;
220  TUrl fUrl(url);
221 
222  TString msg = "GET ";
223  msg += fUrl.GetProtocol();
224  msg += "://";
225  msg += fUrl.GetHost();
226  msg += ":";
227  msg += fUrl.GetPort();
228  msg += "/";
229  msg += fUrl.GetFile();
230  msg += "\r\n";
231 
232  TString uri(url);
233  if (!uri.BeginsWith("http://"))
234  return std::string();
235  TSocket s(fUrl.GetHost(), fUrl.GetPort());
236  if (!s.IsValid())
237  return std::string();
238  if (s.SendRaw(msg.Data(), msg.Length()) == -1)
239  return std::string();
240  Int_t size = 1024 * 1024;
241  buf = (char*)calloc(size, sizeof(char));
242  if (s.RecvRaw(buf, size) == -1) {
243  free(buf);
244  return std::string();
245  }
246  std::string returnValue(buf);
247  free(buf);
248  return returnValue;
249 }
250 
251 //______________________________________________________________________________
252 
254  // std::cout << "CmsShowSearchFiles::sendToWebBrowser " << fileName << std::endl ;
255 
256  size_t index = fileName.find_first_of(":");
257  if (index != std::string::npos) {
258  ++index;
259  } else {
260  index = 0;
261  }
262  std::string prefix = fileName.substr(0, index);
263 
264  m_webFile->Clear();
265  if (prefix == s_httpPrefix) {
266  gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kWatch));
267  //If you clicked a hyperlink then the cursor is still a hand but we now
268  // want it to be a watch
269  gVirtualX->SetCursor(m_webFile->GetId(), gVirtualX->CreateCursor(kWatch));
270  //If we don't call ProcessEventsFor then the cursor will not be updated
271  gClient->ProcessEventsFor(this);
272  TUrl url(fileName.c_str());
273  std::string buffer = readRemote(url.GetUrl());
274 
275  if (!buffer.empty()) {
276  m_webFile->SetBaseUri(url.GetUrl());
277  m_webFile->ParseText(const_cast<char*>(buffer.c_str()));
278  } else {
279  readError();
280  }
281  gVirtualX->SetCursor(GetId(), gVirtualX->CreateCursor(kPointer));
282  gVirtualX->SetCursor(m_webFile->GetId(), gVirtualX->CreateCursor(kPointer));
283  } else {
284  readInfo();
285  }
286  m_webFile->Layout();
287 }
288 
289 //______________________________________________________________________________
291  const static char* s_readError[] = {
292  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
293  "\"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
294  "<HTML><HEAD><TITLE>HTTP Read Error</TITLE> ",
295  "<META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
296  "<BODY> ",
297  "<P>Unknown error while trying to get file via http</P>",
298  "</BODY></HTML> ",
299  nullptr};
300 
301  m_webFile->SetBaseUri("");
302  for (int i = 0; s_readError[i]; i++) {
303  m_webFile->ParseText(const_cast<char*>(s_readError[i]));
304  }
305 }
306 
308  const static char* s_noBrowserMessage[] = {
309  "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
310  "\"http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
311  "<HTML><HEAD><TITLE>No Browser Available</TITLE> ",
312  "<META http-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
313  "<BODY> ",
314  //"No file browser is available for this prefix. You can still type the full URL into the above text box to open the EDM ROOT file.<BR>",
315  //"Only a prefix beginning in <STRONG>http:</STRONG> which contains a site name (e.g. http://www.site.org) is supported for browsing."
316  "<b>Welcome....</b><BR>",
317  "<BR>",
318  "<b>You may look at examples:</b><BR>",
319  "If you are in Europe, open example data files at CERN : ",
320  " <a href=",
321  Form("http://fireworks.web.cern.ch/fireworks/%d/", fireworks::supportedDataFormatsVersion()[0]),
322  "> http://fireworks.web.cern.ch/fireworks/ </a><BR>",
323  "If you are in US, open example data files at UCSD: ",
324  " <a href=",
325  Form("http://uaf-2.t2.ucsd.edu/fireworks/%d/", fireworks::supportedDataFormatsVersion()[0]),
326  ">http://uaf-2.t2.ucsd.edu/fireworks/ </a><BR>",
327  "<BR>"
328  "<b>You also may load files with Choose Prefix </b><BR>"
329  "</BODY></HTML> ",
330  nullptr};
331 
332  m_webFile->SetBaseUri("");
333  for (int i = 0; s_noBrowserMessage[i]; i++) {
334  m_webFile->ParseText((char*)s_noBrowserMessage[i]);
335  }
336 }
337 //______________________________________________________________________________
338 
340  DontCallClose();
341  Connect("CloseWindow()", "CmsShowSearchFiles", this, "UnmapWindow()");
342  m_openCalled = false;
343  MapWindow();
344  gClient->WaitForUnmap(this);
345 
346  if (!m_openCalled) {
347  return std::string();
348  }
349  return m_file->GetText();
350 }
size
Write out results.
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
void addToVisited(const char *iToVisit)
const double w
Definition: UKUtility.cc:23
std::vector< bool > m_prefixComplete
static const char *const s_prefixes[][s_columns]
TGTextButton * m_choosePrefix
static const std::string s_filePrefix("file:")
void fileEntryChanged(const char *)
int * supportedDataFormatsVersion()
Definition: fwPaths.cc:35
FWHtml(const TGWindow *p, int w, int h, int id=-1)
TGPopupMenu * m_prefixMenu
int IsVisited(const char *iCheck) override
Definition: value.py:1
TGTextButton * m_openButton
static const std::string s_httpPrefix("http:")
std::vector< std::string > m_prefixes
static const unsigned int s_columns
#define fwLog(_level_)
Definition: fwLog.h:45
std::set< std::string > m_visited
tuple msg
Definition: mps_check.py:285
CmsShowSearchFiles(const char *filename, const char *windowname, const TGWindow *p=nullptr, UInt_t w=1, UInt_t h=1)
void sendToWebBrowser(std::string &iWebFile)
void hyperlinkClicked(const char *)
static std::string readRemote(const char *url)
std::string chooseFileFromURL()
This opens the dialog window and returns once the user has choosen, returns an empty string if cancel...
static const std::string s_rootPostfix(".root")