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"
21 : CoreSupervisorBase(stub)
25 ChatLastUpdateIndex = 1;
29 ChatSupervisor::~ChatSupervisor(
void) { destroy(); }
32 void ChatSupervisor::destroy(
void)
53 void ChatSupervisor::forceSupervisorPropertyValues()
55 CorePropertySupervisorBase::setSupervisorProperty(
56 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
66 HttpXmlDocument& xmlOut,
67 const WebUsers::RequestUserInfo& )
76 cleanupExpiredChats();
78 if(requestType ==
"RefreshChat")
80 std::string lastUpdateIndexString =
81 CgiDataUtilities::postData(cgiIn,
"lastUpdateIndex");
82 std::string user = CgiDataUtilities::postData(cgiIn,
"user");
83 uint64_t lastUpdateIndex;
84 sscanf(lastUpdateIndexString.c_str(),
"%lu", &lastUpdateIndex);
86 insertChatRefresh(&xmlOut, lastUpdateIndex, user);
88 else if(requestType ==
"RefreshUsers")
90 insertActiveUsers(&xmlOut);
92 else if(requestType ==
"SendChat")
94 std::string chat = CgiDataUtilities::postData(cgiIn,
"chat");
95 std::string user = CgiDataUtilities::postData(cgiIn,
"user");
101 else if(requestType ==
"PageUser")
103 std::string topage = CgiDataUtilities::postData(cgiIn,
"topage");
104 unsigned int topageId = CgiDataUtilities::postDataAsInt(cgiIn,
"topageId");
105 std::string user = CgiDataUtilities::postData(cgiIn,
"user");
107 __COUT__ <<
"Paging = " << topage.substr(0, 10)
108 <<
"... from user = " << user.substr(0, 10) << std::endl;
112 theRemoteWebUsers_.sendSystemMessage(topage,
113 user +
" is paging you to come chat.");
116 __COUT__ <<
"requestType request not recognized." << std::endl;
124 void ChatSupervisor::escapeChat(std::string& )
135 void ChatSupervisor::insertActiveUsers(HttpXmlDocument* xmlOut)
137 xmlOut->addTextElementToData(
139 theRemoteWebUsers_.getActiveUserList());
149 void ChatSupervisor::insertChatRefresh(HttpXmlDocument* xmlOut,
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)
167 xmlOut->addTextElementToParent(
"chat_user", ChatUsers_[i],
"chat_users");
171 lastUpdateIndex = ChatHistoryIndex_[ChatHistoryIndex_.size() - 1] -
175 xmlOut->addTextElementToData(
"chat_history",
"");
176 for(uint64_t i = 0; i < ChatHistoryEntry_.size(); ++i)
178 if(isChatOld(ChatHistoryIndex_[i], lastUpdateIndex))
181 xmlOut->addTextElementToParent(
182 "chat_entry", ChatHistoryEntry_[i],
"chat_history");
183 xmlOut->addTextElementToParent(
184 "chat_author", ChatHistoryAuthor_[i],
"chat_history");
185 sprintf(tempStr,
"%lu", ChatHistoryTime_[i]);
186 xmlOut->addTextElementToParent(
"chat_time", tempStr,
"chat_history");
193 void ChatSupervisor::newUser(
const std::string& user)
195 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
196 if(ChatUsers_[i] == user)
198 ChatUsersTime_[i] = time(0);
202 __COUT__ <<
"New user: " << user << std::endl;
204 ChatUsers_.push_back(user);
205 ChatUsersTime_.push_back(time(0));
206 newChat(user +
" joined the chat.",
213 void ChatSupervisor::newChat(
const std::string& chat,
const std::string& user)
215 ChatHistoryEntry_.push_back(chat);
216 ChatHistoryAuthor_.push_back(user);
217 ChatHistoryTime_.push_back(time(0));
218 ChatHistoryIndex_.push_back(incrementAndGetLastUpdate());
224 bool ChatSupervisor::isChatOld(uint64_t chatIndex, uint64_t last)
226 return (last - chatIndex < (uint64_t(1) << 62));
231 bool ChatSupervisor::isLastUpdateIndexStale(uint64_t last)
233 return ChatLastUpdateIndex != last;
238 uint64_t ChatSupervisor::incrementAndGetLastUpdate()
240 if(!++ChatLastUpdateIndex)
241 ++ChatLastUpdateIndex;
242 return ChatLastUpdateIndex;
248 void ChatSupervisor::cleanupExpiredChats()
250 for(uint64_t i = 0; i < ChatHistoryEntry_.size(); ++i)
251 if(i >= CHAT_HISTORY_MAX_ENTRIES ||
252 ChatHistoryTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0))
254 removeChatHistoryEntry(i);
261 for(uint64_t i = 0; i < ChatUsers_.size(); ++i)
262 if(ChatUsersTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0))
264 removeChatUserEntry(i);
274 void ChatSupervisor::removeChatHistoryEntry(uint64_t i)
276 ChatHistoryEntry_.erase(ChatHistoryEntry_.begin() + i);
277 ChatHistoryTime_.erase(ChatHistoryTime_.begin() + i);
278 ChatHistoryAuthor_.erase(ChatHistoryAuthor_.begin() + i);
279 ChatHistoryIndex_.erase(ChatHistoryIndex_.begin() + i);
284 void ChatSupervisor::removeChatUserEntry(uint64_t i)
286 newChat(ChatUsers_[i] +
" left the chat.",
288 ChatUsers_.erase(ChatUsers_.begin() + i);
289 ChatUsersTime_.erase(ChatUsersTime_.begin() + i);
virtual void request(const std::string &requestType, cgicc::Cgicc &cgiIn, HttpXmlDocument &xmlOut, const WebUsers::RequestUserInfo &userInfo) override
end forceSupervisorPropertyValues()