endoreg-db 0.8.8.0__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 (402) hide show
  1. endoreg_db/data/__init__.py +22 -8
  2. endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +0 -1
  3. endoreg_db/data/examination/examinations/data.yaml +114 -14
  4. endoreg_db/data/examination/time-type/data.yaml +0 -3
  5. endoreg_db/data/examination_indication/endoscopy.yaml +108 -173
  6. endoreg_db/data/examination_indication_classification/endoscopy.yaml +0 -70
  7. endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +33 -37
  8. endoreg_db/data/finding/00_generic.yaml +35 -0
  9. endoreg_db/data/finding/00_generic_complication.yaml +9 -0
  10. endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
  11. endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
  12. endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
  13. endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
  14. endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
  15. endoreg_db/data/finding_classification/00_generic.yaml +44 -0
  16. endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
  17. endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
  18. endoreg_db/data/finding_classification/{colonoscopy_bowel_preparation.yaml → 02_colonoscopy_baseline.yaml} +35 -20
  19. endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
  20. endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
  21. endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
  22. endoreg_db/data/finding_classification_choice/{yes_no_na.yaml → 00_generic.yaml} +5 -1
  23. endoreg_db/data/finding_classification_choice/{examination_setting_generic_types.yaml → 00_generic_baseline.yaml} +10 -2
  24. endoreg_db/data/finding_classification_choice/{complication_generic_types.yaml → 00_generic_complication.yaml} +1 -1
  25. endoreg_db/data/finding_classification_choice/{histology.yaml → 00_generic_histology.yaml} +1 -4
  26. endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
  27. endoreg_db/data/finding_classification_choice/{bowel_preparation.yaml → 02_colonoscopy_bowel_preparation.yaml} +1 -30
  28. endoreg_db/data/{_examples/finding_classification_choice/colonoscopy_not_complete_reason.yaml → finding_classification_choice/02_colonoscopy_generic.yaml} +1 -1
  29. endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
  30. endoreg_db/data/{_examples/finding_classification_choice/colonoscopy_location.yaml → finding_classification_choice/02_colonoscopy_location.yaml} +23 -4
  31. endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
  32. endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
  33. endoreg_db/data/{_examples/finding_classification_choice/colon_lesion_paris.yaml → finding_classification_choice/02_colonoscopy_polyp_morphology.yaml} +26 -8
  34. endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
  35. endoreg_db/data/finding_classification_type/{colonoscopy_basic.yaml → 00_generic.yaml} +18 -13
  36. endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
  37. endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
  38. endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
  39. endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
  40. endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
  41. endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
  42. endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
  43. endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
  44. endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
  45. endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
  46. endoreg_db/data/finding_type/data.yaml +8 -12
  47. endoreg_db/data/requirement/01_patient_data.yaml +93 -0
  48. endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
  49. endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +0 -2
  50. endoreg_db/data/requirement_set/90_coloreg.yaml +20 -8
  51. endoreg_db/exceptions.py +0 -1
  52. endoreg_db/forms/examination_form.py +1 -1
  53. endoreg_db/helpers/data_loader.py +124 -52
  54. endoreg_db/helpers/default_objects.py +116 -81
  55. endoreg_db/import_files/__init__.py +27 -0
  56. endoreg_db/import_files/context/__init__.py +7 -0
  57. endoreg_db/import_files/context/default_sensitive_meta.py +81 -0
  58. endoreg_db/import_files/context/ensure_center.py +17 -0
  59. endoreg_db/import_files/context/file_lock.py +66 -0
  60. endoreg_db/import_files/context/import_context.py +43 -0
  61. endoreg_db/import_files/context/validate_directories.py +56 -0
  62. endoreg_db/import_files/file_storage/__init__.py +15 -0
  63. endoreg_db/import_files/file_storage/create_report_file.py +76 -0
  64. endoreg_db/import_files/file_storage/create_video_file.py +75 -0
  65. endoreg_db/import_files/file_storage/sensitive_meta_storage.py +39 -0
  66. endoreg_db/import_files/file_storage/state_management.py +400 -0
  67. endoreg_db/import_files/file_storage/storage.py +36 -0
  68. endoreg_db/import_files/import_service.md +26 -0
  69. endoreg_db/import_files/processing/__init__.py +11 -0
  70. endoreg_db/import_files/processing/report_processing/report_anonymization.py +94 -0
  71. endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
  72. endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
  73. endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +119 -0
  74. endoreg_db/import_files/pseudonymization/fake.py +52 -0
  75. endoreg_db/import_files/pseudonymization/k_anonymity.py +182 -0
  76. endoreg_db/import_files/pseudonymization/k_pseudonymity.py +128 -0
  77. endoreg_db/import_files/report_import_service.py +141 -0
  78. endoreg_db/import_files/video_import_service.py +150 -0
  79. endoreg_db/management/commands/import_report.py +130 -65
  80. endoreg_db/management/commands/import_video_with_classification.py +1 -1
  81. endoreg_db/management/commands/load_ai_model_data.py +5 -5
  82. endoreg_db/management/commands/load_ai_model_label_data.py +9 -7
  83. endoreg_db/management/commands/load_base_db_data.py +5 -134
  84. endoreg_db/management/commands/load_contraindication_data.py +14 -16
  85. endoreg_db/management/commands/load_disease_classification_choices_data.py +15 -18
  86. endoreg_db/management/commands/load_disease_classification_data.py +15 -18
  87. endoreg_db/management/commands/load_disease_data.py +25 -28
  88. endoreg_db/management/commands/load_endoscope_data.py +20 -27
  89. endoreg_db/management/commands/load_event_data.py +14 -16
  90. endoreg_db/management/commands/load_examination_data.py +31 -44
  91. endoreg_db/management/commands/load_examination_indication_data.py +20 -21
  92. endoreg_db/management/commands/load_finding_data.py +52 -80
  93. endoreg_db/management/commands/load_information_source.py +21 -23
  94. endoreg_db/management/commands/load_lab_value_data.py +17 -26
  95. endoreg_db/management/commands/load_medication_data.py +13 -12
  96. endoreg_db/management/commands/load_organ_data.py +15 -19
  97. endoreg_db/management/commands/load_pdf_type_data.py +19 -18
  98. endoreg_db/management/commands/load_profession_data.py +14 -17
  99. endoreg_db/management/commands/load_qualification_data.py +20 -23
  100. endoreg_db/management/commands/load_report_reader_flag_data.py +17 -19
  101. endoreg_db/management/commands/load_requirement_data.py +14 -20
  102. endoreg_db/management/commands/load_risk_data.py +7 -6
  103. endoreg_db/management/commands/load_shift_data.py +20 -23
  104. endoreg_db/management/commands/load_tag_data.py +8 -11
  105. endoreg_db/management/commands/load_unit_data.py +17 -19
  106. endoreg_db/management/commands/start_filewatcher.py +46 -37
  107. endoreg_db/management/commands/validate_video_files.py +1 -5
  108. endoreg_db/migrations/0001_initial.py +1360 -1812
  109. endoreg_db/models/administration/person/patient/patient.py +72 -46
  110. endoreg_db/models/label/__init__.py +2 -2
  111. endoreg_db/models/label/annotation/video_segmentation_annotation.py +18 -26
  112. endoreg_db/models/label/label_video_segment/label_video_segment.py +23 -1
  113. endoreg_db/models/media/pdf/raw_pdf.py +136 -64
  114. endoreg_db/models/media/pdf/report_reader/report_reader_config.py +34 -10
  115. endoreg_db/models/media/processing_history/__init__.py +5 -0
  116. endoreg_db/models/media/processing_history/processing_history.py +96 -0
  117. endoreg_db/models/media/video/create_from_file.py +101 -31
  118. endoreg_db/models/media/video/video_file.py +125 -105
  119. endoreg_db/models/media/video/video_file_io.py +31 -26
  120. endoreg_db/models/medical/contraindication/README.md +1 -0
  121. endoreg_db/models/medical/examination/examination.py +28 -8
  122. endoreg_db/models/medical/examination/examination_indication.py +13 -79
  123. endoreg_db/models/medical/examination/examination_time.py +8 -3
  124. endoreg_db/models/medical/finding/finding.py +5 -12
  125. endoreg_db/models/medical/finding/finding_classification.py +18 -37
  126. endoreg_db/models/medical/finding/finding_intervention.py +7 -9
  127. endoreg_db/models/medical/hardware/endoscope.py +6 -0
  128. endoreg_db/models/medical/patient/medication_examples.py +5 -1
  129. endoreg_db/models/medical/patient/patient_finding.py +1 -1
  130. endoreg_db/models/metadata/pdf_meta.py +22 -10
  131. endoreg_db/models/metadata/sensitive_meta.py +3 -0
  132. endoreg_db/models/metadata/sensitive_meta_logic.py +200 -124
  133. endoreg_db/models/other/information_source.py +27 -6
  134. endoreg_db/models/report/__init__.py +0 -0
  135. endoreg_db/models/report/images.py +0 -0
  136. endoreg_db/models/report/report.py +6 -0
  137. endoreg_db/models/requirement/requirement.py +59 -399
  138. endoreg_db/models/requirement/requirement_operator.py +86 -98
  139. endoreg_db/models/state/audit_ledger.py +4 -5
  140. endoreg_db/models/state/raw_pdf.py +69 -30
  141. endoreg_db/models/state/video.py +64 -49
  142. endoreg_db/models/upload_job.py +33 -9
  143. endoreg_db/models/utils.py +27 -23
  144. endoreg_db/queries/__init__.py +3 -1
  145. endoreg_db/schemas/examination_evaluation.py +1 -1
  146. endoreg_db/serializers/__init__.py +2 -8
  147. endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
  148. endoreg_db/serializers/meta/__init__.py +1 -6
  149. endoreg_db/serializers/misc/sensitive_patient_data.py +50 -26
  150. endoreg_db/serializers/patient_examination/patient_examination.py +3 -3
  151. endoreg_db/serializers/pdf/anony_text_validation.py +39 -23
  152. endoreg_db/serializers/video/video_file_list.py +65 -34
  153. endoreg_db/services/__old/pdf_import.py +1487 -0
  154. endoreg_db/services/__old/video_import.py +1306 -0
  155. endoreg_db/services/anonymization.py +63 -26
  156. endoreg_db/services/lookup_service.py +28 -28
  157. endoreg_db/services/lookup_store.py +2 -2
  158. endoreg_db/services/pdf_import.py +0 -1480
  159. endoreg_db/services/report_import.py +10 -0
  160. endoreg_db/services/video_import.py +6 -1165
  161. endoreg_db/tasks/upload_tasks.py +79 -70
  162. endoreg_db/tasks/video_ingest.py +8 -4
  163. endoreg_db/urls/__init__.py +0 -14
  164. endoreg_db/urls/ai.py +32 -0
  165. endoreg_db/urls/media.py +21 -24
  166. endoreg_db/utils/dataloader.py +87 -57
  167. endoreg_db/utils/paths.py +110 -46
  168. endoreg_db/utils/pipelines/Readme.md +1 -1
  169. endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
  170. endoreg_db/views/__init__.py +85 -173
  171. endoreg_db/views/ai/__init__.py +8 -0
  172. endoreg_db/views/ai/label.py +155 -0
  173. endoreg_db/views/anonymization/media_management.py +8 -7
  174. endoreg_db/views/anonymization/overview.py +97 -68
  175. endoreg_db/views/anonymization/validate.py +25 -21
  176. endoreg_db/views/media/__init__.py +5 -20
  177. endoreg_db/views/media/pdf_media.py +109 -65
  178. endoreg_db/views/media/sensitive_metadata.py +163 -148
  179. endoreg_db/views/meta/__init__.py +0 -8
  180. endoreg_db/views/misc/__init__.py +1 -7
  181. endoreg_db/views/misc/upload_views.py +94 -93
  182. endoreg_db/views/report/__init__.py +7 -0
  183. endoreg_db/views/{pdf → report}/reimport.py +45 -24
  184. endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +40 -32
  185. endoreg_db/views/requirement/lookup_store.py +22 -90
  186. endoreg_db/views/video/__init__.py +23 -22
  187. endoreg_db/views/video/correction.py +201 -172
  188. endoreg_db/views/video/reimport.py +1 -1
  189. endoreg_db/views/{media/video_segments.py → video/segments_crud.py} +75 -37
  190. endoreg_db/views/video/{video_meta.py → video_meta_stats.py} +2 -2
  191. endoreg_db/views/video/video_stream.py +7 -8
  192. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/METADATA +2 -2
  193. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/RECORD +217 -335
  194. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/WHEEL +1 -1
  195. endoreg_db/data/_examples/disease.yaml +0 -55
  196. endoreg_db/data/_examples/disease_classification.yaml +0 -13
  197. endoreg_db/data/_examples/disease_classification_choice.yaml +0 -62
  198. endoreg_db/data/_examples/event.yaml +0 -64
  199. endoreg_db/data/_examples/examination.yaml +0 -72
  200. endoreg_db/data/_examples/finding/anatomy_colon.yaml +0 -128
  201. endoreg_db/data/_examples/finding/colonoscopy.yaml +0 -40
  202. endoreg_db/data/_examples/finding/colonoscopy_bowel_prep.yaml +0 -56
  203. endoreg_db/data/_examples/finding/complication.yaml +0 -16
  204. endoreg_db/data/_examples/finding/data.yaml +0 -105
  205. endoreg_db/data/_examples/finding/examination_setting.yaml +0 -16
  206. endoreg_db/data/_examples/finding/medication_related.yaml +0 -18
  207. endoreg_db/data/_examples/finding/outcome.yaml +0 -12
  208. endoreg_db/data/_examples/finding_classification/colonoscopy_bowel_preparation.yaml +0 -68
  209. endoreg_db/data/_examples/finding_classification/colonoscopy_jnet.yaml +0 -22
  210. endoreg_db/data/_examples/finding_classification/colonoscopy_kudo.yaml +0 -25
  211. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
  212. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
  213. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_size.yaml +0 -68
  214. endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
  215. endoreg_db/data/_examples/finding_classification/colonoscopy_location.yaml +0 -80
  216. endoreg_db/data/_examples/finding_classification/colonoscopy_lst.yaml +0 -21
  217. endoreg_db/data/_examples/finding_classification/colonoscopy_nice.yaml +0 -20
  218. endoreg_db/data/_examples/finding_classification/colonoscopy_paris.yaml +0 -26
  219. endoreg_db/data/_examples/finding_classification/colonoscopy_sano.yaml +0 -22
  220. endoreg_db/data/_examples/finding_classification/colonoscopy_summary.yaml +0 -53
  221. endoreg_db/data/_examples/finding_classification/complication_generic.yaml +0 -25
  222. endoreg_db/data/_examples/finding_classification/examination_setting_generic.yaml +0 -40
  223. endoreg_db/data/_examples/finding_classification/histology_colo.yaml +0 -51
  224. endoreg_db/data/_examples/finding_classification/intervention_required.yaml +0 -26
  225. endoreg_db/data/_examples/finding_classification/medication_related.yaml +0 -23
  226. endoreg_db/data/_examples/finding_classification/visualized.yaml +0 -33
  227. endoreg_db/data/_examples/finding_classification_choice/bowel_preparation.yaml +0 -78
  228. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
  229. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
  230. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
  231. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_lst.yaml +0 -15
  232. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_nice.yaml +0 -17
  233. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
  234. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_sano.yaml +0 -14
  235. endoreg_db/data/_examples/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
  236. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_size.yaml +0 -82
  237. endoreg_db/data/_examples/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
  238. endoreg_db/data/_examples/finding_classification_choice/complication_generic_types.yaml +0 -15
  239. endoreg_db/data/_examples/finding_classification_choice/examination_setting_generic_types.yaml +0 -15
  240. endoreg_db/data/_examples/finding_classification_choice/histology.yaml +0 -24
  241. endoreg_db/data/_examples/finding_classification_choice/histology_polyp.yaml +0 -20
  242. endoreg_db/data/_examples/finding_classification_choice/outcome.yaml +0 -19
  243. endoreg_db/data/_examples/finding_classification_choice/yes_no_na.yaml +0 -11
  244. endoreg_db/data/_examples/finding_classification_type/colonoscopy_basic.yaml +0 -48
  245. endoreg_db/data/_examples/finding_intervention/endoscopy.yaml +0 -43
  246. endoreg_db/data/_examples/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
  247. endoreg_db/data/_examples/finding_intervention/endoscopy_egd.yaml +0 -128
  248. endoreg_db/data/_examples/finding_intervention/endoscopy_ercp.yaml +0 -32
  249. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_lower.yaml +0 -9
  250. endoreg_db/data/_examples/finding_intervention/endoscopy_eus_upper.yaml +0 -36
  251. endoreg_db/data/_examples/finding_intervention_type/endoscopy.yaml +0 -15
  252. endoreg_db/data/_examples/finding_type/data.yaml +0 -43
  253. endoreg_db/data/_examples/requirement/age.yaml +0 -26
  254. endoreg_db/data/_examples/requirement/gender.yaml +0 -25
  255. endoreg_db/data/_examples/requirement_set/01_endoscopy_generic.yaml +0 -48
  256. endoreg_db/data/_examples/requirement_set/colonoscopy_austria_screening.yaml +0 -57
  257. endoreg_db/data/_examples/requirement_set/endoscopy_bleeding_risk.yaml +0 -52
  258. endoreg_db/data/_examples/yaml_examples.xlsx +0 -0
  259. endoreg_db/data/finding/anatomy_colon.yaml +0 -128
  260. endoreg_db/data/finding/colonoscopy.yaml +0 -40
  261. endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +0 -56
  262. endoreg_db/data/finding/complication.yaml +0 -16
  263. endoreg_db/data/finding/data.yaml +0 -105
  264. endoreg_db/data/finding/examination_setting.yaml +0 -16
  265. endoreg_db/data/finding/medication_related.yaml +0 -18
  266. endoreg_db/data/finding/outcome.yaml +0 -12
  267. endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +0 -22
  268. endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +0 -25
  269. endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
  270. endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
  271. endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +0 -38
  272. endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
  273. endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -49
  274. endoreg_db/data/finding_classification/colonoscopy_lst.yaml +0 -21
  275. endoreg_db/data/finding_classification/colonoscopy_nice.yaml +0 -20
  276. endoreg_db/data/finding_classification/colonoscopy_paris.yaml +0 -26
  277. endoreg_db/data/finding_classification/colonoscopy_sano.yaml +0 -22
  278. endoreg_db/data/finding_classification/colonoscopy_summary.yaml +0 -53
  279. endoreg_db/data/finding_classification/complication_generic.yaml +0 -25
  280. endoreg_db/data/finding_classification/examination_setting_generic.yaml +0 -40
  281. endoreg_db/data/finding_classification/histology_colo.yaml +0 -43
  282. endoreg_db/data/finding_classification/intervention_required.yaml +0 -26
  283. endoreg_db/data/finding_classification/medication_related.yaml +0 -23
  284. endoreg_db/data/finding_classification/visualized.yaml +0 -33
  285. endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
  286. endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
  287. endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
  288. endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +0 -15
  289. endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +0 -17
  290. endoreg_db/data/finding_classification_choice/colon_lesion_paris.yaml +0 -57
  291. endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
  292. endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +0 -14
  293. endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
  294. endoreg_db/data/finding_classification_choice/colonoscopy_location.yaml +0 -229
  295. endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +0 -19
  296. endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +0 -82
  297. endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
  298. endoreg_db/data/finding_classification_choice/outcome.yaml +0 -19
  299. endoreg_db/data/finding_intervention/endoscopy.yaml +0 -43
  300. endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
  301. endoreg_db/data/finding_intervention/endoscopy_egd.yaml +0 -128
  302. endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +0 -32
  303. endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +0 -9
  304. endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +0 -36
  305. endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +0 -79
  306. endoreg_db/data/requirement/age.yaml +0 -26
  307. endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +0 -45
  308. endoreg_db/data/requirement/disease_cardiovascular.yaml +0 -79
  309. endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +0 -41
  310. endoreg_db/data/requirement/disease_hepatology.yaml +0 -12
  311. endoreg_db/data/requirement/disease_misc.yaml +0 -12
  312. endoreg_db/data/requirement/disease_renal.yaml +0 -96
  313. endoreg_db/data/requirement/endoscopy_bleeding_risk.yaml +0 -59
  314. endoreg_db/data/requirement/event_cardiology.yaml +0 -251
  315. endoreg_db/data/requirement/event_requirements.yaml +0 -145
  316. endoreg_db/data/requirement/finding_colon_polyp.yaml +0 -50
  317. endoreg_db/data/requirement/gender.yaml +0 -25
  318. endoreg_db/data/requirement/lab_value.yaml +0 -441
  319. endoreg_db/data/requirement/medication.yaml +0 -93
  320. endoreg_db/data/requirement_operator/age.yaml +0 -13
  321. endoreg_db/data/requirement_operator/lab_operators.yaml +0 -129
  322. endoreg_db/data/requirement_operator/model_operators.yaml +0 -96
  323. endoreg_db/management/commands/init_default_ai_model.py +0 -112
  324. endoreg_db/management/commands/reset_celery_schedule.py +0 -9
  325. endoreg_db/management/commands/validate_video.py +0 -204
  326. endoreg_db/migrations/0002_requirementset_depends_on.py +0 -18
  327. endoreg_db/migrations/_old/0001_initial.py +0 -1857
  328. endoreg_db/migrations/_old/0002_add_video_correction_models.py +0 -52
  329. endoreg_db/migrations/_old/0003_add_center_display_name.py +0 -30
  330. endoreg_db/migrations/_old/0004_employee_city_employee_post_code_employee_street_and_more.py +0 -68
  331. endoreg_db/migrations/_old/0004_remove_casetemplate_rules_and_more.py +0 -77
  332. endoreg_db/migrations/_old/0005_merge_20251111_1003.py +0 -14
  333. endoreg_db/migrations/_old/0006_sensitivemeta_anonymized_text_and_more.py +0 -68
  334. endoreg_db/migrations/_old/0007_remove_rule_attribute_dtype_remove_rule_rule_type_and_more.py +0 -89
  335. endoreg_db/migrations/_old/0008_remove_event_event_classification_and_more.py +0 -27
  336. endoreg_db/migrations/_old/0009_alter_modelmeta_options_and_more.py +0 -21
  337. endoreg_db/renames.yml +0 -8
  338. endoreg_db/serializers/_old/raw_pdf_meta_validation.py +0 -223
  339. endoreg_db/serializers/_old/raw_video_meta_validation.py +0 -179
  340. endoreg_db/serializers/_old/video.py +0 -71
  341. endoreg_db/serializers/meta/pdf_file_meta_extraction.py +0 -115
  342. endoreg_db/serializers/meta/report_meta.py +0 -53
  343. endoreg_db/serializers/report/__init__.py +0 -9
  344. endoreg_db/serializers/report/mixins.py +0 -45
  345. endoreg_db/serializers/report/report.py +0 -105
  346. endoreg_db/serializers/report/report_list.py +0 -22
  347. endoreg_db/serializers/report/secure_file_url.py +0 -26
  348. endoreg_db/services/requirements_object.py +0 -147
  349. endoreg_db/services/storage_aware_video_processor.py +0 -370
  350. endoreg_db/urls/files.py +0 -6
  351. endoreg_db/urls/label_video_segment_validate.py +0 -33
  352. endoreg_db/urls/label_video_segments.py +0 -46
  353. endoreg_db/views/label/__init__.py +0 -5
  354. endoreg_db/views/label/label.py +0 -15
  355. endoreg_db/views/label_video_segment/__init__.py +0 -16
  356. endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +0 -44
  357. endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +0 -50
  358. endoreg_db/views/label_video_segment/label_video_segment.py +0 -77
  359. endoreg_db/views/label_video_segment/label_video_segment_by_label.py +0 -174
  360. endoreg_db/views/label_video_segment/label_video_segment_detail.py +0 -73
  361. endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +0 -46
  362. endoreg_db/views/label_video_segment/validate.py +0 -226
  363. endoreg_db/views/media/segments.py +0 -71
  364. endoreg_db/views/meta/available_files_list.py +0 -146
  365. endoreg_db/views/meta/report_meta.py +0 -53
  366. endoreg_db/views/meta/sensitive_meta_detail.py +0 -85
  367. endoreg_db/views/misc/secure_file_serving_view.py +0 -80
  368. endoreg_db/views/misc/secure_file_url_view.py +0 -84
  369. endoreg_db/views/misc/secure_url_validate.py +0 -79
  370. endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +0 -164
  371. endoreg_db/views/patient_finding_location/__init__.py +0 -5
  372. endoreg_db/views/patient_finding_location/pfl_create.py +0 -70
  373. endoreg_db/views/patient_finding_morphology/__init__.py +0 -5
  374. endoreg_db/views/patient_finding_morphology/pfm_create.py +0 -70
  375. endoreg_db/views/pdf/__init__.py +0 -8
  376. endoreg_db/views/video/segmentation.py +0 -274
  377. endoreg_db/views/video/task_status.py +0 -49
  378. endoreg_db/views/video/timeline.py +0 -46
  379. endoreg_db/views/video/video_analyze.py +0 -52
  380. /endoreg_db/data/requirement/{colon_polyp_intervention.yaml → old/colon_polyp_intervention.yaml} +0 -0
  381. /endoreg_db/data/{_examples/requirement → requirement/old}/colonoscopy_baseline_austria.yaml +0 -0
  382. /endoreg_db/data/requirement/{coloreg_colon_polyp.yaml → old/coloreg_colon_polyp.yaml} +0 -0
  383. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_cardiovascular.yaml +0 -0
  384. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_classification_choice_cardiovascular.yaml +0 -0
  385. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_hepatology.yaml +0 -0
  386. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_misc.yaml +0 -0
  387. /endoreg_db/data/{_examples/requirement → requirement/old}/disease_renal.yaml +0 -0
  388. /endoreg_db/data/{_examples/requirement → requirement/old}/endoscopy_bleeding_risk.yaml +0 -0
  389. /endoreg_db/data/{_examples/requirement → requirement/old}/event_cardiology.yaml +0 -0
  390. /endoreg_db/data/{_examples/requirement → requirement/old}/event_requirements.yaml +0 -0
  391. /endoreg_db/data/{_examples/requirement → requirement/old}/finding_colon_polyp.yaml +0 -0
  392. /endoreg_db/{migrations/__init__.py → data/requirement/old/gender.yaml} +0 -0
  393. /endoreg_db/data/{_examples/requirement → requirement/old}/lab_value.yaml +0 -0
  394. /endoreg_db/data/{_examples/requirement → requirement/old}/medication.yaml +0 -0
  395. /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/age.yaml +0 -0
  396. /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/lab_operators.yaml +0 -0
  397. /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/model_operators.yaml +0 -0
  398. /endoreg_db/{urls/sensitive_meta.py → import_files/pseudonymization/__init__.py} +0 -0
  399. /endoreg_db/{views/pdf/pdf_stream_views.py → import_files/pseudonymization/pseudonymize.py} +0 -0
  400. /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
  401. /endoreg_db/utils/requirement_operator_logic/{model_evaluators.py → _old/model_evaluators.py} +0 -0
  402. {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/licenses/LICENSE +0 -0
@@ -1,174 +0,0 @@
1
- from endoreg_db.models import Label, LabelVideoSegment, VideoFile
2
- from django.shortcuts import get_object_or_404
3
- from django.http import Http404
4
- from rest_framework import status
5
- from rest_framework.decorators import api_view, permission_classes
6
- from rest_framework.response import Response
7
-
8
- from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
9
-
10
- import logging
11
-
12
- logger = logging.getLogger(__name__)
13
-
14
- DEFAULT_FPS = 50 #TODO move to settings or config
15
-
16
- @api_view(['GET'])
17
- @permission_classes(DEBUG_PERMISSIONS) #TODO: Uncomment this line if authentication is set up
18
- def video_segments_by_label_id_view(request, video_id, label_id):
19
- """
20
- Retrieves all labeled segments for a given video and label by their IDs.
21
-
22
- Returns a list of time segments for the specified video and label, including start and end frames and their corresponding times in seconds. If no segments exist, returns an empty list. Responds with 404 if the video or label is not found.
23
- """
24
- try:
25
- video = get_object_or_404(VideoFile, id=video_id)
26
- label = get_object_or_404(Label, id=label_id)
27
-
28
- # Get all segments for this video and label combination
29
- segments = LabelVideoSegment.objects.filter(
30
- video_file=video,
31
- label=label
32
- ).order_by('start_frame_number')
33
-
34
- # Build response in the expected format
35
- if segments.exists():
36
- # Get video properties for time calculation
37
- fps = video.get_fps() or DEFAULT_FPS # Use module-level constant
38
-
39
- time_segments = []
40
- for segment in segments:
41
- # Convert frame numbers to time
42
- start_time = segment.start_frame_number / fps
43
- end_time = segment.end_frame_number / fps
44
-
45
- time_segments.append({
46
- 'segment_start': segment.start_frame_number,
47
- 'segment_end': segment.end_frame_number,
48
- 'start_time': start_time,
49
- 'end_time': end_time,
50
- 'frames': {} # Empty for now, can be populated if needed
51
- })
52
-
53
- response_data = {
54
- 'label': label.name,
55
- 'label_id': label.id,
56
- 'time_segments': time_segments
57
- }
58
- else:
59
- # Return empty response if no segments found
60
- response_data = {
61
- 'label': label.name,
62
- 'label_id': label.id,
63
- 'time_segments': []
64
- }
65
-
66
- return Response(response_data)
67
- except Http404 as e:
68
- return Response({'error': str(e)}, status=status.HTTP_404_NOT_FOUND)
69
- except VideoFile.DoesNotExist:
70
- return Response(
71
- {'error': f'Video with id {video_id} not found'},
72
- status=status.HTTP_404_NOT_FOUND
73
- )
74
- except Label.DoesNotExist:
75
- return Response(
76
- {'error': f'Label with id {label_id} not found'},
77
- status=status.HTTP_404_NOT_FOUND
78
- )
79
- except Exception as e:
80
- logger.error(f"Error fetching segments for video {video_id} and label {label_id}: {str(e)}")
81
- return Response(
82
- {'error': f'Internal server error: {str(e)}'},
83
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
84
- )
85
-
86
-
87
- @api_view(['GET'])
88
- @permission_classes(DEBUG_PERMISSIONS) #TODO: Uncomment this line if authentication is set up
89
- def video_segments_by_label_name_view(request, video_id, label_name):
90
- """
91
- Retrieves labeled video segments for a given video and label name.
92
-
93
- Handles cases where multiple labels share the same name by returning a conflict response with details of all matching labels and a suggestion to use the label ID endpoint. If a unique label is found, returns a list of segments for the specified video and label, including frame and time information. Returns appropriate error responses if the video or label is not found, or if an internal error occurs.
94
- """
95
- try:
96
- video = get_object_or_404(VideoFile, id=video_id)
97
-
98
- # Find all labels with this name
99
- labels_with_name = Label.objects.filter(name=label_name)
100
-
101
- if not labels_with_name.exists():
102
- return Response(
103
- {'error': f'No labels found with name "{label_name}"'},
104
- status=status.HTTP_404_NOT_FOUND
105
- )
106
-
107
- if labels_with_name.count() > 1:
108
- # Multiple labels with same name - log warning and return info about all
109
- logger.warning(f"Multiple labels found with name '{label_name}': {[l.id for l in labels_with_name]}")
110
-
111
- return Response({
112
- 'error': f'Multiple labels found with name "{label_name}"',
113
- 'suggestion': 'Use the label-id endpoint instead for unambiguous results',
114
- 'available_labels': [
115
- {'id': label.id, 'name': label.name, 'description': label.description}
116
- for label in labels_with_name
117
- ]
118
- }, status=status.HTTP_409_CONFLICT)
119
-
120
- # Single label found - proceed normally
121
- label = labels_with_name.first()
122
-
123
- # Get all segments for this video and label combination
124
- segments = LabelVideoSegment.objects.filter(
125
- video_file=video,
126
- label=label
127
- ).order_by('start_frame_number')
128
-
129
- # Build response in the expected format
130
- if segments.exists():
131
- # Get video properties for time calculation
132
- fps = video.get_fps() or DEFAULT_FPS # Use module-level constant
133
-
134
- time_segments = []
135
- for segment in segments:
136
- # Convert frame numbers to time
137
- start_time = segment.start_frame_number / fps
138
- end_time = segment.end_frame_number / fps
139
-
140
- time_segments.append({
141
- 'segment_start': segment.start_frame_number,
142
- 'segment_end': segment.end_frame_number,
143
- 'start_time': start_time,
144
- 'end_time': end_time,
145
- 'frames': {} # Empty for now, can be populated if needed
146
- })
147
-
148
- response_data = {
149
- 'label': label.name,
150
- 'label_id': label.id,
151
- 'time_segments': time_segments
152
- }
153
- else:
154
- # Return empty response if no segments found
155
- response_data = {
156
- 'label': label.name,
157
- 'label_id': label.id,
158
- 'time_segments': []
159
- }
160
-
161
- return Response(response_data)
162
- except Http404 as e:
163
- return Response({'error': str(e)}, status=status.HTTP_404_NOT_FOUND)
164
- except VideoFile.DoesNotExist:
165
- return Response(
166
- {'error': f'Video with id {video_id} not found'},
167
- status=status.HTTP_404_NOT_FOUND
168
- )
169
- except Exception as e:
170
- logger.error(f"Error fetching segments for video {video_id} and label '{label_name}': {str(e)}")
171
- return Response(
172
- {'error': f'Internal server error: {str(e)}'},
173
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
174
- )
@@ -1,73 +0,0 @@
1
- from endoreg_db.models import LabelVideoSegment
2
- from endoreg_db.serializers.label_video_segment.label_video_segment import LabelVideoSegmentSerializer
3
- from django.db import transaction
4
- from django.shortcuts import get_object_or_404
5
- from rest_framework import status
6
- from rest_framework.decorators import api_view, permission_classes
7
- from rest_framework.response import Response
8
-
9
- from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
10
-
11
- import logging
12
- logger = logging.getLogger(__name__)
13
-
14
- @api_view(['GET', 'PUT', 'DELETE', 'PATCH'])
15
- @permission_classes(DEBUG_PERMISSIONS)
16
- def video_segment_detail_view(request, segment_id):
17
- """
18
- Handles retrieval, update, and deletion of a single labeled video segment.
19
-
20
- Supports:
21
- - GET: Returns details of the specified video segment.
22
- - PUT: Partially updates the segment with validated data.
23
- - DELETE: Removes the segment from the database.
24
-
25
- Returns appropriate HTTP status codes and error messages for invalid data or exceptions.
26
- """
27
- segment = get_object_or_404(LabelVideoSegment, id=segment_id)
28
-
29
- if request.method == 'GET':
30
- serializer = LabelVideoSegmentSerializer(segment)
31
- return Response(serializer.data)
32
-
33
- elif request.method in ('PUT', 'PATCH'):
34
- logger.info(f"Updating video segment {segment_id} with data: {request.data}")
35
-
36
- partial = request.method == 'PATCH' # Allow partial updates with PATCH
37
-
38
- with transaction.atomic():
39
- serializer = LabelVideoSegmentSerializer(segment, data=request.data, partial=partial)
40
- if serializer.is_valid():
41
- try:
42
- segment = serializer.save()
43
- logger.info(f"Successfully updated video segment {segment_id}")
44
- return Response(LabelVideoSegmentSerializer(segment).data)
45
- except Exception as e:
46
- logger.error(f"Error updating video segment {segment_id}: {str(e)}")
47
- return Response(
48
- {'error': f'Failed to update segment: {str(e)}'},
49
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
50
- )
51
- else:
52
- logger.warning(f"Invalid data for video segment update: {serializer.errors}")
53
- return Response(
54
- {'error': 'Invalid data', 'details': serializer.errors},
55
- status=status.HTTP_400_BAD_REQUEST
56
- )
57
-
58
- elif request.method == 'DELETE':
59
- logger.info(f"Deleting video segment {segment_id}")
60
- try:
61
- with transaction.atomic():
62
- segment.delete()
63
- logger.info(f"Successfully deleted video segment {segment_id}")
64
- return Response(
65
- {'message': f'Segment {segment_id} deleted successfully'},
66
- status=status.HTTP_204_NO_CONTENT
67
- )
68
- except Exception as e:
69
- logger.error(f"Error deleting video segment {segment_id}: {str(e)}")
70
- return Response(
71
- {'error': f'Failed to delete segment: {str(e)}'},
72
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
73
- )
@@ -1,46 +0,0 @@
1
- from endoreg_db.models import LabelVideoSegment, InformationSource
2
- from endoreg_db.serializers import LabelVideoSegmentSerializer
3
- from rest_framework import status
4
- from rest_framework.decorators import api_view, permission_classes
5
- from rest_framework.permissions import IsAuthenticated
6
- from rest_framework.response import Response
7
- import logging
8
-
9
- logger = logging.getLogger(__name__)
10
-
11
- @api_view(['PATCH'])
12
- @permission_classes([IsAuthenticated])
13
- def update_label_video_segment(request, annotation_id) -> Response:
14
- """
15
- Update an existing LabelVideoSegment, treating it as a manual annotation.
16
- """
17
- logger.info(f"Updating LabelVideoSegment {annotation_id} with data: {request.data}")
18
-
19
- try:
20
- segment = LabelVideoSegment.objects.get(id=annotation_id)
21
- except LabelVideoSegment.DoesNotExist:
22
- logger.error(f"LabelVideoSegment {annotation_id} not found")
23
- return Response(
24
- {'error': 'Segment not found'},
25
- status=status.HTTP_404_NOT_FOUND
26
- )
27
-
28
- data = request.data
29
- updated = False
30
-
31
- if 'start_frame' in data:
32
- segment.start_frame_number = data['start_frame']
33
- updated = True
34
-
35
- if 'end_frame' in data:
36
- segment.end_frame_number = data['end_frame']
37
- updated = True
38
-
39
- if updated:
40
- # Ensure the source is correct for a manual annotation
41
- manual_source, _ = InformationSource.objects.get_or_create(name="manual_annotation")
42
- segment.source = manual_source
43
- segment.save()
44
-
45
- serializer = LabelVideoSegmentSerializer(segment)
46
- return Response(serializer.data)
@@ -1,226 +0,0 @@
1
- from rest_framework import status
2
- from rest_framework.response import Response
3
- from rest_framework.views import APIView
4
- from django.db import transaction
5
- from endoreg_db.models import LabelVideoSegment, VideoFile
6
- from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
7
-
8
-
9
- class LabelVideoSegmentValidateView(APIView):
10
- """
11
- POST /api/label-video-segment/<int:segment_id>/validate/
12
-
13
- Validiert ein einzelnes LabelVideoSegment und markiert es als verifiziert.
14
- Dies wird verwendet, um vom Benutzer überprüfte Segment-Annotationen zu bestätigen.
15
-
16
- Body (optional):
17
- {
18
- "is_validated": true, // optional, default true
19
- "notes": "..." // optional, Validierungsnotizen
20
- }
21
- """
22
- permission_classes = DEBUG_PERMISSIONS
23
-
24
- @transaction.atomic
25
- def post(self, request, segment_id: int):
26
- try:
27
- # Segment abrufen
28
- segment = LabelVideoSegment.objects.select_related('state', 'video_file', 'label').get(pk=segment_id)
29
-
30
- # Validierungsstatus aus Request (default: True)
31
- is_validated = request.data.get('is_validated', True)
32
- notes = request.data.get('notes', '')
33
-
34
- # State-Objekt abrufen oder erstellen
35
- if not hasattr(segment, 'state') or segment.state is None:
36
- # State muss existieren - wenn nicht, könnte ein Model-Problem vorliegen
37
- return Response({
38
- "error": "Segment has no state object. Cannot validate."
39
- }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
40
-
41
- # State aktualisieren
42
- segment.state.is_validated = is_validated
43
- if notes:
44
- # Falls ein notes-Feld existiert
45
- if hasattr(segment.state, 'validation_notes'):
46
- segment.state.validation_notes = notes
47
- segment.state.save()
48
-
49
- return Response({
50
- "message": f"Segment {segment_id} validation status updated.",
51
- "segment_id": segment_id,
52
- "is_validated": is_validated,
53
- "label": segment.label.name if segment.label else None,
54
- "video_id": segment.video_file.id if segment.video_file else None,
55
- "start_frame": segment.start_frame_number,
56
- "end_frame": segment.end_frame_number
57
- }, status=status.HTTP_200_OK)
58
-
59
- except LabelVideoSegment.DoesNotExist:
60
- return Response({
61
- "error": f"Segment {segment_id} not found."
62
- }, status=status.HTTP_404_NOT_FOUND)
63
- except Exception as e:
64
- import logging
65
- logger = logging.getLogger(__name__)
66
- logger.error(f"Error validating segment {segment_id}: {e}")
67
- return Response({
68
- "error": f"Validation failed: {str(e)}"
69
- }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
70
-
71
-
72
- class BulkSegmentValidateView(APIView):
73
- """
74
- POST /api/label-video-segments/validate-bulk/
75
-
76
- Validiert mehrere LabelVideoSegments gleichzeitig.
77
- Nützlich für Batch-Validierung nach Review.
78
-
79
- Body:
80
- {
81
- "segment_ids": [1, 2, 3, ...],
82
- "is_validated": true, // optional, default true
83
- "notes": "..." // optional, gilt für alle Segmente
84
- }
85
- """
86
- permission_classes = DEBUG_PERMISSIONS
87
-
88
- @transaction.atomic
89
- def post(self, request):
90
- segment_ids = request.data.get('segment_ids', [])
91
- is_validated = request.data.get('is_validated', True)
92
- notes = request.data.get('notes', '')
93
-
94
- if not segment_ids:
95
- return Response({
96
- "error": "segment_ids is required"
97
- }, status=status.HTTP_400_BAD_REQUEST)
98
-
99
- try:
100
- # Alle Segmente abrufen
101
- segments = LabelVideoSegment.objects.filter(pk__in=segment_ids).select_related('state')
102
-
103
- if not segments.exists():
104
- return Response({
105
- "error": "No segments found with provided IDs"
106
- }, status=status.HTTP_404_NOT_FOUND)
107
-
108
- updated_count = 0
109
- failed_ids = []
110
-
111
- for segment in segments:
112
- try:
113
- if segment.state:
114
- segment.state.is_validated = is_validated
115
- if notes and hasattr(segment.state, 'validation_notes'):
116
- segment.state.validation_notes = notes
117
- segment.state.save()
118
- updated_count += 1
119
- else:
120
- failed_ids.append(segment.id)
121
- except Exception as e:
122
- import logging
123
- logger = logging.getLogger(__name__)
124
- logger.error(f"Error validating segment {segment.id}: {e}")
125
- failed_ids.append(segment.id)
126
-
127
- response_data = {
128
- "message": f"Bulk validation completed. {updated_count} segments updated.",
129
- "updated_count": updated_count,
130
- "requested_count": len(segment_ids),
131
- "is_validated": is_validated
132
- }
133
-
134
- if failed_ids:
135
- response_data["failed_ids"] = failed_ids
136
- response_data["warning"] = f"{len(failed_ids)} segments could not be validated"
137
-
138
- return Response(response_data, status=status.HTTP_200_OK)
139
-
140
- except Exception as e:
141
- import logging
142
- logger = logging.getLogger(__name__)
143
- logger.error(f"Error in bulk validation: {e}")
144
- return Response({
145
- "error": f"Bulk validation failed: {str(e)}"
146
- }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
147
-
148
-
149
- class VideoSegmentValidationCompleteView(APIView):
150
- """
151
- POST /api/videos/<int:video_id>/segments/validate-complete/
152
-
153
- Markiert alle Segmente eines Videos als validiert.
154
- Nützlich nach vollständiger Review eines Videos.
155
-
156
- Body (optional):
157
- {
158
- "label_name": "...", // optional, nur Segmente mit diesem Label validieren
159
- "notes": "..." // optional
160
- }
161
- """
162
- permission_classes = DEBUG_PERMISSIONS
163
-
164
- @transaction.atomic
165
- def post(self, request, video_id: int):
166
- try:
167
- # Video abrufen
168
- video = VideoFile.objects.get(pk=video_id)
169
-
170
- label_name = request.data.get('label_name')
171
- notes = request.data.get('notes', '')
172
-
173
- # Segmente filtern
174
- segments_query = LabelVideoSegment.objects.filter(video_file=video).select_related('state', 'label')
175
-
176
- if label_name:
177
- segments_query = segments_query.filter(label__name=label_name)
178
-
179
- segments = segments_query.all()
180
-
181
- if not segments.exists():
182
- return Response({
183
- "message": "No segments found to validate",
184
- "video_id": video_id,
185
- "updated_count": 0
186
- }, status=status.HTTP_200_OK)
187
-
188
- updated_count = 0
189
- failed_count = 0
190
-
191
- for segment in segments:
192
- try:
193
- if segment.state:
194
- segment.state.is_validated = True
195
- if notes and hasattr(segment.state, 'validation_notes'):
196
- segment.state.validation_notes = notes
197
- segment.state.save()
198
- updated_count += 1
199
- else:
200
- failed_count += 1
201
- except Exception as e:
202
- import logging
203
- logger = logging.getLogger(__name__)
204
- logger.error(f"Error validating segment {segment.id}: {e}")
205
- failed_count += 1
206
-
207
- return Response({
208
- "message": f"Video segment validation completed for video {video_id}",
209
- "video_id": video_id,
210
- "total_segments": len(segments),
211
- "updated_count": updated_count,
212
- "failed_count": failed_count,
213
- "label_filter": label_name
214
- }, status=status.HTTP_200_OK)
215
-
216
- except VideoFile.DoesNotExist:
217
- return Response({
218
- "error": f"Video {video_id} not found"
219
- }, status=status.HTTP_404_NOT_FOUND)
220
- except Exception as e:
221
- import logging
222
- logger = logging.getLogger(__name__)
223
- logger.error(f"Error completing validation for video {video_id}: {e}")
224
- return Response({
225
- "error": f"Validation completion failed: {str(e)}"
226
- }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
@@ -1,71 +0,0 @@
1
- """
2
- Modern Media Framework - Video Segment API Views
3
- October 14, 2025 - Migration to unified /api/media/videos/<pk>/segments/ pattern
4
-
5
- This module provides modern framework views for video segment management,
6
- wrapping legacy segment views with pk-based parameter handling.
7
- """
8
- from endoreg_db.models import Label, LabelVideoSegment, VideoFile
9
- from endoreg_db.serializers.label_video_segment.label_video_segment import LabelVideoSegmentSerializer
10
-
11
- from django.db import transaction
12
- from rest_framework import status
13
- from rest_framework.decorators import api_view, permission_classes
14
- from rest_framework.response import Response
15
-
16
- from endoreg_db.utils.permissions import EnvironmentAwarePermission
17
- import logging
18
-
19
- logger = logging.getLogger(__name__)
20
-
21
-
22
- @api_view(['GET'])
23
- @permission_classes([EnvironmentAwarePermission])
24
- def video_segments_by_pk(request, pk):
25
- """
26
- Modern media framework endpoint for retrieving video segments.
27
-
28
- GET /api/media/videos/<int:pk>/segments/?label=<label_name>
29
-
30
- Returns all segments for a video, optionally filtered by label name.
31
- This is the modern replacement for /api/video/<id>/segments/
32
-
33
- Query Parameters:
34
- label (str, optional): Filter segments by label name (e.g., 'outside')
35
-
36
- Returns:
37
- 200: List of video segments
38
- 404: Video not found
39
- """
40
- try:
41
- video = VideoFile.objects.get(id=pk)
42
- except VideoFile.DoesNotExist:
43
- logger.warning(f"Video with pk {pk} not found")
44
- return Response(
45
- {'error': f'Video with id {pk} not found'},
46
- status=status.HTTP_404_NOT_FOUND
47
- )
48
-
49
- # Start with all segments for this video
50
- queryset = LabelVideoSegment.objects.filter(video_file=video)
51
-
52
- # Optional filtering by label name
53
- label_name = request.GET.get('label')
54
- if label_name:
55
- try:
56
- label = Label.objects.get(name=label_name)
57
- queryset = queryset.filter(label=label)
58
- logger.info(f"Filtering segments for video {pk} by label '{label_name}'")
59
- except Label.DoesNotExist:
60
- logger.warning(f"Label '{label_name}' not found, returning empty result")
61
- return Response(
62
- {'error': f"Label '{label_name}' not found"},
63
- status=status.HTTP_404_NOT_FOUND
64
- )
65
-
66
- # Order by start time for consistent results
67
- segments = queryset.order_by('start_frame_number')
68
- serializer = LabelVideoSegmentSerializer(segments, many=True)
69
-
70
- logger.info(f"Returning {len(segments)} segments for video {pk}")
71
- return Response(serializer.data)