Mercurial > hg > orthanc-wsi
changeset 570:90d017623910 annotations
reorganization
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Tue, 01 Sep 2026 21:24:14 +0200 |
| parents | d8b367955b10 |
| children | c4f3e08e0c44 |
| files | ViewerPlugin/Annotations/AnnotationsRestApi.cpp ViewerPlugin/Annotations/AnnotationsWorkspaceId.cpp ViewerPlugin/Annotations/AnnotationsWorkspaceId.h ViewerPlugin/Annotations/ISerializable.cpp ViewerPlugin/Annotations/ISerializable.h ViewerPlugin/CMakeLists.txt ViewerPlugin/ViewerToolbox.cpp ViewerPlugin/ViewerToolbox.h |
| diffstat | 8 files changed, 365 insertions(+), 192 deletions(-) [+] |
line wrap: on
line diff
--- a/ViewerPlugin/Annotations/AnnotationsRestApi.cpp Tue Sep 01 21:05:06 2026 +0200 +++ b/ViewerPlugin/Annotations/AnnotationsRestApi.cpp Tue Sep 01 21:24:14 2026 +0200 @@ -27,7 +27,9 @@ #include "../../Framework/BackgroundColor.h" #include "../ViewerConfiguration.h" #include "../ViewerToolbox.h" +#include "AnnotationsWorkspaceId.h" #include "IAuthenticatedUser.h" +#include "ISerializable.h" #include <Cache/SharedObjectCache.h> #include <Compression/GzipCompressor.h> @@ -42,105 +44,6 @@ namespace OrthancWSI { - class AnnotationsWorkspaceId - { - private: - std::string projectId_; - Orthanc::ResourceType level_; - std::string resourceId_; - unsigned int frameNumber_; - - std::string GetKeyPrefix() const - { - switch (level_) - { - case Orthanc::ResourceType_Series: - return projectId_ + "|series|" + resourceId_; - - case Orthanc::ResourceType_Instance: - return projectId_ + "|instance|" + boost::lexical_cast<std::string>(frameNumber_) + "|" + resourceId_; - - default: - throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); - } - } - - public: - AnnotationsWorkspaceId(const std::string& projectId, - Orthanc::ResourceType level, - const std::string& resourceId, - unsigned int frameNumber) : - projectId_(projectId), - level_(level), - resourceId_(resourceId), - frameNumber_(frameNumber) - { - if (level_ != Orthanc::ResourceType_Series && - level_ != Orthanc::ResourceType_Instance) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - - // The pipe symbol is disallowed as it is used to build the key, cf. GetKey() - if (!Orthanc::Toolbox::IsAsciiString(projectId_) || - projectId_.find('|') != std::string::npos) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, - "Project name containing non-ASCII characters or the pipe symbol: " + projectId_); - } - - if (!Orthanc::Toolbox::IsAsciiString(resourceId_) || - resourceId_.find('|') != std::string::npos) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, - "Resource ID containing non-ASCII characters or the pipe symbol: " + resourceId_); - } - } - - const std::string& GetProjectId() const - { - return projectId_; - } - - Orthanc::ResourceType GetLevel() const - { - return level_; - } - - const std::string& GetResourceId() const - { - return resourceId_; - } - - unsigned int GetFrameNumber() const - { - if (level_ == Orthanc::ResourceType_Instance) - { - return frameNumber_; - } - else - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); - } - } - - std::string GetInfoKey() const - { - return GetKeyPrefix() + "|info"; - } - - std::string GetSettingsKey(const UserId& user) const - { - return GetKeyPrefix() + "|settings|" + user.GetKey(); - } - - std::string GetFeaturesKey(const UserId& user) const - { - return GetKeyPrefix() + "|features|" + user.GetKey(); - } - }; - - static const char* const KEY_AUTHOR = "author"; static const char* const KEY_COLOR = "color"; static const char* const KEY_FEATURES = "features"; @@ -154,27 +57,6 @@ static const char* const KEY_VERSION = "version"; static const char* const KEY_VISIBLE = "visible"; - static const char* const KEY_VALUE_STORE = "wsi"; - - - class ISerializable : public boost::noncopyable - { - public: - virtual ~ISerializable() - { - } - - virtual void Serialize(Json::Value& serialized) const = 0; - - static void Serialize(std::string& serialized, - const ISerializable& obj) - { - Json::Value value; - obj.Serialize(value); - Orthanc::Toolbox::WriteFastJson(serialized, value); - } - }; - class ILayer : public ISerializable { @@ -330,71 +212,6 @@ }; - static void SetKeyValueStore(const std::string& key, - const std::string& value) - { -#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 8) - OrthancPlugins::KeyValueStore store(KEY_VALUE_STORE); - store.Store(key, value); -#else - LOG(WARNING) << "Your Orthanc SDK is too old to save annotations"; -#endif - } - - - static void SetKeyValueStore(const std::string& key, - const Json::Value& value) - { - std::string s; - Orthanc::Toolbox::WriteFastJson(s, value); - SetKeyValueStore(key, s); - } - - - static void SetKeyValueStore(const std::string& key, - const ISerializable& value) - { - std::string s; - ISerializable::Serialize(s, value); - SetKeyValueStore(key, s); - } - - - static bool LookupKeyValueStore(std::string& value, - const std::string& key) - { -#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 8) - OrthancPlugins::KeyValueStore store(KEY_VALUE_STORE); - return store.GetValue(value, key); -#else - LOG(WARNING) << "Your Orthanc SDK is too old to load annotations"; - return false; -#endif - } - - - static bool LookupKeyValueStore(Json::Value& value, - const std::string& key) - { - std::string s; - if (LookupKeyValueStore(s, key)) - { - if (Orthanc::Toolbox::ReadJson(value, s)) - { - return true; - } - else - { - LOG(WARNING) << "Discarding incorrect JSON in the key-value store: " << key; - return false; - } - } - else - { - return false; - } - } - static const char* const KEY_ACTIVE_USERS = "active-users"; static const char* const KEY_PROJECT_NAME = "project-name"; @@ -873,7 +690,7 @@ const std::string key = id_.GetSettingsKey(user); Json::Value layers; - if (LookupKeyValueStore(layers, key)) + if (ViewerToolbox::LookupKeyValueStore(layers, key)) { std::unique_ptr<UserAnnotationsSettings> item(new UserAnnotationsSettings(layers)); @@ -902,7 +719,7 @@ Json::Value info; - if (LookupKeyValueStore(info, key)) + if (ViewerToolbox::LookupKeyValueStore(info, key)) { persistentInfo_.reset(new PersistentInfo(info)); @@ -916,7 +733,7 @@ { persistentInfo_.reset(new PersistentInfo); persistentInfo_->Serialize(info); - SetKeyValueStore(key, info); + ViewerToolbox::SetKeyValueStore(key, info); } } @@ -1124,7 +941,7 @@ void Commit() { - SetKeyValueStore(that_.id_.GetSettingsKey(userId_), *userSettings_); + ISerializable::SetKeyValueStore(that_.id_.GetSettingsKey(userId_), *userSettings_); } public: @@ -1137,7 +954,7 @@ 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.persistentInfo_); + ISerializable::SetKeyValueStore(that.id_.GetInfoKey(), *that.persistentInfo_); } Content::iterator found = that.content_.find(userId_); @@ -1483,7 +1300,7 @@ content_ = Json::arrayValue; std::string compressed; - if (LookupKeyValueStore(compressed, key_)) + if (ViewerToolbox::LookupKeyValueStore(compressed, key_)) { std::string uncompressed; Orthanc::GzipCompressor compressor; @@ -1534,7 +1351,7 @@ Orthanc::GzipCompressor compressor; Orthanc::IBufferCompressor::Compress(compressed, compressor, serialized); - SetKeyValueStore(key_, compressed); + ViewerToolbox::SetKeyValueStore(key_, compressed); } public:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ViewerPlugin/Annotations/AnnotationsWorkspaceId.cpp Tue Sep 01 21:24:14 2026 +0200 @@ -0,0 +1,112 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2023 Osimis S.A., Belgium + * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium + * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "../../Framework/PrecompiledHeadersWSI.h" +#include "AnnotationsWorkspaceId.h" + +#include <OrthancException.h> +#include <Toolbox.h> + +#include <boost/lexical_cast.hpp> + + +namespace OrthancWSI +{ + std::string AnnotationsWorkspaceId::GetKeyPrefix() const + { + switch (level_) + { + case Orthanc::ResourceType_Series: + return projectId_ + "|series|" + resourceId_; + + case Orthanc::ResourceType_Instance: + return projectId_ + "|instance|" + boost::lexical_cast<std::string>(frameNumber_) + "|" + resourceId_; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); + } + } + + + AnnotationsWorkspaceId::AnnotationsWorkspaceId(const std::string& projectId, + Orthanc::ResourceType level, + const std::string& resourceId, + unsigned int frameNumber) : + projectId_(projectId), + level_(level), + resourceId_(resourceId), + frameNumber_(frameNumber) + { + if (level_ != Orthanc::ResourceType_Series && + level_ != Orthanc::ResourceType_Instance) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + + // The pipe symbol is disallowed as it is used to build the key, cf. GetKey() + if (!Orthanc::Toolbox::IsAsciiString(projectId_) || + projectId_.find('|') != std::string::npos) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, + "Project name containing non-ASCII characters or the pipe symbol: " + projectId_); + } + + if (!Orthanc::Toolbox::IsAsciiString(resourceId_) || + resourceId_.find('|') != std::string::npos) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, + "Resource ID containing non-ASCII characters or the pipe symbol: " + resourceId_); + } + } + + + unsigned int AnnotationsWorkspaceId::GetFrameNumber() const + { + if (level_ == Orthanc::ResourceType_Instance) + { + return frameNumber_; + } + else + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + } + + + std::string AnnotationsWorkspaceId::GetInfoKey() const + { + return GetKeyPrefix() + "|info"; + } + + + std::string AnnotationsWorkspaceId::GetSettingsKey(const UserId& user) const + { + return GetKeyPrefix() + "|settings|" + user.GetKey(); + } + + + std::string AnnotationsWorkspaceId::GetFeaturesKey(const UserId& user) const + { + return GetKeyPrefix() + "|features|" + user.GetKey(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ViewerPlugin/Annotations/AnnotationsWorkspaceId.h Tue Sep 01 21:24:14 2026 +0200 @@ -0,0 +1,72 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2023 Osimis S.A., Belgium + * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium + * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "UserId.h" + +#include <Enumerations.h> + + +namespace OrthancWSI +{ + class AnnotationsWorkspaceId + { + private: + std::string projectId_; + Orthanc::ResourceType level_; + std::string resourceId_; + unsigned int frameNumber_; + + std::string GetKeyPrefix() const; + + public: + AnnotationsWorkspaceId(const std::string& projectId, + Orthanc::ResourceType level, + const std::string& resourceId, + unsigned int frameNumber); + + const std::string& GetProjectId() const + { + return projectId_; + } + + Orthanc::ResourceType GetLevel() const + { + return level_; + } + + const std::string& GetResourceId() const + { + return resourceId_; + } + + unsigned int GetFrameNumber() const; + + std::string GetInfoKey() const; + + std::string GetSettingsKey(const UserId& user) const; + + std::string GetFeaturesKey(const UserId& user) const; + }; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ViewerPlugin/Annotations/ISerializable.cpp Tue Sep 01 21:24:14 2026 +0200 @@ -0,0 +1,50 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2023 Osimis S.A., Belgium + * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium + * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "../../Framework/PrecompiledHeadersWSI.h" +#include "ISerializable.h" + +#include "../ViewerToolbox.h" + +#include <Toolbox.h> + + +namespace OrthancWSI +{ + void ISerializable::Serialize(std::string& serialized, + const ISerializable& obj) + { + Json::Value value; + obj.Serialize(value); + Orthanc::Toolbox::WriteFastJson(serialized, value); + } + + + void ISerializable::SetKeyValueStore(const std::string& key, + const ISerializable& obj) + { + std::string s; + ISerializable::Serialize(s, obj); + ViewerToolbox::SetKeyValueStore(key, s); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ViewerPlugin/Annotations/ISerializable.h Tue Sep 01 21:24:14 2026 +0200 @@ -0,0 +1,47 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2023 Osimis S.A., Belgium + * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium + * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include <boost/noncopyable.hpp> +#include <json/value.h> + + +namespace OrthancWSI +{ + class ISerializable : public boost::noncopyable + { + public: + virtual ~ISerializable() + { + } + + virtual void Serialize(Json::Value& serialized) const = 0; + + static void Serialize(std::string& serialized, + const ISerializable& obj); + + static void SetKeyValueStore(const std::string& key, + const ISerializable& obj); + }; +}
--- a/ViewerPlugin/CMakeLists.txt Tue Sep 01 21:05:06 2026 +0200 +++ b/ViewerPlugin/CMakeLists.txt Tue Sep 01 21:24:14 2026 +0200 @@ -186,7 +186,9 @@ set(ORTHANC_WSI_SOURCES Annotations/AnnotationsRestApi.cpp + Annotations/AnnotationsWorkspaceId.cpp Annotations/IAuthenticatedUser.cpp + Annotations/ISerializable.cpp Annotations/UserId.cpp DicomPyramidCache.cpp IIIF.cpp
--- a/ViewerPlugin/ViewerToolbox.cpp Tue Sep 01 21:05:06 2026 +0200 +++ b/ViewerPlugin/ViewerToolbox.cpp Tue Sep 01 21:24:14 2026 +0200 @@ -24,11 +24,15 @@ #include "../Framework/PrecompiledHeadersWSI.h" #include "ViewerToolbox.h" +#include <Logging.h> #include <Toolbox.h> #include "../Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h" +static const char* const KEY_VALUE_STORE = "wsi"; + + namespace OrthancWSI { namespace ViewerToolbox @@ -47,5 +51,62 @@ Json::Value answer = Json::objectValue; AnswerJson(output, answer); } + + + void SetKeyValueStore(const std::string& key, + const std::string& value) + { +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 8) + OrthancPlugins::KeyValueStore store(KEY_VALUE_STORE); + store.Store(key, value); +#else + LOG(WARNING) << "Your Orthanc SDK is too old to save annotations"; +#endif + } + + + void SetKeyValueStore(const std::string& key, + const Json::Value& value) + { + std::string s; + Orthanc::Toolbox::WriteFastJson(s, value); + SetKeyValueStore(key, s); + } + + + bool LookupKeyValueStore(std::string& value, + const std::string& key) + { +#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 8) + OrthancPlugins::KeyValueStore store(KEY_VALUE_STORE); + return store.GetValue(value, key); +#else + LOG(WARNING) << "Your Orthanc SDK is too old to load annotations"; + return false; +#endif + } + + + bool LookupKeyValueStore(Json::Value& value, + const std::string& key) + { + std::string s; + if (LookupKeyValueStore(s, key)) + { + if (Orthanc::Toolbox::ReadJson(value, s)) + { + return true; + } + else + { + LOG(WARNING) << "Discarding incorrect JSON in the key-value store: " << key; + return false; + } + } + else + { + return false; + } + } } }
--- a/ViewerPlugin/ViewerToolbox.h Tue Sep 01 21:05:06 2026 +0200 +++ b/ViewerPlugin/ViewerToolbox.h Tue Sep 01 21:24:14 2026 +0200 @@ -35,5 +35,17 @@ const Json::Value& value); void AnswerEmpty(OrthancPluginRestOutput* output); + + void SetKeyValueStore(const std::string& key, + const std::string& value); + + void SetKeyValueStore(const std::string& key, + const Json::Value& value); + + bool LookupKeyValueStore(std::string& value, + const std::string& key); + + bool LookupKeyValueStore(Json::Value& value, + const std::string& key); } }
