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
@@ -1,64 +1,66 @@
1
1
  import mimetypes
2
+
2
3
  from django.http import Http404
3
4
  from django.urls import reverse
5
+ from django.utils.decorators import method_decorator
6
+ from django.views.decorators.csrf import csrf_exempt
4
7
  from rest_framework import status
5
- from rest_framework.views import APIView
6
- from rest_framework.response import Response
7
- from rest_framework.parsers import MultiPartParser, FormParser
8
+ from rest_framework.parsers import FormParser, MultiPartParser
8
9
  from rest_framework.permissions import AllowAny
9
- from django.views.decorators.csrf import csrf_exempt
10
- from django.utils.decorators import method_decorator
10
+ from rest_framework.response import Response
11
+ from rest_framework.views import APIView
11
12
 
12
13
  # Try to import python-magic, but provide fallback if not available
13
14
  try:
14
15
  import magic
16
+
15
17
  MAGIC_AVAILABLE = True
16
18
  except ImportError:
17
19
  MAGIC_AVAILABLE = False
18
20
 
19
21
  from endoreg_db.models.upload_job import UploadJob
20
- from endoreg_db.serializers.misc.upload_job import (
21
- UploadJobStatusSerializer,
22
- )
22
+ from endoreg_db.serializers.misc.upload_job import UploadJobStatusSerializer
23
23
 
24
24
  # Try to import celery task, but provide fallback
25
25
  try:
26
26
  from endoreg_db.tasks.upload_tasks import process_upload_job
27
+
27
28
  CELERY_AVAILABLE = True
28
29
  except ImportError:
29
30
  CELERY_AVAILABLE = False
31
+
30
32
  # Define a dummy function for development
31
33
  def process_upload_job(job_id):
32
34
  pass
33
35
 
34
36
 
35
- @method_decorator(csrf_exempt, name='dispatch')
37
+ @method_decorator(csrf_exempt, name="dispatch")
36
38
  class UploadFileView(APIView):
37
39
  """
38
40
  Handle file uploads (POST /api/upload/).
39
-
40
- Accepts multipart/form-data with a 'file' field containing PDF or video files.
41
+
42
+ Accepts multipart/form-data with a 'file' field containing report or video files.
41
43
  Creates an UploadJob and starts asynchronous processing.
42
-
44
+
43
45
  Returns:
44
46
  201 Created: {"upload_id": "<uuid>", "status_url": "/api/upload/<uuid>/status/"}
45
47
  400 Bad Request: File validation errors
46
48
  """
47
-
49
+
48
50
  parser_classes = [MultiPartParser, FormParser]
49
51
  permission_classes = [AllowAny] # Adjust based on your auth requirements
50
-
52
+
51
53
  # Maximum file size (1 GiB)
52
54
  MAX_FILE_SIZE = 1024 * 1024 * 1024 # 1 GiB in bytes
53
-
55
+
54
56
  # Allowed MIME types
55
57
  ALLOWED_MIME_TYPES = {
56
- 'application/pdf',
57
- 'video/mp4',
58
- 'video/avi',
59
- 'video/quicktime',
60
- 'video/x-msvideo',
61
- 'video/x-ms-wmv'
58
+ "application/pdf",
59
+ "video/mp4",
60
+ "video/avi",
61
+ "video/quicktime",
62
+ "video/x-msvideo",
63
+ "video/x-ms-wmv",
62
64
  }
63
65
 
64
66
  def post(self, request, *args, **kwargs):
@@ -66,93 +68,95 @@ class UploadFileView(APIView):
66
68
  Handle file upload and create processing job.
