1 #include "otsdaq-utilities/Chat/ChatSupervisor.h"
2 #include "otsdaq/CgiDataUtilities/CgiDataUtilities.h"
3 #include "otsdaq/Macros/CoutMacros.h"
4 #include "otsdaq/MessageFacility/MessageFacility.h"
5 #include "otsdaq/XmlUtilities/HttpXmlDocument.h"
7 #include <xdaq/NamespaceURI.h>
14 #define __MF_SUBJECT__ "Chat"
23 ChatLastUpdateIndex = 1;
27 ChatSupervisor::~ChatSupervisor(
void) { destroy(); }
30 void ChatSupervisor::destroy(
void)
36 void ChatSupervisor::defaultPage(xgi::Input* , xgi::Output* out)
38 out->getHTTPResponseHeader().addHeader(
"Access-Control-Allow-Origin",
"*");
39 out->getHTTPResponseHeader().addHeader(
"Pragma",
"no-cache");
41 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
42 "src='/WebPath/html/Chat.html?urn="
43 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
51 CorePropertySupervisorBase::setSupervisorProperty(
52 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
63 const WebUsers::RequestUserInfo& )
65 __COUTVS__(40, requestType);
72 cleanupExpiredChats();
74 if(requestType ==
"RefreshChat")
76 std::string lastUpdateIndexString =
79 uint64_t lastUpdateIndex;
80 sscanf(lastUpdateIndexString.c_str(),
"%lu", &lastUpdateIndex);
82 insertChatRefresh(&xmlOut, lastUpdateIndex, user);
84 else if(requestType ==
"RefreshUsers")
86 insertActiveUsers(&xmlOut);
88 else if(requestType ==
"SendChat")
97 else if(requestType ==
"PageUser")
100 unsigned int topageId = CgiDataUtilities::postDataAsInt(cgiIn,
"topageId");
103 __COUT__ <<
"Paging = " << topage.substr(0, 10)
104 <<
"... from user = " << user.substr(0, 10) << std::endl;
108 theRemoteWebUsers_.sendSystemMessage(topage,
109 user +
" is paging you to come chat.");
113 __SUP_SS__ <<
"requestType Request, " << requestType
114 <<
", not recognized by the Chat Editor Supervisor (was it intended "
115 "for another Supervisor?)."
126 void ChatSupervisor::escapeChat(std::string& )
139 xmlOut->addTextElementToData(
"active_users", theRemoteWebUsers_.getActiveUserList());
150 uint64_t lastUpdateIndex,
151 const std::string& user)
155 if(!isLastUpdateIndexStale(lastUpdateIndex))
161 sprintf(tempStr,
"%lu", ChatLastUpdateIndex);
162 xmlOut->addTextElementToData(
"last_update_index", tempStr);
165 xmlOut->addTextElementToData(
"chat_users",
"");
166 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
172 xmlOut->addTextElementToData(
"chat_history",
"");
173 for(uint64_t i = 0; i < ChatHistoryEntry_.size(); ++i)
175 __COUTT__ <<
"Chat[" << i <<
"]: " << ChatHistoryIndex_[i] <<
" vs "
176 << lastUpdateIndex << __E__;
177 if(isChatOld(ChatHistoryIndex_[i], lastUpdateIndex))
181 "chat_entry", ChatHistoryEntry_[i],
"chat_history");
183 "chat_author", ChatHistoryAuthor_[i],
"chat_history");
184 sprintf(tempStr,
"%lu", ChatHistoryTime_[i]);
192 void ChatSupervisor::newUser(
const std::string& user)
194 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
195 if(ChatUsers_[i] == user)
197 ChatUsersTime_[i] = time(0);
201 __COUT__ <<
"New user: " << user << std::endl;
203 ChatUsers_.push_back(user);
204 ChatUsersTime_.push_back(time(0));
205 newChat(user +
" joined the chat.",
212 void ChatSupervisor::newChat(
const std::string& chat,
const std::string& user)
214 ChatHistoryEntry_.push_back(chat);
215 ChatHistoryAuthor_.push_back(user);
216 ChatHistoryTime_.push_back(time(0));
217 ChatHistoryIndex_.push_back(incrementAndGetLastUpdate());
223 bool ChatSupervisor::isChatOld(uint64_t chatIndex, uint64_t last)
225 return (last - chatIndex < (uint64_t(1) << 62));
230 bool ChatSupervisor::isLastUpdateIndexStale(uint64_t last)
232 return ChatLastUpdateIndex != last;
237 uint64_t ChatSupervisor::incrementAndGetLastUpdate()
239 if(!++ChatLastUpdateIndex)
240 ++ChatLastUpdateIndex;
241 return ChatLastUpdateIndex;
247 void ChatSupervisor::cleanupExpiredChats()
249 for(uint64_t i = 0; i < ChatHistoryEntry_.size(); ++i)
250 if(i >= CHAT_HISTORY_MAX_ENTRIES ||
251 ChatHistoryTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0))
253 removeChatHistoryEntry(i);
260 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
261 if(ChatUsersTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0))
263 removeChatUserEntry(i);
273 void ChatSupervisor::removeChatHistoryEntry(uint64_t i)
275 ChatHistoryEntry_.erase(ChatHistoryEntry_.begin() + i);
276 ChatHistoryTime_.erase(ChatHistoryTime_.begin() + i);
277 ChatHistoryAuthor_.erase(ChatHistoryAuthor_.begin() + i);
278 ChatHistoryIndex_.erase(ChatHistoryIndex_.begin() + i);
283 void ChatSupervisor::removeChatUserEntry(uint64_t i)
285 newChat(ChatUsers_[i] +
" left the chat.",
287 ChatUsers_.erase(ChatUsers_.begin() + i);
288 ChatUsersTime_.erase(ChatUsersTime_.begin() + i);
static std::string postData(cgicc::Cgicc &cgi, const std::string &needle)
virtual void request(const std::string &requestType, cgicc::Cgicc &cgiIn, HttpXmlDocument &xmlOut, const WebUsers::RequestUserInfo &userInfo) override
end forceSupervisorPropertyValues()
virtual void forceSupervisorPropertyValues(void) override
override to force supervisor property values (and ignore user settings)
xercesc::DOMElement * addTextElementToParent(const std::string &childName, const std::string &childText, xercesc::DOMElement *parent)
void INIT_MF(const char *name)