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,19 +1,22 @@
1
- from django.db import models
2
- import pandas as pd
3
1
  from typing import TYPE_CHECKING
4
2
 
3
+ import pandas as pd
4
+ from django.db import models
5
+
5
6
  if TYPE_CHECKING:
6
- from .product import Product
7
7
  from ...other.unit import Unit
8
+ from .product import Product
9
+
8
10
 
9
11
  class ProductWeightManager(models.Manager):
10
12
  def get_by_natural_key(self, product, product_group, weight):
11
13
  return self.get(product=product, product_group=product_group, weight=weight)
12
-
14
+
15
+
13
16
  class ProductWeight(models.Model):
14
17
  objects = ProductWeightManager()
15
18
 
16
- name = models.CharField(max_length=255, null = True)
19
+ name = models.CharField(max_length=255, null=True)
17
20
  product = models.ForeignKey("Product", on_delete=models.CASCADE)
18
21
  measured = models.FloatField(null=True)
19
22
  verified = models.FloatField(null=True)
@@ -21,8 +24,8 @@ class ProductWeight(models.Model):
21
24
  unit = models.ForeignKey("Unit", on_delete=models.SET_NULL, null=True)
22
25
 
23
26
  if TYPE_CHECKING:
24
- product: "Product"
25
- unit: "Unit"
27
+ product: models.ForeignKey["Product"]
28
+ unit: models.ForeignKey["Unit|None"]
26
29
 
27
30
  def get_weight(self):
28
31
  if not pd.isnull(self.verified):
@@ -33,7 +36,7 @@ class ProductWeight(models.Model):
33
36
  return self.manufacturer
34
37
  else:
35
38
  return None
36
-
39
+
37
40
  def get_weight_source(self):
38
41
  if not pd.isnull(self.verified):
39
42
  return "verified"
@@ -43,5 +46,6 @@ class ProductWeight(models.Model):
43
46
  return "manufacturer"
44
47
  else:
45
48
  return None
49
+
46
50
  def __str__(self):
47
51
  return f"{self.product} - {self.get_weight()} {self.unit} (Source: {self.get_weight_source()})"
@@ -1,13 +1,18 @@
1
- from django.db import models
2
1
  from typing import TYPE_CHECKING
2
+
3
+ from django.db import models
4
+
3
5
  if TYPE_CHECKING:
4
6
  from ...other.emission import EmissionFactor
5
7
  from .product import Product
6
8
  from .product_group import ProductGroup
9
+
10
+
7
11
  class ReferenceProductManager(models.Manager):
8
- def get_by_natural_key(self, product_name:str, product_group_name:str):
12
+ def get_by_natural_key(self, product_name: str, product_group_name: str):
9
13
  return self.get(product__name=product_name, product_group__name=product_group_name)
10
14
 
15
+
11
16
  class ReferenceProduct(models.Model):
12
17
  name = models.CharField(max_length=255)
