endoreg-db 0.8.6.1__py3-none-any.whl → 0.8.8.9__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.

Potentially problematic release.


This version of endoreg-db might be problematic. Click here for more details.

Files changed (503) hide show
  1. endoreg_db/authz/auth.py +74 -0
  2. endoreg_db/authz/backends.py +168 -0
  3. endoreg_db/authz/management/commands/list_routes.py +18 -0
  4. endoreg_db/authz/middleware.py +83 -0
  5. endoreg_db/authz/permissions.py +127 -0
  6. endoreg_db/authz/policy.py +218 -0
  7. endoreg_db/authz/views_auth.py +66 -0
  8. endoreg_db/config/env.py +13 -8
  9. endoreg_db/data/__init__.py +2 -11
  10. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +3 -3
  11. endoreg_db/data/event_classification/data.yaml +4 -0
  12. endoreg_db/data/event_classification_choice/data.yaml +9 -0
  13. endoreg_db/data/examination/examinations/data.yaml +114 -14
  14. endoreg_db/data/examination/time-type/data.yaml +0 -3
  15. endoreg_db/data/examination_indication/endoscopy.yaml +108 -173
  16. endoreg_db/data/examination_indication_classification/endoscopy.yaml +0 -70
  17. endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +33 -37
  18. endoreg_db/data/finding/00_generic.yaml +35 -0
  19. endoreg_db/data/finding/00_generic_complication.yaml +9 -0
  20. endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
  21. endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
  22. endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
  23. endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
  24. endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
  25. endoreg_db/data/finding_classification/00_generic.yaml +44 -0
  26. endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
  27. endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
  28. endoreg_db/data/finding_classification/02_colonoscopy_baseline.yaml +83 -0
  29. endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
  30. endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
  31. endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
  32. endoreg_db/data/finding_classification_choice/{yes_no_na.yaml → 00_generic.yaml} +5 -1
  33. endoreg_db/data/finding_classification_choice/{examination_setting_generic_types.yaml → 00_generic_baseline.yaml} +10 -2
  34. endoreg_db/data/finding_classification_choice/{complication_generic_types.yaml → 00_generic_complication.yaml} +1 -1
  35. endoreg_db/data/finding_classification_choice/{histology.yaml → 00_generic_histology.yaml} +1 -4
  36. endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
  37. endoreg_db/data/finding_classification_choice/{bowel_preparation.yaml → 02_colonoscopy_bowel_preparation.yaml} +1 -30
  38. endoreg_db/data/finding_classification_choice/{colonoscopy_not_complete_reason.yaml → 02_colonoscopy_generic.yaml} +1 -1
  39. endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
  40. endoreg_db/data/finding_classification_choice/{colonoscopy_location.yaml → 02_colonoscopy_location.yaml} +23 -4
  41. endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
  42. endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
  43. endoreg_db/data/finding_classification_choice/{colon_lesion_paris.yaml → 02_colonoscopy_polyp_morphology.yaml} +26 -8
  44. endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
  45. endoreg_db/data/finding_classification_type/{colonoscopy_basic.yaml → 00_generic.yaml} +18 -13
  46. endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
  47. endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
  48. endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
  49. endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
  50. endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
  51. endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
  52. endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
  53. endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
  54. endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
  55. endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
  56. endoreg_db/data/finding_type/data.yaml +8 -12
  57. endoreg_db/data/requirement/01_patient_data.yaml +93 -0
  58. endoreg_db/data/requirement/old/colon_polyp_intervention.yaml +49 -0
  59. endoreg_db/data/requirement/old/coloreg_colon_polyp.yaml +49 -0
  60. endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
  61. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +29 -12
  62. endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
  63. endoreg_db/data/requirement_set/{endoscopy_bleeding_risk.yaml → 02_endoscopy_bleeding_risk.yaml} +0 -6
  64. endoreg_db/data/requirement_set/90_coloreg.yaml +190 -0
  65. endoreg_db/data/requirement_set/_old_ +109 -0
  66. endoreg_db/data/requirement_set_type/data.yaml +21 -0
  67. endoreg_db/data/setup_config.yaml +4 -4
  68. endoreg_db/data/tag/requirement_set_tags.yaml +21 -0
  69. endoreg_db/exceptions.py +4 -2
  70. endoreg_db/forms/examination_form.py +1 -1
  71. endoreg_db/helpers/data_loader.py +125 -53
  72. endoreg_db/helpers/default_objects.py +116 -81
  73. endoreg_db/import_files/__init__.py +27 -0
  74. endoreg_db/import_files/context/__init__.py +7 -0
  75. endoreg_db/import_files/context/default_sensitive_meta.py +81 -0
  76. endoreg_db/import_files/context/ensure_center.py +17 -0
  77. endoreg_db/import_files/context/file_lock.py +66 -0
  78. endoreg_db/import_files/context/import_context.py +43 -0
  79. endoreg_db/import_files/context/validate_directories.py +56 -0
  80. endoreg_db/import_files/file_storage/__init__.py +15 -0
  81. endoreg_db/import_files/file_storage/create_report_file.py +76 -0
  82. endoreg_db/import_files/file_storage/create_video_file.py +75 -0
  83. endoreg_db/import_files/file_storage/sensitive_meta_storage.py +39 -0
  84. endoreg_db/import_files/file_storage/state_management.py +400 -0
  85. endoreg_db/import_files/file_storage/storage.py +36 -0
  86. endoreg_db/import_files/import_service.md +26 -0
  87. endoreg_db/import_files/processing/__init__.py +11 -0
  88. endoreg_db/import_files/processing/report_processing/report_anonymization.py +94 -0
  89. endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
  90. endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
  91. endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +119 -0
  92. endoreg_db/import_files/pseudonymization/fake.py +52 -0
  93. endoreg_db/import_files/pseudonymization/k_anonymity.py +182 -0
  94. endoreg_db/import_files/pseudonymization/k_pseudonymity.py +128 -0
  95. endoreg_db/import_files/report_import_service.py +141 -0
  96. endoreg_db/import_files/video_import_service.py +150 -0
  97. endoreg_db/management/commands/create_model_meta_from_huggingface.py +21 -10
  98. endoreg_db/management/commands/create_multilabel_model_meta.py +299 -129
  99. endoreg_db/management/commands/import_report.py +130 -65
  100. endoreg_db/management/commands/import_video.py +9 -10
  101. endoreg_db/management/commands/import_video_with_classification.py +2 -2
  102. endoreg_db/management/commands/list_routes.py +18 -0
  103. endoreg_db/management/commands/load_ai_model_data.py +5 -5
  104. endoreg_db/management/commands/load_ai_model_label_data.py +9 -7
  105. endoreg_db/management/commands/load_base_db_data.py +5 -134
  106. endoreg_db/management/commands/load_center_data.py +12 -12
  107. endoreg_db/management/commands/load_contraindication_data.py +14 -16
  108. endoreg_db/management/commands/load_disease_classification_choices_data.py +15 -18
  109. endoreg_db/management/commands/load_disease_classification_data.py +15 -18
  110. endoreg_db/management/commands/load_disease_data.py +25 -28
  111. endoreg_db/management/commands/load_endoscope_data.py +20 -27
  112. endoreg_db/management/commands/load_event_data.py +14 -16
  113. endoreg_db/management/commands/load_examination_data.py +31 -44
  114. endoreg_db/management/commands/load_examination_indication_data.py +20 -21
  115. endoreg_db/management/commands/load_finding_data.py +52 -80
  116. endoreg_db/management/commands/load_information_source.py +21 -23
  117. endoreg_db/management/commands/load_lab_value_data.py +17 -26
  118. endoreg_db/management/commands/load_medication_data.py +13 -12
  119. endoreg_db/management/commands/load_organ_data.py +15 -19
  120. endoreg_db/management/commands/load_pdf_type_data.py +19 -18
  121. endoreg_db/management/commands/load_profession_data.py +14 -17
  122. endoreg_db/management/commands/load_qualification_data.py +20 -23
  123. endoreg_db/management/commands/load_report_reader_flag_data.py +17 -19
  124. endoreg_db/management/commands/load_requirement_data.py +62 -39
  125. endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
  126. endoreg_db/management/commands/load_risk_data.py +7 -6
  127. endoreg_db/management/commands/load_shift_data.py +20 -23
  128. endoreg_db/management/commands/load_tag_data.py +8 -11
  129. endoreg_db/management/commands/load_unit_data.py +17 -19
  130. endoreg_db/management/commands/setup_endoreg_db.py +3 -3
  131. endoreg_db/management/commands/start_filewatcher.py +46 -37
  132. endoreg_db/management/commands/storage_management.py +271 -203
  133. endoreg_db/management/commands/validate_video_files.py +1 -5
  134. endoreg_db/migrations/0001_initial.py +297 -250
  135. endoreg_db/models/__init__.py +78 -123
  136. endoreg_db/models/administration/__init__.py +21 -42
  137. endoreg_db/models/administration/ai/active_model.py +2 -2
  138. endoreg_db/models/administration/ai/ai_model.py +7 -6
  139. endoreg_db/models/administration/case/__init__.py +1 -15
  140. endoreg_db/models/administration/case/case.py +3 -3
  141. endoreg_db/models/administration/case/case_template/__init__.py +2 -14
  142. endoreg_db/models/administration/case/case_template/case_template.py +2 -124
  143. endoreg_db/models/administration/case/case_template/case_template_rule.py +2 -268
  144. endoreg_db/models/administration/case/case_template/case_template_rule_value.py +2 -85
  145. endoreg_db/models/administration/case/case_template/case_template_type.py +2 -25
  146. endoreg_db/models/administration/center/center.py +33 -19
  147. endoreg_db/models/administration/center/center_product.py +12 -9
  148. endoreg_db/models/administration/center/center_resource.py +25 -19
  149. endoreg_db/models/administration/center/center_shift.py +21 -17
  150. endoreg_db/models/administration/center/center_waste.py +16 -8
  151. endoreg_db/models/administration/person/__init__.py +2 -0
  152. endoreg_db/models/administration/person/employee/employee.py +10 -5
  153. endoreg_db/models/administration/person/employee/employee_qualification.py +9 -4
  154. endoreg_db/models/administration/person/employee/employee_type.py +12 -6
  155. endoreg_db/models/administration/person/examiner/examiner.py +13 -11
  156. endoreg_db/models/administration/person/patient/__init__.py +2 -0
  157. endoreg_db/models/administration/person/patient/patient.py +129 -100
  158. endoreg_db/models/administration/person/patient/patient_external_id.py +37 -0
  159. endoreg_db/models/administration/person/person.py +4 -0
  160. endoreg_db/models/administration/person/profession/__init__.py +8 -4
  161. endoreg_db/models/administration/person/user/portal_user_information.py +11 -7
  162. endoreg_db/models/administration/product/product.py +20 -15
  163. endoreg_db/models/administration/product/product_material.py +17 -18
  164. endoreg_db/models/administration/product/product_weight.py +12 -8
  165. endoreg_db/models/administration/product/reference_product.py +23 -55
  166. endoreg_db/models/administration/qualification/qualification.py +7 -3
  167. endoreg_db/models/administration/qualification/qualification_type.py +7 -3
  168. endoreg_db/models/administration/shift/scheduled_days.py +8 -5
  169. endoreg_db/models/administration/shift/shift.py +16 -12
  170. endoreg_db/models/administration/shift/shift_type.py +23 -31
  171. endoreg_db/models/label/__init__.py +8 -9
  172. endoreg_db/models/label/annotation/image_classification.py +10 -9
  173. endoreg_db/models/label/annotation/video_segmentation_annotation.py +23 -28
  174. endoreg_db/models/label/label.py +15 -15
  175. endoreg_db/models/label/label_set.py +19 -6
  176. endoreg_db/models/label/label_type.py +1 -1
  177. endoreg_db/models/label/label_video_segment/_create_from_video.py +5 -8
  178. endoreg_db/models/label/label_video_segment/label_video_segment.py +98 -102
  179. endoreg_db/models/label/video_segmentation_label.py +4 -0
  180. endoreg_db/models/label/video_segmentation_labelset.py +4 -3
  181. endoreg_db/models/media/frame/frame.py +22 -22
  182. endoreg_db/models/media/pdf/raw_pdf.py +194 -194
  183. endoreg_db/models/media/pdf/report_file.py +25 -29
  184. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +55 -47
  185. endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
  186. endoreg_db/models/media/processing_history/__init__.py +5 -0
  187. endoreg_db/models/media/processing_history/processing_history.py +96 -0
  188. endoreg_db/models/media/video/__init__.py +1 -0
  189. endoreg_db/models/media/video/create_from_file.py +139 -77
  190. endoreg_db/models/media/video/pipe_2.py +8 -9
  191. endoreg_db/models/media/video/video_file.py +174 -112
  192. endoreg_db/models/media/video/video_file_ai.py +288 -74
  193. endoreg_db/models/media/video/video_file_anonymize.py +38 -38
  194. endoreg_db/models/media/video/video_file_frames/__init__.py +3 -1
  195. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -8
  196. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +7 -9
  197. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +9 -8
  198. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +38 -45
  199. endoreg_db/models/media/video/video_file_frames/_get_frame.py +6 -8
  200. endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +4 -18
  201. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -3
  202. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +7 -6
  203. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +6 -8
  204. endoreg_db/models/media/video/video_file_frames/_get_frames.py +6 -8
  205. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +15 -25
  206. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +26 -23
  207. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +23 -14
  208. endoreg_db/models/media/video/video_file_io.py +113 -61
  209. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +3 -3
  210. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +5 -3
  211. endoreg_db/models/media/video/video_file_meta/get_fps.py +37 -34
  212. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +19 -25
  213. endoreg_db/models/media/video/video_file_meta/text_meta.py +41 -38
  214. endoreg_db/models/media/video/video_file_meta/video_meta.py +14 -7
  215. endoreg_db/models/media/video/video_file_segments.py +24 -17
  216. endoreg_db/models/media/video/video_metadata.py +19 -35
  217. endoreg_db/models/media/video/video_processing.py +96 -95
  218. endoreg_db/models/medical/contraindication/README.md +1 -0
  219. endoreg_db/models/medical/contraindication/__init__.py +13 -3
  220. endoreg_db/models/medical/disease.py +22 -16
  221. endoreg_db/models/medical/event.py +31 -18
  222. endoreg_db/models/medical/examination/__init__.py +13 -6
  223. endoreg_db/models/medical/examination/examination.py +39 -20
  224. endoreg_db/models/medical/examination/examination_indication.py +30 -95
  225. endoreg_db/models/medical/examination/examination_time.py +23 -8
  226. endoreg_db/models/medical/examination/examination_time_type.py +9 -6
  227. endoreg_db/models/medical/examination/examination_type.py +3 -4
  228. endoreg_db/models/medical/finding/finding.py +32 -40
  229. endoreg_db/models/medical/finding/finding_classification.py +42 -72
  230. endoreg_db/models/medical/finding/finding_intervention.py +25 -22
  231. endoreg_db/models/medical/finding/finding_type.py +13 -12
  232. endoreg_db/models/medical/hardware/endoscope.py +26 -26
  233. endoreg_db/models/medical/hardware/endoscopy_processor.py +2 -2
  234. endoreg_db/models/medical/laboratory/lab_value.py +62 -91
  235. endoreg_db/models/medical/medication/medication.py +22 -10
  236. endoreg_db/models/medical/medication/medication_indication.py +29 -3
  237. endoreg_db/models/medical/medication/medication_indication_type.py +25 -14
  238. endoreg_db/models/medical/medication/medication_intake_time.py +31 -19
  239. endoreg_db/models/medical/medication/medication_schedule.py +27 -16
  240. endoreg_db/models/medical/organ/__init__.py +15 -12
  241. endoreg_db/models/medical/patient/medication_examples.py +6 -6
  242. endoreg_db/models/medical/patient/patient_disease.py +20 -23
  243. endoreg_db/models/medical/patient/patient_event.py +19 -22
  244. endoreg_db/models/medical/patient/patient_examination.py +48 -54
  245. endoreg_db/models/medical/patient/patient_examination_indication.py +16 -14
  246. endoreg_db/models/medical/patient/patient_finding.py +122 -139
  247. endoreg_db/models/medical/patient/patient_finding_classification.py +44 -49
  248. endoreg_db/models/medical/patient/patient_finding_intervention.py +8 -19
  249. endoreg_db/models/medical/patient/patient_lab_sample.py +28 -23
  250. endoreg_db/models/medical/patient/patient_lab_value.py +82 -89
  251. endoreg_db/models/medical/patient/patient_medication.py +27 -38
  252. endoreg_db/models/medical/patient/patient_medication_schedule.py +28 -36
  253. endoreg_db/models/medical/risk/risk.py +7 -6
  254. endoreg_db/models/medical/risk/risk_type.py +8 -5
  255. endoreg_db/models/metadata/model_meta.py +60 -29
  256. endoreg_db/models/metadata/model_meta_logic.py +125 -18
  257. endoreg_db/models/metadata/pdf_meta.py +31 -24
  258. endoreg_db/models/metadata/sensitive_meta.py +105 -85
  259. endoreg_db/models/metadata/sensitive_meta_logic.py +198 -103
  260. endoreg_db/models/metadata/video_meta.py +51 -31
  261. endoreg_db/models/metadata/video_prediction_logic.py +16 -23
  262. endoreg_db/models/metadata/video_prediction_meta.py +29 -33
  263. endoreg_db/models/other/distribution/date_value_distribution.py +89 -29
  264. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +21 -5
  265. endoreg_db/models/other/distribution/numeric_value_distribution.py +114 -53
  266. endoreg_db/models/other/distribution/single_categorical_value_distribution.py +4 -3
  267. endoreg_db/models/other/emission/emission_factor.py +18 -8
  268. endoreg_db/models/other/gender.py +10 -5
  269. endoreg_db/models/other/information_source.py +50 -29
  270. endoreg_db/models/other/material.py +9 -5
  271. endoreg_db/models/other/resource.py +6 -4
  272. endoreg_db/models/other/tag.py +10 -5
  273. endoreg_db/models/other/transport_route.py +13 -8
  274. endoreg_db/models/other/unit.py +10 -6
  275. endoreg_db/models/other/waste.py +6 -5
  276. endoreg_db/models/report/report.py +6 -0
  277. endoreg_db/models/requirement/requirement.py +329 -361
  278. endoreg_db/models/requirement/requirement_error.py +85 -0
  279. endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
  280. endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +3 -6
  281. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +90 -64
  282. endoreg_db/models/requirement/requirement_operator.py +103 -112
  283. endoreg_db/models/requirement/requirement_set.py +74 -57
  284. endoreg_db/models/state/__init__.py +4 -4
  285. endoreg_db/models/state/abstract.py +2 -2
  286. endoreg_db/models/state/anonymization.py +12 -0
  287. endoreg_db/models/state/audit_ledger.py +49 -51
  288. endoreg_db/models/state/label_video_segment.py +9 -0
  289. endoreg_db/models/state/raw_pdf.py +101 -68
  290. endoreg_db/models/state/sensitive_meta.py +6 -2
  291. endoreg_db/models/state/video.py +110 -90
  292. endoreg_db/models/upload_job.py +35 -34
  293. endoreg_db/models/utils.py +28 -25
  294. endoreg_db/queries/__init__.py +3 -1
  295. endoreg_db/root_urls.py +21 -2
  296. endoreg_db/schemas/examination_evaluation.py +1 -1
  297. endoreg_db/serializers/__init__.py +2 -10
  298. endoreg_db/serializers/anonymization.py +18 -10
  299. endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
  300. endoreg_db/serializers/meta/__init__.py +1 -6
  301. endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
  302. endoreg_db/serializers/misc/file_overview.py +11 -99
  303. endoreg_db/serializers/misc/sensitive_patient_data.py +50 -26
  304. endoreg_db/serializers/patient_examination/patient_examination.py +3 -3
  305. endoreg_db/serializers/pdf/anony_text_validation.py +39 -23
  306. endoreg_db/serializers/requirements/requirement_sets.py +92 -22
  307. endoreg_db/serializers/video/segmentation.py +2 -1
  308. endoreg_db/serializers/video/video_file_list.py +65 -34
  309. endoreg_db/serializers/video/video_processing_history.py +20 -5
  310. endoreg_db/services/__old/pdf_import.py +1487 -0
  311. endoreg_db/services/__old/video_import.py +1306 -0
  312. endoreg_db/services/anonymization.py +128 -89
  313. endoreg_db/services/lookup_service.py +65 -52
  314. endoreg_db/services/lookup_store.py +2 -2
  315. endoreg_db/services/pdf_import.py +0 -1382
  316. endoreg_db/services/report_import.py +10 -0
  317. endoreg_db/services/video_import.py +6 -1255
  318. endoreg_db/tasks/upload_tasks.py +79 -70
  319. endoreg_db/tasks/video_ingest.py +8 -4
  320. endoreg_db/urls/__init__.py +5 -32
  321. endoreg_db/urls/ai.py +32 -0
  322. endoreg_db/urls/media.py +121 -83
  323. endoreg_db/urls/root_urls.py +29 -0
  324. endoreg_db/utils/__init__.py +15 -5
  325. endoreg_db/utils/ai/multilabel_classification_net.py +116 -20
  326. endoreg_db/utils/case_generator/__init__.py +3 -0
  327. endoreg_db/utils/dataloader.py +142 -40
  328. endoreg_db/utils/defaults/set_default_center.py +32 -0
  329. endoreg_db/utils/names.py +22 -16
  330. endoreg_db/utils/paths.py +110 -46
  331. endoreg_db/utils/permissions.py +2 -1
  332. endoreg_db/utils/pipelines/Readme.md +1 -1
  333. endoreg_db/utils/pipelines/process_video_dir.py +1 -1
  334. endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +655 -0
  335. endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
  336. endoreg_db/utils/setup_config.py +8 -5
  337. endoreg_db/utils/storage.py +115 -0
  338. endoreg_db/utils/validate_endo_roi.py +8 -2
  339. endoreg_db/utils/video/ffmpeg_wrapper.py +184 -188
  340. endoreg_db/views/__init__.py +85 -183
  341. endoreg_db/views/ai/__init__.py +8 -0
  342. endoreg_db/views/ai/label.py +155 -0
  343. endoreg_db/views/anonymization/media_management.py +202 -166
  344. endoreg_db/views/anonymization/overview.py +99 -67
  345. endoreg_db/views/anonymization/validate.py +182 -44
  346. endoreg_db/views/media/__init__.py +7 -20
  347. endoreg_db/views/media/pdf_media.py +197 -174
  348. endoreg_db/views/media/sensitive_metadata.py +193 -138
  349. endoreg_db/views/media/video_media.py +89 -82
  350. endoreg_db/views/meta/__init__.py +0 -8
  351. endoreg_db/views/misc/__init__.py +1 -7
  352. endoreg_db/views/misc/upload_views.py +94 -93
  353. endoreg_db/views/patient/patient.py +5 -4
  354. endoreg_db/views/report/__init__.py +5 -7
  355. endoreg_db/views/{pdf → report}/reimport.py +22 -22
  356. endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +46 -39
  357. endoreg_db/views/requirement/evaluate.py +188 -187
  358. endoreg_db/views/requirement/lookup.py +17 -3
  359. endoreg_db/views/requirement/lookup_store.py +22 -90
  360. endoreg_db/views/requirement/requirement_utils.py +89 -0
  361. endoreg_db/views/video/__init__.py +23 -24
  362. endoreg_db/views/video/correction.py +201 -172
  363. endoreg_db/views/video/reimport.py +1 -1
  364. endoreg_db/views/{media/video_segments.py → video/segments_crud.py} +77 -40
  365. endoreg_db/views/video/{video_meta.py → video_meta_stats.py} +2 -2
  366. endoreg_db/views/video/video_stream.py +7 -8
  367. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/METADATA +7 -3
  368. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/RECORD +391 -413
  369. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/WHEEL +1 -1
  370. endoreg_db/data/finding/anatomy_colon.yaml +0 -128
  371. endoreg_db/data/finding/colonoscopy.yaml +0 -40
  372. endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +0 -56
  373. endoreg_db/data/finding/complication.yaml +0 -16
  374. endoreg_db/data/finding/data.yaml +0 -105
  375. endoreg_db/data/finding/examination_setting.yaml +0 -16
  376. endoreg_db/data/finding/medication_related.yaml +0 -18
  377. endoreg_db/data/finding/outcome.yaml +0 -12
  378. endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +0 -95
  379. endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +0 -22
  380. endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +0 -25
  381. endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
  382. endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
  383. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +0 -68
  384. endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
  385. endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -80
  386. endoreg_db/data/finding_classification/colonoscopy_lst.yaml +0 -21
  387. endoreg_db/data/finding_classification/colonoscopy_nice.yaml +0 -20
  388. endoreg_db/data/finding_classification/colonoscopy_paris.yaml +0 -26
  389. endoreg_db/data/finding_classification/colonoscopy_sano.yaml +0 -22
  390. endoreg_db/data/finding_classification/colonoscopy_summary.yaml +0 -53
  391. endoreg_db/data/finding_classification/complication_generic.yaml +0 -25
  392. endoreg_db/data/finding_classification/examination_setting_generic.yaml +0 -40
  393. endoreg_db/data/finding_classification/histology_colo.yaml +0 -51
  394. endoreg_db/data/finding_classification/intervention_required.yaml +0 -26
  395. endoreg_db/data/finding_classification/medication_related.yaml +0 -23
  396. endoreg_db/data/finding_classification/visualized.yaml +0 -33
  397. endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
  398. endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
  399. endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
  400. endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +0 -15
  401. endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +0 -17
  402. endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
  403. endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +0 -14
  404. endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
  405. endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +0 -82
  406. endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
  407. endoreg_db/data/finding_classification_choice/outcome.yaml +0 -19
  408. endoreg_db/data/finding_intervention/endoscopy.yaml +0 -43
  409. endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
  410. endoreg_db/data/finding_intervention/endoscopy_egd.yaml +0 -128
  411. endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +0 -32
  412. endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +0 -9
  413. endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +0 -36
  414. endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +0 -79
  415. endoreg_db/data/requirement/age.yaml +0 -26
  416. endoreg_db/data/requirement/gender.yaml +0 -25
  417. endoreg_db/management/commands/init_default_ai_model.py +0 -112
  418. endoreg_db/management/commands/reset_celery_schedule.py +0 -9
  419. endoreg_db/management/commands/validate_video.py +0 -204
  420. endoreg_db/migrations/0002_add_video_correction_models.py +0 -52
  421. endoreg_db/migrations/0003_add_center_display_name.py +0 -30
  422. endoreg_db/models/administration/permissions/__init__.py +0 -44
  423. endoreg_db/models/rule/__init__.py +0 -13
  424. endoreg_db/models/rule/rule.py +0 -27
  425. endoreg_db/models/rule/rule_applicator.py +0 -224
  426. endoreg_db/models/rule/rule_attribute_dtype.py +0 -17
  427. endoreg_db/models/rule/rule_type.py +0 -20
  428. endoreg_db/models/rule/ruleset.py +0 -17
  429. endoreg_db/renames.yml +0 -8
  430. endoreg_db/serializers/_old/raw_pdf_meta_validation.py +0 -223
  431. endoreg_db/serializers/_old/raw_video_meta_validation.py +0 -179
  432. endoreg_db/serializers/_old/video.py +0 -71
  433. endoreg_db/serializers/meta/pdf_file_meta_extraction.py +0 -115
  434. endoreg_db/serializers/meta/report_meta.py +0 -53
  435. endoreg_db/serializers/report/__init__.py +0 -9
  436. endoreg_db/serializers/report/mixins.py +0 -45
  437. endoreg_db/serializers/report/report.py +0 -105
  438. endoreg_db/serializers/report/report_list.py +0 -22
  439. endoreg_db/serializers/report/secure_file_url.py +0 -26
  440. endoreg_db/serializers/video/video_metadata.py +0 -105
  441. endoreg_db/services/requirements_object.py +0 -147
  442. endoreg_db/services/storage_aware_video_processor.py +0 -344
  443. endoreg_db/urls/files.py +0 -6
  444. endoreg_db/urls/label_video_segment_validate.py +0 -33
  445. endoreg_db/urls/label_video_segments.py +0 -46
  446. endoreg_db/urls/report.py +0 -48
  447. endoreg_db/urls/video.py +0 -61
  448. endoreg_db/utils/case_generator/case_generator.py +0 -159
  449. endoreg_db/utils/case_generator/utils.py +0 -30
  450. endoreg_db/utils/requirement_operator_logic/model_evaluators.py +0 -368
  451. endoreg_db/views/label/__init__.py +0 -5
  452. endoreg_db/views/label/label.py +0 -15
  453. endoreg_db/views/label_video_segment/__init__.py +0 -16
  454. endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +0 -44
  455. endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +0 -50
  456. endoreg_db/views/label_video_segment/label_video_segment.py +0 -77
  457. endoreg_db/views/label_video_segment/label_video_segment_by_label.py +0 -174
  458. endoreg_db/views/label_video_segment/label_video_segment_detail.py +0 -73
  459. endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +0 -46
  460. endoreg_db/views/label_video_segment/validate.py +0 -226
  461. endoreg_db/views/media/segments.py +0 -71
  462. endoreg_db/views/meta/available_files_list.py +0 -146
  463. endoreg_db/views/meta/report_meta.py +0 -53
  464. endoreg_db/views/meta/sensitive_meta_detail.py +0 -148
  465. endoreg_db/views/misc/secure_file_serving_view.py +0 -80
  466. endoreg_db/views/misc/secure_file_url_view.py +0 -84
  467. endoreg_db/views/misc/secure_url_validate.py +0 -79
  468. endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +0 -164
  469. endoreg_db/views/patient_finding_location/__init__.py +0 -5
  470. endoreg_db/views/patient_finding_location/pfl_create.py +0 -70
  471. endoreg_db/views/patient_finding_morphology/__init__.py +0 -5
  472. endoreg_db/views/patient_finding_morphology/pfm_create.py +0 -70
  473. endoreg_db/views/pdf/__init__.py +0 -8
  474. endoreg_db/views/report/report_list.py +0 -112
  475. endoreg_db/views/report/report_with_secure_url.py +0 -28
  476. endoreg_db/views/report/start_examination.py +0 -7
  477. endoreg_db/views/video/segmentation.py +0 -274
  478. endoreg_db/views/video/task_status.py +0 -49
  479. endoreg_db/views/video/timeline.py +0 -46
  480. endoreg_db/views/video/video_analyze.py +0 -52
  481. endoreg_db/views.py +0 -0
  482. /endoreg_db/data/requirement/{colonoscopy_baseline_austria.yaml → old/colonoscopy_baseline_austria.yaml} +0 -0
  483. /endoreg_db/data/requirement/{disease_cardiovascular.yaml → old/disease_cardiovascular.yaml} +0 -0
  484. /endoreg_db/data/requirement/{disease_classification_choice_cardiovascular.yaml → old/disease_classification_choice_cardiovascular.yaml} +0 -0
  485. /endoreg_db/data/requirement/{disease_hepatology.yaml → old/disease_hepatology.yaml} +0 -0
  486. /endoreg_db/data/requirement/{disease_misc.yaml → old/disease_misc.yaml} +0 -0
  487. /endoreg_db/data/requirement/{disease_renal.yaml → old/disease_renal.yaml} +0 -0
  488. /endoreg_db/data/requirement/{endoscopy_bleeding_risk.yaml → old/endoscopy_bleeding_risk.yaml} +0 -0
  489. /endoreg_db/data/requirement/{event_cardiology.yaml → old/event_cardiology.yaml} +0 -0
  490. /endoreg_db/data/requirement/{event_requirements.yaml → old/event_requirements.yaml} +0 -0
  491. /endoreg_db/data/requirement/{finding_colon_polyp.yaml → old/finding_colon_polyp.yaml} +0 -0
  492. /endoreg_db/{migrations/__init__.py → data/requirement/old/gender.yaml} +0 -0
  493. /endoreg_db/data/requirement/{lab_value.yaml → old/lab_value.yaml} +0 -0
  494. /endoreg_db/data/requirement/{medication.yaml → old/medication.yaml} +0 -0
  495. /endoreg_db/data/requirement_operator/{age.yaml → _old/age.yaml} +0 -0
  496. /endoreg_db/data/requirement_operator/{lab_operators.yaml → _old/lab_operators.yaml} +0 -0
  497. /endoreg_db/data/requirement_operator/{model_operators.yaml → _old/model_operators.yaml} +0 -0
  498. /endoreg_db/{models/media/video/refactor_plan.md → import_files/pseudonymization/__init__.py} +0 -0
  499. /endoreg_db/{models/media/video/video_file_frames.py → import_files/pseudonymization/pseudonymize.py} +0 -0
  500. /endoreg_db/models/{metadata/frame_ocr_result.py → report/__init__.py} +0 -0
  501. /endoreg_db/{urls/sensitive_meta.py → models/report/images.py} +0 -0
  502. /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
  503. {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/licenses/LICENSE +0 -0
@@ -7,7 +7,6 @@ Unterstützt DD.MM.YYYY als Primärformat und YYYY-MM-DD als Fallback.
7
7
  from rest_framework import serializers
8
8
  from endoreg_db.models.metadata.sensitive_meta_logic import parse_any_date
9
9
 
10
-
11
10
  class SensitiveMetaValidateSerializer(serializers.Serializer):
12
11
  """
13
12
  Serializer für SensitiveMeta-Validierung mit deutscher Datums-Priorität.
@@ -19,11 +18,11 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
19
18
  Alle Datumsfelder werden in date-Objekte konvertiert.
20
19
  """
21
20
 
22
- patient_first_name = serializers.CharField(required=False, allow_blank=True)
23
- patient_last_name = serializers.CharField(required=False, allow_blank=True)
24
- patient_dob = serializers.CharField(required=False, allow_blank=True)
25
- examination_date = serializers.CharField(required=False, allow_blank=True)
26
- casenumber = serializers.CharField(required=False, allow_blank=True)
21
+ patient_first_name = serializers.CharField(required=True, allow_blank=True)
22
+ patient_last_name = serializers.CharField(required=True, allow_blank=True)
23
+ patient_dob = serializers.CharField(required=True, allow_blank=True)
24
+ examination_date = serializers.CharField(required=True, allow_blank=True)
25
+ casenumber = serializers.CharField(required=True, allow_blank=True)
27
26
  anonymized_text = serializers.CharField(required=False, allow_blank=True)
28
27
  patient_gender = serializers.CharField(required=False, allow_blank=True)
29
28
  center_name = serializers.CharField(required=False, allow_blank=True)
@@ -31,6 +30,10 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
31
30
  file_type = serializers.ChoiceField(
32
31
  choices=['video', 'pdf'], required=False
33
32
  ) # Optional: "video" oder "pdf"
33
+ center_name = serializers.CharField(required=False, allow_blank=True)
34
+ external_id = serializers.CharField(required=False, allow_blank=True)
35
+ external_id_origin = serializers.CharField(required=False, allow_blank=True)
36
+
34
37
 
35
38
  def validate_patient_dob(self, value):
36
39
  """
@@ -40,8 +43,11 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
40
43
  - DD.MM.YYYY (z.B. "21.03.1994")
41
44
  - YYYY-MM-DD (z.B. "1994-03-21")
42
45
  """
43
- if not value:
44
- return None
46
+
47
+ if value == '' or not value:
48
+ raise serializers.ValidationError(
49
+ "Ungültiges Datum. Kein Input! Erlaubte Formate: DD.MM.YYYY oder YYYY-MM-DD."
50
+ )
45
51
 
46
52
  parsed_date = parse_any_date(value)
47
53
  if not parsed_date:
@@ -58,8 +64,10 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
58
64
  - DD.MM.YYYY (z.B. "15.02.2024")
59
65
  - YYYY-MM-DD (z.B. "2024-02-15")
60
66
  """
61
- if not value:
62
- return None
67
+ if value == '' or not value:
68
+ raise serializers.ValidationError(
69
+ "Ungültiges Datum. Kein Input! Erlaubte Formate: DD.MM.YYYY oder YYYY-MM-DD."
70
+ )
63
71
 
64
72
  parsed_date = parse_any_date(value)
65
73
  if not parsed_date:
@@ -142,7 +142,7 @@ class LabelVideoSegmentSerializer(serializers.ModelSerializer):
142
142
  logger.debug(f"Serializer initialized with data: {self.initial_data}")
143
143
 
144
144
 
145
- def get_time_segments(self, obj: LabelVideoSegment) -> List[dict]:
145
+ def get_time_segments(self, obj: LabelVideoSegment) -> dict[str, dict]:
146
146
  frames = obj.frames
147
147
  time_segments = {
148
148
  "segment_id": obj.id,
@@ -225,34 +225,7 @@ class LabelVideoSegmentSerializer(serializers.ModelSerializer):
225
225
  """
226
226
  return ImageClassificationAnnotationSerializer(obj.all_frame_annotations, many=True).data
227
227
 
228
- def get_label_display(self, obj:LabelVideoSegment):
229
- """
230
- Return the German translation of the label name for display purposes.
231
-
232
- If the segment has no label, returns "Unbekannt". If a translation is not available, returns the original label name.
233
- """
234
- if not obj.label:
235
- return "Unbekannt"
236
-
237
- label_name = obj.label.name
238
- #TODO Refactor
239
- translations = {
240
- 'appendix': 'Appendix',
241
- 'blood': 'Blut',
242
- 'diverticule': 'Divertikel',
243
- 'grasper': 'Greifer',
244
- 'ileocaecalvalve': 'Ileozäkalklappe',
245
- 'ileum': 'Ileum',
246
- 'low_quality': 'Niedrige Bildqualität',
247
- 'nbi': 'Narrow Band Imaging',
248
- 'needle': 'Nadel',
249
- 'outside': 'Außerhalb',
250
- 'polyp': 'Polyp',
251
- 'snare': 'Snare',
252
- 'water_jet': 'Wasserstrahl',
253
- 'wound': 'Wunde'
254
- }
255
- return translations.get(label_name, label_name)
228
+
256
229
 
257
230
  def get_video_name(self, obj):
258
231
  """
@@ -1,7 +1,4 @@
1
- from .pdf_file_meta_extraction import PDFFileForMetaSerializer
2
- from .report_meta import (
3
- ReportMetaSerializer,
4
- )
1
+
5
2
  from .sensitive_meta_detail import SensitiveMetaDetailSerializer
6
3
  from .sensitive_meta_update import SensitiveMetaUpdateSerializer
7
4
  from .sensitive_meta_verification import SensitiveMetaVerificationSerializer
@@ -10,8 +7,6 @@ from .video_meta import (
10
7
  )
11
8
 
12
9
  __all__ = [
13
- "PDFFileForMetaSerializer",
14
- "ReportMetaSerializer",
15
10
  "SensitiveMetaDetailSerializer",
16
11
  "SensitiveMetaUpdateSerializer",
17
12
  "SensitiveMetaVerificationSerializer",
@@ -1,6 +1,5 @@
1
1
  from rest_framework import serializers
2
2
  import logging
3
-
4
3
  from ...models import SensitiveMeta
5
4
 
6
5
  logger = logging.getLogger(__name__)
@@ -10,153 +9,99 @@ class SensitiveMetaDetailSerializer(serializers.ModelSerializer):
10
9
  Serializer for displaying SensitiveMeta details with verification state.
11
10
  Includes all relevant fields for annotation and verification.
12
11
  """
13
-
12
+
14
13
  # State verification fields
15
14
  is_verified = serializers.SerializerMethodField()
16
15
  dob_verified = serializers.SerializerMethodField()
17
16
  names_verified = serializers.SerializerMethodField()
18
-
19
- # Related fields for better display
17
+
18
+ # Related fields
20
19
  center_name = serializers.CharField(source="center.name", read_only=True)
21
20
  patient_gender_name = serializers.CharField(source="patient_gender.name", read_only=True)
22
-
23
- # Examiner information
24
21
  examiners_display = serializers.SerializerMethodField()
25
-
26
- # Formatted dates for display
22
+
23
+ # Formatted display fields
27
24
  patient_dob_display = serializers.SerializerMethodField()
28
25
  examination_date_display = serializers.SerializerMethodField()
29
-
30
- # Hash displays (last 8 characters for security)
26
+
27
+ # Hash displays (last 8 chars)
31
28
  patient_hash_display = serializers.SerializerMethodField()
32
29
  examination_hash_display = serializers.SerializerMethodField()
33
30
 
31
+ # Text fields
32
+ text = serializers.SerializerMethodField()
33
+ anonymized_text = serializers.SerializerMethodField()
34
+
34
35
  class Meta:
35
36
  model = SensitiveMeta
36
37
  fields = [
37
- 'id',
38
- 'patient_first_name',
39
- 'patient_last_name',
40
- 'patient_dob',
41
- 'patient_dob_display',
42
- 'examination_date',
43
- 'examination_date_display',
44
- 'center_name',
45
- 'patient_gender_name',
46
- 'endoscope_type',
47
- 'endoscope_sn',
48
- 'patient_hash_display',
49
- 'examination_hash_display',
50
- 'examiners_display',
51
- 'is_verified',
52
- 'dob_verified',
53
- 'names_verified',
38
+ "id",
39
+ "casenumber",
40
+ "patient_first_name",
41
+ "patient_last_name",
42
+ "patient_dob",
43
+ "patient_dob_display",
44
+ "examination_date",
45
+ "examination_date_display",
46
+ "examination_time",
47
+ "center_name",
48
+ "patient_gender_name",
49
+ "endoscope_type",
50
+ "endoscope_sn",
51
+ "patient_hash_display",
52
+ "examination_hash_display",
53
+ "examiners_display",
54
+ "is_verified",
55
+ "dob_verified",
56
+ "names_verified",
57
+ "text",
58
+ "anonymized_text",
59
+ "external_id",
60
+ "external_id_origin"
54
61
  ]
55
62
  read_only_fields = [
56
- 'id',
57
- 'patient_hash_display',
58
- 'examination_hash_display',
63
+ "id",
64
+ "patient_hash_display",
65
+ "examination_hash_display",
59
66
  ]
60
67
 
61
- def get_is_verified(self, obj):
62
- """
63
- Return the overall verification status of the given SensitiveMeta instance.
64
-
65
- Returns:
66
- bool: True if the instance is verified; False if the verification attribute is missing.
67
-
68
- Raises:
69
- Exception: Propagates unexpected exceptions after logging.
70
- """
71
- try:
72
- return obj.is_verified
73
- except AttributeError:
74
- return False
75
- except Exception as e:
76
- logger.exception(f"Unexpected error in get_is_verified for SensitiveMeta {getattr(obj, 'pk', None)}: {e}")
77
- raise
78
-
79
- def get_dob_verified(self, obj):
80
- """
81
- Return the date of birth verification status for the given object.
82
-
83
- Returns:
84
- bool: True if the date of birth is verified; otherwise, False if unavailable or on error.
85
- """
86
- try:
87
- return obj.state.dob_verified
88
- except Exception:
89
- return False
90
-
91
- def get_names_verified(self, obj):
92
- """
93
- Return whether the patient's names have been verified.
94
-
95
- Returns:
96
- bool: True if the names are verified; False if not verified or if an error occurs.
97
- """
98
- try:
99
- return obj.state.names_verified
100
- except Exception:
101
- return False
68
+ # --- Verification getters ---
69
+ def get_is_verified(self, obj): return getattr(obj, "is_verified", False)
70
+ def get_dob_verified(self, obj): return getattr(getattr(obj, "state", None), "dob_verified", False)
71
+ def get_names_verified(self, obj): return getattr(getattr(obj, "state", None), "names_verified", False)
102
72
 
73
+ # --- Examiner display ---
103
74
  def get_examiners_display(self, obj):
104
- """
105
- Return a list of examiner full names for the given SensitiveMeta instance.
106
-
107
- Returns:
108
- list[str]: List of examiner names in "First Last" format, or an empty list if unavailable.
109
- """
110
75
  try:
111
- if obj.pk:
112
- examiners = obj.examiners.all()
113
- return [f"{e.first_name} {e.last_name}" for e in examiners]
114
- return []
76
+ return [f"{e.first_name} {e.last_name}" for e in obj.examiners.all()] if obj.pk else []
115
77
  except Exception as e:
116
- logger.warning(f"Error getting examiners for SensitiveMeta {obj.pk}: {e}")
78
+ logger.warning(f"Error fetching examiners for SensitiveMeta {obj.pk}: {e}")
117
79
  return []
118
80
 
81
+ # --- Date formatters ---
119
82
  def get_patient_dob_display(self, obj):
120
- """
121
- Return the patient's date of birth formatted as "YYYY-MM-DD" for display.
122
-
123
- Returns:
124
- str or None: Formatted date string if available, otherwise None.
125
- """
126
- if obj.patient_dob:
127
- return obj.patient_dob.strftime("%Y-%m-%d")
128
- return None
83
+ return obj.patient_dob.strftime("%Y-%m-%d") if obj.patient_dob else None
129
84
 
130
85
  def get_examination_date_display(self, obj):
131
- """
132
- Return the examination date formatted as "YYYY-MM-DD" for display.
133
-
134
- Returns:
135
- str or None: Formatted examination date string, or None if not set.
136
- """
137
- if obj.examination_date:
138
- return obj.examination_date.strftime("%Y-%m-%d")
139
- return None
86
+ return obj.examination_date.strftime("%Y-%m-%d") if obj.examination_date else None
140
87
 
88
+ # --- Hash short forms ---
141
89
  def get_patient_hash_display(self, obj):
142
- """
143
- Return the last eight characters of the patient's hash, prefixed with ellipsis, or None if not available.
144
-
145
- Returns:
146
- str or None: Truncated patient hash for display, or None if the hash is not set.
147
- """
148
- if obj.patient_hash:
149
- return f"...{obj.patient_hash[-8:]}"
150
- return None
90
+ return f"...{obj.patient_hash[-8:]}" if obj.patient_hash else None
151
91
 
152
92
  def get_examination_hash_display(self, obj):
153
- """
154
- Return the last eight characters of the examination hash, prefixed with ellipsis, or None if not available.
155
-
156
- Returns:
157
- str or None: Truncated examination hash for display, or None if the hash is not set.
158
- """
159
- if obj.examination_hash:
160
- return f"...{obj.examination_hash[-8:]}"
161
- return None
93
+ return f"...{obj.examination_hash[-8:]}" if obj.examination_hash else None
94
+
95
+ # --- Text fields ---
96
+ def get_text(self, obj):
97
+ return obj.text if isinstance(obj.text, str) else None
98
+
99
+ def get_anonymized_text(self, obj):
100
+ return obj.anonymized_text if isinstance(obj.anonymized_text, str) else None
101
+
102
+ def get_external_id(self, obj) -> str | None:
103
+ return obj.external_id if isinstance(obj.external_id, str) else None
104
+
105
+ def get_external_id_origin(self, obj) -> str | None:
106
+ return obj.external_id_origin if isinstance(obj.external_id_origin, str) else None
162
107
 
@@ -3,12 +3,8 @@ from typing import TYPE_CHECKING
3
3
  from rest_framework import serializers
4
4
 
5
5
  from endoreg_db.models.media import RawPdfFile, VideoFile
6
- from endoreg_db.models.state.raw_pdf import (
7
- AnonymizationStatus as PdfAnonymizationStatus,
8
- )
9
- from endoreg_db.models.state.video import (
10
- AnonymizationStatus as VideoAnonymizationStatus,
11
- )
6
+ from endoreg_db.models.state.anonymization import AnonymizationState as PdfAnonymizationState
7
+ from endoreg_db.models.state.anonymization import AnonymizationState as VideoAnonymizationState
12
8
 
13
9
  if TYPE_CHECKING:
14
10
  pass
@@ -28,10 +24,6 @@ class FileOverviewSerializer(serializers.Serializer):
28
24
  anonymizationStatus = serializers.CharField(read_only=True)
29
25
  annotationStatus = serializers.CharField(read_only=True)
30
26
  createdAt = serializers.DateTimeField(read_only=True)
31
- text = serializers.CharField(required=False, allow_blank=True, read_only=True)
32
- anonymizedText = serializers.CharField(
33
- required=False, allow_blank=True, read_only=True
34
- )
35
27
 
36
28
  # --- converting DB objects to that shape -----------------------
37
29
  def to_representation(self, instance):
@@ -62,110 +54,32 @@ class FileOverviewSerializer(serializers.Serializer):
62
54
  )
