1 #include "otsdaq-utilities/Chat/ChatSupervisor.h"
2 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h"
3 #include "otsdaq-core/Macros/CoutMacros.h"
4 #include "otsdaq-core/MessageFacility/MessageFacility.h"
5 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
7 #include <xdaq/NamespaceURI.h>
14 #define __MF_SUBJECT__ "Chat"
21 : CoreSupervisorBase(stub)
23 INIT_MF(
"ChatSupervisor");
25 ChatLastUpdateIndex = 1;
29 ChatSupervisor::~ChatSupervisor(
void) { destroy(); }
32 void ChatSupervisor::destroy(
void)
38 void ChatSupervisor::defaultPage(xgi::Input* cgiIn, xgi::Output* out)
40 *out <<
"<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame "
41 "src='/WebPath/html/Chat.html?urn="
42 << this->getApplicationDescriptor()->getLocalId() <<
"'></frameset></html>";
48 void ChatSupervisor::forceSupervisorPropertyValues()
50 CorePropertySupervisorBase::setSupervisorProperty(
51 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
59 void ChatSupervisor::request(
const std::string& requestType,
61 HttpXmlDocument& xmlOut,
62 const WebUsers::RequestUserInfo& userInfo)
71 cleanupExpiredChats();
73 if(requestType ==
"RefreshChat")
75 std::string lastUpdateIndexString =
76 CgiDataUtilities::postData(cgiIn,
"lastUpdateIndex");
77 std::string user = CgiDataUtilities::postData(cgiIn,
"user");
78 uint64_t lastUpdateIndex;
79 sscanf(lastUpdateIndexString.c_str(),
"%lu", &lastUpdateIndex);
81 insertChatRefresh(&xmlOut, lastUpdateIndex, user);
83 else if(requestType ==
"RefreshUsers")
85 insertActiveUsers(&xmlOut);
87 else if(requestType ==
"SendChat")
89 std::string chat = CgiDataUtilities::postData(cgiIn,
"chat");
90 std::string user = CgiDataUtilities::postData(cgiIn,
"user");
96 else if(requestType ==
"PageUser")
98 std::string topage = CgiDataUtilities::postData(cgiIn,
"topage");
99 std::string user = CgiDataUtilities::postData(cgiIn,
"user");
101 __COUT__ <<
"Paging = " << topage.substr(0, 10)
102 <<
"... from user = " << user.substr(0, 10) << std::endl;
104 theRemoteWebUsers_.sendSystemMessage(allSupervisorInfo_.getGatewayDescriptor(),
106 user +
" is paging you to come chat.");
109 __COUT__ <<
"requestType request not recognized." << std::endl;
119 void ChatSupervisor::escapeChat(std::string& chat)
130 void ChatSupervisor::insertActiveUsers(HttpXmlDocument* xmlOut)
132 xmlOut->addTextElementToData(
134 theRemoteWebUsers_.getActiveUserList(allSupervisorInfo_.getGatewayDescriptor()));
144 void ChatSupervisor::insertChatRefresh(HttpXmlDocument* xmlOut,
145 uint64_t lastUpdateIndex,
150 if(!isLastUpdateIndexStale(lastUpdateIndex))
156 sprintf(tempStr,
"%lu", ChatLastUpdateIndex);
157 xmlOut->addTextElementToData(
"last_update_index", tempStr);
160 xmlOut->addTextElementToData(
"chat_users",
"");
161 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
162 xmlOut->addTextElementToParent(
"chat_user", ChatUsers_[i],
"chat_users");
166 lastUpdateIndex = ChatHistoryIndex_[ChatHistoryIndex_.size() - 1] -
170 xmlOut->addTextElementToData(
"chat_history",
"");
171 for(uint64_t i = 0; i < ChatHistoryEntry_.size(); ++i)
173 if(isChatOld(ChatHistoryIndex_[i], lastUpdateIndex))
176 xmlOut->addTextElementToParent(
177 "chat_entry", ChatHistoryEntry_[i],
"chat_history");
178 xmlOut->addTextElementToParent(
179 "chat_author", ChatHistoryAuthor_[i],
"chat_history");
180 sprintf(tempStr,
"%lu", ChatHistoryTime_[i]);
181 xmlOut->addTextElementToParent(
"chat_time", tempStr,
"chat_history");
188 void ChatSupervisor::newUser(std::string user)
190 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
191 if(ChatUsers_[i] == user)
193 ChatUsersTime_[i] = time(0);
197 __COUT__ <<
"New user: " << user << std::endl;
199 ChatUsers_.push_back(user);
200 ChatUsersTime_.push_back(time(0));
201 newChat(user +
" joined the chat.",
208 void ChatSupervisor::newChat(std::string chat, std::string user)
210 ChatHistoryEntry_.push_back(chat);
211 ChatHistoryAuthor_.push_back(user);
212 ChatHistoryTime_.push_back(time(0));
213 ChatHistoryIndex_.push_back(incrementAndGetLastUpdate());
219 bool ChatSupervisor::isChatOld(uint64_t chatIndex, uint64_t last)
221 return (last - chatIndex < (uint64_t(1) << 62));
226 bool ChatSupervisor::isLastUpdateIndexStale(uint64_t last)
228 return ChatLastUpdateIndex != last;
233 uint64_t ChatSupervisor::incrementAndGetLastUpdate()
235 if(!++ChatLastUpdateIndex)
236 ++ChatLastUpdateIndex;
237 return ChatLastUpdateIndex;
243 void ChatSupervisor::cleanupExpiredChats()
245 for(uint64_t i = 0; i < ChatHistoryEntry_.size(); ++i)
246 if(i >= CHAT_HISTORY_MAX_ENTRIES ||
247 ChatHistoryTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0))
249 removeChatHistoryEntry(i);
256 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
257 if(ChatUsersTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0))
259 removeChatUserEntry(i);
269 void ChatSupervisor::removeChatHistoryEntry(uint64_t i)
271 ChatHistoryEntry_.erase(ChatHistoryEntry_.begin() + i);
272 ChatHistoryTime_.erase(ChatHistoryTime_.begin() + i);
273 ChatHistoryAuthor_.erase(ChatHistoryAuthor_.begin() + i);
274 ChatHistoryIndex_.erase(ChatHistoryIndex_.begin() + i);
279 void ChatSupervisor::removeChatUserEntry(uint64_t i)
281 newChat(ChatUsers_[i] +
" left the chat.",
283 ChatUsers_.erase(ChatUsers_.begin() + i);
284 ChatUsersTime_.erase(ChatUsersTime_.begin() + i);