1 #include "otsdaq-utilities/MacroMaker/MacroMakerSupervisor.h"
3 #include "otsdaq/CodeEditor/CodeEditor.h"
4 #include "otsdaq/ConfigurationInterface/ConfigurationManager.h"
5 #include "otsdaq/FECore/FEVInterface.h"
7 #include "otsdaq/NetworkUtilities/TransceiverSocket.h"
15 #include "otsdaq/TableCore/TableGroupKey.h"
17 #define MACROS_DB_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/MacroData/"
18 #define MACROS_HIST_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/MacroHistory/"
19 #define MACROS_SEQUENCE_PATH std::string(__ENV__("SERVICE_DATA_PATH")) + "/MacroSequence/"
20 #define MACROS_EXPORT_PATH std::string("/MacroExport/")
22 #define SEQUENCE_FILE_NAME \
23 std::string(__ENV__("SERVICE_DATA_PATH")) + "/OtsWizardData/sequence.dat"
24 #define SEQUENCE_OUT_FILE_NAME \
25 std::string(__ENV__("SERVICE_DATA_PATH")) + "/OtsWizardData/sequence.out"
30 #define __MF_SUBJECT__ "MacroMaker"
35 MacroMakerSupervisor::MacroMakerSupervisor(xdaq::ApplicationStub* stub)
36 : CoreSupervisorBase(stub)
38 __SUP_COUT__ <<
"Constructing..." << __E__;
43 mkdir(((std::string)MACROS_DB_PATH).c_str(), 0755);
44 mkdir(((std::string)MACROS_HIST_PATH).c_str(), 0755);
45 mkdir(((std::string)MACROS_SEQUENCE_PATH).c_str(), 0755);
46 mkdir((__ENV__(
"SERVICE_DATA_PATH") + MACROS_EXPORT_PATH).c_str(), 0755);
49 &MacroMakerSupervisor::frontEndCommunicationRequest,
54 if(CorePropertySupervisorBase::allSupervisorInfo_.isMacroMakerMode())
56 __SUP_COUT__ <<
"Starting constructor for Macro Maker mode." << __E__;
58 xgi::bind(
this, &MacroMakerSupervisor::requestIcons,
"requestIcons");
59 xgi::bind(
this, &MacroMakerSupervisor::verification,
"Verify");
60 xgi::bind(
this, &MacroMakerSupervisor::tooltipRequest,
"TooltipRequest");
61 xgi::bind(
this, &MacroMakerSupervisor::requestWrapper,
"Request");
63 &MacroMakerSupervisor::supervisorSequenceCheck,
64 "SupervisorSequenceCheck",
67 __SUP_COUT__ <<
"Completed constructor for Macro Maker mode." << __E__;
70 __SUP_COUT__ <<
"Not Macro Maker only mode." << __E__;
76 if(CorePropertySupervisorBase::allSupervisorInfo_.isMacroMakerMode())
81 ConfigurationTree appsNode = theConfigurationManager_->getNode(
82 ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME);
87 FEPluginTypetoFEsMap_.clear();
88 FEtoSupervisorMap_.clear();
89 FEtoPluginTypeMap_.clear();
92 __SUP_COUT__ <<
"FEs for app MacroMakerFESupervisor"
98 .getNode(
"MacroMakerFESupervisor")
99 .getNode(
"LinkToSupervisorTable")
100 .getNode(
"LinkToFEInterfaceTable")
103 for(
auto& fe : feChildren)
105 if(!fe.second.status())
108 __SUP_COUTV__(fe.first);
109 FEtoSupervisorMap_[fe.first] =
110 atoi(__ENV__(
"FE_SUPERVISOR_ID"));
112 std::string pluginType =
113 fe.second.getNode(
"FEInterfacePluginName").getValue();
114 FEPluginTypetoFEsMap_[pluginType].emplace(fe.first);
115 FEtoPluginTypeMap_[fe.first] = pluginType;
119 __SUP_COUTV__(StringMacros::mapToString(FEtoSupervisorMap_));
120 __SUP_COUTV__(StringMacros::mapToString(FEPluginTypetoFEsMap_));
121 __SUP_COUTV__(StringMacros::mapToString(FEtoPluginTypeMap_));
126 bool enableRemoteControl =
false;
129 __ENV__(
"OTS_MACROMAKER_UDP_PORT");
130 __ENV__(
"OTS_MACROMAKER_UDP_IP");
131 enableRemoteControl =
true;
138 if(enableRemoteControl)
140 __SUP_COUT__ <<
"Enabling remote control over UDP..." << __E__;
144 MacroMakerSupervisor::RemoteControlWorkLoop(s);
150 __SUP_COUT__ <<
"Remote control over UDP is disabled." << __E__;
153 __SUP_COUT__ <<
"Constructed." << __E__;
157 MacroMakerSupervisor::~MacroMakerSupervisor(
void) { destroy(); }
160 void MacroMakerSupervisor::init(
void)
165 allFESupervisorInfo_ =
166 SupervisorInfoMap(allSupervisorInfo_.getAllFETypeSupervisorInfo());
171 void MacroMakerSupervisor::destroy(
void)
183 void MacroMakerSupervisor::tooltipRequest(xgi::Input* in, xgi::Output* out)
185 cgicc::Cgicc cgi(in);
187 std::string Command = CgiDataUtilities::getData(cgi,
"RequestType");
190 std::string submittedSequence = CgiDataUtilities::postData(cgi,
"sequence");
193 if(securityCode_.compare(submittedSequence) != 0)
195 __COUT__ <<
"Unauthorized Request made, security sequence doesn't match!"
205 HttpXmlDocument xmldoc;
207 if(Command ==
"check")
209 WebUsers::tooltipCheckForUsername(WebUsers::DEFAULT_ADMIN_USERNAME,
211 CgiDataUtilities::getData(cgi,
"srcFile"),
212 CgiDataUtilities::getData(cgi,
"srcFunc"),
213 CgiDataUtilities::getData(cgi,
"srcId"));
215 else if(Command ==
"setNeverShow")
217 WebUsers::tooltipSetNeverShowForUsername(
218 WebUsers::DEFAULT_ADMIN_USERNAME,
220 CgiDataUtilities::getData(cgi,
"srcFile"),
221 CgiDataUtilities::getData(cgi,
"srcFunc"),
222 CgiDataUtilities::getData(cgi,
"srcId"),
223 CgiDataUtilities::getData(cgi,
"doNeverShow") ==
"1" ?
true :
false,
224 CgiDataUtilities::getData(cgi,
"temporarySilence") ==
"1" ?
true :
false);
227 __COUT__ <<
"Command Request, " << Command <<
", not recognized." << __E__;
229 xmldoc.outputXmlDocument((std::ostringstream*)out,
false,
true);
233 void MacroMakerSupervisor::verification(xgi::Input* in, xgi::Output* out)
235 cgicc::Cgicc cgi(in);
236 std::string submittedSequence = CgiDataUtilities::getData(cgi,
"code");
237 __COUT__ <<
"submittedSequence=" << submittedSequence <<
" " << time(0) << __E__;
239 std::string securityWarning =
"";
241 if(securityCode_.compare(submittedSequence) != 0)
243 __COUT__ <<
"Unauthorized Request made, security sequence doesn't match!"
245 *out <<
"Invalid code.";
251 __COUT__ <<
"*** Successfully authenticated security sequence "
252 <<
"@ " << time(0) << __E__;
257 securityWarning =
"&secure=False";
261 *out <<
"<!DOCTYPE HTML><html lang='en'><head><title>ots MacroMaker mode</title>" <<
264 "<link rel='apple-touch-icon' sizes='57x57' href='/WebPath/images/otsdaqIcons/apple-icon-57x57.png'>\
265 <link rel='apple-touch-icon' sizes='60x60' href='/WebPath/images/otsdaqIcons/apple-icon-60x60.png'>\
266 <link rel='apple-touch-icon' sizes='72x72' href='/WebPath/images/otsdaqIcons/apple-icon-72x72.png'>\
267 <link rel='apple-touch-icon' sizes='76x76' href='/WebPath/images/otsdaqIcons/apple-icon-76x76.png'>\
268 <link rel='apple-touch-icon' sizes='114x114' href='/WebPath/images/otsdaqIcons/apple-icon-114x114.png'>\
269 <link rel='apple-touch-icon' sizes='120x120' href='/WebPath/images/otsdaqIcons/apple-icon-120x120.png'>\
270 <link rel='apple-touch-icon' sizes='144x144' href='/WebPath/images/otsdaqIcons/apple-icon-144x144.png'>\
271 <link rel='apple-touch-icon' sizes='152x152' href='/WebPath/images/otsdaqIcons/apple-icon-152x152.png'>\
272 <link rel='apple-touch-icon' sizes='180x180' href='/WebPath/images/otsdaqIcons/apple-icon-180x180.png'>\
273 <link rel='icon' type='image/png' sizes='192x192' href='/WebPath/images/otsdaqIcons/android-icon-192x192.png'>\
274 <link rel='icon' type='image/png' sizes='32x32' href='/WebPath/images/otsdaqIcons/favicon-32x32.png'>\
275 <link rel='icon' type='image/png' sizes='96x96' href='/WebPath/images/otsdaqIcons/favicon-96x96.png'>\
276 <link rel='icon' type='image/png' sizes='16x16' href='/WebPath/images/otsdaqIcons/favicon-16x16.png'>\
277 <link rel='manifest' href='/WebPath/images/otsdaqIcons/manifest.json'>\
278 <meta name='msapplication-TileColor' content='#ffffff'>\
279 <meta name='msapplication-TileImage' content='/ms-icon-144x144.png'>\
280 <meta name='theme-color' content='#ffffff'>"
284 <<
"<frameset col='100%' row='100%'><frame "
285 "src='/WebPath/html/MacroMakerSupervisor.html?urn="
286 << this->getApplicationDescriptor()->getLocalId() << securityWarning
287 <<
"'></frameset></html>";
291 void MacroMakerSupervisor::generateURL()
293 defaultSequence_ =
true;
296 FILE* fp = fopen((SEQUENCE_FILE_NAME).c_str(),
"r");
299 __SUP_COUT_INFO__ <<
"Sequence length file found: " << SEQUENCE_FILE_NAME
302 fgets(line, 100, fp);
303 sscanf(line,
"%d", &length);
308 defaultSequence_ =
false;
314 <<
"(Reverting to default wiz security) Sequence length file NOT found: "
315 << SEQUENCE_FILE_NAME << __E__;
319 __SUP_COUT__ <<
"Sequence length = " << length << __E__;
323 const char alphanum[] =
325 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
326 "abcdefghijklmnopqrstuvwxyz";
328 for(
int i = 0; i < length; ++i)
330 securityCode_ += alphanum[rand() % (
sizeof(alphanum) - 1)];
333 __SUP_COUT__ << __ENV__(
"HOSTNAME") <<
":" << __ENV__(
"PORT")
334 <<
"/urn:xdaq-application:lid="
335 << this->getApplicationDescriptor()->getLocalId()
336 <<
"/Verify?code=" << securityCode_ << __E__;
342 fp = fopen((SEQUENCE_OUT_FILE_NAME).c_str(),
"w");
345 fprintf(fp,
"%s", securityCode_.c_str());
349 __SUP_COUT_ERR__ <<
"Sequence output file NOT found: " << SEQUENCE_OUT_FILE_NAME
356 void MacroMakerSupervisor::requestIcons(xgi::Input* in, xgi::Output* out)
358 cgicc::Cgicc cgi(in);
360 std::string submittedSequence = CgiDataUtilities::postData(cgi,
"sequence");
363 if(securityCode_.compare(submittedSequence) != 0)
365 __COUT__ <<
"Unauthorized Request made, security sequence doesn't match! "
371 __COUT__ <<
"***Successfully authenticated security sequence. " << time(0)
384 *out <<
"Macro Maker "
385 ",MM,0,1,icon-MacroMaker.png,/WebPath/html/"
386 "MacroMaker.html?urn=290,/"
388 ",CFG,0,1,icon-Configure.png,/WebPath/html/"
389 "FEMacroTest.html?urn=290,/"
391 <<
",Code Editor,CODE,0,1,icon-CodeEditor.png,/urn:xdaq-application:lid=240/,/"
395 std::string iconFile = std::string(__ENV__(
"USER_DATA")) +
"/MacroMakerModeIcons.dat";
396 __COUT__ <<
"Macro Maker mode user icons file: " << iconFile << __E__;
397 FILE* fp = fopen(iconFile.c_str(),
"r");
400 __COUT__ <<
"Macro Maker mode user icons loading from " << iconFile << __E__;
401 fseek(fp, 0, SEEK_END);
402 const unsigned long fileSize = ftell(fp);
403 std::string fileString(fileSize, 0);
405 if(fread(&fileString[0], 1, fileSize, fp) != fileSize)
407 __COUT_ERR__ <<
"Unable to read proper size string from icons file!" << __E__;
412 __COUTV__(fileString);
416 __COUT__ <<
"Macro Maker mode user icons file not found: " << iconFile << __E__;
423 xoap::MessageReference MacroMakerSupervisor::supervisorSequenceCheck(
424 xoap::MessageReference message)
427 SOAPParameters parameters;
428 parameters.addParameter(
"sequence");
429 SOAPUtilities::receive(message, parameters);
431 std::string submittedSequence = parameters.getValue(
"sequence");
435 std::map<std::string , WebUsers::permissionLevel_t> permissionMap;
437 if(securityCode_ == submittedSequence)
438 permissionMap.emplace(
439 std::pair<std::string /*groupName*/, WebUsers::permissionLevel_t>(
440 WebUsers::DEFAULT_USER_GROUP, WebUsers::PERMISSION_LEVEL_ADMIN));
443 __COUT__ <<
"Unauthorized Request made, security sequence doesn't match!"
446 permissionMap.emplace(
447 std::pair<std::string /*groupName*/, WebUsers::permissionLevel_t>(
448 WebUsers::DEFAULT_USER_GROUP, WebUsers::PERMISSION_LEVEL_INACTIVE));
452 SOAPParameters retParameters;
453 retParameters.addParameter(
"Permissions", StringMacros::mapToString(permissionMap));
455 return SOAPUtilities::makeSOAPMessageReference(
"SequenceResponse", retParameters);
465 std::string ipAddressForRemoteControlOverUDP = __ENV__(
466 "OTS_MACROMAKER_UDP_IP");
467 int portForRemoteControlOverUDP = atoi(__ENV__(
468 "OTS_MACROMAKER_UDP_PORT"));
469 bool acknowledgementEnabled =
472 __COUTV__(ipAddressForRemoteControlOverUDP);
473 __COUTV__(portForRemoteControlOverUDP);
474 __COUTV__(acknowledgementEnabled);
476 TransceiverSocket sock(ipAddressForRemoteControlOverUDP,
477 portForRemoteControlOverUDP);
485 __SS__ <<
"FATAL Console error. Could not initialize socket at ip '"
486 << ipAddressForRemoteControlOverUDP <<
"' and port "
487 << portForRemoteControlOverUDP
488 <<
". Perhaps it is already in use? Exiting Remote Control "
489 "SOAPUtilities::receive loop."
496 __COUT__ <<
"UDP Remote Control workloop starting..." << __E__;
506 buffer, 0 , 1 ,
false ) !=
509 __COUT__ <<
"UDP Remote Control packet received of size = " << buffer.size()
515 if(buffer ==
"GetFrontendMacroInfo")
517 HttpXmlDocument xmldoc;
518 theSupervisor->getFEMacroList(xmldoc,
"NO-USER");
520 std::stringstream out;
521 xmldoc.outputXmlDocument((std::ostringstream*)&out,
524 __COUT__ <<
"out: " << out.str();
525 sock.acknowledge(out.str(),
true );
527 else if(buffer.find(
"RunFrontendMacro") == 0)
529 HttpXmlDocument xmldoc;
531 std::vector<std::string> bufferFields =
532 StringMacros::getVectorFromString(buffer, {
';'});
533 if(bufferFields.size() < 8)
535 __SS__ <<
"Missing input arguments for running FE Macro: "
536 << bufferFields.size() <<
" vs 8 expected" << __E__;
540 std::string feClassSelected = bufferFields[1];
541 std::string feUIDSelected =
543 std::string macroType = bufferFields[3];
544 std::string macroName =
545 StringMacros::decodeURIComponent(bufferFields[4]);
546 std::string inputArgs = StringMacros::decodeURIComponent(
548 std::string outputArgs =
549 StringMacros::decodeURIComponent(bufferFields[6]);
550 bool saveOutputs = bufferFields[7] ==
"1";
551 std::string username =
"NO-USER";
552 std::string userGroupPermission =
"allUsers: 255";
554 theSupervisor->runFEMacro(xmldoc,
563 userGroupPermission);
565 std::stringstream out;
566 xmldoc.outputXmlDocument((std::ostringstream*)&out,
569 __COUT__ <<
"out: " << out.str();
570 sock.acknowledge(out.str(),
true );
574 __SS__ <<
"Unrecognized UDP command received: " << buffer << __E__;
578 catch(
const std::runtime_error& e)
580 __COUT_ERR__ <<
"Error during UDP command handling: " << e.what()
582 sock.acknowledge(std::string(
"Error: ") + e.what(),
true );
586 __COUT_ERR__ <<
"Unknown error caught during UDP command handling - "
589 sock.acknowledge(std::string(
"Error: ") +
"unknown error caught",
593 __COUT__ <<
"Done handling command '" << buffer <<
"'" << __E__;
603 void MacroMakerSupervisor::requestWrapper(xgi::Input* in, xgi::Output* out)
606 if(!CorePropertySupervisorBase::allSupervisorInfo_.isMacroMakerMode())
609 return CoreSupervisorBase::requestWrapper(in, out);
617 cgicc::Cgicc cgiIn(in);
619 std::string submittedSequence = CgiDataUtilities::postData(cgiIn,
"sequence");
622 if(securityCode_.compare(submittedSequence) != 0)
624 __COUT__ <<
"Unauthorized Request made, security sequence doesn't match! "
630 __COUT__ <<
"***Successfully authenticated security sequence. " << time(0)
635 std::string requestType = CgiDataUtilities::getData(cgiIn,
"RequestType");
640 HttpXmlDocument xmlOut;
641 WebUsers::RequestUserInfo userInfo(
642 requestType, CgiDataUtilities::getOrPostData(cgiIn,
"CookieCode"));
644 CorePropertySupervisorBase::getRequestUserInfo(userInfo);
647 userInfo.username_ =
"admin";
648 userInfo.displayName_ =
"Admin";
649 userInfo.usernameWithLock_ =
"admin";
650 userInfo.userSessionIndex_ = 0;
651 std::map<std::string , WebUsers::permissionLevel_t> initPermissions = {
652 {WebUsers::DEFAULT_USER_GROUP, WebUsers::PERMISSION_LEVEL_ADMIN}};
653 userInfo.setGroupPermissionLevels(StringMacros::mapToString(initPermissions));
655 if(1 || !userInfo.automatedCommand_)
656 __SUP_COUT__ <<
"requestType: " << requestType << __E__;
658 if(userInfo.NonXMLRequestType_)
662 nonXmlRequest(requestType, cgiIn, *out, userInfo);
664 catch(
const std::runtime_error& e)
666 __SUP_SS__ <<
"An error was encountered handling requestType '" << requestType
667 <<
"':" << e.what() << __E__;
668 __SUP_COUT_ERR__ <<
"\n" << ss.str();
672 __SUP_SS__ <<
"An unknown error was encountered handling requestType '"
673 << requestType <<
".' "
674 <<
"Please check the printouts to debug." << __E__;
679 catch(
const std::exception& e)
681 ss <<
"Exception message: " << e.what();
686 __SUP_COUT_ERR__ <<
"\n" << ss.str();
695 request(requestType, cgiIn, xmlOut, userInfo);
697 catch(
const std::runtime_error& e)
699 __SUP_SS__ <<
"An error was encountered handling requestType '" << requestType
700 <<
"':" << e.what() << __E__;
701 __SUP_COUT_ERR__ <<
"\n" << ss.str();
702 xmlOut.addTextElementToData(
"Error", ss.str());
706 __SUP_SS__ <<
"An unknown error was encountered handling requestType '"
707 << requestType <<
".' "
708 <<
"Please check the printouts to debug." << __E__;
713 catch(
const std::exception& e)
715 ss <<
"Exception message: " << e.what();
720 __SUP_COUT_ERR__ <<
"\n" << ss.str();
721 xmlOut.addTextElementToData(
"Error", ss.str());
726 unsigned int occurance = 0;
727 std::string err = xmlOut.getMatchingValue(
"Error", occurance++);
730 __SUP_COUT_ERR__ <<
"'" << requestType <<
"' ERROR encountered: " << err
732 __SUP_COUT_ERR__ <<
"'" << requestType <<
"' ERROR encountered: " << err
734 err = xmlOut.getMatchingValue(
"Error", occurance++);
739 xmlOut.outputXmlDocument((std::ostringstream*)out,
741 !userInfo.NoXmlWhiteSpace_ );
745 void MacroMakerSupervisor::request(
const std::string& requestType,
747 HttpXmlDocument& xmlOut,
748 const WebUsers::RequestUserInfo& userInfo)
751 std::chrono::steady_clock::time_point requestStart = std::chrono::steady_clock::now();
752 time_t requestStartTime = time(0);
755 std::string username =
"";
756 for(
unsigned int i = 0; i < userInfo.username_.size(); ++i)
757 if((userInfo.username_[i] >=
'a' && userInfo.username_[i] <=
'z') ||
758 (userInfo.username_[i] >=
'A' && userInfo.username_[i] <=
'Z') ||
759 (userInfo.username_[i] >=
'0' && userInfo.username_[i] <=
'9') ||
760 userInfo.username_[i] >=
'-' || userInfo.username_[i] <=
'_')
761 username += userInfo.username_[i];
763 if(username.size() < 2)
765 __SUP_SS__ <<
"Illegal username '" << userInfo.username_ <<
"' received."
770 __SUP_COUT__ <<
"User name is " << userInfo.username_ <<
"." << __E__;
771 __SUP_COUT__ <<
"User permission level for request '" << requestType <<
"' is "
772 << unsigned(userInfo.permissionLevel_) <<
"." << __E__;
776 if(requestType ==
"loadFEHistory")
778 std::string histPath = (std::string)MACROS_HIST_PATH + userInfo.username_ +
"/";
779 mkdir(histPath.c_str(), 0755);
782 if(requestType ==
"loadFEMacroSequences")
784 std::string seqPath =
785 (std::string)MACROS_SEQUENCE_PATH + userInfo.username_ +
"/";
786 mkdir(seqPath.c_str(), 0755);
789 if(requestType ==
"getPermission")
791 xmlOut.addTextElementToData(
"Permission",
792 std::to_string(
unsigned(userInfo.permissionLevel_)));
795 std::string publicPath = (std::string)MACROS_DB_PATH +
"publicMacros/";
796 mkdir(publicPath.c_str(), 0755);
797 std::string exportPath =
798 __ENV__(
"SERVICE_DATA_PATH") + MACROS_EXPORT_PATH + userInfo.username_ +
"/";
799 mkdir(exportPath.c_str(), 0755);
802 handleRequest(requestType, xmlOut, cgiIn, userInfo);
804 __SUP_COUTT__ <<
"Total MacroMaker request time: "
805 << artdaq::TimeUtils::GetElapsedTime(requestStart) <<
" = "
806 << time(0) - requestStartTime << __E__;
808 catch(
const std::runtime_error& e)
810 __SS__ <<
"Error occurred handling request '" << requestType <<
"': " << e.what()
812 __SUP_COUT__ << ss.str();
813 xmlOut.addTextElementToData(
"Error", ss.str());
817 __SS__ <<
"Unknown error occurred handling request '" << requestType <<
"!'" << __E__;
822 catch(
const std::exception& e)
824 ss <<
"Exception message: " << e.what();
829 __SUP_COUT__ << ss.str();
830 xmlOut.addTextElementToData(
"Error", ss.str());
835 void MacroMakerSupervisor::handleRequest(
const std::string Command,
836 HttpXmlDocument& xmldoc,
838 const WebUsers::RequestUserInfo& userInfo)
840 if(Command ==
"FElist")
842 else if(Command ==
"writeData")
843 writeData(xmldoc, cgi, userInfo.username_);
844 else if(Command ==
"readData")
845 readData(xmldoc, cgi, userInfo.username_);
846 else if(Command ==
"createMacro")
847 createMacro(xmldoc, cgi, userInfo.username_);
848 else if(Command ==
"loadMacros")
849 loadMacros(xmldoc, userInfo.username_);
850 else if(Command ==
"loadHistory")
851 loadHistory(xmldoc, userInfo.username_);
852 else if(Command ==
"deleteMacro")
853 deleteMacro(xmldoc, cgi, userInfo.username_);
854 else if(Command ==
"editMacro")
855 editMacro(xmldoc, cgi, userInfo.username_);
856 else if(Command ==
"clearHistory")
857 clearHistory(userInfo.username_);
858 else if(Command ==
"exportMacro")
859 exportMacro(xmldoc, cgi, userInfo.username_);
860 else if(Command ==
"exportFEMacro")
861 exportFEMacro(xmldoc, cgi, userInfo.username_);
862 else if(Command ==
"getFEMacroList")
865 std::string macroPath = (std::string)MACROS_DB_PATH + userInfo.username_ +
"/";
866 mkdir(macroPath.c_str(), 0755);
867 std::string histPath = (std::string)MACROS_HIST_PATH + userInfo.username_ +
"/";
868 mkdir(histPath.c_str(), 0755);
870 getFEMacroList(xmldoc, userInfo.username_);
872 else if(Command ==
"runFEMacro")
874 runFEMacro(xmldoc, cgi, userInfo);
875 else if(Command ==
"loadFEHistory")
877 loadFEHistory(xmldoc, userInfo.username_);
878 else if(Command ==
"clearFEHistory")
880 clearFEHistory(userInfo.username_);
881 else if(Command ==
"loadFEMacroSequences")
882 loadFEMacroSequences(xmldoc, userInfo.username_);
883 else if(Command ==
"saveFEMacroSequence")
884 saveFEMacroSequence(cgi, userInfo.username_);
885 else if(Command ==
"getFEMacroSequence")
886 getFEMacroSequence(xmldoc, cgi, userInfo.username_);
887 else if(Command ==
"deleteFEMacroSequence")
888 deleteFEMacroSequence(cgi, userInfo.username_);
892 xmldoc.addTextElementToData(
"Error",
"Unrecognized command '" + Command +
"'");
896 xoap::MessageReference MacroMakerSupervisor::frontEndCommunicationRequest(
897 xoap::MessageReference message)
901 __SUP_COUT__ <<
"FE Request received: " << SOAPUtilities::translate(message) << __E__;
903 SOAPParameters typeParameter, rxParameters;
904 typeParameter.addParameter(
"type");
905 SOAPUtilities::receive(message, typeParameter);
907 std::string type = typeParameter.getValue(
"type");
909 std::string error =
"";
911 if(type ==
"initFElist")
915 rxParameters.addParameter(
"groupName");
916 rxParameters.addParameter(
"groupKey");
917 SOAPUtilities::receive(message, rxParameters);
919 std::string groupName = rxParameters.getValue(
"groupName");
920 std::string groupKey = rxParameters.getValue(
"groupKey");
922 __SUP_COUTV__(groupName);
923 __SUP_COUTV__(groupKey);
925 ConfigurationManager cfgMgr;
926 cfgMgr.loadTableGroup(groupName, TableGroupKey(groupKey),
true);
931 const SupervisorInfoMap& feTypeSupervisors =
932 CorePropertySupervisorBase::allSupervisorInfo_.getAllFETypeSupervisorInfo();
934 ConfigurationTree appsNode =
935 cfgMgr.getNode(ConfigurationManager::XDAQ_APPLICATION_TABLE_NAME);
937 __SUP_COUT__ <<
"Number of FE Supervisors found = " << feTypeSupervisors.size()
940 FEPluginTypetoFEsMap_.clear();
941 FEtoSupervisorMap_.clear();
942 FEtoPluginTypeMap_.clear();
943 for(
auto& feApp : feTypeSupervisors)
945 __SUP_COUT__ <<
"FEs for app " << feApp.first <<
":" << feApp.second.getName()
948 auto feChildren = appsNode.getNode(feApp.second.getName())
949 .getNode(
"LinkToSupervisorTable")
950 .getNode(
"LinkToFEInterfaceTable")
953 for(
auto& fe : feChildren)
955 if(!fe.second.status())
958 __SUP_COUTV__(fe.first);
959 FEtoSupervisorMap_[fe.first] = feApp.first;
961 std::string pluginType =
962 fe.second.getNode(
"FEInterfacePluginName").getValue();
963 FEPluginTypetoFEsMap_[pluginType].emplace(fe.first);
964 FEtoPluginTypeMap_[fe.first] = pluginType;
968 __SUP_COUTV__(StringMacros::mapToString(FEtoSupervisorMap_));
969 __SUP_COUTV__(StringMacros::mapToString(FEPluginTypetoFEsMap_));
970 __SUP_COUTV__(StringMacros::mapToString(FEtoPluginTypeMap_));
972 else if(type ==
"feSend" ||
974 type ==
"feMacroMultiDimensionalStart" ||
975 type ==
"feMacroMultiDimensionalCheck" ||
976 type ==
"macroMultiDimensionalStart" ||
977 type ==
"macroMultiDimensionalCheck")
981 rxParameters.addParameter(
"targetInterfaceID");
982 SOAPUtilities::receive(message, rxParameters);
984 std::string targetInterfaceID = rxParameters.getValue(
"targetInterfaceID");
986 __SUP_COUTV__(targetInterfaceID);
988 auto feIt = FEtoSupervisorMap_.find(targetInterfaceID);
989 if(feIt == FEtoSupervisorMap_.end())
991 __SUP_SS__ <<
"Destination front end interface ID '" << targetInterfaceID
992 <<
"' was not found in the list of front ends." << __E__;
996 unsigned int FESupervisorIndex = feIt->second;
997 __SUP_COUT__ <<
"Found supervisor index: " << FESupervisorIndex << __E__;
999 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
1000 if(it == allFESupervisorInfo_.end())
1002 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
1003 << targetInterfaceID <<
":" << FESupervisorIndex <<
".' \n\n"
1004 <<
"The FE Supervisor Index does not exist. Have you configured "
1005 "the state machine properly?"
1010 if(type ==
"macroMultiDimensionalStart")
1014 SOAPParameters rxParameters;
1015 rxParameters.addParameter(
"macroName");
1016 SOAPUtilities::receive(message, rxParameters);
1017 std::string macroName = rxParameters.getValue(
"macroName");
1018 __SUP_COUTV__(macroName);
1020 std::string macroString;
1021 loadMacro(macroName, macroString);
1023 SOAPParameters parameters;
1024 parameters.addParameter(
"macroString", macroString);
1025 SOAPUtilities::addParameters(message, parameters);
1030 __SUP_COUT__ <<
"Forwarding request: " << SOAPUtilities::translate(message)
1033 xoap::MessageReference replyMessage =
1034 SOAPMessenger::sendWithSOAPReply(it->second.getDescriptor(), message);
1036 if(type !=
"feSend")
1038 __SUP_COUT__ <<
"Forwarding FE Macro response: "
1039 << SOAPUtilities::translate(replyMessage) << __E__;
1041 return replyMessage;
1044 catch(
const xdaq::exception::Exception& e)
1046 __SUP_SS__ <<
"Error forwarding FE Communication request to FE Supervisor '"
1047 << targetInterfaceID <<
":" << FESupervisorIndex <<
".' "
1048 <<
"Have you configured the state machine properly?\n\n"
1049 << e.what() << __E__;
1055 __SUP_SS__ <<
"Unrecognized FE Communication type: " << type << __E__;
1059 return SOAPUtilities::makeSOAPMessageReference(
"Received");
1061 catch(
const std::runtime_error& e)
1063 __SUP_SS__ <<
"Error processing FE communication request: " << e.what() << __E__;
1064 __SUP_COUT_ERR__ << ss.str();
1066 xoap::MessageReference returnMessage =
1067 SOAPUtilities::makeSOAPMessageReference(
"Error");
1069 SOAPParameters parameters;
1070 parameters.addParameter(
"Error", ss.str());
1071 SOAPUtilities::addParameters(returnMessage, parameters);
1072 return returnMessage;
1076 xoap::MessageReference returnMessage =
1077 SOAPUtilities::makeSOAPMessageReference(
"Error");
1079 __SUP_SS__ <<
"Unknown error processing FE communication request." << __E__;
1084 catch(
const std::exception& e)
1086 ss <<
"Exception message: " << e.what();
1091 __SUP_COUT_ERR__ << ss.str();
1093 SOAPParameters parameters;
1094 parameters.addParameter(
"Error", ss.str());
1095 SOAPUtilities::addParameters(returnMessage, parameters);
1096 return returnMessage;
1100 void MacroMakerSupervisor::getFElist(HttpXmlDocument& xmldoc)
1102 __SUP_COUT__ <<
"Getting FE list!!!!!!!!!" << __E__;
1104 SOAPParameters txParameters;
1105 txParameters.addParameter(
"Request",
"GetInterfaces");
1107 SOAPParameters rxParameters;
1108 rxParameters.addParameter(
"Command");
1109 rxParameters.addParameter(
"FEList");
1110 rxParameters.addParameter(
"frontEndError");
1114 SupervisorInfoMap::const_iterator it;
1115 std::string oneInterface;
1116 std::string rxFEList;
1117 std::string rxFrontEndError;
1119 size_t lastColonIndex;
1123 for(
auto& appInfo : allFESupervisorInfo_)
1131 __SUP_COUT__ <<
"FESupervisor LID = " << appInfo.second.getId()
1132 <<
" name = " << appInfo.second.getName() << __E__;
1136 xoap::MessageReference retMsg =
1137 SOAPMessenger::sendWithSOAPReply(appInfo.second.getDescriptor(),
1138 "MacroMakerSupervisorRequest",
1140 SOAPUtilities::receive(retMsg, rxParameters);
1142 __SUP_COUT__ <<
"Received MacroMaker response: "
1143 << SOAPUtilities::translate(retMsg).getCommand() <<
"==>"
1144 << SOAPUtilities::translate(retMsg) << __E__;
1146 if(SOAPUtilities::translate(retMsg).getCommand() ==
"Fault")
1148 __SUP_SS__ <<
"Unrecognized command received!" << __E__;
1152 catch(
const xdaq::exception::Exception& e)
1154 __SUP_SS__ <<
"Error transmitting request to FE Supervisor LID = "
1155 << appInfo.second.getId() <<
" name = " << appInfo.second.getName()
1157 << e.what() << __E__;
1161 rxFEList = rxParameters.getValue(
"FEList");
1162 rxFrontEndError = rxParameters.getValue(
"frontEndError");
1164 __SUP_COUT__ <<
"FE List received: \n" << rxFEList << __E__;
1166 if(rxFrontEndError !=
"")
1168 __SUP_SS__ <<
"FE Errors received: \n" << rxFrontEndError << __E__;
1172 std::istringstream allInterfaces(rxFEList);
1173 while(std::getline(allInterfaces, oneInterface))
1175 __SUP_COUTV__(oneInterface);
1176 xmldoc.addTextElementToData(
"FE", oneInterface);
1178 lastColonIndex = oneInterface.rfind(
':');
1179 if(lastColonIndex == std::string::npos)
1181 __SUP_SS__ <<
"Last colon could not be found in " << oneInterface
1185 oneInterface = oneInterface.substr(lastColonIndex);
1187 __SUP_COUTV__(oneInterface);
1195 void MacroMakerSupervisor::writeData(HttpXmlDocument& ,
1197 const std::string& username)
1199 __SUP_COUT__ <<
"MacroMaker writing..." << __E__;
1201 std::string Address = CgiDataUtilities::getData(cgi,
"Address");
1202 std::string Data = CgiDataUtilities::getData(cgi,
"Data");
1203 std::string interfaceIndexArray = CgiDataUtilities::getData(cgi,
"interfaceIndex");
1204 std::string supervisorIndexArray = CgiDataUtilities::getData(cgi,
"supervisorIndex");
1206 StringMacros::decodeURIComponent(CgiDataUtilities::getData(cgi,
"time"));
1207 std::string addressFormatStr = CgiDataUtilities::getData(cgi,
"addressFormatStr");
1208 std::string dataFormatStr = CgiDataUtilities::getData(cgi,
"dataFormatStr");
1210 std::string interfaces = CgiDataUtilities::postData(cgi,
"interfaces");
1212 __SUP_COUT__ <<
"Write Address: " << Address <<
" Data: " << Data << __E__;
1213 __SUP_COUTV__(interfaces);
1215 std::string command =
"w:" + Address +
":" + Data;
1216 std::string format = addressFormatStr +
":" + dataFormatStr;
1217 appendCommandToHistory(command, format, time, interfaces, username);
1219 SOAPParameters txParameters;
1220 txParameters.addParameter(
"Request",
"UniversalWrite");
1221 txParameters.addParameter(
"Address", Address);
1222 txParameters.addParameter(
"Data", Data);
1224 __SUP_COUT__ <<
"Here comes the array from multiselect box for WRITE, behold: \n"
1225 << supervisorIndexArray <<
"\n"
1226 << interfaceIndexArray << __E__;
1230 std::vector<std::string> interfaceIndices;
1231 std::istringstream f(interfaceIndexArray);
1233 while(getline(f, s,
','))
1234 interfaceIndices.push_back(s);
1235 std::vector<int> supervisorIndices;
1236 std::istringstream g(supervisorIndexArray);
1238 while(getline(g, t,
','))
1239 supervisorIndices.push_back(std::stoi(t));
1241 for(
unsigned int i = 0; i < supervisorIndices.size(); i++)
1243 unsigned int FESupervisorIndex = supervisorIndices[i];
1244 std::string interfaceIndex = interfaceIndices[i];
1246 txParameters.addParameter(
"InterfaceID", interfaceIndex);
1248 __SUP_COUT__ <<
"The index of the supervisor instance is: " << FESupervisorIndex
1250 __SUP_COUT__ <<
"...and the interface ID is: " << interfaceIndex << __E__;
1252 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
1253 if(it == allFESupervisorInfo_.end())
1255 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
1256 << interfaceIndex <<
":" << FESupervisorIndex <<
".' \n\n"
1257 <<
"The FE Index doesn't exist. Have you configured the state "
1265 xoap::MessageReference replyMessage = SOAPMessenger::sendWithSOAPReply(
1266 it->second.getDescriptor(),
"MacroMakerSupervisorRequest", txParameters);
1268 __SUP_COUT__ <<
"Response received: "
1269 << SOAPUtilities::translate(replyMessage) << __E__;
1271 SOAPParameters rxParameters;
1272 rxParameters.addParameter(
"Error");
1273 SOAPUtilities::receive(replyMessage, rxParameters);
1275 std::string error = rxParameters.getValue(
"Error");
1276 __SUP_COUTV__(error);
1281 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
1282 << interfaceIndex <<
":" << FESupervisorIndex <<
".' "
1283 <<
"Have you configured the state machine properly?\n\n"
1288 catch(
const xdaq::exception::Exception& e)
1290 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
1291 << interfaceIndex <<
":" << FESupervisorIndex <<
".' "
1292 <<
"Have you configured the state machine properly?\n\n"
1293 << e.what() << __E__;
1301 void MacroMakerSupervisor::readData(HttpXmlDocument& xmldoc,
1303 const std::string& username)
1305 __SUP_COUT__ <<
"@@@@@@@ MacroMaker wants to read data @@@@@@@@" << __E__;
1306 std::string Address = CgiDataUtilities::getData(cgi,
"Address");
1307 std::string interfaceIndexArray = CgiDataUtilities::getData(cgi,
"interfaceIndex");
1308 std::string supervisorIndexArray = CgiDataUtilities::getData(cgi,
"supervisorIndex");
1310 StringMacros::decodeURIComponent(CgiDataUtilities::getData(cgi,
"time"));
1311 std::string addressFormatStr = CgiDataUtilities::getData(cgi,
"addressFormatStr");
1312 std::string dataFormatStr = CgiDataUtilities::getData(cgi,
"dataFormatStr");
1314 std::string interfaces = CgiDataUtilities::postData(cgi,
"interfaces");
1316 __SUP_COUT__ <<
"Read Address: " << Address << __E__;
1317 __SUP_COUTV__(interfaces);
1319 SOAPParameters txParameters;
1320 txParameters.addParameter(
"Request",
"UniversalRead");
1321 txParameters.addParameter(
"Address", Address);
1323 SOAPParameters rxParameters;
1324 rxParameters.addParameter(
"dataResult");
1325 rxParameters.addParameter(
"Error");
1326 __SUP_COUT__ <<
"Here comes the array from multiselect box for READ, behold: "
1327 << supervisorIndexArray <<
"," << interfaceIndexArray << __E__;
1331 std::vector<std::string> interfaceIndices;
1332 std::istringstream f(interfaceIndexArray);
1334 while(getline(f, s,
','))
1335 interfaceIndices.push_back(s);
1336 std::vector<int> supervisorIndices;
1337 std::istringstream g(supervisorIndexArray);
1339 while(getline(g, t,
','))
1340 supervisorIndices.push_back(std::stoi(t));
1342 for(
unsigned int i = 0; i < supervisorIndices.size(); i++)
1344 unsigned int FESupervisorIndex = supervisorIndices[i];
1345 std::string interfaceIndex = interfaceIndices[i];
1347 txParameters.addParameter(
"InterfaceID", interfaceIndex);
1349 __SUP_COUT__ <<
"The index of the supervisor instance is: " << FESupervisorIndex
1351 __SUP_COUT__ <<
"...and the interface ID is: " << interfaceIndex << __E__;
1353 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
1354 if(it == allFESupervisorInfo_.end())
1356 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
1357 << interfaceIndex <<
":" << FESupervisorIndex <<
".' \n\n"
1358 <<
"The FE Index doesn't exist. Have you configured the state "
1366 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
1367 it->second.getDescriptor(),
"MacroMakerSupervisorRequest", txParameters);
1369 __SUP_COUT__ <<
"Response received: " << SOAPUtilities::translate(retMsg)
1374 SOAPUtilities::receive(retMsg, rxParameters);
1376 std::string error = rxParameters.getValue(
"Error");
1377 __SUP_COUTV__(error);
1382 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
1383 << interfaceIndex <<
":" << FESupervisorIndex <<
".' "
1384 <<
"Have you configured the state machine properly?\n\n"
1389 catch(
const xdaq::exception::Exception& e)
1391 __SUP_SS__ <<
"Error transmitting request to FE Supervisor '"
1392 << interfaceIndex <<
":" << FESupervisorIndex <<
".' "
1393 <<
"Have you configured the state machine properly?\n\n"
1394 << e.what() << __E__;
1398 std::string dataReadResult = rxParameters.getValue(
"dataResult");
1399 __SUP_COUT__ <<
"Data reading result received: " << dataReadResult << __E__;
1400 xmldoc.addTextElementToData(
"readData", dataReadResult);
1401 std::string command =
"r:" + Address +
":" + dataReadResult;
1402 std::string format = addressFormatStr +
":" + dataFormatStr;
1403 appendCommandToHistory(command, format, time, interfaces, username);
1408 void MacroMakerSupervisor::createMacro(HttpXmlDocument& ,
1410 const std::string& username)
1412 __SUP_COUT__ <<
"MacroMaker wants to create a macro!!!!!!!!!" << __E__;
1413 std::string Name = CgiDataUtilities::postData(cgi,
"Name");
1414 std::string Sequence = CgiDataUtilities::postData(cgi,
"Sequence");
1415 std::string Time = CgiDataUtilities::postData(cgi,
"Time");
1417 StringMacros::decodeURIComponent(CgiDataUtilities::postData(cgi,
"Notes"));
1418 std::string isMacroPublic = CgiDataUtilities::getData(cgi,
"isPublic");
1419 std::string isMacroLSBF = CgiDataUtilities::getData(cgi,
"isLSBF");
1421 __SUP_COUTV__(Name);
1422 __SUP_COUTV__(Sequence);
1423 __SUP_COUTV__(Notes);
1424 __SUP_COUTV__(Time);
1425 __SUP_COUTV__(isMacroPublic);
1426 __SUP_COUTV__(isMacroLSBF);
1428 __SUP_COUTV__(MACROS_DB_PATH);
1430 std::string fileName = Name +
".dat";
1431 std::string fullPath;
1432 if(isMacroPublic ==
"true")
1433 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/" + fileName;
1435 fullPath = (std::string)MACROS_DB_PATH + username +
"/" + fileName;
1437 __SUP_COUTV__(fullPath);
1439 std::ofstream macrofile(fullPath.c_str());
1440 if(macrofile.is_open())
1443 macrofile <<
"\"name\":\"" << Name <<
"\",\n";
1444 macrofile <<
"\"sequence\":\"" << Sequence <<
"\",\n";
1445 macrofile <<
"\"time\":\"" << Time <<
"\",\n";
1446 macrofile <<
"\"notes\":\"" << Notes <<
"\",\n";
1447 macrofile <<
"\"LSBF\":\"" << isMacroLSBF <<
"\"\n";
1448 macrofile <<
"}@" << __E__;
1452 __SUP_COUT__ <<
"Unable to open file" << __E__;
1463 void MacroMakerSupervisor::loadMacro(
const std::string& macroName,
1464 std::string& macroString,
1465 const std::string& username )
1467 __SUP_COUTV__(macroName);
1470 std::string fullPath, line;
1472 for(
unsigned int i = 0; i < 2; ++i)
1475 fullPath = (std::string)MACROS_DB_PATH + username +
"/";
1477 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/";
1479 fullPath += macroName;
1480 if(macroName.find(
".dat") != macroName.size() - 4)
1482 __SUP_COUTV__(fullPath);
1484 std::ifstream read(fullPath.c_str());
1489 getline(read, line);
1490 macroString += line;
1497 __SUP_COUT__ <<
"Unable to open file: " << fullPath << __E__;
1501 if(macroString !=
"")
1505 if(macroString ==
"")
1507 __SUP_SS__ <<
"Unable to locate file for macro '" << macroName
1508 <<
"'... does it exist?" << __E__;
1510 ss <<
" Attempted username was '" << username <<
".'" << __E__;
1514 __SUP_COUTV__(macroString);
1518 void MacroMakerSupervisor::loadMacroNames(
1519 const std::string& username,
1520 std::pair<std::vector<std::string> ,
1521 std::vector<std::string> >& returnMacroNames)
1525 std::string fullPath = (std::string)MACROS_DB_PATH + username +
"/";
1526 if((dir = opendir(fullPath.c_str())) != NULL)
1529 while((ent = readdir(dir)) != NULL)
1532 if((
unsigned)strlen(ent->d_name) > 4)
1536 ((fullPath + (std::string)ent->d_name)).c_str());
1541 returnMacroNames.second.push_back(ent->d_name);
1544 __SUP_COUT__ <<
"Unable to open file" << __E__;
1551 __SUP_COUT__ <<
"Looping through privateMacros folder failed! Wrong directory"
1554 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/";
1555 if((dir = opendir(fullPath.c_str())) != NULL)
1558 while((ent = readdir(dir)) != NULL)
1561 if((
unsigned)strlen(ent->d_name) > 4)
1565 ((fullPath + (std::string)ent->d_name)).c_str());
1569 returnMacroNames.first.push_back(ent->d_name);
1573 __SUP_COUT__ <<
"Unable to open file" << __E__;
1580 __SUP_COUT__ << fullPath << __E__;
1581 __SUP_COUT__ <<
"Looping through MacroData folder failed! Wrong directory"
1588 void MacroMakerSupervisor::loadMacros(HttpXmlDocument& xmldoc,
1589 const std::string& username)
1593 std::string returnStr =
"";
1594 std::string fullPath = (std::string)MACROS_DB_PATH + username +
"/";
1595 if((dir = opendir(fullPath.c_str())) != NULL)
1598 while((ent = readdir(dir)) != NULL)
1601 if((
unsigned)strlen(ent->d_name) > 4)
1605 ((fullPath + (std::string)ent->d_name)).c_str());
1608 std::stringstream buffer;
1611 getline(read, line);
1615 returnStr += buffer.str();
1620 __SUP_COUT__ <<
"Unable to open file" << __E__;
1623 std::string returnMacroStr = returnStr.substr(0, returnStr.size() - 1);
1625 __SUP_COUT__ <<
"Loading existing macros! " << returnMacroStr << __E__;
1628 xmldoc.addTextElementToData(
"returnMacroStr", returnMacroStr);
1632 __SUP_COUT__ <<
"Looping through privateMacros folder failed! Wrong directory"
1635 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/";
1637 if((dir = opendir(fullPath.c_str())) != NULL)
1640 while((ent = readdir(dir)) != NULL)
1643 if((
unsigned)strlen(ent->d_name) > 4)
1647 ((fullPath + (std::string)ent->d_name)).c_str());
1650 std::stringstream buffer;
1653 getline(read, line);
1657 returnStr += buffer.str();
1661 __SUP_COUT__ <<
"Unable to open file" << __E__;
1664 std::string returnPublicStr = returnStr.substr(0, returnStr.size() - 1);
1665 __SUP_COUT__ <<
"Loading existing public macros: " << returnPublicStr << __E__;
1667 xmldoc.addTextElementToData(
"returnPublicStr", returnPublicStr);
1671 __SUP_COUT__ << fullPath << __E__;
1672 __SUP_COUT__ <<
"Looping through MacroData folder failed! Wrong directory"
1678 void MacroMakerSupervisor::appendCommandToHistory(std::string Command,
1681 std::string Interfaces,
1682 const std::string& username)
1684 std::string fileName =
"history.hist";
1685 std::string fullPath = (std::string)MACROS_HIST_PATH + username +
"/" + fileName;
1686 __SUP_COUT__ << fullPath << __E__;
1687 std::ofstream histfile(fullPath.c_str(), std::ios::app);
1688 if(histfile.is_open())
1691 histfile <<
"\"Command\":\"" << Command <<
"\",\n";
1692 histfile <<
"\"Format\":\"" << Format <<
"\",\n";
1693 histfile <<
"\"Time\":\"" << Time <<
"\",\n";
1694 histfile <<
"\"Interfaces\":\"" << Interfaces <<
"\"\n";
1695 histfile <<
"}#" << __E__;
1699 __SUP_COUT__ <<
"Unable to open history.hist" << __E__;
1703 void MacroMakerSupervisor::appendCommandToHistory(std::string feClass,
1705 std::string macroType,
1706 std::string macroName,
1707 std::string inputArgs,
1708 std::string outputArgs,
1710 const std::string& username)
1713 auto feHistoryIt = lastFeCommandToHistory_.find(username);
1714 if(feHistoryIt != lastFeCommandToHistory_.end() && feHistoryIt->second.size() == 7 &&
1715 feHistoryIt->second[0] == feClass && feHistoryIt->second[1] == feUID &&
1716 feHistoryIt->second[2] == macroType && feHistoryIt->second[3] == macroName &&
1717 feHistoryIt->second[4] == inputArgs && feHistoryIt->second[5] == outputArgs &&
1718 feHistoryIt->second[6] == (saveOutputs ?
"1" :
"0"))
1720 __SUP_COUTT__ <<
"Not saving repeat command to history from user " << username
1725 std::string fileName =
"FEhistory.hist";
1726 std::string fullPath = (std::string)MACROS_HIST_PATH + username +
"/" + fileName;
1727 __SUP_COUT__ << fullPath << __E__;
1728 std::ofstream histfile(fullPath.c_str(), std::ios::app);
1729 if(histfile.is_open())
1732 histfile <<
"\"feClass\":\"" << feClass <<
"\",\n";
1733 histfile <<
"\"feUID\":\"" << feUID <<
"\",\n";
1734 histfile <<
"\"macroType\":\"" << macroType <<
"\",\n";
1735 histfile <<
"\"macroName\":\"" << macroName <<
"\",\n";
1736 histfile <<
"\"inputArgs\":\"" << inputArgs <<
"\",\n";
1737 histfile <<
"\"outputArgs\":\"" << outputArgs <<
"\",\n";
1739 histfile <<
"\"saveOutputs\":\"" << 1 <<
"\"\n";
1741 histfile <<
"\"saveOutputs\":\"" << 0 <<
"\"\n";
1742 histfile <<
"}#" << __E__;
1745 lastFeCommandToHistory_[username].clear();
1746 feHistoryIt = lastFeCommandToHistory_.find(username);
1747 feHistoryIt->second.push_back(feClass);
1748 feHistoryIt->second.push_back(feUID);
1749 feHistoryIt->second.push_back(macroType);
1750 feHistoryIt->second.push_back(macroName);
1751 feHistoryIt->second.push_back(inputArgs);
1752 feHistoryIt->second.push_back(outputArgs);
1753 feHistoryIt->second.push_back((saveOutputs ?
"1" :
"0"));
1756 __SUP_COUT__ <<
"Unable to open FEhistory.hist" << __E__;
1761 void MacroMakerSupervisor::loadFEMacroSequences(HttpXmlDocument& xmldoc,
1762 const std::string& username)
1766 std::string fullPath = (std::string)MACROS_SEQUENCE_PATH + username +
"/";
1767 std::string sequences =
"";
1768 if((dir = opendir(fullPath.c_str())) != NULL)
1771 while((ent = readdir(dir)) != NULL)
1775 ((fullPath + (std::string)ent->d_name)).c_str());
1779 sequences = sequences + ent->d_name +
";";
1782 __SUP_COUT__ <<
"Unable to open file" << __E__;
1788 __SUP_COUT__ <<
"Looping through MacroSequence/" + username +
1789 " folder failed! Wrong directory"
1794 xmldoc.addTextElementToData(
"FEsequences", sequences);
1799 void MacroMakerSupervisor::saveFEMacroSequence(cgicc::Cgicc& cgi,
1800 const std::string& username)
1803 std::string name = CgiDataUtilities::postData(cgi,
"sequenceName");
1804 std::string FEsequence =
1805 StringMacros::decodeURIComponent(CgiDataUtilities::postData(cgi,
"FEsequence"));
1807 __SUP_COUTV__(name);
1808 __SUP_COUTV__(FEsequence);
1811 std::string fullPath =
1812 (std::string)MACROS_SEQUENCE_PATH + username +
"/" + name +
".dat";
1813 __SUP_COUT__ << fullPath << __E__;
1814 std::ofstream seqfile(fullPath.c_str(), std::ios::app);
1815 if(seqfile.is_open())
1818 seqfile << FEsequence << __E__;
1822 __SUP_COUT__ <<
"Unable to open " << name <<
".dat" << __E__;
1826 void MacroMakerSupervisor::getFEMacroSequence(HttpXmlDocument& xmldoc,
1828 const std::string& username)
1830 std::string sequenceName = CgiDataUtilities::getData(cgi,
"name");
1832 __SUP_COUTV__(sequenceName);
1835 std::string fullPath =
1836 (std::string)MACROS_SEQUENCE_PATH + username +
"/" + sequenceName +
".dat";
1837 __SUP_COUT__ << fullPath << __E__;
1839 std::ifstream read(fullPath.c_str());
1841 unsigned long long fileSize;
1845 read.seekg(0, std::ios::end);
1846 fileSize = read.tellg();
1847 response =
new char[fileSize + 1];
1848 response[fileSize] =
'\0';
1849 read.seekg(0, std::ios::beg);
1852 read.read(response, fileSize);
1855 xmldoc.addTextElementToData(
"FEsequence", &response[0]);
1861 __SUP_COUT__ <<
"Unable to open " << fullPath <<
"!" << __E__;
1862 xmldoc.addTextElementToData(
"error",
"ERROR");
1867 void MacroMakerSupervisor::deleteFEMacroSequence(cgicc::Cgicc& cgi,
1868 const std::string& username)
1870 std::string sequenceName = CgiDataUtilities::getData(cgi,
"name");
1872 __SUP_COUTV__(sequenceName);
1875 std::string fullPath =
1876 (std::string)MACROS_SEQUENCE_PATH + username +
"/" + sequenceName +
".dat";
1877 __SUP_COUT__ << fullPath << __E__;
1879 std::remove(fullPath.c_str());
1880 __SUP_COUT__ <<
"Successfully deleted " << fullPath;
1884 void MacroMakerSupervisor::loadHistory(HttpXmlDocument& xmldoc,
1885 const std::string& username)
1887 std::string fileName = MACROS_HIST_PATH + username +
"/" +
"history.hist";
1889 std::ifstream read(fileName.c_str());
1890 __SUP_COUT__ << fileName << __E__;
1896 unsigned long long fileSz, i = 0, MAX_HISTORY_SIZE = 100000;
1900 read.seekg(0, std::ios::end);
1901 fileSz = read.tellg();
1902 returnStr =
new char[fileSz + 1];
1903 returnStr[fileSz] =
'\0';
1904 read.seekg(0, std::ios::beg);
1907 read.read(returnStr, fileSz);
1911 if(fileSz > MAX_HISTORY_SIZE)
1913 i = fileSz - MAX_HISTORY_SIZE;
1914 for(; i < fileSz; ++i)
1915 if(returnStr[i] ==
'#')
1924 FILE* fp = fopen(fileName.c_str(),
"w");
1928 __SS__ <<
"Big problem with macromaker history file: " << fileName
1932 fwrite(&returnStr[i], fileSz - i, 1, fp);
1936 __SUP_COUT__ <<
"Loading user history! " << __E__;
1939 returnStr[fileSz - 2] =
'\0';
1941 xmldoc.addTextElementToData(
"returnHistStr", &returnStr[i]);
1946 __SUP_COUT__ <<
"Unable to open history.hist" << __E__;
1951 void MacroMakerSupervisor::loadFEHistory(HttpXmlDocument& xmldoc,
1952 const std::string& username)
1954 std::string fileName = MACROS_HIST_PATH + username +
"/" +
"FEhistory.hist";
1956 std::ifstream read(fileName.c_str());
1957 __SUP_COUT__ << fileName << __E__;
1959 if(!read.is_open() && username != WebUsers::DEFAULT_ADMIN_USERNAME)
1961 __SUP_COUT__ <<
"Unable to open FE history.hist.. Defaulting to admin's FE "
1962 "history as starting point."
1966 MACROS_HIST_PATH + WebUsers::DEFAULT_ADMIN_USERNAME +
"/" +
"FEhistory.hist";
1967 read.open(fileName.c_str());
1974 unsigned long long fileSize;
1975 unsigned long long i = 0;
1976 unsigned long long MAX_HISTORY_SIZE = 100000;
1979 read.seekg(0, std::ios::end);
1980 fileSize = read.tellg();
1981 returnStr =
new char[fileSize + 1];
1982 returnStr[fileSize] =
'\0';
1983 read.seekg(0, std::ios::beg);
1986 read.read(returnStr, fileSize);
1990 if(fileSize > MAX_HISTORY_SIZE)
1992 i = fileSize - MAX_HISTORY_SIZE;
1993 for(; i < fileSize; ++i)
1995 if(returnStr[i] ==
'#')
2005 FILE* fp = fopen(fileName.c_str(),
"w");
2009 __SS__ <<
"Big problem with FE history file: " << fileName << __E__;
2012 fwrite(&returnStr[i], fileSize - i, 1, fp);
2016 __SUP_COUT__ <<
"Loading user history! " << __E__;
2019 returnStr[fileSize - 2] =
'\0';
2021 xmldoc.addTextElementToData(
"returnHistStr", &returnStr[i]);
2026 __SUP_COUT__ <<
"Unable to open FE history.hist" << __E__;
2031 void MacroMakerSupervisor::deleteMacro(HttpXmlDocument& xmldoc,
2033 const std::string& username)
2035 std::string MacroName = CgiDataUtilities::getData(cgi,
"MacroName");
2036 std::string isMacroPublic = CgiDataUtilities::getData(cgi,
"isPublic");
2038 std::string fileName = MacroName +
".dat";
2039 std::string fullPath;
2040 if(isMacroPublic ==
"true")
2041 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/" + fileName;
2043 fullPath = (std::string)MACROS_DB_PATH + username +
"/" + fileName;
2045 __SUP_COUT__ << fullPath << __E__;
2047 std::remove(fullPath.c_str());
2048 __SUP_COUT__ <<
"Successfully deleted " << MacroName;
2049 xmldoc.addTextElementToData(
"deletedMacroName", MacroName);
2053 void MacroMakerSupervisor::editMacro(HttpXmlDocument& xmldoc,
2055 const std::string& username)
2057 std::string oldMacroName = CgiDataUtilities::postData(cgi,
"oldMacroName");
2058 std::string newMacroName = CgiDataUtilities::postData(cgi,
"newMacroName");
2059 std::string FESequence = CgiDataUtilities::postData(cgi,
"FEsequence");
2060 std::string Time = CgiDataUtilities::postData(cgi,
"Time");
2062 StringMacros::decodeURIComponent(CgiDataUtilities::postData(cgi,
"Notes"));
2064 std::string isMacroPublic = CgiDataUtilities::getData(cgi,
"isPublic");
2065 std::string isMacroLSBF = CgiDataUtilities::getData(cgi,
"isLSBF");
2067 __SUP_COUTV__(oldMacroName);
2068 __SUP_COUTV__(newMacroName);
2069 __SUP_COUTV__(FESequence);
2070 __SUP_COUTV__(Notes);
2071 __SUP_COUTV__(Time);
2072 __SUP_COUTV__(isMacroPublic);
2073 __SUP_COUTV__(isMacroLSBF);
2075 __SUP_COUTV__(MACROS_DB_PATH);
2077 std::string fileName = oldMacroName +
".dat";
2078 std::string fullPath;
2079 if(isMacroPublic ==
"true")
2080 fullPath = (std::string)MACROS_DB_PATH +
"publicMacros/" + fileName;
2082 fullPath = (std::string)MACROS_DB_PATH + username +
"/" + fileName;
2084 __SUP_COUTV__(fullPath);
2086 std::ofstream macrofile(fullPath.c_str());
2087 if(macrofile.is_open())
2090 macrofile <<
"\"name\":\"" << newMacroName <<
"\",\n";
2091 macrofile <<
"\"FEsequence\":\"" << FESequence <<
"\",\n";
2092 macrofile <<
"\"time\":\"" << Time <<
"\",\n";
2093 macrofile <<
"\"notes\":\"" << Notes <<
"\",\n";
2094 macrofile <<
"\"LSBF\":\"" << isMacroLSBF <<
"\"\n";
2095 macrofile <<
"}@" << __E__;
2099 __SUP_COUT__ <<
"Unable to open file" << __E__;
2101 if(oldMacroName != newMacroName)
2105 rename((MACROS_DB_PATH + username +
"/" + oldMacroName +
".dat").c_str(),
2106 (MACROS_DB_PATH + username +
"/" + newMacroName +
".dat").c_str());
2108 xmldoc.addTextElementToData(
"newMacroName", newMacroName);
2110 xmldoc.addTextElementToData(
"newMacroName",
"ERROR");
2115 void MacroMakerSupervisor::clearHistory(
const std::string& username)
2117 std::string fileName =
"history.hist";
2118 std::string fullPath = (std::string)MACROS_HIST_PATH + username +
"/" + fileName;
2120 std::remove(fullPath.c_str());
2121 __SUP_COUT__ <<
"Successfully deleted " << fullPath;
2125 void MacroMakerSupervisor::clearFEHistory(
const std::string& username)
2127 std::string fileName =
"FEhistory.hist";
2128 std::string fullPath = (std::string)MACROS_HIST_PATH + username +
"/" + fileName;
2130 std::remove(fullPath.c_str());
2131 __SUP_COUT__ <<
"Successfully deleted " << fullPath;
2135 void MacroMakerSupervisor::exportFEMacro(HttpXmlDocument& xmldoc,
2137 const std::string& username)
2139 std::string macroName = CgiDataUtilities::getData(cgi,
"MacroName");
2140 std::string pluginName = CgiDataUtilities::getData(cgi,
"PluginName");
2141 std::string macroSequence = CgiDataUtilities::postData(cgi,
"MacroSequence");
2142 std::string macroNotes =
2143 StringMacros::decodeURIComponent(CgiDataUtilities::postData(cgi,
"MacroNotes"));
2145 __SUP_COUTV__(pluginName);
2146 __SUP_COUTV__(macroName);
2147 __SUP_COUTV__(macroSequence);
2150 for(
unsigned int i = 0; i < macroNotes.length(); ++i)
2151 if(macroNotes[i] ==
'\r' || macroNotes[i] ==
'\n')
2152 macroNotes[i] =
' ';
2153 __SUP_COUTV__(macroNotes);
2155 std::stringstream ss(macroSequence);
2156 std::string command;
2157 std::vector<std::string> commands;
2159 while(getline(ss, command,
','))
2160 commands.push_back(command);
2162 __SUP_COUTV__(StringMacros::vectorToString(commands));
2164 std::map<std::string , std::set<std::string> >
2165 specialsCodeMap = CodeEditor::getSpecialsMap();
2168 auto specialsCodeMapIt = specialsCodeMap.find(CodeEditor::SPECIAL_TYPE_FEInterface);
2169 if(specialsCodeMapIt == specialsCodeMap.end())
2172 <<
"Could not find any FE Interface plugins in source code. Does MacroMaker "
2173 <<
"have access to the source code? Check that the Supervisor context places "
2175 <<
"location with access to the source code." << __E__;
2180 std::string headerFile = pluginName +
".h";
2181 std::string sourceFile = pluginName +
"_interface.cc";
2182 bool foundHeaderFile =
false;
2183 bool foundSourceFile =
false;
2184 for(
const auto& filePath : specialsCodeMapIt->second)
2186 if(!foundHeaderFile && filePath.find(headerFile) != std::string::npos)
2188 foundHeaderFile =
true;
2189 headerFile = filePath;
2190 __SUP_COUT__ <<
"found headerFile=" << filePath << __E__;
2192 if(!foundSourceFile && filePath.find(sourceFile) != std::string::npos)
2194 foundSourceFile =
true;
2195 sourceFile = filePath;
2196 __SUP_COUT__ <<
"found sourceFile=" << filePath << __E__;
2199 if(foundSourceFile && foundHeaderFile)
2203 if(!foundHeaderFile)
2205 __SS__ <<
"Could not find the header file for the FE Interface plugins at '"
2206 << headerFile <<
".' Does MacroMaker "
2207 <<
"have access to the source code? Check that the Supervisor context "
2208 "places MacroMaker in a "
2209 <<
"location with access to the source code." << __E__;
2212 if(!foundSourceFile)
2214 __SS__ <<
"Could not find the source file for the FE Interface plugins at '"
2215 << sourceFile <<
".' Does MacroMaker "
2216 <<
"have access to the source code? Check that the Supervisor context "
2217 "places MacroMaker in a "
2218 <<
"location with access to the source code." << __E__;
2231 char timeBuffer[100];
2234 struct tm* timeinfo;
2237 timeinfo = localtime(&rawtime);
2239 strftime(timeBuffer, 100,
"%b-%d-%Y %I:%M:%S", timeinfo);
2242 std::string contents;
2247 CodeEditor::readFile(CodeEditor::SOURCE_BASE_PATH, sourceFile, contents);
2251 xmldoc.addTextElementToData(
"sourceFile", sourceFile);
2252 xmldoc.addTextElementToData(
"headerFile", headerFile);
2255 if(contents.find(pluginName +
"::" + macroName) != std::string::npos)
2257 __SS__ <<
"The function definition '" << (pluginName +
"::" + macroName)
2258 <<
"(...)' already exists in the source file '" << sourceFile
2259 <<
".' Duplicate functions are not allowed - please rename the macro or "
2260 "modify the source file."
2265 std::stringstream codess;
2266 std::set<std::string> inArgNames, outArgNames;
2273 __SUP_COUTV__(StringMacros::setToString(inArgNames));
2274 __SUP_COUTV__(StringMacros::setToString(outArgNames));
2278 auto insertPos = contents.find(pluginName +
"::" + pluginName);
2279 if(insertPos == std::string::npos)
2281 __SS__ <<
"Could not find the code insert position in the source file '"
2282 << sourceFile <<
".' The FE plugin class constructor must be '"
2283 << pluginName <<
":" << pluginName <<
"' - is this the case?" << __E__;
2286 __SUP_COUTV__(insertPos);
2288 insertPos = contents.find(
"{", insertPos);
2289 if(insertPos == std::string::npos)
2291 __SS__ <<
"Could not find the code insert position in the source file '"
2293 <<
".' The FE plugin class constructor must begin with '{"
2294 <<
"' - is this the case?" << __E__;
2298 __SUP_COUTV__(insertPos);
2300 insert =
"\n\t//registration of FEMacro '" + macroName +
"' generated, " +
2301 timeBuffer +
", by '" + username +
"' using MacroMaker.\n\t" +
2302 "FEVInterface::registerFEMacroFunction(\"" + macroName +
2303 "\",//feMacroName \n\t\t" +
2304 "static_cast<FEVInterface::frontEndMacroFunction_t>(&" + pluginName +
2305 "::" + macroName +
"), //feMacroFunction \n\t\t" +
2306 "std::vector<std::string>{";
2309 for(
const auto& inArg : inArgNames)
2315 insert +=
"\"" + inArg +
"\"";
2318 insert +=
"}, //namesOfInputArgs \n\t\t";
2319 insert +=
"std::vector<std::string>{";
2322 for(
const auto& outArg : outArgNames)
2328 insert +=
"\"" + outArg +
"\"";
2331 insert +=
"}, //namesOfOutputArgs \n\t\t";
2332 insert +=
"1); //requiredUserPermissions \n\n";
2334 __SUP_COUTV__(insert);
2335 contents = contents.substr(0, insertPos) + insert + contents.substr(insertPos);
2340 auto insertPos = contents.rfind(
"DEFINE_OTS_INTERFACE");
2341 if(insertPos == std::string::npos)
2343 __SS__ <<
"Could not find the code insert position in the source file '"
2345 <<
".' The FE plugin class must end with a 'DEFINE_OTS_INTERFACE("
2346 << pluginName <<
")' - is this the case?" << __E__;
2349 __SUP_COUTV__(insertPos);
2353 "============================================================================"
2354 "============================================\n//" +
2355 macroName +
"\n" +
"//\tFEMacro '" + macroName +
"' generated, " +
2356 timeBuffer +
", by '" + username +
"' using MacroMaker.\n" +
2357 "//\tMacro Notes: " + macroNotes +
"\n" +
"void " + pluginName +
2358 "::" + macroName +
"(__ARGS__)\n{\n\t" +
2359 "__CFG_COUT__ << \"# of input args = \" << argsIn.size() << __E__; \n\t" +
2360 "__CFG_COUT__ << \"# of output args = \" << argsOut.size() << __E__; \n\t" +
2361 "for(auto &argIn:argsIn) \n\t\t" +
2362 "__CFG_COUT__ << argIn.first << \": \" << argIn.second << __E__; \n\n\t" +
2363 "//macro commands section \n" + codess.str() +
"\n\n\t" +
2364 "for(auto &argOut:argsOut) \n\t\t" +
2365 "__CFG_COUT__ << argOut.first << \": \" << argOut.second << __E__; \n\n" +
2366 "} //end " + macroName +
"()\n\n";
2369 CodeEditor::writeFile(CodeEditor::SOURCE_BASE_PATH,
2372 "MacroMaker-" + username,
2379 CodeEditor::readFile(CodeEditor::SOURCE_BASE_PATH, headerFile, contents);
2384 auto insertPos = contents.rfind(
"};");
2385 if(insertPos == std::string::npos)
2387 __SS__ <<
"Could not find the code insert position in the header file '"
2389 <<
".' The FE plugin class must end with a '};' - is this the case?"
2394 __SUP_COUTV__(insertPos);
2396 insert =
"\npublic: // FEMacro '" + macroName +
"' generated, " + timeBuffer +
2397 ", by '" + username +
"' using MacroMaker.\n\t" +
"void " + macroName +
2400 __SUP_COUTV__(insert);
2401 CodeEditor::writeFile(CodeEditor::SOURCE_BASE_PATH,
2404 "MacroMaker-" + username,
2412 void MacroMakerSupervisor::exportMacro(HttpXmlDocument& xmldoc,
2414 const std::string& username)
2416 std::string macroName = CgiDataUtilities::getData(cgi,
"MacroName");
2417 std::string macroSequence = CgiDataUtilities::postData(cgi,
"MacroSequence");
2418 std::string macroNotes =
2419 StringMacros::decodeURIComponent(CgiDataUtilities::postData(cgi,
"MacroNotes"));
2421 __SUP_COUTV__(macroName);
2422 __SUP_COUTV__(macroSequence);
2425 for(
unsigned int i = 0; i < macroNotes.length(); ++i)
2426 if(macroNotes[i] ==
'\r' || macroNotes[i] ==
'\n')
2427 macroNotes[i] =
' ';
2428 __SUP_COUTV__(macroNotes);
2430 std::stringstream ss(macroSequence);
2431 std::string command;
2432 std::vector<std::string> commands;
2434 while(getline(ss, command,
','))
2435 commands.push_back(command);
2437 std::string fileName = macroName +
".cc";
2439 std::string fullPath =
2440 __ENV__(
"SERVICE_DATA_PATH") + MACROS_EXPORT_PATH + username +
"/" + fileName;
2441 __SUP_COUT__ << fullPath << __E__;
2442 std::ofstream exportFile(fullPath.c_str(), std::ios::trunc);
2443 if(exportFile.is_open())
2445 exportFile <<
"//Generated Macro Name:\t" << macroName <<
"\n";
2446 exportFile <<
"//Macro Notes: " << macroNotes <<
"\n";
2450 struct tm* timeinfo;
2454 timeinfo = localtime(&rawtime);
2456 strftime(buffer, 100,
"%b-%d-%Y %I:%M:%S", timeinfo);
2457 exportFile <<
"//Generated Time: \t\t" << buffer <<
"\n";
2460 exportFile <<
"//Paste this whole file into an interface to transfer Macro "
2463 createCode(exportFile, commands);
2467 xmldoc.addTextElementToData(
2469 "$USER_DATA/ServiceData/" + MACROS_EXPORT_PATH + username +
"/" + fileName);
2472 __SUP_COUT__ <<
"Unable to open file" << __E__;
2477 void MacroMakerSupervisor::createCode(std::ostream& out,
2478 const std::vector<std::string>& commands,
2479 const std::string& tabOffset,
2481 std::set<std::string>* inArgNames,
2482 std::set<std::string>* outArgNames)
2485 std::set<std::string > argInHasBeenInitializedSet;
2486 bool addressIsVariable, dataIsVariable;
2488 out << tabOffset <<
"{";
2491 << tabOffset <<
"\t"
2492 <<
"char *address \t= new char[universalAddressSize_]{0}; //create address "
2493 "buffer of interface size and init to all 0";
2495 << tabOffset <<
"\t"
2496 <<
"char *data \t\t= new char[universalDataSize_]{0}; //create data buffer "
2497 "of interface size and init to all 0";
2500 << tabOffset <<
"\t"
2501 <<
"uint64_t macroAddress; //create macro address buffer (size 8 bytes)";
2503 << tabOffset <<
"\t"
2504 <<
"uint64_t macroData; //create macro address buffer (size 8 bytes)";
2507 << tabOffset <<
"\t"
2508 <<
"std::map<std::string /*arg name*/,uint64_t /*arg val*/> macroArgs; //create "
2509 "map from arg name to 64-bit number";
2512 for(
unsigned int i = 0; i < commands.size(); i++)
2514 std::stringstream sst(commands[i]);
2516 std::vector<std::string>
2518 while(getline(sst, tokens,
':'))
2519 oneCommand.push_back(tokens);
2520 while(oneCommand.size() < 4)
2521 oneCommand.push_back(
"");
2523 __SUP_COUTV__(StringMacros::vectorToString(oneCommand));
2549 addressIsVariable = isArgumentVariable(oneCommand[2]);
2550 dataIsVariable = isArgumentVariable(oneCommand[3]);
2552 __SUP_COUTV__(addressIsVariable);
2553 __SUP_COUTV__(dataIsVariable);
2555 out <<
"\n\n" << tabOffset <<
"\t// command-#" << i <<
": ";
2557 if(oneCommand[1][0] ==
'w' || oneCommand[1][0] ==
'r')
2559 if(oneCommand[1][0] ==
'w')
2561 else if(oneCommand[1][0] ==
'r')
2564 if(addressIsVariable)
2565 out << oneCommand[2];
2567 out <<
"0x" << oneCommand[2];
2568 out <<
" /*address*/,";
2572 out << oneCommand[3] <<
" /*data*/";
2573 else if(oneCommand[1][0] ==
'w')
2574 out <<
"0x" << oneCommand[3] <<
" /*data*/";
2575 else if(oneCommand[1][0] ==
'r')
2579 else if(oneCommand[1][0] ==
'd')
2581 out <<
"delay(" << oneCommand[2] <<
");\n";
2582 out << tabOffset <<
"\t"
2583 <<
"__CFG_COUT__ << \"Sleeping for... \" << " << oneCommand[2]
2584 <<
" << \" milliseconds \" << __E__;\n";
2585 out << tabOffset <<
"\t"
2586 <<
"usleep(" << oneCommand[2] <<
"*1000 /* microseconds */);\n";
2591 __SS__ <<
"FATAL ERROR: Unknown command '" << oneCommand[1]
2592 <<
"'... command is not w, r or d" << __E__;
2598 if(addressIsVariable)
2600 if(argInHasBeenInitializedSet.find(oneCommand[2]) ==
2601 argInHasBeenInitializedSet.end())
2603 argInHasBeenInitializedSet.emplace(oneCommand[2]);
2608 out << tabOffset <<
"\t"
2609 <<
"macroArgs[\"" << oneCommand[2]
2611 "theXDAQContextConfigTree_.getNode(theConfigurationPath_)."
2614 << tabOffset <<
"\t\t\"" << oneCommand[2]
2615 <<
"\").getValue<uint64_t>();";
2620 inArgNames->emplace(oneCommand[2]);
2623 out << tabOffset <<
"\t"
2624 <<
"macroArgs[\"" << oneCommand[2] <<
"\"] = __GET_ARG_IN__(\""
2625 << oneCommand[2] <<
"\", uint64_t);";
2628 out <<
"\t//get macro address argument";
2630 << tabOffset <<
"\tmemcpy(address,¯oArgs[\"" << oneCommand[2]
2631 <<
"\"],8); //copy macro address argument to buffer";
2635 out << tabOffset <<
"\t"
2636 <<
"macroAddress = 0x" << oneCommand[2]
2637 <<
"; memcpy(address,¯oAddress,8);"
2638 <<
"\t//copy macro address to buffer";
2643 if(oneCommand[1] ==
"w")
2647 if(argInHasBeenInitializedSet.find(oneCommand[3]) ==
2648 argInHasBeenInitializedSet
2651 argInHasBeenInitializedSet.emplace(oneCommand[3]);
2656 inArgNames->emplace(oneCommand[3]);
2660 << tabOffset <<
"\t"
2661 <<
"macroArgs[\"" << oneCommand[3]
2662 <<
"\"] = __GET_ARG_IN__(\"" << oneCommand[3]
2663 <<
"\", uint64_t); //initialize from input arguments";
2669 << tabOffset <<
"\t"
2670 <<
"macroArgs[\"" << oneCommand[3]
2672 "theXDAQContextConfigTree_.getNode(theConfigurationPath_)."
2675 << tabOffset <<
"\t\t\"" << oneCommand[3]
2676 <<
"\").getValue<uint64_t>(); //initialize from "
2677 "configuration tree";
2680 out <<
"\t//get macro data argument";
2682 << tabOffset <<
"\tmemcpy(data,¯oArgs[\"" << oneCommand[3]
2683 <<
"\"],8); //copy macro data argument to buffer";
2688 << tabOffset <<
"\t"
2689 <<
"macroData = 0x" << oneCommand[3] <<
"; memcpy(data,¯oData,8);"
2690 <<
"\t//copy macro data to buffer";
2693 << tabOffset <<
"\t"
2694 <<
"universalWrite(address,data);";
2699 << tabOffset <<
"\t"
2700 <<
"universalRead(address,data);";
2702 std::string outputArgName;
2705 outputArgName = oneCommand[3];
2709 sprintf(str,
"outArg%d", i);
2710 outputArgName = str;
2712 __SUP_COUTV__(outputArgName);
2714 out << tabOffset <<
"\t"
2715 <<
"memcpy(¯oArgs[\"" << outputArgName
2716 <<
"\"],data,8); //copy buffer to argument map";
2721 << tabOffset <<
"\t"
2722 <<
"__SET_ARG_OUT__(\"" << outputArgName <<
"\",macroArgs[\""
2723 << outputArgName <<
"\"]); //update output argument result";
2726 outArgNames->emplace(outputArgName);
2727 argInHasBeenInitializedSet.emplace(
2732 out <<
"\n\n" << tabOffset <<
"\tdelete[] address; //free the memory";
2733 out <<
"\n" << tabOffset <<
"\tdelete[] data; //free the memory";
2734 out <<
"\n" << tabOffset <<
"}";
2736 __SUP_COUT__ <<
"Done with code generation." << __E__;
2742 bool MacroMakerSupervisor::isArgumentVariable(
const std::string& argumentString)
2744 for(
unsigned int i = 0; i < argumentString.length(); ++i)
2747 if(!((argumentString[i] >=
'0' && argumentString[i] <=
'9') ||
2748 (argumentString[i] >=
'a' && argumentString[i] <=
'f') ||
2749 (argumentString[i] >=
'A' && argumentString[i] <=
'F')))
2764 std::string MacroMakerSupervisor::generateHexArray(
const std::string& sourceHexString,
2767 std::stringstream retSs;
2769 std::string srcHexStr = sourceHexString;
2770 __SUP_COUT__ <<
"Translating: \n";
2771 __SUP_COUT__ << srcHexStr << __E__;
2773 if(srcHexStr.size() % 2)
2774 srcHexStr =
"0" + srcHexStr;
2776 numOfBytes = srcHexStr.size() / 2;
2777 retSs <<
"[" << numOfBytes <<
"] = {";
2779 for(
int i = 0; i < numOfBytes * 2; i += 2)
2782 if(!((srcHexStr[i] >=
'0' && srcHexStr[i] <=
'9') ||
2783 (srcHexStr[i] >=
'a' && srcHexStr[i] <=
'f') ||
2784 (srcHexStr[i] >=
'A' && srcHexStr[i] <=
'F')) ||
2785 !((srcHexStr[i + 1] >=
'0' && srcHexStr[i + 1] <=
'9') ||
2786 (srcHexStr[i + 1] >=
'a' && srcHexStr[i + 1] <=
'f') ||
2787 (srcHexStr[i + 1] >=
'A' && srcHexStr[i + 1] <=
'F')))
2795 retSs <<
"0x" << srcHexStr[srcHexStr.size() - 1 - i - 1]
2796 << srcHexStr[srcHexStr.size() - 1 - i];
2800 __SUP_COUT__ << retSs.str() << __E__;
2806 void MacroMakerSupervisor::runFEMacro(HttpXmlDocument& xmldoc,
2808 const WebUsers::RequestUserInfo& userInfo)
2811 __SUP_COUT__ << __E__;
2813 std::string feClassSelected = CgiDataUtilities::getData(cgi,
"feClassSelected");
2814 std::string feUIDSelected =
2815 CgiDataUtilities::getData(cgi,
"feUIDSelected");
2816 std::string macroType = CgiDataUtilities::getData(cgi,
"macroType");
2817 std::string macroName =
2818 StringMacros::decodeURIComponent(CgiDataUtilities::getData(cgi,
"macroName"));
2819 std::string inputArgs = CgiDataUtilities::postData(cgi,
"inputArgs");
2820 std::string outputArgs = CgiDataUtilities::postData(cgi,
"outputArgs");
2821 bool saveOutputs = CgiDataUtilities::getDataAsInt(cgi,
"saveOutputs") == 1;
2832 StringMacros::mapToString(userInfo.getGroupPermissionLevels()));
2834 catch(
const std::runtime_error& e)
2836 __SUP_SS__ <<
"Error processing FE communication request: " << e.what() << __E__;
2837 __SUP_COUT_ERR__ << ss.str();
2838 xmldoc.addTextElementToData(
"Error", ss.str());
2842 __SUP_SS__ <<
"Unknown error processing FE communication request." << __E__;
2847 catch(
const std::exception& e)
2849 ss <<
"Exception message: " << e.what();
2854 __SUP_COUT_ERR__ << ss.str();
2856 xmldoc.addTextElementToData(
"Error", ss.str());
2860 void MacroMakerSupervisor::runFEMacro(HttpXmlDocument& xmldoc,
2861 std::string feClassSelected,
2862 std::string feUIDSelected,
2863 const std::string& macroType,
2864 const std::string& macroName,
2865 const std::string& inputArgs,
2866 const std::string outputArgs,
2868 const std::string& username,
2869 const std::string& userGroupPermissions)
2871 __SUP_COUTV__(feClassSelected);
2872 __SUP_COUTV__(feUIDSelected);
2873 __SUP_COUTV__(macroType);
2874 __SUP_COUTV__(macroName);
2875 __SUP_COUTV__(inputArgs);
2876 __SUP_COUTV__(outputArgs);
2877 __SUP_COUTV__(saveOutputs);
2878 __SUP_COUTV__(username);
2879 __SUP_COUTV__(userGroupPermissions);
2881 appendCommandToHistory(feClassSelected,
2890 std::set<std::string > feUIDs;
2892 if(feUIDSelected ==
"")
2893 feUIDSelected =
"*";
2894 if(feClassSelected ==
"")
2895 feClassSelected =
"*";
2897 if(feClassSelected ==
"" || feUIDSelected ==
"" || macroType ==
"" || macroName ==
"")
2899 __SUP_SS__ <<
"Illegal empty front-end parameter." << __E__;
2902 else if(feUIDSelected !=
"*")
2904 StringMacros::getSetFromString(feUIDSelected, feUIDs);
2909 if(feClassSelected ==
"*")
2911 for(
auto& feTypePair : FEPluginTypetoFEsMap_)
2912 for(
auto& feUID : feTypePair.second)
2913 feUIDs.emplace(feUID);
2917 auto typeIt = FEPluginTypetoFEsMap_.find(feClassSelected);
2918 if(typeIt == FEPluginTypetoFEsMap_.end())
2920 __SUP_SS__ <<
"Illegal front-end type parameter '" << feClassSelected
2921 <<
"' not in list of types." << __E__;
2925 for(
auto& feUID : typeIt->second)
2926 feUIDs.emplace(feUID);
2930 __SUP_COUTV__(StringMacros::setToString(feUIDs));
2932 std::string macroString;
2933 if(macroType ==
"public")
2934 loadMacro(macroName, macroString);
2935 else if(macroType ==
"private")
2936 loadMacro(macroName, macroString, username);
2938 __SUP_COUTV__(macroString);
2945 std::string filename =
"/macroOutput_" + std::to_string(time(0)) +
"_" +
2946 std::to_string(clock()) +
".txt";
2948 __SUP_COUTV__(filename);
2949 fp = fopen((CodeEditor::OTSDAQ_DATA_PATH + filename).c_str(),
"w");
2952 __SUP_SS__ <<
"Failed to open file to save macro output '"
2953 << CodeEditor::OTSDAQ_DATA_PATH << filename <<
"'..." << __E__;
2957 fprintf(fp,
"############################\n");
2959 "### Running '%s' at time %s\n",
2961 StringMacros::getTimestampString().c_str());
2963 "### \t Target front-ends (count=%lu): %s\n",
2965 StringMacros::setToString(feUIDs).c_str());
2966 fprintf(fp,
"### \t\t Inputs: %s\n", inputArgs.c_str());
2967 fprintf(fp,
"############################\n\n\n");
2969 xmldoc.addTextElementToData(
"feMacroRunArgs_name",
"Filename");
2970 xmldoc.addTextElementToData(
"feMacroRunArgs_value",
2971 "$OTSDAQ_DATA/" + filename);
2975 for(
auto& feUID : feUIDs)
2977 auto feIt = FEtoSupervisorMap_.find(feUID);
2978 if(feIt == FEtoSupervisorMap_.end())
2980 __SUP_SS__ <<
"Destination front end interface ID '" << feUID
2981 <<
"' was not found in the list of front ends." << __E__;
2982 ss <<
"\n\nHere is the map:\n\n"
2983 << StringMacros::mapToString(FEtoSupervisorMap_) << __E__;
2987 unsigned int FESupervisorIndex = feIt->second;
2988 __SUP_COUT__ <<
"Found supervisor index: " << FESupervisorIndex << __E__;
2990 SupervisorInfoMap::iterator it = allFESupervisorInfo_.find(FESupervisorIndex);
2991 if(it == allFESupervisorInfo_.end())
2994 <<
"Error transmitting request to FE Supervisor '" << feUID <<
":"
2995 << FESupervisorIndex <<
".' \n\n"
2996 <<
"The FE Supervisor Index does not exist. Have you configured "
2997 "the state machine properly?"
3003 SOAPParameters txParameters;
3004 if(macroType ==
"fe")
3005 txParameters.addParameter(
"Request",
"RunInterfaceMacro");
3007 txParameters.addParameter(
"Request",
"RunMacroMakerMacro");
3008 txParameters.addParameter(
"InterfaceID", feUID);
3009 if(macroType ==
"fe")
3010 txParameters.addParameter(
"feMacroName", macroName);
3013 txParameters.addParameter(
"macroName", macroName);
3014 txParameters.addParameter(
"macroString", macroString);
3016 txParameters.addParameter(
"inputArgs", inputArgs);
3017 txParameters.addParameter(
"outputArgs", outputArgs);
3018 txParameters.addParameter(
"userPermissions", userGroupPermissions);
3020 SOAPParameters rxParameters;
3022 rxParameters.addParameter(
"outputArgs");
3023 rxParameters.addParameter(
"Error");
3028 "Running '%s' at time %s\n",
3030 StringMacros::getTimestampString().c_str());
3032 "\t Target front-end: '%s::%s'\n",
3033 FEtoPluginTypeMap_[feUID].c_str(),
3036 "\t\t Inputs: %s\n",
3037 StringMacros::decodeURIComponent(inputArgs).c_str());
3041 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
3042 it->second.getDescriptor(),
3043 "MacroMakerSupervisorRequest",
3046 __SUP_COUT__ <<
"Received response message: "
3047 << SOAPUtilities::translate(retMsg) << __E__;
3049 SOAPUtilities::receive(retMsg, rxParameters);
3051 __SUP_COUT__ <<
"Received it " << __E__;
3054 std::string outputResults = rxParameters.getValue(
"outputArgs");
3055 std::string error = rxParameters.getValue(
"Error");
3058 __SUP_COUT__ <<
"outputArgs = " << outputResults << __E__;
3062 __SS__ <<
"Attempted FE Macro Failed. Attempted target "
3063 <<
"was UID=" << feUID
3064 <<
" at feSupervisorID=" << FESupervisorIndex <<
"." << __E__;
3065 ss <<
"\n\n The error was:\n\n" << error << __E__;
3066 __SUP_COUT_ERR__ <<
"\n" << ss.str();
3067 xmldoc.addTextElementToData(
"Error", ss.str());
3075 DOMElement* feMacroExecParent =
3076 xmldoc.addTextElementToData(
"feMacroExec", macroName);
3078 xmldoc.addTextElementToParent(
3079 "exec_time", StringMacros::getTimestampString(), feMacroExecParent);
3080 xmldoc.addTextElementToParent(
"fe_uid", feUID, feMacroExecParent);
3081 xmldoc.addTextElementToParent(
3082 "fe_type", FEtoPluginTypeMap_[feUID], feMacroExecParent);
3083 xmldoc.addTextElementToParent(
3084 "fe_context", it->second.getContextName(), feMacroExecParent);
3085 xmldoc.addTextElementToParent(
3086 "fe_supervisor", it->second.getName(), feMacroExecParent);
3087 xmldoc.addTextElementToParent(
3088 "fe_hostname", it->second.getHostname(), feMacroExecParent);
3090 std::istringstream inputStream(outputResults);
3091 std::string splitVal, argName, argValue;
3092 while(getline(inputStream, splitVal,
';'))
3094 std::istringstream pairInputStream(splitVal);
3095 getline(pairInputStream, argName,
',');
3096 getline(pairInputStream, argValue,
',');
3101 "\t\t Output '%s' = %s\n",
3103 StringMacros::decodeURIComponent(argValue).c_str());
3107 xmldoc.addTextElementToParent(
3108 "outputArgs_name", argName, feMacroExecParent);
3109 xmldoc.addTextElementToParent(
3110 "outputArgs_value", argValue, feMacroExecParent);
3112 __SUP_COUT__ << argName <<
": " << argValue << __E__;
3130 void MacroMakerSupervisor::getFEMacroList(HttpXmlDocument& xmldoc,
3131 const std::string& username)
3133 __SUP_COUT__ <<
"Getting FE Macro list" << __E__;
3135 SOAPParameters txParameters;
3136 txParameters.addParameter(
"Request",
"GetInterfaceMacros");
3138 SOAPParameters rxParameters;
3139 rxParameters.addParameter(
"FEMacros");
3141 std::string oneInterface;
3142 std::string rxFEMacros;
3146 for(
auto& appInfo : allFESupervisorInfo_)
3148 __SUP_COUT__ <<
"FESupervisor LID = " << appInfo.second.getId()
3149 <<
" name = " << appInfo.second.getName() << __E__;
3151 xoap::MessageReference retMsg = SOAPMessenger::sendWithSOAPReply(
3152 appInfo.second.getDescriptor(),
"MacroMakerSupervisorRequest", txParameters);
3153 SOAPUtilities::receive(retMsg, rxParameters);
3155 rxFEMacros = rxParameters.getValue(
"FEMacros");
3157 __SUP_COUT__ <<
"FE Macros received: \n" << rxFEMacros << __E__;
3159 std::istringstream allInterfaces(rxFEMacros);
3160 while(std::getline(allInterfaces, oneInterface))
3164 xmldoc.addTextElementToData(
"FEMacros", oneInterface);
3170 std::pair<std::vector<std::string> ,
3171 std::vector<std::string> >
3173 loadMacroNames(username, macroNames);
3175 __SUP_COUT__ <<
"Public macro count: " << macroNames.first.size() << __E__;
3176 __SUP_COUT__ <<
"Private macro count: " << macroNames.second.size() << __E__;
3178 std::string macroString;
3187 for(
int i = 0; i < 2; ++i)
3188 for(
auto& macroName : (i ? macroNames.second : macroNames.first))
3191 loadMacro(macroName, macroString, username);
3194 FEVInterface::macroStruct_t macro(macroString);
3196 std::stringstream xmlMacroStream;
3197 xmlMacroStream << macro.macroName_;
3198 xmlMacroStream <<
":"
3200 xmlMacroStream <<
":" << macro.namesOfInputArguments_.size();
3201 for(
auto& inputArg : macro.namesOfInputArguments_)
3202 xmlMacroStream <<
":" << inputArg;
3203 xmlMacroStream <<
":" << macro.namesOfOutputArguments_.size();
3204 for(
auto& inputArg : macro.namesOfOutputArguments_)
3205 xmlMacroStream <<
":" << inputArg;
3207 xmldoc.addTextElementToData(i ?
"PrivateMacro" :
"PublicMacro",
3208 xmlMacroStream.str());
virtual void forceSupervisorPropertyValues(void) override