otsdaq_utilities  v2_04_01
VisualSupervisor.cc
1 #include "otsdaq-utilities/Visualization/VisualSupervisor.h"
2 //#include "otsdaq-core/RootUtilities/DQMHistos.h"
3 #include "otsdaq-core/DataManager/DataManagerSingleton.h"
4 #include "otsdaq-core/Macros/BinaryStringMacros.h"
5 
6 // ROOT documentation
7 // http://root.cern.ch/root/html/index.html
8 
9 #include <TBuffer.h>
10 #include <TBufferJSON.h>
11 #include <TCanvas.h>
12 #include <TClass.h>
13 #include <TDirectory.h>
14 #include <TFile.h>
15 #include <TH1.h>
16 #include <TH2.h>
17 #include <TIterator.h>
18 #include <TKey.h>
19 #include <TProfile.h>
20 #include <TROOT.h>
21 #include <TRegexp.h>
22 #include <TString.h>
23 #include "TBufferFile.h"
24 #include "TObject.h"
25 
26 #include <dirent.h> /*DIR and dirent*/
27 #include <sys/stat.h> /*mkdir*/
28 
29 #include <xdaq/NamespaceURI.h>
30 
31 #include <iostream>
32 
33 #define ROOT_BROWSER_PATH __ENV__("ROOT_BROWSER_PATH")
34 #define ROOT_DISPLAY_CONFIG_PATH __ENV__("ROOT_DISPLAY_CONFIG_PATH")
35 
36 #define LIVEDQM_DIR std::string("LIVE_DQM")
37 #define PRE_MADE_ROOT_CFG_DIR std::string("Pre-made Views")
38 
39 #define PRE_MADE_ROOT_CFG_FILE_EXT std::string(".rcfg")
40 
41 #define PREFERENCES_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/VisualizerData/"
42 #define PREFERENCES_FILE_EXT ".pref"
43 
44 #define ROOT_VIEWER_PERMISSIONS_THRESHOLD 100
45 
46 using namespace ots;
47 
48 #undef __MF_SUBJECT__
49 #define __MF_SUBJECT__ "Visualizer"
50 
51 XDAQ_INSTANTIATOR_IMPL(VisualSupervisor)
52 
53 //========================================================================================================================
54 VisualSupervisor::VisualSupervisor(xdaq::ApplicationStub* stub)
55  : CoreSupervisorBase(stub), theDataManager_(0), loadedRunNumber_(-1)
56 {
57  __SUP_COUT__ << "Constructor." << __E__;
58  INIT_MF("VisualSupervisor");
59 
60  theDataManager_ = DataManagerSingleton::getInstance<VisualDataManager>(
61  theConfigurationManager_->getNode(
62  theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)->getTableName()),
63  CorePropertySupervisorBase::getSupervisorConfigurationPath(),
64  CorePropertySupervisorBase::getSupervisorUID());
65 
66  CoreSupervisorBase::theStateMachineImplementation_.push_back(theDataManager_);
67 
68  __SUP_COUT__ << "Done instantiating Visual data manager." << __E__;
69 
70  // xgi::bind(this, &VisualSupervisor::safariDefaultPage, "safari" );
71 
72  // make preferences directory in case they don't exist
73  mkdir(((std::string)PREFERENCES_PATH).c_str(), 0755);
74 
75  __SUP_COUT__ << "Constructed." << __E__;
76 } // end constructor
77 
78 //========================================================================================================================
79 VisualSupervisor::~VisualSupervisor(void)
80 {
81  __SUP_COUT__ << "Destructor." << __E__;
82  destroy();
83  __SUP_COUT__ << "Destructed." << __E__;
84 } // end destructor()
85 
86 //========================================================================================================================
87 void VisualSupervisor::destroy(void)
88 {
89  __SUP_COUT__ << "Destroying..." << __E__;
90 
91  // called by destructor
92  // delete theConfigurationManager_;
93 
94  DataManagerSingleton::deleteInstance(CorePropertySupervisorBase::getSupervisorUID());
95  theStateMachineImplementation_.pop_back();
96 } // end destroy()
97 //
99 // void VisualSupervisor::defaultPage(xgi::Input * in, xgi::Output * out )
100 //{
101 // //__SUP_COUT__ << this->getApplicationContext()->getURL() << __E__;
102 //
103 // *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame
104 // src='/WebPath/html/Visualization.html?urn=" <<
105 // this->getApplicationDescriptor()->getLocalId() <<"'></frameset></html>";
106 //
107 //}
108 //
110 // void VisualSupervisor::safariDefaultPage(xgi::Input * in, xgi::Output * out )
111 //{
112 // *out << "<!DOCTYPE HTML><html lang='en'><iframe
113 // style='width:100%;height:100%;position:absolute;left:0;top:0;border:0;padding:0;margin:0;'
114 // src='/WebPath/html/Visualization.html?urn=" <<
115 // this->getApplicationDescriptor()->getLocalId() <<"'></iframe></html>";
116 //}
117 
118 //========================================================================================================================
119 // setSupervisorPropertyDefaults
120 // override to set defaults for supervisor property values (before user settings
121 // override)
122 void VisualSupervisor::setSupervisorPropertyDefaults()
123 {
124  CorePropertySupervisorBase::setSupervisorProperty(
125  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AllowNoLoginRequestTypes,
126  "setUserPreferences | getUserPreferences | getDirectoryContents | getRoot | "
127  "getEvents");
128 
129  CorePropertySupervisorBase::setSupervisorProperty(
130  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
131  "*=1 | rootAdminControls=100");
132 }
133 
134 //========================================================================================================================
135 // forceSupervisorPropertyValues
136 // override to force supervisor property values (and ignore user settings)
137 void VisualSupervisor::forceSupervisorPropertyValues()
138 {
139  CorePropertySupervisorBase::setSupervisorProperty(
140  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
141  "getRoot | getEvents");
142  CorePropertySupervisorBase::setSupervisorProperty(
143  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.NoXmlWhiteSpaceRequestTypes,
144  "getRoot | getEvents"); // json data in ROOTJS library expects no funny
145  // characters
146  // CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.NeedUsernameRequestTypes,
147  // "setUserPreferences | getUserPreferences");
148 }
149 
150 //========================================================================================================================
151 void VisualSupervisor::request(const std::string& requestType,
152  cgicc::Cgicc& cgiIn,
153  HttpXmlDocument& xmlOut,
154  const WebUsers::RequestUserInfo& userInfo)
155 {
156  // Commands
157  // getRawData
158  // getGeometry
159  // getEvents
160  // getRoot
161  // getDirectoryContents
162  // setUserPreferences
163  // getUserPreference
164 
165  // if (requestType == "getHisto" && theDataManager_->getLiveDQMHistos() != 0)
166  // {
167  // // TH1I* histo =
168  // (TH1I*)theDataManager_->getLiveDQMHistos()->get("Planes/Plane_0_Occupancy");
169  //
170  // // theDataManager_->load("Run185_Histo.root","Histograms");
171  // //TH1F* histo1d = theDataManager_->getFileDQMHistos().getHisto1D();
172  // //TCanvas* canvas = theDataManager_->getFileDQMHistos().getCanvas ();
173  // //TH2F* histo2d = theDataManager_->getFileDQMHistos().getHisto2D();
174  // //TProfile* profile = theDataManager_->getFileDQMHistos().getProfile();
175  //
176  // }
177  if(requestType == "getRawData")
178  {
179  __SUP_COUT__ << __E__;
180  try
181  {
182  // TODO -- add timestamp, so we know if data is new
183  __SUP_COUT__ << "Getting Raw data and converting to binary string" << __E__;
184  xmlOut.addBinaryStringToData("rawData", theDataManager_->getRawData());
185  __SUP_COUT__ << __E__;
186  }
187  catch(std::exception const& e)
188  {
189  __SUP_COUT__
190  << "ERROR! Exception while getting raw data. Incoming exception data..."
191  << __E__;
192  __SUP_COUT__ << e.what() << __E__;
193  __SUP_COUT__ << "End Exception Data" << __E__;
194  }
195  catch(...)
196  {
197  __SUP_COUT__ << "ERROR! Something went wrong trying to get raw data."
198  << __E__;
199  __SUP_COUT_INFO__ << "ERROR! Something went wrong trying to get raw data."
200  << __E__;
201  }
202  }
203  else if(requestType == "setUserPreferences" &&
204  userInfo.username_ != "" /*from allow no user*/)
205  {
206  __SUP_COUT__ << "userInfo.username_: " << userInfo.username_ << __E__;
207  std::string fullPath =
208  (std::string)PREFERENCES_PATH + userInfo.username_ + PREFERENCES_FILE_EXT;
209  __SUP_COUT__ << "fullPath: " << fullPath << __E__;
210 
211  std::string radioSelect = CgiDataUtilities::getData(cgiIn, "radioSelect");
212  std::string autoRefresh = CgiDataUtilities::getData(cgiIn, "autoRefresh");
213  std::string autoHide = CgiDataUtilities::getData(cgiIn, "autoHide");
214  std::string hardRefresh = CgiDataUtilities::getData(cgiIn, "hardRefresh");
215  std::string autoRefreshPeriod =
216  CgiDataUtilities::getData(cgiIn, "autoRefreshPeriod");
217 
218  __SUP_COUT__ << "radioSelect: " << radioSelect << __E__;
219  __SUP_COUT__ << "autoRefresh: " << autoRefresh << __E__;
220  __SUP_COUT__ << "autoHide: " << autoHide << __E__;
221  __SUP_COUT__ << "hardRefresh: " << hardRefresh << __E__;
222  __SUP_COUT__ << "autoRefreshPeriod: " << autoRefreshPeriod << __E__;
223 
224  // read existing
225  FILE* fp = fopen(fullPath.c_str(), "r");
226  if(fp)
227  {
228  char line[100];
229  char val[100];
230 
231  fgets(line, 100, fp);
232  sscanf(line, "%*s %s", val);
233  if(radioSelect == "")
234  radioSelect = val;
235 
236  fgets(line, 100, fp);
237  sscanf(line, "%*s %s", val);
238  if(autoRefresh == "")
239  autoRefresh = val;
240 
241  fgets(line, 100, fp);
242  sscanf(line, "%*s %s", val);
243  if(autoHide == "")
244  autoHide = val;
245 
246  fgets(line, 100, fp);
247  sscanf(line, "%*s %s", val);
248  if(hardRefresh == "")
249  hardRefresh = val;
250 
251  fgets(line, 100, fp);
252  sscanf(line, "%*s %s", val);
253  if(autoRefreshPeriod == "")
254  autoRefreshPeriod = val;
255 
256  fclose(fp);
257  }
258 
259  // write new
260  fp = fopen(fullPath.c_str(), "w");
261  if(fp)
262  {
263  fprintf(fp, "radioSelect %s\n", radioSelect.c_str());
264  fprintf(fp, "autoRefresh %s\n", autoRefresh.c_str());
265  fprintf(fp, "autoHide %s\n", autoHide.c_str());
266  fprintf(fp, "hardRefresh %s\n", hardRefresh.c_str());
267  fprintf(fp, "autoRefreshPeriod %s\n", autoRefreshPeriod.c_str());
268  fclose(fp);
269  }
270  else
271  __SUP_COUT_ERR__ << "Failure writing preferences to file: " << fullPath
272  << __E__;
273  }
274  else if(requestType == "getUserPreferences")
275  {
276  __SUP_COUT__ << "userInfo.username_: " << userInfo.username_ << __E__;
277  std::string fullPath =
278  (std::string)PREFERENCES_PATH + userInfo.username_ + PREFERENCES_FILE_EXT;
279  __SUP_COUT__ << "fullPath: " << fullPath << __E__;
280 
281  FILE* fp = fopen(fullPath.c_str(), "r");
282  if(fp)
283  {
284  char line[100];
285  // char val[100];
286  int val;
287 
288  fgets(line, 100, fp);
289  sscanf(line, "%*s %d", &val);
290  if(val < 0 || val > 3)
291  val = 0; // FIXME.. value can get corrupt...
292  xmlOut.addTextElementToData("radioSelect", std::to_string(val));
293  fgets(line, 100, fp);
294  sscanf(line, "%*s %d", &val);
295  xmlOut.addTextElementToData("autoRefresh", std::to_string(val));
296  fgets(line, 100, fp);
297  sscanf(line, "%*s %d", &val);
298  xmlOut.addTextElementToData("autoHide", std::to_string(val));
299  fgets(line, 100, fp);
300  sscanf(line, "%*s %d", &val);
301  xmlOut.addTextElementToData("hardRefresh", std::to_string(val));
302  fgets(line, 100, fp);
303  sscanf(line, "%*s %d", &val);
304  xmlOut.addTextElementToData("autoRefreshPeriod", std::to_string(val));
305  fclose(fp);
306  }
307  else
308  {
309  // else assume user has no preferences yet
310  xmlOut.addTextElementToData("radioSelect", "");
311  xmlOut.addTextElementToData("autoRefresh", "");
312  xmlOut.addTextElementToData("autoHide", "");
313  xmlOut.addTextElementToData("hardRefresh", "");
314  xmlOut.addTextElementToData("autoRefreshPeriod", "");
315  }
316  }
317  else if(requestType == "getDirectoryContents")
318  {
319  // return directory structure for requested path, types are "dir" and "file"
320 
321  std::string rootpath = std::string(ROOT_BROWSER_PATH) + "/";
322  std::string path = CgiDataUtilities::postData(cgiIn, "Path");
323  __SUP_COUT__ << path << __E__;
324 
325  // return 1 if user has access to admin controls, else 0
326  char permStr[10];
327  sprintf(permStr,
328  "%d",
329  userInfo.permissionLevel_ >=
330  CoreSupervisorBase::getSupervisorPropertyUserPermissionsThreshold(
331  "rootAdminControls"));
332  xmlOut.addTextElementToData("permissions", permStr); // add permissions
333 
334  std::string dirpath = rootpath + path;
335  if(path == "/" + PRE_MADE_ROOT_CFG_DIR + "/")
336  dirpath = ROOT_DISPLAY_CONFIG_PATH;
337 
338  if(path.find("/" + PRE_MADE_ROOT_CFG_DIR + "/") ==
339  0) // ROOT config path must start the path
340  dirpath = std::string(ROOT_DISPLAY_CONFIG_PATH) + "/" +
341  path.substr(PRE_MADE_ROOT_CFG_DIR.length() + 2);
342 
343  __SUP_COUT__ << "full path: " << dirpath << __E__;
344 
345  DIR* pDIR;
346  struct dirent* entry;
347  bool isNotRtCfg;
348  bool isDir;
349  if((pDIR = opendir(dirpath.c_str())))
350  {
351  xmlOut.addTextElementToData("path", path);
352 
353  // add LIVE if path is / and DQM is active
354  // add Pre-made Views if path is / and ROOT_DISPLAY_CONFIG_PATH isnt already
355  // there
356  if(path == "/")
357  {
358  if(theDataManager_->getLiveDQMHistos() != 0)
359  xmlOut.addTextElementToData("dir",
360  LIVEDQM_DIR + ".root"); // add to xml
361 
362  // check for ROOT_DISPLAY_CONFIG_PATH
363  DIR* pRtDIR = opendir(ROOT_DISPLAY_CONFIG_PATH);
364  bool recheck = false;
365  if(!pRtDIR) // if doesn't exist, make it
366  {
367  recheck = true;
368  if(mkdir(ROOT_DISPLAY_CONFIG_PATH,
369  S_IRWXU | (S_IRGRP | S_IXGRP) |
370  (S_IROTH | S_IXOTH))) // mode = drwx r-x r-x
371  __SUP_COUT__ << "Failed to make directory for pre made views: "
372  << ROOT_DISPLAY_CONFIG_PATH << __E__;
373  }
374  else
375  closedir(pRtDIR); // else close and display
376 
377  if(!recheck || (pRtDIR = opendir(ROOT_DISPLAY_CONFIG_PATH)))
378  {
379  xmlOut.addTextElementToData("dir",
380  PRE_MADE_ROOT_CFG_DIR); // add to xml
381  if(recheck)
382  closedir(pRtDIR);
383  }
384  }
385 
386  while((entry = readdir(pDIR)))
387  {
388  //__SUP_COUT__ << int(entry->d_type) << " " << entry->d_name << "\n" <<
389  // __E__;
390  if(entry->d_name[0] != '.' &&
391  (entry->d_type ==
392  0 || // 0 == UNKNOWN (which can happen - seen in SL7 VM)
393  entry->d_type == 4 ||
394  entry->d_type == 8))
395  {
396  //__SUP_COUT__ << int(entry->d_type) << " " << entry->d_name << "\n"
397  //<< __E__;
398  isNotRtCfg =
399  std::string(entry->d_name).find(".rcfg") == std::string::npos;
400  isDir = false;
401 
402  if(entry->d_type == 0)
403  {
404  // unknown type .. determine if directory
405  DIR* pTmpDIR = opendir((dirpath + entry->d_name).c_str());
406  if(pTmpDIR)
407  {
408  isDir = true;
409  closedir(pTmpDIR);
410  }
411  // else //assume file
412  }
413 
414  if((entry->d_type == 8 ||
415  (!isDir && entry->d_type == 0)) // file type
416  && std::string(entry->d_name).find(".root") == std::string::npos &&
417  isNotRtCfg)
418  continue; // skip if not a root file or a config file
419  else if(entry->d_type == 4)
420  isDir = true; // flag directory types
421 
422  xmlOut.addTextElementToData(
423  isDir ? "dir" : (isNotRtCfg ? "dir" : "file"), entry->d_name);
424  }
425  }
426  closedir(pDIR);
427  }
428  else
429  __SUP_COUT__ << "Failed to access directory contents!" << __E__;
430  }
431  else if(requestType == "getRoot")
432  {
433  // return directory structure for requested ROOT path, types are "dir" and "file"
434 
435  std::string path = CgiDataUtilities::postData(cgiIn, "RootPath");
436  std::string fullPath = std::string(__ENV__("ROOT_BROWSER_PATH")) + path;
437 
438  //__SUP_COUT__ << "Full path:-" << fullPath << "-" << __E__;
439 
440  std::string rootFileName = fullPath.substr(0, fullPath.find(".root") + 5);
441  std::string rootDirectoryName =
442  rootFileName + ":" +
443  fullPath.substr(fullPath.find(".root") + 5,
444  fullPath.size() - fullPath.find(".root") + 5 + 1);
445 
446  std::string::size_type LDQM_pos = path.find("/" + LIVEDQM_DIR + ".root/");
447  TFile* rootFile;
448 
449  if(theDataManager_->getLiveDQMHistos() != nullptr && LDQM_pos == 0)
450  {
451  //__SUP_COUT__ << "Attempting to get LIVE file." << __E__;
452  rootFile = theDataManager_->getLiveDQMHistos()->getFile();
453  if(!rootFile)
454  __SUP_COUT__ << "File was closed." << __E__;
455  else
456  {
457  //__SUP_COUT__ << "LIVE file name: " << rootFile->GetName() << __E__;
458  rootDirectoryName = path.substr(("/" + LIVEDQM_DIR + ".root").length());
459  }
460  }
461  else
462  rootFile = TFile::Open(rootFileName.c_str());
463 
464  //__SUP_COUT__ << "FileName : " << rootFileName << " Object: " <<
465  // rootDirectoryName << __E__;
466 
467  if(!rootFile || !rootFile->IsOpen())
468  {
469  __SUP_COUT__ << "Failed to access root file: " << rootFileName << __E__;
470  }
471  else
472  {
473  xmlOut.addTextElementToData("path", path);
474 
475  TDirectory* directory;
476  if((directory = rootFile->GetDirectory(rootDirectoryName.c_str())) == 0)
477  {
478  //__SUP_COUT__ << "This is not a directory!" << __E__;
479  directory = rootFile;
480 
481  // failed directory so assume it's file
482  //__SUP_COUT__ << "Getting object name: " << rootDirectoryName <<
483  // __E__;
484  TObject* histoClone = nullptr;
485  TObject* histo = (TObject*)rootFile->Get(rootDirectoryName.c_str());
486 
487  if(histo != nullptr) // turns out was a root object path
488  {
489  // Clone histo to avoid conflict when it is filled by other threads
490  histoClone = histo->Clone();
491  TString json = TBufferJSON::ConvertToJSON(histoClone);
492  TBufferFile tBuffer(TBuffer::kWrite);
493  histoClone->Streamer(tBuffer);
494 
495  //__SUP_COUT__ << "histo length " << tbuff.Length() << __E__;
496 
497  std::string destination = BinaryStringMacros::binaryToHexString(
498  tBuffer.Buffer(), tBuffer.Length());
499 
500  xmlOut.addTextElementToData("rootType", histoClone->ClassName());
501  xmlOut.addTextElementToData("rootData", destination);
502  xmlOut.addTextElementToData("rootJSON", json.Data());
503  delete histoClone;
504  }
505  else
506  __SUP_COUT_ERR__ << "Failed to access:-" << rootDirectoryName << "-"
507  << __E__;
508  }
509  else
510  {
511  __SUP_COUT__ << "directory found getting the content!" << __E__;
512  TRegexp re("*", kTRUE);
513  if(LDQM_pos == 0)
514  {
515  TObject* obj;
516  TIter nextobj(directory->GetList());
517  while((obj = (TObject*)nextobj()))
518  {
519  TString s = obj->GetName();
520  if(s.Index(re) == kNPOS)
521  continue;
522  __SUP_COUT__ << "Class Name: " << obj->IsA()->GetName() << __E__;
523  xmlOut.addTextElementToData(
524  (std::string(obj->IsA()->GetName()).find("Directory") !=
525  std::string::npos)
526  ? "dir"
527  : "file",
528  obj->GetName());
529  }
530  }
531  else
532  {
533  TKey* key;
534  TIter next(directory->GetListOfKeys());
535  while((key = (TKey*)next()))
536  {
537  TString s = key->GetName();
538  if(s.Index(re) == kNPOS)
539  continue;
540  __SUP_COUT__ << "Class Name: " << key->GetClassName() << __E__;
541  xmlOut.addTextElementToData(
542  (std::string(key->GetClassName()).find("Directory") !=
543  std::string::npos)
544  ? "dir"
545  : "file",
546  key->GetName());
547  }
548  }
549  }
550  if(LDQM_pos == std::string::npos)
551  rootFile->Close();
552  }
553  }
554  else if(requestType == "getEvents")
555  {
556  int Run = atoi(cgiIn("run").c_str());
557 
558  __SUP_COUT__ << "getEvents for run " << Run << __E__;
559 
560  if(Run != (int)loadedRunNumber_ || loadedRunNumber_ == (unsigned int)-1)
561  {
562  theDataManager_->load("Run1684.root", "Monicelli");
563  loadedRunNumber_ = Run;
564  }
565 
566  DOMElement* eventsParent = xmlOut.addTextElementToData("events", "");
567  DOMElement* eventParent;
568  char str[40];
569 
570  // const Visual3DEvents& events = theDataManager_->getVisual3DEvents();
571  // __SUP_COUT__ << "Preparing hits xml" << __E__;
572  // int numberOfEvents = 0;
573  // for(Visual3DEvents::const_iterator it=events.begin(); it!=events.end() &&
574  // numberOfEvents < 10000; it++, numberOfEvents++)
575  // {
576  // //__SUP_COUT__ << "Event: " << numberOfEvents << __E__;
577  // eventParent = xmlOut.addTextElementToParent("event", str,
578  // eventsParent); const VisualHits& hits = it->getHits();
579  // for(VisualHits::const_iterator itHits=hits.begin();
580  // itHits!=hits.end(); itHits++)
581  // {
582  // sprintf(str,"%f",itHits->x);
583  // xmlOut.addTextElementToParent("xyz_point", str, eventParent);
584  // sprintf(str,"%f",itHits->y);
585  // xmlOut.addTextElementToParent("xyz_point", str, eventParent);
586  // sprintf(str,"%f",itHits->z);
587  // xmlOut.addTextElementToParent("xyz_point", str, eventParent);
588  // //__SUP_COUT__ << "X: " << itHits->x << " Y: " << itHits->y << "
589  // Z:
590  //"
591  //<< itHits->z << __E__;
592  // }
593  // const VisualTracks& tracks = it->getTracks();
594  // for(VisualTracks::const_iterator itTrks=tracks.begin();
595  // itTrks!=tracks.end(); itTrks++)
596  // {
597  // sprintf(str,"%f",itTrks->slopeX);
598  // xmlOut.addTextElementToParent("slope", str, eventParent);
599  // sprintf(str,"%f",itTrks->slopeY);
600  // xmlOut.addTextElementToParent("slope", str, eventParent);
601  // sprintf(str,"%f",itTrks->interceptX);
602  // xmlOut.addTextElementToParent("intcpt", str, eventParent);
603  // sprintf(str,"%f",itTrks->interceptY);
604  // xmlOut.addTextElementToParent("intcpt", str, eventParent);
605  //
606  // }
607  //
608  // }
609  __SUP_COUT__ << "Done hits xml" << __E__;
610  }
611  else if(requestType == "getGeometry")
612  {
613  __SUP_COUT__ << "getGeometry" << __E__;
614 
615  // FIXME -- this crashes when the file doesn't exist!
616  theDataManager_->load("Run1684.geo", "Geometry");
617 
618  __SUP_COUT__ << "getGeometry" << __E__;
619 
620  DOMElement* geometryParent = xmlOut.addTextElementToData("geometry", "");
621  // const Visual3DShapes& shapes =
622  // theDataManager_->getVisual3DGeometry().getShapes();
623  //
624  // __SUP_COUT__ << "getGeometry" << __E__;
625  //
626  //
627  // DOMElement* objectParent;
628  // char str[40];
629  // for(Visual3DShapes::const_iterator itShapes=shapes.begin();
630  // itShapes!=shapes.end(); itShapes++)
631  // {
632  // objectParent = xmlOut.addTextElementToParent("object", str,
633  // geometryParent);
634  // xmlOut.addTextElementToParent("object_type", "LINE_LOOP",
635  // objectParent); sprintf(str,"%d",itShapes->numberOfRows);
636  // xmlOut.addTextElementToParent("object_rows", str, objectParent);
637  // sprintf(str,"%d",itShapes->numberOfColumns);
638  // xmlOut.addTextElementToParent("object_columns", str, objectParent);
639  // for(Points::const_iterator itCorners=itShapes->corners.begin();
640  // itCorners!=itShapes->corners.end(); itCorners++)
641  // {
642  // sprintf(str,"%f",itCorners->x);
643  // xmlOut.addTextElementToParent("xyz_point", str, objectParent);
644  // sprintf(str,"%f",itCorners->y);
645  // xmlOut.addTextElementToParent("xyz_point", str, objectParent);
646  // sprintf(str,"%f",itCorners->z);
647  // xmlOut.addTextElementToParent("xyz_point", str, objectParent);
648  // }
649  // }
650  }
651  else if(requestType == "getRootConfig")
652  {
653  std::string path = CgiDataUtilities::postData(cgiIn, "RootConfigPath");
654  __SUP_COUT__ << "path " << path << __E__;
655 
656  if(path.find("/" + PRE_MADE_ROOT_CFG_DIR + "/") ==
657  0) // ROOT config path must start the path
658  {
659  path = std::string(ROOT_DISPLAY_CONFIG_PATH) + "/" +
660  path.substr(PRE_MADE_ROOT_CFG_DIR.length() + 2);
661  __SUP_COUT__ << "mod path " << path << __E__;
662  }
663 
664  HttpXmlDocument cfgXml;
665  if(cfgXml.loadXmlDocument(path))
666  {
667  xmlOut.addTextElementToData("status", "1");
668  xmlOut.copyDataChildren(cfgXml); // copy file to output xml
669  cfgXml.saveXmlDocument(path);
670  }
671  else
672  xmlOut.addTextElementToData("status",
673  "Failed. File to properly load config file.");
674  }
675  else if(requestType == "rootAdminControls")
676  {
677  // if(userPermissions < ROOT_VIEWER_PERMISSIONS_THRESHOLD)
678  // {
679  // __SUP_COUT__ << "Insufficient permissions for Root Viewer Admin
680  // Controls: " << userPermissions << " < " << ROOT_VIEWER_PERMISSIONS_THRESHOLD <<
681  // __E__;
682  // xmlOut.addTextElementToData("status", "Failed. Insufficient user
683  // permissions.");
684  // }
685  // else
686  // {
687  std::string cmd = cgiIn("cmd"); // possible commands are
688  // mkdir
689  // save
690  // delete
691 
692  std::string path = CgiDataUtilities::postData(cgiIn, "path");
693  std::string name = CgiDataUtilities::postData(cgiIn, "name");
694  __SUP_COUT__ << "cmd " << cmd << __E__;
695  __SUP_COUT__ << "path " << path << __E__;
696  __SUP_COUT__ << "name " << name << __E__;
697 
698  if(path.find("/" + PRE_MADE_ROOT_CFG_DIR + "/") ==
699  0) // ROOT config path must start the path
700  {
701  path = std::string(ROOT_DISPLAY_CONFIG_PATH) + "/" +
702  path.substr(PRE_MADE_ROOT_CFG_DIR.length() + 2) + name;
703  __SUP_COUT__ << "mod path " << path << __E__;
704 
705  if(cmd == "mkdir")
706  {
707  if(mkdir(path.c_str(),
708  S_IRWXU | (S_IRGRP | S_IXGRP) |
709  (S_IROTH | S_IXOTH))) // mode = drwx r-x r-x
710  xmlOut.addTextElementToData("status",
711  "Failed. Directory create rejected.");
712  else
713  xmlOut.addTextElementToData("status", "1"); // success
714  }
715  else if(cmd == "save")
716  {
717  path += PRE_MADE_ROOT_CFG_FILE_EXT; // add file extension
718 
719  bool useRunWildCard =
720  atoi(CgiDataUtilities::postData(cgiIn, "useRunWildCard")
721  .c_str()); // 0 or 1
722  std::string config = CgiDataUtilities::postData(cgiIn, "config");
723  __SUP_COUT__ << "config " << config << __E__;
724  __SUP_COUT__ << "useRunWildCard " << useRunWildCard << __E__;
725 
726  // check if file already exists
727  FILE* fp = fopen(path.c_str(), "r");
728  if(fp)
729  {
730  fclose(fp);
731  xmlOut.addTextElementToData("status", "Failed. File already exists.");
732  __SUP_COUT__ << " Failed. File already exists." << __E__;
733  }
734  else
735  {
736  // dump to file
737  // verify proper format through read back
738  // if successfully loaded, re-save for formatting
739 
740  // dump to file
741  fp = fopen(path.c_str(), "w");
742  fputs(config.c_str(), fp);
743  fclose(fp);
744 
745  // verify proper format through read back
746  HttpXmlDocument cfgXml;
747  if(cfgXml.loadXmlDocument(path))
748  {
749  // successfully loaded, re-save for formatting
750  cfgXml.saveXmlDocument(path);
751  xmlOut.addTextElementToData("status", "1"); // success
752  }
753  else // failed to load properly
754  {
755  xmlOut.addTextElementToData(
756  "status", "Failed. Fatal. Improper file format.");
757  if(remove(path.c_str()) != 0)
758  __SUP_COUT__ << "Failed. Could not remove poorly formed Root "
759  "config file!"
760  << __E__;
761  }
762  }
763  }
764  else if(cmd == "delete")
765  {
766  // guess first directory and then file
767  if(rmdir(path.c_str()) == 0 ||
768  remove((path + PRE_MADE_ROOT_CFG_FILE_EXT).c_str()) == 0)
769  xmlOut.addTextElementToData("status", "1"); // success
770  else
771  xmlOut.addTextElementToData("status",
772  "Failed. Target could not be deleted.");
773  }
774  else
775  xmlOut.addTextElementToData("status", "Failed. Unrecognized command.");
776  }
777  else
778  xmlOut.addTextElementToData("status", "Failed. Invalid path.");
779 
780  //}
781  }
782  else
783  __SUP_COUT__ << "requestType request, " << requestType << ", not recognized."
784  << __E__;
785  // return xml doc holding server response
786  // xmlOut.outputXmlDocument((std::ostringstream*) out, false);
787 }