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"
19 ChatSupervisor::ChatSupervisor(xdaq::ApplicationStub* stub) : CoreSupervisorBase(stub)
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,
62 HttpXmlDocument& xmlOut,
63 const WebUsers::RequestUserInfo& )
65 __COUTVS__(40, requestType);
72 cleanupExpiredChats();
74 if(requestType ==
"RefreshChat")
76 std::string lastUpdateIndexString =
77 CgiDataUtilities::postData(cgiIn,
"lastUpdateIndex");
78 std::string user = CgiDataUtilities::postData(cgiIn,
"user");
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")
90 std::string chat = CgiDataUtilities::postData(cgiIn,
"chat");
91 std::string user = CgiDataUtilities::postData(cgiIn,
"user");
97 else if(requestType ==
"PageUser")
99 std::string topage = CgiDataUtilities::postData(cgiIn,
"topage");
100 unsigned int topageId = CgiDataUtilities::postDataAsInt(cgiIn,
"topageId");
101 std::string user = CgiDataUtilities::postData(cgiIn,
"user");
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.");
112 __COUT__ <<
"requestType request not recognized." << std::endl;
120 void ChatSupervisor::escapeChat(std::string& )
131 void ChatSupervisor::insertActiveUsers(HttpXmlDocument* xmlOut)
133 xmlOut->addTextElementToData(
"active_users", theRemoteWebUsers_.getActiveUserList());
143 void ChatSupervisor::insertChatRefresh(HttpXmlDocument* xmlOut,
144 uint64_t lastUpdateIndex,
145 const std::string& user)
149 if(!isLastUpdateIndexStale(lastUpdateIndex))
155 sprintf(tempStr,
"%lu", ChatLastUpdateIndex);
156 xmlOut->addTextElementToData(
"last_update_index", tempStr);
159 xmlOut->addTextElementToData(
"chat_users",
"");
160 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
161 xmlOut->addTextElementToParent(
"chat_user", ChatUsers_[i],
"chat_users");
166 xmlOut->addTextElementToData(
"chat_history",
"");
167 for(uint64_t i = 0; i < ChatHistoryEntry_.size(); ++i)
169 __COUTT__ <<
"Chat[" << i <<
"]: " << ChatHistoryIndex_[i] <<
" vs "
170 << lastUpdateIndex << __E__;
171 if(isChatOld(ChatHistoryIndex_[i], lastUpdateIndex))
174 xmlOut->addTextElementToParent(
175 "chat_entry", ChatHistoryEntry_[i],
"chat_history");
176 xmlOut->addTextElementToParent(
177 "chat_author", ChatHistoryAuthor_[i],
"chat_history");
178 sprintf(tempStr,
"%lu", ChatHistoryTime_[i]);
179 xmlOut->addTextElementToParent(
"chat_time", tempStr,
"chat_history");
186 void ChatSupervisor::newUser(
const std::string& user)
188 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
189 if(ChatUsers_[i] == user)
191 ChatUsersTime_[i] = time(0);
195 __COUT__ <<
"New user: " << user << std::endl;
197 ChatUsers_.push_back(user);
198 ChatUsersTime_.push_back(time(0));
199 newChat(user +
" joined the chat.",
206 void ChatSupervisor::newChat(
const std::string& chat,
const std::string& user)
208 ChatHistoryEntry_.push_back(chat);
209 ChatHistoryAuthor_.push_back(user);
210 ChatHistoryTime_.push_back(time(0));
211 ChatHistoryIndex_.push_back(incrementAndGetLastUpdate());
217 bool ChatSupervisor::isChatOld(uint64_t chatIndex, uint64_t last)
219 return (last - chatIndex < (uint64_t(1) << 62));
224 bool ChatSupervisor::isLastUpdateIndexStale(uint64_t last)
226 return ChatLastUpdateIndex != last;
231 uint64_t ChatSupervisor::incrementAndGetLastUpdate()
233 if(!++ChatLastUpdateIndex)
234 ++ChatLastUpdateIndex;
235 return ChatLastUpdateIndex;
241 void ChatSupervisor::cleanupExpiredChats()
243 for(uint64_t i = 0; i < ChatHistoryEntry_.size(); ++i)
244 if(i >= CHAT_HISTORY_MAX_ENTRIES ||
245 ChatHistoryTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0))
247 removeChatHistoryEntry(i);
254 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
255 if(ChatUsersTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0))
257 removeChatUserEntry(i);
267 void ChatSupervisor::removeChatHistoryEntry(uint64_t i)
269 ChatHistoryEntry_.erase(ChatHistoryEntry_.begin() + i);
270 ChatHistoryTime_.erase(ChatHistoryTime_.begin() + i);
271 ChatHistoryAuthor_.erase(ChatHistoryAuthor_.begin() + i);
272 ChatHistoryIndex_.erase(ChatHistoryIndex_.begin() + i);
277 void ChatSupervisor::removeChatUserEntry(uint64_t i)
279 newChat(ChatUsers_[i] +
" left the chat.",
281 ChatUsers_.erase(ChatUsers_.begin() + i);
282 ChatUsersTime_.erase(ChatUsersTime_.begin() + i);
virtual void request(const std::string &requestType, cgicc::Cgicc &cgiIn, HttpXmlDocument &xmlOut, const WebUsers::RequestUserInfo &userInfo) override
end forceSupervisorPropertyValues()
virtual void forceSupervisorPropertyValues(void) override