13
18
  product = models.ForeignKey(
@@ -18,51 +23,32 @@ class ReferenceProduct(models.Model):
18
23
  product_group = models.OneToOneField(
19
24
  "ProductGroup",
20
25
  on_delete=models.CASCADE,
21
- related_name="reference_product" # Changed from "reference_products"
22
- )
23
- emission_factor_total = models.ForeignKey(
24
- "EmissionFactor",
25
- on_delete=models.SET_NULL,
26
- null=True,
27
- blank = True,
28
- related_name="reference_products"
29
- )
30
- emission_factor_package = models.ForeignKey(
31
- "EmissionFactor",
32
- on_delete=models.SET_NULL,
33
- null=True,
34
- related_name="reference_product_package"
35
- )
36
- emission_factor_product = models.ForeignKey(
37
- "EmissionFactor",
38
- on_delete=models.SET_NULL,
39
- null=True,
40
- related_name="reference_product_product"
26
+ related_name="reference_product", # Changed from "reference_products"
41
27
  )
28
+ emission_factor_total = models.ForeignKey("EmissionFactor", on_delete=models.SET_NULL, null=True, blank=True, related_name="reference_products")
29
+ emission_factor_package = models.ForeignKey("EmissionFactor", on_delete=models.SET_NULL, null=True, related_name="reference_product_package")
30
+ emission_factor_product = models.ForeignKey("EmissionFactor", on_delete=models.SET_NULL, null=True, related_name="reference_product_product")
42
31
 
43
32
  if TYPE_CHECKING:
44
- product: "Product"
45
- product_group: "ProductGroup"
46
- emission_factor_total: "EmissionFactor"
47
- emission_factor_package: "EmissionFactor"
48
- emission_factor_product: "EmissionFactor"
49
-
33
+ product: models.ForeignKey["Product"]
34
+ product_group: models.ForeignKey["ProductGroup"]
35
+ emission_factor_total: models.ForeignKey["EmissionFactor|None"]
36
+ emission_factor_package: models.ForeignKey["EmissionFactor|None"]
37
+ emission_factor_product: models.ForeignKey["EmissionFactor|None"]
38
+
50
39
  objects = ReferenceProductManager()
51
40
 
52
41
  def __str__(self):
53
42
  return self.product.name + " (" + self.product_group.name + ")"
54
-
43
+
55
44
  def set_emission_factors(self):
56
45
  from ...other.emission import EmissionFactor
46
+
57
47
  product = self.product
58
- materials = product.product_materials.all()
59
48
  emission_factor_name = f"{self.product_group.name}_{product.name}_total_emission_factor"
60
49
  emission_factor_package_name = f"{self.product_group.name}_{product.name}_package_emission_factor"
61
50
  emission_factor_product_name = f"{self.product_group.name}_{product.name}_product_emission_factor"
62
51
 
63
- product_emissions = 0
64
- package_emissions = 0
65
-
66
52
  product_weight, product_weight_unit = product.get_product_material_weight()
67
53
  package_weight, package_weight_unit = product.get_package_material_weight()
68
54
  product_emission, product_emission_unit = product.get_product_material_emission()
@@ -81,38 +67,23 @@ class ReferenceProduct(models.Model):
81
67
  total_emission_factor_value = total_emission / total_weight
82
68
 
83
69
  emission_factor, created = EmissionFactor.objects.get_or_create(
84
- name=emission_factor_name,
85
- defaults={
86
- "name": emission_factor_name,
87
- "value": total_emission_factor_value,
88
- "unit": reference_unit
89
- }
70
+ name=emission_factor_name, defaults={"name": emission_factor_name, "value": total_emission_factor_value, "unit": reference_unit}
90
71
  )
91
72
  self.emission_factor_total = emission_factor
92
73
 
93
74
  emission_factor_package, created = EmissionFactor.objects.get_or_create(
94
- name=emission_factor_package_name,
95
- defaults={
96
- "name": emission_factor_package_name,
97
- "value": package_emission_factor_value,
98
- "unit": reference_unit
99
- }
75
+ name=emission_factor_package_name, defaults={"name": emission_factor_package_name, "value": package_emission_factor_value, "unit": reference_unit}
100
76
  )
101
77
  self.emission_factor_package = emission_factor_package
102
78
 
103
79
  emission_factor_product, created = EmissionFactor.objects.get_or_create(
104
- name=emission_factor_product_name,
105
- defaults={
106
- "name": emission_factor_product_name,
107
- "value": product_emission_factor_value,
108
- "unit": reference_unit
109
- }
80
+ name=emission_factor_product_name, defaults={"name": emission_factor_product_name, "value": product_emission_factor_value, "unit": reference_unit}
110
81
  )
111
82
  self.emission_factor_product = emission_factor_product
112
83
 
113
84
  self.save()
114
85
 
115
- def get_emission_factor(self, component:str):
86
+ def get_emission_factor(self, component: str):
116
87
  # check if emission_factor_total exists:
117
88
  if self.emission_factor_total is None:
118
89
  self.set_emission_factors()
@@ -125,6 +96,3 @@ class ReferenceProduct(models.Model):
125
96
  return self.emission_factor_product
126
97
  else:
127
98
  raise Exception("Unknown component: " + component)
128
-
129
-
130
-
@@ -1,22 +1,26 @@
1
+ from typing import TYPE_CHECKING, cast
2
+
1
3
  from django.db import models
2
- from typing import TYPE_CHECKING
3
4
 
4
5
  if TYPE_CHECKING:
5
6
  from endoreg_db.models import (
6
7
  QualificationType,
7
8
  )
8
9
 
10
+
9
11
  class QualificationManager(models.Manager):
10
12
  def get_queryset(self):
11
13
  """
12
14
  Returns a queryset of qualifications filtered to include only active entries.
13
15
  """
14
16
  return super().get_queryset().filter(is_active=True)
15
-
17
+
18
+
16
19
  class Qualification(models.Model):
17
20
  """
18
21
  Model representing a qualification.
19
22
  """
23
+
20
24
  name = models.CharField(max_length=255, unique=True)
21
25
  description = models.TextField(blank=True, null=True)
22
26
  is_active = models.BooleanField(default=True)
@@ -26,7 +30,7 @@ class Qualification(models.Model):
26
30
  related_name="qualifications",
27
31
  )
