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,80 +0,0 @@
1
- from endoreg_db.models import RawPdfFile
2
-
3
-
4
- from django.http import Http404, HttpResponse
5
- from django.shortcuts import get_object_or_404
6
- from rest_framework import status
7
- from rest_framework.response import Response
8
- from rest_framework.views import APIView
9
-
10
-
11
- from pathlib import Path
12
- import logging
13
- from ...utils.paths import data_paths # Added for centralized path management
14
- logger = logging.getLogger(__name__)
15
-
16
-
17
-
18
- class SecureFileServingView(APIView):
19
- """
20
- Serviert Dateien über sichere URLs mit Token-Validierung
21
- GET /api/reports/{report_id}/secure-file/?token={token}
22
- """
23
-
24
- def get(self, request, report_id):
25
- token = request.GET.get('token')
26
-
27
- if not token:
28
- return Response(
29
- {"error": "Token ist erforderlich"},
30
- status=status.HTTP_400_BAD_REQUEST
31
- )
32
-
33
- try:
34
- report = get_object_or_404(RawPdfFile, id=report_id)
35
-
36
- if not report.file:
37
- raise Http404("Datei nicht gefunden")
38
-
39
- # Token validieren (hier würde normalerweise eine Token-Speicherung/Validierung stattfinden)
40
- # Für diese Implementierung nehmen wir an, dass das Token gültig ist
41
-
42
- # Datei servieren
43
- return self._serve_file(report.file)
44
-
45
- except (ValueError, TypeError, OSError) as e:
46
- logger.error("Fehler beim Servieren der Datei: %s", str(e))
47
- raise Http404("Datei konnte nicht geladen werden") from e
48
-
49
- def _serve_file(self, file_field):
50
- """Serviert die Datei als HTTP-Response"""
51
- try:
52
- file_path = Path(file_field.path)
53
-
54
- with open(file_field.path, 'rb') as f:
55
- response = HttpResponse(
56
- f.read(),
57
- content_type=self._get_content_type(file_path.suffix)
58
- )
59
- response['Content-Disposition'] = f'inline; filename="{file_path.name}"'
60
- return response
61
-
62
- except (OSError, IOError) as e:
63
- logger.error("Fehler beim Lesen der Datei: %s", str(e))
64
- raise Http404("Datei konnte nicht gelesen werden") from e
65
-
66
- def _get_content_type(self, file_extension):
67
- """Ermittelt den Content-Type basierend auf der Dateiendung"""
68
- content_types = {
69
- '.pdf': 'application/pdf',
70
- '.jpg': 'image/jpeg',
71
- '.jpeg': 'image/jpeg',
72
- '.png': 'image/png',
73
- '.gif': 'image/gif',
74
- '.bmp': 'image/bmp',
75
- '.webp': 'image/webp',
76
- '.txt': 'text/plain',
77
- '.doc': 'application/msword',
78
- '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
79
- }
80
- return content_types.get(file_extension.lower(), 'application/octet-stream')
@@ -1,84 +0,0 @@
1
- from endoreg_db.models import RawPdfFile
2
- from endoreg_db.serializers.report.secure_file_url import SecureFileUrlSerializer
3
-
4
- from django.shortcuts import get_object_or_404
5
- from django.utils import timezone
6
- from rest_framework import status
7
- from rest_framework.response import Response
8
- from rest_framework.views import APIView
9
-
10
-
11
- import uuid
12
- from datetime import timedelta
13
- from pathlib import Path
14
-
15
- import logging
16
- from ...utils.paths import data_paths # Added for centralized path management
17
- logger = logging.getLogger(__name__)
18
-
19
- class SecureFileUrlView(APIView):
20
- """
21
- API-Endpunkt für sichere URL-Generierung
22
- POST /api/secure-file-urls/
23
- """
24
-
25
- def post(self, request):
26
- report_id = request.data.get('report_id')
27
- file_type = request.data.get('file_type', 'pdf')
28
-
29
- if not report_id:
30
- return Response(
31
- {"error": "report_id ist erforderlich"},
32
- status=status.HTTP_400_BAD_REQUEST
33
- )
34
-
35
- try:
36
- report = get_object_or_404(RawPdfFile, id=report_id)
37
-
38
- if not report.file:
39
- return Response(
40
- {"error": "Keine Datei für diesen Report verfügbar"},
41
- status=status.HTTP_404_NOT_FOUND
42
- )
43
-
44
- # Sichere URL generieren
45
- secure_url_data = self._generate_secure_url(report, request, file_type)
46
- serializer = SecureFileUrlSerializer(data=secure_url_data)
47
-
48
- if serializer.is_valid():
49
- return Response(serializer.data)
50
- else:
51
- return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
52
-
53
- except (ValueError, TypeError) as e:
54
- logger.error("Fehler beim Generieren der sicheren URL: %s", str(e))
55
- return Response(
56
- {"error": "Sichere URL konnte nicht generiert werden"},
57
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
58
- )
59
-
60
- def _generate_secure_url(self, report, request, file_type):
61
- """Generiert eine sichere URL mit Token"""
62
- token = str(uuid.uuid4())
63
- expires_at = timezone.now() + timedelta(hours=2)
64
-
65
- secure_url = request.build_absolute_uri(
66
- f"/api/reports/{report.id}/secure-file/?token={token}"
67
- )
68
-
69
- # Dateigröße ermitteln
70
- file_size = 0
71
- try:
72
- if report.file:
73
- file_size = report.file.size
74
- except OSError:
75
- # Datei nicht verfügbar
76
- file_size = 0
77
-
78
- return {
79
- 'url': secure_url,
80
- 'expires_at': expires_at,
81
- 'file_type': file_type,
82
- 'original_filename': Path(report.file.name).name if report.file else 'unknown',
83
- 'file_size': file_size
84
- }
@@ -1,79 +0,0 @@
1
- # endoreg_db/views/misc/secure_url_validate.py
2
-
3
- from urllib.parse import urlparse
4
-
5
- from django.core.exceptions import ValidationError
6
- from django.core.validators import URLValidator
7
-
8
- from rest_framework import status
9
- from rest_framework.decorators import api_view, throttle_classes
10
- from rest_framework.response import Response
11
- from rest_framework.throttling import ScopedRateThrottle
12
-
13
- import logging
14
- logger = logging.getLogger(__name__)
15
-
16
- # Accept only http/https; adjust if you later need custom schemes
17
- _url_validator = URLValidator(schemes=["http", "https"])
18
- _MAX_URL_LENGTH = 2048 # pragmatic upper bound to avoid abuse
19
-
20
- @api_view(['GET'])
21
- @throttle_classes([ScopedRateThrottle]) # 429s will be returned automatically if exceeded
22
- def validate_secure_url(request):
23
- """
24
- Validiert eine sichere URL
25
- GET /api/validate-secure-url/?url={url}
26
- """
27
- url = request.GET.get('url')
28
-
29
- if not url:
30
- return Response(
31
- {"error": "URL Parameter ist erforderlich"},
32
- status=status.HTTP_400_BAD_REQUEST
33
- )
34
-
35
- # Basic length guardrails
36
- if len(url) > _MAX_URL_LENGTH:
37
- return Response(
38
- {"error": "URL ist zu lang"},
39
- status=status.HTTP_400_BAD_REQUEST
40
- )
41
-
42
- # Syntactic + scheme validation
43
- try:
44
- _url_validator(url)
45
- except ValidationError:
46
- return Response(
47
- {"error": "Ungültiges URL-Format (erlaubt sind http/https)"},
48
- status=status.HTTP_400_BAD_REQUEST
49
- )
50
-
51
- # Extra cheap sanity checks (netloc must exist, no data/file/javascript, etc.)
52
- parsed = urlparse(url)
53
- if not parsed.netloc:
54
- return Response(
55
- {"error": "Ungültige URL: Hostname fehlt"},
56
- status=status.HTTP_400_BAD_REQUEST
57
- )
58
-
59
- try:
60
- # Hier würde normalerweise eine Token-Validierung stattfinden
61
- # Für diese Implementierung geben wir immer True zurück
62
- is_valid = True
63
-
64
- return Response({
65
- "is_valid": is_valid,
66
- "message": "URL ist gültig" if is_valid else "URL ist ungültig oder abgelaufen"
67
- })
68
-
69
- except (ValueError, TypeError) as e:
70
- logger.error("Fehler bei URL-Validierung: %s", str(e))
71
- return Response(
72
- {"error": "URL-Validierung fehlgeschlagen"},
73
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
74
- )
75
-
76
- # Assign a throttle scope so we can configure a specific rate in settings
77
- validate_secure_url.throttle_scope = "secure-url-validate"
78
-
79
- # for update got to base_settings.py
@@ -1,164 +0,0 @@
1
- # from rest_framework import viewsets, status
2
- # from rest_framework.response import Response
3
- # from django.shortcuts import get_object_or_404
4
- # from endoreg_db.models import Examination, VideoFile, Finding, FindingClassification
5
- # from django.db import transaction
6
- # from django.utils import timezone
7
- # import logging
8
-
9
-
10
- # class VideoExaminationViewSet(viewsets.ModelViewSet):
11
- # """
12
- # ViewSet for Video Examination CRUD operations
13
- # Handles POST and PATCH for video examinations at timestamps
14
- # """
15
- # def get_queryset(self):
16
- # return []
17
-
18
- # def create(self, request, *args, **kwargs):
19
-
20
- # logger = logging.getLogger(__name__)
21
- # try:
22
- # data = request.data
23
- # required_fields = ['videoId', 'timestamp', 'examinationTypeId', 'findingId']
24
- # for field in required_fields:
25
- # if field not in data or data[field] is None:
26
- # return Response({'error': f'Missing or null required field: {field}'}, status=status.HTTP_400_BAD_REQUEST)
27
- # try:
28
- # video_id = int(data['videoId'])
29
- # timestamp = float(data['timestamp'])
30
- # examination_type_id = int(data['examinationTypeId'])
31
- # finding_id = int(data['findingId'])
32
- # except (ValueError, TypeError) as e:
33
- # return Response({'error': f'Invalid data type in request: {str(e)}'}, status=status.HTTP_400_BAD_REQUEST)
34
- # if timestamp < 0:
35
- # return Response({'error': 'Timestamp cannot be negative'}, status=status.HTTP_400_BAD_REQUEST)
36
- # with transaction.atomic():
37
- # try:
38
- # video = VideoFile.objects.get(id=video_id)
39
- # except VideoFile.DoesNotExist:
40
- # return Response({'error': 'Video not found'}, status=status.HTTP_404_NOT_FOUND)
41
- # try:
42
- # examination = Examination.objects.get(id=examination_type_id)
43
- # except Examination.DoesNotExist:
44
- # return Response({'error': 'Examination type not found'}, status=status.HTTP_404_NOT_FOUND)
45
- # try:
46
- # finding = Finding.objects.get(id=finding_id)
47
- # except Finding.DoesNotExist:
48
- # return Response({'error': 'Finding not found'}, status=status.HTTP_404_NOT_FOUND)
49
- # if data.get('locationClassificationId'):
50
- # try:
51
- # FindingClassification.objects.get(id=data['locationClassificationId'], classification_types__name__iexact="location")
52
- # except FindingClassification.DoesNotExist:
53
- # return Response({'error': 'Location classification not found'}, status=status.HTTP_404_NOT_FOUND)
54
- # if data.get('morphologyClassificationId'):
55
- # try:
56
- # FindingClassification.objects.get(id=data['morphologyClassificationId'], classification_types__name__iexact="morphology")
57
- # except FindingClassification.DoesNotExist:
58
- # return Response({'error': 'Morphology classification not found'}, status=status.HTTP_404_NOT_FOUND)
59
- # examination_data = {
60
- # 'id': f"exam_{video.id}_{timestamp}_{examination.id}",
61
- # 'video_id': video_id,
62
- # 'timestamp': timestamp,
63
- # 'examination_type': examination.name,
64
- # 'finding': finding.name,
65
- # 'location_classification': data.get('locationClassificationId'),
66
- # 'location_choice': data.get('locationChoiceId'),
67
- # 'morphology_classification': data.get('morphologyClassificationId'),
68
- # 'morphology_choice': data.get('morphologyChoiceId'),
69
- # 'interventions': data.get('interventionIds', []),
70
- # 'notes': data.get('notes', ''),
71
- # 'created_at': timezone.now().isoformat()
72
- # }
73
- # logger.info(f"Created video examination for video {video_id} at timestamp {timestamp}")
74
- # return Response(examination_data, status=status.HTTP_201_CREATED)
75
- # except Exception as e:
76
- # logger.error(f"Unexpected error creating examination: {str(e)}")
77
- # return Response({'error': 'Internal server error while creating examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
78
-
79
- # def update(self, request, *args, **kwargs):
80
- # logger = logging.getLogger(__name__)
81
- # try:
82
- # examination_id = kwargs.get('pk')
83
- # if not examination_id:
84
- # return Response({'error': 'Examination ID is required'}, status=status.HTTP_400_BAD_REQUEST)
85
- # data = request.data
86
- # if 'videoId' in data:
87
- # try:
88
- # data['videoId'] = int(data['videoId'])
89
- # except (ValueError, TypeError):
90
- # return Response({'error': 'Invalid videoId format'}, status=status.HTTP_400_BAD_REQUEST)
91
- # if 'timestamp' in data:
92
- # try:
93
- # timestamp = float(data['timestamp'])
94
- # if timestamp < 0:
95
- # return Response({'error': 'Timestamp cannot be negative'}, status=status.HTTP_400_BAD_REQUEST)
96
- # data['timestamp'] = timestamp
97
- # except (ValueError, TypeError):
98
- # return Response({'error': 'Invalid timestamp format'}, status=status.HTTP_400_BAD_REQUEST)
99
- # with transaction.atomic():
100
- # if 'videoId' in data:
101
- # try:
102
- # VideoFile.objects.get(id=data['videoId'])
103
- # except VideoFile.DoesNotExist:
104
- # return Response({'error': 'Video not found'}, status=status.HTTP_404_NOT_FOUND)
105
- # if 'examinationTypeId' in data:
106
- # try:
107
- # examination_type_id = int(data['examinationTypeId'])
108
- # Examination.objects.get(id=examination_type_id)
109
- # except (ValueError, TypeError):
110
- # return Response({'error': 'Invalid examination type ID format'}, status=status.HTTP_400_BAD_REQUEST)
111
- # except Examination.DoesNotExist:
112
- # return Response({'error': 'Examination type not found'}, status=status.HTTP_404_NOT_FOUND)
113
- # if 'findingId' in data:
114
- # try:
115
- # finding_id = int(data['findingId'])
116
- # Finding.objects.get(id=finding_id)
117
- # except (ValueError, TypeError):
118
- # return Response({'error': 'Invalid finding ID format'}, status=status.HTTP_400_BAD_REQUEST)
119
- # except Finding.DoesNotExist:
120
- # return Response({'error': 'Finding not found'}, status=status.HTTP_404_NOT_FOUND)
121
- # examination_data = {
122
- # 'id': examination_id,
123
- # 'video_id': data.get('videoId'),
124
- # 'timestamp': data.get('timestamp'),
125
- # 'examination_type': data.get('examinationTypeId'),
126
- # 'finding': data.get('findingId'),
127
- # 'location_classification': data.get('locationClassificationId'),
128
- # 'location_choice': data.get('locationChoiceId'),
129
- # 'morphology_classification': data.get('morphologyClassificationId'),
130
- # 'morphology_choice': data.get('morphologyChoiceId'),
131
- # 'interventions': data.get('interventionIds', []),
132
- # 'notes': data.get('notes', ''),
133
- # 'updated_at': '2024-01-01T00:00:00Z'
134
- # }
135
- # logger.info(f"Updated video examination {examination_id}")
136
- # return Response(examination_data, status=status.HTTP_200_OK)
137
- # except Exception as e:
138
- # logger.error(f"Unexpected error updating examination {examination_id}: {str(e)}")
139
- # return Response({'error': 'Internal server error while updating examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
140
-
141
- # def destroy(self, request, *args, **kwargs):
142
- # logger = logging.getLogger(__name__)
143
- # try:
144
- # examination_id = kwargs.get('pk')
145
- # if not examination_id:
146
- # return Response({'error': 'Examination ID is required'}, status=status.HTTP_400_BAD_REQUEST)
147
- # try:
148
- # if not str(examination_id).strip():
149
- # return Response({'error': 'Invalid examination ID format'}, status=status.HTTP_400_BAD_REQUEST)
150
- # except (ValueError, TypeError):
151
- # return Response({'error': 'Invalid examination ID format'}, status=status.HTTP_400_BAD_REQUEST)
152
- # with transaction.atomic():
153
- # logger.info(f"Deleted video examination {examination_id}")
154
- # return Response({'message': f'Examination {examination_id} deleted successfully'}, status=status.HTTP_204_NO_CONTENT)
155
- # except Exception as e:
156
- # logger.error(f"Unexpected error deleting examination {examination_id}: {str(e)}")
157
- # return Response({'error': 'Internal server error while deleting examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
158
-
159
- # from rest_framework.decorators import api_view
160
- # @api_view(["GET"])
161
- # def get_examinations_for_video(request, video_id):
162
- # _video = get_object_or_404(VideoFile, id=video_id)
163
- # #TODO no functionality implemented yet
164
- # return Response([])
@@ -1,5 +0,0 @@
1
- from .pfl_create import create_patient_finding_location
2
-
3
- __all__ = [
4
- "create_patient_finding_location",
5
- ]
@@ -1,70 +0,0 @@
1
- from endoreg_db.serializers.patient_finding.patient_finding import PatientFindingSerializer
2
- from rest_framework.viewsets import ModelViewSet
3
- from rest_framework.decorators import api_view, permission_classes
4
- from rest_framework.response import Response
5
- from rest_framework import status
6
- from endoreg_db.models.medical.patient.patient_finding import PatientFinding
7
- from endoreg_db.models.medical.patient.patient_finding_location import PatientFindingLocation
8
- from endoreg_db.models.medical.patient.patient_finding_morphology import PatientFindingMorphology
9
- from endoreg_db.models import ( FindingLocationClassificationChoice, FindingMorphologyClassificationChoice )
10
- from rest_framework import serializers
11
- from utils.permissions import EnvironmentAwarePermission
12
-
13
- class PatientFindingViewSet(ModelViewSet):
14
- queryset = PatientFinding.objects.all()
15
- serializer_class = PatientFindingSerializer
16
-
17
- @api_view(['POST'])
18
- @permission_classes([EnvironmentAwarePermission])
19
- def create_patient_finding_location(request):
20
- """
21
- Create a patient finding location relationship.
22
- Expected payload: {
23
- "patient_finding_id": 1,
24
- "location_classification_choice_id": 2
25
- }
26
- """
27
- try:
28
- patient_finding_id = request.data.get('patient_finding_id')
29
- choice_id = request.data.get('location_classification_choice_id')
30
-
31
- if not patient_finding_id or not choice_id:
32
- return Response(
33
- {'detail': 'patient_finding_id and location_classification_choice_id are required'},
34
- status=status.HTTP_400_BAD_REQUEST
35
- )
36
-
37
- # Get the objects
38
- try:
39
- patient_finding = PatientFinding.objects.get(id=patient_finding_id)
40
- except PatientFinding.DoesNotExist:
41
- return Response(
42
- {'detail': f'PatientFinding with id {patient_finding_id} not found'},
43
- status=status.HTTP_404_NOT_FOUND
44
- )
45
-
46
- try:
47
- choice = FindingLocationClassificationChoice.objects.get(id=choice_id)
48
- except FindingLocationClassificationChoice.DoesNotExist:
49
- return Response(
50
- {'detail': f'LocationClassificationChoice with id {choice_id} not found'},
51
- status=status.HTTP_404_NOT_FOUND
52
- )
53
-
54
- # Create the relationship
55
- patient_finding_location = PatientFindingLocation.objects.create(
56
- patient_finding=patient_finding,
57
- location_classification_choice=choice
58
- )
59
-
60
- return Response({
61
- 'id': patient_finding_location.id,
62
- 'patient_finding_id': patient_finding.id,
63
- 'location_classification_choice_id': choice.id
64
- }, status=status.HTTP_201_CREATED)
65
-
66
- except Exception as e:
67
- return Response(
68
- {'detail': f'Error creating patient finding location: {str(e)}'},
69
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
70
- )
@@ -1,5 +0,0 @@
1
- from .pfm_create import create_patient_finding_morphology
2
-
3
- __all__ = [
4
- "create_patient_finding_morphology",
5
- ]
@@ -1,70 +0,0 @@
1
- from endoreg_db.serializers.patient_finding.patient_finding import PatientFindingSerializer
2
- from rest_framework.viewsets import ModelViewSet
3
- from rest_framework.decorators import api_view, permission_classes
4
- from rest_framework.response import Response
5
- from rest_framework import status
6
- from endoreg_db.models.medical.patient.patient_finding import PatientFinding
7
- from endoreg_db.models.medical.patient.patient_finding_location import PatientFindingLocation
8
- from endoreg_db.models.medical.patient.patient_finding_morphology import PatientFindingMorphology
9
- from endoreg_db.models import ( FindingLocationClassificationChoice, FindingMorphologyClassificationChoice)
10
- from rest_framework import serializers
11
- from utils.permissions import EnvironmentAwarePermission
12
-
13
- class PatientFindingViewSet(ModelViewSet):
14
- queryset = PatientFinding.objects.all()
15
- serializer_class = PatientFindingSerializer
16
-
17
- @api_view(['POST'])
18
- @permission_classes([EnvironmentAwarePermission])
19
- def create_patient_finding_morphology(request):
20
- """
21
- Create a patient finding morphology relationship.
22
- Expected payload: {
23
- "patient_finding_id": 1,
24
- "morphology_classification_choice_id": 2
25
- }
26
- """
27
- try:
28
- patient_finding_id = request.data.get('patient_finding_id')
29
- choice_id = request.data.get('morphology_classification_choice_id')
30
-
31
- if not patient_finding_id or not choice_id:
32
- return Response(
33
- {'detail': 'patient_finding_id and morphology_classification_choice_id are required'},
34
- status=status.HTTP_400_BAD_REQUEST
35
- )
36
-
37
- # Get the objects
38
- try:
39
- patient_finding = PatientFinding.objects.get(id=patient_finding_id)
40
- except PatientFinding.DoesNotExist:
41
- return Response(
42
- {'detail': f'PatientFinding with id {patient_finding_id} not found'},
43
- status=status.HTTP_404_NOT_FOUND
44
- )
45
-
46
- try:
47
- choice = FindingMorphologyClassificationChoice.objects.get(id=choice_id)
48
- except FindingMorphologyClassificationChoice.DoesNotExist:
49
- return Response(
50
- {'detail': f'MorphologyClassificationChoice with id {choice_id} not found'},
51
- status=status.HTTP_404_NOT_FOUND
52
- )
53
-
54
- # Create the relationship
55
- patient_finding_morphology = PatientFindingMorphology.objects.create(
56
- patient_finding=patient_finding,
57
- morphology_classification_choice=choice
58
- )
59
-
60
- return Response({
61
- 'id': patient_finding_morphology.id,
62
- 'patient_finding_id': patient_finding.id,
63
- 'morphology_classification_choice_id': choice.id
64
- }, status=status.HTTP_201_CREATED)
65
-
66
- except Exception as e:
67
- return Response(
68
- {'detail': f'Error creating patient finding morphology: {str(e)}'},
69
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
70
- )
@@ -1,8 +0,0 @@
1
- from .reimport import PdfReimportView
2
- from .pdf_stream import PdfStreamView
3
-
4
-
5
- __all__ = [
6
- "PdfReimportView",
7
- "PdfStreamView",
8
- ]