Mercurial > hg > orthanc
view OrthancServer/Plugins/Samples/AdoptDicomInstance/Plugin.cpp @ 6294:470e2a8b42e0 default
merge
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 02 Sep 2025 18:00:26 +0200 |
parents | 2944662388fd |
children | 88aa865b6a54 |
line wrap: on
line source
/** * 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-2025 Orthanc Team SRL, Belgium * Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ #include "../../../../OrthancFramework/Sources/Logging.h" #include "../../../../OrthancFramework/Sources/SystemToolbox.h" #include "../../../../OrthancFramework/Sources/Toolbox.h" #include "../Common/OrthancPluginCppWrapper.h" #include <boost/filesystem.hpp> static boost::filesystem::path storageDirectory_; static std::string GetStorageDirectoryPath(const char* uuid) { if (uuid == NULL) { throw Orthanc::OrthancException(Orthanc::ErrorCode_NullPointer); } else { return (storageDirectory_ / std::string(uuid)).string(); } } #define CATCH_EXCEPTIONS(errorValue) \ catch (Orthanc::OrthancException& e) \ { \ LOG(ERROR) << "Orthanc exception: " << e.What(); \ return errorValue; \ } \ catch (std::runtime_error& e) \ { \ LOG(ERROR) << "Native exception: " << e.what(); \ return errorValue; \ } \ catch (...) \ { \ return errorValue; \ } OrthancPluginErrorCode StorageCreate(OrthancPluginMemoryBuffer* customData, const char* uuid, const void* content, uint64_t size, OrthancPluginContentType type, OrthancPluginCompressionType compressionType, const OrthancPluginDicomInstance* dicomInstance) { try { Json::Value info; info["IsAdopted"] = false; OrthancPlugins::MemoryBuffer buffer; buffer.Assign(info.toStyledString()); *customData = buffer.Release(); const std::string path = GetStorageDirectoryPath(uuid); LOG(WARNING) << "Creating non-adopted file: " << path; Orthanc::SystemToolbox::WriteFile(content, size, path); return OrthancPluginErrorCode_Success; } CATCH_EXCEPTIONS(OrthancPluginErrorCode_Plugin); } OrthancPluginErrorCode StorageReadRange(OrthancPluginMemoryBuffer64* target, const char* uuid, OrthancPluginContentType type, uint64_t rangeStart, const void* customData, uint32_t customDataSize) { try { Json::Value info; if (!Orthanc::Toolbox::ReadJson(info, customData, customDataSize)) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } std::string path; if (info["IsAdopted"].asBool()) { path = info["AdoptedPath"].asString(); LOG(WARNING) << "Reading adopted file from: " << path; } else { path = GetStorageDirectoryPath(uuid); LOG(WARNING) << "Reading non-adopted file from: " << path; } std::string range; Orthanc::SystemToolbox::ReadFileRange(range, path, rangeStart, rangeStart + target->size, true); assert(range.size() == target->size); if (target->size != 0) { memcpy(target->data, range.c_str(), target->size); } return OrthancPluginErrorCode_Success; } CATCH_EXCEPTIONS(OrthancPluginErrorCode_Plugin); } OrthancPluginErrorCode StorageRemove(const char* uuid, OrthancPluginContentType type, const void* customData, uint32_t customDataSize) { try { Json::Value info; if (!Orthanc::Toolbox::ReadJson(info, customData, customDataSize)) { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat); } // Only remove non-adopted files (i.e., whose for which Orthanc has the ownership) if (info["IsAdopted"].asBool()) { LOG(WARNING) << "Don't removing adopted file: " << info["AdoptedPath"].asString(); } else { const std::string path = GetStorageDirectoryPath(uuid); LOG(WARNING) << "Removing non-adopted file from: " << path; Orthanc::SystemToolbox::RemoveFile(path); } return OrthancPluginErrorCode_Success; } CATCH_EXCEPTIONS(OrthancPluginErrorCode_Plugin); } OrthancPluginErrorCode Adopt(OrthancPluginRestOutput* output, const char* url, const OrthancPluginHttpRequest* request) { try { if (request->method != OrthancPluginHttpMethod_Post) { OrthancPluginSendMethodNotAllowed(OrthancPlugins::GetGlobalContext(), output, "POST"); return OrthancPluginErrorCode_Success; } else { const std::string path(reinterpret_cast<const char*>(request->body), request->bodySize); LOG(WARNING) << "Adopting DICOM instance from path: " << path; std::string dicom; Orthanc::SystemToolbox::ReadFile(dicom, path); Json::Value info; info["IsAdopted"] = true; info["AdoptedPath"] = path; const std::string customData = info.toStyledString(); OrthancPluginStoreStatus status; OrthancPlugins::MemoryBuffer instanceId, attachmentUuid; OrthancPluginErrorCode code = OrthancPluginAdoptDicomInstance( OrthancPlugins::GetGlobalContext(), *instanceId, *attachmentUuid, &status, dicom.empty() ? NULL : dicom.c_str(), dicom.size(), customData.empty() ? NULL : customData.c_str(), customData.size()); if (code == OrthancPluginErrorCode_Success) { const std::string answer = "OK\n"; OrthancPluginAnswerBuffer(OrthancPlugins::GetGlobalContext(), output, answer.c_str(), answer.size(), "text/plain"); return OrthancPluginErrorCode_Success; } else { return code; } } } CATCH_EXCEPTIONS(OrthancPluginErrorCode_Plugin); } extern "C" { ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) { OrthancPlugins::SetGlobalContext(context, PLUGIN_NAME); Orthanc::Logging::InitializePluginContext(context, PLUGIN_NAME); /* Check the version of the Orthanc core */ if (OrthancPluginCheckVersion(context) == 0) { char info[1024]; sprintf(info, "Your version of Orthanc (%s) must be above %d.%d.%d to run this plugin", context->orthancVersion, ORTHANC_PLUGINS_MINIMAL_MAJOR_NUMBER, ORTHANC_PLUGINS_MINIMAL_MINOR_NUMBER, ORTHANC_PLUGINS_MINIMAL_REVISION_NUMBER); OrthancPluginLogError(context, info); return -1; } OrthancPluginSetDescription2(context, PLUGIN_NAME, "Sample plugin illustrating the adoption of DICOM instances."); OrthancPluginRegisterStorageArea3(context, StorageCreate, StorageReadRange, StorageRemove); try { OrthancPlugins::OrthancConfiguration config; storageDirectory_ = config.GetStringValue("StorageDirectory", "OrthancStorage"); Orthanc::SystemToolbox::MakeDirectory(storageDirectory_.string()); OrthancPluginRegisterRestCallback(context, "/adopt", Adopt); } CATCH_EXCEPTIONS(-1) return 0; } ORTHANC_PLUGINS_API void OrthancPluginFinalize() { } ORTHANC_PLUGINS_API const char* OrthancPluginGetName() { return PLUGIN_NAME; } ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() { return PLUGIN_VERSION; } }