28
32
  if TYPE_CHECKING:
29
- qualification_types: models.QuerySet["QualificationType"]
33
+ qualification_types = cast(models.manager.RelatedManager["QualificationType"], qualification_types)
30
34
 
31
35
  objects = QualificationManager()
32
36
 
@@ -1,24 +1,28 @@
1
- from django.db import models
2
1
  from typing import TYPE_CHECKING
3
2
 
3
+ from django.db import models
4
+
4
5
  if TYPE_CHECKING:
5
6
  from endoreg_db.models import (
6
7
  Qualification,
7
8
  )
8
9
 
10
+
9
11
  class QualificationTypeManager(models.Manager):
10
12
  def get_queryset(self):
11
13
  """
12
14
  Returns a queryset of active qualification types.
13
-
15
+
14
16
  Only includes records where the `is_active` field is set to True.
15
17
  """
16
18
  return super().get_queryset().filter(is_active=True)
17
-
19
+
20
+
18
21
  class QualificationType(models.Model):
19
22
  """
20
23
  Model representing a qualification type.
21
24
  """
25
+
22
26
  name = models.CharField(max_length=255, unique=True)
23
27
  description = models.TextField(blank=True, null=True)
24
28
  is_active = models.BooleanField(default=True)
@@ -1,29 +1,32 @@
1
- from django.db import models
2
-
3
1
  from typing import TYPE_CHECKING
4
2
 
3
+ from django.db import models
4
+
5
5
  if TYPE_CHECKING:
6
6
  from endoreg_db.models import (
7
7
  CenterShift,
8
8
  )
9
9
 
10
+
10
11
  class ScheduledDaysManager(models.Manager):
11
12
  def get_by_natural_key(self, name):
12
13
  """
13
14
  Retrieves a ScheduledDays instance by its unique name.
14
-
15
+
15
16
  Args:
16
17
  name: The unique name of the ScheduledDays instance to retrieve.
17
-
18
+
18
19
  Returns:
19
20
  The ScheduledDays instance matching the given name.
20
21
  """
21
22
  return self.get(name=name)
22
-
23
+
24
+
23
25
  class ScheduledDays(models.Model):
24
26
  """
25
27
  Model representing scheduled days for a shift.
26
28
  """
