1 #include "otsdaq-utilities/Logbook/LogbookSupervisor.h"
20 const std::string LOGBOOK_PATH = __ENV__(
"LOGBOOK_DATA_PATH") + std::string(
"/");
21 #define LOGBOOK_EXPERIMENT_LIST_PATH LOGBOOK_PATH + "experiment_list.xml"
22 #define LOGBOOK_EXPERIMENT_DIR_PREFACE "log_"
23 #define LOGBOOK_UPLOADS_PATH "uploads/" // within experiment directory
24 #define LOGBOOK_LOGBOOKS_PATH "logbooks/"
25 #define LOGBOOK_PREVIEWS_PATH "previews/"
26 #define LOGBOOK_FILE_PREFACE "entries_"
27 #define LOGBOOK_FILE_EXTENSION ".xml"
29 #define ACTIVE_EXPERIMENT_PATH LOGBOOK_PATH + "active_experiment.txt"
30 #define REMOVE_EXPERIMENT_LOG_PATH LOGBOOK_PATH + "removed_experiments.log"
32 #define XML_ADMIN_STATUS "logbook_admin_status"
33 #define XML_STATUS "logbook_status"
34 #define XML_MOST_RECENT_DAY "most_recent_day"
35 #define XML_EXPERIMENTS_ROOT "experiments"
36 #define XML_EXPERIMENT "experiment"
37 #define XML_ACTIVE_EXPERIMENT "active_experiment"
38 #define XML_EXPERIMENT_CREATE "create_time"
39 #define XML_EXPERIMENT_CREATOR "creator"
41 #define XML_LOGBOOK_ENTRY "logbook_entry"
42 #define XML_LOGBOOK_ENTRY_SUBJECT "logbook_entry_subject"
43 #define XML_LOGBOOK_ENTRY_TEXT "logbook_entry_text"
44 #define XML_LOGBOOK_ENTRY_FILE "logbook_entry_file"
45 #define XML_LOGBOOK_ENTRY_TIME "logbook_entry_time"
46 #define XML_LOGBOOK_ENTRY_CREATOR "logbook_entry_creator"
47 #define XML_LOGBOOK_ENTRY_HIDDEN "logbook_entry_hidden"
48 #define XML_LOGBOOK_ENTRY_HIDER "logbook_entry_hider"
49 #define XML_LOGBOOK_ENTRY_HIDDEN_TIME "logbook_entry_hidden_time"
51 #define XML_PREVIEW_INDEX "preview_index"
52 #define LOGBOOK_PREVIEW_FILE "preview.xml"
53 #define LOGBOOK_PREVIEW_UPLOAD_PREFACE "upload_"
58 #define __MF_SUBJECT__ "Logbook"
63 int sendmail(
const char* to,
const char* from,
const char* subject,
const char* message)
66 FILE* mailpipe = popen(
"/usr/lib/sendmail -t",
"w");
69 fprintf(mailpipe,
"To: %s\n", to);
70 fprintf(mailpipe,
"From: %s\n", from);
71 fprintf(mailpipe,
"Subject: %s\n\n", subject);
72 fwrite(message, 1, strlen(message), mailpipe);
73 fwrite(
".\n", 1, 2, mailpipe);
79 perror(
"Failed to invoke sendmail");
85 LogbookSupervisor::LogbookSupervisor(xdaq::ApplicationStub* stub)
86 : CoreSupervisorBase(stub)
87 , allowedFileUploadTypes_({
"image/png",
94 , matchingFileUploadTypes_({
"png",
110 &LogbookSupervisor::MakeSystemLogbookEntry,
111 "MakeSystemLogbookEntry",
120 LogbookSupervisor::~LogbookSupervisor(
void) { destroy(); }
123 void LogbookSupervisor::init(
void)
130 std::string path = LOGBOOK_PATH;
131 DIR* dir = opendir(path.c_str());
134 else if(-1 == mkdir(path.c_str(), 0755))
137 std::stringstream ss;
138 ss << __COUT_HDR_FL__ <<
"Service directory creation failed: " << path
143 path = LOGBOOK_PATH + LOGBOOK_UPLOADS_PATH;
144 dir = opendir(path.c_str());
147 else if(-1 == mkdir((path).c_str(), 0755))
150 __SS__ <<
"Service directory creation failed: " << path << std::endl;
154 path = LOGBOOK_PATH + LOGBOOK_LOGBOOKS_PATH;
155 dir = opendir(path.c_str());
158 else if(-1 == mkdir(path.c_str(), 0755))
161 __SS__ <<
"Service directory creation failed: " << path << std::endl;
166 getActiveExperiment();
167 __COUT__ <<
"Active Experiment is " << activeExperiment_ << std::endl;
168 mostRecentDayIndex_ = 0;
172 void LogbookSupervisor::destroy(
void)
178 void LogbookSupervisor::defaultPage(xgi::Input* , xgi::Output* out)
180 __COUT__ <<
" active experiment " << activeExperiment_ << std::endl;
181 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
182 "src='/WebPath/html/Logbook.html?urn="
183 << this->getApplicationDescriptor()->getLocalId()
184 <<
"&active_experiment=" << activeExperiment_ <<
"'></frameset></html>";
191 void LogbookSupervisor::setSupervisorPropertyDefaults()
193 CorePropertySupervisorBase::setSupervisorProperty(
194 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.UserPermissionsThreshold,
196 "*=1 | CreateExperiment=-1 | RemoveExperiment=-1 | GetExperimentListAdmin=-1 "
197 "| SetActiveExperiment=-1" +
198 " | AdminRemoveRestoreEntry=-1");
204 void LogbookSupervisor::forceSupervisorPropertyValues()
206 CorePropertySupervisorBase::setSupervisorProperty(
207 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
209 CorePropertySupervisorBase::setSupervisorProperty(
210 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.NonXMLRequestTypes,
211 "LogImage | LogReport");
221 void LogbookSupervisor::request(
const std::string& requestType,
223 HttpXmlDocument& xmlOut,
224 const WebUsers::RequestUserInfo& userInfo)
291 if(requestType ==
"CreateExperiment")
309 std::string creator = userInfo.username_;
312 CgiDataUtilities::postData(cgiIn,
"Experiment"), creator, &xmlOut);
314 __COUT__ <<
"Created" << std::endl;
316 else if(requestType ==
"RemoveExperiment")
328 std::string remover = userInfo.username_;
330 CgiDataUtilities::postData(cgiIn,
"Experiment"), remover, &xmlOut);
332 else if(requestType ==
"GetExperimentList")
336 if(userInfo.permissionLevel_ >=
337 CoreSupervisorBase::getSupervisorPropertyUserPermissionsThreshold(
338 "GetExperimentListAdmin"))
340 xmlOut.addTextElementToData(
"is_admin",
"0");
345 xmlOut.addTextElementToData(
"is_admin",
"1");
346 getExperiments(&xmlOut);
348 else if(requestType ==
"SetActiveExperiment")
359 webUserSetActiveExperiment(CgiDataUtilities::postData(cgiIn,
"Experiment"),
362 else if(requestType ==
"RefreshLogbook")
367 std::string Date = CgiDataUtilities::postData(cgiIn,
"Date");
368 std::string Duration = CgiDataUtilities::postData(cgiIn,
"Duration");
371 unsigned char duration;
372 sscanf(Date.c_str(),
"%li", &date);
373 sscanf(Duration.c_str(),
"%hhu", &duration);
375 __COUT__ <<
"date " << date <<
" duration " << (int)duration << std::endl;
376 std::stringstream str;
377 refreshLogbook(date, duration, &xmlOut, (std::ostringstream*)&str);
378 __COUT__ << str.str() << std::endl;
380 else if(requestType ==
"PreviewEntry")
389 std::string EntryText = cgiIn(
"EntryText");
390 __COUT__ <<
"EntryText " << EntryText << std::endl << std::endl;
391 std::string EntrySubject = cgiIn(
"EntrySubject");
392 __COUT__ <<
"EntrySubject " << EntrySubject << std::endl << std::endl;
395 std::string creator = userInfo.username_;
397 savePostPreview(EntrySubject, EntryText, cgiIn.getFiles(), creator, &xmlOut);
401 else if(requestType ==
"ApproveEntry")
406 std::string PreviewNumber = CgiDataUtilities::postData(cgiIn,
"PreviewNumber");
407 std::string Approve = CgiDataUtilities::postData(cgiIn,
"Approve");
409 movePreviewEntry(PreviewNumber, Approve ==
"1", &xmlOut);
411 else if(requestType ==
"AdminRemoveRestoreEntry")
419 std::string EntryId = CgiDataUtilities::postData(cgiIn,
"EntryId");
420 bool Hide = CgiDataUtilities::postData(cgiIn,
"Hide") ==
"1" ?
true :
false;
423 std::string hider = userInfo.username_;
425 hideLogbookEntry(EntryId, Hide, hider);
427 xmlOut.addTextElementToData(XML_ADMIN_STATUS,
"1");
430 __COUT__ <<
"requestType request not recognized." << std::endl;
437 void LogbookSupervisor::nonXmlRequest(
const std::string& requestType,
440 const WebUsers::RequestUserInfo& )
446 if(requestType ==
"LogImage")
448 std::string src = CgiDataUtilities::getData(cgiIn,
"src");
449 __COUT__ <<
" Get Log Image " << src << std::endl;
451 out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
452 "src='/WebPath/html/LogbookImage.html?urn="
453 << this->getApplicationDescriptor()->getLocalId() <<
"&src=" << src
454 <<
"'></frameset></html>";
456 else if(requestType ==
"LogReport")
458 std::string activeExperiment =
459 CgiDataUtilities::getData(cgiIn,
"activeExperiment");
460 __COUT__ <<
" Start Log Report for " << activeExperiment << std::endl;
462 out <<
"<!DOCTYPE HTML><html lang='en'><header><title>ots Logbook "
463 "Reports</title></header><frameset col='100%' row='100%'><frame "
464 "src='/WebPath/html/LogbookReport.html?urn="
465 << this->getApplicationDescriptor()->getLocalId()
466 <<
"&activeExperiment=" << activeExperiment <<
"'></frameset></html>";
469 __COUT__ <<
"requestType request not recognized." << std::endl;
476 xoap::MessageReference LogbookSupervisor::MakeSystemLogbookEntry(
477 xoap::MessageReference msg)
479 SOAPParameters parameters(
"EntryText");
482 SOAPUtilities::receive(msg, parameters);
483 std::string EntryText = parameters.getValue(
"EntryText");
485 __COUT__ <<
"Received External Supervisor System Entry " << EntryText << std::endl;
486 __COUT__ <<
"Active Experiment is " << activeExperiment_ << std::endl;
488 std::string retStr =
"Success";
491 logDirPath = (std::string)LOGBOOK_PATH + (std::string)LOGBOOK_LOGBOOKS_PATH +
492 (std::string)LOGBOOK_EXPERIMENT_DIR_PREFACE + activeExperiment_;
494 char dayIndexStr[20];
495 HttpXmlDocument logXml;
497 xercesc::DOMElement* entryEl;
500 if(activeExperiment_ ==
"")
502 retStr =
"Warning - Currently, no Active Experiment.";
503 __COUT__ << retStr << std::endl;
508 dir = opendir(logDirPath.c_str());
511 retStr =
"Error - Active Experiment directory missing.";
512 __COUT__ << retStr << std::endl;
517 sprintf(dayIndexStr,
"%6.6lu", time(0) / (60 * 60 * 24));
519 logPath = logDirPath +
"/" + LOGBOOK_FILE_PREFACE + activeExperiment_ +
"_" +
520 (std::string)dayIndexStr + LOGBOOK_FILE_EXTENSION;
521 __COUT__ <<
"logPath " << logPath << std::endl;
523 logXml.loadXmlDocument(logPath);
534 entryEl = logXml.addTextElementToData(XML_LOGBOOK_ENTRY);
540 logXml.addTextElementToParent(XML_LOGBOOK_ENTRY_TIME, fileIndex, entryEl);
541 logXml.addTextElementToParent(XML_LOGBOOK_ENTRY_CREATOR,
"SYSTEM LOG", entryEl);
542 logXml.addTextElementToParent(XML_LOGBOOK_ENTRY_TEXT, EntryText, entryEl);
543 logXml.addTextElementToParent(XML_LOGBOOK_ENTRY_SUBJECT,
"System Log", entryEl);
545 logXml.saveXmlDocument(logPath);
550 SOAPParameters retParameters(
"Status", retStr);
555 return SOAPUtilities::makeSOAPMessageReference(
"LogbookEntryStatusResponse",
600 std::string LogbookSupervisor::getActiveExperiment()
602 FILE* fp = fopen(std::string((std::string)ACTIVE_EXPERIMENT_PATH).c_str(),
"r");
604 activeExperiment_ =
"";
608 if(!fgets(line, 100, fp))
614 if(line[strlen(line) - 2] ==
'\r')
615 line[strlen(line) - 2] =
'\0';
616 else if(line[strlen(line) - 1] ==
'\n')
617 line[strlen(line) - 1] =
'\0';
619 activeExperiment_ = line;
622 return activeExperiment_;
628 void LogbookSupervisor::setActiveExperiment(std::string experiment)
630 FILE* fp = fopen(std::string((std::string)ACTIVE_EXPERIMENT_PATH).c_str(),
"w");
633 __COUT__ <<
"FATAL ERROR!!! - file write" << std::endl;
637 fprintf(fp,
"%s", experiment.c_str());
640 if(activeExperiment_ !=
"" &&
641 activeExperiment_ != experiment)
642 theRemoteWebUsers_.makeSystemLogbookEntry(
643 "Experiment was made inactive.");
645 bool entryNeeded =
false;
646 if(experiment !=
"" &&
647 activeExperiment_ != experiment)
650 activeExperiment_ = experiment;
651 __COUT__ <<
"Active Experiment set to " << activeExperiment_ << std::endl;
654 theRemoteWebUsers_.makeSystemLogbookEntry(
655 "Experiment was made active.");
661 bool LogbookSupervisor::validateExperimentName(std::string& exp)
663 if(exp.length() < EXPERIMENT_NAME_MIN_LENTH ||
664 exp.length() > EXPERIMENT_NAME_MAX_LENTH)
666 for(
int i = 0; i < (int)exp.length(); ++i)
667 if(!((exp[i] >=
'a' && exp[i] <=
'z') || (exp[i] >=
'A' && exp[i] <=
'Z') ||
668 (exp[i] >=
'0' && exp[i] <=
'9') || (exp[i] ==
'-' || exp[i] ==
'_')))
670 exp = exp.substr(0, i) + exp.substr(i + 1);
681 void LogbookSupervisor::getExperiments(HttpXmlDocument* xmlOut, std::ostringstream* out)
684 HttpXmlDocument expXml;
685 if(!expXml.loadXmlDocument((std::string)LOGBOOK_EXPERIMENT_LIST_PATH))
687 __COUT__ <<
"Fatal Error - Experiment database." << std::endl;
688 __COUT__ <<
"Creating empty experiment database." << std::endl;
690 expXml.addTextElementToData((std::string)XML_EXPERIMENTS_ROOT);
691 expXml.saveXmlDocument((std::string)LOGBOOK_EXPERIMENT_LIST_PATH);
695 std::vector<std::string> exps;
696 expXml.getAllMatchingValues(XML_EXPERIMENT, exps);
699 xmlOut->addTextElementToData(XML_ACTIVE_EXPERIMENT, activeExperiment_);
701 for(
unsigned int i = 0; i < exps.size(); ++i)
704 xmlOut->addTextElementToData(XML_EXPERIMENT, exps[i]);
706 *out << exps[i] << std::endl;
712 void LogbookSupervisor::createExperiment(std::string experiment,
714 HttpXmlDocument* xmlOut)
716 if(!validateExperimentName(experiment))
719 xmlOut->addTextElementToData(
720 XML_ADMIN_STATUS,
"Error - Experiment name must be 3-25 characters.");
724 __COUT__ <<
"experiment " << experiment << std::endl;
727 std::string dirPath = (std::string)LOGBOOK_PATH + (std::string)LOGBOOK_LOGBOOKS_PATH +
728 (std::string)LOGBOOK_EXPERIMENT_DIR_PREFACE + experiment;
730 __COUT__ <<
"dirPath " << dirPath << std::endl;
732 bool directoryExists =
false;
733 DIR* dir = opendir(dirPath.c_str());
737 directoryExists =
true;
741 HttpXmlDocument expXml;
742 if(!expXml.loadXmlDocument((std::string)LOGBOOK_EXPERIMENT_LIST_PATH))
745 xmlOut->addTextElementToData(XML_ADMIN_STATUS,
746 "Fatal Error - Experiment database.");
750 std::vector<std::string> exps;
751 expXml.getAllMatchingValues(XML_EXPERIMENT, exps);
753 for(
unsigned int i = 0; i < exps.size(); ++i)
754 if(experiment == exps[i])
757 xmlOut->addTextElementToData(
759 "Failed - Experiment, " + experiment +
", already exists.");
762 __COUT__ <<
"experiments count: " << exps.size() << std::endl;
770 xercesc::DOMElement* expEl =
771 expXml.addTextElementToParent(XML_EXPERIMENT, experiment, XML_EXPERIMENTS_ROOT);
773 sprintf(createTime,
"%lu", time(0));
774 expXml.addTextElementToParent(XML_EXPERIMENT_CREATE, createTime, expEl);
775 expXml.addTextElementToParent(XML_EXPERIMENT_CREATOR, creator, expEl);
776 expXml.saveXmlDocument((std::string)LOGBOOK_EXPERIMENT_LIST_PATH);
782 dirPath +=
"/" + (std::string)LOGBOOK_UPLOADS_PATH;
783 __COUT__ <<
"Checking uploads directory" << std::endl;
785 directoryExists =
false;
786 dir = opendir(dirPath.c_str());
789 __COUT__ <<
"Creating uploads directory" << std::endl;
790 if(-1 == mkdir(dirPath.c_str(), 0755))
793 xmlOut->addTextElementToData(XML_ADMIN_STATUS,
794 "Failed - uploads directory for " +
795 experiment +
" was not created.");
796 __COUT__ <<
"Uploads directory failure." << std::endl;
803 xmlOut->addTextElementToData(XML_ADMIN_STATUS,
804 "Directory already exists for " + experiment +
805 ", re-added to list of experiments.");
808 __COUT__ <<
"Creating experiment and uploads directory at: " << dirPath << std::endl;
809 if(-1 == mkdir(dirPath.c_str(), 0755) ||
810 -1 == mkdir((dirPath +
"/" + (std::string)LOGBOOK_UPLOADS_PATH).c_str(), 0755))
813 xmlOut->addTextElementToData(
815 "Failed - directory, " + experiment +
", could not be created.");
820 xmlOut->addTextElementToData(
821 XML_ADMIN_STATUS,
"Experiment, " + experiment +
", successfully created.");
828 void LogbookSupervisor::webUserSetActiveExperiment(std::string experiment,
829 HttpXmlDocument* xmlOut)
833 setActiveExperiment(experiment);
835 xmlOut->addTextElementToData(XML_ADMIN_STATUS,
836 "Active experiment cleared successfully.");
840 HttpXmlDocument expXml;
841 if(!expXml.loadXmlDocument((std::string)LOGBOOK_EXPERIMENT_LIST_PATH))
844 xmlOut->addTextElementToData(XML_ADMIN_STATUS,
845 "Fatal Error - Experiment database.");
848 std::vector<std::string> exps;
849 expXml.getAllMatchingValues(XML_EXPERIMENT, exps);
852 for(i = 0; i < exps.size(); ++i)
853 if(experiment == exps[i])
859 xmlOut->addTextElementToData(
860 XML_ADMIN_STATUS,
"Failed - Experiment, " + experiment +
", not found.");
865 setActiveExperiment(experiment);
867 xmlOut->addTextElementToData(
869 "Active experiment set to " + experiment +
" successfully.");
876 void LogbookSupervisor::removeExperiment(std::string experiment,
878 HttpXmlDocument* xmlOut)
880 __COUT__ <<
"experiment " << experiment << std::endl;
883 HttpXmlDocument expXml;
884 if(!expXml.loadXmlDocument((std::string)LOGBOOK_EXPERIMENT_LIST_PATH))
887 xmlOut->addTextElementToData(XML_ADMIN_STATUS,
888 "Fatal Error - Experiment database.");
891 std::vector<std::string> exps;
892 expXml.getAllMatchingValues(XML_EXPERIMENT, exps);
895 for(i = 0; i < exps.size(); ++i)
896 if(experiment == exps[i])
902 xmlOut->addTextElementToData(
903 XML_ADMIN_STATUS,
"Failed - Experiment, " + experiment +
", not found.");
910 xercesc::DOMElement* parent = expXml.getMatchingElement(XML_EXPERIMENTS_ROOT);
911 xercesc::DOMElement* child = expXml.getMatchingElement(XML_EXPERIMENT, i);
912 __COUT__ <<
"experiments original count: " << expXml.getChildrenCount(parent)
914 expXml.recursiveRemoveChild(child, parent);
915 __COUT__ <<
"experiments new count: " << expXml.getChildrenCount(parent) << std::endl;
918 FILE* fp = fopen(((std::string)REMOVE_EXPERIMENT_LOG_PATH).c_str(),
"a");
922 xmlOut->addTextElementToData(XML_ADMIN_STATUS,
"Fatal Error - Remove log.");
926 "%s -- %s Experiment removed by %s.\n",
927 asctime(localtime(&((time_t
const&)(time(0))))),
932 expXml.saveXmlDocument((std::string)LOGBOOK_EXPERIMENT_LIST_PATH);
935 if(activeExperiment_ == experiment)
936 setActiveExperiment();
939 xmlOut->addTextElementToData(
940 XML_ADMIN_STATUS,
"Experiment, " + experiment +
", successfully removed.");
949 void LogbookSupervisor::refreshLogbook(time_t date,
950 unsigned char duration,
951 HttpXmlDocument* xmlOut,
952 std::ostringstream* out,
953 std::string experiment)
956 experiment = activeExperiment_;
958 xmlOut->addTextElementToData(XML_ACTIVE_EXPERIMENT, experiment);
961 std::string dirPath = (std::string)LOGBOOK_PATH + (std::string)LOGBOOK_LOGBOOKS_PATH +
962 (std::string)LOGBOOK_EXPERIMENT_DIR_PREFACE + experiment;
965 *out << __COUT_HDR_FL__ <<
"dirPath " << dirPath << std::endl;
967 DIR* dir = opendir(dirPath.c_str());
971 xmlOut->addTextElementToData(
973 "Error - Directory for experiment, " + experiment +
", missing.");
975 *out << __COUT_HDR_FL__ <<
"Error - Directory missing" << std::endl;
979 unsigned int baseDay;
984 unsigned int extractedDay;
987 mostRecentDayIndex_ = 0;
988 while((drnt = readdir(dir)))
993 if(strcmp(&(drnt->d_name[strlen(drnt->d_name) - 4]),
".xml"))
996 for(finish = strlen(drnt->d_name) - 1; finish > 0; --finish)
997 if(drnt->d_name[finish] ==
'.')
1002 *out << __COUT_HDR_FL__ <<
"failed to find day index finish "
1006 for(start = finish - 1; start > 0; --start)
1007 if(drnt->d_name[start - 1] ==
'_')
1012 *out << __COUT_HDR_FL__ <<
"failed to find day index start "
1016 drnt->d_name[finish] =
'\0';
1017 extractedDay = atoi((
char*)(&(drnt->d_name[start])));
1020 if(!mostRecentDayIndex_ || mostRecentDayIndex_ < extractedDay)
1021 mostRecentDayIndex_ = extractedDay;
1024 *out << __COUT_HDR_FL__
1025 <<
"dirContents done, found most recent day: " << mostRecentDayIndex_
1028 baseDay = mostRecentDayIndex_;
1031 baseDay = (date / (60 * 60 * 24));
1034 std::string entryPath;
1035 char dayIndexStr[20];
1041 for(
unsigned char i = duration; i != 0; --i)
1043 sprintf(dayIndexStr,
"%6.6u", baseDay - i + 1);
1044 entryPath = dirPath +
"/" + LOGBOOK_FILE_PREFACE + experiment +
"_" +
1045 (std::string)dayIndexStr + LOGBOOK_FILE_EXTENSION;
1048 *out << __COUT_HDR_FL__ <<
"Directory Entry " << entryPath << std::endl;
1050 fp = fopen(entryPath.c_str(),
"r");
1054 *out << __COUT_HDR_FL__ <<
"File not found" << std::endl;
1061 HttpXmlDocument logXml;
1062 if(!logXml.loadXmlDocument(entryPath))
1065 xmlOut->addTextElementToData(
1066 XML_STATUS,
"Critical Failure - log did not load. Notify admins.");
1068 *out << __COUT_HDR_FL__ <<
"Failure - log XML did not load" << std::endl;
1073 xmlOut->copyDataChildren(logXml);
1077 xmlOut->addTextElementToData(XML_STATUS,
"1");
1079 *out << __COUT_HDR_FL__ <<
"Today: " << time(0) / (60 * 60 * 24) << std::endl;
1081 sprintf(dayIndexStr,
"%lu", time(0) / (60 * 60 * 24) - mostRecentDayIndex_);
1083 xmlOut->addTextElementToData(XML_MOST_RECENT_DAY,
1091 void LogbookSupervisor::cleanUpPreviews()
1093 std::string previewPath =
1094 (std::string)LOGBOOK_PATH + (std::string)LOGBOOK_PREVIEWS_PATH;
1096 DIR* dir = opendir(previewPath.c_str());
1099 __COUT__ <<
"Error - Previews directory missing: " << previewPath << std::endl;
1103 struct dirent* entry;
1104 time_t dirCreateTime;
1111 if(strcmp(entry->d_name,
".") != 0 && strcmp(entry->d_name,
"..") != 0 &&
1112 strcmp(entry->d_name,
".svn") != 0)
1115 for(i = 0; i < strlen(entry->d_name); ++i)
1116 if(entry->d_name[i] ==
'_')
1118 entry->d_name[i] =
' ';
1121 sscanf(entry->d_name,
"%li", &dirCreateTime);
1123 if((time(0) - dirCreateTime) > LOGBOOK_PREVIEW_EXPIRATION_TIME)
1125 __COUT__ <<
"Expired" << std::endl;
1127 entry->d_name[i] =
'_';
1129 __COUT__ <<
"rm -rf " << previewPath + (std::string)entry->d_name
1133 ((std::string)(
"rm -rf " + previewPath + (std::string)entry->d_name))
1145 void LogbookSupervisor::savePostPreview(std::string& subject,
1147 const std::vector<cgicc::FormFile>& files,
1148 std::string creator,
1149 HttpXmlDocument* xmlOut)
1151 if(activeExperiment_ ==
"")
1154 xmlOut->addTextElementToData(XML_STATUS,
1155 "Failed - no active experiment currently!");
1164 std::string previewPath = (std::string)LOGBOOK_PATH +
1165 (std::string)LOGBOOK_PREVIEWS_PATH + (std::string)fileIndex;
1167 __COUT__ <<
"previewPath " << previewPath << std::endl;
1168 if(-1 == mkdir(previewPath.c_str(), 0755))
1171 xmlOut->addTextElementToData(XML_STATUS,
1172 "Failed - preview could not be generated.");
1187 escapeLogbookEntry(text);
1188 escapeLogbookEntry(subject);
1189 __COUT__ <<
"~~subject " << subject << std::endl
1190 <<
"~~text " << text << std::endl
1193 HttpXmlDocument previewXml;
1195 previewXml.addTextElementToData(XML_LOGBOOK_ENTRY);
1196 previewXml.addTextElementToParent(
1197 XML_LOGBOOK_ENTRY_TIME, fileIndex, XML_LOGBOOK_ENTRY);
1199 xmlOut->addTextElementToData(XML_LOGBOOK_ENTRY_TIME, fileIndex);
1200 previewXml.addTextElementToParent(
1201 XML_LOGBOOK_ENTRY_CREATOR, creator, XML_LOGBOOK_ENTRY);
1203 xmlOut->addTextElementToData(XML_LOGBOOK_ENTRY_CREATOR,
1205 previewXml.addTextElementToParent(XML_LOGBOOK_ENTRY_TEXT, text, XML_LOGBOOK_ENTRY);
1207 xmlOut->addTextElementToData(XML_LOGBOOK_ENTRY_TEXT, text);
1208 previewXml.addTextElementToParent(
1209 XML_LOGBOOK_ENTRY_SUBJECT, subject, XML_LOGBOOK_ENTRY);
1211 xmlOut->addTextElementToData(XML_LOGBOOK_ENTRY_SUBJECT,
1214 __COUT__ <<
"file size " << files.size() << std::endl;
1216 std::string filename;
1217 std::ofstream myfile;
1218 for(
unsigned int i = 0; i < files.size(); ++i)
1220 previewXml.addTextElementToParent(
1221 XML_LOGBOOK_ENTRY_FILE, files[i].getDataType(), XML_LOGBOOK_ENTRY);
1223 xmlOut->addTextElementToData(XML_LOGBOOK_ENTRY_FILE,
1224 files[i].getDataType());
1226 if((filename = validateUploadFileType(files[i].getDataType())) ==
1230 xmlOut->addTextElementToData(
1232 "Failed - invalid file type, " + files[i].getDataType() +
".");
1237 sprintf(fileIndex,
"%d", i);
1238 filename = previewPath +
"/" + (std::string)LOGBOOK_PREVIEW_UPLOAD_PREFACE +
1239 (std::string)fileIndex + "." + filename;
1241 __COUT__ << "file " << i << " - " << filename << std::endl;
1242 myfile.open(filename.c_str());
1243 if(myfile.is_open())
1245 files[i].writeToStream(myfile);
1251 previewXml.saveXmlDocument(previewPath +
"/" + (std::string)LOGBOOK_PREVIEW_FILE);
1254 xmlOut->addTextElementToData(XML_STATUS,
"1");
1256 xmlOut->addTextElementToData(XML_PREVIEW_INDEX,
1266 void LogbookSupervisor::movePreviewEntry(std::string previewNumber,
1270 __COUT__ <<
"previewNumber " << previewNumber
1271 << (approve ?
" Accepted" :
" Cancelled") << std::endl;
1273 std::string sysCmd, previewPath = (std::string)LOGBOOK_PATH +
1274 (std::string)LOGBOOK_PREVIEWS_PATH + previewNumber;
1280 HttpXmlDocument previewXml;
1281 previewXml.loadXmlDocument(previewPath +
"/" + (std::string)LOGBOOK_PREVIEW_FILE);
1283 std::string logPath,
1284 logDirPath = (std::string)LOGBOOK_PATH + (std::string)LOGBOOK_LOGBOOKS_PATH +
1285 (std::string)LOGBOOK_EXPERIMENT_DIR_PREFACE + activeExperiment_;
1288 DIR* dir = opendir(logDirPath.c_str());
1291 __COUT__ <<
"Error - Active Experiment directory missing: " << logPath
1297 char dayIndexStr[20];
1298 sprintf(dayIndexStr,
"%6.6lu", time(0) / (60 * 60 * 24));
1300 logPath = logDirPath +
"/" + LOGBOOK_FILE_PREFACE + activeExperiment_ +
"_" +
1301 (std::string)dayIndexStr + LOGBOOK_FILE_EXTENSION;
1302 __COUT__ <<
"logPath " << logPath << std::endl;
1304 HttpXmlDocument logXml;
1305 logXml.loadXmlDocument(logPath);
1316 logXml.copyDataChildren(previewXml);
1317 logXml.saveXmlDocument(logPath);
1320 std::vector<std::string> fileTypes;
1321 previewXml.getAllMatchingValues(XML_LOGBOOK_ENTRY_FILE, fileTypes);
1322 std::string entryTimeLabel = previewXml.getMatchingValue(XML_LOGBOOK_ENTRY_TIME);
1323 std::string fileExtension, previewFilename, logFilename;
1325 for(
unsigned int i = 0; i < fileTypes.size(); ++i)
1327 if((fileExtension = validateUploadFileType(fileTypes[i])) ==
1330 __COUT__ <<
"Failed - invalid file type: " << fileTypes[i] << std::endl;
1335 sprintf(fileIndex,
"%d", i);
1336 previewFilename = (std::string)LOGBOOK_PREVIEW_UPLOAD_PREFACE +
1337 (std::string)fileIndex +
"." + fileExtension;
1338 logFilename = (std::string)LOGBOOK_PREVIEW_UPLOAD_PREFACE + entryTimeLabel +
1339 "_" + (std::string)fileIndex +
"." + fileExtension;
1341 sysCmd =
"mv " + (previewPath +
"/" + previewFilename) +
" " +
1342 (logDirPath +
"/" + (std::string)LOGBOOK_UPLOADS_PATH + logFilename);
1343 __COUT__ << sysCmd << std::endl;
1344 system(sysCmd.c_str());
1349 sysCmd =
"rm -rf " + previewPath;
1350 __COUT__ << sysCmd << std::endl << std::endl;
1351 system(sysCmd.c_str());
1357 std::string LogbookSupervisor::validateUploadFileType(
const std::string fileType)
1359 for(
unsigned int i = 0; i < allowedFileUploadTypes_.size(); ++i)
1360 if(allowedFileUploadTypes_[i] == fileType)
1361 return matchingFileUploadTypes_[i];
1370 void LogbookSupervisor::escapeLogbookEntry(std::string& )
1384 void LogbookSupervisor::hideLogbookEntry(
const std::string& entryId,
1386 const std::string& hider)
1388 __COUT__ <<
"Hide=" << hide <<
" for entryid " << entryId << std::endl;
1391 char dayIndexStr[20];
1393 for(i = 0; i < entryId.length(); ++i)
1394 if(entryId[i] ==
'_')
1396 dayIndexStr[i] =
'\0';
1400 dayIndexStr[i] = entryId[i];
1402 sscanf(dayIndexStr,
"%li", &days);
1403 days /= 60 * 60 * 24;
1404 sprintf(dayIndexStr,
"%6.6lu", days);
1406 std::string logDirPath =
1407 (std::string)LOGBOOK_PATH + (std::string)LOGBOOK_LOGBOOKS_PATH +
1408 (std::string)LOGBOOK_EXPERIMENT_DIR_PREFACE + activeExperiment_;
1409 std::string logPath = logDirPath +
"/" + LOGBOOK_FILE_PREFACE + activeExperiment_ +
1410 "_" + (std::string)dayIndexStr + LOGBOOK_FILE_EXTENSION;
1412 __COUT__ <<
"logPath=" << logPath << std::endl;
1415 HttpXmlDocument logXml;
1416 if(!logXml.loadXmlDocument(logPath))
1418 __COUT__ <<
"Failure - log XML did not load" << std::endl;
1422 std::vector<std::string> allEntryIds;
1423 logXml.getAllMatchingValues(XML_LOGBOOK_ENTRY_TIME, allEntryIds);
1424 for(i = 0; i < allEntryIds.size(); ++i)
1425 if(allEntryIds[i] == entryId)
1427 if(i == allEntryIds.size())
1429 __COUT__ <<
"Failure - entry not found" << std::endl;
1433 __COUT__ <<
"found " << logXml.getMatchingValue(XML_LOGBOOK_ENTRY_TEXT, i)
1436 xercesc::DOMElement *hiddenParentEl, *entryParentEl = logXml.getMatchingElement(
1437 XML_LOGBOOK_ENTRY, i);
1441 logXml.getMatchingElementInSubtree(entryParentEl, XML_LOGBOOK_ENTRY_HIDDEN);
1447 __COUT__ <<
"Hidden tag already applied to entry." << std::endl;
1450 hiddenParentEl = logXml.addTextElementToParent(
1451 XML_LOGBOOK_ENTRY_HIDDEN,
1454 logXml.addTextElementToParent(
1455 XML_LOGBOOK_ENTRY_HIDER, hider, hiddenParentEl);
1456 sprintf(dayIndexStr,
"%lu", time(0));
1457 logXml.addTextElementToParent(
1458 XML_LOGBOOK_ENTRY_HIDDEN_TIME, dayIndexStr, hiddenParentEl);
1464 __COUT__ <<
"Entry already was not hidden." << std::endl;
1468 logXml.recursiveRemoveChild(hiddenParentEl,
1471 logXml.saveXmlDocument(logPath);
1472 __COUT__ <<
"Success." << std::endl;