208 lines
5.6 KiB
C++
208 lines
5.6 KiB
C++
/**
|
|
* 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 "PluginToolbox.h"
|
|
|
|
#include "../../../../OrthancFramework/Sources/OrthancException.h"
|
|
#include "../../../../OrthancFramework/Sources/SerializationToolbox.h"
|
|
#include "../../../../OrthancFramework/Sources/Toolbox.h"
|
|
|
|
#include "../Common/OrthancPluginCppWrapper.h"
|
|
|
|
|
|
namespace PluginToolbox
|
|
{
|
|
bool IsValidLabel(const std::string& label)
|
|
{
|
|
if (label.empty())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (label.size() > 64)
|
|
{
|
|
// This limitation is for MySQL, which cannot use a TEXT
|
|
// column of undefined length as a primary key
|
|
return false;
|
|
}
|
|
|
|
for (size_t i = 0; i < label.size(); i++)
|
|
{
|
|
if (!(label[i] == '_' ||
|
|
label[i] == '-' ||
|
|
(label[i] >= 'a' && label[i] <= 'z') ||
|
|
(label[i] >= 'A' && label[i] <= 'Z') ||
|
|
(label[i] >= '0' && label[i] <= '9')))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
Orthanc::ResourceType ParseQueryRetrieveLevel(const std::string& level)
|
|
{
|
|
if (level == "PATIENT")
|
|
{
|
|
return Orthanc::ResourceType_Patient;
|
|
}
|
|
else if (level == "STUDY")
|
|
{
|
|
return Orthanc::ResourceType_Study;
|
|
}
|
|
else if (level == "SERIES")
|
|
{
|
|
return Orthanc::ResourceType_Series;
|
|
}
|
|
else if (level == "INSTANCE")
|
|
{
|
|
return Orthanc::ResourceType_Instance;
|
|
}
|
|
else
|
|
{
|
|
throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol, "Bad value for QueryRetrieveLevel in DICOM C-FIND: " + level);
|
|
}
|
|
}
|
|
|
|
|
|
bool IsSameAETitle(bool isStrict,
|
|
const std::string& aet1,
|
|
const std::string& aet2)
|
|
{
|
|
if (isStrict)
|
|
{
|
|
// Case-sensitive matching
|
|
return aet1 == aet2;
|
|
}
|
|
else
|
|
{
|
|
// Case-insensitive matching (default)
|
|
std::string tmp1, tmp2;
|
|
Orthanc::Toolbox::ToLowerCase(tmp1, aet1);
|
|
Orthanc::Toolbox::ToLowerCase(tmp2, aet2);
|
|
return tmp1 == tmp2;
|
|
}
|
|
}
|
|
|
|
|
|
bool LookupAETitle(std::string& name,
|
|
Orthanc::RemoteModalityParameters& parameters,
|
|
bool isStrict,
|
|
const std::string& aet)
|
|
{
|
|
Json::Value modalities;
|
|
if (!OrthancPlugins::RestApiGet(modalities, "/modalities?expand", false))
|
|
{
|
|
throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, "Unable to obtain the list of the remote modalities");
|
|
}
|
|
|
|
std::vector<std::string> names = modalities.getMemberNames();
|
|
for (size_t i = 0; i < names.size(); i++)
|
|
{
|
|
parameters = Orthanc::RemoteModalityParameters(modalities[names[i]]);
|
|
|
|
if (IsSameAETitle(isStrict, parameters.GetApplicationEntityTitle(), aet))
|
|
{
|
|
name = names[i];
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
void ParseLabels(std::set<std::string>& targetLabels,
|
|
LabelsConstraint& targetConstraint,
|
|
const Json::Value& serverConfig)
|
|
{
|
|
Orthanc::SerializationToolbox::ReadSetOfStrings(targetLabels, serverConfig, KEY_LABELS);
|
|
|
|
for (std::set<std::string>::const_iterator it = targetLabels.begin(); it != targetLabels.end(); ++it)
|
|
{
|
|
if (!PluginToolbox::IsValidLabel(*it))
|
|
{
|
|
throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, "Invalid label: " + *it);
|
|
}
|
|
}
|
|
|
|
std::string s = Orthanc::SerializationToolbox::ReadString(serverConfig, KEY_LABELS_CONSTRAINT, KEY_ALL);
|
|
targetConstraint = PluginToolbox::StringToLabelsConstraint(s);
|
|
}
|
|
|
|
|
|
void AddLabelsToFindRequest(Json::Value& request,
|
|
const std::set<std::string>& labels,
|
|
LabelsConstraint constraint)
|
|
{
|
|
Json::Value items = Json::arrayValue;
|
|
for (std::set<std::string>::const_iterator it = labels.begin(); it != labels.end(); ++it)
|
|
{
|
|
items.append(*it);
|
|
}
|
|
|
|
request[KEY_LABELS] = items;
|
|
|
|
switch (constraint)
|
|
{
|
|
case LabelsConstraint_All:
|
|
request[KEY_LABELS_CONSTRAINT] = KEY_ALL;
|
|
break;
|
|
|
|
case LabelsConstraint_Any:
|
|
request[KEY_LABELS_CONSTRAINT] = KEY_ANY;
|
|
break;
|
|
|
|
case LabelsConstraint_None:
|
|
request[KEY_LABELS_CONSTRAINT] = KEY_NONE;
|
|
break;
|
|
|
|
default:
|
|
throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
|
|
}
|
|
}
|
|
|
|
|
|
LabelsConstraint StringToLabelsConstraint(const std::string& s)
|
|
{
|
|
if (s == KEY_ALL)
|
|
{
|
|
return LabelsConstraint_All;
|
|
}
|
|
else if (s == KEY_ANY)
|
|
{
|
|
return LabelsConstraint_Any;
|
|
}
|
|
else if (s == KEY_NONE)
|
|
{
|
|
return LabelsConstraint_None;
|
|
}
|
|
else
|
|
{
|
|
throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange, "Bad value for constraint of labels: " + s);
|
|
}
|
|
}
|
|
}
|