67
69
  """
68
70
  # Validate file presence
69
- if 'file' not in request.FILES:
71
+ if "file" not in request.FILES:
70
72
  return Response(
71
- {'error': 'No file provided. Please include a file in the "file" field.'},
72
- status=status.HTTP_400_BAD_REQUEST
73
+ {
74
+ "error": 'No file provided. Please include a file in the "file" field.'
75
+ },
76
+ status=status.HTTP_400_BAD_REQUEST,
73
77
  )
74
-
75
- uploaded_file = request.FILES['file']
76
-
78
+
79
+ uploaded_file = request.FILES["file"]
80
+
77
81
  # Validate file is not empty
78
82
  if not uploaded_file or uploaded_file.size == 0:
79
83
  return Response(
80
- {'error': 'Uploaded file is empty. Please select a valid file.'},
81
- status=status.HTTP_400_BAD_REQUEST
84
+ {"error": "Uploaded file is empty. Please select a valid file."},
85
+ status=status.HTTP_400_BAD_REQUEST,
82
86
  )
83
-
87
+
84
88
  # Validate file size
85
89
  if uploaded_file.size > self.MAX_FILE_SIZE:
86
90
  return Response(
87
- {'error': f'File too large. Maximum size is {self.MAX_FILE_SIZE // (1024**3)} GB.'},
88
- status=status.HTTP_400_BAD_REQUEST
91
+ {
92
+ "error": f"File too large. Maximum size is {self.MAX_FILE_SIZE // (1024**3)} GB."
93
+ },
94
+ status=status.HTTP_400_BAD_REQUEST,
89
95
  )
90
-
96
+
91
97
  # Validate filename
92
- if not uploaded_file.name or uploaded_file.name.strip() == '':
98
+ if not uploaded_file.name or uploaded_file.name.strip() == "":
93
99
  return Response(
94
- {'error': 'Invalid filename. Please ensure the file has a valid name.'},
95
- status=status.HTTP_400_BAD_REQUEST
100
+ {"error": "Invalid filename. Please ensure the file has a valid name."},
101
+ status=status.HTTP_400_BAD_REQUEST,
96
102
  )
97
-
103
+
98
104
  # Detect MIME type
99
105
  try:
100
106
  content_type = self._detect_mime_type(uploaded_file)
101
107
  except Exception as e:
102
108
  return Response(
103
- {'error': f'Could not determine file type: {str(e)}'},
104
- status=status.HTTP_400_BAD_REQUEST
109
+ {"error": f"Could not determine file type: {str(e)}"},
110
+ status=status.HTTP_400_BAD_REQUEST,
105
111
  )
106
-
112
+
107
113
  # Validate MIME type
108
114
  if content_type not in self.ALLOWED_MIME_TYPES:
109
115
  return Response(
110
- {'error': f'Unsupported file type: {content_type}. Allowed types: PDF, MP4, AVI, MOV, WMV.'},
111
- status=status.HTTP_400_BAD_REQUEST
116
+ {
117
+ "error": f"Unsupported file type: {content_type}. Allowed types: report, MP4, AVI, MOV, WMV."
118
+ },
119
+ status=status.HTTP_400_BAD_REQUEST,
112
120
  )
113
-
121
+
114
122
  try:
115
123
  # Create upload job
116
124
  upload_job = UploadJob.objects.create(
117
- file=uploaded_file,
118
- content_type=content_type
125
+ file=uploaded_file, content_type=content_type
119
126
  )
120
-
127
+
121
128
  # Start asynchronous processing if Celery is available
122
129
  if CELERY_AVAILABLE:
123
130
  try:
124
131
  process_upload_job.delay(str(upload_job.id))
125
132
  except Exception as e:
126
133
  # If Celery task fails to start, mark job as failed
127
- upload_job.mark_failed(f'Failed to start processing: {str(e)}')
134
+ upload_job.mark_failed(f"Failed to start processing: {str(e)}")
128
135
  return Response(
129
- {'error': f'Failed to start processing: {str(e)}'},
130
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
136
+ {"error": f"Failed to start processing: {str(e)}"},
137
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR,
131
138
  )
132
139
  else:
133
140
  # For development without Celery, mark as processing immediately
134
141
  upload_job.mark_processing()
135
142
  # In production, this would be handled by Celery
136
143
  # For now, just leave it in processing state
137
-
144
+
138
145
  # Prepare response
139
- status_url = reverse('upload_status', kwargs={'id': upload_job.id})
146
+ status_url = reverse("upload_status", kwargs={"id": upload_job.id})
140
147
  response_data = {
141
- 'upload_id': str(upload_job.id), # Ensure UUID is converted to string
142
- 'status_url': status_url,
143
- 'message': 'Upload job created successfully'
148
+ "upload_id": str(upload_job.id), # Ensure UUID is converted to string
149
+ "status_url": status_url,
150
+ "message": "Upload job created successfully",
144
151
  }
145
-
152
+
146
153
  # Return the response data directly since serializer fields are read-only
147
- return Response(
148
- response_data,
149
- status=status.HTTP_201_CREATED
150
- )
151
-
154
+ return Response(response_data, status=status.HTTP_201_CREATED)
155
+
152
156
  except Exception as e:
153
157
  return Response(
154
- {'error': f'Failed to create upload job: {str(e)}'},
155
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
158
+ {"error": f"Failed to create upload job: {str(e)}"},
159
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR,
156
160
  )
157
161
 
158
162
  def _detect_mime_type(self, uploaded_file) -> str:
@@ -163,39 +167,39 @@ class UploadFileView(APIView):
163
167
  try:
164
168
  # Reset file pointer
165
169
  uploaded_file.seek(0)
166
-
170
+
167
171
  # Try python-magic first (more reliable) if available
168
172
  if MAGIC_AVAILABLE:
169
173
  try:
170
174
  # Read first chunk for magic detection
171
175
  chunk = uploaded_file.read(2048)
172
176
  uploaded_file.seek(0) # Reset again
173
-
177
+
174
178
  mime_type = magic.from_buffer(chunk, mime=True)
175
- if mime_type and mime_type != 'application/octet-stream':
179
+ if mime_type and mime_type != "application/octet-stream":
176
180
  return mime_type
177
181
  except Exception:
178
182
  pass # Fall back to mimetypes
179
-
183
+
180
184
  # Fallback to mimetypes module
181
185
  mime_type, _ = mimetypes.guess_type(uploaded_file.name)
182
186
  if mime_type:
183
187
  return mime_type
184
-
188
+
185
189
  # Last resort - check file extension
186
- if uploaded_file.name.lower().endswith('.pdf'):
187
- return 'application/pdf'
188
- elif uploaded_file.name.lower().endswith(('.mp4', '.m4v')):
189
- return 'video/mp4'
190
- elif uploaded_file.name.lower().endswith('.avi'):
191
- return 'video/avi'
192
- elif uploaded_file.name.lower().endswith(('.mov', '.qt')):
193
- return 'video/quicktime'
194
- elif uploaded_file.name.lower().endswith('.wmv'):
195
- return 'video/x-ms-wmv'
196
-
190
+ if uploaded_file.name.lower().endswith(".pdf"):
191
+ return "application/pdf"
192
+ elif uploaded_file.name.lower().endswith((".mp4", ".m4v")):
193
+ return "video/mp4"
194
+ elif uploaded_file.name.lower().endswith(".avi"):
195
+ return "video/avi"
196
+ elif uploaded_file.name.lower().endswith((".mov", ".qt")):
197
+ return "video/quicktime"
198
+ elif uploaded_file.name.lower().endswith(".wmv"):
199
+ return "video/x-ms-wmv"
200
+
197
201
  raise ValueError("Could not determine file type")
198
-
202
+
199
203
  finally:
200
204
  # Ensure file pointer is reset
201
205
  uploaded_file.seek(0)
@@ -204,15 +208,15 @@ class UploadFileView(APIView):
204
208
  class UploadStatusView(APIView):
205
209
  """
206
210
  Get upload job status (GET /api/upload/<uuid>/status/).
207
-
211
+
208
212
  Returns current processing status and relevant metadata.
209
213
  Should be polled every 2 seconds by the frontend.
210
-
214
+
211
215
  Returns:
212
216
  200 OK: Status information
213
217
  404 Not Found: Upload job not found
214
218
  """
215
-
219
+
216
220
  permission_classes = [AllowAny] # Adjust based on your auth requirements
217
221
 
218
222
  def get(self, request, id, *args, **kwargs):
@@ -221,20 +225,17 @@ class UploadStatusView(APIView):
221
225
  """
222
226
  try:
223
227
  # Look up upload job by UUID
224
- upload_job = UploadJob.objects.select_related('sensitive_meta').get(id=id)
225
-
228
+ upload_job = UploadJob.objects.select_related("sensitive_meta").get(id=id)
229
+
226
230
  # Serialize the response
227
231
  serializer = UploadJobStatusSerializer(upload_job)
228
-
229
- return Response(
230
- serializer.data,
231
- status=status.HTTP_200_OK
232
- )
233
-
232
+
233
+ return Response(serializer.data, status=status.HTTP_200_OK)
234
+
234
235
  except UploadJob.DoesNotExist:
235
236
  raise Http404("Upload job not found")
236
237
  except Exception as e:
237
238
  return Response(
238
- {'error': f'Failed to get upload status: {str(e)}'},
239
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
240
- )
239
+ {"error": f"Failed to get upload status: {str(e)}"},
240
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR,
241
+ )
@@ -6,11 +6,11 @@ from rest_framework import viewsets, status, serializers
6
6
  from rest_framework.response import Response
7
7
  from rest_framework.decorators import action
8
8
 
9
-
9
+ from endoreg_db.authz.permissions import PolicyPermission
10
10
  from endoreg_db.models import Patient
11
11
  from endoreg_db.serializers.patient import PatientSerializer
12
12
  from endoreg_db.models.medical.patient.patient_examination import PatientExamination
13
-
13
+ from rest_framework.permissions import IsAuthenticated
14
14
  @staff_member_required # Ensures only staff members can access the page
15
15
  def start_examination(request):
16
16
  return render(request, 'admin/start_examination.html') # Loads the simple HTML page
@@ -21,8 +21,9 @@ class PatientViewSet(viewsets.ModelViewSet):
21
21
  """API endpoint for managing patients."""
22
22
  queryset = Patient.objects.all()
23
23
  serializer_class = PatientSerializer
24
- #permission_classes = [IsAuthenticatedOrReadOnly]
25
-
24
+ permission_classes = [PolicyPermission]
25
+ #permission_classes = [PolicyPermission]
26
+
26
27
  def perform_create(self, serializer):
27
28
  """Erweiterte Validierung beim Erstellen eines Patienten"""
28
29
  try:
@@ -1,9 +1,7 @@
1
- from .report_list import ReportListView
2
- from .report_with_secure_url import ReportWithSecureUrlView
3
- from .start_examination import start_examination
1
+ from .reimport import ReportReimportView
2
+ from .report_stream import ReportStreamView
4
3
 
5
4
  __all__ = [
6
- "ReportListView",
7
- "ReportWithSecureUrlView",
8
- "start_examination",
9
- ]
5
+ "ReportReimportView",
6
+ "ReportStreamView",
7
+ ]
@@ -6,12 +6,12 @@ from rest_framework.response import Response
6
6
  from rest_framework.views import APIView
7
7
 
8
8
  from ...models import RawPdfFile, SensitiveMeta
9
- from ...services.pdf_import import PdfImportService
9
+ from endoreg_db.services.report_import import ReportImportService
10
10
 
11
11
  logger = logging.getLogger(__name__)
12
12
 
13
13
 
14
- class PdfReimportView(APIView):
14
+ class ReportReimportView(APIView):
15
15
  """
16
16
  API endpoint to re-import a pdf file and regenerate metadata.
17
17
  This is useful when OCR failed or metadata is incomplete.
@@ -19,7 +19,7 @@ class PdfReimportView(APIView):
19
19
 
20
20
  def __init__(self, **kwargs):
21
21
  super().__init__(**kwargs)
22
- self.pdf_service = PdfImportService()
22
+ self.pdf_service = ReportImportService()
23
23
 
24
24
  def post(self, request, pk):
25
25
  """
@@ -28,24 +28,24 @@ class PdfReimportView(APIView):
28
28
 
29
29
  Args:
30
30
  request: HTTP request object
31
- pk: PDF primary key (ID)
31
+ pk: report primary key (ID)
32
32
  """
33
33
  pdf_id = pk # Align with media framework naming convention
34
34
 
35
35
  # Validate pdf_id parameter
36
36
  if not pdf_id or not isinstance(pdf_id, int):
37
37
  return Response(
38
- {"error": "Invalid PDF ID provided."},
38
+ {"error": "Invalid report ID provided."},
39
39
  status=status.HTTP_400_BAD_REQUEST,
40
40
  )
41
41
 
42
42
  try:
43
43
  pdf = RawPdfFile.objects.get(id=pdf_id)
44
- logger.info(f"Found PDF {pdf.pdf_hash} (ID: {pdf_id}) for re-import")
44
+ logger.info(f"Found report {pdf.pdf_hash} (ID: {pdf_id}) for re-import")
45
45
  except RawPdfFile.DoesNotExist:
46
- logger.warning(f"PDF with ID {pdf_id} not found")
46
+ logger.warning(f"report with ID {pdf_id} not found")
47
47
  return Response(
48
- {"error": f"PDF with ID {pdf_id} not found."},
48
+ {"error": f"report with ID {pdf_id} not found."},
49
49
  status=status.HTTP_404_NOT_FOUND,
50
50
  )
51
51
 
@@ -54,25 +54,25 @@ class PdfReimportView(APIView):
54
54
 
55
55
  if not raw_file_path or not raw_file_path.exists():
56
56
  logger.error(
57
- f"Raw PDF file not found for hash {pdf.pdf_hash}: {raw_file_path}"
57
+ f"Raw report file not found for hash {pdf.pdf_hash}: {raw_file_path}"
58
58
  )
59
59
  return Response(
60
60
  {
61
- "error": f"Raw PDF file not found for PDF {pdf.pdf_hash}. Please upload the original file again."
61
+ "error": f"Raw report file not found for report {pdf.pdf_hash}. Please upload the original file again."
62
62
  },
63
63
  status=status.HTTP_404_NOT_FOUND,
64
64
  )
65
65
 
66
- # Check if PDF has required relationships
66
+ # Check if report has required relationships
67
67
  if not pdf.center:
68
- logger.warning(f"PDF {pdf.pdf_hash} has no associated center")
68
+ logger.warning(f"report {pdf.pdf_hash} has no associated center")
69
69
  return Response(
70
- {"error": "PDF has no associated center."},
70
+ {"error": "report has no associated center."},
71
71
  status=status.HTTP_400_BAD_REQUEST,
72
72
  )
73
73
 
74
74
  try:
75
- logger.info(f"Starting re-import for PDF {pdf.pdf_hash} (ID: {pdf_id})")
75
+ logger.info(f"Starting re-import for report {pdf.pdf_hash} (ID: {pdf_id})")
76
76
 
77
77
  with transaction.atomic():
78
78
  # Clear existing metadata to force regeneration
@@ -80,9 +80,9 @@ class PdfReimportView(APIView):
80
80
  if pdf.sensitive_meta:
81
81
  old_meta_id = pdf.sensitive_meta.pk
82
82
  logger.info(
83
- f"Clearing existing SensitiveMeta {old_meta_id} for PDF {pdf.pdf_hash}"
83
+ f"Clearing existing SensitiveMeta {old_meta_id} for report {pdf.pdf_hash}"
84
84
  )
85
- pdf.sensitive_meta = None # type: ignore
85
+ pdf.sensitive_meta = None
86
86
  pdf.save(update_fields=["sensitive_meta"])
87
87
 
88
88
  # Delete the old SensitiveMeta record
@@ -94,10 +94,10 @@ class PdfReimportView(APIView):
94
94
  f"Could not delete old SensitiveMeta {old_meta_id}: {e}"
95
95
  )
96
96
 
97
- # Use PdfImportService for reprocessing
97
+ # Use ReportImportService for reprocessing
98
98
  try:
99
99
  logger.info(
100
- f"Starting reprocessing using PdfImportService for {pdf.pdf_hash}"
100
+ f"Starting reprocessing using ReportImportService for {pdf.pdf_hash}"
101
101
  )
102
102
  self.pdf_service.import_and_anonymize(
103
103
  file_path=raw_file_path,
@@ -107,7 +107,7 @@ class PdfReimportView(APIView):
107
107
  )
108
108
 
109
109
  logger.info(
110
- f"PdfImportService reprocessing completed for {pdf.pdf_hash}"
110
+ f"ReportImportService reprocessing completed for {pdf.pdf_hash}"
111
111
  )
112
112
 
113
113
  # Refresh to get updated state
@@ -115,7 +115,7 @@ class PdfReimportView(APIView):
115
115
 
116
116
  return Response(
117
117
  {
118
- "message": "PDF re-import completed successfully.",
118
+ "message": "report re-import completed successfully.",
119
119
  "pdf_id": pdf_id,
120
120
  "pdf_hash": str(pdf.pdf_hash),
121
121
  "sensitive_meta_created": pdf.sensitive_meta is not None,
@@ -131,7 +131,7 @@ class PdfReimportView(APIView):
131
131
 
132
132
  except Exception as e:
133
133
  logger.exception(
134
- f"PdfImportService reprocessing failed for PDF {pdf.pdf_hash}: {e}"
134
+ f"ReportImportService reprocessing failed for report {pdf.pdf_hash}: {e}"
135
135
  )
136
136
  return Response(
137
137
  {
@@ -145,7 +145,7 @@ class PdfReimportView(APIView):
145
145
 
146
146
  except Exception as e:
147
147
  logger.error(
148
- f"Failed to re-import PDF {pdf.pdf_hash}: {str(e)}", exc_info=True
148
+ f"Failed to re-import report {pdf.pdf_hash}: {str(e)}", exc_info=True
149
149
  )
150
150
 
151
151
  # Handle specific error types