endoreg-db 0.3.6__py3-none-any.whl → 0.3.8__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.
Files changed (351) hide show
  1. endoreg_db/admin.py +3 -3
  2. endoreg_db/apps.py +6 -6
  3. endoreg_db/data/__init__.py +67 -64
  4. endoreg_db/data/active_model/data.yaml +2 -2
  5. endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +167 -167
  6. endoreg_db/data/case_template/rule/01_patient-set-age.yaml +7 -7
  7. endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +8 -8
  8. endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +22 -22
  9. endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +18 -18
  10. endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +18 -18
  11. endoreg_db/data/case_template/rule/19_create_patient.yaml +16 -16
  12. endoreg_db/data/case_template/rule_type/base_types.yaml +35 -35
  13. endoreg_db/data/case_template/rule_value/.init +0 -0
  14. endoreg_db/data/case_template/rule_value_type/base_types.yaml +58 -58
  15. endoreg_db/data/case_template/template/base.yaml +7 -7
  16. endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +2 -2
  17. endoreg_db/data/case_template/tmp/_rule_value +13 -13
  18. endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -21
  19. endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +9 -9
  20. endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +6 -6
  21. endoreg_db/data/center/data.yaml +59 -59
  22. endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -144
  23. endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -48
  24. endoreg_db/data/disease/cardiovascular.yaml +37 -37
  25. endoreg_db/data/disease/hepatology.yaml +4 -4
  26. endoreg_db/data/disease/misc.yaml +5 -5
  27. endoreg_db/data/disease/renal.yaml +4 -4
  28. endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +5 -5
  29. endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +5 -5
  30. endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +40 -40
  31. endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +19 -19
  32. endoreg_db/data/distribution/date/patient.yaml +6 -6
  33. endoreg_db/data/distribution/multiple_categorical/.init +0 -0
  34. endoreg_db/data/distribution/numeric/.init +0 -0
  35. endoreg_db/data/distribution/single_categorical/patient.yaml +6 -6
  36. endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -132
  37. endoreg_db/data/endoscope_type/data.yaml +10 -10
  38. endoreg_db/data/endoscopy_processor/data.yaml +45 -45
  39. endoreg_db/data/event/cardiology.yaml +27 -27
  40. endoreg_db/data/event/neurology.yaml +13 -13
  41. endoreg_db/data/event/surgery.yaml +12 -12
  42. endoreg_db/data/event/thrombembolism.yaml +19 -19
  43. endoreg_db/data/examination/examinations/data.yaml +65 -65
  44. endoreg_db/data/examination/time/data.yaml +47 -47
  45. endoreg_db/data/examination/time-type/data.yaml +7 -7
  46. endoreg_db/data/examination/type/data.yaml +5 -5
  47. endoreg_db/data/gender/data.yaml +18 -18
  48. endoreg_db/data/information_source/data.yaml +30 -30
  49. endoreg_db/data/information_source/medication.yaml +5 -5
  50. endoreg_db/data/lab_value/cardiac_enzymes.yaml +30 -30
  51. endoreg_db/data/lab_value/coagulation.yaml +48 -48
  52. endoreg_db/data/lab_value/electrolytes.yaml +189 -189
  53. endoreg_db/data/lab_value/gastrointestinal_function.yaml +121 -121
  54. endoreg_db/data/lab_value/hematology.yaml +169 -169
  55. endoreg_db/data/lab_value/hormones.yaml +53 -53
  56. endoreg_db/data/lab_value/lipids.yaml +44 -44
  57. endoreg_db/data/lab_value/misc.yaml +30 -30
  58. endoreg_db/data/lab_value/renal_function.yaml +10 -10
  59. endoreg_db/data/label/label/data.yaml +62 -62
  60. endoreg_db/data/label/label-set/data.yaml +17 -17
  61. endoreg_db/data/label/label-type/data.yaml +6 -6
  62. endoreg_db/data/medication/anticoagulation.yaml +64 -64
  63. endoreg_db/data/medication/tah.yaml +69 -69
  64. endoreg_db/data/medication_indication/anticoagulation.yaml +120 -120
  65. endoreg_db/data/medication_indication_type/data.yaml +10 -10
  66. endoreg_db/data/medication_indication_type/thrombembolism.yaml +40 -40
  67. endoreg_db/data/medication_intake_time/base.yaml +30 -30
  68. endoreg_db/data/medication_schedule/apixaban.yaml +94 -94
  69. endoreg_db/data/medication_schedule/ass.yaml +12 -12
  70. endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -26
  71. endoreg_db/data/model_type/data.yaml +6 -6
  72. endoreg_db/data/network_device/data.yaml +17 -0
  73. endoreg_db/data/network_device_type/data.yaml +8 -0
  74. endoreg_db/data/patient_lab_sample_type/generic.yaml +5 -5
  75. endoreg_db/data/pdf_type/data.yaml +28 -28
  76. endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -66
  77. endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -33
  78. endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -308
  79. endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -88
  80. endoreg_db/data/profession/data.yaml +70 -70
  81. endoreg_db/data/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +55 -55
  82. endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +26 -26
  83. endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +19 -19
  84. endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -15
  85. endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -12
  86. endoreg_db/data/unit/concentration.yaml +92 -92
  87. endoreg_db/data/unit/data.yaml +17 -17
  88. endoreg_db/data/unit/length.yaml +30 -30
  89. endoreg_db/data/unit/misc.yaml +19 -19
  90. endoreg_db/data/unit/rate.yaml +5 -5
  91. endoreg_db/data/unit/time.yaml +12 -12
  92. endoreg_db/data/unit/volume.yaml +35 -35
  93. endoreg_db/data/unit/weight.yaml +37 -37
  94. endoreg_db/data/waste/data.yaml +11 -11
  95. endoreg_db/forms/__init__.py +2 -2
  96. endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -23
  97. endoreg_db/forms/settings/__init__.py +8 -8
  98. endoreg_db/forms/unit.py +5 -5
  99. endoreg_db/management/commands/_load_model_template.py +40 -40
  100. endoreg_db/management/commands/delete_all.py +18 -18
  101. endoreg_db/management/commands/delete_legacy_images.py +19 -19
  102. endoreg_db/management/commands/delete_legacy_videos.py +16 -16
  103. endoreg_db/management/commands/extract_legacy_video_frames.py +18 -18
  104. endoreg_db/management/commands/fetch_legacy_image_dataset.py +32 -32
  105. endoreg_db/management/commands/fix_auth_permission.py +20 -20
  106. endoreg_db/management/commands/import_legacy_images.py +94 -94
  107. endoreg_db/management/commands/import_legacy_videos.py +76 -76
  108. endoreg_db/management/commands/load_active_model_data.py +44 -44
  109. endoreg_db/management/commands/load_ai_model_data.py +44 -44
  110. endoreg_db/management/commands/load_base_db_data.py +132 -128
  111. endoreg_db/management/commands/load_center_data.py +42 -42
  112. endoreg_db/management/commands/load_disease_classification_choices_data.py +40 -40
  113. endoreg_db/management/commands/load_disease_classification_data.py +40 -40
  114. endoreg_db/management/commands/load_disease_data.py +39 -39
  115. endoreg_db/management/commands/load_distribution_data.py +65 -65
  116. endoreg_db/management/commands/load_endoscope_type_data.py +44 -44
  117. endoreg_db/management/commands/load_endoscopy_processor_data.py +44 -44
  118. endoreg_db/management/commands/load_event_data.py +40 -40
  119. endoreg_db/management/commands/load_examination_data.py +74 -74
  120. endoreg_db/management/commands/load_g_play_data.py +112 -112
  121. endoreg_db/management/commands/load_gender_data.py +43 -43
  122. endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +132 -132
  123. endoreg_db/management/commands/load_information_source.py +44 -44
  124. endoreg_db/management/commands/load_lab_value_data.py +49 -49
  125. endoreg_db/management/commands/load_label_data.py +66 -66
  126. endoreg_db/management/commands/load_medication_data.py +40 -40
  127. endoreg_db/management/commands/load_medication_indication_data.py +62 -62
  128. endoreg_db/management/commands/load_medication_indication_type_data.py +40 -40
  129. endoreg_db/management/commands/load_medication_intake_time_data.py +40 -40
  130. endoreg_db/management/commands/load_medication_schedule_data.py +54 -54
  131. endoreg_db/management/commands/load_network_data.py +49 -0
  132. endoreg_db/management/commands/load_pdf_type_data.py +60 -60
  133. endoreg_db/management/commands/load_profession_data.py +43 -43
  134. endoreg_db/management/commands/load_report_reader_flag.py +45 -45
  135. endoreg_db/management/commands/load_unit_data.py +45 -45
  136. endoreg_db/management/commands/load_user_groups.py +28 -28
  137. endoreg_db/management/commands/register_ai_model.py +65 -65
  138. endoreg_db/management/commands/reset_celery_schedule.py +9 -9
  139. endoreg_db/migrations/0001_initial.py +582 -582
  140. endoreg_db/migrations/0002_rawvideofile.py +26 -26
  141. endoreg_db/migrations/0003_rawvideofile_frames_required.py +18 -18
  142. endoreg_db/migrations/0004_rename_hash_rawvideofile_video_hash.py +18 -18
  143. endoreg_db/migrations/0005_ffmpegmeta_remove_videoimportmeta_center_and_more.py +56 -56
  144. endoreg_db/migrations/0006_rawvideofile_center_alter_videometa_processor.py +25 -25
  145. endoreg_db/migrations/0007_rawvideofile_processor.py +19 -19
  146. endoreg_db/migrations/0008_rename_frames_required_rawvideofile_state_frames_required.py +18 -18
  147. endoreg_db/migrations/0009_sensitivemeta_rawvideofile_sensitive_meta.py +31 -31
  148. endoreg_db/migrations/0010_rename_endoscope_serial_number_sensitivemeta_endoscope_sn.py +18 -18
  149. endoreg_db/migrations/0011_rawvideofile_state_sensitive_data_retrieved.py +18 -18
  150. endoreg_db/migrations/0012_rawvideofile_prediction_dir_and_more.py +109 -109
  151. endoreg_db/migrations/0013_rawpdffile.py +31 -31
  152. endoreg_db/migrations/0014_pdftype_alter_rawpdffile_file_pdfmeta.py +38 -38
  153. endoreg_db/migrations/0015_rename_report_processed_rawpdffile_state_report_processed_and_more.py +31 -31
  154. endoreg_db/migrations/0016_rawpdffile_state_report_processing_required.py +18 -18
  155. endoreg_db/migrations/0017_firstname_lastname_center_first_names_and_more.py +37 -37
  156. endoreg_db/migrations/0018_reportreaderflag_reportreaderconfig.py +37 -37
  157. endoreg_db/migrations/0019_pdftype_cut_off_above_lines_and_more.py +42 -42
  158. endoreg_db/migrations/0020_rename_endoscopy_info_line_pdftype_endoscope_info_line.py +18 -18
  159. endoreg_db/migrations/0021_alter_pdftype_endoscope_info_line.py +19 -19
  160. endoreg_db/migrations/0022_alter_pdftype_endoscope_info_line.py +19 -19
  161. endoreg_db/migrations/0023_ttoquestionnaire_alter_pdftype_endoscope_info_line.py +59 -59
  162. endoreg_db/migrations/0024_remove_ttoquestionnaire_infections_and_more.py +27 -27
  163. endoreg_db/migrations/0025_event_alter_rawpdffile_file_patientevent.py +42 -42
  164. endoreg_db/migrations/0026_disease_diseaseclassification_and_more.py +166 -166
  165. endoreg_db/migrations/0027_labvalue_abbreviation_labvalue_default_normal_range_and_more.py +38 -38
  166. endoreg_db/migrations/0028_alter_unit_abbreviation.py +18 -18
  167. endoreg_db/migrations/0029_medicationintaketime_and_more.py +75 -75
  168. endoreg_db/migrations/0030_medicationindicationtype_and_more.py +101 -101
  169. endoreg_db/migrations/0031_rename_adapt_to_liver_function_medication_adapt_to_age_and_more.py +38 -38
  170. endoreg_db/migrations/0032_alter_medicationschedule_therapy_duration_d.py +18 -18
  171. endoreg_db/migrations/0033_medicationindication_sources.py +18 -18
  172. endoreg_db/migrations/0034_alter_rawpdffile_file.py +20 -20
  173. endoreg_db/migrations/0035_alter_medicationindication_sources.py +18 -18
  174. endoreg_db/migrations/0036_alter_rawpdffile_file.py +20 -20
  175. endoreg_db/migrations/0037_alter_medicationindication_sources.py +18 -18
  176. endoreg_db/migrations/0038_emissionfactor_material_product_productgroup_and_more.py +164 -164
  177. endoreg_db/migrations/0039_referenceproduct_name.py +19 -19
  178. endoreg_db/migrations/0040_quizanswertype_quizquestiontype_quizquestion_and_more.py +50 -50
  179. endoreg_db/migrations/0041_gender_patientmedication_medication_indication_and_more.py +40 -40
  180. endoreg_db/migrations/0042_casetemplateruletype_casetemplaterulevalue_and_more.py +74 -74
  181. endoreg_db/migrations/0043_casetemplatetype_name_de_casetemplatetype_name_en.py +23 -23
  182. endoreg_db/migrations/0044_casetemplateruletype_name_de_and_more.py +23 -23
  183. endoreg_db/migrations/0045_casetemplaterulevalue_value_type.py +19 -19
  184. endoreg_db/migrations/0046_casetemplaterulevalue_target_field.py +18 -18
  185. endoreg_db/migrations/0047_casetemplaterule_target_model.py +18 -18
  186. endoreg_db/migrations/0048_remove_casetemplaterule_chained_rules_and_more.py +22 -22
  187. endoreg_db/migrations/0049_remove_casetemplaterule_rule_values.py +17 -17
  188. endoreg_db/migrations/0050_casetemplaterule_rule_values.py +18 -18
  189. endoreg_db/migrations/0051_remove_casetemplaterule_calling_rules_and_more.py +27 -27
  190. endoreg_db/migrations/0052_rename_case_template_type_casetemplate_template_type.py +18 -18
  191. endoreg_db/migrations/0053_patientlabsampletype_patientlabsample_and_more.py +38 -38
  192. endoreg_db/migrations/0054_multiplecategoricalvaluedistribution_and_more.py +69 -69
  193. endoreg_db/migrations/0055_remove_casetemplaterule_rule_values_and_more.py +59 -59
  194. endoreg_db/migrations/0056_datevaluedistribution_and_more.py +32 -32
  195. endoreg_db/migrations/0057_remove_datevaluedistribution_max_date_and_more.py +72 -72
  196. endoreg_db/migrations/0058_datevaluedistribution_description_and_more.py +28 -28
  197. endoreg_db/migrations/0059_casetemplaterule_rule_values.py +18 -18
  198. endoreg_db/migrations/0060_labvalue__default_date_value_distribution_and_more.py +44 -44
  199. endoreg_db/migrations/0061_remove_patientlabvalue_date_patientlabvalue_datetime.py +24 -24
  200. endoreg_db/migrations/0062_labvalue_numeric_precision.py +18 -18
  201. endoreg_db/migrations/0063_alter_labvalue_numeric_precision.py +18 -18
  202. endoreg_db/migrations/0064_casetemplaterule_extra_parameters_and_more.py +23 -23
  203. endoreg_db/migrations/0065_rename__date_value_distribution_casetemplaterule_date_value_distribution_and_more.py +58 -58
  204. endoreg_db/migrations/0066_alter_patientlabvalue_patient_and_more.py +29 -29
  205. endoreg_db/migrations/0067_alter_medicationindication_indication_type.py +19 -19
  206. endoreg_db/migrations/0068_networkdevicetype_networkdevicetypemanager_and_more.py +57 -0
  207. endoreg_db/models/__init__.py +75 -74
  208. endoreg_db/models/ai_model/__init__.py +3 -3
  209. endoreg_db/models/ai_model/active_model.py +9 -9
  210. endoreg_db/models/ai_model/model_meta.py +24 -24
  211. endoreg_db/models/ai_model/model_type.py +25 -25
  212. endoreg_db/models/ai_model/utils.py +8 -8
  213. endoreg_db/models/annotation/__init__.py +1 -1
  214. endoreg_db/models/annotation/binary_classification_annotation_task.py +80 -80
  215. endoreg_db/models/annotation/image_classification.py +26 -26
  216. endoreg_db/models/case_template/__init__.py +5 -5
  217. endoreg_db/models/case_template/case_template.py +81 -81
  218. endoreg_db/models/case_template/case_template_rule.py +276 -276
  219. endoreg_db/models/case_template/case_template_rule_value.py +73 -73
  220. endoreg_db/models/case_template/case_template_type.py +27 -27
  221. endoreg_db/models/center/__init__.py +4 -4
  222. endoreg_db/models/center/center.py +24 -24
  223. endoreg_db/models/center/center_product.py +33 -33
  224. endoreg_db/models/center/center_resource.py +18 -18
  225. endoreg_db/models/center/center_waste.py +10 -10
  226. endoreg_db/models/data_file/__init__.py +5 -5
  227. endoreg_db/models/data_file/base_classes/__init__.py +2 -2
  228. endoreg_db/models/data_file/base_classes/abstract_frame.py +50 -50
  229. endoreg_db/models/data_file/base_classes/abstract_video.py +200 -200
  230. endoreg_db/models/data_file/frame.py +45 -45
  231. endoreg_db/models/data_file/import_classes/__init__.py +31 -31
  232. endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +34 -34
  233. endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +28 -28
  234. endoreg_db/models/data_file/import_classes/processing_functions/video.py +260 -260
  235. endoreg_db/models/data_file/import_classes/raw_pdf.py +188 -188
  236. endoreg_db/models/data_file/import_classes/raw_video.py +343 -343
  237. endoreg_db/models/data_file/metadata/__init__.py +3 -3
  238. endoreg_db/models/data_file/metadata/pdf_meta.py +70 -70
  239. endoreg_db/models/data_file/metadata/sensitive_meta.py +31 -31
  240. endoreg_db/models/data_file/metadata/video_meta.py +132 -132
  241. endoreg_db/models/data_file/report_file.py +89 -89
  242. endoreg_db/models/data_file/video/__init__.py +6 -6
  243. endoreg_db/models/data_file/video/import_meta.py +25 -25
  244. endoreg_db/models/data_file/video/video.py +25 -25
  245. endoreg_db/models/data_file/video_segment.py +107 -107
  246. endoreg_db/models/disease.py +55 -55
  247. endoreg_db/models/emission/emission_factor.py +19 -19
  248. endoreg_db/models/event.py +21 -21
  249. endoreg_db/models/examination/__init__.py +3 -3
  250. endoreg_db/models/examination/examination.py +26 -26
  251. endoreg_db/models/examination/examination_time.py +27 -27
  252. endoreg_db/models/examination/examination_time_type.py +24 -24
  253. endoreg_db/models/examination/examination_type.py +18 -18
  254. endoreg_db/models/hardware/__init__.py +1 -1
  255. endoreg_db/models/hardware/endoscope.py +44 -44
  256. endoreg_db/models/hardware/endoscopy_processor.py +143 -143
  257. endoreg_db/models/information_source.py +29 -29
  258. endoreg_db/models/label/label.py +84 -84
  259. endoreg_db/models/laboratory/lab_value.py +102 -102
  260. endoreg_db/models/legacy_data/__init__.py +3 -3
  261. endoreg_db/models/legacy_data/image.py +34 -34
  262. endoreg_db/models/medication/medication.py +148 -148
  263. endoreg_db/models/network/__init__.py +2 -0
  264. endoreg_db/models/network/network_device.py +27 -0
  265. endoreg_db/models/network/network_device_type.py +23 -0
  266. endoreg_db/models/other/__init__.py +4 -4
  267. endoreg_db/models/other/distribution.py +215 -215
  268. endoreg_db/models/other/material.py +16 -16
  269. endoreg_db/models/other/resource.py +17 -17
  270. endoreg_db/models/other/transport_route.py +20 -20
  271. endoreg_db/models/other/waste.py +20 -20
  272. endoreg_db/models/patient_examination/__init__.py +35 -35
  273. endoreg_db/models/permissions/__init__.py +44 -44
  274. endoreg_db/models/persons/__init__.py +6 -6
  275. endoreg_db/models/persons/examiner/__init__.py +1 -1
  276. endoreg_db/models/persons/examiner/examiner.py +15 -15
  277. endoreg_db/models/persons/examiner/examiner_type.py +1 -1
  278. endoreg_db/models/persons/first_name.py +17 -17
  279. endoreg_db/models/persons/gender.py +22 -22
  280. endoreg_db/models/persons/last_name.py +19 -19
  281. endoreg_db/models/persons/patient/__init__.py +7 -7
  282. endoreg_db/models/persons/patient/case/case.py +30 -30
  283. endoreg_db/models/persons/patient/patient.py +216 -216
  284. endoreg_db/models/persons/patient/patient_disease.py +16 -16
  285. endoreg_db/models/persons/patient/patient_event.py +22 -22
  286. endoreg_db/models/persons/patient/patient_lab_sample.py +106 -106
  287. endoreg_db/models/persons/patient/patient_lab_value.py +176 -176
  288. endoreg_db/models/persons/patient/patient_medication.py +43 -43
  289. endoreg_db/models/persons/patient/patient_medication_schedule.py +27 -27
  290. endoreg_db/models/persons/person.py +31 -31
  291. endoreg_db/models/persons/portal_user_information.py +27 -27
  292. endoreg_db/models/prediction/__init__.py +1 -1
  293. endoreg_db/models/prediction/image_classification.py +37 -37
  294. endoreg_db/models/prediction/video_prediction_meta.py +244 -244
  295. endoreg_db/models/product/__init__.py +4 -4
  296. endoreg_db/models/product/product.py +97 -97
  297. endoreg_db/models/product/product_group.py +19 -19
  298. endoreg_db/models/product/product_material.py +24 -24
  299. endoreg_db/models/product/product_weight.py +26 -26
  300. endoreg_db/models/product/reference_product.py +99 -99
  301. endoreg_db/models/questionnaires/__init__.py +114 -114
  302. endoreg_db/models/quiz/__init__.py +1 -1
  303. endoreg_db/models/quiz/quiz_answer.py +41 -41
  304. endoreg_db/models/quiz/quiz_question.py +54 -54
  305. endoreg_db/models/report_reader/__init__.py +1 -1
  306. endoreg_db/models/report_reader/report_reader_config.py +53 -53
  307. endoreg_db/models/report_reader/report_reader_flag.py +19 -19
  308. endoreg_db/models/rules/__init__.py +4 -4
  309. endoreg_db/models/rules/rule.py +23 -23
  310. endoreg_db/models/rules/rule_applicator.py +224 -224
  311. endoreg_db/models/rules/rule_attribute_dtype.py +18 -18
  312. endoreg_db/models/rules/rule_type.py +21 -21
  313. endoreg_db/models/rules/ruleset.py +19 -19
  314. endoreg_db/models/unit.py +21 -21
  315. endoreg_db/queries/__init__.py +4 -4
  316. endoreg_db/queries/annotations/__init__.py +2 -2
  317. endoreg_db/queries/annotations/legacy.py +159 -159
  318. endoreg_db/queries/get/__init__.py +5 -5
  319. endoreg_db/queries/get/center.py +42 -42
  320. endoreg_db/queries/get/model.py +13 -13
  321. endoreg_db/queries/get/patient.py +14 -14
  322. endoreg_db/queries/get/patient_examination.py +20 -20
  323. endoreg_db/queries/get/report_file.py +33 -33
  324. endoreg_db/queries/get/video.py +31 -31
  325. endoreg_db/serializers/__init__.py +9 -9
  326. endoreg_db/serializers/ai_model.py +18 -18
  327. endoreg_db/serializers/annotation.py +17 -17
  328. endoreg_db/serializers/center.py +11 -11
  329. endoreg_db/serializers/examination.py +32 -32
  330. endoreg_db/serializers/frame.py +13 -13
  331. endoreg_db/serializers/hardware.py +20 -20
  332. endoreg_db/serializers/label.py +22 -22
  333. endoreg_db/serializers/patient.py +10 -10
  334. endoreg_db/serializers/prediction.py +15 -15
  335. endoreg_db/serializers/report_file.py +7 -7
  336. endoreg_db/serializers/video.py +27 -27
  337. endoreg_db/tests.py +3 -3
  338. endoreg_db/utils/cropping.py +28 -28
  339. endoreg_db/utils/dataloader.py +92 -92
  340. endoreg_db/utils/file_operations.py +30 -30
  341. endoreg_db/utils/hashs.py +33 -33
  342. endoreg_db/utils/legacy_ocr.py +201 -201
  343. endoreg_db/utils/ocr.py +197 -197
  344. endoreg_db/utils/uuid.py +4 -4
  345. endoreg_db/utils/video_metadata.py +87 -87
  346. endoreg_db/views.py +3 -3
  347. {endoreg_db-0.3.6.dist-info → endoreg_db-0.3.8.dist-info}/LICENSE +674 -674
  348. {endoreg_db-0.3.6.dist-info → endoreg_db-0.3.8.dist-info}/METADATA +3 -1
  349. endoreg_db-0.3.8.dist-info/RECORD +367 -0
  350. {endoreg_db-0.3.6.dist-info → endoreg_db-0.3.8.dist-info}/WHEEL +1 -1
  351. endoreg_db-0.3.6.dist-info/RECORD +0 -357
