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.
- endoreg_db/data/__init__.py +22 -8
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +0 -1
- endoreg_db/data/examination/examinations/data.yaml +114 -14
- endoreg_db/data/examination/time-type/data.yaml +0 -3
- endoreg_db/data/examination_indication/endoscopy.yaml +108 -173
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +0 -70
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +33 -37
- endoreg_db/data/finding/00_generic.yaml +35 -0
- endoreg_db/data/finding/00_generic_complication.yaml +9 -0
- endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
- endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
- endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
- endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
- endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
- endoreg_db/data/finding_classification/00_generic.yaml +44 -0
- endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
- endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
- endoreg_db/data/finding_classification/{colonoscopy_bowel_preparation.yaml → 02_colonoscopy_baseline.yaml} +35 -20
- endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
- endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
- endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
- endoreg_db/data/finding_classification_choice/{yes_no_na.yaml → 00_generic.yaml} +5 -1
- endoreg_db/data/finding_classification_choice/{examination_setting_generic_types.yaml → 00_generic_baseline.yaml} +10 -2
- endoreg_db/data/finding_classification_choice/{complication_generic_types.yaml → 00_generic_complication.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology.yaml → 00_generic_histology.yaml} +1 -4
- endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
- endoreg_db/data/finding_classification_choice/{bowel_preparation.yaml → 02_colonoscopy_bowel_preparation.yaml} +1 -30
- endoreg_db/data/{_examples/finding_classification_choice/colonoscopy_not_complete_reason.yaml → finding_classification_choice/02_colonoscopy_generic.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
- endoreg_db/data/{_examples/finding_classification_choice/colonoscopy_location.yaml → finding_classification_choice/02_colonoscopy_location.yaml} +23 -4
- endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
- endoreg_db/data/{_examples/finding_classification_choice/colon_lesion_paris.yaml → finding_classification_choice/02_colonoscopy_polyp_morphology.yaml} +26 -8
- endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
- endoreg_db/data/finding_classification_type/{colonoscopy_basic.yaml → 00_generic.yaml} +18 -13
- endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
- endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
- endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
- endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
- endoreg_db/data/finding_type/data.yaml +8 -12
- endoreg_db/data/requirement/01_patient_data.yaml +93 -0
- endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +0 -2
- endoreg_db/data/requirement_set/90_coloreg.yaml +20 -8
- endoreg_db/exceptions.py +0 -1
- endoreg_db/forms/examination_form.py +1 -1
- endoreg_db/helpers/data_loader.py +124 -52
- endoreg_db/helpers/default_objects.py +116 -81
- endoreg_db/import_files/__init__.py +27 -0
- endoreg_db/import_files/context/__init__.py +7 -0
- endoreg_db/import_files/context/default_sensitive_meta.py +81 -0
- endoreg_db/import_files/context/ensure_center.py +17 -0
- endoreg_db/import_files/context/file_lock.py +66 -0
- endoreg_db/import_files/context/import_context.py +43 -0
- endoreg_db/import_files/context/validate_directories.py +56 -0
- endoreg_db/import_files/file_storage/__init__.py +15 -0
- endoreg_db/import_files/file_storage/create_report_file.py +76 -0
- endoreg_db/import_files/file_storage/create_video_file.py +75 -0
- endoreg_db/import_files/file_storage/sensitive_meta_storage.py +39 -0
- endoreg_db/import_files/file_storage/state_management.py +400 -0
- endoreg_db/import_files/file_storage/storage.py +36 -0
- endoreg_db/import_files/import_service.md +26 -0
- endoreg_db/import_files/processing/__init__.py +11 -0
- endoreg_db/import_files/processing/report_processing/report_anonymization.py +94 -0
- endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
- endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
- endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +119 -0
- endoreg_db/import_files/pseudonymization/fake.py +52 -0
- endoreg_db/import_files/pseudonymization/k_anonymity.py +182 -0
- endoreg_db/import_files/pseudonymization/k_pseudonymity.py +128 -0
- endoreg_db/import_files/report_import_service.py +141 -0
- endoreg_db/import_files/video_import_service.py +150 -0
- endoreg_db/management/commands/import_report.py +130 -65
- endoreg_db/management/commands/import_video_with_classification.py +1 -1
- endoreg_db/management/commands/load_ai_model_data.py +5 -5
- endoreg_db/management/commands/load_ai_model_label_data.py +9 -7
- endoreg_db/management/commands/load_base_db_data.py +5 -134
- endoreg_db/management/commands/load_contraindication_data.py +14 -16
- endoreg_db/management/commands/load_disease_classification_choices_data.py +15 -18
- endoreg_db/management/commands/load_disease_classification_data.py +15 -18
- endoreg_db/management/commands/load_disease_data.py +25 -28
- endoreg_db/management/commands/load_endoscope_data.py +20 -27
- endoreg_db/management/commands/load_event_data.py +14 -16
- endoreg_db/management/commands/load_examination_data.py +31 -44
- endoreg_db/management/commands/load_examination_indication_data.py +20 -21
- endoreg_db/management/commands/load_finding_data.py +52 -80
- endoreg_db/management/commands/load_information_source.py +21 -23
- endoreg_db/management/commands/load_lab_value_data.py +17 -26
- endoreg_db/management/commands/load_medication_data.py +13 -12
- endoreg_db/management/commands/load_organ_data.py +15 -19
- endoreg_db/management/commands/load_pdf_type_data.py +19 -18
- endoreg_db/management/commands/load_profession_data.py +14 -17
- endoreg_db/management/commands/load_qualification_data.py +20 -23
- endoreg_db/management/commands/load_report_reader_flag_data.py +17 -19
- endoreg_db/management/commands/load_requirement_data.py +14 -20
- endoreg_db/management/commands/load_risk_data.py +7 -6
- endoreg_db/management/commands/load_shift_data.py +20 -23
- endoreg_db/management/commands/load_tag_data.py +8 -11
- endoreg_db/management/commands/load_unit_data.py +17 -19
- endoreg_db/management/commands/start_filewatcher.py +46 -37
- endoreg_db/management/commands/validate_video_files.py +1 -5
- endoreg_db/migrations/0001_initial.py +1360 -1812
- endoreg_db/models/administration/person/patient/patient.py +72 -46
- endoreg_db/models/label/__init__.py +2 -2
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +18 -26
- endoreg_db/models/label/label_video_segment/label_video_segment.py +23 -1
- endoreg_db/models/media/pdf/raw_pdf.py +136 -64
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +34 -10
- endoreg_db/models/media/processing_history/__init__.py +5 -0
- endoreg_db/models/media/processing_history/processing_history.py +96 -0
- endoreg_db/models/media/video/create_from_file.py +101 -31
- endoreg_db/models/media/video/video_file.py +125 -105
- endoreg_db/models/media/video/video_file_io.py +31 -26
- endoreg_db/models/medical/contraindication/README.md +1 -0
- endoreg_db/models/medical/examination/examination.py +28 -8
- endoreg_db/models/medical/examination/examination_indication.py +13 -79
- endoreg_db/models/medical/examination/examination_time.py +8 -3
- endoreg_db/models/medical/finding/finding.py +5 -12
- endoreg_db/models/medical/finding/finding_classification.py +18 -37
- endoreg_db/models/medical/finding/finding_intervention.py +7 -9
- endoreg_db/models/medical/hardware/endoscope.py +6 -0
- endoreg_db/models/medical/patient/medication_examples.py +5 -1
- endoreg_db/models/medical/patient/patient_finding.py +1 -1
- endoreg_db/models/metadata/pdf_meta.py +22 -10
- endoreg_db/models/metadata/sensitive_meta.py +3 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +200 -124
- endoreg_db/models/other/information_source.py +27 -6
- endoreg_db/models/report/__init__.py +0 -0
- endoreg_db/models/report/images.py +0 -0
- endoreg_db/models/report/report.py +6 -0
- endoreg_db/models/requirement/requirement.py +59 -399
- endoreg_db/models/requirement/requirement_operator.py +86 -98
- endoreg_db/models/state/audit_ledger.py +4 -5
- endoreg_db/models/state/raw_pdf.py +69 -30
- endoreg_db/models/state/video.py +64 -49
- endoreg_db/models/upload_job.py +33 -9
- endoreg_db/models/utils.py +27 -23
- endoreg_db/queries/__init__.py +3 -1
- endoreg_db/schemas/examination_evaluation.py +1 -1
- endoreg_db/serializers/__init__.py +2 -8
- endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
- endoreg_db/serializers/meta/__init__.py +1 -6
- endoreg_db/serializers/misc/sensitive_patient_data.py +50 -26
- endoreg_db/serializers/patient_examination/patient_examination.py +3 -3
- endoreg_db/serializers/pdf/anony_text_validation.py +39 -23
- endoreg_db/serializers/video/video_file_list.py +65 -34
- endoreg_db/services/__old/pdf_import.py +1487 -0
- endoreg_db/services/__old/video_import.py +1306 -0
- endoreg_db/services/anonymization.py +63 -26
- endoreg_db/services/lookup_service.py +28 -28
- endoreg_db/services/lookup_store.py +2 -2
- endoreg_db/services/pdf_import.py +0 -1480
- endoreg_db/services/report_import.py +10 -0
- endoreg_db/services/video_import.py +6 -1165
- endoreg_db/tasks/upload_tasks.py +79 -70
- endoreg_db/tasks/video_ingest.py +8 -4
- endoreg_db/urls/__init__.py +0 -14
- endoreg_db/urls/ai.py +32 -0
- endoreg_db/urls/media.py +21 -24
- endoreg_db/utils/dataloader.py +87 -57
- endoreg_db/utils/paths.py +110 -46
- endoreg_db/utils/pipelines/Readme.md +1 -1
- endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
- endoreg_db/views/__init__.py +85 -173
- endoreg_db/views/ai/__init__.py +8 -0
- endoreg_db/views/ai/label.py +155 -0
- endoreg_db/views/anonymization/media_management.py +8 -7
- endoreg_db/views/anonymization/overview.py +97 -68
- endoreg_db/views/anonymization/validate.py +25 -21
- endoreg_db/views/media/__init__.py +5 -20
- endoreg_db/views/media/pdf_media.py +109 -65
- endoreg_db/views/media/sensitive_metadata.py +163 -148
- endoreg_db/views/meta/__init__.py +0 -8
- endoreg_db/views/misc/__init__.py +1 -7
- endoreg_db/views/misc/upload_views.py +94 -93
- endoreg_db/views/report/__init__.py +7 -0
- endoreg_db/views/{pdf → report}/reimport.py +45 -24
- endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +40 -32
- endoreg_db/views/requirement/lookup_store.py +22 -90
- endoreg_db/views/video/__init__.py +23 -22
- endoreg_db/views/video/correction.py +201 -172
- endoreg_db/views/video/reimport.py +1 -1
- endoreg_db/views/{media/video_segments.py → video/segments_crud.py} +75 -37
- endoreg_db/views/video/{video_meta.py → video_meta_stats.py} +2 -2
- endoreg_db/views/video/video_stream.py +7 -8
- {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/METADATA +2 -2
- {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/RECORD +217 -335
- {endoreg_db-0.8.8.0.dist-info → endoreg_db-0.8.8.9.dist-info}/WHEEL +1 -1
- endoreg_db/data/_examples/disease.yaml +0 -55
- endoreg_db/data/_examples/disease_classification.yaml +0 -13
- endoreg_db/data/_examples/disease_classification_choice.yaml +0 -62
- endoreg_db/data/_examples/event.yaml +0 -64
- endoreg_db/data/_examples/examination.yaml +0 -72
- endoreg_db/data/_examples/finding/anatomy_colon.yaml +0 -128
- endoreg_db/data/_examples/finding/colonoscopy.yaml +0 -40
- endoreg_db/data/_examples/finding/colonoscopy_bowel_prep.yaml +0 -56
- endoreg_db/data/_examples/finding/complication.yaml +0 -16
- endoreg_db/data/_examples/finding/data.yaml +0 -105
- endoreg_db/data/_examples/finding/examination_setting.yaml +0 -16
- endoreg_db/data/_examples/finding/medication_related.yaml +0 -18
- endoreg_db/data/_examples/finding/outcome.yaml +0 -12
- endoreg_db/data/_examples/finding_classification/colonoscopy_bowel_preparation.yaml +0 -68
- endoreg_db/data/_examples/finding_classification/colonoscopy_jnet.yaml +0 -22
- endoreg_db/data/_examples/finding_classification/colonoscopy_kudo.yaml +0 -25
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_size.yaml +0 -68
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
- endoreg_db/data/_examples/finding_classification/colonoscopy_location.yaml +0 -80
- endoreg_db/data/_examples/finding_classification/colonoscopy_lst.yaml +0 -21
- endoreg_db/data/_examples/finding_classification/colonoscopy_nice.yaml +0 -20
- endoreg_db/data/_examples/finding_classification/colonoscopy_paris.yaml +0 -26
- endoreg_db/data/_examples/finding_classification/colonoscopy_sano.yaml +0 -22
- endoreg_db/data/_examples/finding_classification/colonoscopy_summary.yaml +0 -53
- endoreg_db/data/_examples/finding_classification/complication_generic.yaml +0 -25
- endoreg_db/data/_examples/finding_classification/examination_setting_generic.yaml +0 -40
- endoreg_db/data/_examples/finding_classification/histology_colo.yaml +0 -51
- endoreg_db/data/_examples/finding_classification/intervention_required.yaml +0 -26
- endoreg_db/data/_examples/finding_classification/medication_related.yaml +0 -23
- endoreg_db/data/_examples/finding_classification/visualized.yaml +0 -33
- endoreg_db/data/_examples/finding_classification_choice/bowel_preparation.yaml +0 -78
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_lst.yaml +0 -15
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_nice.yaml +0 -17
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_sano.yaml +0 -14
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
- endoreg_db/data/_examples/finding_classification_choice/colonoscopy_size.yaml +0 -82
- endoreg_db/data/_examples/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
- endoreg_db/data/_examples/finding_classification_choice/complication_generic_types.yaml +0 -15
- endoreg_db/data/_examples/finding_classification_choice/examination_setting_generic_types.yaml +0 -15
- endoreg_db/data/_examples/finding_classification_choice/histology.yaml +0 -24
- endoreg_db/data/_examples/finding_classification_choice/histology_polyp.yaml +0 -20
- endoreg_db/data/_examples/finding_classification_choice/outcome.yaml +0 -19
- endoreg_db/data/_examples/finding_classification_choice/yes_no_na.yaml +0 -11
- endoreg_db/data/_examples/finding_classification_type/colonoscopy_basic.yaml +0 -48
- endoreg_db/data/_examples/finding_intervention/endoscopy.yaml +0 -43
- endoreg_db/data/_examples/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
- endoreg_db/data/_examples/finding_intervention/endoscopy_egd.yaml +0 -128
- endoreg_db/data/_examples/finding_intervention/endoscopy_ercp.yaml +0 -32
- endoreg_db/data/_examples/finding_intervention/endoscopy_eus_lower.yaml +0 -9
- endoreg_db/data/_examples/finding_intervention/endoscopy_eus_upper.yaml +0 -36
- endoreg_db/data/_examples/finding_intervention_type/endoscopy.yaml +0 -15
- endoreg_db/data/_examples/finding_type/data.yaml +0 -43
- endoreg_db/data/_examples/requirement/age.yaml +0 -26
- endoreg_db/data/_examples/requirement/gender.yaml +0 -25
- endoreg_db/data/_examples/requirement_set/01_endoscopy_generic.yaml +0 -48
- endoreg_db/data/_examples/requirement_set/colonoscopy_austria_screening.yaml +0 -57
- endoreg_db/data/_examples/requirement_set/endoscopy_bleeding_risk.yaml +0 -52
- endoreg_db/data/_examples/yaml_examples.xlsx +0 -0
- endoreg_db/data/finding/anatomy_colon.yaml +0 -128
- endoreg_db/data/finding/colonoscopy.yaml +0 -40
- endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +0 -56
- endoreg_db/data/finding/complication.yaml +0 -16
- endoreg_db/data/finding/data.yaml +0 -105
- endoreg_db/data/finding/examination_setting.yaml +0 -16
- endoreg_db/data/finding/medication_related.yaml +0 -18
- endoreg_db/data/finding/outcome.yaml +0 -12
- endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +0 -22
- endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +0 -25
- endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
- endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +0 -38
- endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -49
- endoreg_db/data/finding_classification/colonoscopy_lst.yaml +0 -21
- endoreg_db/data/finding_classification/colonoscopy_nice.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_paris.yaml +0 -26
- endoreg_db/data/finding_classification/colonoscopy_sano.yaml +0 -22
- endoreg_db/data/finding_classification/colonoscopy_summary.yaml +0 -53
- endoreg_db/data/finding_classification/complication_generic.yaml +0 -25
- endoreg_db/data/finding_classification/examination_setting_generic.yaml +0 -40
- endoreg_db/data/finding_classification/histology_colo.yaml +0 -43
- endoreg_db/data/finding_classification/intervention_required.yaml +0 -26
- endoreg_db/data/finding_classification/medication_related.yaml +0 -23
- endoreg_db/data/finding_classification/visualized.yaml +0 -33
- endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
- endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
- endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
- endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +0 -15
- endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +0 -17
- endoreg_db/data/finding_classification_choice/colon_lesion_paris.yaml +0 -57
- endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +0 -14
- endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
- endoreg_db/data/finding_classification_choice/colonoscopy_location.yaml +0 -229
- endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +0 -19
- endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +0 -82
- endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
- endoreg_db/data/finding_classification_choice/outcome.yaml +0 -19
- endoreg_db/data/finding_intervention/endoscopy.yaml +0 -43
- endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
- endoreg_db/data/finding_intervention/endoscopy_egd.yaml +0 -128
- endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +0 -32
- endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +0 -9
- endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +0 -36
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +0 -79
- endoreg_db/data/requirement/age.yaml +0 -26
- endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +0 -45
- endoreg_db/data/requirement/disease_cardiovascular.yaml +0 -79
- endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +0 -41
- endoreg_db/data/requirement/disease_hepatology.yaml +0 -12
- endoreg_db/data/requirement/disease_misc.yaml +0 -12
- endoreg_db/data/requirement/disease_renal.yaml +0 -96
- endoreg_db/data/requirement/endoscopy_bleeding_risk.yaml +0 -59
- endoreg_db/data/requirement/event_cardiology.yaml +0 -251
- endoreg_db/data/requirement/event_requirements.yaml +0 -145
- endoreg_db/data/requirement/finding_colon_polyp.yaml +0 -50
- endoreg_db/data/requirement/gender.yaml +0 -25
- endoreg_db/data/requirement/lab_value.yaml +0 -441
- endoreg_db/data/requirement/medication.yaml +0 -93
- endoreg_db/data/requirement_operator/age.yaml +0 -13
- endoreg_db/data/requirement_operator/lab_operators.yaml +0 -129
- endoreg_db/data/requirement_operator/model_operators.yaml +0 -96
- endoreg_db/management/commands/init_default_ai_model.py +0 -112
- endoreg_db/management/commands/reset_celery_schedule.py +0 -9
- endoreg_db/management/commands/validate_video.py +0 -204
- endoreg_db/migrations/0002_requirementset_depends_on.py +0 -18
- endoreg_db/migrations/_old/0001_initial.py +0 -1857
- endoreg_db/migrations/_old/0002_add_video_correction_models.py +0 -52
- endoreg_db/migrations/_old/0003_add_center_display_name.py +0 -30
- endoreg_db/migrations/_old/0004_employee_city_employee_post_code_employee_street_and_more.py +0 -68
- endoreg_db/migrations/_old/0004_remove_casetemplate_rules_and_more.py +0 -77
- endoreg_db/migrations/_old/0005_merge_20251111_1003.py +0 -14
- endoreg_db/migrations/_old/0006_sensitivemeta_anonymized_text_and_more.py +0 -68
- endoreg_db/migrations/_old/0007_remove_rule_attribute_dtype_remove_rule_rule_type_and_more.py +0 -89
- endoreg_db/migrations/_old/0008_remove_event_event_classification_and_more.py +0 -27
- endoreg_db/migrations/_old/0009_alter_modelmeta_options_and_more.py +0 -21
- endoreg_db/renames.yml +0 -8
- endoreg_db/serializers/_old/raw_pdf_meta_validation.py +0 -223
- endoreg_db/serializers/_old/raw_video_meta_validation.py +0 -179
- endoreg_db/serializers/_old/video.py +0 -71
- endoreg_db/serializers/meta/pdf_file_meta_extraction.py +0 -115
- endoreg_db/serializers/meta/report_meta.py +0 -53
- endoreg_db/serializers/report/__init__.py +0 -9
- endoreg_db/serializers/report/mixins.py +0 -45
- endoreg_db/serializers/report/report.py +0 -105
- endoreg_db/serializers/report/report_list.py +0 -22
- endoreg_db/serializers/report/secure_file_url.py +0 -26
- endoreg_db/services/requirements_object.py +0 -147
- endoreg_db/services/storage_aware_video_processor.py +0 -370
- endoreg_db/urls/files.py +0 -6
- endoreg_db/urls/label_video_segment_validate.py +0 -33
- endoreg_db/urls/label_video_segments.py +0 -46
- endoreg_db/views/label/__init__.py +0 -5
- endoreg_db/views/label/label.py +0 -15
- endoreg_db/views/label_video_segment/__init__.py +0 -16
- endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +0 -44
- endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +0 -50
- endoreg_db/views/label_video_segment/label_video_segment.py +0 -77
- endoreg_db/views/label_video_segment/label_video_segment_by_label.py +0 -174
- endoreg_db/views/label_video_segment/label_video_segment_detail.py +0 -73
- endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +0 -46
- endoreg_db/views/label_video_segment/validate.py +0 -226
- endoreg_db/views/media/segments.py +0 -71
- endoreg_db/views/meta/available_files_list.py +0 -146
- endoreg_db/views/meta/report_meta.py +0 -53
- endoreg_db/views/meta/sensitive_meta_detail.py +0 -85
- endoreg_db/views/misc/secure_file_serving_view.py +0 -80
- endoreg_db/views/misc/secure_file_url_view.py +0 -84
- endoreg_db/views/misc/secure_url_validate.py +0 -79
- endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +0 -164
- endoreg_db/views/patient_finding_location/__init__.py +0 -5
- endoreg_db/views/patient_finding_location/pfl_create.py +0 -70
- endoreg_db/views/patient_finding_morphology/__init__.py +0 -5
- endoreg_db/views/patient_finding_morphology/pfm_create.py +0 -70
- endoreg_db/views/pdf/__init__.py +0 -8
- endoreg_db/views/video/segmentation.py +0 -274
- endoreg_db/views/video/task_status.py +0 -49
- endoreg_db/views/video/timeline.py +0 -46
- endoreg_db/views/video/video_analyze.py +0 -52
- /endoreg_db/data/requirement/{colon_polyp_intervention.yaml → old/colon_polyp_intervention.yaml} +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/colonoscopy_baseline_austria.yaml +0 -0
- /endoreg_db/data/requirement/{coloreg_colon_polyp.yaml → old/coloreg_colon_polyp.yaml} +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/disease_cardiovascular.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/disease_classification_choice_cardiovascular.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/disease_hepatology.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/disease_misc.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/disease_renal.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/endoscopy_bleeding_risk.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/event_cardiology.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/event_requirements.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/finding_colon_polyp.yaml +0 -0
- /endoreg_db/{migrations/__init__.py → data/requirement/old/gender.yaml} +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/lab_value.yaml +0 -0
- /endoreg_db/data/{_examples/requirement → requirement/old}/medication.yaml +0 -0
- /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/age.yaml +0 -0
- /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/lab_operators.yaml +0 -0
- /endoreg_db/data/{_examples/requirement_operator → requirement_operator/_old}/model_operators.yaml +0 -0
- /endoreg_db/{urls/sensitive_meta.py → import_files/pseudonymization/__init__.py} +0 -0
- /endoreg_db/{views/pdf/pdf_stream_views.py → import_files/pseudonymization/pseudonymize.py} +0 -0
- /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
- /endoreg_db/utils/requirement_operator_logic/{model_evaluators.py → _old/model_evaluators.py} +0 -0
- {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)
|