[Решено] Cложносочиненный скрипт (Выгрузки исследований с Orthanc)

На самом деле это единственный раздел про unix на этом форуме

Модератор: /dev/random

JTMarsh
Сообщения: 143
ОС: Debian

[Решено] Cложносочиненный скрипт

Сообщение JTMarsh »

Доброго времени суток!

Исходные данные.
1. Есть DICOM-сервер Orthanc на который отправляют исследования.
2. Исследования надо хранить еще в месте Б.
3. В месте Б есть NAS толстый, на нем настроена NFS шара
4. В месте Б поднял ВМ куда подключил эту NFS шару.

Задача: запихнуть сложносочиненный скрипт в крон, который с утра начнет выгружать исследования на шару за предыдущий день, расскладываясь по каталогам ГОД-МЕСЯЦ-ЧИСЛО.
Просто выгрузить не проблема: есть требование, что бы архивированные исследования назывались ИД - ФИО

У Orthanc есть апи которое отдается с помощью curl
Cама задача разбивается на 3 этапа:
1. Получаем список исследований за день

Код: Выделить всё

curl -X POST http://IP-SERVER:8042/tools/find -d '{"Level":"Study","Expand":false,"Query":{"StudyDate":"20211215-20211215"}}' > /home/dicom/lists/20211215.list
файлик 20211215.list (оставил 3 исследования, бо там манускрипт длинный)
Spoiler
[
"03f1d5dc-0f5d9538-9ae87d90-ce05730c-b1fb75d9",
"f44a7807-953aad54-4cc7228f-079182ed-a57d0a1f",
"f5009020-4969c539-2098a2f8-7c5cfb3a-55d84da8"
]
2. Получить значения ИД и ФИО можно с помощью:

Код: Выделить всё

curl http://IP-SERVER:8042/studies/f5009020-4969c539-2098a2f8-7c5cfb3a-55d84da8
На выходе получаем слудующее (я стрелками указал что надо вытащить):
Spoiler

Код: Выделить всё

curl http://IP-SERVER:8042/studies/f5009020-4969c539-2098a2f8-7c5cfb3a-55d84da8
{
   "ID" : "f5009020-4969c539-2098a2f8-7c5cfb3a-55d84da8",
   "IsStable" : true,
   "LastUpdate" : "20211215T210045",
   "MainDicomTags" : {
      "AccessionNumber" : "",
      "InstitutionName" : "XXXXXXXXXX",
      "ReferringPhysicianName" : "",
      "StudyDate" : "20211215",
      "StudyDescription" : "Brain Sequens(Adult)",
      "StudyID" : "cbf75611-9d86-43",
      "StudyInstanceUID" : "1.3.12.2.1107.5.1.7.123080.30000021121302042855600000131",
      "StudyTime" : "224051.897821"
   },
   "ParentPatient" : "bb865f3f-f391dbd6-d6efc35d-ad5c589b-2ed348ec",
   "PatientMainDicomTags" : {
      "PatientBirthDate" : "19880416",
--->>      "PatientID" : "0003540",
--->>      "PatientName" : "FAMILIYA I.O.",
      "PatientSex" : "M"
   },
   "Series" : [
      "b4f835f9-adbd89c7-30786772-501a2bcf-a3b156af",
      "41eda6db-7da77bb1-38120a10-1c032749-f58f2f19",
      "2d9d3406-ad3934a4-cc03ee3c-a47b2af3-441a9812",
      "1d093b22-ee1c911a-fef45856-0e714bc2-1178deb4",
      "a67df51a-f11e2b3d-c029d6d1-af11039e-aaf9dcf2",
      "9cc0ab2a-f66670b3-334d936e-2f0fe811-d6491dda",
      "bd03d0d3-b0e8ea86-03f706e3-7fed7200-cccdcd8e",
      "edad3ac1-15c37536-6c680b46-a9219b6b-9c5aa712",
      "4b3b67da-b62b2d12-fdac386c-89925169-c588ba08",
      "9084284b-46737e81-cec45f02-560b272d-2d4e5cd0",
      "364197dd-55d25084-5bd47538-5fa9ac14-670671cc",
      "356adb83-bf09ce1c-4fb8cbdd-e8f0adc2-7f499eec"
   ],
   "Type" : "Study"
}
3. Ну и само исследование архивируется:

Код: Выделить всё

curl http://SERVER-IP:8042/studies/f5009020-4969c539-2098a2f8-7c5cfb3a-55d84da8/archive > файлик.zip
Сижу вот теперь голову ломаю как реализовать.
Я в группе дисскусии задал вопрос, как это правильнее сделать, но сгородить конструкцию надо уже..

Заранее спасибо за идеи компоновки реализации.
Последний раз редактировалось JTMarsh 17.12.2021 13:14, всего редактировалось 1 раз.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 19302
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Cложносочиненный скрипт

Сообщение Bizdelnick »

На шелле хотите делать? На любом ЯП общего назначения, имеющем библиотеки HTTP-клиента и парсера JSON, было бы проще.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

JTMarsh
Сообщения: 143
ОС: Debian

Re: Cложносочиненный скрипт

Сообщение JTMarsh »

Заковыка номер 1:
Не передается вчерашняя дата в многокавычье

#!/bin/bash
#storage-studies.sh
a=`date "+%Y%m%d" -d "1 day ago"`
echo $a

curl -X POST http://---:8042/tools/find -d '{"Level":"Study","Expand":false,"Query":{"StudyDate":"$a"}}'
Спасибо сказали:

JTMarsh
Сообщения: 143
ОС: Debian

Re: Cложносочиненный скрипт

Сообщение JTMarsh »

Bizdelnick писал:
16.12.2021 16:58
На шелле хотите делать? На любом ЯП общего назначения, имеющем библиотеки HTTP-клиента и парсера JSON, было бы проще.
Да на баше, бо тут хоть что-то могу сделать, а там же вообще ни в зуб ногой.
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 19302
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Cложносочиненный скрипт

Сообщение Bizdelnick »

JTMarsh писал:
16.12.2021 17:10
там же вообще ни в зуб ногой
Ну тогда jq Вам в руки.
Что-то типа

Код: Выделить всё

set -e
set -o pipefail

for id in $( jq --raw-output '.[]' "$LIST" ); do
    name=$( curl --fail --no-progress-meter "${BASEURL}/studies/${id}" | jq --raw-output '.PatientMainDicomTags.PatientID + "-" + .PatientMainDicomTags.PatientName' )
    curl --fail --output "${name}.zip" "${BASEURL}/studies/${id}/archive"
done
Для Вашего примера

Код: Выделить всё

LIST=/home/dicom/lists/20211215.list
BASEURL=http://IP-SERVER:8042
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

JTMarsh
Сообщения: 143
ОС: Debian

Re: Cложносочиненный скрипт

Сообщение JTMarsh »

Bizdelnick писал:
16.12.2021 17:37
Ну тогда jq Вам в руки.
Спасибо.

Отписались в группе. Оказывается есть скрипт на питоне. Видимо я уже не первый такой.

https://hg.orthanc-server.com/orthanc/file/tip/OrthancServer/Resources/Samples/Python/ArchiveStudiesInTimeRange.py

Буду его наверное крутить.
Если шой-то не будет получаться спрошу здесь.
Добавлено (19:04):
ArchiveStudiesInTimeRange.py
Spoiler
#!/usr/bin/python
# -*- coding: utf-8 -*-

# Orthanc - A Lightweight, RESTful DICOM Store
# Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
# Department, University Hospital of Liege, Belgium
# Copyright (C) 2017-2021 Osimis S.A., Belgium
# Copyright (C) 2021-2021 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/>.


import os
import os.path
import sys
import RestToolbox

def PrintHelp():
print('Download ZIP archives for all the studies generated '
'during a given time range (according to the StudyDate tag)\n')
print('Usage: %s <URL> <StartDate> <EndDate> <TargetFolder>\n' % sys.argv[0])
print('Example: %s http://127.0.0.1:8042/ 20150101 20151231 /tmp/\n' % sys.argv[0])
exit(-1)


def CheckIsDate(date):
if len(date) != 8 or not date.isdigit():
print ('"%s" is not a valid date!\n' % date)
exit(-1)