63
55
 
64
56
  # ------- anonymization status using VideoState model
65
- vs = instance.state
57
+ vs = instance.get_or_create_state()
66
58
  anonym_status = (
67
- vs.anonymization_status if vs else VideoAnonymizationStatus.NOT_STARTED
59
+ vs.anonymization_status if vs else VideoAnonymizationState.NOT_STARTED
68
60
  )
69
61
 
70
62
  # ------- annotation status (validated label segments)
71
63
  if instance.label_video_segments.filter(state__is_validated=True).exists():
72
- annot_status = "done"
64
+ annot_status = "validated"
73
65
  else:
74
66
  annot_status = "not_started"
75
67
 
76
- # ------- Extract text from sensitive_meta for videos
77
- if instance.sensitive_meta:
78
- sm = instance.sensitive_meta
79
- # Create a structured text representation from sensitive meta
80
- text_parts = []
81
-
82
- # Patient information
83
- if sm.patient_first_name or sm.patient_last_name:
84
- patient_name = f"{sm.patient_first_name or ''} {sm.patient_last_name or ''}".strip()
85
- text_parts.append(f"Patient: {patient_name}")
86
-
87
- if sm.patient_dob:
88
- text_parts.append(f"Date of Birth: {sm.patient_dob.date()}")
89
-
90
- if sm.patient_gender:
91
- text_parts.append(f"Gender: {sm.patient_gender}")
92
-
93
- # Examination information
94
- if sm.examination_date:
95
- text_parts.append(f"Examination Date: {sm.examination_date}")
96
-
97
- if sm.center:
98
- text_parts.append(f"Center: {sm.center.name}")
99
-
100
- # Equipment information
101
- if sm.endoscope_type:
102
- text_parts.append(f"Endoscope Type: {sm.endoscope_type}")
103
-
104
- if sm.endoscope_sn:
105
- text_parts.append(f"Endoscope SN: {sm.endoscope_sn}")
106
-
107
- # Examiner information
108
- if sm.pk: # Only if saved
109
- try:
110
- examiners = list(sm.examiners.all())
111
- if examiners:
112
- examiner_names = ", ".join(str(e) for e in examiners)
113
- text_parts.append(f"Examiners: {examiner_names}")
114
- except Exception:
115
- pass # Ignore examiner lookup errors
116
-
117
- text = "\n".join(text_parts)
118
-
119
- # Create anonymized version by replacing sensitive data
120
- anonym_text = text
121
- if sm.patient_first_name:
122
- anonym_text = anonym_text.replace(
123
- sm.patient_first_name, "[FIRST_NAME]"
124
- )
125
- if sm.patient_last_name:
126
- anonym_text = anonym_text.replace(
127
- sm.patient_last_name, "[LAST_NAME]"
128
- )
129
- if sm.patient_dob:
130
- anonym_text = anonym_text.replace(
131
- str(sm.patient_dob.date()), "[DOB]"
132
- )
133
- if sm.endoscope_sn:
134
- anonym_text = anonym_text.replace(sm.endoscope_sn, "[ENDOSCOPE_SN]")
135
-
136
- # Replace examiner names if available
137
- if sm.pk:
138
- try:
139
- examiners = list(sm.examiners.all())
140
- for examiner in examiners:
141
- anonym_text = anonym_text.replace(
142
- str(examiner), "[EXAMINER]"
143
- )
144
- except Exception:
145
- pass
146
-
147
68
  elif isinstance(instance, RawPdfFile):
