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