$treeview $search $mathjax $extrastylesheet
otsdaq_utilities
v2_03_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #include "otsdaq-utilities/Chat/ChatSupervisor.h" 00002 #include "otsdaq-core/CgiDataUtilities/CgiDataUtilities.h" 00003 #include "otsdaq-core/Macros/CoutMacros.h" 00004 #include "otsdaq-core/MessageFacility/MessageFacility.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; // skip 0 00026 } 00027 00028 //======================================================================================================================== 00029 ChatSupervisor::~ChatSupervisor(void) { destroy(); } 00030 00031 //======================================================================================================================== 00032 void ChatSupervisor::destroy(void) 00033 { 00034 // called by destructor 00035 } 00036 00037 //======================================================================================================================== 00038 void ChatSupervisor::defaultPage(xgi::Input* cgiIn, xgi::Output* out) 00039 { 00040 *out << "<!DOCTYPE HTML><html lang='en'><frameset col='100%' row='100%'><frame " 00041 "src='/WebPath/html/Chat.html?urn=" 00042 << this->getApplicationDescriptor()->getLocalId() << "'></frameset></html>"; 00043 } 00044 00045 //======================================================================================================================== 00046 // forceSupervisorPropertyValues 00047 // override to force supervisor property values (and ignore user settings) 00048 void ChatSupervisor::forceSupervisorPropertyValues() 00049 { 00050 CorePropertySupervisorBase::setSupervisorProperty( 00051 CorePropertySupervisorBase::SUPERVISOR_PROPERTIES.AutomatedRequestTypes, 00052 "RefreshChat"); 00053 } 00054 00055 //======================================================================================================================== 00056 // request 00057 // Handles Web Interface requests to chat supervisor. 00058 // Does not refresh cookie for automatic update checks. 00059 void ChatSupervisor::request(const std::string& requestType, 00060 cgicc::Cgicc& cgiIn, 00061 HttpXmlDocument& xmlOut, 00062 const WebUsers::RequestUserInfo& userInfo) 00063 { 00064 //__COUT__ << "requestType: " << requestType << std::endl; 00065 00066 // Commands 00067 // RefreshChat 00068 // RefreshUsers 00069 // SendChat 00070 00071 cleanupExpiredChats(); 00072 00073 if(requestType == "RefreshChat") 00074 { 00075 std::string lastUpdateIndexString = 00076 CgiDataUtilities::postData(cgiIn, "lastUpdateIndex"); 00077 std::string user = CgiDataUtilities::postData(cgiIn, "user"); 00078 uint64_t lastUpdateIndex; 00079 sscanf(lastUpdateIndexString.c_str(), "%lu", &lastUpdateIndex); 00080 00081 insertChatRefresh(&xmlOut, lastUpdateIndex, user); 00082 } 00083 else if(requestType == "RefreshUsers") 00084 { 00085 insertActiveUsers(&xmlOut); 00086 } 00087 else if(requestType == "SendChat") 00088 { 00089 std::string chat = CgiDataUtilities::postData(cgiIn, "chat"); 00090 std::string user = CgiDataUtilities::postData(cgiIn, "user"); 00091 00092 escapeChat(chat); 00093 00094 newChat(chat, user); 00095 } 00096 else if(requestType == "PageUser") 00097 { 00098 std::string topage = CgiDataUtilities::postData(cgiIn, "topage"); 00099 std::string user = CgiDataUtilities::postData(cgiIn, "user"); 00100 00101 __COUT__ << "Paging = " << topage.substr(0, 10) 00102 << "... from user = " << user.substr(0, 10) << std::endl; 00103 00104 theRemoteWebUsers_.sendSystemMessage(allSupervisorInfo_.getGatewayDescriptor(), 00105 topage, 00106 user + " is paging you to come chat."); 00107 } 00108 else 00109 __COUT__ << "requestType request not recognized." << std::endl; 00110 // 00111 // //return xml doc holding server response 00112 // xmlOut.outputXmlDocument((std::ostringstream*)out); 00113 } 00114 00115 //======================================================================================================================== 00116 // ChatSupervisor::escapeChat() 00117 // replace html/xhtml reserved characters with equivalent. 00118 // reserved: ", ', &, <, > 00119 void ChatSupervisor::escapeChat(std::string& chat) 00120 { 00121 // char reserved[] = {'"','\'','&','<','>'}; 00122 // std::string replace[] = {""","'","&","<",">"}; 00123 // for(uint64_t i=0;i<chat.size();++i) 00124 // for(uint64_t j=0;j<chat.size();++j) 00125 // if(chat[i] == 00126 } 00127 00128 //======================================================================================================================== 00129 // ChatSupervisor::insertActiveUsers() 00130 void ChatSupervisor::insertActiveUsers(HttpXmlDocument* xmlOut) 00131 { 00132 xmlOut->addTextElementToData( 00133 "active_users", 00134 theRemoteWebUsers_.getActiveUserList(allSupervisorInfo_.getGatewayDescriptor())); 00135 } 00136 00137 //======================================================================================================================== 00138 // ChatSupervisor::insertChatRefresh() 00139 // check if user is new to list (may cause update) 00140 // each new user causes update to last index 00141 // if lastUpdateIndex is current, return nothing 00142 // else return full chat user list and new chats 00143 // (note: lastUpdateIndex==0 first time and returns only user list. no chats) 00144 void ChatSupervisor::insertChatRefresh(HttpXmlDocument* xmlOut, 00145 uint64_t lastUpdateIndex, 00146 std::string user) 00147 { 00148 newUser(user); 00149 00150 if(!isLastUpdateIndexStale(lastUpdateIndex)) 00151 return; // if lastUpdateIndex is current, return nothing 00152 00153 // return new update index, full chat user list, and new chats! 00154 00155 char tempStr[50]; 00156 sprintf(tempStr, "%lu", ChatLastUpdateIndex); 00157 xmlOut->addTextElementToData("last_update_index", tempStr); 00158 00159 // get all users 00160 xmlOut->addTextElementToData("chat_users", ""); 00161 for(uint64_t i = 0; i < ChatUsers_.size(); ++i) 00162 xmlOut->addTextElementToParent("chat_user", ChatUsers_[i], "chat_users"); 00163 00164 if(!lastUpdateIndex) // lastUpdateIndex == 0, so just give the <user> entered chat 00165 // message only 00166 lastUpdateIndex = ChatHistoryIndex_[ChatHistoryIndex_.size() - 1] - 00167 1; // new user will then get future chats 00168 00169 // get all accounts 00170 xmlOut->addTextElementToData("chat_history", ""); 00171 for(uint64_t i = 0; i < ChatHistoryEntry_.size(); ++i) // output oldest to new 00172 { 00173 if(isChatOld(ChatHistoryIndex_[i], lastUpdateIndex)) 00174 continue; 00175 00176 xmlOut->addTextElementToParent( 00177 "chat_entry", ChatHistoryEntry_[i], "chat_history"); 00178 xmlOut->addTextElementToParent( 00179 "chat_author", ChatHistoryAuthor_[i], "chat_history"); 00180 sprintf(tempStr, "%lu", ChatHistoryTime_[i]); 00181 xmlOut->addTextElementToParent("chat_time", tempStr, "chat_history"); 00182 } 00183 } 00184 00185 //======================================================================================================================== 00186 // ChatSupervisor::newUser() 00187 // create new user if needed, and increment update 00188 void ChatSupervisor::newUser(std::string user) 00189 { 00190 for(uint64_t i = 0; i < ChatUsers_.size(); ++i) 00191 if(ChatUsers_[i] == user) 00192 { 00193 ChatUsersTime_[i] = time(0); // update time 00194 return; // do not add new if found 00195 } 00196 00197 __COUT__ << "New user: " << user << std::endl; 00198 // add and increment 00199 ChatUsers_.push_back(user); 00200 ChatUsersTime_.push_back(time(0)); 00201 newChat(user + " joined the chat.", 00202 "ots"); // add status message to chat, increment update 00203 } 00204 00205 //======================================================================================================================== 00206 // ChatSupervisor::newChat() 00207 // create new chat, and increment update 00208 void ChatSupervisor::newChat(std::string chat, std::string user) 00209 { 00210 ChatHistoryEntry_.push_back(chat); 00211 ChatHistoryAuthor_.push_back(user); 00212 ChatHistoryTime_.push_back(time(0)); 00213 ChatHistoryIndex_.push_back(incrementAndGetLastUpdate()); 00214 } 00215 00216 //======================================================================================================================== 00217 // ChatSupervisor::isChatNew() 00218 // return true if chatIndex is older than lastUpdateIndex 00219 bool ChatSupervisor::isChatOld(uint64_t chatIndex, uint64_t last) 00220 { 00221 return (last - chatIndex < (uint64_t(1) << 62)); 00222 } 00223 00224 //======================================================================================================================== 00225 // ChatSupervisor::isLastUpdateIndexStale() 00226 bool ChatSupervisor::isLastUpdateIndexStale(uint64_t last) 00227 { 00228 return ChatLastUpdateIndex != last; 00229 } 00230 00231 //======================================================================================================================== 00232 // ChatSupervisor::incrementAndGetLastUpdate() 00233 uint64_t ChatSupervisor::incrementAndGetLastUpdate() 00234 { 00235 if(!++ChatLastUpdateIndex) 00236 ++ChatLastUpdateIndex; // skip 0 00237 return ChatLastUpdateIndex; 00238 } 00239 00240 //======================================================================================================================== 00241 // ChatSupervisor::cleanupExpiredChats() 00242 // remove expired entries from Chat history and user list 00243 void ChatSupervisor::cleanupExpiredChats() 00244 { 00245 for(uint64_t i = 0; i < ChatHistoryEntry_.size(); ++i) 00246 if(i >= CHAT_HISTORY_MAX_ENTRIES || 00247 ChatHistoryTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0)) // expired 00248 { 00249 removeChatHistoryEntry(i); 00250 --i; // rewind loop 00251 } 00252 else 00253 break; // chronological order, so first encountered that is still valid exit 00254 // loop 00255 00256 for(uint64_t i = 0; i < ChatUsers_.size(); ++i) 00257 if(ChatUsersTime_[i] + CHAT_HISTORY_EXPIRATION_TIME < time(0)) // expired 00258 { 00259 removeChatUserEntry(i); 00260 --i; // rewind loop 00261 } 00262 else 00263 break; // chronological order, so first encountered that is still valid exit 00264 // loop 00265 } 00266 00267 //======================================================================================================================== 00268 // ChatSupervisor::removeChatHistoryEntry() 00269 void ChatSupervisor::removeChatHistoryEntry(uint64_t i) 00270 { 00271 ChatHistoryEntry_.erase(ChatHistoryEntry_.begin() + i); 00272 ChatHistoryTime_.erase(ChatHistoryTime_.begin() + i); 00273 ChatHistoryAuthor_.erase(ChatHistoryAuthor_.begin() + i); 00274 ChatHistoryIndex_.erase(ChatHistoryIndex_.begin() + i); 00275 } 00276 00277 //======================================================================================================================== 00278 // ChatSupervisor::removeChatHistoryEntry() 00279 void ChatSupervisor::removeChatUserEntry(uint64_t i) 00280 { 00281 newChat(ChatUsers_[i] + " left the chat.", 00282 "ots"); // add status message to chat, increment update 00283 ChatUsers_.erase(ChatUsers_.begin() + i); 00284 ChatUsersTime_.erase(ChatUsersTime_.begin() + i); 00285 }