CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/Fireworks/Core/src/CmsShowSearchFiles.cc

Go to the documentation of this file.
00001 #include <stdexcept>
00002 #include <iostream>
00003 #include <fstream>
00004 #include <stdlib.h>
00005 #include <set>
00006 #include "TGClient.h"
00007 #include "TGHtml.h"
00008 #include "TGButton.h"
00009 #include "TGMenu.h"
00010 #include "TGLabel.h"
00011 #include "TGTextEntry.h"
00012 #include "TPluginManager.h"
00013 #include "TUrl.h"
00014 #include "TSocket.h"
00015 #include "TSystem.h"
00016 #include "TVirtualX.h"
00017 #include "TPRegexp.h"
00018 #include "Fireworks/Core/interface/CmsShowSearchFiles.h"
00019 #include "Fireworks/Core/interface/fwLog.h"
00020 #include "Fireworks/Core/interface/fwPaths.h"
00021 
00022 class FWHtml : public TGHtml {
00023 public:
00024    FWHtml(const TGWindow* p, int w, int h, int id = -1):
00025    TGHtml(p,w,h,id) {}
00026    
00027    int  IsVisited(const char* iCheck) {
00028       std::string check(GetBaseUri());
00029       check +=iCheck;
00030       int value = m_visited.find(check)==m_visited.end()?kFALSE:kTRUE;
00031       return value;
00032    }
00033    void addToVisited(const char* iToVisit) {
00034       m_visited.insert(iToVisit);
00035    }
00036 private:
00037    std::set<std::string> m_visited;
00038 };
00039 
00040 static const unsigned int s_columns = 3;
00041 static const char* const s_prefixes[][s_columns] ={ 
00042   {"https://", "Web site known by you",0},
00043   {"file:","Local file [you must type full path name]",0},
00044   {"dcap://","dCache [FNAL]",0},
00045   {"rfio://","Castor [CERN]",0}
00046   
00047 };
00048 
00049 static const std::string s_httpsPrefix("https:");
00050 static const std::string s_filePrefix("file:");
00051 static const std::string s_rootPostfix(".root");
00052 
00053 
00054 namespace {
00055 float
00056 getURLResponseTime(const char* url)
00057 {
00058   TString com = "ping -q -c 1 -n " + TString(url) + "| tail -n 1";
00059   FILE* p = gSystem->OpenPipe(com, "r");
00060   TString l;
00061   l.Gets(p);
00062   gSystem->ClosePipe(p);
00063 
00064   TPMERegexp re("([\\d\\.]+)");
00065   if (re.Match(l))
00066     return  re[1].Atof();
00067   else
00068     return -1;
00069 }
00070 }
00071 
00072 CmsShowSearchFiles::CmsShowSearchFiles (const char *filename,
00073                                         const char* windowname,
00074                                         const TGWindow* p, UInt_t w, UInt_t h)
00075    : TGTransientFrame(gClient->GetDefaultRoot(), p, w, h)
00076 {
00077    TGVerticalFrame* vf = new TGVerticalFrame(this);
00078    this->AddFrame(vf,new TGLayoutHints(kLHintsExpandX|kLHintsExpandY,5,5,5,5));
00079    TGHorizontalFrame* urlFrame = new TGHorizontalFrame(this);
00080    vf->AddFrame(urlFrame,new TGLayoutHints(kLHintsExpandX,5,0,5,5));
00081    
00082    TGLabel* urlLabel = new TGLabel(urlFrame,"URL");
00083    urlFrame->AddFrame(urlLabel, new TGLayoutHints(kLHintsLeft|kLHintsCenterY,1,1,1,1));
00084    m_choosePrefix = new TGTextButton(urlFrame,"Choose Prefix");
00085    urlFrame->AddFrame(m_choosePrefix, new TGLayoutHints(kLHintsLeft,1,1,1,1));
00086    
00087    m_file= new TGTextEntry(urlFrame);
00088    urlFrame->AddFrame(m_file, new TGLayoutHints(kLHintsExpandX,1,0,1,1));
00089    m_file->Connect("TextChanged(const char*)", "CmsShowSearchFiles",this,"fileEntryChanged(const char*)");
00090    m_file->Connect("ReturnPressed()", "CmsShowSearchFiles",this,"updateBrowser()");
00091    
00092    m_webFile = new FWHtml(vf,1,1);
00093    m_webFile->Connect("MouseDown(const char*)","CmsShowSearchFiles",this,"hyperlinkClicked(const char*)");
00094    vf->AddFrame(m_webFile, new TGLayoutHints(kLHintsExpandX|kLHintsExpandY,1,1,1,1));
00095    
00096    TGHorizontalFrame* buttonFrame = new TGHorizontalFrame(vf);
00097    vf->AddFrame(buttonFrame, new TGLayoutHints(kLHintsExpandX,1,10,1,10));
00098    
00099    m_openButton = new TGTextButton(buttonFrame,"Open");
00100    buttonFrame->AddFrame(m_openButton, new TGLayoutHints(kLHintsRight,5,5,1,1));
00101    m_openButton->SetEnabled(kFALSE);
00102    m_openButton->Connect("Clicked()","CmsShowSearchFiles",this,"openClicked()");
00103 
00104    TGTextButton* cancel = new TGTextButton(buttonFrame,"Cancel");
00105    buttonFrame->AddFrame(cancel, new TGLayoutHints(kLHintsRight,5,5,1,1));
00106    cancel->Connect("Clicked()","CmsShowSearchFiles",this,"UnmapWindow()");
00107 
00108    SetWindowName(windowname);
00109    float x1 = getURLResponseTime("lxplus.cern.ch");
00110    float x2 = getURLResponseTime("uaf-2.t2.ucsd.edu");
00111    // printf("timtes %f %f \n", x1, x2); fflush(stdout);
00112 
00113    std::string path;
00114    if (x1 > 0 && x1 < x2)
00115       path = Form("https://fireworks.web.cern.ch/fireworks/%d/",fireworks::supportedDataFormatsVersion()[0] );
00116    else if (x2 > 0)
00117       path = Form("https://uaf-2.t2.ucsd.edu/fireworks/%d/", fireworks::supportedDataFormatsVersion()[0]);
00118 
00119    if (!path.empty())
00120       fwLog(fwlog::kInfo) << "Search files at " << path  << "." << std::endl;
00121 
00122    sendToWebBrowser(path);
00123 
00124 
00125    MapSubwindows();
00126    Layout();
00127    m_prefixMenu=0;
00128    m_choosePrefix->Connect("Clicked()","CmsShowSearchFiles",this,"showPrefixes()");
00129 }
00130 
00131 CmsShowSearchFiles::~CmsShowSearchFiles()
00132 {
00133    delete m_prefixMenu;
00134 }
00135 
00136 //______________________________________________________________________________
00137 
00138 void 
00139 CmsShowSearchFiles::prefixChoosen(Int_t iIndex)
00140 {
00141    //   printf ("pref chosen %d \n", iIndex);
00142    m_file->SetText(m_prefixes[iIndex].c_str(),kFALSE);
00143    m_openButton->SetEnabled(kFALSE);
00144 
00145    if(m_prefixComplete[iIndex]) {
00146       //gClient->NeedRedraw(this);
00147       gClient->NeedRedraw(m_choosePrefix);
00148       gClient->NeedRedraw(m_webFile);
00149       gClient->ProcessEventsFor(this);
00150       updateBrowser();
00151    } else {
00152       std::string p;
00153       sendToWebBrowser(p);
00154    }
00155 }
00156 
00157 //______________________________________________________________________________
00158 
00159 
00160 void 
00161 CmsShowSearchFiles::fileEntryChanged(const char* iFileName)
00162 {
00163    std::string fileName =iFileName;
00164    size_t index = fileName.find_last_of(".");
00165    std::string postfix;
00166    if(index != std::string::npos) {
00167       postfix=fileName.substr(index,std::string::npos);
00168    }
00169    if(postfix ==s_rootPostfix) {
00170       m_openButton->SetEnabled(kTRUE);
00171    } else {
00172       m_openButton->SetEnabled(kFALSE);
00173    }
00174 }
00175 
00176 //______________________________________________________________________________
00177 
00178 void 
00179 CmsShowSearchFiles::updateBrowser()
00180 {
00181    std::string n = m_file->GetText();
00182    sendToWebBrowser(n);
00183 }
00184 
00185 
00186 //______________________________________________________________________________
00187 
00188 void 
00189 CmsShowSearchFiles::hyperlinkClicked(const char* iLink)
00190 {
00191    m_file->SetText(iLink,kTRUE);
00192    
00193    m_webFile->addToVisited(iLink);
00194    std::string fileName =iLink;
00195    size_t index = fileName.find_last_of(".");
00196    std::string postfix = fileName.substr(index,std::string::npos);
00197    
00198    if(postfix !=s_rootPostfix) {
00199       updateBrowser();
00200    } else {
00201       openClicked();
00202    }
00203 }
00204 
00205 //______________________________________________________________________________
00206 
00207 void 
00208 CmsShowSearchFiles::openClicked()
00209 {
00210    m_openCalled=true;
00211    this->UnmapWindow();
00212 }
00213 
00214 //______________________________________________________________________________
00215 
00216 void 
00217 CmsShowSearchFiles::showPrefixes()
00218 {
00219    if(0==m_prefixMenu) {
00220       m_prefixMenu = new TGPopupMenu(this);
00221       const char* const (*itEnd)[s_columns] = s_prefixes+sizeof(s_prefixes)/sizeof(const char*[3]);
00222       int index = 0;
00223       for(const char* const (*it)[s_columns] = s_prefixes;
00224           it != itEnd;
00225           ++it,++index) {
00226          //only add the protocols this version of the code actually can load
00227          std::string prefix = std::string((*it)[0]).substr(0,std::string((*it)[0]).find_first_of(":")+1);
00228          if(s_httpsPrefix==prefix ||
00229             s_filePrefix==prefix ||
00230             (gPluginMgr->FindHandler("TSystem",prefix.c_str()) && 
00231              gPluginMgr->FindHandler("TSystem",prefix.c_str())->CheckPlugin() != -1)) {
00232             m_prefixMenu->AddEntry((std::string((*it)[0])+" ("+((*it)[1])+")").c_str(),index);
00233             m_prefixes.push_back((*it)[0]);
00234             m_prefixComplete.push_back(0!=(*it)[2]);
00235          }
00236       }
00237       m_prefixMenu->Connect("Activated(Int_t)","CmsShowSearchFiles",this,"prefixChoosen(Int_t)");
00238    }
00239    m_prefixMenu->PlaceMenu(m_choosePrefix->GetX(),m_choosePrefix->GetY(),true,true);
00240 }
00241 
00242 
00243 //______________________________________________________________________________
00244 
00245 
00246     //Copied from TGHtmlBrowser
00247 static std::string readRemote(const char *url)
00248 {
00249    // Read (open) remote files.
00250    
00251    char *buf = 0;
00252    TUrl fUrl(url);
00253 
00254    TString msg = "GET ";
00255    msg += fUrl.GetProtocol();
00256    msg += "://";
00257    msg += fUrl.GetHost();
00258    msg += ":";
00259    msg += fUrl.GetPort();
00260    msg += "/";
00261    msg += fUrl.GetFile();
00262    msg += "\r\n";
00263    
00264    TString uri(url);
00265    if (!uri.BeginsWith("https://"))
00266       return std::string();
00267    TSocket s(fUrl.GetHost(), fUrl.GetPort());
00268    if (!s.IsValid())
00269       return std::string();
00270    if (s.SendRaw(msg.Data(), msg.Length()) == -1)
00271       return std::string();
00272    Int_t size = 1024*1024;
00273    buf = (char *)calloc(size, sizeof(char));
00274    if (s.RecvRaw(buf, size) == -1) {
00275       free(buf);
00276       return std::string();
00277    }
00278    std::string returnValue(buf);
00279    free(buf);
00280    return returnValue;
00281 }
00282 
00283 //______________________________________________________________________________
00284 
00285 void 
00286 CmsShowSearchFiles::sendToWebBrowser(std::string& fileName)
00287 {
00288    //  std::cout << "CmsShowSearchFiles::sendToWebBrowser " <<  fileName << std::endl ;
00289 
00290    size_t index = fileName.find_first_of(":");
00291    if(index != std::string::npos) {
00292       ++index;
00293    } else {
00294       index = 0;
00295    }
00296    std::string prefix = fileName.substr(0,index);
00297 
00298    m_webFile->Clear();
00299    if(prefix == s_httpsPrefix) {
00300       gVirtualX->SetCursor(GetId(),gVirtualX->CreateCursor(kWatch));
00301       //If you clicked a hyperlink then the cursor is still a hand but we now
00302       // want it to be a watch
00303       gVirtualX->SetCursor(m_webFile->GetId(),gVirtualX->CreateCursor(kWatch));
00304       //If we don't call ProcessEventsFor then the cursor will not be updated
00305       gClient->ProcessEventsFor(this);
00306       TUrl url(fileName.c_str());
00307       std::string buffer = readRemote(url.GetUrl());
00308 
00309       if (buffer.size()) {
00310          m_webFile->SetBaseUri(url.GetUrl());
00311          m_webFile->ParseText(const_cast<char*>(buffer.c_str()));
00312       }
00313       else {
00314          readError();
00315       }
00316       gVirtualX->SetCursor(GetId(),gVirtualX->CreateCursor(kPointer));
00317       gVirtualX->SetCursor(m_webFile->GetId(),gVirtualX->CreateCursor(kPointer));
00318    } else {
00319       readInfo();
00320    }
00321    m_webFile->Layout();
00322 }
00323 
00324 //______________________________________________________________________________
00325 void 
00326 CmsShowSearchFiles::readError()
00327 {
00328 
00329    static const char *s_readError[] = {
00330       "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
00331       "<HTML><HEAD><TITLE>HTTP Read Error</TITLE> ",
00332       "<META https-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
00333       "<BODY> ",
00334       "<P>Unknown error while trying to get file via https</P>",
00335       "</BODY></HTML> ",
00336       0
00337    };
00338 
00339    m_webFile->SetBaseUri("");
00340    for (int i=0; s_readError[i]; i++) {
00341       m_webFile->ParseText(const_cast<char *>(s_readError[i]));
00342    }
00343 }
00344 
00345 void 
00346 CmsShowSearchFiles::readInfo()
00347 {
00348    static const char *s_noBrowserMessage[] = {
00349       "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"https://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd\"> ",
00350       "<HTML><HEAD><TITLE>No Browser Available</TITLE> ",
00351       "<META https-equiv=Content-Type content=\"text/html; charset=UTF-8\"></HEAD> ",
00352       "<BODY> ",
00353       //"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>",
00354       //"Only a prefix beginning in <STRONG>https:</STRONG> which contains a site name (e.g. https://www.site.org) is supported for browsing."
00355       "<b>Welcome....</b><BR>",
00356       "<BR>",
00357       "<b>You may look at examples:</b><BR>",  
00358       "If you are in Europe, open example data files at CERN :  ", " <a href=" , Form("https://fireworks.web.cern.ch/fireworks/%d/",fireworks::supportedDataFormatsVersion()[0] ),"> https://fireworks.web.cern.ch/fireworks/ </a><BR>",
00359       "If you are in US, open example data files at UCSD:  ", " <a href=" , Form("https://uaf-2.t2.ucsd.edu/fireworks/%d/",fireworks::supportedDataFormatsVersion()[0] ),">https://uaf-2.t2.ucsd.edu/fireworks/ </a><BR>",
00360       "<BR>"
00361       "<b>You also may load files with Choose Prefix </b><BR>"
00362       "</BODY></HTML> ",
00363       0
00364    };
00365 
00366    m_webFile->SetBaseUri("");
00367    for (int i=0; s_noBrowserMessage[i]; i++) {
00368       m_webFile->ParseText((char *)s_noBrowserMessage[i]);
00369    }
00370 
00371 }
00372 //______________________________________________________________________________
00373 
00374 std::string 
00375 CmsShowSearchFiles::chooseFileFromURL()
00376 {
00377    DontCallClose();
00378    Connect("CloseWindow()","CmsShowSearchFiles",this,"UnmapWindow()");
00379    m_openCalled = false;
00380    MapWindow();
00381    gClient->WaitForUnmap(this);
00382 
00383    if(!m_openCalled) {
00384       return std::string();
00385    }
00386    return m_file->GetText();
00387 }