Mercurial > hg > orthanc-wsi
changeset 568:88cbe7ab5c23 annotations
periodic update of project information
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Tue, 01 Sep 2026 20:51:08 +0200 |
| parents | b596132164b6 |
| children | d8b367955b10 |
| files | ViewerPlugin/Annotations/AnnotationsRestApi.cpp |
| diffstat | 1 files changed, 99 insertions(+), 73 deletions(-) [+] |
line wrap: on
line diff
--- a/ViewerPlugin/Annotations/AnnotationsRestApi.cpp Tue Sep 01 18:31:38 2026 +0200 +++ b/ViewerPlugin/Annotations/AnnotationsRestApi.cpp Tue Sep 01 20:51:08 2026 +0200 @@ -725,26 +725,90 @@ }; + class ProjectInformation : public boost::noncopyable + { + private: + boost::mutex mutex_; + std::string projectId_; + boost::posix_time::ptime lastUpdate_; + std::string name_; + std::string description_; + + static boost::posix_time::ptime GetNow() + { + return boost::posix_time::second_clock::universal_time(); + } + + + void Load() + { + Json::Value info; + + if (OrthancPlugins::RestApiGet(info, "/education/api-plugins/project?id=" + projectId_, true) && + info.isObject()) + { + // The "orthanc-education" plugin is available + name_ = Orthanc::SerializationToolbox::ReadString(info, "name", ""); + description_ = Orthanc::SerializationToolbox::ReadString(info, "description", ""); + } + else + { + name_.clear(); + description_.clear(); + } + + lastUpdate_ = GetNow(); + + description_ = boost::posix_time::to_iso_string(lastUpdate_); + } + + // The mutex must be locked + void Refresh() + { + if (GetNow() - lastUpdate_ >= boost::posix_time::seconds(10)) + { + Load(); + } + } + + public: + ProjectInformation(const std::string& projectId) : + projectId_(projectId) + { + Load(); + } + + std::string GetName() + { + boost::mutex::scoped_lock lock(mutex_); + Refresh(); + return name_; + } + + std::string GetDescription() + { + boost::mutex::scoped_lock lock(mutex_); + Refresh(); + return description_; + } + }; + + class AnnotationsWorkspace : public Orthanc::IDynamicObject { private: - class Info : public ISerializable + class PersistentInfo : public ISerializable { private: - std::string projectName_; - std::string projectDescription_; std::set<UserId> activeUsers_; public: - Info() + PersistentInfo() { } - Info(const Json::Value& serialized) + PersistentInfo(const Json::Value& serialized) { - projectName_ = Orthanc::SerializationToolbox::ReadString(serialized, KEY_PROJECT_NAME); - projectDescription_ = Orthanc::SerializationToolbox::ReadString(serialized, KEY_PROJECT_DESCRIPTION); - const Json::Value& users = serialized[KEY_ACTIVE_USERS]; if (!users.isArray()) @@ -758,26 +822,6 @@ } } - const std::string& GetProjectName() const - { - return projectName_; - } - - void SetProjectName(const std::string& name) - { - projectName_ = name; - } - - const std::string& GetProjectDescription() const - { - return projectDescription_; - } - - void SetProjectDescription(const std::string& description) - { - projectDescription_ = description; - } - // Return "true" iff. the user was not already tagged as active bool AddActiveUser(const UserId& user) { @@ -808,8 +852,6 @@ } serialized = Json::objectValue; - serialized[KEY_PROJECT_NAME] = projectName_; - serialized[KEY_PROJECT_DESCRIPTION] = projectDescription_; serialized[KEY_ACTIVE_USERS] = users; } }; @@ -831,23 +873,19 @@ } } - const Info& GetInfo() const - { - assert(info_.get() != NULL); - return *info_; - } - typedef std::map<UserId, UserAnnotationsSettings*> Content; - Orthanc::ReaderWriterLock mutex_; - AnnotationsWorkspaceId id_; - std::unique_ptr<Info> info_; - Content content_; + Orthanc::ReaderWriterLock mutex_; + AnnotationsWorkspaceId id_; + std::unique_ptr<PersistentInfo> persistentInfo_; + Content content_; + ProjectInformation projectInformation_; public: AnnotationsWorkspace(const AnnotationsWorkspaceId& id) : - id_(id) + id_(id), + projectInformation_(id.GetProjectId()) { const std::string key = id.GetInfoKey(); @@ -855,26 +893,18 @@ if (LookupKeyValueStore(info, key)) { - info_.reset(new Info(info)); + persistentInfo_.reset(new PersistentInfo(info)); - for (std::set<UserId>::const_iterator it = info_->GetActiveUsers().begin(); - it != info_->GetActiveUsers().end(); ++it) + for (std::set<UserId>::const_iterator it = persistentInfo_->GetActiveUsers().begin(); + it != persistentInfo_->GetActiveUsers().end(); ++it) { Load(*it); } } else { - info_.reset(new Info); - - if (OrthancPlugins::RestApiGet(info, "/education/api-plugins/project?id=" + id.GetProjectId(), true)) - { - // The "orthanc-education" plugin is available - info_->SetProjectName(Orthanc::SerializationToolbox::ReadString(info, "name")); - info_->SetProjectDescription(Orthanc::SerializationToolbox::ReadString(info, "description")); - } - - info_->Serialize(info); + persistentInfo_.reset(new PersistentInfo); + persistentInfo_->Serialize(info); SetKeyValueStore(key, info); } } @@ -888,6 +918,16 @@ } } + std::string GetProjectName() + { + return projectInformation_.GetName(); + } + + std::string GetProjectDescription() + { + return projectInformation_.GetDescription(); + } + void SearchActiveUsers(std::set<UserId>& target, const std::string& query) @@ -897,7 +937,7 @@ target.clear(); const boost::regex re(query); - const std::set<UserId>& activeUsers = info_->GetActiveUsers(); + const std::set<UserId>& activeUsers = persistentInfo_->GetActiveUsers(); for (std::set<UserId>::const_iterator it = activeUsers.begin(); it != activeUsers.end(); ++it) { @@ -977,16 +1017,6 @@ return userSettings_ != NULL; } - const std::string& GetProjectName() const - { - return that_.GetInfo().GetProjectName(); - } - - const std::string& GetProjectDescription() const - { - return that_.GetInfo().GetProjectDescription(); - } - void ListLayers(Json::Value& serialized) const { serialized = Json::objectValue; @@ -1088,10 +1118,10 @@ that_(that), userId_(userId) { - if (that.info_->AddActiveUser(userId_)) + if (that.persistentInfo_->AddActiveUser(userId_)) { // Only update the key-value store if this is the first time we meet this user - SetKeyValueStore(that.id_.GetInfoKey(), *that.info_); + SetKeyValueStore(that.id_.GetInfoKey(), *that.persistentInfo_); } Content::iterator found = that.content_.find(userId_); @@ -1328,12 +1358,8 @@ Json::Value answer; - { - AnnotationsWorkspace::UserReader reader(context.GetWorkspace(), context.GetUser().GetAnnotatingId()); - answer["description"] = reader.GetProjectDescription(); - answer["name"] = reader.GetProjectName(); - } - + answer["name"] = context.GetWorkspace().GetProjectName(); + answer["description"] = context.GetWorkspace().GetProjectDescription(); answer["enabled"] = ViewerConfiguration::GetInstance().AreAnnotationsEnabled(); answer["sharing"] = (ViewerConfiguration::GetInstance().AreAnnotationsEnabled() && ViewerConfiguration::GetInstance().IsAnnotationsSharingEnabled());