@@ -1,3 +1,3 @@
1
- from .sensitive_meta import SensitiveMeta
2
- from .pdf_meta import PdfMeta, PdfType
3
- from .video_meta import VideoMeta, FFMpegMeta, VideoImportMeta
1
+ from .sensitive_meta import SensitiveMeta
2
+ from .pdf_meta import PdfMeta, PdfType
3
+ from .video_meta import VideoMeta, FFMpegMeta, VideoImportMeta
@@ -1,70 +1,70 @@
1
- from django.db import models
2
-
3
- # import endoreg_center_id from django settings
4
- from django.conf import settings
5
-
6
-
7
- # import File class
8
- from django.core.files import File
9
-
10
- # # check if endoreg_center_id is set
11
- # if not hasattr(settings, 'ENDOREG_CENTER_ID'):
12
- # ENDOREG_CENTER_ID = 9999
13
- # else:
14
- # ENDOREG_CENTER_ID = settings.ENDOREG_CENTER_ID
15
-
16
- class PdfType(models.Model):
17
- name = models.CharField(max_length=255)
18
-
19
- patient_info_line = models.ForeignKey(
20
- "ReportReaderFlag",
21
- related_name="pdf_type_patient_info_line",
22
- on_delete=models.CASCADE
23
- )
24
- endoscope_info_line = models.ForeignKey(
25
- "ReportReaderFlag",
26
- related_name="pdf_type_endoscopy_info_line",
27
- on_delete=models.CASCADE,
28
- )
29
- examiner_info_line = models.ForeignKey(
30
- "ReportReaderFlag",
31
- related_name="pdf_type_examiner_info_line",
32
- on_delete=models.CASCADE
33
- )
34
- cut_off_above_lines = models.ManyToManyField(
35
- "ReportReaderFlag",
36
- related_name="pdf_type_cut_off_above_lines",
37
- )
38
- cut_off_below_lines = models.ManyToManyField(
39
- "ReportReaderFlag",
40
- related_name="pdf_type_cut_off_below_lines",
41
- )
42
-
43
-
44
- def __str__(self):
45
- summary = f"{self.name}"
46
- # add lines to summary
47
- summary += f"\nPatient Info Line: {self.patient_info_line.value}"
48
- summary += f"\nEndoscope Info Line: {self.endoscope_info_line.value}"
49
- summary += f"\nExaminer Info Line: {self.examiner_info_line.value}"
50
- summary += f"\nCut Off Above Lines: {[_.value for _ in self.cut_off_above_lines.all()]}"
51
- summary += f"\nCut Off Below Lines: {[_.value for _ in self.cut_off_below_lines.all()]}"
52
-
53
- return summary
54
-
55
- class PdfMeta(models.Model):
56
- pdf_type = models.ForeignKey(PdfType, on_delete=models.CASCADE)
57
- date = models.DateField()
58
- time = models.TimeField()
59
- pdf_hash = models.CharField(max_length=255, unique=True)
60
-
61
- def __str__(self):
62
- return self.pdf_hash
63
-
64
- @classmethod
65
- def create_from_file(cls, pdf_file):
66
- pdf_file = File(pdf_file)
67
- pdf_meta = cls(file=pdf_file)
68
- pdf_meta.save()
69
- return pdf_meta
70
-
1
+ from django.db import models
2
+
3
+ # import endoreg_center_id from django settings
4
+ from django.conf import settings
5
+
6
+
7
+ # import File class
8
+ from django.core.files import File
9
+
10
+ # # check if endoreg_center_id is set
11
+ # if not hasattr(settings, 'ENDOREG_CENTER_ID'):
12
+ # ENDOREG_CENTER_ID = 9999
13
+ # else:
14
+ # ENDOREG_CENTER_ID = settings.ENDOREG_CENTER_ID
15
+
16
+ class PdfType(models.Model):
17
+ name = models.CharField(max_length=255)
18
+
19
+ patient_info_line = models.ForeignKey(
20
+ "ReportReaderFlag",
21
+ related_name="pdf_type_patient_info_line",
22
+ on_delete=models.CASCADE
23
+ )
24
+ endoscope_info_line = models.ForeignKey(
25
+ "ReportReaderFlag",
26
+ related_name="pdf_type_endoscopy_info_line",
27
+ on_delete=models.CASCADE,
28
+ )
29
+ examiner_info_line = models.ForeignKey(
30
+ "ReportReaderFlag",
31
+ related_name="pdf_type_examiner_info_line",
32
+ on_delete=models.CASCADE
33
+ )
34
+ cut_off_above_lines = models.ManyToManyField(
35
+ "ReportReaderFlag",
36
+ related_name="pdf_type_cut_off_above_lines",
37
+ )
38
+ cut_off_below_lines = models.ManyToManyField(
39
+ "ReportReaderFlag",
40
+ related_name="pdf_type_cut_off_below_lines",
41
+ )
42
+
43
+
44
+ def __str__(self):
45
+ summary = f"{self.name}"
46
+ # add lines to summary
47
+ summary += f"\nPatient Info Line: {self.patient_info_line.value}"
48
+ summary += f"\nEndoscope Info Line: {self.endoscope_info_line.value}"
49
+ summary += f"\nExaminer Info Line: {self.examiner_info_line.value}"
50
+ summary += f"\nCut Off Above Lines: {[_.value for _ in self.cut_off_above_lines.all()]}"
51
+ summary += f"\nCut Off Below Lines: {[_.value for _ in self.cut_off_below_lines.all()]}"
52
+
53
+ return summary
54
+
55
+ class PdfMeta(models.Model):
56
+ pdf_type = models.ForeignKey(PdfType, on_delete=models.CASCADE)
57
+ date = models.DateField()
58
+ time = models.TimeField()
59
+ pdf_hash = models.CharField(max_length=255, unique=True)
60
+
61
+ def __str__(self):
62
+ return self.pdf_hash
63
+
64
+ @classmethod
65
+ def create_from_file(cls, pdf_file):
66
+ pdf_file = File(pdf_file)
67
+ pdf_meta = cls(file=pdf_file)
68
+ pdf_meta.save()
69
+ return pdf_meta
70
+
@@ -1,31 +1,31 @@
1
- from django.db import models
2
-
3
- class SensitiveMeta(models.Model):
4
- examination_date = models.DateField(blank=True, null=True)
5
- patient_first_name = models.CharField(max_length=255, blank=True, null=True)
6
- patient_last_name = models.CharField(max_length=255, blank=True, null=True)
7
- patient_dob = models.DateField(blank=True, null=True)
8
- endoscope_type = models.CharField(max_length=255, blank=True, null=True)
9
- endoscope_sn = models.CharField(max_length=255, blank=True, null=True)
10
-
11
- @classmethod
12
- def create_from_dict(cls, data: dict):
13
- # data can contain more fields than the model has
14
- field_names = [_.name for _ in cls._meta.fields]
15
- selected_data = {k: v for k, v in data.items() if k in field_names}
16
-
17
- return cls.objects.create(**selected_data)
18
-
19
- def update_from_dict(self, data: dict):
20
- # data can contain more fields than the model has
21
- field_names = [_.name for _ in self._meta.fields]
22
- selected_data = {k: v for k, v in data.items() if k in field_names}
23
-
24
- for k, v in selected_data.items():
25
- setattr(self, k, v)
26
-
27
- self.save()
28
-
29
- def __str__(self):
30
- return f"SensitiveMeta: {self.examination_date} {self.patient_first_name} {self.patient_last_name} (*{self.patient_dob})"
31
-
1
+ from django.db import models
2
+
3
+ class SensitiveMeta(models.Model):
4
+ examination_date = models.DateField(blank=True, null=True)
5
+ patient_first_name = models.CharField(max_length=255, blank=True, null=True)
6
+ patient_last_name = models.CharField(max_length=255, blank=True, null=True)
7
+ patient_dob = models.DateField(blank=True, null=True)
8
+ endoscope_type = models.CharField(max_length=255, blank=True, null=True)
9
+ endoscope_sn = models.CharField(max_length=255, blank=True, null=True)
10
+
11
+ @classmethod
12
+ def create_from_dict(cls, data: dict):
13
+ # data can contain more fields than the model has
14
+ field_names = [_.name for _ in cls._meta.fields]
15
+ selected_data = {k: v for k, v in data.items() if k in field_names}
16
+
17
+ return cls.objects.create(**selected_data)
18
+
19
+ def update_from_dict(self, data: dict):
20
+ # data can contain more fields than the model has
21
+ field_names = [_.name for _ in self._meta.fields]
22
+ selected_data = {k: v for k, v in data.items() if k in field_names}
23
+
24
+ for k, v in selected_data.items():
25
+ setattr(self, k, v)
26
+
27
+ self.save()
28
+
29
+ def __str__(self):
30
+ return f"SensitiveMeta: {self.examination_date} {self.patient_first_name} {self.patient_last_name} (*{self.patient_dob})"
31
+
@@ -1,133 +1,133 @@
1
- from django.db import models
2
- import ffmpeg
3
- from pathlib import Path
4
-
5
- # import endoreg_center_id from django settings
6
- from django.conf import settings
7
-
8
- # check if endoreg_center_id is set
9
- if not hasattr(settings, 'ENDOREG_CENTER_ID'):
10
- ENDOREG_CENTER_ID = 9999
11
- else:
12
- ENDOREG_CENTER_ID = settings.ENDOREG_CENTER_ID
13
-
14
- # VideoMeta
15
- class VideoMeta(models.Model):
16
- processor = models.ForeignKey('EndoscopyProcessor', on_delete=models.CASCADE, blank=True, null=True)
17
- endoscope = models.ForeignKey('Endoscope', on_delete=models.CASCADE, blank=True, null=True)
18
- center = models.ForeignKey('Center', on_delete=models.CASCADE)
19
- import_meta = models.OneToOneField('VideoImportMeta', on_delete=models.CASCADE, blank=True, null=True)
20
- ffmpeg_meta = models.OneToOneField('FFMpegMeta', on_delete=models.CASCADE, blank=True, null=True)
21
-
22
- def __str__(self):
23
-
24
- processor_name = self.processor.name if self.processor is not None else "None"
25
- endoscope_name = self.endoscope.name if self.endoscope is not None else "None"
26
- center_name = self.center.name if self.center is not None else "None"
27
-
28
- result_html = ""
29
-
30
- result_html += f"Processor: {processor_name}<br>"
31
- result_html += f"Endoscope: {endoscope_name}<br>"
32
- result_html += f"Center: {center_name}<br>"
33
-
34
- return result_html
35
-
36
- # import meta should be created when video meta is created
37
- def save(self, *args, **kwargs):
38
- if self.import_meta is None:
39
- self.import_meta = VideoImportMeta.objects.create()
40
- super(VideoMeta, self).save(*args, **kwargs)
41
-
42
- def initialize_ffmpeg_meta(self, file_path):
43
- """Initializes FFMpeg metadata for the video file if not already done."""
44
- self.ffmpeg_meta = FFMpegMeta.create_from_file(Path(file_path))
45
- self.save()
46
-
47
- def update_meta(self, file_path):
48
- """Updates the video metadata from the file."""
49
- self.initialize_ffmpeg_meta(file_path)
50
- self.save()
51
-
52
- def get_endo_roi(self):
53
- endo_roi = self.processor.get_roi_endoscope_image()
54
- return endo_roi
55
-
56
- def get_fps(self):
57
- if not self.ffmpeg_meta:
58
- return None
59
-
60
- return self.ffmpeg_meta.frame_rate
61
-
62
-
63
- class FFMpegMeta(models.Model):
64
- # Existing fields
65
- duration = models.FloatField(blank=True, null=True)
66
- width = models.IntegerField(blank=True, null=True)
67
- height = models.IntegerField(blank=True, null=True)
68
- frame_rate = models.FloatField(blank=True, null=True)
69
-
70
- # New fields for comprehensive information
71
- video_codec = models.CharField(max_length=50, blank=True, null=True)
72
- audio_codec = models.CharField(max_length=50, blank=True, null=True)
73
- audio_channels = models.IntegerField(blank=True, null=True)
74
- audio_sample_rate = models.IntegerField(blank=True, null=True)
75
-
76
- # Existing __str__ method can be updated to include new fields
77
-
78
- @classmethod
79
- def create_from_file(cls, file_path: Path):
80
- """Creates an FFMpegMeta instance from a video file using ffmpeg probe."""
81
- try:
82
- probe = ffmpeg.probe(file_path.resolve().as_posix())
83
- except: # ffmpeg.Error as e:
84
- # print(e.stderr)
85
- print(f"Error while probing {file_path}")
86
- return None
87
-
88
- video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
89
- audio_streams = [stream for stream in probe['streams'] if stream['codec_type'] == 'audio']
90
-
91
- # Check for the existence of a video stream
92
- if video_stream is None:
93
- print(f"No video stream found in {file_path}")
94
- return None
95
-
96
- # Extract and store video metadata
97
- metadata = {
98
- 'duration': float(video_stream.get('duration', 0)),
99
- 'width': int(video_stream.get('width', 0)),
100
- 'height': int(video_stream.get('height', 0)),
101
- 'frame_rate': float(next(iter(video_stream.get('avg_frame_rate', '').split('/')), 0)),
102
- 'video_codec': video_stream.get('codec_name', ''),
103
- }
104
-
105
- # If there are audio streams, extract and store audio metadata from the first stream
106
- if audio_streams:
107
- first_audio_stream = audio_streams[0]
108
- metadata.update({
109
- 'audio_codec': first_audio_stream.get('codec_name', ''),
110
- 'audio_channels': int(first_audio_stream.get('channels', 0)),
111
- 'audio_sample_rate': int(first_audio_stream.get('sample_rate', 0)),
112
- })
113
-
114
- # Create and return the FFMpegMeta instance
115
- return cls.objects.create(**metadata)
116
-
117
- class VideoImportMeta(models.Model):
118
-
119
- video_anonymized = models.BooleanField(default=False)
120
- video_patient_data_detected = models.BooleanField(default=False)
121
- outside_detected = models.BooleanField(default=False)
122
- patient_data_removed = models.BooleanField(default=False)
123
- outside_removed = models.BooleanField(default=False)
124
-
125
- def __str__(self):
126
- result_html = ""
127
-
128
- result_html += f"Video anonymized: {self.video_anonymized}<br>"
129
- result_html += f"Video patient data detected: {self.video_patient_data_detected}<br>"
130
- result_html += f"Outside detected: {self.outside_detected}<br>"
131
- result_html += f"Patient data removed: {self.patient_data_removed}<br>"
132
- result_html += f"Outside removed: {self.outside_removed}<br>"
1
+ from django.db import models
2
+ import ffmpeg
3
+ from pathlib import Path
4
+
5
+ # import endoreg_center_id from django settings
6
+ from django.conf import settings
7
+
8
+ # check if endoreg_center_id is set
9
+ if not hasattr(settings, 'ENDOREG_CENTER_ID'):
10
+ ENDOREG_CENTER_ID = 9999
11
+ else:
12
+ ENDOREG_CENTER_ID = settings.ENDOREG_CENTER_ID
13
+
14
+ # VideoMeta
15
+ class VideoMeta(models.Model):
16
+ processor = models.ForeignKey('EndoscopyProcessor', on_delete=models.CASCADE, blank=True, null=True)
17
+ endoscope = models.ForeignKey('Endoscope', on_delete=models.CASCADE, blank=True, null=True)
18
+ center = models.ForeignKey('Center', on_delete=models.CASCADE)
19
+ import_meta = models.OneToOneField('VideoImportMeta', on_delete=models.CASCADE, blank=True, null=True)
20
+ ffmpeg_meta = models.OneToOneField('FFMpegMeta', on_delete=models.CASCADE, blank=True, null=True)
21
+
22
+ def __str__(self):
23
+
24
+ processor_name = self.processor.name if self.processor is not None else "None"
25
+ endoscope_name = self.endoscope.name if self.endoscope is not None else "None"
26
+ center_name = self.center.name if self.center is not None else "None"
27
+
28
+ result_html = ""
29
+
30
+ result_html += f"Processor: {processor_name}<br>"
31
+ result_html += f"Endoscope: {endoscope_name}<br>"
32
+ result_html += f"Center: {center_name}<br>"
33
+
34
+ return result_html
35
+
36
+ # import meta should be created when video meta is created
37
+ def save(self, *args, **kwargs):
38
+ if self.import_meta is None:
39
+ self.import_meta = VideoImportMeta.objects.create()
40
+ super(VideoMeta, self).save(*args, **kwargs)
41
+
42
+ def initialize_ffmpeg_meta(self, file_path):
43
+ """Initializes FFMpeg metadata for the video file if not already done."""
44
+ self.ffmpeg_meta = FFMpegMeta.create_from_file(Path(file_path))
45
+ self.save()
46
+
47
+ def update_meta(self, file_path):
48
+ """Updates the video metadata from the file."""
49
+ self.initialize_ffmpeg_meta(file_path)
50
+ self.save()
51
+
52
+ def get_endo_roi(self):
53
+ endo_roi = self.processor.get_roi_endoscope_image()
54
+ return endo_roi
55
+
56
+ def get_fps(self):
57
+ if not self.ffmpeg_meta:
58
+ return None
59
+
60
+ return self.ffmpeg_meta.frame_rate
61
+
62
+
63
+ class FFMpegMeta(models.Model):
64
+ # Existing fields
65
+ duration = models.FloatField(blank=True, null=True)
66
+ width = models.IntegerField(blank=True, null=True)
67
+ height = models.IntegerField(blank=True, null=True)
68
+ frame_rate = models.FloatField(blank=True, null=True)
69
+
70
+ # New fields for comprehensive information
71
+ video_codec = models.CharField(max_length=50, blank=True, null=True)
72
+ audio_codec = models.CharField(max_length=50, blank=True, null=True)
73
+ audio_channels = models.IntegerField(blank=True, null=True)
74
+ audio_sample_rate = models.IntegerField(blank=True, null=True)
75
+
76
+ # Existing __str__ method can be updated to include new fields
77
+
78
+ @classmethod
79
+ def create_from_file(cls, file_path: Path):
80
+ """Creates an FFMpegMeta instance from a video file using ffmpeg probe."""
81
+ try:
82
+ probe = ffmpeg.probe(file_path.resolve().as_posix())
83
+ except: # ffmpeg.Error as e:
84
+ # print(e.stderr)
85
+ print(f"Error while probing {file_path}")
86
+ return None
87
+
88
+ video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
89
+ audio_streams = [stream for stream in probe['streams'] if stream['codec_type'] == 'audio']
90
+
91
+ # Check for the existence of a video stream
92
+ if video_stream is None:
93
+ print(f"No video stream found in {file_path}")
94
+ return None
95
+
96
+ # Extract and store video metadata
97
+ metadata = {
98
+ 'duration': float(video_stream.get('duration', 0)),
99
+ 'width': int(video_stream.get('width', 0)),
100
+ 'height': int(video_stream.get('height', 0)),
101
+ 'frame_rate': float(next(iter(video_stream.get('avg_frame_rate', '').split('/')), 0)),
102
+ 'video_codec': video_stream.get('codec_name', ''),
103
+ }
104
+
105
+ # If there are audio streams, extract and store audio metadata from the first stream
106
+ if audio_streams:
107
+ first_audio_stream = audio_streams[0]
108
+ metadata.update({
109
+ 'audio_codec': first_audio_stream.get('codec_name', ''),
110
+ 'audio_channels': int(first_audio_stream.get('channels', 0)),
111
+ 'audio_sample_rate': int(first_audio_stream.get('sample_rate', 0)),
112
+ })
113
+
114
+ # Create and return the FFMpegMeta instance
115
+ return cls.objects.create(**metadata)
116
+
117
+ class VideoImportMeta(models.Model):
118
+
119
+ video_anonymized = models.BooleanField(default=False)
120
+ video_patient_data_detected = models.BooleanField(default=False)
121
+ outside_detected = models.BooleanField(default=False)
122
+ patient_data_removed = models.BooleanField(default=False)
123
+ outside_removed = models.BooleanField(default=False)
124
+
125
+ def __str__(self):
126
+ result_html = ""
127
+
128
+ result_html += f"Video anonymized: {self.video_anonymized}<br>"
129
+ result_html += f"Video patient data detected: {self.video_patient_data_detected}<br>"
130
+ result_html += f"Outside detected: {self.outside_detected}<br>"
131
+ result_html += f"Patient data removed: {self.patient_data_removed}<br>"
132
+ result_html += f"Outside removed: {self.outside_removed}<br>"
133
133
  return result_html
