endoreg-db 0.8.6.1__py3-none-any.whl → 0.8.8.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of endoreg-db might be problematic. Click here for more details.
- endoreg_db/authz/auth.py +74 -0
- endoreg_db/authz/backends.py +168 -0
- endoreg_db/authz/management/commands/list_routes.py +18 -0
- endoreg_db/authz/middleware.py +83 -0
- endoreg_db/authz/permissions.py +127 -0
- endoreg_db/authz/policy.py +218 -0
- endoreg_db/authz/views_auth.py +66 -0
- endoreg_db/config/env.py +13 -8
- endoreg_db/data/__init__.py +2 -11
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +3 -3
- endoreg_db/data/event_classification/data.yaml +4 -0
- endoreg_db/data/event_classification_choice/data.yaml +9 -0
- 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/02_colonoscopy_baseline.yaml +83 -0
- 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/finding_classification_choice/{colonoscopy_not_complete_reason.yaml → 02_colonoscopy_generic.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{colonoscopy_location.yaml → 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/finding_classification_choice/{colon_lesion_paris.yaml → 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/old/colon_polyp_intervention.yaml +49 -0
- endoreg_db/data/requirement/old/coloreg_colon_polyp.yaml +49 -0
- endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +29 -12
- endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
- endoreg_db/data/requirement_set/{endoscopy_bleeding_risk.yaml → 02_endoscopy_bleeding_risk.yaml} +0 -6
- endoreg_db/data/requirement_set/90_coloreg.yaml +190 -0
- endoreg_db/data/requirement_set/_old_ +109 -0
- endoreg_db/data/requirement_set_type/data.yaml +21 -0
- endoreg_db/data/setup_config.yaml +4 -4
- endoreg_db/data/tag/requirement_set_tags.yaml +21 -0
- endoreg_db/exceptions.py +4 -2
- endoreg_db/forms/examination_form.py +1 -1
- endoreg_db/helpers/data_loader.py +125 -53
- 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/create_model_meta_from_huggingface.py +21 -10
- endoreg_db/management/commands/create_multilabel_model_meta.py +299 -129
- endoreg_db/management/commands/import_report.py +130 -65
- endoreg_db/management/commands/import_video.py +9 -10
- endoreg_db/management/commands/import_video_with_classification.py +2 -2
- endoreg_db/management/commands/list_routes.py +18 -0
- 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_center_data.py +12 -12
- 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 +62 -39
- endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
- 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/setup_endoreg_db.py +3 -3
- endoreg_db/management/commands/start_filewatcher.py +46 -37
- endoreg_db/management/commands/storage_management.py +271 -203
- endoreg_db/management/commands/validate_video_files.py +1 -5
- endoreg_db/migrations/0001_initial.py +297 -250
- endoreg_db/models/__init__.py +78 -123
- endoreg_db/models/administration/__init__.py +21 -42
- endoreg_db/models/administration/ai/active_model.py +2 -2
- endoreg_db/models/administration/ai/ai_model.py +7 -6
- endoreg_db/models/administration/case/__init__.py +1 -15
- endoreg_db/models/administration/case/case.py +3 -3
- endoreg_db/models/administration/case/case_template/__init__.py +2 -14
- endoreg_db/models/administration/case/case_template/case_template.py +2 -124
- endoreg_db/models/administration/case/case_template/case_template_rule.py +2 -268
- endoreg_db/models/administration/case/case_template/case_template_rule_value.py +2 -85
- endoreg_db/models/administration/case/case_template/case_template_type.py +2 -25
- endoreg_db/models/administration/center/center.py +33 -19
- endoreg_db/models/administration/center/center_product.py +12 -9
- endoreg_db/models/administration/center/center_resource.py +25 -19
- endoreg_db/models/administration/center/center_shift.py +21 -17
- endoreg_db/models/administration/center/center_waste.py +16 -8
- endoreg_db/models/administration/person/__init__.py +2 -0
- endoreg_db/models/administration/person/employee/employee.py +10 -5
- endoreg_db/models/administration/person/employee/employee_qualification.py +9 -4
- endoreg_db/models/administration/person/employee/employee_type.py +12 -6
- endoreg_db/models/administration/person/examiner/examiner.py +13 -11
- endoreg_db/models/administration/person/patient/__init__.py +2 -0
- endoreg_db/models/administration/person/patient/patient.py +129 -100
- endoreg_db/models/administration/person/patient/patient_external_id.py +37 -0
- endoreg_db/models/administration/person/person.py +4 -0
- endoreg_db/models/administration/person/profession/__init__.py +8 -4
- endoreg_db/models/administration/person/user/portal_user_information.py +11 -7
- endoreg_db/models/administration/product/product.py +20 -15
- endoreg_db/models/administration/product/product_material.py +17 -18
- endoreg_db/models/administration/product/product_weight.py +12 -8
- endoreg_db/models/administration/product/reference_product.py +23 -55
- endoreg_db/models/administration/qualification/qualification.py +7 -3
- endoreg_db/models/administration/qualification/qualification_type.py +7 -3
- endoreg_db/models/administration/shift/scheduled_days.py +8 -5
- endoreg_db/models/administration/shift/shift.py +16 -12
- endoreg_db/models/administration/shift/shift_type.py +23 -31
- endoreg_db/models/label/__init__.py +8 -9
- endoreg_db/models/label/annotation/image_classification.py +10 -9
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +23 -28
- endoreg_db/models/label/label.py +15 -15
- endoreg_db/models/label/label_set.py +19 -6
- endoreg_db/models/label/label_type.py +1 -1
- endoreg_db/models/label/label_video_segment/_create_from_video.py +5 -8
- endoreg_db/models/label/label_video_segment/label_video_segment.py +98 -102
- endoreg_db/models/label/video_segmentation_label.py +4 -0
- endoreg_db/models/label/video_segmentation_labelset.py +4 -3
- endoreg_db/models/media/frame/frame.py +22 -22
- endoreg_db/models/media/pdf/raw_pdf.py +194 -194
- endoreg_db/models/media/pdf/report_file.py +25 -29
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +55 -47
- endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
- 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/__init__.py +1 -0
- endoreg_db/models/media/video/create_from_file.py +139 -77
- endoreg_db/models/media/video/pipe_2.py +8 -9
- endoreg_db/models/media/video/video_file.py +174 -112
- endoreg_db/models/media/video/video_file_ai.py +288 -74
- endoreg_db/models/media/video/video_file_anonymize.py +38 -38
- endoreg_db/models/media/video/video_file_frames/__init__.py +3 -1
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +7 -9
- endoreg_db/models/media/video/video_file_frames/_delete_frames.py +9 -8
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +38 -45
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +4 -18
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -3
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +7 -6
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +15 -25
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +26 -23
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +23 -14
- endoreg_db/models/media/video/video_file_io.py +113 -61
- endoreg_db/models/media/video/video_file_meta/get_crop_template.py +3 -3
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +5 -3
- endoreg_db/models/media/video/video_file_meta/get_fps.py +37 -34
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +19 -25
- endoreg_db/models/media/video/video_file_meta/text_meta.py +41 -38
- endoreg_db/models/media/video/video_file_meta/video_meta.py +14 -7
- endoreg_db/models/media/video/video_file_segments.py +24 -17
- endoreg_db/models/media/video/video_metadata.py +19 -35
- endoreg_db/models/media/video/video_processing.py +96 -95
- endoreg_db/models/medical/contraindication/README.md +1 -0
- endoreg_db/models/medical/contraindication/__init__.py +13 -3
- endoreg_db/models/medical/disease.py +22 -16
- endoreg_db/models/medical/event.py +31 -18
- endoreg_db/models/medical/examination/__init__.py +13 -6
- endoreg_db/models/medical/examination/examination.py +39 -20
- endoreg_db/models/medical/examination/examination_indication.py +30 -95
- endoreg_db/models/medical/examination/examination_time.py +23 -8
- endoreg_db/models/medical/examination/examination_time_type.py +9 -6
- endoreg_db/models/medical/examination/examination_type.py +3 -4
- endoreg_db/models/medical/finding/finding.py +32 -40
- endoreg_db/models/medical/finding/finding_classification.py +42 -72
- endoreg_db/models/medical/finding/finding_intervention.py +25 -22
- endoreg_db/models/medical/finding/finding_type.py +13 -12
- endoreg_db/models/medical/hardware/endoscope.py +26 -26
- endoreg_db/models/medical/hardware/endoscopy_processor.py +2 -2
- endoreg_db/models/medical/laboratory/lab_value.py +62 -91
- endoreg_db/models/medical/medication/medication.py +22 -10
- endoreg_db/models/medical/medication/medication_indication.py +29 -3
- endoreg_db/models/medical/medication/medication_indication_type.py +25 -14
- endoreg_db/models/medical/medication/medication_intake_time.py +31 -19
- endoreg_db/models/medical/medication/medication_schedule.py +27 -16
- endoreg_db/models/medical/organ/__init__.py +15 -12
- endoreg_db/models/medical/patient/medication_examples.py +6 -6
- endoreg_db/models/medical/patient/patient_disease.py +20 -23
- endoreg_db/models/medical/patient/patient_event.py +19 -22
- endoreg_db/models/medical/patient/patient_examination.py +48 -54
- endoreg_db/models/medical/patient/patient_examination_indication.py +16 -14
- endoreg_db/models/medical/patient/patient_finding.py +122 -139
- endoreg_db/models/medical/patient/patient_finding_classification.py +44 -49
- endoreg_db/models/medical/patient/patient_finding_intervention.py +8 -19
- endoreg_db/models/medical/patient/patient_lab_sample.py +28 -23
- endoreg_db/models/medical/patient/patient_lab_value.py +82 -89
- endoreg_db/models/medical/patient/patient_medication.py +27 -38
- endoreg_db/models/medical/patient/patient_medication_schedule.py +28 -36
- endoreg_db/models/medical/risk/risk.py +7 -6
- endoreg_db/models/medical/risk/risk_type.py +8 -5
- endoreg_db/models/metadata/model_meta.py +60 -29
- endoreg_db/models/metadata/model_meta_logic.py +125 -18
- endoreg_db/models/metadata/pdf_meta.py +31 -24
- endoreg_db/models/metadata/sensitive_meta.py +105 -85
- endoreg_db/models/metadata/sensitive_meta_logic.py +198 -103
- endoreg_db/models/metadata/video_meta.py +51 -31
- endoreg_db/models/metadata/video_prediction_logic.py +16 -23
- endoreg_db/models/metadata/video_prediction_meta.py +29 -33
- endoreg_db/models/other/distribution/date_value_distribution.py +89 -29
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +21 -5
- endoreg_db/models/other/distribution/numeric_value_distribution.py +114 -53
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +4 -3
- endoreg_db/models/other/emission/emission_factor.py +18 -8
- endoreg_db/models/other/gender.py +10 -5
- endoreg_db/models/other/information_source.py +50 -29
- endoreg_db/models/other/material.py +9 -5
- endoreg_db/models/other/resource.py +6 -4
- endoreg_db/models/other/tag.py +10 -5
- endoreg_db/models/other/transport_route.py +13 -8
- endoreg_db/models/other/unit.py +10 -6
- endoreg_db/models/other/waste.py +6 -5
- endoreg_db/models/report/report.py +6 -0
- endoreg_db/models/requirement/requirement.py +329 -361
- endoreg_db/models/requirement/requirement_error.py +85 -0
- endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +3 -6
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +90 -64
- endoreg_db/models/requirement/requirement_operator.py +103 -112
- endoreg_db/models/requirement/requirement_set.py +74 -57
- endoreg_db/models/state/__init__.py +4 -4
- endoreg_db/models/state/abstract.py +2 -2
- endoreg_db/models/state/anonymization.py +12 -0
- endoreg_db/models/state/audit_ledger.py +49 -51
- endoreg_db/models/state/label_video_segment.py +9 -0
- endoreg_db/models/state/raw_pdf.py +101 -68
- endoreg_db/models/state/sensitive_meta.py +6 -2
- endoreg_db/models/state/video.py +110 -90
- endoreg_db/models/upload_job.py +35 -34
- endoreg_db/models/utils.py +28 -25
- endoreg_db/queries/__init__.py +3 -1
- endoreg_db/root_urls.py +21 -2
- endoreg_db/schemas/examination_evaluation.py +1 -1
- endoreg_db/serializers/__init__.py +2 -10
- endoreg_db/serializers/anonymization.py +18 -10
- endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
- endoreg_db/serializers/meta/__init__.py +1 -6
- endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
- endoreg_db/serializers/misc/file_overview.py +11 -99
- 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/requirements/requirement_sets.py +92 -22
- endoreg_db/serializers/video/segmentation.py +2 -1
- endoreg_db/serializers/video/video_file_list.py +65 -34
- endoreg_db/serializers/video/video_processing_history.py +20 -5
- endoreg_db/services/__old/pdf_import.py +1487 -0
- endoreg_db/services/__old/video_import.py +1306 -0
- endoreg_db/services/anonymization.py +128 -89
- endoreg_db/services/lookup_service.py +65 -52
- endoreg_db/services/lookup_store.py +2 -2
- endoreg_db/services/pdf_import.py +0 -1382
- endoreg_db/services/report_import.py +10 -0
- endoreg_db/services/video_import.py +6 -1255
- endoreg_db/tasks/upload_tasks.py +79 -70
- endoreg_db/tasks/video_ingest.py +8 -4
- endoreg_db/urls/__init__.py +5 -32
- endoreg_db/urls/ai.py +32 -0
- endoreg_db/urls/media.py +121 -83
- endoreg_db/urls/root_urls.py +29 -0
- endoreg_db/utils/__init__.py +15 -5
- endoreg_db/utils/ai/multilabel_classification_net.py +116 -20
- endoreg_db/utils/case_generator/__init__.py +3 -0
- endoreg_db/utils/dataloader.py +142 -40
- endoreg_db/utils/defaults/set_default_center.py +32 -0
- endoreg_db/utils/names.py +22 -16
- endoreg_db/utils/paths.py +110 -46
- endoreg_db/utils/permissions.py +2 -1
- endoreg_db/utils/pipelines/Readme.md +1 -1
- endoreg_db/utils/pipelines/process_video_dir.py +1 -1
- endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +655 -0
- endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
- endoreg_db/utils/setup_config.py +8 -5
- endoreg_db/utils/storage.py +115 -0
- endoreg_db/utils/validate_endo_roi.py +8 -2
- endoreg_db/utils/video/ffmpeg_wrapper.py +184 -188
- endoreg_db/views/__init__.py +85 -183
- endoreg_db/views/ai/__init__.py +8 -0
- endoreg_db/views/ai/label.py +155 -0
- endoreg_db/views/anonymization/media_management.py +202 -166
- endoreg_db/views/anonymization/overview.py +99 -67
- endoreg_db/views/anonymization/validate.py +182 -44
- endoreg_db/views/media/__init__.py +7 -20
- endoreg_db/views/media/pdf_media.py +197 -174
- endoreg_db/views/media/sensitive_metadata.py +193 -138
- endoreg_db/views/media/video_media.py +89 -82
- 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/patient/patient.py +5 -4
- endoreg_db/views/report/__init__.py +5 -7
- endoreg_db/views/{pdf → report}/reimport.py +22 -22
- endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +46 -39
- endoreg_db/views/requirement/evaluate.py +188 -187
- endoreg_db/views/requirement/lookup.py +17 -3
- endoreg_db/views/requirement/lookup_store.py +22 -90
- endoreg_db/views/requirement/requirement_utils.py +89 -0
- endoreg_db/views/video/__init__.py +23 -24
- 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} +77 -40
- 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.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/METADATA +7 -3
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/RECORD +391 -413
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/WHEEL +1 -1
- 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_bowel_preparation.yaml +0 -95
- 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 -68
- endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -80
- 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 -51
- 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_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_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/gender.yaml +0 -25
- 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_add_video_correction_models.py +0 -52
- endoreg_db/migrations/0003_add_center_display_name.py +0 -30
- endoreg_db/models/administration/permissions/__init__.py +0 -44
- endoreg_db/models/rule/__init__.py +0 -13
- endoreg_db/models/rule/rule.py +0 -27
- endoreg_db/models/rule/rule_applicator.py +0 -224
- endoreg_db/models/rule/rule_attribute_dtype.py +0 -17
- endoreg_db/models/rule/rule_type.py +0 -20
- endoreg_db/models/rule/ruleset.py +0 -17
- 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/serializers/video/video_metadata.py +0 -105
- endoreg_db/services/requirements_object.py +0 -147
- endoreg_db/services/storage_aware_video_processor.py +0 -344
- 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/urls/report.py +0 -48
- endoreg_db/urls/video.py +0 -61
- endoreg_db/utils/case_generator/case_generator.py +0 -159
- endoreg_db/utils/case_generator/utils.py +0 -30
- endoreg_db/utils/requirement_operator_logic/model_evaluators.py +0 -368
- 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 -148
- 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/report/report_list.py +0 -112
- endoreg_db/views/report/report_with_secure_url.py +0 -28
- endoreg_db/views/report/start_examination.py +0 -7
- 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/views.py +0 -0
- /endoreg_db/data/requirement/{colonoscopy_baseline_austria.yaml → old/colonoscopy_baseline_austria.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_cardiovascular.yaml → old/disease_cardiovascular.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_classification_choice_cardiovascular.yaml → old/disease_classification_choice_cardiovascular.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_hepatology.yaml → old/disease_hepatology.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_misc.yaml → old/disease_misc.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_renal.yaml → old/disease_renal.yaml} +0 -0
- /endoreg_db/data/requirement/{endoscopy_bleeding_risk.yaml → old/endoscopy_bleeding_risk.yaml} +0 -0
- /endoreg_db/data/requirement/{event_cardiology.yaml → old/event_cardiology.yaml} +0 -0
- /endoreg_db/data/requirement/{event_requirements.yaml → old/event_requirements.yaml} +0 -0
- /endoreg_db/data/requirement/{finding_colon_polyp.yaml → old/finding_colon_polyp.yaml} +0 -0
- /endoreg_db/{migrations/__init__.py → data/requirement/old/gender.yaml} +0 -0
- /endoreg_db/data/requirement/{lab_value.yaml → old/lab_value.yaml} +0 -0
- /endoreg_db/data/requirement/{medication.yaml → old/medication.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{age.yaml → _old/age.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{lab_operators.yaml → _old/lab_operators.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{model_operators.yaml → _old/model_operators.yaml} +0 -0
- /endoreg_db/{models/media/video/refactor_plan.md → import_files/pseudonymization/__init__.py} +0 -0
- /endoreg_db/{models/media/video/video_file_frames.py → import_files/pseudonymization/pseudonymize.py} +0 -0
- /endoreg_db/models/{metadata/frame_ocr_result.py → report/__init__.py} +0 -0
- /endoreg_db/{urls/sensitive_meta.py → models/report/images.py} +0 -0
- /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/licenses/LICENSE +0 -0
|
@@ -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)
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import RawPdfFile, VideoFile
|
|
2
|
-
from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
|
|
3
|
-
import logging
|
|
4
|
-
|
|
5
|
-
from rest_framework import status
|
|
6
|
-
from rest_framework.response import Response
|
|
7
|
-
from rest_framework.views import APIView
|
|
8
|
-
|
|
9
|
-
logger = logging.getLogger(__name__)
|
|
10
|
-
|
|
11
|
-
class AvailableFilesListView(APIView):
|
|
12
|
-
"""
|
|
13
|
-
API endpoint to list available PDFs and videos for anonymization selection.
|
|
14
|
-
|
|
15
|
-
GET: Returns lists of available PDF and video files with their metadata
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
permission_classes = DEBUG_PERMISSIONS
|
|
19
|
-
|
|
20
|
-
def _validate_pagination_params(self, request):
|
|
21
|
-
"""Validates and returns pagination parameters, raising ValueError on failure."""
|
|
22
|
-
try:
|
|
23
|
-
limit = int(request.query_params.get('limit', 50))
|
|
24
|
-
offset = int(request.query_params.get('offset', 0))
|
|
25
|
-
except (ValueError, TypeError):
|
|
26
|
-
raise ValueError("Invalid 'limit' or 'offset' parameter. Must be integers.")
|
|
27
|
-
|
|
28
|
-
if limit < 0 or offset < 0:
|
|
29
|
-
raise ValueError("'limit' and 'offset' must be non-negative.")
|
|
30
|
-
|
|
31
|
-
if limit > 100:
|
|
32
|
-
logger.warning(f"Client requested limit of {limit}, capping at 100.")
|
|
33
|
-
limit = 100
|
|
34
|
-
|
|
35
|
-
return limit, offset
|
|
36
|
-
|
|
37
|
-
def get(self, request):
|
|
38
|
-
"""
|
|
39
|
-
List available PDF and video files for anonymization selection.
|
|
40
|
-
|
|
41
|
-
Query Parameters:
|
|
42
|
-
- type: Filter by file type ('pdf' or 'video')
|
|
43
|
-
- status: Filter by anonymization status
|
|
44
|
-
- limit: Number of results to return (default 50, max 100)
|
|
45
|
-
- offset: Offset for pagination (default 0)
|
|
46
|
-
|
|
47
|
-
Returns:
|
|
48
|
-
{
|
|
49
|
-
"pdfs": [...],
|
|
50
|
-
"videos": [...],
|
|
51
|
-
"total_pdfs": N,
|
|
52
|
-
"total_videos": N
|
|
53
|
-
}
|
|
54
|
-
"""
|
|
55
|
-
try:
|
|
56
|
-
limit, offset = self._validate_pagination_params(request)
|
|
57
|
-
file_type = request.query_params.get('type', 'all').lower()
|
|
58
|
-
except ValueError as e:
|
|
59
|
-
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
|
|
60
|
-
|
|
61
|
-
try:
|
|
62
|
-
response_data = {}
|
|
63
|
-
|
|
64
|
-
# Get PDFs if requested
|
|
65
|
-
if file_type in ['all', 'pdf']:
|
|
66
|
-
pdf_queryset = RawPdfFile.objects.select_related('sensitive_meta').all()
|
|
67
|
-
total_pdfs = pdf_queryset.count()
|
|
68
|
-
paginated_pdfs = pdf_queryset[offset:offset + limit]
|
|
69
|
-
|
|
70
|
-
pdf_list = []
|
|
71
|
-
for pdf in paginated_pdfs:
|
|
72
|
-
# Safely handle missing file attribute
|
|
73
|
-
file_name = 'Unknown'
|
|
74
|
-
file_path = None
|
|
75
|
-
if hasattr(pdf, 'file') and pdf.file:
|
|
76
|
-
file_name = pdf.file.name.split('/')[-1]
|
|
77
|
-
file_path = pdf.file.name
|
|
78
|
-
pdf_data = {
|
|
79
|
-
'id': pdf.id,
|
|
80
|
-
'filename': file_name,
|
|
81
|
-
'file_path': file_path,
|
|
82
|
-
'sensitive_meta_id': pdf.sensitive_meta_id,
|
|
83
|
-
'anonymized_text': getattr(pdf, 'anonymized_text', None),
|
|
84
|
-
'created_at': pdf.date_created if hasattr(pdf, 'created_at') else None,
|
|
85
|
-
'patient_info': None
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
# Add patient info if available
|
|
89
|
-
if pdf.sensitive_meta:
|
|
90
|
-
pdf_data['patient_info'] = {
|
|
91
|
-
'patient_first_name': pdf.sensitive_meta.patient_first_name,
|
|
92
|
-
'patient_last_name': pdf.sensitive_meta.patient_last_name,
|
|
93
|
-
'patient_dob': pdf.sensitive_meta.patient_dob,
|
|
94
|
-
'examination_date': pdf.sensitive_meta.examination_date,
|
|
95
|
-
'center_name': pdf.sensitive_meta.center.name if pdf.sensitive_meta.center else None
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
pdf_list.append(pdf_data)
|
|
99
|
-
|
|
100
|
-
response_data['pdfs'] = pdf_list
|
|
101
|
-
response_data['total_pdfs'] = total_pdfs
|
|
102
|
-
|
|
103
|
-
# Get Videos if requested
|
|
104
|
-
if file_type in ['all', 'video']:
|
|
105
|
-
video_queryset = VideoFile.objects.select_related('sensitive_meta').all()
|
|
106
|
-
total_videos = video_queryset.count()
|
|
107
|
-
paginated_videos = video_queryset[offset:offset + limit]
|
|
108
|
-
|
|
109
|
-
video_list = []
|
|
110
|
-
for video in paginated_videos:
|
|
111
|
-
# Safely handle missing raw_file attribute
|
|
112
|
-
file_name = 'Unknown'
|
|
113
|
-
file_path = None
|
|
114
|
-
if hasattr(video, 'raw_file') and video.raw_file:
|
|
115
|
-
file_name = video.raw_file.name.split('/')[-1]
|
|
116
|
-
file_path = video.raw_file.name
|
|
117
|
-
video_data = {
|
|
118
|
-
'id': video.id,
|
|
119
|
-
'filename': file_name,
|
|
120
|
-
'file_path': file_path,
|
|
121
|
-
'sensitive_meta_id': video.sensitive_meta_id,
|
|
122
|
-
'patient_info': None
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
# Add patient info if available
|
|
126
|
-
if video.sensitive_meta:
|
|
127
|
-
video_data['patient_info'] = {
|
|
128
|
-
'patient_first_name': video.sensitive_meta.patient_first_name,
|
|
129
|
-
'patient_last_name': video.sensitive_meta.patient_last_name,
|
|
130
|
-
'patient_dob': video.sensitive_meta.patient_dob,
|
|
131
|
-
'examination_date': video.sensitive_meta.examination_date,
|
|
132
|
-
'center_name': video.sensitive_meta.center.name if video.sensitive_meta.center else None
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
video_list.append(video_data)
|
|
136
|
-
|
|
137
|
-
response_data['videos'] = video_list
|
|
138
|
-
response_data['total_videos'] = total_videos
|
|
139
|
-
|
|
140
|
-
return Response(response_data)
|
|
141
|
-
except Exception as e:
|
|
142
|
-
logger.error(f"Error listing available files: {e}", exc_info=True)
|
|
143
|
-
return Response(
|
|
144
|
-
{"error": "An unexpected error occurred while fetching files."},
|
|
145
|
-
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
146
|
-
)
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import RawPdfFile
|
|
2
|
-
|
|
3
|
-
from django.shortcuts import get_object_or_404
|
|
4
|
-
from rest_framework import status
|
|
5
|
-
from rest_framework.response import Response
|
|
6
|
-
from rest_framework.views import APIView
|
|
7
|
-
from pathlib import Path
|
|
8
|
-
import logging
|
|
9
|
-
|
|
10
|
-
logger = logging.getLogger(__name__)
|
|
11
|
-
|
|
12
|
-
class ReportFileMetadataView(APIView):
|
|
13
|
-
"""
|
|
14
|
-
API-Endpunkt für Report-Datei-Metadaten
|
|
15
|
-
GET /api/reports/{report_id}/file-metadata/
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
def get(self, _request, report_id):
|
|
19
|
-
try:
|
|
20
|
-
report = get_object_or_404(RawPdfFile, id=report_id)
|
|
21
|
-
|
|
22
|
-
if not report.file:
|
|
23
|
-
return Response(
|
|
24
|
-
{"error": "Keine Datei für diesen Report verfügbar"},
|
|
25
|
-
status=status.HTTP_404_NOT_FOUND
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
metadata = self._get_file_metadata(report)
|
|
29
|
-
return Response(metadata)
|
|
30
|
-
|
|
31
|
-
except (ValueError, TypeError) as e:
|
|
32
|
-
logger.error("Fehler beim Laden der Datei-Metadaten: %s", str(e))
|
|
33
|
-
return Response(
|
|
34
|
-
{"error": "Metadaten konnten nicht geladen werden"},
|
|
35
|
-
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
def _get_file_metadata(self, report):
|
|
39
|
-
"""Sammelt Datei-Metadaten"""
|
|
40
|
-
file_path = Path(report.file.name)
|
|
41
|
-
|
|
42
|
-
try:
|
|
43
|
-
file_size = report.file.size
|
|
44
|
-
except OSError:
|
|
45
|
-
file_size = 0
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
'filename': file_path.name,
|
|
49
|
-
'file_type': file_path.suffix.lower().lstrip('.'),
|
|
50
|
-
'file_size': file_size,
|
|
51
|
-
'upload_date': report.created_at if hasattr(report, 'created_at') else None,
|
|
52
|
-
'last_modified': report.updated_at if hasattr(report, 'updated_at') else None
|
|
53
|
-
}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import SensitiveMeta
|
|
2
|
-
from endoreg_db.serializers import SensitiveMetaDetailSerializer, SensitiveMetaUpdateSerializer
|
|
3
|
-
|
|
4
|
-
from django.db import transaction
|
|
5
|
-
from django.shortcuts import get_object_or_404
|
|
6
|
-
from rest_framework import status
|
|
7
|
-
from rest_framework.response import Response
|
|
8
|
-
from rest_framework.views import APIView
|
|
9
|
-
|
|
10
|
-
from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
|
|
11
|
-
import logging
|
|
12
|
-
|
|
13
|
-
logger = logging.getLogger(__name__)
|
|
14
|
-
|
|
15
|
-
class SensitiveMetaDetailView(APIView):
|
|
16
|
-
"""
|
|
17
|
-
API endpoint to retrieve and update SensitiveMeta details with verification state.
|
|
18
|
-
|
|
19
|
-
GET: Returns detailed SensitiveMeta information for annotation/verification
|
|
20
|
-
PATCH: Updates SensitiveMeta fields including verification state
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
permission_classes = DEBUG_PERMISSIONS # Changed from IsAuthenticated for development
|
|
24
|
-
|
|
25
|
-
def get(self, request, sensitive_meta_id=None):
|
|
26
|
-
"""
|
|
27
|
-
Retrieve SensitiveMeta details for display and annotation.
|
|
28
|
-
|
|
29
|
-
Supports both URL parameter and query parameter access patterns:
|
|
30
|
-
- /api/pdf/sensitivemeta/123/ (URL parameter)
|
|
31
|
-
- /api/pdf/sensitivemeta/?id=123 (query parameter - for backward compatibility)
|
|
32
|
-
- /api/pdf/sensitivemeta/ (list all - returns empty list instead of 400)
|
|
33
|
-
|
|
34
|
-
Returns detailed information suitable for user verification.
|
|
35
|
-
"""
|
|
36
|
-
# Handle both URL parameter and query parameter patterns
|
|
37
|
-
if not sensitive_meta_id:
|
|
38
|
-
sensitive_meta_id = request.query_params.get('id')
|
|
39
|
-
|
|
40
|
-
# If no ID provided, return empty list instead of error
|
|
41
|
-
if not sensitive_meta_id:
|
|
42
|
-
return Response([], status=status.HTTP_200_OK)
|
|
43
|
-
|
|
44
|
-
try:
|
|
45
|
-
# Convert to int if it's a string
|
|
46
|
-
sensitive_meta_id = int(sensitive_meta_id)
|
|
47
|
-
|
|
48
|
-
# Get the SensitiveMeta instance with related data
|
|
49
|
-
sensitive_meta = SensitiveMeta.objects.select_related(
|
|
50
|
-
'center',
|
|
51
|
-
'patient_gender',
|
|
52
|
-
'pseudo_patient',
|
|
53
|
-
'pseudo_examination'
|
|
54
|
-
).prefetch_related(
|
|
55
|
-
'examiners',
|
|
56
|
-
'state'
|
|
57
|
-
).get(id=sensitive_meta_id)
|
|
58
|
-
|
|
59
|
-
# Serialize for display
|
|
60
|
-
serializer = SensitiveMetaDetailSerializer(sensitive_meta)
|
|
61
|
-
|
|
62
|
-
# Return direct data to match anonymization store expectations
|
|
63
|
-
# Instead of wrapping in "sensitive_meta" key, return data directly
|
|
64
|
-
response_data = serializer.data
|
|
65
|
-
|
|
66
|
-
logger.info(f"Retrieved SensitiveMeta {sensitive_meta_id} for user {request.user}")
|
|
67
|
-
return Response(response_data, status=status.HTTP_200_OK)
|
|
68
|
-
|
|
69
|
-
except ValueError:
|
|
70
|
-
return Response(
|
|
71
|
-
{"error": "Invalid sensitive_meta_id format. Must be an integer."},
|
|
72
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
73
|
-
)
|
|
74
|
-
except SensitiveMeta.DoesNotExist:
|
|
75
|
-
return Response(
|
|
76
|
-
{"error": f"SensitiveMeta with ID {sensitive_meta_id} not found"},
|
|
77
|
-
status=status.HTTP_404_NOT_FOUND
|
|
78
|
-
)
|
|
79
|
-
except Exception as e:
|
|
80
|
-
logger.error(f"Error retrieving SensitiveMeta {sensitive_meta_id}: {e}")
|
|
81
|
-
return Response(
|
|
82
|
-
{"error": "Internal server error occurred"},
|
|
83
|
-
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
84
|
-
)
|
|
85
|
-
|
|
86
|
-
@transaction.atomic
|
|
87
|
-
def patch(self, request, sensitive_meta_id=None):
|
|
88
|
-
"""
|
|
89
|
-
Update SensitiveMeta fields including verification state.
|
|
90
|
-
|
|
91
|
-
Accepts partial updates for any field in SensitiveMetaUpdateSerializer.
|
|
92
|
-
Special handling for verification state changes.
|
|
93
|
-
"""
|
|
94
|
-
if not sensitive_meta_id:
|
|
95
|
-
return Response(
|
|
96
|
-
{"error": "sensitive_meta_id is required"},
|
|
97
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
try:
|
|
101
|
-
# Get the SensitiveMeta instance
|
|
102
|
-
sensitive_meta = get_object_or_404(SensitiveMeta, id=sensitive_meta_id)
|
|
103
|
-
|
|
104
|
-
# Validate and update using serializer
|
|
105
|
-
serializer = SensitiveMetaUpdateSerializer(
|
|
106
|
-
sensitive_meta,
|
|
107
|
-
data=request.data,
|
|
108
|
-
partial=True
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
if serializer.is_valid():
|
|
112
|
-
updated_instance = serializer.save()
|
|
113
|
-
|
|
114
|
-
# Return updated data using detail serializer
|
|
115
|
-
response_serializer = SensitiveMetaDetailSerializer(updated_instance)
|
|
116
|
-
|
|
117
|
-
response_data = {
|
|
118
|
-
"message": "SensitiveMeta updated successfully",
|
|
119
|
-
"sensitive_meta": response_serializer.data,
|
|
120
|
-
"updated_fields": list(request.data.keys())
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
logger.info(
|
|
124
|
-
f"Updated SensitiveMeta {sensitive_meta_id} by user {request.user}. "
|
|
125
|
-
f"Fields: {list(request.data.keys())}"
|
|
126
|
-
)
|
|
127
|
-
|
|
128
|
-
return Response(response_data, status=status.HTTP_200_OK)
|
|
129
|
-
else:
|
|
130
|
-
return Response(
|
|
131
|
-
{
|
|
132
|
-
"error": "Validation failed",
|
|
133
|
-
"details": serializer.errors
|
|
134
|
-
},
|
|
135
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
except SensitiveMeta.DoesNotExist:
|
|
139
|
-
return Response(
|
|
140
|
-
{"error": f"SensitiveMeta with ID {sensitive_meta_id} not found"},
|
|
141
|
-
status=status.HTTP_404_NOT_FOUND
|
|
142
|
-
)
|
|
143
|
-
except Exception as e:
|
|
144
|
-
logger.error(f"Error updating SensitiveMeta {sensitive_meta_id}: {e}")
|
|
145
|
-
return Response(
|
|
146
|
-
{"error": "Internal server error occurred"},
|
|
147
|
-
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
148
|
-
)
|