148
- instance: RawPdfFile
149
69
  media_type = "pdf"
150
70
  created_at = instance.date_created
151
71
  filename = instance.file.name.split("/")[-1] if instance.file else "unknown"
152
72
 
153
- # ------- anonymization status using RawPdfState model (like VideoFile)
154
- ps = instance.state
73
+ # ------- anonymization status using RawPdfState model
74
+ rps = instance.get_or_create_state()
155
75
  anonym_status = (
156
- ps.anonymization_status if ps else PdfAnonymizationStatus.NOT_STARTED
76
+ rps.anonymization_status if rps else PdfAnonymizationState.NOT_STARTED
157
77
  )
158
78
 
159
- # PDF annotation == "sensitive meta validated"
79
+ # ------- annotation status (not applicable for PDFs)
160
80
  annot_status = (
161
- "done"
162
- if getattr(instance.sensitive_meta, "is_verified", False)
163
- else "not_started"
164
- )
165
-
166
- # Extract text content from PDF
167
- text = instance.text or ""
168
- anonym_text = instance.anonymized_text or ""
81
+ PdfAnonymizationState.VALIDATED if rps.anonymization_validated else PdfAnonymizationState.NOT_STARTED
82
+ )
169
83
 
170
84
  else: # shouldn't happen
171
85
  raise TypeError(f"Unsupported instance for overview: {type(instance)}")
@@ -177,6 +91,4 @@ class FileOverviewSerializer(serializers.Serializer):
177
91
  "anonymizationStatus": anonym_status,
178
92
  "annotationStatus": annot_status,
179
93
  "createdAt": created_at,
180
- "text": text,
181
- "anonymizedText": anonym_text,
182
94
  }
@@ -1,14 +1,14 @@
1
- from endoreg_db.models.media import RawPdfFile, VideoFile
2
-
3
-
4
1
  from rest_framework import serializers
5
2
 
6
- #TODO add this "naming convention" to the documentation
3
+ from endoreg_db.models.media import RawPdfFile, VideoFile
4
+
5
+ # TODO add this "naming convention" to the documentation
7
6
  # VoP: Video or Pdf
8
7
 
8
+
9
9
  class VoPPatientDataSerializer(serializers.Serializer):
10
10
  """
11
- Serializer that converts a VideoFile or RawPdfFile to the structure
11
+ Serializer that converts a VideoFile or RawPdfFile to the structure
12
12
  the Pinia store needs for validation workflow.
13
13
  """
14
14
 
@@ -24,12 +24,12 @@ class VoPPatientDataSerializer(serializers.Serializer):
24
24
  def to_representation(self, instance):
25
25
  """
26
26
  Serialize a VideoFile or RawPdfFile instance into a structured dictionary for validation workflows.
27
-
27
+
28
28
  Depending on the instance type, constructs a dictionary containing identifiers, sensitive metadata, text summaries, anonymized text, processing status, and error flag. For VideoFile instances, generates a text summary from associated sensitive metadata and anonymizes personal identifiers. For RawPdfFile instances, uses the instance's text fields directly. Raises a TypeError if the instance is neither type.
29
-
29
+
30
30
  Parameters:
31
31
  instance: A VideoFile or RawPdfFile model instance to serialize.
32
-
32
+
33
33
  Returns:
34
34
  dict: A structured representation of the instance suitable for Pinia store consumption.
35
35
  """
@@ -62,44 +62,62 @@ class VoPPatientDataSerializer(serializers.Serializer):
62
62
  # Create anonymized version
63
63
  anonym_text = text
64
64
  if sm.patient_first_name:
65
- anonym_text = anonym_text.replace(sm.patient_first_name, "[FIRST_NAME]")
65
+ anonym_text = anonym_text.replace(
66
+ sm.patient_first_name, "[FIRST_NAME]"
67
+ )
66
68
  if sm.patient_last_name:
67
- anonym_text = anonym_text.replace(sm.patient_last_name, "[LAST_NAME]")
69
+ anonym_text = anonym_text.replace(
70
+ sm.patient_last_name, "[LAST_NAME]"
71
+ )
68
72
  if sm.patient_dob:
69
- anonym_text = anonym_text.replace(str(sm.patient_dob.date()), "[DOB]")
73
+ anonym_text = anonym_text.replace(
74
+ str(sm.patient_dob.date()), "[DOB]"
75
+ )
70
76
 
71
77
  return {
72
78
  "id": instance.pk,
73
- "sensitiveMetaId": instance.sensitive_meta.pk if instance.sensitive_meta else None,
79
+ "sensitiveMetaId": instance.sensitive_meta.pk
80
+ if instance.sensitive_meta
81
+ else None,
74
82
  "text": text,
75
83
  "anonymizedText": anonym_text,
76
- "reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta) if instance.sensitive_meta else None,
77
- "status": "processing" if instance.state and instance.state.frames_extracted else "not_started",
84
+ "reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta)
85
+ if instance.sensitive_meta
86
+ else None,
87
+ "status": "processing"
88
+ if instance.state and instance.state.frames_extracted
89
+ else "not_started",
78
90
  "error": False,
79
91
  }
80
92
 
81
93
  elif isinstance(instance, RawPdfFile):
82
- # Generate PDF streaming URL using pdf_id (RawPdfFile.id)
83
- pdf_stream_url = f"/api/media/pdfs/{instance.pk}/stream/"
84
-
94
+ # Generate report streaming URL using pdf_id (RawPdfFile.id)
95
+ report_stream_url = f"/api/media/pdfs/{instance.pk}/stream/"
96
+
85
97
  return {
86
98
  "id": instance.pk,
87
- "sensitiveMetaId": instance.sensitive_meta.pk if instance.sensitive_meta else None,
99
+ "sensitiveMetaId": instance.sensitive_meta.pk
100
+ if instance.sensitive_meta
101
+ else None,
88
102
  "text": instance.text or "",
89
103
  "anonymizedText": instance.anonymized_text or "",
90
- "reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta) if instance.sensitive_meta else None,
104
+ "reportMeta": self._serialize_sensitive_meta(instance.sensitive_meta)
105
+ if instance.sensitive_meta
106
+ else None,
91
107
  "status": "done" if instance.anonymized_text else "not_started",
92
108
  "error": False,
93
- "pdfStreamUrl": pdf_stream_url,
109
+ "pdfStreamUrl": report_stream_url,
94
110
  }
95
111
 
96
112
  else:
97
- raise TypeError(f"Unsupported instance for VoPPatientDataSerializer: {type(instance)}")
113
+ raise TypeError(
114
+ f"Unsupported instance for VoPPatientDataSerializer: {type(instance)}"
115
+ )
98
116
 
99
117
  def _serialize_sensitive_meta(self, sensitive_meta):
100
118
  """
101
119
  Serialize a SensitiveMeta object into a dictionary with patient and examination details.
102
-
120
+
103
121
  Returns:
104
122
  dict or None: A dictionary containing patient and examination metadata fields, or None if sensitive_meta is not provided.
105
123
  """
@@ -110,11 +128,17 @@ class VoPPatientDataSerializer(serializers.Serializer):
110
128
  "id": sensitive_meta.pk,
111
129
  "patientFirstName": sensitive_meta.patient_first_name or "",
112
130
  "patientLastName": sensitive_meta.patient_last_name or "",
113
- "patientDob": sensitive_meta.patient_dob.isoformat() if sensitive_meta.patient_dob else "",
114
- "patientGender": str(sensitive_meta.patient_gender) if sensitive_meta.patient_gender else "",
115
- "examinationDate": sensitive_meta.examination_date.isoformat() if sensitive_meta.examination_date else "",
131
+ "patientDob": sensitive_meta.patient_dob.isoformat()
132
+ if sensitive_meta.patient_dob
133
+ else "",
134
+ "patientGender": str(sensitive_meta.patient_gender)
135
+ if sensitive_meta.patient_gender
136
+ else "",
137
+ "examinationDate": sensitive_meta.examination_date.isoformat()
138
+ if sensitive_meta.examination_date
139
+ else "",
116
140
  "centerName": sensitive_meta.center.name if sensitive_meta.center else "",
117
141
  "endoscopeType": sensitive_meta.endoscope_type or "",
118
142
  "endoscopeSn": sensitive_meta.endoscope_sn or "",
119
143
  "isVerified": getattr(sensitive_meta, "is_verified", False),
120
- }
144
+ }
@@ -135,7 +135,7 @@ class PatientExaminationSerializer(serializers.ModelSerializer):
135
135
 
136
136
  def get_findings(self, patient_examination_id):
137
137
  """Gibt die zugehörigen Befunde zurück"""
138
- obj = PatientExamination.get_or_create_patient_examination_by_id(PatientExamination, patient_examination_id)
138
+ pe = PatientExamination()
139
+ obj = pe.get_or_create_patient_examination_by_id(patient_examination_id)
139
140
  self.instance = obj
140
- response = PatientExaminationSerializer()
141
- return self.instance.patient_findings.all() if self.instance else []
141
+ return self.instance.get_available_findings() if self.instance else []