@@ -1,89 +1,89 @@
1
- from django.db import models
2
- from ..center import Center
3
- import hashlib
4
- from datetime import date, time
5
-
6
- class ReportFile(models.Model):
7
- pdf = models.FileField(upload_to="raw_report_pdfs", blank=True, null=True)
8
- pdf_hash = models.CharField(max_length=255, unique=True)
9
- center = models.ForeignKey(Center, on_delete=models.CASCADE)
10
- meta = models.JSONField(blank=True, null=True)
11
- text = models.TextField(blank=True, null=True)
12
- text_anonymized = models.TextField(blank=True, null=True)
13
- patient = models.ForeignKey("Patient", on_delete=models.CASCADE, blank=True, null=True)
14
- examiner = models.ForeignKey("Examiner", on_delete=models.CASCADE, blank=True, null=True)
15
- date = models.DateField(blank=True, null=True)
16
- time = models.TimeField(blank=True, null=True)
17
-
18
- def get_pdf_hash(self):
19
- #FIXME should use endoreg_db.utils.get_pdf_hash in future
20
- pdf = self.pdf
21
- pdf_hash = None
22
-
23
- if pdf:
24
- # Open the file in binary mode and read its contents
25
- with pdf.open(mode='rb') as f:
26
- pdf_contents = f.read()
27
- # Create a hash object using SHA-256 algorithm
28
- hash_object = hashlib.sha256(pdf_contents, usedforsecurity=False)
29
- # Get the hexadecimal representation of the hash
30
- pdf_hash = hash_object.hexdigest()
31
- assert len(pdf_hash) <= 255, "Hash length exceeds 255 characters"
32
-
33
- return pdf_hash
34
-
35
- def initialize_metadata_in_db(self, report_meta=None):
36
- if not report_meta:
37
- report_meta = self.meta
38
- self.set_examination_date_and_time(report_meta)
39
- self.patient, created = self.get_or_create_patient(report_meta)
40
- self.examiner, created = self.get_or_create_examiner(report_meta)
41
- self.save()
42
-
43
- def get_or_create_patient(self, report_meta=None):
44
- from ..persons import Patient
45
- if not report_meta:
46
- report_meta = self.meta
47
- patient_first_name = report_meta['patient_first_name']
48
- patient_last_name = report_meta['patient_last_name']
49
- patient_dob = report_meta['patient_dob']
50
-
51
- patient, created = Patient.objects.get_or_create(
52
- first_name=patient_first_name,
53
- last_name=patient_last_name,
54
- dob=patient_dob
55
- )
56
-
57
- return patient, created
58
-
59
- def get_or_create_examiner(self, report_meta= None):
60
- from ..persons import Examiner
61
- if not report_meta:
62
- report_meta = self.meta
63
- examiner_first_name = report_meta['examiner_first_name']
64
- examiner_last_name = report_meta['examiner_last_name']
65
- examiner_center = self.center
66
-
67
- examiner, created = Examiner.objects.get_or_create(
68
- first_name=examiner_first_name,
69
- last_name=examiner_last_name,
70
- center=examiner_center
71
- )
72
-
73
- return examiner, created
74
-
75
- def set_examination_date_and_time(self, report_meta=None):
76
- if not report_meta:
77
- report_meta = self.meta
78
- examination_date_str = report_meta['examination_date']
79
- examination_time_str = report_meta['examination_time']
80
-
81
- if examination_date_str:
82
- # TODO: get django DateField compatible date from string (e.g. "2021-01-01")
83
- self.date = date.fromisoformat(examination_date_str)
84
- if examination_time_str:
85
- # TODO: get django TimeField compatible time from string (e.g. "12:00")
86
- self.time = time.fromisoformat(examination_time_str)
87
-
88
-
89
-
1
+ from django.db import models
2
+ from ..center import Center
3
+ import hashlib
4
+ from datetime import date, time
5
+
6
+ class ReportFile(models.Model):
7
+ pdf = models.FileField(upload_to="raw_report_pdfs", blank=True, null=True)
8
+ pdf_hash = models.CharField(max_length=255, unique=True)
9
+ center = models.ForeignKey(Center, on_delete=models.CASCADE)
10
+ meta = models.JSONField(blank=True, null=True)
11
+ text = models.TextField(blank=True, null=True)
12
+ text_anonymized = models.TextField(blank=True, null=True)
13
+ patient = models.ForeignKey("Patient", on_delete=models.CASCADE, blank=True, null=True)
14
+ examiner = models.ForeignKey("Examiner", on_delete=models.CASCADE, blank=True, null=True)
15
+ date = models.DateField(blank=True, null=True)
16
+ time = models.TimeField(blank=True, null=True)
17
+
18
+ def get_pdf_hash(self):
19
+ #FIXME should use endoreg_db.utils.get_pdf_hash in future
20
+ pdf = self.pdf
21
+ pdf_hash = None
22
+
23
+ if pdf:
24
+ # Open the file in binary mode and read its contents
25
+ with pdf.open(mode='rb') as f:
26
+ pdf_contents = f.read()
27
+ # Create a hash object using SHA-256 algorithm
28
+ hash_object = hashlib.sha256(pdf_contents, usedforsecurity=False)
29
+ # Get the hexadecimal representation of the hash
30
+ pdf_hash = hash_object.hexdigest()
31
+ assert len(pdf_hash) <= 255, "Hash length exceeds 255 characters"
32
+
33
+ return pdf_hash
34
+
35
+ def initialize_metadata_in_db(self, report_meta=None):
36
+ if not report_meta:
37
+ report_meta = self.meta
38
+ self.set_examination_date_and_time(report_meta)
39
+ self.patient, created = self.get_or_create_patient(report_meta)
40
+ self.examiner, created = self.get_or_create_examiner(report_meta)
41
+ self.save()
42
+
43
+ def get_or_create_patient(self, report_meta=None):
44
+ from ..persons import Patient
45
+ if not report_meta:
46
+ report_meta = self.meta
47
+ patient_first_name = report_meta['patient_first_name']
48
+ patient_last_name = report_meta['patient_last_name']
49
+ patient_dob = report_meta['patient_dob']
50
+
51
+ patient, created = Patient.objects.get_or_create(
52
+ first_name=patient_first_name,
53
+ last_name=patient_last_name,
54
+ dob=patient_dob
55
+ )
56
+
57
+ return patient, created
58
+
59
+ def get_or_create_examiner(self, report_meta= None):
60
+ from ..persons import Examiner
61
+ if not report_meta:
62
+ report_meta = self.meta
63
+ examiner_first_name = report_meta['examiner_first_name']
64
+ examiner_last_name = report_meta['examiner_last_name']
65
+ examiner_center = self.center
66
+
67
+ examiner, created = Examiner.objects.get_or_create(
68
+ first_name=examiner_first_name,
69
+ last_name=examiner_last_name,
70
+ center=examiner_center
71
+ )
72
+
73
+ return examiner, created
74
+
75
+ def set_examination_date_and_time(self, report_meta=None):
76
+ if not report_meta:
77
+ report_meta = self.meta
78
+ examination_date_str = report_meta['examination_date']
79
+ examination_time_str = report_meta['examination_time']
80
+
81
+ if examination_date_str:
82
+ # TODO: get django DateField compatible date from string (e.g. "2021-01-01")
83
+ self.date = date.fromisoformat(examination_date_str)
84
+ if examination_time_str:
85
+ # TODO: get django TimeField compatible time from string (e.g. "12:00")
86
+ self.time = time.fromisoformat(examination_time_str)
87
+
88
+
89
+