29
+
27
30
  name = models.CharField(
28
31
  max_length=255,
29
32
  unique=True,
@@ -1,31 +1,33 @@
1
- from django.db import models
2
- from typing import TYPE_CHECKING
1
+ from typing import TYPE_CHECKING, cast
3
2
 
3
+ from django.db import models
4
4
 
5
5
  if TYPE_CHECKING:
6
6
  from endoreg_db.models import (
7
- ShiftType,
8
- Qualification,
9
7
  CenterShift,
8
+ Qualification,
9
+ ShiftType,
10
10
  )
11
11
 
12
+
12
13
  class ShiftManager(models.Manager):
13
14
  def get_queryset(self):
14
15
  """
15
16
  Returns a queryset of active shifts.
16
-
17
+
17
18
  Only includes shifts where the 'is_active' field is set to True.
18
19
  """
19
20
  return super().get_queryset().filter(is_active=True)
20
-
21
+
22
+
21
23
  class Shift(models.Model):
22
24
  """
23
25
  Model representing a shift.
24
26
  """
27
+
25
28
  name = models.CharField(max_length=255, unique=True)
26
29
  description = models.TextField(blank=True, null=True)
27
- is_active = models.BooleanField(default=True)
28
-
30
+ is_active = models.BooleanField(default=True)
29
31
 
30
32
  shift_types = models.ManyToManyField(
31
33
  "ShiftType",
@@ -38,9 +40,11 @@ class Shift(models.Model):
38
40
  )
39
41
 
40
42
  if TYPE_CHECKING:
41
- shift_types: models.QuerySet["ShiftType"]
42
- required_qualifications: models.QuerySet["Qualification"]
43
- center_shifts: models.QuerySet["CenterShift"]
43
+ shift_types = cast(models.QuerySet["ShiftType"], shift_types)
44
+ required_qualifications = cast(models.QuerySet["Qualification"], required_qualifications)
45
+
46
+ @property
47
+ def center_shifts(self) -> models.QuerySet["CenterShift"]: ...
44
48
 
45
49
  objects = ShiftManager()
46
50
 
@@ -48,4 +52,4 @@ class Shift(models.Model):
48
52
  """
49
53
  Returns the string representation of the shift using its name.
50
54
  """
51
- return str(self.name)
55
+ return str(self.name)
@@ -1,7 +1,8 @@
1
- import logging # Added import
2
- from django.db import models
1
+ import logging # Added import
3
2
  from typing import TYPE_CHECKING
4
3
 
4
+ from django.db import models
5
+
5
6
  if TYPE_CHECKING:
6
7
  from endoreg_db.models import Shift
7
8
 
@@ -11,7 +12,8 @@ NAME_ON_CALL = "on_call"
11
12
  NAME_WARD = "ward"
12
13
  NAME_OFF_HOURS = "off_hours"
13
14
 
14
- logger = logging.getLogger(__name__) # Added logger
15
+ logger = logging.getLogger(__name__) # Added logger
16
+
15
17
 
16
18
  class ShiftTypeManager(models.Manager):
17
19
  def get_queryset(self):
@@ -19,11 +21,13 @@ class ShiftTypeManager(models.Manager):
19
21
  Returns a queryset containing only active shift types.
20
22
  """
21
23
  return super().get_queryset().filter(is_active=True)
22
-
24
+
25
+
23
26
  class ShiftType(models.Model):
24
27
  """
25
28
  Model representing a Shift type.
26
29
  """
30
+
27
31
  name = models.CharField(max_length=255, unique=True)
28
32
  description = models.TextField(blank=True, null=True)
29
33
  is_active = models.BooleanField(default=True)
@@ -40,69 +44,57 @@ class ShiftType(models.Model):
40
44
  return str(self.name)
41
45
 
42
46
  @classmethod
43
- def get_type_regular(cls) -> "ShiftType | None": # Modified return type
47
+ def get_type_regular(cls) -> "ShiftType | None": # Modified return type
44
48
  """
45
49
  Retrieves the 'regular' shift type instance.
46
-
50
+
47
51
  Returns:
48
52
  The ShiftType instance with the name 'regular', or None if it does not exist.
49
53
  """
50
54
  try:
51
55
  return cls.objects.get(name=NAME_REGULAR)
52
56
  except cls.DoesNotExist:
53
- logger.error(
54
- f"ShiftType with name '{NAME_REGULAR}' does not exist. "
55
- "Base data might be missing."
56
- )
57
+ logger.error(f"ShiftType with name '{NAME_REGULAR}' does not exist. Base data might be missing.")
57
58
  return None
58
-
59
+
59
60
  @classmethod
60
- def get_type_on_call(cls) -> "ShiftType | None": # Modified return type
61
+ def get_type_on_call(cls) -> "ShiftType | None": # Modified return type
61
62
  """
62
63
  Retrieves the ShiftType instance representing the on-call shift type.
63
-
64
+
64
65
  Returns:
65
66
  The ShiftType instance with the on-call name, or None if it does not exist.
66
67
  """
67
68
  try:
68
69
  return cls.objects.get(name=NAME_ON_CALL)
69
70
  except cls.DoesNotExist:
70
- logger.error(
71
- f"ShiftType with name '{NAME_ON_CALL}' does not exist. "
72
- "Base data might be missing."
73
- )
71
+ logger.error(f"ShiftType with name '{NAME_ON_CALL}' does not exist. Base data might be missing.")
74
72
  return None
75
-
73
+
76
74
  @classmethod
77
- def get_type_ward(cls) -> "ShiftType | None": # Modified return type
75
+ def get_type_ward(cls) -> "ShiftType | None": # Modified return type
78
76
  """
79
77
  Retrieves the ShiftType instance representing a ward shift.
80
-
78
+
81
79
  Returns:
82
80
  The ShiftType instance with the name corresponding to a ward shift, or None if it does not exist.
83
81
  """
84
82
  try:
85
83
  return cls.objects.get(name=NAME_WARD)
86
84
  except cls.DoesNotExist:
87
- logger.error(
88
- f"ShiftType with name '{NAME_WARD}' does not exist. "
89
- "Base data might be missing."
90
- )
85
+ logger.error(f"ShiftType with name '{NAME_WARD}' does not exist. Base data might be missing.")
91
86
  return None
92
-
87
+
93
88
  @classmethod
94
- def get_type_off_hours(cls) -> "ShiftType | None": # Modified return type
89
+ def get_type_off_hours(cls) -> "ShiftType | None": # Modified return type
95
90
  """
96
91
  Retrieves the off-hours shift type instance by name.
97
-
92
+
98
93
  Returns:
99
94
  The ShiftType instance for off-hours if it exists, otherwise None.
100
95
  """
101
96
  try:
102
97
  return cls.objects.get(name=NAME_OFF_HOURS)
103
98
  except cls.DoesNotExist:
104
- logger.error(
105
- f"ShiftType with name '{NAME_OFF_HOURS}' does not exist. "
106
- "Base data might be missing."
107
- )
99
+ logger.error(f"ShiftType with name '{NAME_OFF_HOURS}' does not exist. Base data might be missing.")
108
100
  return None
@@ -1,16 +1,15 @@
1
+ from .annotation import (
2
+ ImageClassificationAnnotation,
3
+ )
1
4
  from .label import Label
2
5
  from .label_set import LabelSet
3
6
  from .label_type import LabelType
4
- from .video_segmentation_label import VideoSegmentationLabel
5
- from .video_segmentation_labelset import VideoSegmentationLabelSet
6
7
  from .label_video_segment import (
7
8
  LabelVideoSegment,
8
9
  )
9
-
10
- from .annotation import (
11
- ImageClassificationAnnotation,
12
- VideoSegmentationAnnotation,
13
- )
10
+ from .video_segmentation_label import VideoSegmentationLabel
11
+ from .video_segmentation_labelset import VideoSegmentationLabelSet
12
+ from .annotation import VideoSegmentationAnnotation
14
13
 
15
14
  __all__ = [
16
15
  "Label",
@@ -20,5 +19,5 @@ __all__ = [
20
19
  "VideoSegmentationLabelSet",
21
20
  "LabelVideoSegment",
22
21
  "ImageClassificationAnnotation",
23
- "VideoSegmentationAnnotation",
24
- ]
22
+ "VideoSegmentationAnnotation"
23
+ ]
@@ -1,12 +1,13 @@
1
- from django.db import models
2
-
3
1
  from typing import TYPE_CHECKING
4
2
 
3
+ from django.db import models
4
+
5
5
  if TYPE_CHECKING:
6
- from ..label import Label
7
6
  from ...media.frame import Frame
8
7
  from ...metadata import ModelMeta
9
8
  from ...other.information_source import InformationSource
9
+ from ..label import Label
10
+
10
11
 
11
12
  class ImageClassificationAnnotation(models.Model):
12
13
  """
@@ -64,15 +65,15 @@ class ImageClassificationAnnotation(models.Model):
64
65
  )
65
66
 
66
67
  if TYPE_CHECKING:
67
- frame: "Frame" # Updated type hint
68
- label: "Label"
69
- information_source: "InformationSource"
70
- model_meta: "ModelMeta" # Added for completeness
68
+ frame: models.ForeignKey["Frame"]
69
+ label: models.ForeignKey["Label"]
70
+ information_source: models.ForeignKey["InformationSource|None"]
71
+ model_meta: models.ForeignKey["ModelMeta|None"]
71
72
 
72
73
  class Meta:
73
74
  indexes = [
74
- models.Index(fields=['frame', 'label']),
75
- models.Index(fields=['frame']),
75
+ models.Index(fields=["frame", "label"]),
76
+ models.Index(fields=["frame"]),
76
77
  ]
77
78
 
78
79
  def __str__(self) -> str:
@@ -1,61 +1,54 @@
1
1
  from typing import TYPE_CHECKING
2
+
2
3
  from django.db import models
3
- from django.db.models import Q, CheckConstraint, F
4
+ from django.db.models import CheckConstraint, F, Q
5
+
4
6
 
5
7
  if TYPE_CHECKING:
6
8
  from ...media.video.video_file import VideoFile
7
9
  from ..video_segmentation_label import VideoSegmentationLabel
8
10
 
11
+
9
12
  class VideoSegmentationAnnotation(models.Model):
10
13
  """
11
14
  Represents a video segmentation annotation, linking a label to a time segment
12
15
  within a specific video file.
13
16
 
14
17
  An annotation must be associated with exactly one `VideoFile`.
15
-
16
- Attributes:
17
- video_file (ForeignKey): The video file associated with the annotation.
18
- label (ForeignKey): The label for the annotation.
19
- start_time (float): The start time of the annotation in seconds.
20
- stop_time (float): The stop time of the annotation in seconds.
21
- is_true (bool): Indicates if the annotation is valid (defaults to True).
22
18
  """
23
- # Foreign key to the unified VideoFile model.
19
+
24
20
  video_file = models.ForeignKey(
25
21
  "VideoFile",
26
22
  on_delete=models.CASCADE,
27
23
  related_name="video_segmentation_annotations",
28
- null=False,
29
- blank=False,
30
24
  )
31
25
 
32
- label = models.ForeignKey("VideoSegmentationLabel", on_delete=models.CASCADE)
33
- start_time = models.FloatField() # in seconds
34
- stop_time = models.FloatField() # in seconds
26
+ label = models.ForeignKey(
27
+ "VideoSegmentationLabel",
28
+ on_delete=models.CASCADE,
29
+ )
30
+
31
+ # times in seconds
32
+ start_time = models.FloatField()
33
+ stop_time = models.FloatField()
34
+
35
35
  is_true = models.BooleanField(default=True)
36
36
 
37
37
  if TYPE_CHECKING:
38
- video_file: "VideoFile"
39
- label: "VideoSegmentationLabel"
38
+ video_file: models.ForeignKey["VideoFile"]
39
+ label: models.ForeignKey["VideoSegmentationLabel"]
40
40
 
41
41
  def __str__(self) -> str:
42
- """
43
- String representation of the annotation.
44
- """
45
- video_repr = self.get_video() # Get the actual video object for representation
46
- return f"{video_repr} - {self.label.name} - {self.start_time} to {self.stop_time}"
42
+ return f"{self.video_file.pk} - {self.label.name} - {self.start_time} to {self.stop_time}"
47
43
 
48
44
  def get_video(self) -> "VideoFile":
49
45
  """
50
- Get the video file associated with this annotation.
51
-
52
- Returns the `VideoFile` instance.
46
+ Convenience accessor for the associated VideoFile instance.
53
47
  """
54
- if self.video_file:
55
- return self.video_file
56
- else:
57
- # This state should ideally not be reachable due to null=False, blank=False
48
+ if self.video_file.pk is None:
49
+ # Should not happen due to null=False
58
50
  raise ValueError("Annotation is not linked to a VideoFile.")
51
+ return self.video_file
59
52
 
60
53
  class Meta:
61
54
  constraints = [
@@ -64,3 +57,5 @@ class VideoSegmentationAnnotation(models.Model):
64
57
  name="start_time_less_than_stop_time",
65
58
  ),
66
59
  ]
60
+ # optional but usually helpful:
61
+ # ordering = ("video_file_id", "start_time")