00001 #include "otsdaq-utilities/Chat/ChatSupervisor.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutMacros.h"
00004 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h"
00005 #include "otsdaq-core/XmlUtilities/HttpXmlDocument.h"
00006
00007 #include <xdaq/NamespaceURI.h>
00008
00009 #include <iostream>
00010
00011 using namespace ots;
00012
00013 #undef __MF_SUBJECT__
00014 #define __MF_SUBJECT__ "Chat"
00015
00016 XDAQ_INSTANTIATOR_IMPL(ChatSupervisor)
00017
00018
00019 ChatSupervisor::ChatSupervisor(xdaq::ApplicationStub* stub)
00020
00021 : CoreSupervisorBase (stub)
00022 {
00023 INIT_MF("ChatSupervisor");
00024
00025 ChatLastUpdateIndex = 1;
00026 }
00027
00028
00029 ChatSupervisor::~ChatSupervisor(void)
00030 {
00031 destroy();
00032 }
00033
00034
00035 void ChatSupervisor::destroy(void)
00036 {
00037
00038
00039 }
00040
00041
00042 void ChatSupervisor::defaultPage(xgi::Input * cgiIn, xgi::Output * out )
00043 {
00044 *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame src='/WebPath/html/Chat.html?urn=" <<
00045 this->getApplicationDescriptor()->getLocalId() <<"'></frameset></html>";
00046 }
00047
00048
00049
00050
00051 void ChatSupervisor::forceSupervisorPropertyValues()
00052 {
00053 CorePropertySupervisorBase::setSupervisorProperty(CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes,
00054 "RefreshChat");
00055 }
00056
00057
00058
00059
00060
00061 void ChatSupervisor::request(const std::string& requestType, cgicc::Cgicc& cgiIn,
00062 HttpXmlDocument& xmlOut, const WebUsers::RequestUserInfo& userInfo)
00063 {
00064
00065
00066
00067
00068
00069
00070
00071 cleanupExpiredChats();
00072
00073 if(requestType == "RefreshChat")
00074 {
00075 std::string lastUpdateIndexString = CgiDataUtilities::postData(cgiIn,"lastUpdateIndex");
00076 std::string user = CgiDataUtilities::postData(cgiIn,"user");
00077 uint64_t lastUpdateIndex;
00078 sscanf(lastUpdateIndexString.c_str(),"%lu",&lastUpdateIndex);
00079
00080 insertChatRefresh(&xmlOut,lastUpdateIndex,user);
00081 }
00082 else if(requestType == "RefreshUsers")
00083 {
00084 insertActiveUsers(&xmlOut);
00085 }
00086 else if(requestType == "SendChat")
00087 {
00088 std::string chat = CgiDataUtilities::postData(cgiIn,"chat");
00089 std::string user = CgiDataUtilities::postData(cgiIn,"user");
00090
00091 escapeChat(chat);
00092
00093 newChat(chat, user);
00094 }
00095 else if(requestType == "PageUser")
00096 {
00097 std::string topage = CgiDataUtilities::postData(cgiIn,"topage");
00098 std::string user = CgiDataUtilities::postData(cgiIn,"user");
00099
00100 __COUT__ << "Paging = " << topage.substr(0,10) << "... from user = " << user.substr(0,10) << std::endl;
00101
00102 theRemoteWebUsers_.sendSystemMessage(allSupervisorInfo_.getGatewayDescriptor(),
00103 topage, user + " is paging you to come chat.");
00104 }
00105 else
00106 __COUT__ << "requestType request not recognized." << std::endl;
00107
00108
00109
00110 }
00111
00112
00113
00114
00115
00116 void ChatSupervisor::escapeChat(std::string &chat)
00117 {
00118
00119
00120
00121
00122
00123 }
00124
00125
00126
00127 void ChatSupervisor::insertActiveUsers(HttpXmlDocument *xmlOut)
00128 {
00129 xmlOut->addTextElementToData("active_users",
00130 theRemoteWebUsers_.getActiveUserList(allSupervisorInfo_.getGatewayDescriptor()));
00131 }
00132
00133
00134
00135
00136
00137
00138
00139
00140 void ChatSupervisor::insertChatRefresh(HttpXmlDocument *xmlOut, uint64_t lastUpdateIndex, std::string user)
00141 {
00142 newUser(user);
00143
00144 if(!isLastUpdateIndexStale(lastUpdateIndex)) return;
00145
00146
00147
00148 char tempStr[50];
00149 sprintf(tempStr,"%lu",ChatLastUpdateIndex);
00150 xmlOut->addTextElementToData("last_update_index",tempStr);
00151
00152
00153 xmlOut->addTextElementToData("chat_users","");
00154 for(uint64_t i=0;i<ChatUsers_.size();++i)
00155 xmlOut->addTextElementToParent("chat_user",ChatUsers_[i],"chat_users");
00156
00157 if(!lastUpdateIndex)
00158 lastUpdateIndex = ChatHistoryIndex_[ChatHistoryIndex_.size()-1]-1;
00159
00160
00161 xmlOut->addTextElementToData("chat_history","");
00162 for(uint64_t i=0;i<ChatHistoryEntry_.size();++i)
00163 {
00164 if(isChatOld(ChatHistoryIndex_[i],lastUpdateIndex)) continue;
00165
00166 xmlOut->addTextElementToParent("chat_entry",ChatHistoryEntry_[i],"chat_history");
00167 xmlOut->addTextElementToParent("chat_author",ChatHistoryAuthor_[i],"chat_history");
00168 sprintf(tempStr,"%lu",ChatHistoryTime_[i]);
00169 xmlOut->addTextElementToParent("chat_time",tempStr,"chat_history");
00170 }
00171 }
00172
00173
00174
00175
00176 void ChatSupervisor::newUser(std::string user)
00177 {
00178 for(uint64_t i=0;i<ChatUsers_.size();++i)
00179 if(ChatUsers_[i] == user)
00180 {
00181 ChatUsersTime_[i] = time(0);
00182 return;
00183 }
00184
00185 __COUT__ << "New user: " << user << std::endl;
00186
00187 ChatUsers_.push_back(user);
00188 ChatUsersTime_.push_back(time(0));
00189 newChat(user + " joined the chat.","ots");
00190 }
00191
00192
00193
00194
00195 void ChatSupervisor::newChat(std::string chat, std::string user)
00196 {
00197 ChatHistoryEntry_.push_back(chat);
00198 ChatHistoryAuthor_.push_back(user);
00199 ChatHistoryTime_.push_back(time(0));
00200 ChatHistoryIndex_.push_back(incrementAndGetLastUpdate());
00201 }
00202
00203
00204
00205
00206 bool ChatSupervisor::isChatOld(uint64_t chatIndex, uint64_t last)
00207 {
00208 return (last - chatIndex < (uint64_t(1) << 62));
00209 }
00210
00211
00212
00213 bool ChatSupervisor::isLastUpdateIndexStale(uint64_t last)
00214 {
00215 return ChatLastUpdateIndex != last;
00216 }
00217
00218
00219
00220 uint64_t ChatSupervisor::incrementAndGetLastUpdate()
00221 {
00222 if(!++ChatLastUpdateIndex) ++ChatLastUpdateIndex;
00223 return ChatLastUpdateIndex;
00224 }
00225
00226
00227
00228
00229 void ChatSupervisor::cleanupExpiredChats()
00230 {
00231 for(uint64_t i=0;i<ChatHistoryEntry_.size();++i)
00232 if(i >= CHAT_HISTORY_MAX_ENTRIES ||
00233 ChatHistoryTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0))
00234 {
00235 removeChatHistoryEntry(i);
00236 --i;
00237 }
00238 else
00239 break;
00240
00241 for(uint64_t i=0;i<ChatUsers_.size();++i)
00242 if(ChatUsersTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0))
00243 {
00244 removeChatUserEntry(i);
00245 --i;
00246 }
00247 else
00248 break;
00249 }
00250
00251
00252
00253 void ChatSupervisor::removeChatHistoryEntry(uint64_t i)
00254 {
00255 ChatHistoryEntry_.erase (ChatHistoryEntry_.begin()+i);
00256 ChatHistoryTime_.erase (ChatHistoryTime_.begin()+i);
00257 ChatHistoryAuthor_.erase (ChatHistoryAuthor_.begin()+i);
00258 ChatHistoryIndex_.erase (ChatHistoryIndex_.begin()+i);
00259 }
00260
00261
00262
00263 void ChatSupervisor::removeChatUserEntry(uint64_t i)
00264 {
00265 newChat(ChatUsers_[i] + " left the chat.","ots");
00266 ChatUsers_.erase (ChatUsers_.begin()+i);
00267 ChatUsersTime_.erase (ChatUsersTime_.begin()+i);
00268 }
00269
00270
00271
00272
00273
00274
00275
00276