loleaflet/dist/admin/bootstrap/dashboard.css | 12 ++++++ loleaflet/src/admin/AdminSocketOverview.js | 53 ++++++++++++++++++--------- wsd/Admin.cpp | 6 +-- wsd/Admin.hpp | 2 - wsd/AdminModel.cpp | 43 ++++++++++++++++++--- wsd/AdminModel.hpp | 10 +++-- wsd/ClientSession.hpp | 1 wsd/DocumentBroker.cpp | 2 - 8 files changed, 99 insertions(+), 30 deletions(-)
New commits: commit 41ed318de8c1ebb5c2d707b6fb12a9c9b5440407 Author: Aditya Dewan <iit2015...@iiita.ac.in> Date: Fri Apr 7 19:49:04 2017 +0530 tdf#106449 admin:adding user list for each document Change-Id: Ia5c382f469a80464d0435e1e2e4de3daaba8a690 Reviewed-on: https://gerrit.libreoffice.org/36275 Reviewed-by: pranavk <pran...@collabora.co.uk> Tested-by: pranavk <pran...@collabora.co.uk> diff --git a/loleaflet/dist/admin/bootstrap/dashboard.css b/loleaflet/dist/admin/bootstrap/dashboard.css index 0535a2fd..60ed98d2 100644 --- a/loleaflet/dist/admin/bootstrap/dashboard.css +++ b/loleaflet/dist/admin/bootstrap/dashboard.css @@ -113,3 +113,15 @@ body { position: absolute; display: none; } + +.userContainer{ + display: none; + position: absolute; + border: 1px solid black; + padding: 5px; + border-radius: 4px; + background-color: #dddddd; +} +tr:hover .userContainer{ + display: block; +} \ No newline at end of file diff --git a/loleaflet/src/admin/AdminSocketOverview.js b/loleaflet/src/admin/AdminSocketOverview.js index 4f6e0812..96c29a0b 100644 --- a/loleaflet/src/admin/AdminSocketOverview.js +++ b/loleaflet/src/admin/AdminSocketOverview.js @@ -89,21 +89,31 @@ var AdminSocketOverview = AdminSocketBase.extend({ var nViews, nTotalViews; var docProps, sPid, sName, sViews, sMem, sDocTime; if (textMsg.startsWith('documents')) { - var documents = textMsg.substring('documents'.length); - documents = documents.trim().split('\n'); - for (var i = 0; i < documents.length; i++) { - docProps = documents[i].trim().split(' '); - sPid = docProps[0]; - sName = decodeURI(docProps[1]); - sViews = docProps[2]; - sMem = docProps[3]; - sDocTime = docProps[4]; - sDocIdle = docProps[5]; + jsonStart = textMsg.indexOf('{'); + jsonMsg = JSON.parse(textMsg.substr(jsonStart).trim()); + docList = jsonMsg['documents']; + for (var i = 0; i < docList.length; i++) { + + docProps = docList[i]; + sPid = docProps['pid']; + sName = decodeURI(docProps['fileName']); + sViews = docProps['activeViews']; + sMem = docProps['memory']; + sDocTime = docProps['elapsedTime']; + sDocIdle = docProps['idleTime']; + userListJson = docProps['views'] $doc = $('#doc' + sPid); $rowContainer = $(document.createElement('tr')).attr('id', 'doc' + sPid); - $pid = $(document.createElement('td')).text(sPid); + $userContainer = $(document.createElement('div')).attr('id', 'ucontainer' + sPid) + .addClass('userContainer'); + for (var j = 0; j < userListJson.length; j++) { + $user = $(document.createElement('div')).text(userListJson[j]['userName']) + .attr('id', 'user' + userListJson[j]['sessionid']); + $userContainer.append($user); + } + $pid.append($userContainer); $rowContainer.append($pid); $name = $(document.createElement('td')).text(sName); @@ -142,14 +152,18 @@ var AdminSocketOverview = AdminSocketBase.extend({ docProps = textMsg.trim().split(' '); sPid = docProps[0]; sName = decodeURI(docProps[1]); - // docProps[2] == sessionid - sMem = docProps[3]; + sessionid = docProps[2]; + uName = decodeURI(docProps[3]); + sMem = docProps[4]; $doc = $('#doc' + sPid); if ($doc.length === 0) { $rowContainer = $(document.createElement('tr')).attr('id', 'doc' + sPid); $pid = $(document.createElement('td')).text(sPid); + $userContainer = $(document.createElement('div')).attr('id', 'ucontainer' + sPid) + .addClass('userContainer'); + $pid.append($userContainer); $rowContainer.append($pid); $name = $(document.createElement('td')).text(sName); @@ -183,6 +197,11 @@ var AdminSocketOverview = AdminSocketBase.extend({ nViews = parseInt($views.text()); $views.text(nViews + 1); + $userContainer = $(document.getElementById('ucontainer' + sPid)); + $user = $(document.createElement('div')).text(uName) + .attr('id', 'user' + sessionid); + $userContainer.append($user); + $a = $(document.getElementById('active_users_count')); nTotalViews = parseInt($a.text()); $a.text(nTotalViews + 1); @@ -204,22 +223,24 @@ var AdminSocketOverview = AdminSocketBase.extend({ textMsg = textMsg.substring('rmdoc'.length); docProps = textMsg.trim().split(' '); sPid = docProps[0]; - // docProps[1] == sessionid + sessionid = docProps[1]; $doc = $('#doc' + sPid); if ($doc.length !== 0) { + $user = $(document.getElementById('user' + sessionid)); + $user.remove(); $views = $('#docview' + sPid); nViews = parseInt($views.text()) - 1; $views.text(nViews); if (nViews === 0) { $doc.remove(); } - $a = $(document.getElementById('active_users_count')); nTotalViews = parseInt($a.text()); $a.text(nTotalViews - 1); } - } else if (textMsg.startsWith('propchange')) { + } + else if (textMsg.startsWith('propchange')) { textMsg = textMsg.substring('propchange'.length); docProps = textMsg.trim().split(' '); sPid = docProps[0]; diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp index f5b63b1e..f4bbe1de 100644 --- a/wsd/Admin.cpp +++ b/wsd/Admin.cpp @@ -349,10 +349,10 @@ void Admin::pollingThread() } } -void Admin::addDoc(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const std::string& sessionId) +void Admin::addDoc(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const std::string& sessionId, const std::string& userName) { - addCallback([this, docKey, pid, filename, sessionId] - { _model.addDocument(docKey, pid, filename, sessionId); }); + addCallback([this, docKey, pid, filename, sessionId, userName] + { _model.addDocument(docKey, pid, filename, sessionId, userName); }); } void Admin::rmDoc(const std::string& docKey, const std::string& sessionId) diff --git a/wsd/Admin.hpp b/wsd/Admin.hpp index 033619a7..d04fa543 100644 --- a/wsd/Admin.hpp +++ b/wsd/Admin.hpp @@ -75,7 +75,7 @@ public: void update(const std::string& message); /// Calls with same pid will increment view count, if pid already exists - void addDoc(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const std::string& sessionId); + void addDoc(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const std::string& sessionId, const std::string& userName); /// Decrement view count till becomes zero after which doc is removed void rmDoc(const std::string& docKey, const std::string& sessionId); diff --git a/wsd/AdminModel.cpp b/wsd/AdminModel.cpp index 3429553f..e7a2e4ac 100644 --- a/wsd/AdminModel.cpp +++ b/wsd/AdminModel.cpp @@ -26,9 +26,9 @@ #include "Unit.hpp" #include "Util.hpp" -void Document::addView(const std::string& sessionId) +void Document::addView(const std::string& sessionId, const std::string& userName) { - const auto ret = _views.emplace(sessionId, View(sessionId)); + const auto ret = _views.emplace(sessionId, View(sessionId, userName)); if (!ret.second) { LOG_WRN("View with SessionID [" << sessionId << "] already exists."); @@ -374,24 +374,28 @@ void AdminModel::notify(const std::string& message) } void AdminModel::addDocument(const std::string& docKey, Poco::Process::PID pid, - const std::string& filename, const std::string& sessionId) + const std::string& filename, const std::string& sessionId, + const std::string& userName) { assertCorrectThread(); const auto ret = _documents.emplace(docKey, Document(docKey, pid, filename)); - ret.first->second.addView(sessionId); ret.first->second.takeSnapshot(); + ret.first->second.addView(sessionId, userName); LOG_DBG("Added admin document [" << docKey << "]."); + std::string encodedUsername; std::string encodedFilename; Poco::URI::encode(filename, " ", encodedFilename); + Poco::URI::encode(userName, " ", encodedUsername); // Notify the subscribers std::ostringstream oss; oss << "adddoc " << pid << ' ' << encodedFilename << ' ' - << sessionId << ' '; + << sessionId << ' ' + << encodedUsername << ' '; // We have to wait until the kit sends us its PSS. // Here we guestimate until we get an update. @@ -512,13 +516,40 @@ std::string AdminModel::getDocuments() const assertCorrectThread(); std::ostringstream oss; + std::map<std::string, View> viewers; + oss << '{' << "\"documents\"" << ':' << '['; + std::string separator1 = ""; for (const auto& it: _documents) { if (!it.second.isExpired()) { - oss << it.second.to_string() << "\n "; + std::string encodedFilename; + Poco::URI::encode(it.second.getFilename(), " ", encodedFilename); + oss << separator1 << '{' << ' ' + << "\"pid\"" << ':' << it.second.getPid() << ',' + << "\"fileName\"" << ':' << '"' << encodedFilename << '"' << ',' + << "\"activeViews\"" << ':' << it.second.getActiveViews() << ',' + << "\"memory\"" << ':' << it.second.getMemoryDirty() << ',' + << "\"elapsedTime\"" << ':' << it.second.getElapsedTime() << ',' + << "\"idleTime\"" << ':' << it.second.getIdleTime() << ',' + << "\"views\"" << ':' << '['; + viewers = it.second.getViews(); + std::string separator = ""; + for(const auto& viewIt: viewers) + { + if(!viewIt.second.isExpired()) { + oss << separator << '{' + << "\"userName\"" << ':' << '"' << viewIt.second.getUserName() << '"' << ',' + << "\"sessionid\"" << ':' << '"' << viewIt.second.getSessionId() << '"' << '}'; + separator = ','; + } + } + oss << "]" + << "}"; + separator1 = ','; } } + oss << "]" << "}"; return oss.str(); } diff --git a/wsd/AdminModel.hpp b/wsd/AdminModel.hpp index 1b37f1a8..aad075eb 100644 --- a/wsd/AdminModel.hpp +++ b/wsd/AdminModel.hpp @@ -24,17 +24,21 @@ class View { public: - View(const std::string& sessionId) : + View(const std::string& sessionId, const std::string& userName) : _sessionId(sessionId), + _userName(userName), _start(std::time(nullptr)) { } void expire() { _end = std::time(nullptr); } + std::string getUserName() const { return _userName; } + std::string getSessionId() const { return _sessionId; } bool isExpired() const { return _end != 0 && std::time(nullptr) >= _end; } private: const std::string _sessionId; + const std::string _userName; const std::time_t _start; std::time_t _end = 0; }; @@ -65,7 +69,7 @@ public: std::time_t getIdleTime() const { return std::time(nullptr) - _lastActivity; } - void addView(const std::string& sessionId); + void addView(const std::string& sessionId, const std::string& userName); int expireView(const std::string& sessionId); @@ -185,7 +189,7 @@ public: void notify(const std::string& message); - void addDocument(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const std::string& sessionId); + void addDocument(const std::string& docKey, Poco::Process::PID pid, const std::string& filename, const std::string& sessionId, const std::string& userName); void removeDocument(const std::string& docKey, const std::string& sessionId); void removeDocument(const std::string& docKey); diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp index 9cd67533..396f45c9 100644 --- a/wsd/ClientSession.hpp +++ b/wsd/ClientSession.hpp @@ -39,6 +39,7 @@ public: void setAttached() { _isAttached = true; } const std::string getUserId() const { return _userId; } + const std::string getUserName() const {return _userName; } void setUserId(const std::string& userId) { _userId = userId; } void setUserName(const std::string& userName) { _userName = userName; } void setDocumentOwner(const bool documentOwner) { _isDocumentOwner = documentOwner; } diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 94a49a1d..31ab6598 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -847,7 +847,7 @@ size_t DocumentBroker::addSession(const std::shared_ptr<ClientSession>& session) _childProcess->sendTextFrame(aMessage); // Tell the admin console about this new doc - Admin::instance().addDoc(_docKey, getPid(), getFilename(), id); + Admin::instance().addDoc(_docKey, getPid(), getFilename(), id, session->getUserName()); LOG_TRC("Added " << (session->isReadOnly() ? "readonly" : "non-readonly") << " session [" << id << "] to docKey [" << _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits