endoreg-db 0.8.6.4__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 (793) hide show
  1. endoreg_db/__init__.py +0 -0
  2. endoreg_db/admin.py +92 -0
  3. endoreg_db/api/serializers/finding_descriptions.py +0 -0
  4. endoreg_db/api/views/finding_descriptions.py +0 -0
  5. endoreg_db/api_urls.py +4 -0
  6. endoreg_db/apps.py +18 -0
  7. endoreg_db/assets/dummy_model.ckpt +1 -0
  8. endoreg_db/codemods/readme.md +88 -0
  9. endoreg_db/codemods/rename_datetime_fields.py +92 -0
  10. endoreg_db/config/__init__.py +0 -0
  11. endoreg_db/config/env.py +101 -0
  12. endoreg_db/data/__init__.py +144 -0
  13. endoreg_db/data/ai_model/data.yaml +7 -0
  14. endoreg_db/data/ai_model_label/label/data.yaml +88 -0
  15. endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
  16. endoreg_db/data/ai_model_label/label-set/data.yaml +40 -0
  17. endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
  18. endoreg_db/data/ai_model_label/label-type/data.yaml +7 -0
  19. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +27 -0
  20. endoreg_db/data/ai_model_type/data.yaml +7 -0
  21. endoreg_db/data/ai_model_video_segmentation_label/base_segmentation.yaml +176 -0
  22. endoreg_db/data/ai_model_video_segmentation_labelset/data.yaml +20 -0
  23. endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +167 -0
  24. endoreg_db/data/case_template/rule/01_patient-set-age.yaml +8 -0
  25. endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +9 -0
  26. endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +23 -0
  27. endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +19 -0
  28. endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +19 -0
  29. endoreg_db/data/case_template/rule/19_create_patient.yaml +17 -0
  30. endoreg_db/data/case_template/rule_type/base_types.yaml +35 -0
  31. endoreg_db/data/case_template/rule_value/.init +0 -0
  32. endoreg_db/data/case_template/rule_value_type/base_types.yaml +59 -0
  33. endoreg_db/data/case_template/template/base.yaml +8 -0
  34. endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +3 -0
  35. endoreg_db/data/case_template/tmp/_rule_value +13 -0
  36. endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -0
  37. endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +10 -0
  38. endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +7 -0
  39. endoreg_db/data/center/data.yaml +91 -0
  40. endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -0
  41. endoreg_db/data/center_shift/ukw.yaml +9 -0
  42. endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -0
  43. endoreg_db/data/contraindication/bleeding.yaml +11 -0
  44. endoreg_db/data/db_summary.csv +58 -0
  45. endoreg_db/data/db_summary.xlsx +0 -0
  46. endoreg_db/data/disease/cardiovascular.yaml +37 -0
  47. endoreg_db/data/disease/hepatology.yaml +5 -0
  48. endoreg_db/data/disease/misc.yaml +5 -0
  49. endoreg_db/data/disease/renal.yaml +5 -0
  50. endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +6 -0
  51. endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +6 -0
  52. endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +41 -0
  53. endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +20 -0
  54. endoreg_db/data/distribution/date/patient.yaml +7 -0
  55. endoreg_db/data/distribution/multiple_categorical/.init +0 -0
  56. endoreg_db/data/distribution/numeric/data.yaml +14 -0
  57. endoreg_db/data/distribution/single_categorical/patient.yaml +7 -0
  58. endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -0
  59. endoreg_db/data/endoscope/data.yaml +93 -0
  60. endoreg_db/data/endoscope_type/data.yaml +11 -0
  61. endoreg_db/data/endoscopy_processor/data.yaml +50 -0
  62. endoreg_db/data/event/cardiology.yaml +15 -0
  63. endoreg_db/data/event/neurology.yaml +14 -0
  64. endoreg_db/data/event/surgery.yaml +13 -0
  65. endoreg_db/data/event/thrombembolism.yaml +20 -0
  66. endoreg_db/data/examination/examinations/data.yaml +72 -0
  67. endoreg_db/data/examination/time/data.yaml +48 -0
  68. endoreg_db/data/examination/time-type/data.yaml +8 -0
  69. endoreg_db/data/examination/type/data.yaml +17 -0
  70. endoreg_db/data/examination_indication/endoscopy.yaml +424 -0
  71. endoreg_db/data/examination_indication_classification/endoscopy.yaml +160 -0
  72. endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +101 -0
  73. endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
  74. endoreg_db/data/finding/anatomy_colon.yaml +128 -0
  75. endoreg_db/data/finding/colonoscopy.yaml +40 -0
  76. endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +56 -0
  77. endoreg_db/data/finding/complication.yaml +16 -0
  78. endoreg_db/data/finding/data.yaml +105 -0
  79. endoreg_db/data/finding/examination_setting.yaml +16 -0
  80. endoreg_db/data/finding/medication_related.yaml +18 -0
  81. endoreg_db/data/finding/outcome.yaml +12 -0
  82. endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +95 -0
  83. endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +22 -0
  84. endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +25 -0
  85. endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
  86. endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
  87. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +68 -0
  88. endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
  89. endoreg_db/data/finding_classification/colonoscopy_location.yaml +80 -0
  90. endoreg_db/data/finding_classification/colonoscopy_lst.yaml +21 -0
  91. endoreg_db/data/finding_classification/colonoscopy_nice.yaml +20 -0
  92. endoreg_db/data/finding_classification/colonoscopy_paris.yaml +26 -0
  93. endoreg_db/data/finding_classification/colonoscopy_sano.yaml +22 -0
  94. endoreg_db/data/finding_classification/colonoscopy_summary.yaml +53 -0
  95. endoreg_db/data/finding_classification/complication_generic.yaml +25 -0
  96. endoreg_db/data/finding_classification/examination_setting_generic.yaml +40 -0
  97. endoreg_db/data/finding_classification/histology_colo.yaml +51 -0
  98. endoreg_db/data/finding_classification/intervention_required.yaml +26 -0
  99. endoreg_db/data/finding_classification/medication_related.yaml +23 -0
  100. endoreg_db/data/finding_classification/visualized.yaml +33 -0
  101. endoreg_db/data/finding_classification_choice/bowel_preparation.yaml +78 -0
  102. endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +32 -0
  103. endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
  104. endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
  105. endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +15 -0
  106. endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +17 -0
  107. endoreg_db/data/finding_classification_choice/colon_lesion_paris.yaml +57 -0
  108. endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +49 -0
  109. endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +14 -0
  110. endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +36 -0
  111. endoreg_db/data/finding_classification_choice/colonoscopy_location.yaml +229 -0
  112. endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
  113. endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +82 -0
  114. endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
  115. endoreg_db/data/finding_classification_choice/complication_generic_types.yaml +15 -0
  116. endoreg_db/data/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
  117. endoreg_db/data/finding_classification_choice/histology.yaml +24 -0
  118. endoreg_db/data/finding_classification_choice/histology_polyp.yaml +20 -0
  119. endoreg_db/data/finding_classification_choice/outcome.yaml +19 -0
  120. endoreg_db/data/finding_classification_choice/yes_no_na.yaml +11 -0
  121. endoreg_db/data/finding_classification_type/colonoscopy_basic.yaml +48 -0
  122. endoreg_db/data/finding_intervention/endoscopy.yaml +43 -0
  123. endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +168 -0
  124. endoreg_db/data/finding_intervention/endoscopy_egd.yaml +128 -0
  125. endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +32 -0
  126. endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +9 -0
  127. endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +36 -0
  128. endoreg_db/data/finding_intervention_type/endoscopy.yaml +15 -0
  129. endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +79 -0
  130. endoreg_db/data/finding_type/data.yaml +43 -0
  131. endoreg_db/data/gender/data.yaml +42 -0
  132. endoreg_db/data/information_source/annotation.yaml +6 -0
  133. endoreg_db/data/information_source/data.yaml +30 -0
  134. endoreg_db/data/information_source/endoscopy_guidelines.yaml +7 -0
  135. endoreg_db/data/information_source/medication.yaml +6 -0
  136. endoreg_db/data/information_source/prediction.yaml +7 -0
  137. endoreg_db/data/information_source_type/data.yaml +8 -0
  138. endoreg_db/data/lab_value/cardiac_enzymes.yaml +37 -0
  139. endoreg_db/data/lab_value/coagulation.yaml +54 -0
  140. endoreg_db/data/lab_value/electrolytes.yaml +228 -0
  141. endoreg_db/data/lab_value/gastrointestinal_function.yaml +133 -0
  142. endoreg_db/data/lab_value/hematology.yaml +184 -0
  143. endoreg_db/data/lab_value/hormones.yaml +59 -0
  144. endoreg_db/data/lab_value/lipids.yaml +53 -0
  145. endoreg_db/data/lab_value/misc.yaml +76 -0
  146. endoreg_db/data/lab_value/renal_function.yaml +12 -0
  147. endoreg_db/data/log_type/data.yaml +57 -0
  148. endoreg_db/data/lx_client_tag/base.yaml +54 -0
  149. endoreg_db/data/lx_client_type/base.yaml +30 -0
  150. endoreg_db/data/lx_permission/base.yaml +24 -0
  151. endoreg_db/data/lx_permission/endoreg.yaml +52 -0
  152. endoreg_db/data/material/material.yaml +91 -0
  153. endoreg_db/data/medication/anticoagulation.yaml +65 -0
  154. endoreg_db/data/medication/tah.yaml +70 -0
  155. endoreg_db/data/medication_indication/anticoagulation.yaml +115 -0
  156. endoreg_db/data/medication_indication_type/data.yaml +11 -0
  157. endoreg_db/data/medication_indication_type/thrombembolism.yaml +41 -0
  158. endoreg_db/data/medication_intake_time/base.yaml +31 -0
  159. endoreg_db/data/medication_schedule/apixaban.yaml +95 -0
  160. endoreg_db/data/medication_schedule/ass.yaml +12 -0
  161. endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -0
  162. endoreg_db/data/names_first/first_names.yaml +54 -0
  163. endoreg_db/data/names_last/last_names.yaml +51 -0
  164. endoreg_db/data/network_device/data.yaml +59 -0
  165. endoreg_db/data/network_device_type/data.yaml +12 -0
  166. endoreg_db/data/organ/data.yaml +29 -0
  167. endoreg_db/data/patient_lab_sample_type/generic.yaml +6 -0
  168. endoreg_db/data/pdf_type/data.yaml +46 -0
  169. endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -0
  170. endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -0
  171. endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -0
  172. endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -0
  173. endoreg_db/data/profession/data.yaml +70 -0
  174. endoreg_db/data/qualification/endoscopy.yaml +36 -0
  175. endoreg_db/data/qualification/m2.yaml +39 -0
  176. endoreg_db/data/qualification/outpatient_clinic.yaml +35 -0
  177. endoreg_db/data/qualification/sonography.yaml +36 -0
  178. endoreg_db/data/qualification_type/base.yaml +29 -0
  179. endoreg_db/data/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +55 -0
  180. endoreg_db/data/report_reader_flag/rkh-histology-generic.yaml +10 -0
  181. endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +30 -0
  182. endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +24 -0
  183. endoreg_db/data/requirement/age.yaml +26 -0
  184. endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +45 -0
  185. endoreg_db/data/requirement/disease_cardiovascular.yaml +79 -0
  186. endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +41 -0
  187. endoreg_db/data/requirement/disease_hepatology.yaml +12 -0
  188. endoreg_db/data/requirement/disease_misc.yaml +12 -0
  189. endoreg_db/data/requirement/disease_renal.yaml +96 -0
  190. endoreg_db/data/requirement/endoscopy_bleeding_risk.yaml +59 -0
  191. endoreg_db/data/requirement/event_cardiology.yaml +251 -0
  192. endoreg_db/data/requirement/event_requirements.yaml +145 -0
  193. endoreg_db/data/requirement/finding_colon_polyp.yaml +50 -0
  194. endoreg_db/data/requirement/gender.yaml +25 -0
  195. endoreg_db/data/requirement/lab_value.yaml +441 -0
  196. endoreg_db/data/requirement/medication.yaml +93 -0
  197. endoreg_db/data/requirement_operator/age.yaml +13 -0
  198. endoreg_db/data/requirement_operator/lab_operators.yaml +129 -0
  199. endoreg_db/data/requirement_operator/model_operators.yaml +96 -0
  200. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +48 -0
  201. endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
  202. endoreg_db/data/requirement_set/endoscopy_bleeding_risk.yaml +52 -0
  203. endoreg_db/data/requirement_set_type/data.yaml +20 -0
  204. endoreg_db/data/requirement_type/requirement_types.yaml +165 -0
  205. endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -0
  206. endoreg_db/data/risk/bleeding.yaml +26 -0
  207. endoreg_db/data/risk/thrombosis.yaml +37 -0
  208. endoreg_db/data/risk_type/data.yaml +27 -0
  209. endoreg_db/data/setup_config.yaml +38 -0
  210. endoreg_db/data/shift/endoscopy.yaml +21 -0
  211. endoreg_db/data/shift/m2.yaml +0 -0
  212. endoreg_db/data/shift_type/base.yaml +35 -0
  213. endoreg_db/data/tag/requirement_set_tags.yaml +11 -0
  214. endoreg_db/data/tmp/chronic_kidney_disease.yaml +0 -0
  215. endoreg_db/data/tmp/congestive_heart_failure.yaml +0 -0
  216. endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -0
  217. endoreg_db/data/unit/concentration.yaml +115 -0
  218. endoreg_db/data/unit/data.yaml +17 -0
  219. endoreg_db/data/unit/length.yaml +31 -0
  220. endoreg_db/data/unit/misc.yaml +20 -0
  221. endoreg_db/data/unit/rate.yaml +6 -0
  222. endoreg_db/data/unit/time.yaml +48 -0
  223. endoreg_db/data/unit/volume.yaml +35 -0
  224. endoreg_db/data/unit/weight.yaml +38 -0
  225. endoreg_db/data/waste/data.yaml +12 -0
  226. endoreg_db/exceptions.py +19 -0
  227. endoreg_db/factories/__init__.py +0 -0
  228. endoreg_db/forms/__init__.py +5 -0
  229. endoreg_db/forms/examination_form.py +11 -0
  230. endoreg_db/forms/patient_finding_intervention_form.py +18 -0
  231. endoreg_db/forms/patient_form.py +27 -0
  232. endoreg_db/forms/questionnaires/__init__.py +1 -0
  233. endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -0
  234. endoreg_db/forms/settings/__init__.py +8 -0
  235. endoreg_db/forms/unit.py +6 -0
  236. endoreg_db/helpers/__init__.py +0 -0
  237. endoreg_db/helpers/count_db.py +45 -0
  238. endoreg_db/helpers/data_loader.py +208 -0
  239. endoreg_db/helpers/default_objects.py +378 -0
  240. endoreg_db/helpers/download_segmentation_model.py +31 -0
  241. endoreg_db/helpers/interact.py +6 -0
  242. endoreg_db/helpers/test_video_helper.py +119 -0
  243. endoreg_db/logger_conf.py +140 -0
  244. endoreg_db/management/__init__.py +1 -0
  245. endoreg_db/management/commands/__init__.py +1 -0
  246. endoreg_db/management/commands/anonymize_video.py +0 -0
  247. endoreg_db/management/commands/check_auth.py +125 -0
  248. endoreg_db/management/commands/create_model_meta_from_huggingface.py +115 -0
  249. endoreg_db/management/commands/create_multilabel_model_meta.py +214 -0
  250. endoreg_db/management/commands/fix_missing_patient_data.py +172 -0
  251. endoreg_db/management/commands/fix_video_paths.py +165 -0
  252. endoreg_db/management/commands/import_fallback_video.py +203 -0
  253. endoreg_db/management/commands/import_report.py +298 -0
  254. endoreg_db/management/commands/import_video.py +423 -0
  255. endoreg_db/management/commands/import_video_with_classification.py +367 -0
  256. endoreg_db/management/commands/init_default_ai_model.py +112 -0
  257. endoreg_db/management/commands/load_ai_model_data.py +77 -0
  258. endoreg_db/management/commands/load_ai_model_label_data.py +59 -0
  259. endoreg_db/management/commands/load_base_db_data.py +192 -0
  260. endoreg_db/management/commands/load_center_data.py +68 -0
  261. endoreg_db/management/commands/load_contraindication_data.py +41 -0
  262. endoreg_db/management/commands/load_disease_classification_choices_data.py +41 -0
  263. endoreg_db/management/commands/load_disease_classification_data.py +41 -0
  264. endoreg_db/management/commands/load_disease_data.py +62 -0
  265. endoreg_db/management/commands/load_distribution_data.py +66 -0
  266. endoreg_db/management/commands/load_endoscope_data.py +68 -0
  267. endoreg_db/management/commands/load_event_data.py +41 -0
  268. endoreg_db/management/commands/load_examination_data.py +75 -0
  269. endoreg_db/management/commands/load_examination_indication_data.py +86 -0
  270. endoreg_db/management/commands/load_finding_data.py +128 -0
  271. endoreg_db/management/commands/load_gender_data.py +44 -0
  272. endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +132 -0
  273. endoreg_db/management/commands/load_information_source.py +51 -0
  274. endoreg_db/management/commands/load_lab_value_data.py +50 -0
  275. endoreg_db/management/commands/load_medication_data.py +103 -0
  276. endoreg_db/management/commands/load_name_data.py +37 -0
  277. endoreg_db/management/commands/load_organ_data.py +43 -0
  278. endoreg_db/management/commands/load_pdf_type_data.py +61 -0
  279. endoreg_db/management/commands/load_profession_data.py +44 -0
  280. endoreg_db/management/commands/load_qualification_data.py +59 -0
  281. endoreg_db/management/commands/load_report_reader_flag_data.py +46 -0
  282. endoreg_db/management/commands/load_requirement_data.py +180 -0
  283. endoreg_db/management/commands/load_risk_data.py +56 -0
  284. endoreg_db/management/commands/load_shift_data.py +60 -0
  285. endoreg_db/management/commands/load_tag_data.py +57 -0
  286. endoreg_db/management/commands/load_unit_data.py +46 -0
  287. endoreg_db/management/commands/load_user_groups.py +28 -0
  288. endoreg_db/management/commands/register_ai_model.py +64 -0
  289. endoreg_db/management/commands/reset_celery_schedule.py +9 -0
  290. endoreg_db/management/commands/setup_endoreg_db.py +381 -0
  291. endoreg_db/management/commands/start_filewatcher.py +106 -0
  292. endoreg_db/management/commands/storage_management.py +548 -0
  293. endoreg_db/management/commands/summarize_db_content.py +189 -0
  294. endoreg_db/management/commands/validate_video.py +204 -0
  295. endoreg_db/management/commands/validate_video_files.py +161 -0
  296. endoreg_db/management/commands/video_validation.py +22 -0
  297. endoreg_db/mermaid/Overall_flow_patient_finding_intervention.md +10 -0
  298. endoreg_db/mermaid/anonymized_image_annotation.md +20 -0
  299. endoreg_db/mermaid/binary_classification_annotation.md +50 -0
  300. endoreg_db/mermaid/classification.md +8 -0
  301. endoreg_db/mermaid/examination.md +8 -0
  302. endoreg_db/mermaid/findings.md +7 -0
  303. endoreg_db/mermaid/image_classification.md +28 -0
  304. endoreg_db/mermaid/interventions.md +8 -0
  305. endoreg_db/mermaid/morphology.md +8 -0
  306. endoreg_db/mermaid/patient_creation.md +14 -0
  307. endoreg_db/mermaid/video_segmentation_annotation.md +17 -0
  308. endoreg_db/migrations/0001_initial.py +1857 -0
  309. endoreg_db/migrations/0002_add_video_correction_models.py +52 -0
  310. endoreg_db/migrations/0003_add_center_display_name.py +30 -0
  311. endoreg_db/migrations/__init__.py +0 -0
  312. endoreg_db/models/__init__.py +359 -0
  313. endoreg_db/models/administration/__init__.py +116 -0
  314. endoreg_db/models/administration/ai/__init__.py +9 -0
  315. endoreg_db/models/administration/ai/active_model.py +35 -0
  316. endoreg_db/models/administration/ai/ai_model.py +156 -0
  317. endoreg_db/models/administration/ai/model_type.py +41 -0
  318. endoreg_db/models/administration/case/__init__.py +19 -0
  319. endoreg_db/models/administration/case/case.py +114 -0
  320. endoreg_db/models/administration/case/case_template/__init__.py +15 -0
  321. endoreg_db/models/administration/case/case_template/case_template.py +125 -0
  322. endoreg_db/models/administration/case/case_template/case_template_rule.py +269 -0
  323. endoreg_db/models/administration/case/case_template/case_template_rule_value.py +86 -0
  324. endoreg_db/models/administration/case/case_template/case_template_type.py +26 -0
  325. endoreg_db/models/administration/center/__init__.py +13 -0
  326. endoreg_db/models/administration/center/center.py +67 -0
  327. endoreg_db/models/administration/center/center_product.py +64 -0
  328. endoreg_db/models/administration/center/center_resource.py +49 -0
  329. endoreg_db/models/administration/center/center_shift.py +88 -0
  330. endoreg_db/models/administration/center/center_waste.py +30 -0
  331. endoreg_db/models/administration/permissions/__init__.py +44 -0
  332. endoreg_db/models/administration/person/__init__.py +24 -0
  333. endoreg_db/models/administration/person/employee/__init__.py +3 -0
  334. endoreg_db/models/administration/person/employee/employee.py +35 -0
  335. endoreg_db/models/administration/person/employee/employee_qualification.py +39 -0
  336. endoreg_db/models/administration/person/employee/employee_type.py +42 -0
  337. endoreg_db/models/administration/person/examiner/__init__.py +4 -0
  338. endoreg_db/models/administration/person/examiner/examiner.py +54 -0
  339. endoreg_db/models/administration/person/names/__init__.py +0 -0
  340. endoreg_db/models/administration/person/names/first_name.py +18 -0
  341. endoreg_db/models/administration/person/names/last_name.py +19 -0
  342. endoreg_db/models/administration/person/patient/__init__.py +5 -0
  343. endoreg_db/models/administration/person/patient/patient.py +460 -0
  344. endoreg_db/models/administration/person/person.py +31 -0
  345. endoreg_db/models/administration/person/profession/__init__.py +24 -0
  346. endoreg_db/models/administration/person/user/__init__.py +5 -0
  347. endoreg_db/models/administration/person/user/portal_user_information.py +37 -0
  348. endoreg_db/models/administration/product/__init__.py +14 -0
  349. endoreg_db/models/administration/product/product.py +97 -0
  350. endoreg_db/models/administration/product/product_group.py +39 -0
  351. endoreg_db/models/administration/product/product_material.py +54 -0
  352. endoreg_db/models/administration/product/product_weight.py +47 -0
  353. endoreg_db/models/administration/product/reference_product.py +130 -0
  354. endoreg_db/models/administration/qualification/__init__.py +7 -0
  355. endoreg_db/models/administration/qualification/qualification.py +37 -0
  356. endoreg_db/models/administration/qualification/qualification_type.py +35 -0
  357. endoreg_db/models/administration/shift/__init__.py +9 -0
  358. endoreg_db/models/administration/shift/scheduled_days.py +69 -0
  359. endoreg_db/models/administration/shift/shift.py +51 -0
  360. endoreg_db/models/administration/shift/shift_type.py +108 -0
  361. endoreg_db/models/label/__init__.py +24 -0
  362. endoreg_db/models/label/annotation/__init__.py +12 -0
  363. endoreg_db/models/label/annotation/image_classification.py +84 -0
  364. endoreg_db/models/label/annotation/video_segmentation_annotation.py +66 -0
  365. endoreg_db/models/label/label.py +83 -0
  366. endoreg_db/models/label/label_set.py +53 -0
  367. endoreg_db/models/label/label_type.py +29 -0
  368. endoreg_db/models/label/label_video_segment/__init__.py +3 -0
  369. endoreg_db/models/label/label_video_segment/_create_from_video.py +41 -0
  370. endoreg_db/models/label/label_video_segment/label_video_segment.py +511 -0
  371. endoreg_db/models/label/video_segmentation_label.py +31 -0
  372. endoreg_db/models/label/video_segmentation_labelset.py +27 -0
  373. endoreg_db/models/media/__init__.py +16 -0
  374. endoreg_db/models/media/frame/__init__.py +3 -0
  375. endoreg_db/models/media/frame/frame.py +111 -0
  376. endoreg_db/models/media/pdf/__init__.py +11 -0
  377. endoreg_db/models/media/pdf/raw_pdf.py +757 -0
  378. endoreg_db/models/media/pdf/report_file.py +162 -0
  379. endoreg_db/models/media/pdf/report_reader/__init__.py +7 -0
  380. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +77 -0
  381. endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +20 -0
  382. endoreg_db/models/media/video/__init__.py +8 -0
  383. endoreg_db/models/media/video/create_from_file.py +358 -0
  384. endoreg_db/models/media/video/pipe_1.py +213 -0
  385. endoreg_db/models/media/video/pipe_2.py +105 -0
  386. endoreg_db/models/media/video/refactor_plan.md +0 -0
  387. endoreg_db/models/media/video/video_file.py +825 -0
  388. endoreg_db/models/media/video/video_file_ai.py +443 -0
  389. endoreg_db/models/media/video/video_file_anonymize.py +349 -0
  390. endoreg_db/models/media/video/video_file_frames/__init__.py +47 -0
  391. endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +22 -0
  392. endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +23 -0
  393. endoreg_db/models/media/video/video_file_frames/_delete_frames.py +104 -0
  394. endoreg_db/models/media/video/video_file_frames/_extract_frames.py +174 -0
  395. endoreg_db/models/media/video/video_file_frames/_get_frame.py +28 -0
  396. endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +27 -0
  397. endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +20 -0
  398. endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +27 -0
  399. endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +34 -0
  400. endoreg_db/models/media/video/video_file_frames/_get_frames.py +27 -0
  401. endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +129 -0
  402. endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +141 -0
  403. endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +65 -0
  404. endoreg_db/models/media/video/video_file_frames.py +0 -0
  405. endoreg_db/models/media/video/video_file_io.py +168 -0
  406. endoreg_db/models/media/video/video_file_meta/__init__.py +22 -0
  407. endoreg_db/models/media/video/video_file_meta/get_crop_template.py +45 -0
  408. endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +39 -0
  409. endoreg_db/models/media/video/video_file_meta/get_fps.py +147 -0
  410. endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +143 -0
  411. endoreg_db/models/media/video/video_file_meta/text_meta.py +134 -0
  412. endoreg_db/models/media/video/video_file_meta/video_meta.py +70 -0
  413. endoreg_db/models/media/video/video_file_segments.py +209 -0
  414. endoreg_db/models/media/video/video_metadata.py +65 -0
  415. endoreg_db/models/media/video/video_processing.py +152 -0
  416. endoreg_db/models/medical/__init__.py +146 -0
  417. endoreg_db/models/medical/contraindication/__init__.py +17 -0
  418. endoreg_db/models/medical/disease.py +156 -0
  419. endoreg_db/models/medical/event.py +137 -0
  420. endoreg_db/models/medical/examination/__init__.py +9 -0
  421. endoreg_db/models/medical/examination/examination.py +148 -0
  422. endoreg_db/models/medical/examination/examination_indication.py +278 -0
  423. endoreg_db/models/medical/examination/examination_time.py +49 -0
  424. endoreg_db/models/medical/examination/examination_time_type.py +41 -0
  425. endoreg_db/models/medical/examination/examination_type.py +48 -0
  426. endoreg_db/models/medical/finding/__init__.py +18 -0
  427. endoreg_db/models/medical/finding/finding.py +96 -0
  428. endoreg_db/models/medical/finding/finding_classification.py +142 -0
  429. endoreg_db/models/medical/finding/finding_intervention.py +52 -0
  430. endoreg_db/models/medical/finding/finding_type.py +35 -0
  431. endoreg_db/models/medical/hardware/__init__.py +8 -0
  432. endoreg_db/models/medical/hardware/endoscope.py +65 -0
  433. endoreg_db/models/medical/hardware/endoscopy_processor.py +182 -0
  434. endoreg_db/models/medical/laboratory/__init__.py +5 -0
  435. endoreg_db/models/medical/laboratory/lab_value.py +419 -0
  436. endoreg_db/models/medical/medication/__init__.py +19 -0
  437. endoreg_db/models/medical/medication/medication.py +31 -0
  438. endoreg_db/models/medical/medication/medication_indication.py +50 -0
  439. endoreg_db/models/medical/medication/medication_indication_type.py +39 -0
  440. endoreg_db/models/medical/medication/medication_intake_time.py +44 -0
  441. endoreg_db/models/medical/medication/medication_schedule.py +45 -0
  442. endoreg_db/models/medical/organ/__init__.py +35 -0
  443. endoreg_db/models/medical/patient/__init__.py +56 -0
  444. endoreg_db/models/medical/patient/medication_examples.py +38 -0
  445. endoreg_db/models/medical/patient/patient_disease.py +63 -0
  446. endoreg_db/models/medical/patient/patient_event.py +75 -0
  447. endoreg_db/models/medical/patient/patient_examination.py +249 -0
  448. endoreg_db/models/medical/patient/patient_examination_indication.py +44 -0
  449. endoreg_db/models/medical/patient/patient_finding.py +357 -0
  450. endoreg_db/models/medical/patient/patient_finding_classification.py +207 -0
  451. endoreg_db/models/medical/patient/patient_finding_intervention.py +40 -0
  452. endoreg_db/models/medical/patient/patient_lab_sample.py +148 -0
  453. endoreg_db/models/medical/patient/patient_lab_value.py +222 -0
  454. endoreg_db/models/medical/patient/patient_medication.py +104 -0
  455. endoreg_db/models/medical/patient/patient_medication_schedule.py +136 -0
  456. endoreg_db/models/medical/risk/__init__.py +7 -0
  457. endoreg_db/models/medical/risk/risk.py +72 -0
  458. endoreg_db/models/medical/risk/risk_type.py +51 -0
  459. endoreg_db/models/metadata/__init__.py +19 -0
  460. endoreg_db/models/metadata/frame_ocr_result.py +0 -0
  461. endoreg_db/models/metadata/model_meta.py +206 -0
  462. endoreg_db/models/metadata/model_meta_logic.py +343 -0
  463. endoreg_db/models/metadata/pdf_meta.py +89 -0
  464. endoreg_db/models/metadata/sensitive_meta.py +288 -0
  465. endoreg_db/models/metadata/sensitive_meta_logic.py +1048 -0
  466. endoreg_db/models/metadata/video_meta.py +332 -0
  467. endoreg_db/models/metadata/video_prediction_logic.py +190 -0
  468. endoreg_db/models/metadata/video_prediction_meta.py +270 -0
  469. endoreg_db/models/other/__init__.py +40 -0
  470. endoreg_db/models/other/distribution/__init__.py +44 -0
  471. endoreg_db/models/other/distribution/base_value_distribution.py +20 -0
  472. endoreg_db/models/other/distribution/date_value_distribution.py +89 -0
  473. endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +32 -0
  474. endoreg_db/models/other/distribution/numeric_value_distribution.py +125 -0
  475. endoreg_db/models/other/distribution/single_categorical_value_distribution.py +22 -0
  476. endoreg_db/models/other/emission/__init__.py +5 -0
  477. endoreg_db/models/other/emission/emission_factor.py +94 -0
  478. endoreg_db/models/other/gender.py +27 -0
  479. endoreg_db/models/other/information_source.py +159 -0
  480. endoreg_db/models/other/material.py +28 -0
  481. endoreg_db/models/other/resource.py +22 -0
  482. endoreg_db/models/other/tag.py +27 -0
  483. endoreg_db/models/other/transport_route.py +33 -0
  484. endoreg_db/models/other/unit.py +32 -0
  485. endoreg_db/models/other/waste.py +27 -0
  486. endoreg_db/models/requirement/__init__.py +11 -0
  487. endoreg_db/models/requirement/requirement.py +767 -0
  488. endoreg_db/models/requirement/requirement_evaluation/__init__.py +6 -0
  489. endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
  490. endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +9 -0
  491. endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +95 -0
  492. endoreg_db/models/requirement/requirement_operator.py +176 -0
  493. endoreg_db/models/requirement/requirement_set.py +287 -0
  494. endoreg_db/models/rule/__init__.py +13 -0
  495. endoreg_db/models/rule/rule.py +27 -0
  496. endoreg_db/models/rule/rule_applicator.py +224 -0
  497. endoreg_db/models/rule/rule_attribute_dtype.py +17 -0
  498. endoreg_db/models/rule/rule_type.py +20 -0
  499. endoreg_db/models/rule/ruleset.py +17 -0
  500. endoreg_db/models/state/__init__.py +12 -0
  501. endoreg_db/models/state/abstract.py +11 -0
  502. endoreg_db/models/state/audit_ledger.py +150 -0
  503. endoreg_db/models/state/label_video_segment.py +22 -0
  504. endoreg_db/models/state/raw_pdf.py +187 -0
  505. endoreg_db/models/state/sensitive_meta.py +46 -0
  506. endoreg_db/models/state/video.py +232 -0
  507. endoreg_db/models/upload_job.py +99 -0
  508. endoreg_db/models/utils.py +135 -0
  509. endoreg_db/queries/__init__.py +5 -0
  510. endoreg_db/queries/annotations/__init__.py +3 -0
  511. endoreg_db/queries/annotations/legacy.py +158 -0
  512. endoreg_db/queries/sanity/__init_.py +0 -0
  513. endoreg_db/renames.yml +8 -0
  514. endoreg_db/root_urls.py +9 -0
  515. endoreg_db/schemas/__init__.py +0 -0
  516. endoreg_db/schemas/examination_evaluation.py +27 -0
  517. endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +775 -0
  518. endoreg_db/serializers/__init__.py +118 -0
  519. endoreg_db/serializers/_old/raw_pdf_meta_validation.py +223 -0
  520. endoreg_db/serializers/_old/raw_video_meta_validation.py +179 -0
  521. endoreg_db/serializers/_old/video.py +71 -0
  522. endoreg_db/serializers/administration/__init__.py +14 -0
  523. endoreg_db/serializers/administration/ai/__init__.py +10 -0
  524. endoreg_db/serializers/administration/ai/active_model.py +10 -0
  525. endoreg_db/serializers/administration/ai/ai_model.py +18 -0
  526. endoreg_db/serializers/administration/ai/model_type.py +10 -0
  527. endoreg_db/serializers/administration/center.py +9 -0
  528. endoreg_db/serializers/administration/gender.py +9 -0
  529. endoreg_db/serializers/anonymization.py +69 -0
  530. endoreg_db/serializers/evaluation/examination_evaluation.py +1 -0
  531. endoreg_db/serializers/examination/__init__.py +10 -0
  532. endoreg_db/serializers/examination/base.py +46 -0
  533. endoreg_db/serializers/examination/dropdown.py +21 -0
  534. endoreg_db/serializers/examination_serializer.py +12 -0
  535. endoreg_db/serializers/finding/__init__.py +5 -0
  536. endoreg_db/serializers/finding/finding.py +54 -0
  537. endoreg_db/serializers/finding_classification/__init__.py +7 -0
  538. endoreg_db/serializers/finding_classification/choice.py +19 -0
  539. endoreg_db/serializers/finding_classification/classification.py +13 -0
  540. endoreg_db/serializers/label/__init__.py +7 -0
  541. endoreg_db/serializers/label/image_classification_annotation.py +62 -0
  542. endoreg_db/serializers/label/label.py +15 -0
  543. endoreg_db/serializers/label_video_segment/__init__.py +7 -0
  544. endoreg_db/serializers/label_video_segment/_lvs_create.py +149 -0
  545. endoreg_db/serializers/label_video_segment/_lvs_update.py +138 -0
  546. endoreg_db/serializers/label_video_segment/_lvs_validate.py +149 -0
  547. endoreg_db/serializers/label_video_segment/label_video_segment.py +344 -0
  548. endoreg_db/serializers/label_video_segment/label_video_segment_annotation.py +99 -0
  549. endoreg_db/serializers/label_video_segment/label_video_segment_update.py +163 -0
  550. endoreg_db/serializers/meta/__init__.py +19 -0
  551. endoreg_db/serializers/meta/pdf_file_meta_extraction.py +115 -0
  552. endoreg_db/serializers/meta/report_meta.py +53 -0
  553. endoreg_db/serializers/meta/sensitive_meta_detail.py +162 -0
  554. endoreg_db/serializers/meta/sensitive_meta_update.py +148 -0
  555. endoreg_db/serializers/meta/sensitive_meta_verification.py +59 -0
  556. endoreg_db/serializers/meta/video_meta.py +39 -0
  557. endoreg_db/serializers/misc/__init__.py +14 -0
  558. endoreg_db/serializers/misc/file_overview.py +182 -0
  559. endoreg_db/serializers/misc/sensitive_patient_data.py +120 -0
  560. endoreg_db/serializers/misc/stats.py +33 -0
  561. endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
  562. endoreg_db/serializers/misc/upload_job.py +71 -0
  563. endoreg_db/serializers/patient/__init__.py +11 -0
  564. endoreg_db/serializers/patient/patient.py +86 -0
  565. endoreg_db/serializers/patient/patient_dropdown.py +27 -0
  566. endoreg_db/serializers/patient_examination/__init__.py +7 -0
  567. endoreg_db/serializers/patient_examination/patient_examination.py +141 -0
  568. endoreg_db/serializers/patient_finding/__init__.py +15 -0
  569. endoreg_db/serializers/patient_finding/patient_finding.py +31 -0
  570. endoreg_db/serializers/patient_finding/patient_finding_classification.py +39 -0
  571. endoreg_db/serializers/patient_finding/patient_finding_detail.py +53 -0
  572. endoreg_db/serializers/patient_finding/patient_finding_intervention.py +26 -0
  573. endoreg_db/serializers/patient_finding/patient_finding_list.py +41 -0
  574. endoreg_db/serializers/patient_finding/patient_finding_write.py +126 -0
  575. endoreg_db/serializers/pdf/__init__.py +5 -0
  576. endoreg_db/serializers/pdf/anony_text_validation.py +85 -0
  577. endoreg_db/serializers/report/__init__.py +9 -0
  578. endoreg_db/serializers/report/mixins.py +45 -0
  579. endoreg_db/serializers/report/report.py +105 -0
  580. endoreg_db/serializers/report/report_list.py +22 -0
  581. endoreg_db/serializers/report/secure_file_url.py +26 -0
  582. endoreg_db/serializers/requirements/requirement_schema.py +25 -0
  583. endoreg_db/serializers/requirements/requirement_sets.py +29 -0
  584. endoreg_db/serializers/sensitive_meta_serializer.py +282 -0
  585. endoreg_db/serializers/video/__init__.py +7 -0
  586. endoreg_db/serializers/video/segmentation.py +263 -0
  587. endoreg_db/serializers/video/video_file_brief.py +10 -0
  588. endoreg_db/serializers/video/video_file_detail.py +83 -0
  589. endoreg_db/serializers/video/video_file_list.py +67 -0
  590. endoreg_db/serializers/video/video_metadata.py +105 -0
  591. endoreg_db/serializers/video/video_processing_history.py +153 -0
  592. endoreg_db/serializers/video_examination.py +198 -0
  593. endoreg_db/services/__init__.py +5 -0
  594. endoreg_db/services/anonymization.py +223 -0
  595. endoreg_db/services/examination_evaluation.py +149 -0
  596. endoreg_db/services/finding_description_service.py +0 -0
  597. endoreg_db/services/lookup_service.py +411 -0
  598. endoreg_db/services/lookup_store.py +266 -0
  599. endoreg_db/services/pdf_import.py +1382 -0
  600. endoreg_db/services/polling_coordinator.py +288 -0
  601. endoreg_db/services/pseudonym_service.py +89 -0
  602. endoreg_db/services/requirements_object.py +147 -0
  603. endoreg_db/services/segment_sync.py +155 -0
  604. endoreg_db/services/storage_aware_video_processor.py +344 -0
  605. endoreg_db/services/video_import.py +1259 -0
  606. endoreg_db/tasks/upload_tasks.py +207 -0
  607. endoreg_db/tasks/video_ingest.py +157 -0
  608. endoreg_db/tasks/video_processing_tasks.py +327 -0
  609. endoreg_db/templates/admin/patient_finding_intervention.html +253 -0
  610. endoreg_db/templates/admin/start_examination.html +12 -0
  611. endoreg_db/templates/timeline.html +176 -0
  612. endoreg_db/urls/__init__.py +83 -0
  613. endoreg_db/urls/anonymization.py +32 -0
  614. endoreg_db/urls/auth.py +16 -0
  615. endoreg_db/urls/classification.py +39 -0
  616. endoreg_db/urls/examination.py +54 -0
  617. endoreg_db/urls/files.py +6 -0
  618. endoreg_db/urls/label_video_segment_validate.py +33 -0
  619. endoreg_db/urls/label_video_segments.py +46 -0
  620. endoreg_db/urls/media.py +227 -0
  621. endoreg_db/urls/patient.py +19 -0
  622. endoreg_db/urls/report.py +48 -0
  623. endoreg_db/urls/requirements.py +13 -0
  624. endoreg_db/urls/sensitive_meta.py +0 -0
  625. endoreg_db/urls/stats.py +46 -0
  626. endoreg_db/urls/upload.py +20 -0
  627. endoreg_db/urls/video.py +61 -0
  628. endoreg_db/urls.py +9 -0
  629. endoreg_db/utils/__init__.py +88 -0
  630. endoreg_db/utils/ai/__init__.py +9 -0
  631. endoreg_db/utils/ai/get.py +5 -0
  632. endoreg_db/utils/ai/inference_dataset.py +52 -0
  633. endoreg_db/utils/ai/multilabel_classification_net.py +159 -0
  634. endoreg_db/utils/ai/postprocess.py +63 -0
  635. endoreg_db/utils/ai/predict.py +291 -0
  636. endoreg_db/utils/ai/preprocess.py +68 -0
  637. endoreg_db/utils/calc_duration_seconds.py +24 -0
  638. endoreg_db/utils/case_generator/__init__.py +0 -0
  639. endoreg_db/utils/case_generator/case_generator.py +159 -0
  640. endoreg_db/utils/case_generator/lab_sample_factory.py +33 -0
  641. endoreg_db/utils/case_generator/utils.py +30 -0
  642. endoreg_db/utils/check_video_files.py +148 -0
  643. endoreg_db/utils/cropping.py +29 -0
  644. endoreg_db/utils/dataloader.py +175 -0
  645. endoreg_db/utils/dates.py +60 -0
  646. endoreg_db/utils/env.py +33 -0
  647. endoreg_db/utils/extract_specific_frames.py +72 -0
  648. endoreg_db/utils/file_operations.py +58 -0
  649. endoreg_db/utils/fix_video_path_direct.py +141 -0
  650. endoreg_db/utils/frame_anonymization_utils.py +463 -0
  651. endoreg_db/utils/hashs.py +153 -0
  652. endoreg_db/utils/links/__init__.py +0 -0
  653. endoreg_db/utils/links/requirement_link.py +193 -0
  654. endoreg_db/utils/mime_types.py +0 -0
  655. endoreg_db/utils/names.py +76 -0
  656. endoreg_db/utils/ocr.py +190 -0
  657. endoreg_db/utils/parse_and_generate_yaml.py +46 -0
  658. endoreg_db/utils/paths.py +95 -0
  659. endoreg_db/utils/permissions.py +143 -0
  660. endoreg_db/utils/pipelines/Readme.md +235 -0
  661. endoreg_db/utils/pipelines/__init__.py +0 -0
  662. endoreg_db/utils/pipelines/process_video_dir.py +120 -0
  663. endoreg_db/utils/product/__init__.py +0 -0
  664. endoreg_db/utils/product/sum_emissions.py +20 -0
  665. endoreg_db/utils/product/sum_weights.py +18 -0
  666. endoreg_db/utils/pydantic_models/__init__.py +6 -0
  667. endoreg_db/utils/pydantic_models/db_config.py +57 -0
  668. endoreg_db/utils/requirement_helpers.py +0 -0
  669. endoreg_db/utils/requirement_operator_logic/__init__.py +0 -0
  670. endoreg_db/utils/requirement_operator_logic/lab_value_operators.py +578 -0
  671. endoreg_db/utils/requirement_operator_logic/model_evaluators.py +368 -0
  672. endoreg_db/utils/setup_config.py +177 -0
  673. endoreg_db/utils/translation.py +27 -0
  674. endoreg_db/utils/uuid.py +4 -0
  675. endoreg_db/utils/validate_endo_roi.py +19 -0
  676. endoreg_db/utils/validate_subcategory_dict.py +91 -0
  677. endoreg_db/utils/validate_video_detailed.py +357 -0
  678. endoreg_db/utils/video/__init__.py +26 -0
  679. endoreg_db/utils/video/extract_frames.py +88 -0
  680. endoreg_db/utils/video/ffmpeg_wrapper.py +835 -0
  681. endoreg_db/utils/video/names.py +42 -0
  682. endoreg_db/utils/video/streaming_processor.py +312 -0
  683. endoreg_db/utils/video/video_splitter.py +94 -0
  684. endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +238 -0
  685. endoreg_db/views/__init__.py +274 -0
  686. endoreg_db/views/anonymization/__init__.py +27 -0
  687. endoreg_db/views/anonymization/media_management.py +454 -0
  688. endoreg_db/views/anonymization/overview.py +216 -0
  689. endoreg_db/views/anonymization/validate.py +107 -0
  690. endoreg_db/views/auth/__init__.py +13 -0
  691. endoreg_db/views/auth/keycloak.py +113 -0
  692. endoreg_db/views/examination/__init__.py +33 -0
  693. endoreg_db/views/examination/examination.py +37 -0
  694. endoreg_db/views/examination/examination_manifest_cache.py +26 -0
  695. endoreg_db/views/examination/get_finding_classification_choices.py +59 -0
  696. endoreg_db/views/examination/get_finding_classifications.py +36 -0
  697. endoreg_db/views/examination/get_findings.py +41 -0
  698. endoreg_db/views/examination/get_instruments.py +18 -0
  699. endoreg_db/views/examination/get_interventions.py +14 -0
  700. endoreg_db/views/finding/__init__.py +9 -0
  701. endoreg_db/views/finding/finding.py +112 -0
  702. endoreg_db/views/finding/get_classifications.py +14 -0
  703. endoreg_db/views/finding/get_interventions.py +17 -0
  704. endoreg_db/views/finding_classification/__init__.py +13 -0
  705. endoreg_db/views/finding_classification/base.py +0 -0
  706. endoreg_db/views/finding_classification/finding_classification.py +42 -0
  707. endoreg_db/views/finding_classification/get_classification_choices.py +55 -0
  708. endoreg_db/views/label/__init__.py +5 -0
  709. endoreg_db/views/label/label.py +15 -0
  710. endoreg_db/views/label_video_segment/__init__.py +16 -0
  711. endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +44 -0
  712. endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +50 -0
  713. endoreg_db/views/label_video_segment/label_video_segment.py +77 -0
  714. endoreg_db/views/label_video_segment/label_video_segment_by_label.py +174 -0
  715. endoreg_db/views/label_video_segment/label_video_segment_detail.py +73 -0
  716. endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +46 -0
  717. endoreg_db/views/label_video_segment/validate.py +226 -0
  718. endoreg_db/views/media/__init__.py +45 -0
  719. endoreg_db/views/media/pdf_media.py +388 -0
  720. endoreg_db/views/media/segments.py +71 -0
  721. endoreg_db/views/media/sensitive_metadata.py +314 -0
  722. endoreg_db/views/media/video_media.py +272 -0
  723. endoreg_db/views/media/video_segments.py +524 -0
  724. endoreg_db/views/meta/__init__.py +15 -0
  725. endoreg_db/views/meta/available_files_list.py +146 -0
  726. endoreg_db/views/meta/report_meta.py +53 -0
  727. endoreg_db/views/meta/sensitive_meta_detail.py +148 -0
  728. endoreg_db/views/meta/sensitive_meta_list.py +104 -0
  729. endoreg_db/views/meta/sensitive_meta_verification.py +71 -0
  730. endoreg_db/views/misc/__init__.py +63 -0
  731. endoreg_db/views/misc/center.py +13 -0
  732. endoreg_db/views/misc/csrf.py +7 -0
  733. endoreg_db/views/misc/gender.py +14 -0
  734. endoreg_db/views/misc/secure_file_serving_view.py +80 -0
  735. endoreg_db/views/misc/secure_file_url_view.py +84 -0
  736. endoreg_db/views/misc/secure_url_validate.py +79 -0
  737. endoreg_db/views/misc/stats.py +220 -0
  738. endoreg_db/views/misc/translation.py +182 -0
  739. endoreg_db/views/misc/upload_views.py +240 -0
  740. endoreg_db/views/patient/__init__.py +5 -0
  741. endoreg_db/views/patient/patient.py +210 -0
  742. endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +164 -0
  743. endoreg_db/views/patient_examination/__init__.py +11 -0
  744. endoreg_db/views/patient_examination/patient_examination.py +140 -0
  745. endoreg_db/views/patient_examination/patient_examination_create.py +63 -0
  746. endoreg_db/views/patient_examination/patient_examination_detail.py +66 -0
  747. endoreg_db/views/patient_examination/patient_examination_list.py +68 -0
  748. endoreg_db/views/patient_examination/video.py +194 -0
  749. endoreg_db/views/patient_finding/__init__.py +7 -0
  750. endoreg_db/views/patient_finding/base.py +0 -0
  751. endoreg_db/views/patient_finding/patient_finding.py +64 -0
  752. endoreg_db/views/patient_finding/patient_finding_optimized.py +259 -0
  753. endoreg_db/views/patient_finding_classification/__init__.py +5 -0
  754. endoreg_db/views/patient_finding_classification/pfc_create.py +67 -0
  755. endoreg_db/views/patient_finding_location/__init__.py +5 -0
  756. endoreg_db/views/patient_finding_location/pfl_create.py +70 -0
  757. endoreg_db/views/patient_finding_morphology/__init__.py +5 -0
  758. endoreg_db/views/patient_finding_morphology/pfm_create.py +70 -0
  759. endoreg_db/views/pdf/__init__.py +8 -0
  760. endoreg_db/views/pdf/pdf_stream.py +186 -0
  761. endoreg_db/views/pdf/reimport.py +177 -0
  762. endoreg_db/views/report/__init__.py +9 -0
  763. endoreg_db/views/report/report_list.py +112 -0
  764. endoreg_db/views/report/report_with_secure_url.py +28 -0
  765. endoreg_db/views/report/start_examination.py +7 -0
  766. endoreg_db/views/requirement/__init__.py +10 -0
  767. endoreg_db/views/requirement/evaluate.py +279 -0
  768. endoreg_db/views/requirement/lookup.py +367 -0
  769. endoreg_db/views/requirement/lookup_store.py +252 -0
  770. endoreg_db/views/requirement_lookup/lookup.py +0 -0
  771. endoreg_db/views/requirement_lookup/lookup_store.py +0 -0
  772. endoreg_db/views/stats/__init__.py +13 -0
  773. endoreg_db/views/stats/stats_views.py +229 -0
  774. endoreg_db/views/video/__init__.py +59 -0
  775. endoreg_db/views/video/correction.py +530 -0
  776. endoreg_db/views/video/reimport.py +195 -0
  777. endoreg_db/views/video/segmentation.py +274 -0
  778. endoreg_db/views/video/task_status.py +49 -0
  779. endoreg_db/views/video/timeline.py +46 -0
  780. endoreg_db/views/video/video_analyze.py +52 -0
  781. endoreg_db/views/video/video_apply_mask.py +48 -0
  782. endoreg_db/views/video/video_correction.py +21 -0
  783. endoreg_db/views/video/video_download_processed.py +58 -0
  784. endoreg_db/views/video/video_examination_viewset.py +242 -0
  785. endoreg_db/views/video/video_meta.py +29 -0
  786. endoreg_db/views/video/video_processing_history.py +24 -0
  787. endoreg_db/views/video/video_remove_frames.py +48 -0
  788. endoreg_db/views/video/video_stream.py +306 -0
  789. endoreg_db/views.py +0 -0
  790. endoreg_db-0.8.6.4.dist-info/METADATA +383 -0
  791. endoreg_db-0.8.6.4.dist-info/RECORD +793 -0
  792. endoreg_db-0.8.6.4.dist-info/WHEEL +4 -0
  793. endoreg_db-0.8.6.4.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,423 @@
1
+ # See Pipe 1 video file function.
2
+ #
3
+
4
+ """
5
+ Management command to import a video file into the database.
6
+ This command is designed to be run from the command line and takes various arguments
7
+ to specify the video file, center name, and other options.
8
+ """
9
+
10
+ from django.core.management import BaseCommand
11
+ from django.core.files.base import ContentFile
12
+ from django.db import connection
13
+ from pathlib import Path
14
+ from endoreg_db.models import VideoFile
15
+ from endoreg_db.models.administration.center import Center
16
+ from endoreg_db.models.medical.hardware import EndoscopyProcessor
17
+ # #FIXME
18
+ # from endoreg_db.management.commands import validate_video
19
+
20
+ from endoreg_db.utils.video.ffmpeg_wrapper import check_ffmpeg_availability # ADDED
21
+
22
+ import logging
23
+ logger = logging.getLogger(__name__)
24
+
25
+ # Import frame cleaning functionality - simplified approach
26
+ FRAME_CLEANING_AVAILABLE = False
27
+
28
+ # Try to import lx_anonymizer using the existing working import method from create_from_file
29
+ try:
30
+ # Check if we can find the lx-anonymizer directory
31
+ current_file = Path(__file__)
32
+ endoreg_db_root = current_file.parent.parent.parent.parent
33
+ lx_anonymizer_path = endoreg_db_root / "lx-anonymizer"
34
+
35
+ if lx_anonymizer_path.exists():
36
+ # Add to Python path temporarily
37
+ import sys
38
+ if str(lx_anonymizer_path) not in sys.path:
39
+ sys.path.insert(0, str(lx_anonymizer_path))
40
+
41
+ # Try simple import
42
+ from lx_anonymizer import FrameCleaner, ReportReader
43
+
44
+ FRAME_CLEANING_AVAILABLE = True
45
+ logger.debug("Successfully imported lx_anonymizer modules")
46
+
47
+ # Remove from path to avoid conflicts
48
+ if str(lx_anonymizer_path) in sys.path:
49
+ sys.path.remove(str(lx_anonymizer_path))
50
+
51
+ except Exception as e:
52
+ logger.debug(f"Frame cleaning not available: {e}")
53
+ FRAME_CLEANING_AVAILABLE = False
54
+
55
+ IMPORT_MODELS = [
56
+ VideoFile.__name__,
57
+ ]
58
+
59
+ IMPORT_METADATA = {
60
+ VideoFile.__name__: {
61
+ "uuid": VideoFile.uuid,
62
+ "raw_file": VideoFile.raw_file,
63
+ "processed_file": VideoFile.processed_file,
64
+ "foreign_keys": [],
65
+ "foreign_key_models": [],
66
+ },
67
+ }
68
+
69
+ class Command(BaseCommand):
70
+ help = """
71
+ Creates a new VideoFile object in the database.
72
+ 1. Validates the existence of the specified center and processor
73
+ 2. Checks that the video file is saved and anonymized
74
+ 3. Creates or updates a ModelMeta entry with the specified parameters
75
+ """
76
+
77
+ def add_arguments(self, parser):
78
+
79
+ """
80
+ Adds command-line arguments for the video import management command.
81
+
82
+ Defines options for specifying the video file path, associated center and processor names, directory roots for frames and videos, deletion and saving behavior, model path, segmentation usage, and verbosity.
83
+ """
84
+ parser.add_argument(
85
+ "--verbose",
86
+ action="store_true",
87
+ help="Display verbose output",
88
+ )
89
+ parser.add_argument(
90
+ "--center_name",
91
+ type=str,
92
+ default="university_hospital_wuerzburg",
93
+ help="Name of the center to associate with video",
94
+ )
95
+
96
+ # add the path to the video file
97
+ parser.add_argument(
98
+ "video_file",
99
+ type=Path,
100
+ help="Path to the video file to import",
101
+ )
102
+
103
+ # frame dir parent
104
+ parser.add_argument(
105
+ "--frame_dir_root",
106
+ type=str,
107
+ default="~/test-data/raw_frame_dir",
108
+ help="Path to the frame directory",
109
+ )
110
+
111
+ # video dir
112
+ parser.add_argument(
113
+ "--video_dir_root",
114
+ type=str,
115
+ default="~/test-data/raw_video_dir",
116
+ help="Path to the video directory",
117
+ )
118
+
119
+ # delete source
120
+ parser.add_argument(
121
+ "--delete_source",
122
+ action="store_true",
123
+ default=False,
124
+ help="Delete the source video file after importing",
125
+ )
126
+
127
+ # save video file
128
+ parser.add_argument(
129
+ "--save_video_file",
130
+ action="store_true",
131
+ default=True,
132
+ help="Save the video file to the video directory",
133
+ )
134
+
135
+ # model_path
136
+ parser.add_argument(
137
+ "--model_name",
138
+ type=str,
139
+ default="image_multilabel_classification_colonoscopy_default",
140
+ help="AiModel Name",
141
+ )
142
+
143
+ #
144
+ parser.add_argument(
145
+ "--segmentation",
146
+ action="store_true",
147
+ help="Whether to use segmentation",
148
+ )
149
+
150
+ parser.add_argument(
151
+ "--processor_name",
152
+ type=str,
153
+ default="olympus_cv_1500",
154
+ help="Name of the processor to associate with video",
155
+ )
156
+
157
+ def handle(self, *args, **options):
158
+
159
+ """
160
+ Imports a video file into the database, associating it with a specified medical center and endoscopy processor, and optionally applies AI-based segmentation.
161
+
162
+ Checks for required dependencies, loads reference data, validates the existence of the specified center and processor, and processes the video file. If segmentation is enabled, retrieves the latest segmentation model metadata. Handles interactive processor selection if multiple are available, creates a new `VideoFile` entry, and invokes the processing pipeline. Can optionally delete the source file or save the video to a specified directory. Reports the outcome of the import and processing steps.
163
+ """
164
+ try: # ADDED
165
+ check_ffmpeg_availability() # ADDED
166
+ self.stdout.write(self.style.SUCCESS("FFMPEG is available")) # ADDED
167
+ except FileNotFoundError as e: # ADDED
168
+ self.stderr.write(self.style.ERROR(str(e))) # ADDED
169
+ # Decide if the command should exit or if FFMPEG is optional for some operations
170
+ # For this command, it seems FFMPEG is critical for VideoFile.pipe_1 and VideoFile.create_from_file
171
+ return # ADDED
172
+
173
+ self.stdout.write(f"Current database: {connection.alias}")
174
+ self.stdout.write(self.style.SUCCESS("Starting video import..."))
175
+
176
+ # Should not be invoked here but in a previous db setup step
177
+ # load_gender_data()
178
+ # load_disease_data()
179
+ # load_event_data()
180
+ # load_information_source()
181
+ # load_examination_data()
182
+ # load_center_data()
183
+ # load_endoscope_data()
184
+
185
+ segmentation = options["segmentation"]
186
+
187
+ verbose = options["verbose"]
188
+ center_name = options["center_name"]
189
+ video_file = options["video_file"]
190
+ frame_dir_root = options["frame_dir_root"]
191
+ video_dir_root = options["video_dir_root"]
192
+ delete_source = options["delete_source"]
193
+ save_video_file = options["save_video_file"]
194
+ model_name = options["model_name"]
195
+ processor_name = options["processor_name"]
196
+ video_file = Path(video_file).expanduser()
197
+
198
+
199
+ assert isinstance(delete_source, bool), "delete_source must be a boolean"
200
+ assert isinstance(save_video_file, bool), "save_video_file must be a boolean"
201
+ assert isinstance(verbose, bool), "verbose must be a boolean"
202
+ assert isinstance(center_name, str), "center_name must be a string"
203
+ assert isinstance(video_file, Path), "video_file must be a Path"
204
+ assert isinstance(frame_dir_root, str), "frame_dir_root must be a string"
205
+ # Assert Center exists -> Does not exist methods are deprecated
206
+ try:
207
+ center = Center.objects.get(name=center_name)
208
+ self.stdout.write(self.style.SUCCESS(f"Using center: {center.name_en}"))
209
+ except Center.DoesNotExist:
210
+ self.stdout.write(self.style.ERROR(f"Center not found: {center_name}"))
211
+ return
212
+
213
+ # Assert Processor Exists
214
+ if processor_name is None:
215
+ processors_qs = center.endoscopy_processors.all()
216
+ proc_count = processors_qs.count()
217
+ if proc_count == 0:
218
+ raise AssertionError(
219
+ f"No processors linked to '{center.name}' and no processor called '{processor_name}' exists. "
220
+ "Fallback from default Processor applied."
221
+ )
222
+ elif proc_count == 1:
223
+ processor = processors_qs.first()
224
+ else:
225
+
226
+ processor = self._choose_processor_interactively(processors_qs)
227
+ self.stdout.write(self.style.SUCCESS(f"Using processor: {processor.name}"))
228
+
229
+ else:
230
+ processor = EndoscopyProcessor.objects.get(name=processor_name)
231
+
232
+ cns = processor.centers.values_list("name", flat=True)
233
+ if center_name not in cns:
234
+ self.stdout.write(
235
+ self.style.ERROR(
236
+ f"Processor '{processor_name}' is not linked to center '{center_name}'."
237
+ )
238
+ )
239
+ return
240
+
241
+ if not Path(video_file).exists():
242
+ self.stdout.write(self.style.ERROR(f"Video file not found: {video_file} saving unsuccessful."))
243
+ return AssertionError(f"Video file not found: {video_file}")
244
+
245
+ # Create VideoFile instance first
246
+ video_file_obj = VideoFile.create_from_file_initialized(
247
+ file_path=video_file,
248
+ center_name=center_name,
249
+ processor_name=processor_name,
250
+ delete_source=delete_source,
251
+ save_video_file=save_video_file, # Add this line
252
+ )
253
+
254
+ if not video_file_obj:
255
+ self.stdout.write(self.style.ERROR("Failed to create VideoFile instance"))
256
+ return
257
+
258
+ self.stdout.write(self.style.SUCCESS(f"Created VideoFile with UUID: {video_file_obj.uuid}"))
259
+
260
+ # Initialize video specs and frames
261
+ video_file_obj.initialize_video_specs()
262
+ video_file_obj.initialize_frames()
263
+
264
+ # Run Pipe 1 for OCR and AI processing
265
+ self.stdout.write(self.style.SUCCESS("Starting Pipe 1 processing (OCR + AI)..."))
266
+ success = video_file_obj.pipe_1(
267
+ model_name=model_name,
268
+ delete_frames_after=True,
269
+ ocr_frame_fraction=0.01,
270
+ ocr_cap=5
271
+ )
272
+
273
+ if not success:
274
+ self.stdout.write(self.style.ERROR("Pipe 1 processing failed"))
275
+ return
276
+
277
+ self.stdout.write(self.style.SUCCESS("Pipe 1 processing completed"))
278
+
279
+ # Ensure minimum patient data is available
280
+ self.stdout.write(self.style.SUCCESS("Ensuring minimum patient data..."))
281
+ self._ensure_default_patient_data(video_file_obj)
282
+
283
+ # Frame-level anonymization integration
284
+ if FRAME_CLEANING_AVAILABLE and video_file_obj.raw_file:
285
+ try:
286
+ self.stdout.write(self.style.SUCCESS("Starting frame-level anonymization..."))
287
+ # Properly instantiate FrameCleaner and ReportReader with correct arguments
288
+ frame_cleaner = FrameCleaner()
289
+ report_reader = ReportReader(
290
+ report_root_path=str(video_file_obj.raw_file.path),
291
+ locale="de_DE", # Default German locale for medical data
292
+ text_date_format="%d.%m.%Y" # Common German date format
293
+ )
294
+
295
+ # Updated to handle new return signature (path, metadata)
296
+ cleaned_video_path, extracted_metadata = frame_cleaner.clean_video(
297
+ video_path=Path(video_file_obj.raw_file.path),
298
+ endoscope_roi=video_file_obj.processor.get_roi_endoscope_image() if video_file_obj.processor else None,
299
+ endoscope_data_roi_nested=video_file_obj.processor.get_rois() if video_file_obj.processor else None,
300
+ output_path=video_file_obj.get_processed_file_path(),
301
+ technique="mask_overlay" # Use mask overlay technique as default, if not set this will be inferred.
302
+ )
303
+
304
+ # Save the cleaned video using Django's FileField
305
+ with open(cleaned_video_path, 'rb') as f:
306
+ video_file_obj.raw_file.save(cleaned_video_path.name, ContentFile(f.read()))
307
+ video_file_obj.save()
308
+
309
+ self.stdout.write(self.style.SUCCESS(f"Frame cleaning completed: {cleaned_video_path.name}"))
310
+ self.stdout.write(self.style.SUCCESS(f"Extracted metadata: {extracted_metadata}"))
311
+
312
+ except Exception as e:
313
+ self.stdout.write(self.style.WARNING(f"Frame cleaning failed, continuing with original video: {e}"))
314
+ elif not FRAME_CLEANING_AVAILABLE:
315
+ self.stdout.write(self.style.WARNING("Frame cleaning not available (lx_anonymizer not found)"))
316
+
317
+ # Now call pipe_1 on the VideoFile instance
318
+ if segmentation:
319
+ success = video_file_obj.pipe_1(model_name=model_name, model_meta_version = None)
320
+
321
+ if success:
322
+ self.stdout.write(self.style.SUCCESS("Pipeline 1 completed successfully"))
323
+ else:
324
+ self.stdout.write(self.style.ERROR("Pipeline 1 failed"))
325
+
326
+ def _ensure_default_patient_data(self, video_file):
327
+ """
328
+ Ensure video has minimum required patient data in SensitiveMeta.
329
+ Creates default values if data is missing after OCR processing.
330
+ """
331
+ from endoreg_db.models import SensitiveMeta
332
+ from datetime import date
333
+
334
+ if not video_file.sensitive_meta:
335
+ self.stdout.write(self.style.WARNING(f"No SensitiveMeta found for video {video_file.uuid}, creating default"))
336
+
337
+ # Create default SensitiveMeta with placeholder data
338
+ default_data = {
339
+ "patient_first_name": "Patient",
340
+ "patient_last_name": "Unknown",
341
+ "patient_dob": date(1990, 1, 1), # Default DOB
342
+ "examination_date": date.today(),
343
+ "center_name": video_file.center.name if video_file.center else "university_hospital_wuerzburg"
344
+ }
345
+
346
+ try:
347
+ sensitive_meta = SensitiveMeta.create_from_dict(default_data)
348
+ video_file.sensitive_meta = sensitive_meta
349
+ video_file.save(update_fields=['sensitive_meta'])
350
+ self.stdout.write(self.style.SUCCESS(f"Created default SensitiveMeta for video {video_file.uuid}"))
351
+ except Exception as e:
352
+ self.stdout.write(self.style.ERROR(f"Failed to create default SensitiveMeta for video {video_file.uuid}: {e}"))
353
+
354
+ else:
355
+ # Update existing SensitiveMeta with missing fields
356
+ update_needed = False
357
+ update_data = {}
358
+
359
+ if not video_file.sensitive_meta.patient_first_name:
360
+ update_data["patient_first_name"] = "Patient"
361
+ update_needed = True
362
+
363
+ if not video_file.sensitive_meta.patient_last_name:
364
+ update_data["patient_last_name"] = "Unknown"
365
+ update_needed = True
366
+
367
+ if not video_file.sensitive_meta.patient_dob:
368
+ update_data["patient_dob"] = date(1990, 1, 1)
369
+ update_needed = True
370
+
371
+ if not video_file.sensitive_meta.examination_date:
372
+ update_data["examination_date"] = date.today()
373
+ update_needed = True
374
+
375
+ if update_needed:
376
+ try:
377
+ video_file.sensitive_meta.update_from_dict(update_data)
378
+ self.stdout.write(self.style.SUCCESS(f"Updated missing SensitiveMeta fields for video {video_file.uuid}: {list(update_data.keys())}"))
379
+ except Exception as e:
380
+ self.stdout.write(self.style.ERROR(f"Failed to update SensitiveMeta for video {video_file.uuid}: {e}"))
381
+ else:
382
+ self.stdout.write(self.style.SUCCESS(f"SensitiveMeta for video {video_file.uuid} already has all required fields"))
383
+
384
+ def _choose_processor_interactively(
385
+ self, processors_qs
386
+ ) -> EndoscopyProcessor:
387
+ """
388
+ Interactively prompts the user to select an endoscopy processor from a list.
389
+
390
+ Displays all available processors and requests user input until a valid selection is made. Aborts the process if the user interrupts input.
391
+
392
+ Args:
393
+ processors_qs: Queryset of EndoscopyProcessor objects to present for selection.
394
+
395
+ Returns:
396
+ The EndoscopyProcessor object chosen by the user.
397
+ """
398
+ # turn the QS into a concrete list so we can index it later
399
+ processors = list(processors_qs) # -> [EndoscopyProcessor, …]
400
+
401
+ self.stdout.write(self.style.ERROR(
402
+ f"\nThe centre has {len(processors)} endoscopy processors.\n"
403
+ "Choose one for this import:\n"
404
+ ))
405
+ for idx, proc in enumerate(processors, 1):
406
+ self.stdout.write(f" [{idx}] {proc.name}")
407
+
408
+ while True: # keep prompting until valid
409
+ try:
410
+ choice = input("Processor number › ").strip()
411
+ except (EOFError, KeyboardInterrupt):
412
+ self.stderr.write("\nAborted.")
413
+ raise SystemExit(1)
414
+
415
+ try:
416
+ index = int(choice) - 1
417
+ if not 0 <= index < len(processors):
418
+ raise ValueError
419
+ except ValueError:
420
+ self.stderr.write("❌ Please enter a number in the list above.\n")
421
+ continue
422
+
423
+ return processors[index] # ← the chosen object