OpenREM 1.0.0b2__py3-none-any.whl → 1.0.0b3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openrem/locale/de/LC_MESSAGES/django.po +1060 -1059
- openrem/locale/django.pot +973 -972
- openrem/locale/es_MX/LC_MESSAGES/django.po +1049 -1048
- openrem/locale/it/LC_MESSAGES/django.po +1044 -1043
- openrem/locale/lt/LC_MESSAGES/django.po +989 -988
- openrem/locale/nb_NO/LC_MESSAGES/django.po +985 -984
- openrem/locale/pt_BR/LC_MESSAGES/django.po +1003 -1002
- openrem/manage.py +10 -10
- openrem/openremproject/__init__.py +1 -1
- openrem/openremproject/local_settings.py.linux +128 -128
- openrem/openremproject/local_settings.py.windows +144 -144
- openrem/openremproject/local_settings.py.windows-sqlite3 +129 -129
- openrem/openremproject/settings.py +278 -278
- openrem/openremproject/urls.py +32 -32
- openrem/openremproject/wsgi.py.example +28 -28
- openrem/remapp/__init__.py +2 -2
- openrem/remapp/admin.py +31 -31
- openrem/remapp/exports/ct_export.py +780 -753
- openrem/remapp/exports/dx_export.py +817 -805
- openrem/remapp/exports/export_common.py +931 -951
- openrem/remapp/exports/export_common_pandas.py +2422 -0
- openrem/remapp/exports/exportviews.py +815 -860
- openrem/remapp/exports/mg_csv_nhsbsp.py +292 -292
- openrem/remapp/exports/mg_export.py +673 -510
- openrem/remapp/exports/nm_export.py +796 -575
- openrem/remapp/exports/rf_export.py +1418 -1431
- openrem/remapp/extractors/ct_philips.py +424 -414
- openrem/remapp/extractors/ct_toshiba.py +2116 -2108
- openrem/remapp/extractors/dx.py +1033 -952
- openrem/remapp/extractors/extract_common.py +817 -817
- openrem/remapp/extractors/import_views.py +426 -426
- openrem/remapp/extractors/mam.py +685 -672
- openrem/remapp/extractors/nm_image.py +439 -431
- openrem/remapp/extractors/ptsizecsv2db.py +368 -368
- openrem/remapp/extractors/rdsr.py +667 -654
- openrem/remapp/extractors/rdsr_methods.py +1771 -1768
- openrem/remapp/extractors/rrdsr_methods.py +630 -622
- openrem/remapp/fixtures/openskin_safelist.json +11 -11
- openrem/remapp/forms.py +2286 -2277
- openrem/remapp/interface/chart_functions.py +2412 -2393
- openrem/remapp/interface/mod_filters.py +1241 -1243
- openrem/remapp/migrations/0001_initial.py.1-0-upgrade +1043 -1043
- openrem/remapp/models.py +3418 -3407
- openrem/remapp/netdicom/dicomviews.py +681 -683
- openrem/remapp/netdicom/qrscu.py +2646 -2646
- openrem/remapp/netdicom/tools.py +134 -134
- openrem/remapp/static/css/bootstrap-theme.css +587 -587
- openrem/remapp/static/css/bootstrap-theme.min.css +4 -4
- openrem/remapp/static/css/bootstrap.css +6800 -6800
- openrem/remapp/static/css/bootstrap.min.css +4 -4
- openrem/remapp/static/css/datepicker3.css +790 -790
- openrem/remapp/static/css/jquery.qtip.min.css +2 -2
- openrem/remapp/static/css/openrem-extra.css +442 -442
- openrem/remapp/static/css/openrem.css +96 -96
- openrem/remapp/static/css/registration.css +34 -34
- openrem/remapp/static/fonts/glyphicons-halflings-regular.svg +287 -287
- openrem/remapp/static/js/bootstrap-datepicker.js +1671 -1671
- openrem/remapp/static/js/bootstrap.js +2363 -2363
- openrem/remapp/static/js/bootstrap.min.js +6 -6
- openrem/remapp/static/js/charts/chartCommonFunctions.js +75 -75
- openrem/remapp/static/js/charts/chartFullScreen.js +41 -41
- openrem/remapp/static/js/charts/ctChartAjax.js +331 -331
- openrem/remapp/static/js/charts/dxChartAjax.js +290 -290
- openrem/remapp/static/js/charts/mgChartAjax.js +144 -144
- openrem/remapp/static/js/charts/nmChartAjax.js +64 -64
- openrem/remapp/static/js/charts/plotly-2.35.2.min.js +8 -0
- openrem/remapp/static/js/charts/rfChartAjax.js +128 -128
- openrem/remapp/static/js/chroma.min.js +32 -32
- openrem/remapp/static/js/datepicker.js +5 -5
- openrem/remapp/static/js/dicom.js +115 -115
- openrem/remapp/static/js/django_reverse/reverse.js +13 -13
- openrem/remapp/static/js/formatDate.js +7 -7
- openrem/remapp/static/js/html5shiv.min.js +8 -8
- openrem/remapp/static/js/jquery-1.11.0.min.js +4 -4
- openrem/remapp/static/js/npm.js +12 -12
- openrem/remapp/static/js/respond.min.js +4 -4
- openrem/remapp/static/js/skin-dose-maps/jquery.qtip.min.js +4 -4
- openrem/remapp/static/js/skin-dose-maps/rfSkinDoseMap3dHUDObject.js +112 -112
- openrem/remapp/static/js/skin-dose-maps/rfSkinDoseMap3dObject.js +367 -367
- openrem/remapp/static/js/skin-dose-maps/rfSkinDoseMap3dPersonObject.js +158 -158
- openrem/remapp/static/js/skin-dose-maps/rfSkinDoseMapColourScaleObject.js +153 -153
- openrem/remapp/static/js/skin-dose-maps/rfSkinDoseMapObject.js +367 -367
- openrem/remapp/static/js/skin-dose-maps/rfSkinDoseMapping.js +584 -584
- openrem/remapp/static/js/skin-dose-maps/rfSkinDoseMapping3d.js +255 -255
- openrem/remapp/static/js/skin-dose-maps/rfSkinDoseMappingAjax.js +267 -212
- openrem/remapp/static/js/skin-dose-maps/three.min.js +835 -835
- openrem/remapp/static/js/sorttable.js +495 -495
- openrem/remapp/templates/base.html +253 -253
- openrem/remapp/templates/registration/changepassword.html +25 -25
- openrem/remapp/templates/registration/changepassworddone.html +12 -12
- openrem/remapp/templates/registration/login.html +42 -42
- openrem/remapp/templates/remapp/backgroundtaskmaximumrows_form.html +29 -29
- openrem/remapp/templates/remapp/base.html +1 -1
- openrem/remapp/templates/remapp/ctdetail.html +235 -235
- openrem/remapp/templates/remapp/ctfiltered.html +310 -310
- openrem/remapp/templates/remapp/dicomdeletesettings_form.html +31 -31
- openrem/remapp/templates/remapp/dicomqr.html +147 -147
- openrem/remapp/templates/remapp/dicomquerydetails.html +83 -83
- openrem/remapp/templates/remapp/dicomqueryimages.html +49 -49
- openrem/remapp/templates/remapp/dicomqueryseries.html +109 -109
- openrem/remapp/templates/remapp/dicomquerysummary.html +48 -48
- openrem/remapp/templates/remapp/dicomremoteqr_confirm_delete.html +60 -60
- openrem/remapp/templates/remapp/dicomremoteqr_form.html +32 -32
- openrem/remapp/templates/remapp/dicomstorescp_confirm_delete.html +53 -53
- openrem/remapp/templates/remapp/dicomstorescp_form.html +48 -48
- openrem/remapp/templates/remapp/dicomsummary.html +257 -257
- openrem/remapp/templates/remapp/displaychartoptions.html +184 -184
- openrem/remapp/templates/remapp/displayhomepageoptions.html +57 -57
- openrem/remapp/templates/remapp/displayname-count.html +6 -6
- openrem/remapp/templates/remapp/displayname-last-date.html +3 -3
- openrem/remapp/templates/remapp/displayname-modality.html +86 -105
- openrem/remapp/templates/remapp/displayname-skinmap.html +18 -18
- openrem/remapp/templates/remapp/displaynameupdate.html +100 -100
- openrem/remapp/templates/remapp/displaynameview.html +222 -219
- openrem/remapp/templates/remapp/dxdetail.html +176 -176
- openrem/remapp/templates/remapp/dxfiltered.html +324 -324
- openrem/remapp/templates/remapp/exports-active.html +25 -25
- openrem/remapp/templates/remapp/exports-complete.html +35 -35
- openrem/remapp/templates/remapp/exports-error.html +26 -26
- openrem/remapp/templates/remapp/exports-queue.html +18 -18
- openrem/remapp/templates/remapp/exports.html +191 -191
- openrem/remapp/templates/remapp/failed_summary_list.html +27 -27
- openrem/remapp/templates/remapp/filteredbase.html +162 -162
- openrem/remapp/templates/remapp/highdosemetricalertsettings_form.html +76 -76
- openrem/remapp/templates/remapp/home-list-modalities.html +94 -94
- openrem/remapp/templates/remapp/home.html +202 -202
- openrem/remapp/templates/remapp/list_filters.html +24 -24
- openrem/remapp/templates/remapp/mgdetail.html +160 -138
- openrem/remapp/templates/remapp/mgfiltered.html +311 -311
- openrem/remapp/templates/remapp/nmdetail.html +300 -300
- openrem/remapp/templates/remapp/nmfiltered.html +255 -255
- openrem/remapp/templates/remapp/notpatient.html +190 -190
- openrem/remapp/templates/remapp/notpatientindicators_form_base.html +81 -81
- openrem/remapp/templates/remapp/notpatientindicatorsid_confirm_delete.html +54 -54
- openrem/remapp/templates/remapp/notpatientindicatorsid_form.html +23 -23
- openrem/remapp/templates/remapp/notpatientindicatorsname_confirm_delete.html +54 -54
- openrem/remapp/templates/remapp/notpatientindicatorsname_form.html +23 -23
- openrem/remapp/templates/remapp/notpatientindicatorsname_form_base.html +85 -85
- openrem/remapp/templates/remapp/openskinsafelist_add.html +130 -130
- openrem/remapp/templates/remapp/openskinsafelist_confirm_delete.html +100 -100
- openrem/remapp/templates/remapp/openskinsafelist_form.html +207 -207
- openrem/remapp/templates/remapp/patientidsettings_form.html +83 -83
- openrem/remapp/templates/remapp/populate_summary_progress.html +83 -83
- openrem/remapp/templates/remapp/populate_summary_progress_error.html +36 -36
- openrem/remapp/templates/remapp/review_failed_imports.html +157 -157
- openrem/remapp/templates/remapp/review_failed_study.html +41 -41
- openrem/remapp/templates/remapp/review_studies_delete_button.html +20 -20
- openrem/remapp/templates/remapp/review_study.html +19 -19
- openrem/remapp/templates/remapp/review_summary_list.html +245 -245
- openrem/remapp/templates/remapp/rf_dose_alert_email_template.html +14 -1
- openrem/remapp/templates/remapp/rfalertnotificationsview.html +59 -59
- openrem/remapp/templates/remapp/rfdetail.html +547 -543
- openrem/remapp/templates/remapp/rfdetailbase.html +18 -18
- openrem/remapp/templates/remapp/rffiltered.html +404 -404
- openrem/remapp/templates/remapp/sizeimports.html +119 -119
- openrem/remapp/templates/remapp/sizeprocess.html +96 -96
- openrem/remapp/templates/remapp/sizeupload.html +110 -110
- openrem/remapp/templates/remapp/skindosemapcalcsettings_form.html +28 -28
- openrem/remapp/templates/remapp/standardname-modality.html +69 -69
- openrem/remapp/templates/remapp/standardnames_confirm_delete.html +71 -71
- openrem/remapp/templates/remapp/standardnames_form.html +87 -87
- openrem/remapp/templates/remapp/standardnamesettings_form.html +41 -41
- openrem/remapp/templates/remapp/standardnamesrefreshall.html +92 -92
- openrem/remapp/templates/remapp/standardnameview.html +103 -103
- openrem/remapp/templates/remapp/study_confirm_delete.html +147 -147
- openrem/remapp/templates/remapp/task_admin.html +265 -265
- openrem/remapp/templates/remapp/tasks.html +76 -76
- openrem/remapp/templatetags/formfilters.py +13 -13
- openrem/remapp/templatetags/proper_paginate.py +38 -38
- openrem/remapp/templatetags/remappduration.py +36 -36
- openrem/remapp/templatetags/sigdig.py +38 -38
- openrem/remapp/templatetags/sort_class_property_value.py +15 -15
- openrem/remapp/templatetags/update_variable.py +20 -20
- openrem/remapp/templatetags/url_replace.py +25 -25
- openrem/remapp/tests/test_charts_common.py +202 -202
- openrem/remapp/tests/test_charts_ct.py +7111 -7111
- openrem/remapp/tests/test_charts_dx.py +3513 -3513
- openrem/remapp/tests/test_charts_mg.py +1116 -1115
- openrem/remapp/tests/test_dcmdatetime.py +189 -189
- openrem/remapp/tests/test_dicom_qr.py +2580 -2580
- openrem/remapp/tests/test_display_name.py +274 -274
- openrem/remapp/tests/test_export_ct_xlsx.py +272 -248
- openrem/remapp/tests/test_export_dx_xlsx.py +137 -134
- openrem/remapp/tests/test_export_mammo_csv.py +242 -242
- openrem/remapp/tests/test_export_rf_xlsx.py +246 -246
- openrem/remapp/tests/test_files/DX-Im-DRGEM.dcm +0 -0
- openrem/remapp/tests/test_files/MG-RDSR-GEPristina-2D.dcm +0 -0
- openrem/remapp/tests/test_files/MG-RDSR-GEPristina-DBT.dcm +0 -0
- openrem/remapp/tests/test_files/MG-RDSR-Giotto-DBT.dcm +0 -0
- openrem/remapp/tests/test_files/skin_map_alphenix.py +590 -590
- openrem/remapp/tests/test_files/skin_map_zee.py +354 -354
- openrem/remapp/tests/test_filters_ct.py +321 -321
- openrem/remapp/tests/test_filters_dx.py +92 -92
- openrem/remapp/tests/test_filters_mammo.py +183 -183
- openrem/remapp/tests/test_filters_rf.py +118 -118
- openrem/remapp/tests/test_get_values.py +72 -72
- openrem/remapp/tests/test_hash_id.py +65 -65
- openrem/remapp/tests/test_import_ct_esr_ge.py +3034 -3034
- openrem/remapp/tests/test_import_ct_philips_rdsr.py +42 -42
- openrem/remapp/tests/test_import_ct_rdsr_multiple.py +256 -256
- openrem/remapp/tests/test_import_ct_rdsr_siemens.py +827 -827
- openrem/remapp/tests/test_import_ct_rdsr_spectrumdynamics.py +91 -91
- openrem/remapp/tests/test_import_ct_rdsr_toshiba_dosecheck.py +67 -67
- openrem/remapp/tests/test_import_ct_rdsr_toshiba_multivaluesd.py +33 -33
- openrem/remapp/tests/test_import_ct_rdsr_toshiba_pixelmed.py +118 -118
- openrem/remapp/tests/test_import_ct_sc_philips.py +44 -44
- openrem/remapp/tests/test_import_dual_rdsr.py +110 -110
- openrem/remapp/tests/test_import_dx.py +1267 -1191
- openrem/remapp/tests/test_import_dx_rdsr.py +1250 -1253
- openrem/remapp/tests/test_import_mam.py +438 -438
- openrem/remapp/tests/test_import_mg_im_hol_proj.py +46 -46
- openrem/remapp/tests/test_import_mg_rdsr.py +586 -586
- openrem/remapp/tests/test_import_nm_image.py +420 -420
- openrem/remapp/tests/test_import_nm_siemens_rdsr.py +396 -396
- openrem/remapp/tests/test_import_px.py +161 -161
- openrem/remapp/tests/test_import_rf_rdsr.py +420 -418
- openrem/remapp/tests/test_missing_date.py +42 -42
- openrem/remapp/tests/test_not_patient.py +60 -60
- openrem/remapp/tests/test_openskin.py +272 -272
- openrem/remapp/tests/test_patient_id_settings.py +72 -72
- openrem/remapp/tests/test_pt_size_import.py +232 -232
- openrem/remapp/tests/test_rf_detail.py +113 -113
- openrem/remapp/tests/test_rf_high_dose_alert.py +361 -361
- openrem/remapp/tools/background.py +361 -361
- openrem/remapp/tools/check_standard_name_status.py +47 -0
- openrem/remapp/tools/check_uid.py +70 -70
- openrem/remapp/tools/dcmdatetime.py +248 -248
- openrem/remapp/tools/default_import.py +44 -47
- openrem/remapp/tools/get_values.py +230 -230
- openrem/remapp/tools/hash_id.py +58 -58
- openrem/remapp/tools/make_skin_map.py +448 -406
- openrem/remapp/tools/not_patient_indicators.py +72 -72
- openrem/remapp/tools/openskin/calc_exp_map.py +173 -173
- openrem/remapp/tools/openskin/geomclass.py +475 -475
- openrem/remapp/tools/openskin/geomfunc.py +433 -432
- openrem/remapp/tools/openskin/skinmap.py +417 -417
- openrem/remapp/tools/populate_summary.py +185 -193
- openrem/remapp/tools/save_skin_map_structure.py +73 -73
- openrem/remapp/tools/send_high_dose_alert_emails.py +238 -207
- openrem/remapp/urls.py +456 -448
- openrem/remapp/version.py +11 -11
- openrem/remapp/views.py +1147 -1052
- openrem/remapp/views_admin.py +3876 -3936
- openrem/remapp/views_charts_ct.py +2110 -2058
- openrem/remapp/views_charts_dx.py +1906 -1836
- openrem/remapp/views_charts_mg.py +1349 -1196
- openrem/remapp/views_charts_nm.py +535 -535
- openrem/remapp/views_charts_rf.py +1219 -1241
- openrem/remapp/views_openskin.py +379 -384
- openrem/sample-config/openrem-consumer.service +12 -12
- openrem/sample-config/openrem-gunicorn.service +13 -13
- openrem/sample-config/openrem-server +14 -13
- openrem/sample-config/openrem_orthanc_config_linux.lua +454 -454
- openrem/sample-config/openrem_orthanc_config_windows.lua +455 -455
- openrem/sample-config/queue-init.bat +73 -73
- openrem/scripts/openrem_ctphilips.py +25 -25
- openrem/scripts/openrem_cttoshiba.py +28 -28
- openrem/scripts/openrem_dx.py +22 -22
- openrem/scripts/openrem_mg.py +22 -22
- openrem/scripts/openrem_nm.py +22 -22
- openrem/scripts/openrem_ptsizecsv.py +17 -17
- openrem/scripts/openrem_qr.py +12 -12
- openrem/scripts/openrem_rdsr.py +25 -25
- {OpenREM-1.0.0b2.dist-info → openrem-1.0.0b3.dist-info}/METADATA +39 -29
- openrem-1.0.0b3.dist-info/RECORD +379 -0
- {OpenREM-1.0.0b2.dist-info → openrem-1.0.0b3.dist-info}/WHEEL +1 -1
- {OpenREM-1.0.0b2.dist-info → openrem-1.0.0b3.dist-info/licenses}/COPYING-GPLv3 +674 -674
- {OpenREM-1.0.0b2.dist-info → openrem-1.0.0b3.dist-info/licenses}/LICENSE +22 -22
- OpenREM-1.0.0b2.dist-info/RECORD +0 -373
- openrem/remapp/static/js/charts/plotly-2.17.1.min.js +0 -8
- {OpenREM-1.0.0b2.data → openrem-1.0.0b3.data}/scripts/openrem_ctphilips.py +0 -0
- {OpenREM-1.0.0b2.data → openrem-1.0.0b3.data}/scripts/openrem_cttoshiba.py +0 -0
- {OpenREM-1.0.0b2.data → openrem-1.0.0b3.data}/scripts/openrem_dx.py +0 -0
- {OpenREM-1.0.0b2.data → openrem-1.0.0b3.data}/scripts/openrem_mg.py +0 -0
- {OpenREM-1.0.0b2.data → openrem-1.0.0b3.data}/scripts/openrem_nm.py +0 -0
- {OpenREM-1.0.0b2.data → openrem-1.0.0b3.data}/scripts/openrem_ptsizecsv.py +0 -0
- {OpenREM-1.0.0b2.data → openrem-1.0.0b3.data}/scripts/openrem_qr.py +0 -0
- {OpenREM-1.0.0b2.data → openrem-1.0.0b3.data}/scripts/openrem_rdsr.py +0 -0
- {OpenREM-1.0.0b2.dist-info → openrem-1.0.0b3.dist-info}/top_level.txt +0 -0
|
@@ -1,683 +1,681 @@
|
|
|
1
|
-
# OpenREM - Radiation Exposure Monitoring tools for the physicist
|
|
2
|
-
# Copyright (C) 2012,2013 The Royal Marsden NHS Foundation Trust
|
|
3
|
-
#
|
|
4
|
-
# This program is free software: you can redistribute it and/or modify
|
|
5
|
-
# it under the terms of the GNU General Public License as published by
|
|
6
|
-
# the Free Software Foundation, either version 3 of the License, or
|
|
7
|
-
# (at your option) any later version.
|
|
8
|
-
#
|
|
9
|
-
# This program is distributed in the hope that it will be useful,
|
|
10
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
-
# GNU General Public License for more details.
|
|
13
|
-
#
|
|
14
|
-
# Additional permission under section 7 of GPLv3:
|
|
15
|
-
# You shall not make any use of the name of The Royal Marsden NHS
|
|
16
|
-
# Foundation trust in connection with this Program in any press or
|
|
17
|
-
# other public announcement without the prior written consent of
|
|
18
|
-
# The Royal Marsden NHS Foundation Trust.
|
|
19
|
-
#
|
|
20
|
-
# You should have received a copy of the GNU General Public License
|
|
21
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
22
|
-
|
|
23
|
-
"""
|
|
24
|
-
.. module:: dicomviews.py
|
|
25
|
-
:synopsis: To manage the DICOM servers
|
|
26
|
-
|
|
27
|
-
.. moduleauthor:: Ed McDonagh
|
|
28
|
-
|
|
29
|
-
"""
|
|
30
|
-
import json
|
|
31
|
-
import os
|
|
32
|
-
|
|
33
|
-
from django.conf import settings
|
|
34
|
-
from django.contrib import messages
|
|
35
|
-
from django.contrib.auth.decorators import login_required
|
|
36
|
-
from django.core.exceptions import ObjectDoesNotExist
|
|
37
|
-
from django.db.models import Count
|
|
38
|
-
from django.http import HttpResponse
|
|
39
|
-
from django.shortcuts import get_object_or_404, redirect, render
|
|
40
|
-
from django.urls import reverse_lazy
|
|
41
|
-
from django.views.decorators.csrf import csrf_exempt
|
|
42
|
-
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
|
43
|
-
|
|
44
|
-
from remapp.models import (
|
|
45
|
-
DicomDeleteSettings,
|
|
46
|
-
DicomQRRspSeries,
|
|
47
|
-
DicomQRRspStudy,
|
|
48
|
-
DicomQuery,
|
|
49
|
-
DicomStoreSCP,
|
|
50
|
-
DicomRemoteQR,
|
|
51
|
-
)
|
|
52
|
-
from .qrscu import movescu, qrscu
|
|
53
|
-
from .tools import echoscu
|
|
54
|
-
from .. import __docs_version__, __version__
|
|
55
|
-
from ..forms import DicomQueryForm, DicomQRForm, DicomStoreForm
|
|
56
|
-
from ..views_admin import _create_admin_dict
|
|
57
|
-
|
|
58
|
-
from openrem.remapp.tools.background import run_in_background
|
|
59
|
-
|
|
60
|
-
os.environ["DJANGO_SETTINGS_MODULE"] = "openremproject.settings"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def create_admin_info(request):
|
|
64
|
-
admin = {
|
|
65
|
-
"openremversion": __version__,
|
|
66
|
-
"docsversion": __docs_version__,
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
for group in request.user.groups.all():
|
|
70
|
-
admin[group.name] = True
|
|
71
|
-
return admin
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
@csrf_exempt
|
|
75
|
-
@login_required
|
|
76
|
-
def delete_queries(request):
|
|
77
|
-
"""Delete all queries."""
|
|
78
|
-
resp = {}
|
|
79
|
-
resp["status"] = "fail"
|
|
80
|
-
if request.method == "POST":
|
|
81
|
-
DicomQuery.objects.all().delete()
|
|
82
|
-
resp["status"] = "success"
|
|
83
|
-
|
|
84
|
-
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
@csrf_exempt
|
|
88
|
-
@login_required
|
|
89
|
-
def get_query_images(request, pk):
|
|
90
|
-
"""View to show the images of a queried series."""
|
|
91
|
-
queryseries = get_object_or_404(DicomQRRspSeries, pk=pk)
|
|
92
|
-
images = queryseries.dicomqrrspimage_set.all()
|
|
93
|
-
admin = create_admin_info(request)
|
|
94
|
-
|
|
95
|
-
return render(
|
|
96
|
-
request,
|
|
97
|
-
"remapp/dicomqueryimages.html",
|
|
98
|
-
{
|
|
99
|
-
"queryseries": queryseries,
|
|
100
|
-
"queryimages": images,
|
|
101
|
-
"admin": admin,
|
|
102
|
-
},
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
@csrf_exempt
|
|
107
|
-
@login_required
|
|
108
|
-
def get_query_series(request, pk):
|
|
109
|
-
"""View to show the series of a queried study."""
|
|
110
|
-
querystudy = get_object_or_404(DicomQRRspStudy, pk=pk)
|
|
111
|
-
series = querystudy.dicomqrrspseries_set.all()
|
|
112
|
-
admin = create_admin_info(request)
|
|
113
|
-
studyimports = querystudy.related_imports.all()
|
|
114
|
-
|
|
115
|
-
return render(
|
|
116
|
-
request,
|
|
117
|
-
"remapp/dicomqueryseries.html",
|
|
118
|
-
{
|
|
119
|
-
"queryseries": series,
|
|
120
|
-
"admin": admin,
|
|
121
|
-
"studyimports": studyimports,
|
|
122
|
-
},
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
@csrf_exempt
|
|
127
|
-
@login_required
|
|
128
|
-
def get_query_details(request, pk):
|
|
129
|
-
"""View to show all query studies."""
|
|
130
|
-
query = get_object_or_404(DicomQuery, pk=pk)
|
|
131
|
-
querystudies = query.dicomqrrspstudy_set.all()
|
|
132
|
-
admin = create_admin_info(request)
|
|
133
|
-
|
|
134
|
-
return render(
|
|
135
|
-
request,
|
|
136
|
-
"remapp/dicomquerydetails.html",
|
|
137
|
-
{
|
|
138
|
-
"query": query,
|
|
139
|
-
"admin": admin,
|
|
140
|
-
"querystudies": querystudies,
|
|
141
|
-
},
|
|
142
|
-
)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
@csrf_exempt
|
|
146
|
-
@login_required
|
|
147
|
-
def get_query_summary(request):
|
|
148
|
-
"""View to show all queries from the past."""
|
|
149
|
-
queries = DicomQuery.objects.order_by("started_at").reverse().all()
|
|
150
|
-
admin = create_admin_info(request)
|
|
151
|
-
|
|
152
|
-
return render(
|
|
153
|
-
request, "remapp/dicomquerysummary.html", {"queries": queries, "admin": admin}
|
|
154
|
-
)
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
@csrf_exempt
|
|
158
|
-
def status_update_store(request):
|
|
159
|
-
"""View to check if store is running using DICOM ECHO"""
|
|
160
|
-
|
|
161
|
-
resp = {}
|
|
162
|
-
data = request.POST
|
|
163
|
-
scp_pk = data.get("scp_pk")
|
|
164
|
-
|
|
165
|
-
echo_response = echoscu(scp_pk=scp_pk, store_scp=True)
|
|
166
|
-
|
|
167
|
-
resp["message"] = f"<div>{echo_response}</div>"
|
|
168
|
-
if echo_response == "Success":
|
|
169
|
-
resp["statusindicator"] = (
|
|
170
|
-
"<h3 class='pull-right panel-title'>"
|
|
171
|
-
"<span class='glyphicon glyphicon-ok' aria-hidden='true'></span>"
|
|
172
|
-
"<span class='sr-only'>OK:</span> Server is alive</h3>"
|
|
173
|
-
)
|
|
174
|
-
resp[
|
|
175
|
-
"
|
|
176
|
-
|
|
177
|
-
else:
|
|
178
|
-
resp["statusindicator"] = (
|
|
179
|
-
"<h3 class='pull-right panel-title status-red'>"
|
|
180
|
-
"<span class='glyphicon glyphicon-exclamation-sign' aria-hidden='true'></span>"
|
|
181
|
-
"<span class='sr-only'>Error:</span> Server is down - see status</h3>"
|
|
182
|
-
)
|
|
183
|
-
resp[
|
|
184
|
-
"
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
resp["
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
resp["
|
|
205
|
-
resp["
|
|
206
|
-
resp
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
resp["
|
|
211
|
-
resp["
|
|
212
|
-
resp
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
f
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
table.append("
|
|
237
|
-
table.append(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
resp["
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
table.append("
|
|
258
|
-
table.append(
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
"<div class='panel-
|
|
265
|
-
"<div class='panel
|
|
266
|
-
"<
|
|
267
|
-
"<
|
|
268
|
-
"
|
|
269
|
-
"
|
|
270
|
-
"
|
|
271
|
-
"<div
|
|
272
|
-
"<div
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
"<div class='panel-
|
|
279
|
-
"<div class='panel
|
|
280
|
-
"<
|
|
281
|
-
"<
|
|
282
|
-
"
|
|
283
|
-
"
|
|
284
|
-
"
|
|
285
|
-
"<div
|
|
286
|
-
"<
|
|
287
|
-
"
|
|
288
|
-
"
|
|
289
|
-
"
|
|
290
|
-
"
|
|
291
|
-
"OpenREM
|
|
292
|
-
"
|
|
293
|
-
"
|
|
294
|
-
"
|
|
295
|
-
"
|
|
296
|
-
"
|
|
297
|
-
"
|
|
298
|
-
"
|
|
299
|
-
"
|
|
300
|
-
"
|
|
301
|
-
"
|
|
302
|
-
"
|
|
303
|
-
"
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
"
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
)
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
if
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
"
|
|
373
|
-
"
|
|
374
|
-
"
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
resp =
|
|
395
|
-
resp["
|
|
396
|
-
|
|
397
|
-
resp
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
print(
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
resp =
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
"
|
|
448
|
-
"
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
)
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
resp["
|
|
493
|
-
resp
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
f"<
|
|
499
|
-
f
|
|
500
|
-
f"<
|
|
501
|
-
f"<
|
|
502
|
-
f"<td>{query.
|
|
503
|
-
f"
|
|
504
|
-
f"
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
query.
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
resp["
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
"
|
|
587
|
-
"
|
|
588
|
-
"
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
context
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
context["admin"] = admin
|
|
683
|
-
return context
|
|
1
|
+
# OpenREM - Radiation Exposure Monitoring tools for the physicist
|
|
2
|
+
# Copyright (C) 2012,2013 The Royal Marsden NHS Foundation Trust
|
|
3
|
+
#
|
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# Additional permission under section 7 of GPLv3:
|
|
15
|
+
# You shall not make any use of the name of The Royal Marsden NHS
|
|
16
|
+
# Foundation trust in connection with this Program in any press or
|
|
17
|
+
# other public announcement without the prior written consent of
|
|
18
|
+
# The Royal Marsden NHS Foundation Trust.
|
|
19
|
+
#
|
|
20
|
+
# You should have received a copy of the GNU General Public License
|
|
21
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
.. module:: dicomviews.py
|
|
25
|
+
:synopsis: To manage the DICOM servers
|
|
26
|
+
|
|
27
|
+
.. moduleauthor:: Ed McDonagh
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
import json
|
|
31
|
+
import os
|
|
32
|
+
|
|
33
|
+
from django.conf import settings
|
|
34
|
+
from django.contrib import messages
|
|
35
|
+
from django.contrib.auth.decorators import login_required
|
|
36
|
+
from django.core.exceptions import ObjectDoesNotExist
|
|
37
|
+
from django.db.models import Count
|
|
38
|
+
from django.http import HttpResponse
|
|
39
|
+
from django.shortcuts import get_object_or_404, redirect, render
|
|
40
|
+
from django.urls import reverse_lazy
|
|
41
|
+
from django.views.decorators.csrf import csrf_exempt
|
|
42
|
+
from django.views.generic.edit import CreateView, UpdateView, DeleteView
|
|
43
|
+
|
|
44
|
+
from remapp.models import (
|
|
45
|
+
DicomDeleteSettings,
|
|
46
|
+
DicomQRRspSeries,
|
|
47
|
+
DicomQRRspStudy,
|
|
48
|
+
DicomQuery,
|
|
49
|
+
DicomStoreSCP,
|
|
50
|
+
DicomRemoteQR,
|
|
51
|
+
)
|
|
52
|
+
from .qrscu import movescu, qrscu
|
|
53
|
+
from .tools import echoscu
|
|
54
|
+
from .. import __docs_version__, __version__
|
|
55
|
+
from ..forms import DicomQueryForm, DicomQRForm, DicomStoreForm
|
|
56
|
+
from ..views_admin import _create_admin_dict
|
|
57
|
+
|
|
58
|
+
from openrem.remapp.tools.background import run_in_background
|
|
59
|
+
|
|
60
|
+
os.environ["DJANGO_SETTINGS_MODULE"] = "openremproject.settings"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def create_admin_info(request):
|
|
64
|
+
admin = {
|
|
65
|
+
"openremversion": __version__,
|
|
66
|
+
"docsversion": __docs_version__,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for group in request.user.groups.all():
|
|
70
|
+
admin[group.name] = True
|
|
71
|
+
return admin
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@csrf_exempt
|
|
75
|
+
@login_required
|
|
76
|
+
def delete_queries(request):
|
|
77
|
+
"""Delete all queries."""
|
|
78
|
+
resp = {}
|
|
79
|
+
resp["status"] = "fail"
|
|
80
|
+
if request.method == "POST":
|
|
81
|
+
DicomQuery.objects.all().delete()
|
|
82
|
+
resp["status"] = "success"
|
|
83
|
+
|
|
84
|
+
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@csrf_exempt
|
|
88
|
+
@login_required
|
|
89
|
+
def get_query_images(request, pk):
|
|
90
|
+
"""View to show the images of a queried series."""
|
|
91
|
+
queryseries = get_object_or_404(DicomQRRspSeries, pk=pk)
|
|
92
|
+
images = queryseries.dicomqrrspimage_set.all()
|
|
93
|
+
admin = create_admin_info(request)
|
|
94
|
+
|
|
95
|
+
return render(
|
|
96
|
+
request,
|
|
97
|
+
"remapp/dicomqueryimages.html",
|
|
98
|
+
{
|
|
99
|
+
"queryseries": queryseries,
|
|
100
|
+
"queryimages": images,
|
|
101
|
+
"admin": admin,
|
|
102
|
+
},
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
@csrf_exempt
|
|
107
|
+
@login_required
|
|
108
|
+
def get_query_series(request, pk):
|
|
109
|
+
"""View to show the series of a queried study."""
|
|
110
|
+
querystudy = get_object_or_404(DicomQRRspStudy, pk=pk)
|
|
111
|
+
series = querystudy.dicomqrrspseries_set.all()
|
|
112
|
+
admin = create_admin_info(request)
|
|
113
|
+
studyimports = querystudy.related_imports.all()
|
|
114
|
+
|
|
115
|
+
return render(
|
|
116
|
+
request,
|
|
117
|
+
"remapp/dicomqueryseries.html",
|
|
118
|
+
{
|
|
119
|
+
"queryseries": series,
|
|
120
|
+
"admin": admin,
|
|
121
|
+
"studyimports": studyimports,
|
|
122
|
+
},
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@csrf_exempt
|
|
127
|
+
@login_required
|
|
128
|
+
def get_query_details(request, pk):
|
|
129
|
+
"""View to show all query studies."""
|
|
130
|
+
query = get_object_or_404(DicomQuery, pk=pk)
|
|
131
|
+
querystudies = query.dicomqrrspstudy_set.all()
|
|
132
|
+
admin = create_admin_info(request)
|
|
133
|
+
|
|
134
|
+
return render(
|
|
135
|
+
request,
|
|
136
|
+
"remapp/dicomquerydetails.html",
|
|
137
|
+
{
|
|
138
|
+
"query": query,
|
|
139
|
+
"admin": admin,
|
|
140
|
+
"querystudies": querystudies,
|
|
141
|
+
},
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@csrf_exempt
|
|
146
|
+
@login_required
|
|
147
|
+
def get_query_summary(request):
|
|
148
|
+
"""View to show all queries from the past."""
|
|
149
|
+
queries = DicomQuery.objects.order_by("started_at").reverse().all()
|
|
150
|
+
admin = create_admin_info(request)
|
|
151
|
+
|
|
152
|
+
return render(
|
|
153
|
+
request, "remapp/dicomquerysummary.html", {"queries": queries, "admin": admin}
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@csrf_exempt
|
|
158
|
+
def status_update_store(request):
|
|
159
|
+
"""View to check if store is running using DICOM ECHO"""
|
|
160
|
+
|
|
161
|
+
resp = {}
|
|
162
|
+
data = request.POST
|
|
163
|
+
scp_pk = data.get("scp_pk")
|
|
164
|
+
|
|
165
|
+
echo_response = echoscu(scp_pk=scp_pk, store_scp=True)
|
|
166
|
+
|
|
167
|
+
resp["message"] = f"<div>{echo_response}</div>"
|
|
168
|
+
if echo_response == "Success":
|
|
169
|
+
resp["statusindicator"] = (
|
|
170
|
+
"<h3 class='pull-right panel-title'>"
|
|
171
|
+
"<span class='glyphicon glyphicon-ok' aria-hidden='true'></span>"
|
|
172
|
+
"<span class='sr-only'>OK:</span> Server is alive</h3>"
|
|
173
|
+
)
|
|
174
|
+
resp["delbutton"] = (
|
|
175
|
+
"<button type='button' class='btn btn-primary' disabled='disabled'>Delete</button>"
|
|
176
|
+
)
|
|
177
|
+
else:
|
|
178
|
+
resp["statusindicator"] = (
|
|
179
|
+
"<h3 class='pull-right panel-title status-red'>"
|
|
180
|
+
"<span class='glyphicon glyphicon-exclamation-sign' aria-hidden='true'></span>"
|
|
181
|
+
"<span class='sr-only'>Error:</span> Server is down - see status</h3>"
|
|
182
|
+
)
|
|
183
|
+
resp["delbutton"] = (
|
|
184
|
+
f"<a class='btn btn-primary' href='{reverse_lazy('dicomstore_delete', kwargs={'pk': scp_pk})}' "
|
|
185
|
+
f"role='button'>Delete</a>"
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
@csrf_exempt
|
|
192
|
+
def q_update(request):
|
|
193
|
+
"""View to update query status"""
|
|
194
|
+
resp = {}
|
|
195
|
+
data = request.POST
|
|
196
|
+
query_id = data.get("queryID")
|
|
197
|
+
show_details_link = data.get("showDetailsLink")
|
|
198
|
+
resp["queryID"] = query_id
|
|
199
|
+
resp["showDetailsLink"] = show_details_link
|
|
200
|
+
try:
|
|
201
|
+
query = DicomQuery.objects.get(query_id=query_id)
|
|
202
|
+
except ObjectDoesNotExist:
|
|
203
|
+
resp["status"] = "not complete"
|
|
204
|
+
resp["message"] = "<h4>Query {0} not yet started</h4>".format(query_id)
|
|
205
|
+
resp["subops"] = ""
|
|
206
|
+
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
207
|
+
|
|
208
|
+
if query.failed:
|
|
209
|
+
resp["status"] = "failed"
|
|
210
|
+
resp["message"] = "<h4>Query Failed</h4> {0}".format(query.message)
|
|
211
|
+
resp["subops"] = ""
|
|
212
|
+
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
213
|
+
|
|
214
|
+
if show_details_link:
|
|
215
|
+
query_details_link = (
|
|
216
|
+
f'<a href="{reverse_lazy("get_query_details", None, [query.pk])}">'
|
|
217
|
+
f"Go to query details page</a>"
|
|
218
|
+
)
|
|
219
|
+
else:
|
|
220
|
+
query_details_link = ""
|
|
221
|
+
|
|
222
|
+
study_rsp = query.dicomqrrspstudy_set.filter(deleted_flag=False).all()
|
|
223
|
+
if not query.complete:
|
|
224
|
+
modalities = study_rsp.values("modalities_in_study").annotate(count=Count("pk"))
|
|
225
|
+
table = [
|
|
226
|
+
'<table class="table table-bordered">'
|
|
227
|
+
"<tr><th>Modalities in study</th><th>Number of responses</th></tr>"
|
|
228
|
+
]
|
|
229
|
+
for m in modalities:
|
|
230
|
+
table.append("<tr><td>")
|
|
231
|
+
if m["modalities_in_study"]:
|
|
232
|
+
table.append(", ".join(json.loads(m["modalities_in_study"])))
|
|
233
|
+
else:
|
|
234
|
+
table.append("Unknown")
|
|
235
|
+
table.append("</td><td>")
|
|
236
|
+
table.append(str(m["count"]))
|
|
237
|
+
table.append("</tr></td>")
|
|
238
|
+
table.append("</table>")
|
|
239
|
+
tablestr = "".join(table)
|
|
240
|
+
resp["status"] = "not complete"
|
|
241
|
+
resp["message"] = "<h4>{0}</h4><p>{2}</p><p>Responses so far:</p> {1}".format(
|
|
242
|
+
query.stage, tablestr, query_details_link
|
|
243
|
+
)
|
|
244
|
+
resp["subops"] = ""
|
|
245
|
+
else:
|
|
246
|
+
modalities = study_rsp.values("modality").annotate(count=Count("pk"))
|
|
247
|
+
table = [
|
|
248
|
+
'<table class="table table-bordered"><tr><th>Modality</th><th>Number of responses</th></tr>'
|
|
249
|
+
]
|
|
250
|
+
for m in modalities:
|
|
251
|
+
table.append("<tr><td>")
|
|
252
|
+
if m["modality"]:
|
|
253
|
+
table.append(m["modality"])
|
|
254
|
+
else:
|
|
255
|
+
table.append("Unknown - SR only study?")
|
|
256
|
+
table.append("</td><td>")
|
|
257
|
+
table.append(str(m["count"]))
|
|
258
|
+
table.append("</tr></td>")
|
|
259
|
+
table.append("</table>")
|
|
260
|
+
tablestr = "".join(table)
|
|
261
|
+
resp["status"] = "complete"
|
|
262
|
+
query_details_text = (
|
|
263
|
+
"<div class='panel-group' id='accordion'>"
|
|
264
|
+
"<div class='panel panel-default'>"
|
|
265
|
+
"<div class='panel-heading'> "
|
|
266
|
+
"<h4 class='panel-title'>"
|
|
267
|
+
"<a data-toggle='collapse' data-parent='#accordion' href='#query-details'>"
|
|
268
|
+
"Query details</h4>"
|
|
269
|
+
"</a></h4></div>"
|
|
270
|
+
"<div id='query-details' class='panel-collapse collapse'>"
|
|
271
|
+
"<div class='panel-body'>"
|
|
272
|
+
"<p>{0}</p><p>{1}</p></div></div></div></div>".format(
|
|
273
|
+
query.stage, query_details_link
|
|
274
|
+
)
|
|
275
|
+
)
|
|
276
|
+
not_as_expected_help_text = (
|
|
277
|
+
"<div class='panel-group' id='accordion'>"
|
|
278
|
+
"<div class='panel panel-default'>"
|
|
279
|
+
"<div class='panel-heading'> "
|
|
280
|
+
"<h4 class='panel-title'>"
|
|
281
|
+
"<a data-toggle='collapse' data-parent='#accordion' href='#not-expected'>"
|
|
282
|
+
"Not what you expected?</h4>"
|
|
283
|
+
"</a></h4></div>"
|
|
284
|
+
"<div id='not-expected' class='panel-collapse collapse'>"
|
|
285
|
+
"<div class='panel-body'>"
|
|
286
|
+
"<p>For DX and mammography, the query will look for Radiation Dose Structured "
|
|
287
|
+
"Reports, or images if the RDSR is not available. For Fluoroscopy, RDSRs are "
|
|
288
|
+
"required. For CT RDSRs are preferred, but Philips dose images can be used and "
|
|
289
|
+
"for some scanners, particularly older Toshiba scanners that can't create RDSR "
|
|
290
|
+
"OpenREM can process the data to create an RDSR to import. For Nuclear Medicine "
|
|
291
|
+
"OpenREM will try to use the RRDSR if present, otherwise it will fall back to "
|
|
292
|
+
"reading from PET or NM images.</p>"
|
|
293
|
+
"<p>If you haven't got the results you expect, it may be that the imaging system"
|
|
294
|
+
" is not creating RDSRs or not sending them to the PACS you are querying. In "
|
|
295
|
+
"either case you will need to have the system reconfigured to create and/or send"
|
|
296
|
+
" them. If it is a CT scanner that can't create an RDSR (it is too old), it is "
|
|
297
|
+
"worth trying the 'Toshiba' option, but you will need to be using Orthanc and "
|
|
298
|
+
"configure your scanner in the "
|
|
299
|
+
"<a href='https://docs.openrem.org/en/{0}/netdicom-orthanc-config.html"
|
|
300
|
+
"#guide-to-customising-orthanc-configuration' target='_blank'>"
|
|
301
|
+
"toshiba_extractor_systems</a> list"
|
|
302
|
+
". You will need to verify the resulting data to confirm accuracy.</p>"
|
|
303
|
+
"</div></div></div></div>".format(__docs_version__)
|
|
304
|
+
)
|
|
305
|
+
resp["message"] = (
|
|
306
|
+
f"<h4>Query complete - there are {study_rsp.count()} studies we can move</h4> "
|
|
307
|
+
f"{tablestr} {query_details_text} {not_as_expected_help_text}"
|
|
308
|
+
)
|
|
309
|
+
resp["subops"] = ""
|
|
310
|
+
|
|
311
|
+
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@csrf_exempt
|
|
315
|
+
@login_required
|
|
316
|
+
def q_process(request, *args, **kwargs):
|
|
317
|
+
"""View to process query form POST"""
|
|
318
|
+
|
|
319
|
+
if request.method == "POST":
|
|
320
|
+
form = DicomQueryForm(request.POST)
|
|
321
|
+
if form.is_valid():
|
|
322
|
+
rh_pk = form.cleaned_data.get("remote_host_field")
|
|
323
|
+
store_pk = form.cleaned_data.get("store_scp_field")
|
|
324
|
+
date_from = form.cleaned_data.get("date_from_field")
|
|
325
|
+
date_until = form.cleaned_data.get("date_until_field")
|
|
326
|
+
modalities = form.cleaned_data.get("modality_field")
|
|
327
|
+
inc_sr = form.cleaned_data.get("inc_sr_field")
|
|
328
|
+
remove_duplicates = form.cleaned_data.get("duplicates_field")
|
|
329
|
+
desc_exclude = form.cleaned_data.get("desc_exclude_field")
|
|
330
|
+
desc_include = form.cleaned_data.get("desc_include_field")
|
|
331
|
+
stationname_exclude = form.cleaned_data.get("stationname_exclude_field")
|
|
332
|
+
stationname_include = form.cleaned_data.get("stationname_include_field")
|
|
333
|
+
stationname_study_level = form.cleaned_data.get(
|
|
334
|
+
"stationname_study_level_field"
|
|
335
|
+
)
|
|
336
|
+
get_toshiba_images = form.cleaned_data.get("get_toshiba_images_field")
|
|
337
|
+
get_empty_sr = form.cleaned_data.get("get_empty_sr_field")
|
|
338
|
+
|
|
339
|
+
if date_from:
|
|
340
|
+
date_from = date_from.isoformat()
|
|
341
|
+
if date_until:
|
|
342
|
+
date_until = date_until.isoformat()
|
|
343
|
+
|
|
344
|
+
if desc_exclude:
|
|
345
|
+
study_desc_exc = list(
|
|
346
|
+
map(str.lower, list(map(str.strip, desc_exclude.split(","))))
|
|
347
|
+
)
|
|
348
|
+
else:
|
|
349
|
+
study_desc_exc = None
|
|
350
|
+
if desc_include:
|
|
351
|
+
study_desc_inc = list(
|
|
352
|
+
map(str.lower, list(map(str.strip, desc_include.split(","))))
|
|
353
|
+
)
|
|
354
|
+
else:
|
|
355
|
+
study_desc_inc = None
|
|
356
|
+
if stationname_exclude:
|
|
357
|
+
stationname_exc = list(
|
|
358
|
+
map(str.lower, list(map(str.strip, stationname_exclude.split(","))))
|
|
359
|
+
)
|
|
360
|
+
else:
|
|
361
|
+
stationname_exc = None
|
|
362
|
+
if stationname_include:
|
|
363
|
+
stationname_inc = list(
|
|
364
|
+
map(str.lower, list(map(str.strip, stationname_include.split(","))))
|
|
365
|
+
)
|
|
366
|
+
else:
|
|
367
|
+
stationname_inc = None
|
|
368
|
+
|
|
369
|
+
filters = {
|
|
370
|
+
"stationname_inc": stationname_inc,
|
|
371
|
+
"stationname_exc": stationname_exc,
|
|
372
|
+
"study_desc_inc": study_desc_inc,
|
|
373
|
+
"study_desc_exc": study_desc_exc,
|
|
374
|
+
"stationname_study": stationname_study_level,
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
b = run_in_background(
|
|
378
|
+
qrscu,
|
|
379
|
+
"query",
|
|
380
|
+
qr_scp_pk=rh_pk,
|
|
381
|
+
store_scp_pk=store_pk,
|
|
382
|
+
date_from=date_from,
|
|
383
|
+
date_until=date_until,
|
|
384
|
+
modalities=modalities,
|
|
385
|
+
inc_sr=inc_sr,
|
|
386
|
+
remove_duplicates=remove_duplicates,
|
|
387
|
+
filters=filters,
|
|
388
|
+
get_toshiba_images=get_toshiba_images,
|
|
389
|
+
get_empty_sr=get_empty_sr,
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
resp = {}
|
|
393
|
+
resp["message"] = "Request created"
|
|
394
|
+
resp["status"] = "not complete"
|
|
395
|
+
resp["queryID"] = b.id
|
|
396
|
+
|
|
397
|
+
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
398
|
+
else:
|
|
399
|
+
print("Bother, form wasn't valid")
|
|
400
|
+
errors = form.errors
|
|
401
|
+
print(errors)
|
|
402
|
+
print(form)
|
|
403
|
+
|
|
404
|
+
# Need to find a way to deal with this event
|
|
405
|
+
# render_to_response('remapp/dicomqr.html', {'form': form}, context_instance=RequestContext(request))
|
|
406
|
+
resp = {}
|
|
407
|
+
resp["message"] = errors
|
|
408
|
+
resp["status"] = "not complete"
|
|
409
|
+
|
|
410
|
+
admin = {"openremversion": __version__, "docsversion": __docs_version__}
|
|
411
|
+
|
|
412
|
+
for group in request.user.groups.all():
|
|
413
|
+
admin[group.name] = True
|
|
414
|
+
|
|
415
|
+
return render(
|
|
416
|
+
request, "remapp/dicomqr.html", {"form": form, "admin": admin}
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
@login_required
|
|
421
|
+
def dicom_qr_page(request, *args, **kwargs):
|
|
422
|
+
"""View for DICOM Query Retrieve page"""
|
|
423
|
+
|
|
424
|
+
if not request.user.groups.filter(name="importqrgroup"):
|
|
425
|
+
messages.error(
|
|
426
|
+
request,
|
|
427
|
+
"You are not in the importqrgroup - please contact your administrator",
|
|
428
|
+
)
|
|
429
|
+
return redirect(reverse_lazy("home"))
|
|
430
|
+
|
|
431
|
+
form = DicomQueryForm
|
|
432
|
+
|
|
433
|
+
store_nodes = DicomStoreSCP.objects.all()
|
|
434
|
+
qr_nodes = DicomRemoteQR.objects.all()
|
|
435
|
+
|
|
436
|
+
admin = {"openremversion": __version__, "docsversion": __docs_version__}
|
|
437
|
+
|
|
438
|
+
for group in request.user.groups.all():
|
|
439
|
+
admin[group.name] = True
|
|
440
|
+
|
|
441
|
+
return render(
|
|
442
|
+
request,
|
|
443
|
+
"remapp/dicomqr.html",
|
|
444
|
+
{
|
|
445
|
+
"form": form,
|
|
446
|
+
"admin": admin,
|
|
447
|
+
"qr_nodes": qr_nodes,
|
|
448
|
+
"store_nodes": store_nodes,
|
|
449
|
+
},
|
|
450
|
+
)
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
@csrf_exempt
|
|
454
|
+
@login_required
|
|
455
|
+
def r_start(request):
|
|
456
|
+
"""View to trigger move following successful query"""
|
|
457
|
+
resp = {}
|
|
458
|
+
data = request.POST
|
|
459
|
+
query_id = data.get("queryID")
|
|
460
|
+
resp["queryID"] = query_id
|
|
461
|
+
|
|
462
|
+
run_in_background(
|
|
463
|
+
movescu,
|
|
464
|
+
"move",
|
|
465
|
+
query_id,
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
@csrf_exempt
|
|
472
|
+
def r_update(request):
|
|
473
|
+
"""View to update progress of QR move (retrieval)"""
|
|
474
|
+
|
|
475
|
+
resp = {}
|
|
476
|
+
data = request.POST
|
|
477
|
+
query_id = data.get("queryID")
|
|
478
|
+
resp["queryID"] = query_id
|
|
479
|
+
has_started = True
|
|
480
|
+
try:
|
|
481
|
+
query = DicomQuery.objects.get(query_id=query_id)
|
|
482
|
+
except ObjectDoesNotExist:
|
|
483
|
+
has_started = False
|
|
484
|
+
|
|
485
|
+
if has_started:
|
|
486
|
+
task = query.move_task
|
|
487
|
+
has_started = task is not None
|
|
488
|
+
|
|
489
|
+
if not has_started:
|
|
490
|
+
resp["status"] = "not started"
|
|
491
|
+
resp["message"] = f"<h4>Move request {query_id} not yet started</h4>"
|
|
492
|
+
resp["subops"] = ""
|
|
493
|
+
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
494
|
+
|
|
495
|
+
resp["subops"] = (
|
|
496
|
+
f"<h4>Cumulative Sub-operations for move request:</h4>"
|
|
497
|
+
f'<table class="table">'
|
|
498
|
+
f"<tr><th>Completed</th><th>Failed</th><th>Warnings</th></tr>"
|
|
499
|
+
f"<tr>"
|
|
500
|
+
f"<td>{query.move_completed_sub_ops}</td>"
|
|
501
|
+
f"<td>{query.move_failed_sub_ops}</td>"
|
|
502
|
+
f"<td>{query.move_warning_sub_ops}</td>"
|
|
503
|
+
f"</tr>"
|
|
504
|
+
f"</table>"
|
|
505
|
+
)
|
|
506
|
+
# query.move_summary = f'Cumulative Sub-operations for move request: Completed {query.move_completed_sub_ops},' \
|
|
507
|
+
# f'Failed {query.move_failed_sub_ops}, Warnings {query.move_warning_sub_ops}.'
|
|
508
|
+
query.save()
|
|
509
|
+
|
|
510
|
+
if query.failed:
|
|
511
|
+
resp["status"] = "failed"
|
|
512
|
+
resp["message"] = f"<h4>Move request failed</h4> {query.message}"
|
|
513
|
+
query.move_summary = f"Move request failed: {query.message}"
|
|
514
|
+
query.save()
|
|
515
|
+
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
516
|
+
|
|
517
|
+
if not query.move_complete:
|
|
518
|
+
resp["status"] = "not complete"
|
|
519
|
+
resp["message"] = "<h4>{0}</h4>".format(query.move_summary)
|
|
520
|
+
else:
|
|
521
|
+
resp["status"] = "move complete"
|
|
522
|
+
resp["message"] = "<h4>Move request complete</h4>"
|
|
523
|
+
|
|
524
|
+
return HttpResponse(json.dumps(resp), content_type="application/json")
|
|
525
|
+
|
|
526
|
+
|
|
527
|
+
def get_qr_status(request):
|
|
528
|
+
"""View to get query-retrieve node status for query page"""
|
|
529
|
+
|
|
530
|
+
data = request.POST
|
|
531
|
+
echo_response = echoscu(scp_pk=data.get("node"), qr_scp=True)
|
|
532
|
+
if echo_response == "Success":
|
|
533
|
+
status = (
|
|
534
|
+
"<span class='glyphicon glyphicon-ok' aria-hidden='true'></span>"
|
|
535
|
+
"<span class='sr-only'>OK:</span> responding to DICOM echo"
|
|
536
|
+
)
|
|
537
|
+
else:
|
|
538
|
+
status = (
|
|
539
|
+
"<span class='glyphicon glyphicon-exclamation-sign' aria-hidden='true'></span>"
|
|
540
|
+
"<span class='sr-only'>Error:</span> {0}".format(echo_response)
|
|
541
|
+
)
|
|
542
|
+
return HttpResponse(json.dumps(status), content_type="application/json")
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
def get_store_status(request):
|
|
546
|
+
"""View to get store node status for query page"""
|
|
547
|
+
|
|
548
|
+
data = request.POST
|
|
549
|
+
echo_response = echoscu(scp_pk=data.get("node"), store_scp=True)
|
|
550
|
+
if echo_response == "Success":
|
|
551
|
+
status = (
|
|
552
|
+
"<span class='glyphicon glyphicon-ok' aria-hidden='true'></span>"
|
|
553
|
+
"<span class='sr-only'>OK:</span> responding to DICOM echo"
|
|
554
|
+
)
|
|
555
|
+
else:
|
|
556
|
+
status = (
|
|
557
|
+
"<span class='glyphicon glyphicon-exclamation-sign' aria-hidden='true'></span>"
|
|
558
|
+
"<span class='sr-only'>Error:</span> {0}".format(echo_response)
|
|
559
|
+
)
|
|
560
|
+
return HttpResponse(json.dumps(status), content_type="application/json")
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
@login_required
|
|
564
|
+
def dicom_summary(request):
|
|
565
|
+
"""Displays current DICOM configuration"""
|
|
566
|
+
|
|
567
|
+
try:
|
|
568
|
+
del_settings = DicomDeleteSettings.objects.get()
|
|
569
|
+
except ObjectDoesNotExist:
|
|
570
|
+
DicomDeleteSettings.objects.create()
|
|
571
|
+
del_settings = DicomDeleteSettings.objects.get()
|
|
572
|
+
|
|
573
|
+
store = DicomStoreSCP.objects.all()
|
|
574
|
+
remoteqr = DicomRemoteQR.objects.all()
|
|
575
|
+
|
|
576
|
+
admin = _create_admin_dict(request)
|
|
577
|
+
docker_install = settings.DOCKER_INSTALL
|
|
578
|
+
|
|
579
|
+
# Render list page with the documents and the form
|
|
580
|
+
return render(
|
|
581
|
+
request,
|
|
582
|
+
"remapp/dicomsummary.html",
|
|
583
|
+
{
|
|
584
|
+
"store": store,
|
|
585
|
+
"remoteqr": remoteqr,
|
|
586
|
+
"admin": admin,
|
|
587
|
+
"del_settings": del_settings,
|
|
588
|
+
"docker_install": docker_install,
|
|
589
|
+
},
|
|
590
|
+
)
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
class DicomStoreCreate(CreateView): # pylint: disable=unused-variable
|
|
594
|
+
"""CreateView to add details of a DICOM Store to the database"""
|
|
595
|
+
|
|
596
|
+
model = DicomStoreSCP
|
|
597
|
+
form_class = DicomStoreForm
|
|
598
|
+
|
|
599
|
+
def get_context_data(self, **context):
|
|
600
|
+
context = super(DicomStoreCreate, self).get_context_data(**context)
|
|
601
|
+
admin = {"openremversion": __version__, "docsversion": __docs_version__}
|
|
602
|
+
for group in self.request.user.groups.all():
|
|
603
|
+
admin[group.name] = True
|
|
604
|
+
context["admin"] = admin
|
|
605
|
+
context["docker_install"] = settings.DOCKER_INSTALL
|
|
606
|
+
return context
|
|
607
|
+
|
|
608
|
+
|
|
609
|
+
class DicomStoreUpdate(UpdateView): # pylint: disable=unused-variable
|
|
610
|
+
"""UpdateView to update details of a DICOM store in the database"""
|
|
611
|
+
|
|
612
|
+
model = DicomStoreSCP
|
|
613
|
+
form_class = DicomStoreForm
|
|
614
|
+
|
|
615
|
+
def get_context_data(self, **context):
|
|
616
|
+
context = super(DicomStoreUpdate, self).get_context_data(**context)
|
|
617
|
+
admin = {"openremversion": __version__, "docsversion": __docs_version__}
|
|
618
|
+
for group in self.request.user.groups.all():
|
|
619
|
+
admin[group.name] = True
|
|
620
|
+
context["admin"] = admin
|
|
621
|
+
return context
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
class DicomStoreDelete(DeleteView): # pylint: disable=unused-variable
|
|
625
|
+
"""DeleteView to delete DICOM store information from the database"""
|
|
626
|
+
|
|
627
|
+
model = DicomStoreSCP
|
|
628
|
+
success_url = reverse_lazy("dicom_summary")
|
|
629
|
+
|
|
630
|
+
def get_context_data(self, **context):
|
|
631
|
+
context[self.context_object_name] = self.object
|
|
632
|
+
admin = {"openremversion": __version__, "docsversion": __docs_version__}
|
|
633
|
+
for group in self.request.user.groups.all():
|
|
634
|
+
admin[group.name] = True
|
|
635
|
+
context["admin"] = admin
|
|
636
|
+
return context
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
class DicomQRCreate(CreateView): # pylint: disable=unused-variable
|
|
640
|
+
"""CreateView to add details of a DICOM query-retrieve node"""
|
|
641
|
+
|
|
642
|
+
model = DicomRemoteQR
|
|
643
|
+
form_class = DicomQRForm
|
|
644
|
+
|
|
645
|
+
def get_context_data(self, **context):
|
|
646
|
+
context = super(DicomQRCreate, self).get_context_data(**context)
|
|
647
|
+
admin = {"openremversion": __version__, "docsversion": __docs_version__}
|
|
648
|
+
for group in self.request.user.groups.all():
|
|
649
|
+
admin[group.name] = True
|
|
650
|
+
context["admin"] = admin
|
|
651
|
+
return context
|
|
652
|
+
|
|
653
|
+
|
|
654
|
+
class DicomQRUpdate(UpdateView): # pylint: disable=unused-variable
|
|
655
|
+
"""UpdateView to update details of a DICOM query-retrieve node"""
|
|
656
|
+
|
|
657
|
+
model = DicomRemoteQR
|
|
658
|
+
form_class = DicomQRForm
|
|
659
|
+
|
|
660
|
+
def get_context_data(self, **context):
|
|
661
|
+
context = super(DicomQRUpdate, self).get_context_data(**context)
|
|
662
|
+
admin = {"openremversion": __version__, "docsversion": __docs_version__}
|
|
663
|
+
for group in self.request.user.groups.all():
|
|
664
|
+
admin[group.name] = True
|
|
665
|
+
context["admin"] = admin
|
|
666
|
+
return context
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
class DicomQRDelete(DeleteView): # pylint: disable=unused-variable
|
|
670
|
+
"""DeleteView to delete details of a DICOM query-retrieve node"""
|
|
671
|
+
|
|
672
|
+
model = DicomRemoteQR
|
|
673
|
+
success_url = reverse_lazy("dicom_summary")
|
|
674
|
+
|
|
675
|
+
def get_context_data(self, **context):
|
|
676
|
+
context[self.context_object_name] = self.object
|
|
677
|
+
admin = {"openremversion": __version__, "docsversion": __docs_version__}
|
|
678
|
+
for group in self.request.user.groups.all():
|
|
679
|
+
admin[group.name] = True
|
|
680
|
+
context["admin"] = admin
|
|
681
|
+
return context
|