tdaq-develop-2025-02-12
VisualSupervisorV2.cc
1 #include "otsdaq-utilities/VisualizationV2/VisualSupervisorV2.h"
2 #include "otsdaq/XmlUtilities/XmlDocument.h"
3 // #include "otsdaq-utilities/V2/fileSystemToXML.h"
4 // #include "otsdaq/RootUtilities/DQMHistos.h"
5 #include "otsdaq/DataManager/DataManagerSingleton.h"
6 #include "otsdaq/Macros/BinaryStringMacros.h"
7 // #include "otsdaq/otsdaq/Macros/MessageTools.h"
8 #include <boost/regex.hpp>
9 #include "otsdaq/DataManager/DQMHistosConsumerBase.h"
10 #include "otsdaq/Macros/MessageTools.h"
11 #include "otsdaq/RootUtilities/RootFileExplorer.h"
12 
16 #include <TBranchElement.h>
17 #include <TBuffer.h>
18 #include <TBufferJSON.h>
19 #include <TCanvas.h>
20 #include <TClass.h>
21 #include <TDirectory.h>
22 #include <TFile.h>
23 #include <TH1.h>
24 #include <TH2.h>
25 #include <TIterator.h>
26 #include <TKey.h>
27 #include <TProfile.h>
28 #include <TROOT.h>
29 #include <TRegexp.h>
30 #include <TString.h>
31 #include <TTree.h>
32 #include "TBufferFile.h"
33 #include "TObject.h"
34 
35 #include <dirent.h> /*DIR and dirent*/
36 #include <sys/stat.h> /*mkdir*/
37 
38 #include <xdaq/NamespaceURI.h>
39 
40 #include <fstream>
41 #include <iostream>
42 #include <mutex>
43 
44 #define ROOT_BROWSER_PATH __ENV__("ROOT_BROWSER_PATH")
45 #define ROOT_DISPLAY_CONFIG_PATH __ENV__("ROOT_DISPLAY_CONFIG_PATH")
46 
47 #define LIVEDQM_DIR std::string("LIVE_DQM")
48 #define PRE_MADE_ROOT_CFG_DIR std::string("Pre-made Views")
49 
50 #define PRE_MADE_ROOT_CFG_FILE_EXT std::string(".rcfg")
51 
52 #define PREFERENCES_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/VisualizerV2Data/"
53 #define PREFERENCES_FILE_EXT ".pref"
54 
55 #define ROOT_VIEWER_PERMISSIONS_THRESHOLD 100
56 
57 using namespace ots;
58 
59 #undef __MF_SUBJECT__
60 #define __MF_SUBJECT__ "VisualizerV2"
61 
62 XDAQ_INSTANTIATOR_IMPL(VisualSupervisorV2)
63 
64 #undef STDLINE
65 #define STDLINE(X, Y) __COUT__ << X
66 
67 //==============================================================================
68 VisualSupervisorV2::VisualSupervisorV2(xdaq::ApplicationStub* stub)
69  : CoreSupervisorBase(stub), theDataManager_(nullptr), loadedRunNumber_(-1)
70 {
71  __SUP_COUT__ << "Constructor." << __E__;
72  INIT_MF("VisualSupervisorV2");
73 
74  mkdir(((std::string)PREFERENCES_PATH).c_str(), 0755);
75 
76  __SUP_COUT__ << "Constructed." << __E__;
77 } // end constructor
78 
79 //========================================================================================================================
80 VisualSupervisorV2::~VisualSupervisorV2(void)
81 {
82  __SUP_COUT__ << "Destructor." << __E__;
83  destroy();
84  __SUP_COUT__ << "Destructed." << __E__;
85 } // end destructor
86 
87 //========================================================================================================================
88 void VisualSupervisorV2::destroy(void)
89 {
90  __SUP_COUT__ << "Destroying..." << __E__;
91 
92  DataManagerSingleton::deleteInstance(CorePropertySupervisorBase::getSupervisorUID());
93  if(theStateMachineImplementation_.size() > 1)
94  {
95  __SS__ << "Not expecting more than one visual data manager!" << __E__;
96  __SS_THROW__;
97  }
98  if(theStateMachineImplementation_.size())
99  theStateMachineImplementation_.pop_back();
100  else
101  __COUT_WARN__ << "No visual data manager was pushed." << __E__;
102 } // end destroy()
103 
104 //==============================================================================
105 void VisualSupervisorV2::transitionConfiguring(toolbox::Event::Reference /*e*/)
106 {
107  __SUP_COUT__ << "Configuring..." << __E__;
108 
109  { // do like start of CoreSupervisorBase::transitionConfiguring
110  // activate the configuration tree (the first iteration)
111  if(RunControlStateMachine::getIterationIndex() == 0 &&
112  RunControlStateMachine::getSubIterationIndex() == 0)
113  {
114  std::pair<std::string /*group name*/, TableGroupKey> theGroup(
115  SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
116  .getParameters()
117  .getValue("ConfigurationTableGroupName"),
118  TableGroupKey(
119  SOAPUtilities::translate(theStateMachine_.getCurrentMessage())
120  .getParameters()
121  .getValue("ConfigurationTableGroupKey")));
122 
123  __SUP_COUT__ << "Configuration table group name: " << theGroup.first
124  << " key: " << theGroup.second << __E__;
125 
126  //disable version tracking to accept untracked versions to be selected by the FSM transition source
127  theConfigurationManager_->loadTableGroup(
128  theGroup.first,
129  theGroup.second,
130  true /*doActivate*/,
131  0,
132  0,
133  0,
134  0,
135  0,
136  0,
137  false,
138  0,
139  0,
140  ConfigurationManager::LoadGroupType::ALL_TYPES,
141  true /*ignoreVersionTracking*/);
142  }
143  } // end start like CoreSupervisorBase::transitionConfiguring
144 
145  __COUTV__(theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)->getTableName());
146  __COUTV__(theConfigurationManager_
147  ->getNode(theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)
148  ->getTableName())
149  .getValueAsString());
150 
151  __COUTV__("/" +
152  theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)->getTableName() +
153  CorePropertySupervisorBase::getSupervisorConfigurationPath());
154 
155  ConfigurationTree appLink = theConfigurationManager_->getNode(
156  "/" + theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)->getTableName() +
157  CorePropertySupervisorBase::getSupervisorConfigurationPath());
158 
159  __COUTV__(appLink.getValueAsString());
160 
161  if(!appLink.isDisconnected())
162  {
163  theDataManager_ = DataManagerSingleton::getInstance<VisualDataManagerV2>(
164  theConfigurationManager_->getNode(
165  theConfigurationManager_->__GET_CONFIG__(XDAQContextTable)
166  ->getTableName()),
167  CorePropertySupervisorBase::getSupervisorConfigurationPath(),
168  CorePropertySupervisorBase::getSupervisorUID());
169 
170  CoreSupervisorBase::theStateMachineImplementation_.push_back(theDataManager_);
171 
172  __SUP_COUT__ << "Done instantiating Visual data manager." << __E__;
173  }
174  else
175  __SUP_COUT__ << "No Visual Supervisor configuration link, so skipping Visual "
176  "data manager instantiation."
177  << __E__;
178 
179  // just handle FSMs
180  CoreSupervisorBase::transitionConfiguringFSMs();
181 
182  __SUP_COUT__ << "Configured." << __E__;
183 } // end transitionConfiguring()
184 
185 //==============================================================================
186 void VisualSupervisorV2::transitionHalting(toolbox::Event::Reference e)
187 {
188  __SUP_COUT__ << "Halting..." << __E__;
189 
190  CoreSupervisorBase::transitionHalting(e);
191  destroy();
192 
193  __SUP_COUT__ << "Halted." << __E__;
194 } // end transitionHalting()
195 
196 //==============================================================================
201 {
202  CorePropertySupervisorBase::setSupervisorProperty(
203  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AllowNoLoginRequestTypes,
204  "setUserPreferences | getUserPreferences | getDirectoryContents | getRoot | "
205  "getEvents");
206 
207  CorePropertySupervisorBase::setSupervisorProperty(
208  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
209  "*=1 | rootAdminControls=100");
210 }
211 
212 //========================================================================================================================
216 {
217  CorePropertySupervisorBase::setSupervisorProperty(
218  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
219  "getRoot | getEvents");
220  CorePropertySupervisorBase::setSupervisorProperty(
221  CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.NoXmlWhiteSpaceRequestTypes,
222  "getRoot | getEvents");
223  // Note: json data in ROOTJS library expects no funny characters
224 }
225 
226 //========================================================================================================================
227 void VisualSupervisorV2::request(const std::string& requestType,
228  cgicc::Cgicc& cgiIn,
229  HttpXmlDocument& xmlOut,
230  const WebUsers::RequestUserInfo& userInfo)
231 {
232  // Commands
233  // getRawData
234  // getGeometry
235  // getEvents
236  // getRoot
237  // getDirectoryContents
238  // setUserPreferences
239  // getUserPreference
240 
241  // if (requestType == "getHisto" && theDataManager_->getLiveDQMHistos() != 0)
242  // {
243  // // TH1I* histo =
244  // (TH1I*)theDataManager_->getLiveDQMHistos()->get("Planes/Plane_0_Occupancy");
245  //
246  // // theDataManager_->load("Run185_Histo.root","Histograms");
247  // //TH1F* histo1d = theDataManager_->getFileDQMHistos().getHisto1D();
248  // //TCanvas* canvas = theDataManager_->getFileDQMHistos().getCanvas ();
249  // //TH2F* histo2d = theDataManager_->getFileDQMHistos().getHisto2D();
250  // //TProfile* profile = theDataManager_->getFileDQMHistos().getProfile();
251  //
252  // }
253  // std::stringstream ss;
254  // ss << "Request type: |" << requestType << "|";
255  // STDLINE(ss.str(),"") ;
256  if(requestType ==
257  "getRawData") // ################################################################################################################
258  {
259  __SUP_COUT__ << __E__;
260  try
261  {
262  // TODO -- add timestamp, so we know if data is new
263 
264  if(theDataManager_ == nullptr)
265  {
266  __SS__ << "No data manager instantiated." << __E__;
267  __SS_THROW__;
268  }
269  __SUP_COUT__ << "Getting Raw data and converting to binary string" << __E__;
270  xmlOut.addBinaryStringToData("rawData", theDataManager_->getRawData());
271  __SUP_COUT__ << __E__;
272  }
273  catch(std::exception const& e)
274  {
275  __SUP_COUT__
276  << "ERROR! Exception while getting raw data. Incoming exception data..."
277  << __E__;
278  __SUP_COUT__ << e.what() << __E__;
279  __SUP_COUT__ << "End Exception Data" << __E__;
280  }
281  catch(...)
282  {
283  __SUP_COUT__ << "ERROR! Something went wrong trying to get raw data."
284  << __E__;
285  try
286  {
287  throw;
288  } //one more try to printout extra info
289  catch(const std::exception& e)
290  {
291  __SUP_COUT_ERR__ << "Exception message: " << e.what();
292  }
293  catch(...)
294  {
295  }
296  __SUP_COUT_INFO__ << "ERROR! Something went wrong trying to get raw data."
297  << __E__;
298  }
299  }
300  else if(
301  requestType == "setUserPreferences" &&
302  userInfo.username_ !=
303  "" /*from allow no user*/) // ################################################################################################################
304  {
305  __SUP_COUT__ << "userInfo.username_: " << userInfo.username_ << __E__;
306  std::string fullPath =
307  (std::string)PREFERENCES_PATH + userInfo.username_ + PREFERENCES_FILE_EXT;
308  __SUP_COUT__ << "fullPath: " << fullPath << __E__;
309 
310  std::string radioSelect = CgiDataUtilities::getData(cgiIn, "radioSelect");
311  std::string autoRefresh = CgiDataUtilities::getData(cgiIn, "autoRefresh");
312  std::string autoHide = CgiDataUtilities::getData(cgiIn, "autoHide");
313  std::string hardRefresh = CgiDataUtilities::getData(cgiIn, "hardRefresh");
314  std::string autoRefreshPeriod =
315  CgiDataUtilities::getData(cgiIn, "autoRefreshPeriod");
316 
317  __SUP_COUT__ << "radioSelect: " << radioSelect << __E__;
318  __SUP_COUT__ << "autoRefresh: " << autoRefresh << __E__;
319  __SUP_COUT__ << "autoHide: " << autoHide << __E__;
320  __SUP_COUT__ << "hardRefresh: " << hardRefresh << __E__;
321  __SUP_COUT__ << "autoRefreshPeriod: " << autoRefreshPeriod << __E__;
322 
323  // read existing
324  FILE* fp = fopen(fullPath.c_str(), "r");
325  if(fp)
326  {
327  char line[100];
328  char val[100];
329 
330  fgets(line, 100, fp);
331  sscanf(line, "%*s %s", val);
332  if(radioSelect == "")
333  radioSelect = val;
334 
335  fgets(line, 100, fp);
336  sscanf(line, "%*s %s", val);
337  if(autoRefresh == "")
338  autoRefresh = val;
339 
340  fgets(line, 100, fp);
341  sscanf(line, "%*s %s", val);
342  if(autoHide == "")
343  autoHide = val;
344 
345  fgets(line, 100, fp);
346  sscanf(line, "%*s %s", val);
347  if(hardRefresh == "")
348  hardRefresh = val;
349 
350  fgets(line, 100, fp);
351  sscanf(line, "%*s %s", val);
352  if(autoRefreshPeriod == "")
353  autoRefreshPeriod = val;
354 
355  fclose(fp);
356  }
357 
358  // write new
359  fp = fopen(fullPath.c_str(), "w");
360  if(fp)
361  {
362  fprintf(fp, "radioSelect %s\n", radioSelect.c_str());
363  fprintf(fp, "autoRefresh %s\n", autoRefresh.c_str());
364  fprintf(fp, "autoHide %s\n", autoHide.c_str());
365  fprintf(fp, "hardRefresh %s\n", hardRefresh.c_str());
366  fprintf(fp, "autoRefreshPeriod %s\n", autoRefreshPeriod.c_str());
367  fclose(fp);
368  }
369  else
370  __SUP_COUT_ERR__ << "Failure writing preferences to file: " << fullPath
371  << __E__;
372  }
373  else if(
374  requestType ==
375  "getUserPreferences") // ################################################################################################################
376  {
377  __SUP_COUT__ << "userInfo.username_: " << userInfo.username_ << __E__;
378  std::string fullPath =
379  (std::string)PREFERENCES_PATH + userInfo.username_ + PREFERENCES_FILE_EXT;
380  __SUP_COUT__ << "fullPath: " << fullPath << __E__;
381 
382  FILE* fp = fopen(fullPath.c_str(), "r");
383  if(fp)
384  {
385  char line[100];
386  // char val[100];
387  int val;
388 
389  fgets(line, 100, fp);
390  sscanf(line, "%*s %d", &val);
391  if(val < 0 || val > 3)
392  val = 0; // FIXME.. value can get corrupt...
393  xmlOut.addTextElementToData("radioSelect", std::to_string(val));
394  fgets(line, 100, fp);
395  sscanf(line, "%*s %d", &val);
396  xmlOut.addTextElementToData("autoRefresh", std::to_string(val));
397  fgets(line, 100, fp);
398  sscanf(line, "%*s %d", &val);
399  xmlOut.addTextElementToData("autoHide", std::to_string(val));
400  fgets(line, 100, fp);
401  sscanf(line, "%*s %d", &val);
402  xmlOut.addTextElementToData("hardRefresh", std::to_string(val));
403  fgets(line, 100, fp);
404  sscanf(line, "%*s %d", &val);
405  xmlOut.addTextElementToData("autoRefreshPeriod", std::to_string(val));
406  fclose(fp);
407  }
408  else
409  {
410  // else assume user has no preferences yet
411  xmlOut.addTextElementToData("radioSelect", "");
412  xmlOut.addTextElementToData("autoRefresh", "");
413  xmlOut.addTextElementToData("autoHide", "");
414  xmlOut.addTextElementToData("hardRefresh", "");
415  xmlOut.addTextElementToData("autoRefreshPeriod", "");
416  }
417  }
418  else if(
419  requestType ==
420  "getDirectoryContents") // ################################################################################################################
421  {
422  // return directory structure for requested path, types are "dir" and "file"
423 
424  std::string rootpath = std::string(ROOT_BROWSER_PATH) + "/";
425  std::string path = CgiDataUtilities::postData(cgiIn, "Path");
426  boost::regex re("%2F");
427  path = boost::regex_replace(path, re, "/"); // Dario: should be transparent for
428  // Ryan's purposes but required by Extjs
429 
432 
433  // return 1 if user has access to admin controls, else 0
434  char permStr[10];
435  sprintf(permStr,
436  "%d",
437  userInfo.permissionLevel_ >=
438  CoreSupervisorBase::getSupervisorPropertyUserPermissionsThreshold(
439  "rootAdminControls"));
440  xmlOut.addTextElementToData("permissions", permStr); // add permissions
443 
444  std::string dirpath = rootpath + path;
445  if(path == "/" + PRE_MADE_ROOT_CFG_DIR + "/")
446  dirpath = ROOT_DISPLAY_CONFIG_PATH;
447 
448  if(path.find("/" + PRE_MADE_ROOT_CFG_DIR + "/") ==
449  0) // ROOT config path must start the path
450  dirpath = std::string(ROOT_DISPLAY_CONFIG_PATH) + "/" +
451  path.substr(PRE_MADE_ROOT_CFG_DIR.length() + 2);
452 
454  __SUP_COUT__ << "full path: " << dirpath << __E__;
455 
456  DIR* pDIR;
457  struct dirent* entry;
458  bool isNotRtCfg;
459  bool isDir;
460  if((pDIR = opendir(dirpath.c_str())))
461  {
462  xmlOut.addTextElementToData("path", path);
463  xmlOut.addTextElementToData("headOfSearch", "located");
464 
465  // add LIVE if path is / and DQM is active
466  // add Pre-made Views if path is / and ROOT_DISPLAY_CONFIG_PATH isnt already
467  // there
468  if(path == "/")
469  {
471  if(theDataManager_ != nullptr && theDataManager_->getLiveDQMHistos() != 0)
472  xmlOut.addTextElementToData("dir",
473  LIVEDQM_DIR + ".root"); // add to xml
474 
475  // check for ROOT_DISPLAY_CONFIG_PATH
476  DIR* pRtDIR = opendir(ROOT_DISPLAY_CONFIG_PATH);
477  bool recheck = false;
478  if(!pRtDIR) // if doesn't exist, make it
479  {
480  recheck = true;
481  if(mkdir(ROOT_DISPLAY_CONFIG_PATH,
482  S_IRWXU | (S_IRGRP | S_IXGRP) |
483  (S_IROTH | S_IXOTH))) // mode = drwx r-x r-x
484  __SUP_COUT__ << "Failed to make directory for pre made views: "
485  << ROOT_DISPLAY_CONFIG_PATH << __E__;
486  }
487  else
488  closedir(pRtDIR); // else close and display
489 
490  if(!recheck || (pRtDIR = opendir(ROOT_DISPLAY_CONFIG_PATH)))
491  {
494  xmlOut.addTextElementToData("dir",
495  PRE_MADE_ROOT_CFG_DIR); // add to xml
496  if(recheck)
497  closedir(pRtDIR);
498  }
499  }
501  while((entry = readdir(pDIR)))
502  {
503  //__SUP_COUT__ << int(entry->d_type) << " " << entry->d_name << "\n" <<
504  // __E__;
505  if(entry->d_name[0] != '.' &&
506  (entry->d_type ==
507  0 || // 0 == UNKNOWN (which can happen - seen in SL7 VM)
508  entry->d_type == 4 ||
509  entry->d_type == 8))
510  {
511  //__SUP_COUT__ << int(entry->d_type) << " " << entry->d_name << "\n"
512  //<< __E__;
513  isNotRtCfg =
514  std::string(entry->d_name).find(".rcfg") == std::string::npos;
515  isDir = false;
516 
517  if(entry->d_type == 0)
518  {
519  // unknown type .. determine if directory
521  DIR* pTmpDIR = opendir((dirpath + entry->d_name).c_str());
522  if(pTmpDIR)
523  {
525  isDir = true;
526  closedir(pTmpDIR);
527  }
528  // else //assume file
529  }
530 
531  if((entry->d_type == 8 ||
532  (!isDir && entry->d_type == 0)) // file type
533  && std::string(entry->d_name).find(".root") == std::string::npos &&
534  isNotRtCfg)
535  continue; // skip if not a root file or a config file
536  else if(entry->d_type == 4)
537  isDir = true; // flag directory types
538 
539  xmlOut.addTextElementToData(
540  isDir ? "dir" : (isNotRtCfg ? "dir" : "file"), entry->d_name);
541  }
542  }
543  closedir(pDIR);
544  }
545  else
546  __SUP_COUT__ << "Failed to access directory contents!" << __E__;
547  // std::ostringstream* out ;
548  // xmlOut.outputXmlDocument((std::ostringstream*) out, true);
549  }
550  else if(
551  requestType ==
552  "getRoot") // ################################################################################################################
553  {
554  // return directory structure for requested ROOT path, types are "dir" and "file"
555 
556  ss.str("");
557  ss << "PID: " << ::getpid();
558  // STDLINE(ss.str(),ACCyan) ;
559  std::string path = CgiDataUtilities::postData(cgiIn, "RootPath");
560  boost::regex re1("%2F");
561  path = boost::regex_replace(
562  path, re1, "/"); // Dario: should be transparent for Ryan's purposes but
563  // required by Extjs
564  boost::regex re2("%20");
565  path = boost::regex_replace(
566  path, re2, " "); // Dario: should be transparent for Ryan's purposes but
567  // required by Extjs
568  boost::regex re3("%3A");
569  path = boost::regex_replace(path, re3, ""); // Dario: should be transparent for
570  // Ryan's purposes but required by Extjs
571  ss.str("");
572  ss << "path : " << path;
573  STDLINE(ss.str(), ACCyan);
574  std::string fullPath = std::string(__ENV__("ROOT_BROWSER_PATH")) + path;
575  ss.str("");
576  ss << "fullPath: " << fullPath;
577  STDLINE(ss.str(), "");
578 
579  __SUP_COUTV__(fullPath);
580 
581  const size_t rootExtensionStart = fullPath.find(".root");
582  const size_t rootExtensionEnd = rootExtensionStart + std::string(".root").size();
583 
584  std::string rootFileName = fullPath.substr(0, rootExtensionEnd);
585 
586  __SUP_COUTV__(rootFileName);
587  std::string rootDirectoryName =
588  rootFileName + ":" +
589  fullPath.substr(rootExtensionEnd, fullPath.size() - rootExtensionEnd + 1);
590 
591  __SUP_COUTV__(rootDirectoryName);
592  std::string::size_type LDQM_pos = path.find("/" + LIVEDQM_DIR + ".root/");
593  __SUP_COUTV__(LDQM_pos);
594  TFile* rootFile = nullptr;
595  if(LDQM_pos == std::string::npos) // If it is not from LIVE_DQM
596  {
597  __SUP_COUTV__(rootFileName);
598  rootFile = TFile::Open(rootFileName.c_str());
599 
600  if(rootFile == nullptr || !rootFile->IsOpen())
601  {
602  __SUP_SS__ << "Failed to access ROOT file: " << rootFileName << __E__;
603  __SUP_SS_THROW__;
604  }
605  }
606  else
607  {
608  if(theDataManager_ != nullptr &&
609  theDataManager_->getLiveDQMHistos() != nullptr)
610  {
611  __SUP_COUT__ << "Attempting to get LIVE ROOT object." << __E__;
612  __SUP_COUTV__(rootDirectoryName);
613  rootDirectoryName = path.substr(("/" + LIVEDQM_DIR + ".root").length());
614  __SUP_COUTV__(rootDirectoryName);
615  rootFile = theDataManager_->getLiveDQMHistos()->getFile();
616 
617  __SUP_COUT__ << "LIVE file name: " << rootFile->GetName() << __E__;
618 
619  if(rootFile == nullptr || !rootFile->IsOpen())
620  {
621  __SUP_SS__ << "Failed to access LIVE ROOT file: " << rootFileName
622  << __E__;
623  __SUP_COUT__ << ss.str();
624  xmlOut.addTextElementToData("Warning", ss.str());
625  return; // do not treat LIVE root file missing as error, .. assume
626  // just not Running
627  }
628  }
629  else
630  {
631  __SUP_SS__ << "Failed to access LIVE ROOT file: " << rootFileName
632  << __E__;
633  __SUP_COUT__ << ss.str();
634  xmlOut.addTextElementToData("Warning", ss.str());
635  return; // do not treat LIVE root file missing as error, .. assume just
636  // not Running
637  }
638  }
639 
640  // at this point initial ROOT object has been successfully opened
641 
642  xmlOut.addTextElementToData("path", path);
643  STDLINE(string("######## getting directory from ") + rootDirectoryName, "");
644  TDirectory* directory = rootFile->GetDirectory(rootDirectoryName.c_str());
645  TObject* tobject = nullptr;
646 
647  if(!directory) // if not directory yet, peak at object for TTree or
648  // TBranchElement with children
649  {
650  // if TTree or TBranchElement with children, then treat as a directory
651  // else if TBranchElement without children, then treat as leaf ROOT object
652 
653  rootDirectoryName = fullPath.substr(
654  rootExtensionEnd); // re-purpose rootDirectoryName as path within TTree
655 
656  std::vector<std::string> splitTTreePath =
657  StringMacros::getVectorFromString(rootDirectoryName, {'/'});
658  __SUP_COUTV__(StringMacros::vectorToString(splitTTreePath));
659 
660  unsigned int spliti = 0;
661  while(spliti < splitTTreePath.size() && splitTTreePath[spliti].size() == 0)
662  ++spliti; // search for first non-empty
663 
664  if(spliti < splitTTreePath.size())
665  {
666  __SUP_COUTV__(splitTTreePath[spliti]);
667  tobject = (TObject*)rootFile->Get(splitTTreePath[spliti].c_str());
668  ++spliti; // search for next non-empty
669  }
670 
671  if(tobject == nullptr)
672  {
673  __SUP_SS__ << "Failed to access ROOT sub path: " << rootDirectoryName
674  << __E__;
675  __SUP_SS_THROW__;
676  }
677  __SUP_COUTV__(tobject->ClassName());
678 
679  if(std::string(tobject->ClassName()) == "TTree" ||
680  std::string(tobject->ClassName()).find("TBranch") !=
681  std::string::npos || // == "TBranchElement" ||
682  std::string(tobject->ClassName()).find("TDirectory") != std::string::npos)
683  {
684  // continue traversing name split
685  do
686  {
687  while(spliti < splitTTreePath.size() &&
688  splitTTreePath[spliti].size() == 0)
689  ++spliti; // search for next non-empty
690  if(spliti >= splitTTreePath.size())
691  break; // reached end of traversal!
692 
693  __SUP_COUTV__(splitTTreePath[spliti]);
694  __SUP_COUT__ << "Parent class = " << (tobject->ClassName()) << __E__;
695  if(std::string(tobject->ClassName()) == "TTree")
696  tobject = (TObject*)((TTree*)tobject)
697  ->GetBranch(splitTTreePath[spliti].c_str());
698  else if(std::string(tobject->ClassName()).find("TBranch") !=
699  std::string::npos)
700  tobject = (TObject*)((TBranchElement*)tobject)
701  ->FindBranch(splitTTreePath[spliti].c_str());
702  else if(std::string(tobject->ClassName()).find("TDirectory") !=
703  std::string::npos)
704  tobject = (TObject*)((TDirectoryFile*)tobject)
705  ->Get(splitTTreePath[spliti].c_str());
706 
707  ++spliti; // search for next non-empty
708  } while(tobject);
709 
710  if(tobject == nullptr)
711  {
712  __SUP_SS__ << "Failed to access root sub path: " << rootDirectoryName
713  << __E__;
714  __SUP_SS_THROW__;
715  }
716 
717  __SUP_COUTV__(tobject->ClassName());
718 
719  // now at path's target element with tobject
720  // if no branches, then "file" and tobject stringified
721  // else "dir"
722 
723  TObjArray* objects = nullptr;
724 
725  if(std::string(tobject->ClassName()) == "TTree")
726  objects = ((TTree*)tobject)->GetListOfBranches();
727  else if(std::string(tobject->ClassName()).find("TBranch") !=
728  std::string::npos) //== "TBranchElement")
729  objects = ((TBranchElement*)tobject)->GetListOfBranches();
730 
731  if(objects != nullptr && !objects->IsEmpty())
732  {
733  __SUP_COUT__ << "Handling as TTree/TBranchElement directory" << __E__;
734 
735  // treat like a directory, and return branches
736  TObject* obj;
737  TIter nextobj(objects->MakeIterator());
738  TRegexp re("*", kTRUE);
739  while((obj = (TObject*)nextobj()))
740  {
741  std::string name = obj->GetName();
742  TString s = name;
743  if(s.Index(re) == kNPOS)
744  continue;
745 
746  __SUP_COUT__ << "Child class Name: " << obj->IsA()->GetName()
747  << " " << name << __E__;
748 
749  if(std::string(obj->IsA()->GetName()).find("TBranch") !=
750  std::string::npos) // == "TBranchElement")
751  {
752  // decide if leave based on children branches
753  __SUP_COUT__
754  << "Child '" << name << "' of type '"
755  << ((TBranchElement*)obj)->GetTypeName() << "' isLeaf="
756  << ((TBranchElement*)obj)->GetListOfBranches()->IsEmpty()
757  << __E__;
758 
759  xmlOut.addTextElementToData(
760  (((TBranchElement*)obj)->GetListOfBranches()->IsEmpty())
761  ? "file"
762  : "dir",
763  name);
764  }
765  else // handle normal way
766  {
767  xmlOut.addTextElementToData(
768  (std::string(obj->IsA()->GetName()).find("Directory") !=
769  std::string::npos ||
770  std::string(obj->IsA()->GetName()) == "TTree")
771  ? "dir"
772  : "file",
773  name);
774  }
775  }
776  return;
777  } // done handling TTree branches
778  } // end TTree and branch handling
779  else if(spliti < splitTTreePath.size())
780  {
781  __COUTV__(rootDirectoryName);
782  // if more name to mystery object (likely TDirectoryFile), then attempt to
783  // get full subpath
784  tobject = (TObject*)rootFile->Get(rootDirectoryName.c_str());
785  }
786 
787  // at this point have tobject to stringify
788  } // peaking for TTree
789 
790  if(directory == nullptr)
791  {
792  __SUP_COUT__ << "This is not a directory!" << __E__;
793 
794  if(tobject == nullptr)
795  {
796  __SUP_SS__
797  << "Something is wrong. Failed to access ROOT TObject at path: "
798  << fullPath << __E__;
799  __SUP_SS_THROW__;
800  }
801 
802  // TObject* tobjectClone = nullptr;
803 
804  if(tobject != nullptr) // turns out was a root object path
805  {
806  // ignore lock, because Lore says only crashed with Canvas
807 
808  // FIXME -- check this new histo and gDirectory->Get for memory leak!
809  bool doJSONobject = false;
810  TH1F* h8 = nullptr;
811  std::string tmpClassName = tobject->ClassName();
812  if(tmpClassName.find("TBranch") != std::string::npos)
813  {
814  __COUT__ << "Attempting to plot '" << tobject->ClassName()
815  << "' type." << __E__;
816 
817  h8 = new TH1F();
818  TTree* t3 = ((TBranch*)tobject)->GetTree();
819  //__COUT__ << "Attempting to plot '" << t3 << "' type." << __E__;
820  //__COUT__ << "JSON=" << TBufferJSON::ConvertToJSON(h8).Data() <<
821  //__E__;
822  t3->Draw("Value>>h8", "", "goff");
823  tobject = gDirectory->Get("h8");
824 
825  __COUT__ << "Attempting to plot '" << tobject->ClassName()
826  << "' type." << __E__;
827  doJSONobject = true;
828  }
829 
830  TString json;
831  TBufferFile tBuffer(TBuffer::kWrite);
832  if(theDataManager_ != nullptr &&
833  theDataManager_->getLiveDQMHistos() != nullptr && LDQM_pos == 0)
834  {
835  if(tobject->IsA() == TCanvas::Class())
836  {
837  static_cast<TCanvas*>(tobject)->Modified();
838  static_cast<TCanvas*>(tobject)->Update();
839  }
840  std::unique_lock<std::mutex> lock(
841  static_cast<DQMHistosConsumerBase*>(
842  theDataManager_->getLiveDQMHistos())
843  ->getFillHistoMutex());
844  if(std::string(tobject->ClassName()) == "TCanvas")
845  {
846  // tobject->Draw();
847  //__SUP_COUT__ << "Updating canvas!" << __E__;
848  dynamic_cast<TCanvas*>(tobject)->Update();
849  dynamic_cast<TCanvas*>(tobject)->Modified();
850  }
851  json = TBufferJSON::ConvertToJSON(tobject);
852  tobject->Streamer(tBuffer);
853  // __SUP_COUT__ << json.Data() << __E__;
854  }
855  else
856  {
857  // No need to lock from file!
858  json = TBufferJSON::ConvertToJSON(tobject);
859  tobject->Streamer(tBuffer);
860  }
861 
862  std::string hexString = BinaryStringMacros::binaryStringToHexString(
863  tBuffer.Buffer(), tBuffer.Length());
864 
865  //__SUP_COUT__ << "Returning object '" << tobject->GetName()
866  // << "' of class '" << tobject->ClassName() << __E__;
867 
868  xmlOut.addTextElementToData("rootType",
869  doJSONobject ? "JSON" : tobject->ClassName());
870  xmlOut.addTextElementToData("rootData", hexString);
871  xmlOut.addTextElementToData("rootJSON", json.Data());
872 
873  if(h8 != nullptr)
874  delete h8;
875  }
876  else
877  __SUP_COUT_ERR__ << "Failed to access:-" << rootDirectoryName << "-"
878  << __E__;
879  STDLINE("Done with it!", ACBlue);
880  }
881  else // handle as directory
882  {
883  __SUP_COUT__ << "directory found getting the content!" << __E__;
884  STDLINE("Directory found getting the content!", ACGreen);
885  TRegexp re("*", kTRUE);
886  if(LDQM_pos == 0)
887  {
888  TObject* obj;
889  TIter nextobj(directory->GetList());
890  while((obj = (TObject*)nextobj()))
891  {
892  TString s = obj->GetName();
893  if(s.Index(re) == kNPOS)
894  continue;
895  __SUP_COUT__ << "Class Name: " << obj->IsA()->GetName() << __E__;
896 
897  xmlOut.addTextElementToData(
898  (std::string(obj->IsA()->GetName()).find("Directory") !=
899  std::string::npos ||
900  std::string(obj->IsA()->GetName()) == "TTree" ||
901  std::string(obj->IsA()->GetName()).find("TBranch") !=
902  std::string::npos) // == "TBranchElement")
903  ? "dir"
904  : "file",
905  obj->GetName());
906  // ss.str("") ; ss << "obj->GetName(): " << obj->GetName() ;
907  // //STDLINE(ss.str(),"") ;
908  }
909  }
910  else
911  {
912  TKey* key;
913  TIter next(directory->GetListOfKeys());
914  while((key = (TKey*)next()))
915  {
916  TString s = key->GetName();
917  if(s.Index(re) == kNPOS)
918  continue;
919  __SUP_COUT__ << "Class Name: " << key->GetClassName() << __E__;
920  xmlOut.addTextElementToData(
921  (std::string(key->GetClassName()).find("Directory") !=
922  std::string::npos ||
923  std::string(key->GetClassName()) == "TTree" ||
924  std::string(key->GetClassName()).find("TBranch") !=
925  std::string::npos) // == "TBranchElement")
926  ? "dir"
927  : "file",
928  key->GetName());
929  // ss.str("") ; ss << "key->GetName(): " << key->GetName() ;
931  }
932  }
933  }
934  if(LDQM_pos == std::string::npos)
935  rootFile->Close();
936 
937  } // end getRoot handling
938  else if(
939  requestType ==
940  "getEvents") // ################################################################################################################
941  {
942  if(theDataManager_ == nullptr)
943  {
944  __SS__ << "No Data Manager instantiated." << __E__;
945  __SS_THROW__;
946  }
947 
948  int Run = atoi(cgiIn("run").c_str());
949 
950  __SUP_COUT__ << "getEvents for run " << Run << __E__;
951 
952  if(Run != (int)loadedRunNumber_ || loadedRunNumber_ == (unsigned int)-1)
953  {
954  theDataManager_->load("Run1684.root", "Monicelli");
955  loadedRunNumber_ = Run;
956  }
957 
958  /*DOMElement* eventsParent =*/xmlOut.addTextElementToData("events", "");
959  // DOMElement* eventParent;
960  // char str[40];
961 
962  // const Visual3DEvents& events = theDataManager_->getVisual3DEvents();
963  // __SUP_COUT__ << "Preparing hits xml" << __E__;
964  // int numberOfEvents = 0;
965  // for(Visual3DEvents::const_iterator it=events.begin(); it!=events.end() &&
966  // numberOfEvents < 10000; it++, numberOfEvents++)
967  // {
968  // //__SUP_COUT__ << "Event: " << numberOfEvents << __E__;
969  // eventParent = xmlOut.addTextElementToParent("event", str,
970  // eventsParent); const VisualHits& hits = it->getHits();
971  // for(VisualHits::const_iterator itHits=hits.begin();
972  // itHits!=hits.end(); itHits++)
973  // {
974  // sprintf(str,"%f",itHits->x);
975  // xmlOut.addTextElementToParent("xyz_point", str, eventParent);
976  // sprintf(str,"%f",itHits->y);
977  // xmlOut.addTextElementToParent("xyz_point", str, eventParent);
978  // sprintf(str,"%f",itHits->z);
979  // xmlOut.addTextElementToParent("xyz_point", str, eventParent);
980  // //__SUP_COUT__ << "X: " << itHits->x << " Y: " << itHits->y << "
981  // Z:
982  //"
983  //<< itHits->z << __E__;
984  // }
985  // const VisualTracks& tracks = it->getTracks();
986  // for(VisualTracks::const_iterator itTrks=tracks.begin();
987  // itTrks!=tracks.end(); itTrks++)
988  // {
989  // sprintf(str,"%f",itTrks->slopeX);
990  // xmlOut.addTextElementToParent("slope", str, eventParent);
991  // sprintf(str,"%f",itTrks->slopeY);
992  // xmlOut.addTextElementToParent("slope", str, eventParent);
993  // sprintf(str,"%f",itTrks->interceptX);
994  // xmlOut.addTextElementToParent("intcpt", str, eventParent);
995  // sprintf(str,"%f",itTrks->interceptY);
996  // xmlOut.addTextElementToParent("intcpt", str, eventParent);
997  //
998  // }
999  //
1000  // }
1001  __SUP_COUT__ << "Done hits xml" << __E__;
1002  }
1003  else if(
1004  requestType ==
1005  "getGeometry") // ################################################################################################################
1006  {
1007  __SUP_COUT__ << "getGeometry" << __E__;
1008 
1009  if(theDataManager_ == nullptr)
1010  {
1011  __SS__ << "No Data Manager instantiated." << __E__;
1012  __SS_THROW__;
1013  }
1014 
1015  // FIXME -- this crashes when the file doesn't exist!
1016  theDataManager_->load("Run1684.geo", "Geometry");
1017 
1018  __SUP_COUT__ << "getGeometry" << __E__;
1019 
1020  /*DOMElement* geometryParent =*/xmlOut.addTextElementToData("geometry", "");
1021  // const Visual3DShapes& shapes =
1022  // theDataManager_->getVisual3DGeometry().getShapes();
1023  //
1024  // __SUP_COUT__ << "getGeometry" << __E__;
1025  //
1026  //
1027  // DOMElement* objectParent;
1028  // char str[40];
1029  // for(Visual3DShapes::const_iterator itShapes=shapes.begin();
1030  // itShapes!=shapes.end(); itShapes++)
1031  // {
1032  // objectParent = xmlOut.addTextElementToParent("object", str,
1033  // geometryParent);
1034  // xmlOut.addTextElementToParent("object_type", "LINE_LOOP",
1035  // objectParent); sprintf(str,"%d",itShapes->numberOfRows);
1036  // xmlOut.addTextElementToParent("object_rows", str, objectParent);
1037  // sprintf(str,"%d",itShapes->numberOfColumns);
1038  // xmlOut.addTextElementToParent("object_columns", str, objectParent);
1039  // for(Points::const_iterator itCorners=itShapes->corners.begin();
1040  // itCorners!=itShapes->corners.end(); itCorners++)
1041  // {
1042  // sprintf(str,"%f",itCorners->x);
1043  // xmlOut.addTextElementToParent("xyz_point", str, objectParent);
1044  // sprintf(str,"%f",itCorners->y);
1045  // xmlOut.addTextElementToParent("xyz_point", str, objectParent);
1046  // sprintf(str,"%f",itCorners->z);
1047  // xmlOut.addTextElementToParent("xyz_point", str, objectParent);
1048  // }
1049  // }
1050  }
1051  else if(
1052  requestType ==
1053  "getRootConfig") // ################################################################################################################
1054  {
1055  std::string path = CgiDataUtilities::postData(cgiIn, "RootConfigPath");
1056  __SUP_COUT__ << "path " << path << __E__;
1057 
1058  if(path.find("/" + PRE_MADE_ROOT_CFG_DIR + "/") ==
1059  0) // ROOT config path must start the path
1060  {
1061  path = std::string(ROOT_DISPLAY_CONFIG_PATH) + "/" +
1062  path.substr(PRE_MADE_ROOT_CFG_DIR.length() + 2);
1063  __SUP_COUT__ << "mod path " << path << __E__;
1064  }
1065 
1066  HttpXmlDocument cfgXml;
1067  if(cfgXml.loadXmlDocument(path))
1068  {
1069  xmlOut.addTextElementToData("status", "1");
1070  xmlOut.copyDataChildren(cfgXml); // copy file to output xml
1071  cfgXml.saveXmlDocument(path);
1072  }
1073  else
1074  xmlOut.addTextElementToData("status",
1075  "Failed. File to properly load config file.");
1076  }
1077  else if(
1078  requestType ==
1079  "rootAdminControls") // ################################################################################################################
1080  {
1081  // if(userPermissions < ROOT_VIEWER_PERMISSIONS_THRESHOLD)
1082  // {
1083  // __SUP_COUT__ << "Insufficient permissions for Root Viewer Admin
1084  // Controls: " << userPermissions << " < " << ROOT_VIEWER_PERMISSIONS_THRESHOLD <<
1085  // __E__;
1086  // xmlOut.addTextElementToData("status", "Failed. Insufficient user
1087  // permissions.");
1088  // }
1089  // else
1090  // {
1091  std::string cmd = cgiIn("cmd"); // possible commands are
1092  // mkdir
1093  // save
1094  // delete
1095 
1096  std::string path = CgiDataUtilities::postData(cgiIn, "path");
1097  std::string name = CgiDataUtilities::postData(cgiIn, "name");
1098  __SUP_COUT__ << "cmd " << cmd << __E__;
1099  __SUP_COUT__ << "path " << path << __E__;
1100  __SUP_COUT__ << "name " << name << __E__;
1101 
1102  if(path.find("/" + PRE_MADE_ROOT_CFG_DIR + "/") ==
1103  0) // ROOT config path must start the path
1104  {
1105  path = std::string(ROOT_DISPLAY_CONFIG_PATH) + "/" +
1106  path.substr(PRE_MADE_ROOT_CFG_DIR.length() + 2) + name;
1107  __SUP_COUT__ << "mod path " << path << __E__;
1108 
1109  if(cmd == "mkdir")
1110  {
1111  if(mkdir(path.c_str(),
1112  S_IRWXU | (S_IRGRP | S_IXGRP) |
1113  (S_IROTH | S_IXOTH))) // mode = drwx r-x r-x
1114  xmlOut.addTextElementToData("status",
1115  "Failed. Directory create rejected.");
1116  else
1117  xmlOut.addTextElementToData("status", "1"); // success
1118  }
1119  else if(cmd == "save")
1120  {
1121  path += PRE_MADE_ROOT_CFG_FILE_EXT; // add file extension
1122 
1123  bool useRunWildCard =
1124  atoi(CgiDataUtilities::postData(cgiIn, "useRunWildCard")
1125  .c_str()); // 0 or 1
1126  std::string config = CgiDataUtilities::postData(cgiIn, "config");
1127  __SUP_COUT__ << "config " << config << __E__;
1128  __SUP_COUT__ << "useRunWildCard " << useRunWildCard << __E__;
1129 
1130  // check if file already exists
1131  FILE* fp = fopen(path.c_str(), "r");
1132  if(fp)
1133  {
1134  fclose(fp);
1135  xmlOut.addTextElementToData("status", "Failed. File already exists.");
1136  __SUP_COUT__ << " Failed. File already exists." << __E__;
1137  }
1138  else
1139  {
1140  // dump to file
1141  // verify proper format through read back
1142  // if successfully loaded, re-save for formatting
1143 
1144  // dump to file
1145  fp = fopen(path.c_str(), "w");
1146  fputs(config.c_str(), fp);
1147  fclose(fp);
1148 
1149  // verify proper format through read back
1150  HttpXmlDocument cfgXml;
1151  if(cfgXml.loadXmlDocument(path))
1152  {
1153  // successfully loaded, re-save for formatting
1154  cfgXml.saveXmlDocument(path);
1155  xmlOut.addTextElementToData("status", "1"); // success
1156  }
1157  else // failed to load properly
1158  {
1159  xmlOut.addTextElementToData(
1160  "status", "Failed. Fatal. Improper file format.");
1161  if(remove(path.c_str()) != 0)
1162  __SUP_COUT__ << "Failed. Could not remove poorly formed Root "
1163  "config file!"
1164  << __E__;
1165  }
1166  }
1167  }
1168  else if(cmd == "delete")
1169  {
1170  // guess first directory and then file
1171  if(rmdir(path.c_str()) == 0 ||
1172  remove((path + PRE_MADE_ROOT_CFG_FILE_EXT).c_str()) == 0)
1173  xmlOut.addTextElementToData("status", "1"); // success
1174  else
1175  xmlOut.addTextElementToData("status",
1176  "Failed. Target could not be deleted.");
1177  }
1178  else
1179  xmlOut.addTextElementToData("status", "Failed. Unrecognized command.");
1180  }
1181  else
1182  xmlOut.addTextElementToData("status", "Failed. Invalid path.");
1183 
1184  //}
1185  }
1186  else if(
1187  requestType ==
1188  "getMeDirs") // ################################################################################################################
1189  {
1190  xmlOut.setDarioStyle(true); // workaround for XML formatting....
1191  std::string fSystemPath = std::string(ROOT_BROWSER_PATH) + "/";
1192  std::string fRootPath = CgiDataUtilities::postData(cgiIn, "Path");
1193  boost::regex re("%2F");
1194  fRootPath = boost::regex_replace(fRootPath, re, "/");
1195  std::string fullPath = fSystemPath + fRootPath;
1196  // fFoldersPath_ = "pippo" ;
1197  STDLINE(std::string("Begin: fSystemPath = ") + fSystemPath, ACWhite);
1198  STDLINE(std::string("Begin: fRootPath = ") + fRootPath, ACWhite);
1199  STDLINE(std::string("Begin: fullPath = ") + fullPath, ACWhite);
1200  // STDLINE(std::string("Begin: fFoldersPath = ")+fFoldersPath_,ACCyan ) ;
1201 
1202  xmlOut.setRootPath(fRootPath);
1203  xmlOut.makeDirectoryBinaryTree(fSystemPath, fRootPath, 0, NULL);
1204  std::ostringstream* out = new std::ostringstream();
1205  xmlOut.outputXmlDocument((std::ostringstream*)out, true);
1206  }
1207  else if(
1208  requestType ==
1209  "getMeRootFile") // ################################################################################################################
1210  {
1211  xmlOut.setDarioStyle(true); // workaround for XML formatting....
1212  std::string fSystemPath = std::string(ROOT_BROWSER_PATH) + "/";
1213  std::string fRootPath = CgiDataUtilities::postData(cgiIn, "fRootPath");
1214  std::string fFoldersPath = CgiDataUtilities::postData(cgiIn, "fFoldersPath");
1215  std::string fHistName = CgiDataUtilities::postData(cgiIn, "fHistName");
1216  std::string fRFoldersPath = CgiDataUtilities::postData(cgiIn, "fRFoldersPath");
1217  std::string fFileName = CgiDataUtilities::postData(cgiIn, "fFileName");
1218  boost::regex re("%2F");
1219  fRootPath = boost::regex_replace(fRootPath, re, "/");
1220  fFoldersPath = boost::regex_replace(fFoldersPath, re, "/");
1221  STDLINE(std::string("fSystemPath : ") + fSystemPath, ACCyan);
1222  STDLINE(std::string("fRootPath : ") + fRootPath, ACCyan);
1223  STDLINE(std::string("fFoldersPath : ") + fFoldersPath, ACCyan);
1224  STDLINE(std::string("fHistName : ") + fHistName, ACCyan);
1225  STDLINE(std::string("fRFoldersPath: ") + fRFoldersPath, ACCyan);
1226  STDLINE(std::string("fFileName : ") + fFileName, ACCyan);
1227  RootFileExplorer* theExplorer = new RootFileExplorer(
1228  fSystemPath, fRootPath, fFoldersPath, fHistName, fRFoldersPath, fFileName);
1229  xmlOut.setDocument(theExplorer->initialize(false));
1230  std::ostringstream* out = NULL;
1231  xmlOut.outputXmlDocument((std::ostringstream*)out, true);
1232  }
1233  else if(
1234  requestType ==
1235  "getMeLIVE-DQMFile") // ################################################################################################################
1236  {
1237  xmlOut.setDarioStyle(true); // workaround for XML formatting....
1238  std::string fSystemPath = std::string(ROOT_BROWSER_PATH) + "/";
1239  std::string fRootPath = CgiDataUtilities::postData(cgiIn, "fRootPath");
1240  std::string fFoldersPath = CgiDataUtilities::postData(cgiIn, "fFoldersPath");
1241  std::string fHistName = CgiDataUtilities::postData(cgiIn, "fHistName");
1242  std::string fRFoldersPath = CgiDataUtilities::postData(cgiIn, "fRFoldersPath");
1243  std::string fFileName = CgiDataUtilities::postData(cgiIn, "fFileName");
1244  STDLINE(std::string("fSystemPath : ") + fSystemPath, ACCyan);
1245  STDLINE(std::string("fRootPath : ") + fRootPath, ACCyan);
1246  STDLINE(std::string("fFoldersPath : ") + fFoldersPath, ACCyan);
1247  STDLINE(std::string("fHistName : ") + fHistName, ACCyan);
1248  STDLINE(std::string("fRFoldersPath: ") + fRFoldersPath, ACCyan);
1249  STDLINE(std::string("fFileName : ") + fFileName, ACCyan);
1250  boost::regex re("%2F");
1251  fRootPath = boost::regex_replace(fRootPath, re, "/");
1252  fFoldersPath = boost::regex_replace(fFoldersPath, re, "/");
1253  fRFoldersPath = boost::regex_replace(fRFoldersPath, re, "/");
1254 
1255  TFile* rootFile;
1256  if(theDataManager_->getLiveDQMHistos() != nullptr)
1257  {
1258  rootFile = theDataManager_->getLiveDQMHistos()->getFile();
1259  fRootPath = "LIVE_DQM.root";
1260  }
1261  else
1262  {
1263  rootFile = TFile::Open(fRootPath.c_str());
1264  }
1265  RootFileExplorer* theExplorer = new RootFileExplorer(fSystemPath,
1266  fRootPath,
1267  fFoldersPath,
1268  fHistName,
1269  fRFoldersPath,
1270  fFileName,
1271  rootFile);
1272  xmlOut.setDocument(theExplorer->initialize(true));
1273  std::ostringstream* out = NULL;
1274  xmlOut.outputXmlDocument((std::ostringstream*)out, true);
1275  }
1276  else if(
1277  requestType ==
1278  "saveConfiguration") // ################################################################################################################
1279  {
1280  std::string configPayload = CgiDataUtilities::postData(cgiIn, "configPayload");
1281  STDLINE("configPayload: ", ACRed);
1282  STDLINE(configPayload, ACYellow);
1283 
1284  fstream outFile;
1285  outFile.open("/tmp/configPayload.json", ios::out | ios::app);
1286  outFile << configPayload << endl;
1287  outFile.close();
1288  }
1289  else if(
1290  requestType ==
1291  "getConfiguration") // ################################################################################################################
1292  {
1293  std::string configPayload = CgiDataUtilities::postData(cgiIn, "configPayload");
1294  std::string JSONPayLoad = "";
1295  std::string line = "";
1296 
1297  ifstream JSONFile("/tmp/configPayload.json");
1298 
1299  if(JSONFile.is_open())
1300  {
1301  while(getline(JSONFile, line))
1302  {
1303  JSONPayLoad += line;
1304  }
1305  JSONFile.close();
1306  }
1307 
1308  xmlOut.addTextElementToData("JSONPayLoad", JSONPayLoad);
1309  // std::ostringstream* out = NULL;
1310  // xmlOut.outputXmlDocument((std::ostringstream*) out, true);
1311  }
1312 }
DQMHistosBase * getLiveDQMHistos(void)
Getters.
virtual void transitionConfiguring(toolbox::Event::Reference e) override
virtual void request(const std::string &requestType, cgicc::Cgicc &cgiIn, HttpXmlDocument &xmlOut, const WebUsers::RequestUserInfo &userInfo) override
virtual void forceSupervisorPropertyValues(void) override
virtual void setSupervisorPropertyDefaults(void) override