if len(sys.argv) != 5:
PrintHelp()


URL = sys.argv[1]
START = sys.argv[2]
END = sys.argv[3]
TARGET = sys.argv[4]

CheckIsDate(START)
CheckIsDate(END)

def GetTag(tags, key):
if key in tags:
return tags[key]
else:
return 'No%s' % key

# Loop over the studies
for studyId in RestToolbox.DoGet('%s/studies' % URL):
# Retrieve the DICOM tags of the current study
study = RestToolbox.DoGet('%s/studies/%s' % (URL, studyId))['MainDicomTags']

# Retrieve the DICOM tags of the parent patient of this study


# Case 1: Baseline version
patient = RestToolbox.DoGet('%s/studies/%s/patient' % (URL, studyId))['MainDicomTags']

# Case 2: Tweaked version that can be used if several patients
# share the same "Patient ID", but have different "Patient Name"
# (which is invalid according to the DICOM standard).
# https://groups.google.com/d/msg/orthanc-users/58AxIkxFbZs/N6Knub8MAgAJ
# patient = RestToolbox.DoGet('%s/studies/%s' % (URL, studyId)) ['PatientMainDicomTags']

# Check that the StudyDate tag lies within the given range
studyDate = study['StudyDate'][:8]
if studyDate >= START and studyDate <= END:
# Create a filename
filename = '%s - %s %s - %s.zip' % (GetTag(study, 'StudyDate'),
GetTag(patient, 'PatientID'),
GetTag(patient, 'PatientName'),
GetTag(study, 'StudyDescription'))

# Remove any non-ASCII character in the filename
filename = filename.encode('ascii', errors = 'replace').translate(None, r"'\/:*?\"<>|!=").strip()

# Download the ZIP archive of the study
print('Downloading %s' % filename)
zipContent = RestToolbox.DoGet('%s/studies/%s/archive' % (URL, studyId))

# Write the ZIP archive at the proper location
with open(os.path.join(TARGET, filename), 'wb') as f:
f.write(zipContent)
При выполнении
:~$ /usr/bin/python3 /home/dicom/ArchiveStudiesInTimeRange.py http://---:8042/ 20211214 20211215 /mnt/archive/
выдает
Traceback (most recent call last):
File "/home/dicom/ArchiveStudiesInTimeRange.py", line 87, in <module>
filename = filename.encode('ascii', errors = 'replace').translate(None, r"'\/:*?\"<>|!=").strip()
TypeError: a bytes-like object is required, not 'str'

Шо ему не так? :cray:
Спасибо сказали:

Аватара пользователя
Bizdelnick
Модератор
Сообщения: 19302
Статус: nulla salus bello
ОС: Debian GNU/Linux

Re: Cложносочиненный скрипт

Сообщение Bizdelnick »

JTMarsh писал:
16.12.2021 18:24
Шо ему не так?
В питоне не силён, но, видимо, скрипт на python3 не портирован.
Пишите правильно:
в консоли
вку́пе (с чем-либо)
в общем
вообще
в течение (часа)
новичок
нюанс
по умолчанию
приемлемо
проблема
пробовать
трафик
Спасибо сказали:

JTMarsh
Сообщения: 143
ОС: Debian

Re: Cложносочиненный скрипт

Сообщение JTMarsh »

Bizdelnick писал:
16.12.2021 19:24
В питоне не силён, но, видимо, скрипт на python3 не портирован.
Спасибо огромное за наводку. Поставил питон 2 - все работает.
Спасибо сказали:

JTMarsh
Сообщения: 143
ОС: Debian

Re: Cложносочиненный скрипт

Сообщение JTMarsh »

По факту в Debian 11 установить python2, pip2
установить модуль httplib2

Код: Выделить всё

#!/bin/bash

a=`date "+%Y%m%d" -d"1 day ago"`

mkdir /%КУДА%/`date "+%Y-%m-%d" -d"1 day ago"`

/usr/bin/python2 /var/scripts/ArchiveStudiesInTimeRange.py http://%ОТКУДА%:8042/ $a $a /%КУДА%/`date "+%Y-%m-%d" -d"1 day ago"`/
Спасибо сказали: