endoreg-db 0.8.9.32__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/__init__.py +0 -0
- endoreg_db/_version.py +34 -0
- endoreg_db/admin.py +97 -0
- endoreg_db/api/serializers/finding_descriptions.py +0 -0
- endoreg_db/api/views/finding_descriptions.py +0 -0
- endoreg_db/api_urls.py +4 -0
- endoreg_db/apps.py +17 -0
- endoreg_db/assets/dummy_model.ckpt +1 -0
- endoreg_db/authz/auth.py +78 -0
- endoreg_db/authz/backends.py +168 -0
- endoreg_db/authz/management/commands/list_routes.py +20 -0
- endoreg_db/authz/middleware.py +84 -0
- endoreg_db/authz/permissions.py +138 -0
- endoreg_db/authz/policy.py +224 -0
- endoreg_db/authz/settings.py +64 -0
- endoreg_db/authz/views_auth.py +70 -0
- endoreg_db/codemods/readme.md +88 -0
- endoreg_db/codemods/rename_datetime_fields.py +99 -0
- endoreg_db/config/__init__.py +0 -0
- endoreg_db/config/env.py +106 -0
- endoreg_db/config/settings/__init__.py +6 -0
- endoreg_db/config/settings/base.py +148 -0
- endoreg_db/config/settings/case_gen.py +32 -0
- endoreg_db/config/settings/dev.py +108 -0
- endoreg_db/config/settings/keycloak.py +177 -0
- endoreg_db/config/settings/prod.py +66 -0
- endoreg_db/config/settings/test.py +72 -0
- endoreg_db/data/__init__.py +135 -0
- endoreg_db/data/ai_model/data.yaml +7 -0
- endoreg_db/data/ai_model_label/label/data.yaml +88 -0
- endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
- endoreg_db/data/ai_model_label/label-set/data.yaml +40 -0
- endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
- endoreg_db/data/ai_model_label/label-type/data.yaml +7 -0
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +27 -0
- endoreg_db/data/ai_model_type/data.yaml +7 -0
- endoreg_db/data/ai_model_video_segmentation_label/base_segmentation.yaml +176 -0
- endoreg_db/data/ai_model_video_segmentation_labelset/data.yaml +20 -0
- endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +167 -0
- endoreg_db/data/case_template/rule/01_patient-set-age.yaml +8 -0
- endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +9 -0
- endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +23 -0
- endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +19 -0
- endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +19 -0
- endoreg_db/data/case_template/rule/19_create_patient.yaml +17 -0
- endoreg_db/data/case_template/rule_type/base_types.yaml +35 -0
- endoreg_db/data/case_template/rule_value/.init +0 -0
- endoreg_db/data/case_template/rule_value_type/base_types.yaml +59 -0
- endoreg_db/data/case_template/template/base.yaml +8 -0
- endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +3 -0
- endoreg_db/data/case_template/tmp/_rule_value +13 -0
- endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -0
- endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +10 -0
- endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +7 -0
- endoreg_db/data/center/data.yaml +99 -0
- endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -0
- endoreg_db/data/center_shift/ukw.yaml +9 -0
- endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -0
- endoreg_db/data/contraindication/bleeding.yaml +11 -0
- endoreg_db/data/db_summary.csv +58 -0
- endoreg_db/data/db_summary.xlsx +0 -0
- endoreg_db/data/disease/cardiovascular.yaml +37 -0
- endoreg_db/data/disease/hepatology.yaml +5 -0
- endoreg_db/data/disease/misc.yaml +5 -0
- endoreg_db/data/disease/renal.yaml +5 -0
- endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +6 -0
- endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +6 -0
- endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +41 -0
- endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +20 -0
- endoreg_db/data/distribution/date/patient.yaml +7 -0
- endoreg_db/data/distribution/multiple_categorical/.init +0 -0
- endoreg_db/data/distribution/numeric/data.yaml +14 -0
- endoreg_db/data/distribution/single_categorical/patient.yaml +7 -0
- endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -0
- endoreg_db/data/endoscope/data.yaml +93 -0
- endoreg_db/data/endoscope_type/data.yaml +11 -0
- endoreg_db/data/endoscopy_processor/data.yaml +50 -0
- endoreg_db/data/event/cardiology.yaml +15 -0
- endoreg_db/data/event/neurology.yaml +14 -0
- endoreg_db/data/event/surgery.yaml +13 -0
- endoreg_db/data/event/thrombembolism.yaml +20 -0
- 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 +172 -0
- endoreg_db/data/examination/time/data.yaml +48 -0
- endoreg_db/data/examination/time-type/data.yaml +5 -0
- endoreg_db/data/examination/type/data.yaml +17 -0
- endoreg_db/data/examination_indication/endoscopy.yaml +359 -0
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +90 -0
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +97 -0
- endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
- 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/00_generic.yaml +15 -0
- endoreg_db/data/finding_classification_choice/00_generic_baseline.yaml +23 -0
- endoreg_db/data/finding_classification_choice/00_generic_complication.yaml +15 -0
- endoreg_db/data/finding_classification_choice/00_generic_histology.yaml +21 -0
- endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_bowel_preparation.yaml +49 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_generic.yaml +19 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_histology.yaml +20 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_location.yaml +248 -0
- 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/02_colonoscopy_polyp_morphology.yaml +75 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
- endoreg_db/data/finding_classification_type/00_generic.yaml +53 -0
- 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_intervention_type/endoscopy.yaml +15 -0
- endoreg_db/data/finding_type/data.yaml +39 -0
- endoreg_db/data/gender/data.yaml +42 -0
- endoreg_db/data/information_source/annotation.yaml +6 -0
- endoreg_db/data/information_source/data.yaml +30 -0
- endoreg_db/data/information_source/endoscopy_guidelines.yaml +7 -0
- endoreg_db/data/information_source/medication.yaml +6 -0
- endoreg_db/data/information_source/prediction.yaml +7 -0
- endoreg_db/data/information_source_type/data.yaml +8 -0
- endoreg_db/data/lab_value/cardiac_enzymes.yaml +37 -0
- endoreg_db/data/lab_value/coagulation.yaml +54 -0
- endoreg_db/data/lab_value/electrolytes.yaml +228 -0
- endoreg_db/data/lab_value/gastrointestinal_function.yaml +133 -0
- endoreg_db/data/lab_value/hematology.yaml +184 -0
- endoreg_db/data/lab_value/hormones.yaml +59 -0
- endoreg_db/data/lab_value/lipids.yaml +53 -0
- endoreg_db/data/lab_value/misc.yaml +76 -0
- endoreg_db/data/lab_value/renal_function.yaml +12 -0
- endoreg_db/data/log_type/data.yaml +57 -0
- endoreg_db/data/lx_client_tag/base.yaml +54 -0
- endoreg_db/data/lx_client_type/base.yaml +30 -0
- endoreg_db/data/lx_permission/base.yaml +24 -0
- endoreg_db/data/lx_permission/endoreg.yaml +52 -0
- endoreg_db/data/material/material.yaml +91 -0
- endoreg_db/data/medication/anticoagulation.yaml +65 -0
- endoreg_db/data/medication/tah.yaml +70 -0
- endoreg_db/data/medication_indication/anticoagulation.yaml +115 -0
- endoreg_db/data/medication_indication_type/data.yaml +11 -0
- endoreg_db/data/medication_indication_type/thrombembolism.yaml +41 -0
- endoreg_db/data/medication_intake_time/base.yaml +31 -0
- endoreg_db/data/medication_schedule/apixaban.yaml +95 -0
- endoreg_db/data/medication_schedule/ass.yaml +12 -0
- endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -0
- endoreg_db/data/names_first/first_names.yaml +54 -0
- endoreg_db/data/names_last/last_names.yaml +51 -0
- endoreg_db/data/network_device/data.yaml +59 -0
- endoreg_db/data/network_device_type/data.yaml +12 -0
- endoreg_db/data/organ/data.yaml +29 -0
- endoreg_db/data/patient_lab_sample_type/generic.yaml +6 -0
- endoreg_db/data/pdf_type/data.yaml +46 -0
- endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -0
- endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -0
- endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -0
- endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -0
- endoreg_db/data/profession/data.yaml +70 -0
- endoreg_db/data/qualification/endoscopy.yaml +36 -0
- endoreg_db/data/qualification/m2.yaml +39 -0
- endoreg_db/data/qualification/outpatient_clinic.yaml +35 -0
- endoreg_db/data/qualification/sonography.yaml +36 -0
- endoreg_db/data/qualification_type/base.yaml +29 -0
- endoreg_db/data/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +55 -0
- endoreg_db/data/report_reader_flag/rkh-histology-generic.yaml +10 -0
- endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +30 -0
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +24 -0
- 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/colonoscopy_baseline_austria.yaml +45 -0
- endoreg_db/data/requirement/old/coloreg_colon_polyp.yaml +49 -0
- endoreg_db/data/requirement/old/disease_cardiovascular.yaml +79 -0
- endoreg_db/data/requirement/old/disease_classification_choice_cardiovascular.yaml +41 -0
- endoreg_db/data/requirement/old/disease_hepatology.yaml +12 -0
- endoreg_db/data/requirement/old/disease_misc.yaml +12 -0
- endoreg_db/data/requirement/old/disease_renal.yaml +96 -0
- endoreg_db/data/requirement/old/endoscopy_bleeding_risk.yaml +59 -0
- endoreg_db/data/requirement/old/event_cardiology.yaml +251 -0
- endoreg_db/data/requirement/old/event_requirements.yaml +145 -0
- endoreg_db/data/requirement/old/finding_colon_polyp.yaml +50 -0
- endoreg_db/data/requirement/old/gender.yaml +0 -0
- endoreg_db/data/requirement/old/lab_value.yaml +441 -0
- endoreg_db/data/requirement/old/medication.yaml +93 -0
- endoreg_db/data/requirement_operator/_old/age.yaml +13 -0
- endoreg_db/data/requirement_operator/_old/lab_operators.yaml +129 -0
- endoreg_db/data/requirement_operator/_old/model_operators.yaml +96 -0
- endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +65 -0
- endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
- endoreg_db/data/requirement_set/02_endoscopy_bleeding_risk.yaml +46 -0
- endoreg_db/data/requirement_set/90_coloreg.yaml +190 -0
- endoreg_db/data/requirement_set/_old_ +109 -0
- endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
- endoreg_db/data/requirement_set_type/data.yaml +41 -0
- endoreg_db/data/requirement_type/requirement_types.yaml +165 -0
- endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -0
- endoreg_db/data/risk/bleeding.yaml +26 -0
- endoreg_db/data/risk/thrombosis.yaml +37 -0
- endoreg_db/data/risk_type/data.yaml +27 -0
- endoreg_db/data/setup_config.yaml +38 -0
- endoreg_db/data/shift/endoscopy.yaml +21 -0
- endoreg_db/data/shift/m2.yaml +0 -0
- endoreg_db/data/shift_type/base.yaml +35 -0
- endoreg_db/data/tag/requirement_set_tags.yaml +32 -0
- endoreg_db/data/tmp/chronic_kidney_disease.yaml +0 -0
- endoreg_db/data/tmp/congestive_heart_failure.yaml +0 -0
- endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -0
- endoreg_db/data/unit/concentration.yaml +115 -0
- endoreg_db/data/unit/data.yaml +17 -0
- endoreg_db/data/unit/length.yaml +31 -0
- endoreg_db/data/unit/misc.yaml +20 -0
- endoreg_db/data/unit/rate.yaml +6 -0
- endoreg_db/data/unit/time.yaml +48 -0
- endoreg_db/data/unit/volume.yaml +35 -0
- endoreg_db/data/unit/weight.yaml +38 -0
- endoreg_db/data/waste/data.yaml +12 -0
- endoreg_db/exceptions.py +24 -0
- endoreg_db/export/frames/export.py +6 -0
- endoreg_db/export/frames/export_frames_with_labels.py +616 -0
- endoreg_db/factories/__init__.py +0 -0
- endoreg_db/forms/__init__.py +4 -0
- endoreg_db/forms/examination_form.py +12 -0
- endoreg_db/forms/patient_finding_intervention_form.py +40 -0
- endoreg_db/forms/patient_form.py +23 -0
- endoreg_db/forms/questionnaires/__init__.py +1 -0
- endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -0
- endoreg_db/forms/settings/__init__.py +11 -0
- endoreg_db/forms/unit.py +7 -0
- endoreg_db/helpers/__init__.py +0 -0
- endoreg_db/helpers/count_db.py +48 -0
- endoreg_db/helpers/data_loader.py +280 -0
- endoreg_db/helpers/default_objects.py +414 -0
- endoreg_db/helpers/download_segmentation_model.py +32 -0
- endoreg_db/helpers/interact.py +1 -0
- endoreg_db/helpers/test_video_helper.py +127 -0
- 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 +83 -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 +42 -0
- endoreg_db/import_files/context/validate_directories.py +57 -0
- endoreg_db/import_files/file_storage/__init__.py +15 -0
- endoreg_db/import_files/file_storage/create_report_file.py +99 -0
- endoreg_db/import_files/file_storage/create_video_file.py +104 -0
- endoreg_db/import_files/file_storage/sensitive_meta_storage.py +42 -0
- endoreg_db/import_files/file_storage/state_management.py +463 -0
- endoreg_db/import_files/file_storage/storage.py +42 -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 +99 -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/pseudonymization/__init__.py +0 -0
- endoreg_db/import_files/pseudonymization/fake.py +52 -0
- endoreg_db/import_files/pseudonymization/k_anonymity.py +181 -0
- endoreg_db/import_files/pseudonymization/k_pseudonymity.py +139 -0
- endoreg_db/import_files/pseudonymization/pseudonymize.py +0 -0
- endoreg_db/import_files/report_import_service.py +147 -0
- endoreg_db/import_files/video_import_service.py +154 -0
- endoreg_db/logger_conf.py +156 -0
- endoreg_db/management/__init__.py +1 -0
- endoreg_db/management/commands/__init__.py +1 -0
- endoreg_db/management/commands/anonymize_video.py +0 -0
- endoreg_db/management/commands/check_auth.py +132 -0
- endoreg_db/management/commands/create_model_meta_from_huggingface.py +177 -0
- endoreg_db/management/commands/create_multilabel_model_meta.py +419 -0
- endoreg_db/management/commands/export_frame_annot.py +196 -0
- endoreg_db/management/commands/fix_missing_patient_data.py +206 -0
- endoreg_db/management/commands/fix_video_paths.py +186 -0
- endoreg_db/management/commands/import_report.py +361 -0
- endoreg_db/management/commands/list_routes.py +20 -0
- endoreg_db/management/commands/load_ai_model_data.py +83 -0
- endoreg_db/management/commands/load_ai_model_label_data.py +60 -0
- endoreg_db/management/commands/load_base_db_data.py +63 -0
- endoreg_db/management/commands/load_center_data.py +68 -0
- endoreg_db/management/commands/load_contraindication_data.py +39 -0
- endoreg_db/management/commands/load_disease_classification_choices_data.py +38 -0
- endoreg_db/management/commands/load_disease_classification_data.py +38 -0
- endoreg_db/management/commands/load_disease_data.py +59 -0
- endoreg_db/management/commands/load_distribution_data.py +63 -0
- endoreg_db/management/commands/load_endoscope_data.py +58 -0
- endoreg_db/management/commands/load_event_data.py +39 -0
- endoreg_db/management/commands/load_examination_data.py +78 -0
- endoreg_db/management/commands/load_examination_indication_data.py +85 -0
- endoreg_db/management/commands/load_finding_data.py +115 -0
- endoreg_db/management/commands/load_gender_data.py +37 -0
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +142 -0
- endoreg_db/management/commands/load_information_source.py +46 -0
- endoreg_db/management/commands/load_lab_value_data.py +52 -0
- endoreg_db/management/commands/load_legacy_data.py +303 -0
- endoreg_db/management/commands/load_medication_data.py +104 -0
- endoreg_db/management/commands/load_name_data.py +36 -0
- endoreg_db/management/commands/load_organ_data.py +39 -0
- endoreg_db/management/commands/load_pdf_type_data.py +58 -0
- endoreg_db/management/commands/load_profession_data.py +40 -0
- endoreg_db/management/commands/load_qualification_data.py +56 -0
- endoreg_db/management/commands/load_report_reader_flag_data.py +40 -0
- endoreg_db/management/commands/load_requirement_data.py +207 -0
- endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
- endoreg_db/management/commands/load_risk_data.py +57 -0
- endoreg_db/management/commands/load_shift_data.py +57 -0
- endoreg_db/management/commands/load_tag_data.py +54 -0
- endoreg_db/management/commands/load_unit_data.py +40 -0
- endoreg_db/management/commands/load_user_groups.py +26 -0
- endoreg_db/management/commands/model_input.py +169 -0
- endoreg_db/management/commands/register_ai_model.py +70 -0
- endoreg_db/management/commands/setup_endoreg_db.py +459 -0
- endoreg_db/management/commands/start_filewatcher.py +115 -0
- endoreg_db/management/commands/storage_management.py +622 -0
- endoreg_db/management/commands/summarize_db_content.py +280 -0
- endoreg_db/management/commands/train_image_multilabel_model.py +144 -0
- endoreg_db/management/commands/validate_video_files.py +189 -0
- endoreg_db/management/commands/video_validation.py +20 -0
- endoreg_db/mermaid/Overall_flow_patient_finding_intervention.md +10 -0
- endoreg_db/mermaid/anonymized_image_annotation.md +20 -0
- endoreg_db/mermaid/binary_classification_annotation.md +50 -0
- endoreg_db/mermaid/classification.md +8 -0
- endoreg_db/mermaid/examination.md +8 -0
- endoreg_db/mermaid/findings.md +7 -0
- endoreg_db/mermaid/image_classification.md +28 -0
- endoreg_db/mermaid/interventions.md +8 -0
- endoreg_db/mermaid/morphology.md +8 -0
- endoreg_db/mermaid/patient_creation.md +14 -0
- endoreg_db/mermaid/video_segmentation_annotation.md +17 -0
- endoreg_db/migrations/0001_initial.py +1953 -0
- endoreg_db/migrations/__init__.py +0 -0
- endoreg_db/models/__init__.py +322 -0
- endoreg_db/models/administration/__init__.py +95 -0
- endoreg_db/models/administration/ai/__init__.py +9 -0
- endoreg_db/models/administration/ai/active_model.py +35 -0
- endoreg_db/models/administration/ai/ai_model.py +180 -0
- endoreg_db/models/administration/ai/model_type.py +42 -0
- endoreg_db/models/administration/case/__init__.py +5 -0
- endoreg_db/models/administration/case/case.py +114 -0
- endoreg_db/models/administration/case/case_template/__init__.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template_rule.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template_rule_value.py +3 -0
- endoreg_db/models/administration/case/case_template/case_template_type.py +3 -0
- endoreg_db/models/administration/center/__init__.py +13 -0
- endoreg_db/models/administration/center/center.py +85 -0
- endoreg_db/models/administration/center/center_product.py +67 -0
- endoreg_db/models/administration/center/center_resource.py +69 -0
- endoreg_db/models/administration/center/center_shift.py +94 -0
- endoreg_db/models/administration/center/center_waste.py +42 -0
- endoreg_db/models/administration/person/__init__.py +26 -0
- endoreg_db/models/administration/person/employee/__init__.py +3 -0
- endoreg_db/models/administration/person/employee/employee.py +40 -0
- endoreg_db/models/administration/person/employee/employee_qualification.py +44 -0
- endoreg_db/models/administration/person/employee/employee_type.py +50 -0
- endoreg_db/models/administration/person/examiner/__init__.py +4 -0
- endoreg_db/models/administration/person/examiner/examiner.py +64 -0
- endoreg_db/models/administration/person/names/__init__.py +0 -0
- endoreg_db/models/administration/person/names/first_name.py +20 -0
- endoreg_db/models/administration/person/names/last_name.py +20 -0
- endoreg_db/models/administration/person/patient/__init__.py +7 -0
- endoreg_db/models/administration/person/patient/patient.py +488 -0
- endoreg_db/models/administration/person/patient/patient_external_id.py +36 -0
- endoreg_db/models/administration/person/person.py +35 -0
- endoreg_db/models/administration/person/profession/__init__.py +28 -0
- endoreg_db/models/administration/person/user/__init__.py +5 -0
- endoreg_db/models/administration/person/user/portal_user_information.py +41 -0
- endoreg_db/models/administration/product/__init__.py +15 -0
- endoreg_db/models/administration/product/product.py +106 -0
- endoreg_db/models/administration/product/product_group.py +41 -0
- endoreg_db/models/administration/product/product_material.py +60 -0
- endoreg_db/models/administration/product/product_weight.py +51 -0
- endoreg_db/models/administration/product/reference_product.py +147 -0
- endoreg_db/models/administration/qualification/__init__.py +7 -0
- endoreg_db/models/administration/qualification/qualification.py +43 -0
- endoreg_db/models/administration/qualification/qualification_type.py +39 -0
- endoreg_db/models/administration/shift/__init__.py +9 -0
- endoreg_db/models/administration/shift/scheduled_days.py +72 -0
- endoreg_db/models/administration/shift/shift.py +57 -0
- endoreg_db/models/administration/shift/shift_type.py +108 -0
- endoreg_db/models/aidataset/__init__.py +5 -0
- endoreg_db/models/aidataset/aidataset.py +193 -0
- endoreg_db/models/label/__init__.py +23 -0
- endoreg_db/models/label/annotation/__init__.py +12 -0
- endoreg_db/models/label/annotation/image_classification.py +85 -0
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +61 -0
- endoreg_db/models/label/label.py +91 -0
- endoreg_db/models/label/label_set.py +68 -0
- endoreg_db/models/label/label_type.py +29 -0
- endoreg_db/models/label/label_video_segment/__init__.py +3 -0
- endoreg_db/models/label/label_video_segment/_create_from_video.py +42 -0
- endoreg_db/models/label/label_video_segment/label_video_segment.py +611 -0
- endoreg_db/models/label/video_segmentation_label.py +35 -0
- endoreg_db/models/label/video_segmentation_labelset.py +28 -0
- endoreg_db/models/media/__init__.py +23 -0
- endoreg_db/models/media/frame/__init__.py +3 -0
- endoreg_db/models/media/frame/frame.py +137 -0
- endoreg_db/models/media/pdf/__init__.py +12 -0
- endoreg_db/models/media/pdf/raw_pdf.py +764 -0
- endoreg_db/models/media/pdf/report_file.py +162 -0
- endoreg_db/models/media/pdf/report_reader/__init__.py +7 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +85 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +46 -0
- endoreg_db/models/media/video/__init__.py +9 -0
- endoreg_db/models/media/video/create_from_file.py +402 -0
- endoreg_db/models/media/video/pipe_1.py +258 -0
- endoreg_db/models/media/video/pipe_2.py +129 -0
- endoreg_db/models/media/video/video_file.py +907 -0
- endoreg_db/models/media/video/video_file_ai.py +828 -0
- endoreg_db/models/media/video/video_file_anonymize.py +524 -0
- endoreg_db/models/media/video/video_file_frames/__init__.py +49 -0
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +25 -0
- endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +23 -0
- endoreg_db/models/media/video/video_file_frames/_delete_frames.py +126 -0
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +233 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +36 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +13 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +24 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +40 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +44 -0
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +30 -0
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +205 -0
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +228 -0
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +107 -0
- endoreg_db/models/media/video/video_file_io.py +272 -0
- endoreg_db/models/media/video/video_file_meta/__init__.py +22 -0
- endoreg_db/models/media/video/video_file_meta/get_crop_template.py +58 -0
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +62 -0
- endoreg_db/models/media/video/video_file_meta/get_fps.py +183 -0
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +198 -0
- endoreg_db/models/media/video/video_file_meta/text_meta.py +178 -0
- endoreg_db/models/media/video/video_file_meta/video_meta.py +105 -0
- endoreg_db/models/media/video/video_file_segments.py +317 -0
- endoreg_db/models/media/video/video_metadata.py +67 -0
- endoreg_db/models/media/video/video_processing.py +192 -0
- endoreg_db/models/medical/__init__.py +136 -0
- endoreg_db/models/medical/contraindication/README.md +1 -0
- endoreg_db/models/medical/contraindication/__init__.py +29 -0
- endoreg_db/models/medical/disease.py +174 -0
- endoreg_db/models/medical/event.py +154 -0
- endoreg_db/models/medical/examination/__init__.py +20 -0
- endoreg_db/models/medical/examination/examination.py +183 -0
- endoreg_db/models/medical/examination/examination_indication.py +229 -0
- endoreg_db/models/medical/examination/examination_time.py +68 -0
- endoreg_db/models/medical/examination/examination_time_type.py +44 -0
- endoreg_db/models/medical/examination/examination_type.py +47 -0
- endoreg_db/models/medical/finding/__init__.py +20 -0
- endoreg_db/models/medical/finding/finding.py +113 -0
- endoreg_db/models/medical/finding/finding_classification.py +131 -0
- endoreg_db/models/medical/finding/finding_intervention.py +68 -0
- endoreg_db/models/medical/finding/finding_type.py +38 -0
- endoreg_db/models/medical/hardware/__init__.py +8 -0
- endoreg_db/models/medical/hardware/endoscope.py +77 -0
- endoreg_db/models/medical/hardware/endoscopy_processor.py +182 -0
- endoreg_db/models/medical/laboratory/__init__.py +5 -0
- endoreg_db/models/medical/laboratory/lab_value.py +490 -0
- endoreg_db/models/medical/medication/__init__.py +23 -0
- endoreg_db/models/medical/medication/medication.py +45 -0
- endoreg_db/models/medical/medication/medication_indication.py +78 -0
- endoreg_db/models/medical/medication/medication_indication_type.py +58 -0
- endoreg_db/models/medical/medication/medication_intake_time.py +58 -0
- endoreg_db/models/medical/medication/medication_schedule.py +58 -0
- endoreg_db/models/medical/organ/__init__.py +38 -0
- endoreg_db/models/medical/patient/__init__.py +48 -0
- endoreg_db/models/medical/patient/medication_examples.py +56 -0
- endoreg_db/models/medical/patient/patient_disease.py +72 -0
- endoreg_db/models/medical/patient/patient_event.py +80 -0
- endoreg_db/models/medical/patient/patient_examination.py +280 -0
- endoreg_db/models/medical/patient/patient_examination_indication.py +57 -0
- endoreg_db/models/medical/patient/patient_finding.py +416 -0
- endoreg_db/models/medical/patient/patient_finding_classification.py +231 -0
- endoreg_db/models/medical/patient/patient_finding_intervention.py +37 -0
- endoreg_db/models/medical/patient/patient_lab_sample.py +157 -0
- endoreg_db/models/medical/patient/patient_lab_value.py +247 -0
- endoreg_db/models/medical/patient/patient_medication.py +111 -0
- endoreg_db/models/medical/patient/patient_medication_schedule.py +152 -0
- endoreg_db/models/medical/risk/__init__.py +7 -0
- endoreg_db/models/medical/risk/risk.py +73 -0
- endoreg_db/models/medical/risk/risk_type.py +54 -0
- endoreg_db/models/metadata/__init__.py +19 -0
- endoreg_db/models/metadata/model_meta.py +266 -0
- endoreg_db/models/metadata/model_meta_logic.py +485 -0
- endoreg_db/models/metadata/pdf_meta.py +96 -0
- endoreg_db/models/metadata/sensitive_meta.py +345 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +1161 -0
- endoreg_db/models/metadata/video_meta.py +459 -0
- endoreg_db/models/metadata/video_prediction_logic.py +232 -0
- endoreg_db/models/metadata/video_prediction_meta.py +319 -0
- endoreg_db/models/operation_log.py +63 -0
- endoreg_db/models/other/__init__.py +40 -0
- endoreg_db/models/other/distribution/__init__.py +46 -0
- endoreg_db/models/other/distribution/base_value_distribution.py +22 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +163 -0
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +50 -0
- endoreg_db/models/other/distribution/numeric_value_distribution.py +211 -0
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +23 -0
- endoreg_db/models/other/emission/__init__.py +5 -0
- endoreg_db/models/other/emission/emission_factor.py +110 -0
- endoreg_db/models/other/gender.py +32 -0
- endoreg_db/models/other/information_source.py +190 -0
- endoreg_db/models/other/material.py +34 -0
- endoreg_db/models/other/resource.py +24 -0
- endoreg_db/models/other/tag.py +32 -0
- endoreg_db/models/other/transport_route.py +40 -0
- endoreg_db/models/other/unit.py +40 -0
- endoreg_db/models/other/waste.py +28 -0
- endoreg_db/models/report/__init__.py +0 -0
- endoreg_db/models/report/images.py +0 -0
- endoreg_db/models/report/report.py +5 -0
- endoreg_db/models/requirement/__init__.py +11 -0
- endoreg_db/models/requirement/requirement.py +792 -0
- endoreg_db/models/requirement/requirement_error.py +84 -0
- endoreg_db/models/requirement/requirement_evaluation/__init__.py +6 -0
- endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
- endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +6 -0
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +137 -0
- endoreg_db/models/requirement/requirement_operator.py +187 -0
- endoreg_db/models/requirement/requirement_set.py +327 -0
- endoreg_db/models/state/__init__.py +13 -0
- endoreg_db/models/state/abstract.py +11 -0
- endoreg_db/models/state/anonymization.py +30 -0
- endoreg_db/models/state/audit_ledger.py +155 -0
- endoreg_db/models/state/label_video_segment.py +31 -0
- endoreg_db/models/state/processing_history/__init__.py +3 -0
- endoreg_db/models/state/processing_history/processing_history.py +136 -0
- endoreg_db/models/state/raw_pdf.py +219 -0
- endoreg_db/models/state/sensitive_meta.py +50 -0
- endoreg_db/models/state/video.py +251 -0
- endoreg_db/models/upload_job.py +100 -0
- endoreg_db/models/utils.py +138 -0
- endoreg_db/queries/__init__.py +3 -0
- endoreg_db/queries/annotations/__init__.py +1 -0
- endoreg_db/queries/annotations/legacy.py +169 -0
- endoreg_db/queries/sanity/__init_.py +0 -0
- endoreg_db/root_urls.py +27 -0
- endoreg_db/schemas/__init__.py +0 -0
- endoreg_db/schemas/examination_evaluation.py +30 -0
- endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +861 -0
- endoreg_db/serializers/__init__.py +104 -0
- endoreg_db/serializers/administration/__init__.py +13 -0
- endoreg_db/serializers/administration/ai/__init__.py +9 -0
- endoreg_db/serializers/administration/ai/active_model.py +12 -0
- endoreg_db/serializers/administration/ai/ai_model.py +20 -0
- endoreg_db/serializers/administration/ai/model_type.py +12 -0
- endoreg_db/serializers/administration/center.py +14 -0
- endoreg_db/serializers/administration/gender.py +11 -0
- endoreg_db/serializers/anonymization.py +77 -0
- endoreg_db/serializers/evaluation/examination_evaluation.py +0 -0
- endoreg_db/serializers/examination/__init__.py +10 -0
- endoreg_db/serializers/examination/base.py +45 -0
- endoreg_db/serializers/examination/dropdown.py +20 -0
- endoreg_db/serializers/examination_serializer.py +9 -0
- endoreg_db/serializers/finding/__init__.py +5 -0
- endoreg_db/serializers/finding/finding.py +61 -0
- endoreg_db/serializers/finding_classification/__init__.py +7 -0
- endoreg_db/serializers/finding_classification/choice.py +19 -0
- endoreg_db/serializers/finding_classification/classification.py +11 -0
- endoreg_db/serializers/label_video_segment/__init__.py +9 -0
- endoreg_db/serializers/label_video_segment/image_classification_annotation.py +62 -0
- endoreg_db/serializers/label_video_segment/label/__init__.py +6 -0
- endoreg_db/serializers/label_video_segment/label/label.py +15 -0
- endoreg_db/serializers/label_video_segment/label_video_segment.py +427 -0
- endoreg_db/serializers/meta/__init__.py +13 -0
- endoreg_db/serializers/meta/sensitive_meta_detail.py +122 -0
- endoreg_db/serializers/meta/sensitive_meta_update.py +153 -0
- endoreg_db/serializers/meta/sensitive_meta_verification.py +62 -0
- endoreg_db/serializers/meta/video_meta.py +39 -0
- endoreg_db/serializers/misc/__init__.py +14 -0
- endoreg_db/serializers/misc/file_overview.py +72 -0
- endoreg_db/serializers/misc/sensitive_patient_data.py +144 -0
- endoreg_db/serializers/misc/stats.py +35 -0
- endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
- endoreg_db/serializers/misc/upload_job.py +74 -0
- endoreg_db/serializers/patient/__init__.py +12 -0
- endoreg_db/serializers/patient/patient.py +103 -0
- endoreg_db/serializers/patient/patient_dropdown.py +35 -0
- endoreg_db/serializers/patient_examination/__init__.py +7 -0
- endoreg_db/serializers/patient_examination/patient_examination.py +168 -0
- endoreg_db/serializers/patient_finding/__init__.py +15 -0
- endoreg_db/serializers/patient_finding/patient_finding.py +32 -0
- endoreg_db/serializers/patient_finding/patient_finding_classification.py +47 -0
- endoreg_db/serializers/patient_finding/patient_finding_detail.py +62 -0
- endoreg_db/serializers/patient_finding/patient_finding_intervention.py +28 -0
- endoreg_db/serializers/patient_finding/patient_finding_list.py +40 -0
- endoreg_db/serializers/patient_finding/patient_finding_write.py +135 -0
- endoreg_db/serializers/pdf/__init__.py +3 -0
- endoreg_db/serializers/pdf/anony_text_validation.py +101 -0
- endoreg_db/serializers/requirements/requirement_schema.py +20 -0
- endoreg_db/serializers/requirements/requirement_sets.py +99 -0
- endoreg_db/serializers/sensitive_meta_serializer.py +301 -0
- endoreg_db/serializers/video/__init__.py +7 -0
- endoreg_db/serializers/video/video_file.py +283 -0
- endoreg_db/serializers/video/video_file_brief.py +14 -0
- endoreg_db/serializers/video/video_file_detail.py +96 -0
- endoreg_db/serializers/video/video_file_list.py +100 -0
- endoreg_db/serializers/video/video_processing_history.py +172 -0
- endoreg_db/serializers/video_examination.py +198 -0
- endoreg_db/services/__init__.py +5 -0
- endoreg_db/services/anonymization.py +274 -0
- endoreg_db/services/examination_evaluation.py +172 -0
- endoreg_db/services/finding_description_service.py +0 -0
- endoreg_db/services/lookup_service.py +424 -0
- endoreg_db/services/lookup_store.py +266 -0
- endoreg_db/services/model_meta_from_hf.py +76 -0
- endoreg_db/services/pdf_import.py +0 -0
- endoreg_db/services/polling_coordinator.py +319 -0
- endoreg_db/services/pseudonym_service.py +94 -0
- endoreg_db/services/report_import.py +13 -0
- endoreg_db/services/segment_sync.py +171 -0
- endoreg_db/services/video_import.py +9 -0
- endoreg_db/templates/admin/patient_finding_intervention.html +253 -0
- endoreg_db/templates/admin/start_examination.html +12 -0
- endoreg_db/templates/timeline.html +176 -0
- endoreg_db/urls/__init__.py +56 -0
- endoreg_db/urls/ai.py +14 -0
- endoreg_db/urls/anonymization.py +78 -0
- endoreg_db/urls/auth.py +16 -0
- endoreg_db/urls/classification.py +34 -0
- endoreg_db/urls/examination.py +63 -0
- endoreg_db/urls/media.py +251 -0
- endoreg_db/urls/patient.py +23 -0
- endoreg_db/urls/requirements.py +15 -0
- endoreg_db/urls/root_urls.py +28 -0
- endoreg_db/urls/stats.py +54 -0
- endoreg_db/urls/upload.py +12 -0
- endoreg_db/urls.py +9 -0
- endoreg_db/utils/__init__.py +97 -0
- endoreg_db/utils/ai/__init__.py +9 -0
- endoreg_db/utils/ai/data_loader_for_model_input.py +262 -0
- endoreg_db/utils/ai/data_loader_for_model_training.py +262 -0
- endoreg_db/utils/ai/get.py +6 -0
- endoreg_db/utils/ai/inference_dataset.py +51 -0
- endoreg_db/utils/ai/model_training/config.py +117 -0
- endoreg_db/utils/ai/model_training/dataset.py +74 -0
- endoreg_db/utils/ai/model_training/losses.py +68 -0
- endoreg_db/utils/ai/model_training/metrics.py +78 -0
- endoreg_db/utils/ai/model_training/model_backbones.py +155 -0
- endoreg_db/utils/ai/model_training/model_gastronet_resnet.py +118 -0
- endoreg_db/utils/ai/model_training/trainer_gastronet_multilabel.py +771 -0
- endoreg_db/utils/ai/multilabel_classification_net.py +270 -0
- endoreg_db/utils/ai/postprocess.py +63 -0
- endoreg_db/utils/ai/predict.py +293 -0
- endoreg_db/utils/ai/preprocess.py +76 -0
- endoreg_db/utils/calc_duration_seconds.py +24 -0
- endoreg_db/utils/case_generator/__init__.py +3 -0
- endoreg_db/utils/case_generator/lab_sample_factory.py +32 -0
- endoreg_db/utils/check_video_files.py +175 -0
- endoreg_db/utils/cropping.py +30 -0
- endoreg_db/utils/dataloader.py +285 -0
- endoreg_db/utils/dates.py +59 -0
- endoreg_db/utils/defaults/set_default_center.py +33 -0
- endoreg_db/utils/env.py +37 -0
- endoreg_db/utils/extract_specific_frames.py +87 -0
- endoreg_db/utils/file_operations.py +70 -0
- endoreg_db/utils/fix_video_path_direct.py +157 -0
- endoreg_db/utils/frame_anonymization_utils.py +463 -0
- endoreg_db/utils/hashs.py +138 -0
- endoreg_db/utils/links/__init__.py +0 -0
- endoreg_db/utils/links/requirement_link.py +237 -0
- endoreg_db/utils/mime_types.py +0 -0
- endoreg_db/utils/names.py +82 -0
- endoreg_db/utils/ocr.py +195 -0
- endoreg_db/utils/operation_log.py +87 -0
- endoreg_db/utils/parse_and_generate_yaml.py +45 -0
- endoreg_db/utils/paths.py +159 -0
- endoreg_db/utils/permissions.py +160 -0
- endoreg_db/utils/pipelines/Readme.md +235 -0
- endoreg_db/utils/pipelines/__init__.py +0 -0
- endoreg_db/utils/pipelines/process_video_dir.py +144 -0
- endoreg_db/utils/product/__init__.py +0 -0
- endoreg_db/utils/product/sum_emissions.py +22 -0
- endoreg_db/utils/product/sum_weights.py +20 -0
- endoreg_db/utils/pydantic_models/__init__.py +5 -0
- endoreg_db/utils/pydantic_models/db_config.py +57 -0
- endoreg_db/utils/requirement_helpers.py +0 -0
- endoreg_db/utils/requirement_operator_logic/__init__.py +0 -0
- endoreg_db/utils/requirement_operator_logic/_old/lab_value_operators.py +678 -0
- endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +842 -0
- endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +114 -0
- endoreg_db/utils/setup_config.py +196 -0
- endoreg_db/utils/storage.py +117 -0
- endoreg_db/utils/translation.py +31 -0
- endoreg_db/utils/uuid.py +5 -0
- endoreg_db/utils/validate_endo_roi.py +33 -0
- endoreg_db/utils/validate_subcategory_dict.py +93 -0
- endoreg_db/utils/validate_video_detailed.py +415 -0
- endoreg_db/utils/video/__init__.py +30 -0
- endoreg_db/utils/video/extract_frames.py +100 -0
- endoreg_db/utils/video/ffmpeg_wrapper.py +996 -0
- endoreg_db/utils/video/names.py +47 -0
- endoreg_db/utils/video/streaming_processor.py +386 -0
- endoreg_db/utils/video/video_splitter.py +105 -0
- endoreg_db/versioning.md +79 -0
- endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +247 -0
- endoreg_db/views/__init__.py +157 -0
- endoreg_db/views/anonymization/__init__.py +31 -0
- endoreg_db/views/anonymization/media_management.py +486 -0
- endoreg_db/views/anonymization/overview.py +307 -0
- endoreg_db/views/anonymization/validate.py +310 -0
- endoreg_db/views/auth/__init__.py +13 -0
- endoreg_db/views/auth/keycloak.py +146 -0
- endoreg_db/views/examination/__init__.py +30 -0
- endoreg_db/views/examination/examination.py +37 -0
- endoreg_db/views/examination/examination_manifest_cache.py +26 -0
- endoreg_db/views/examination/get_finding_classification_choices.py +62 -0
- endoreg_db/views/examination/get_finding_classifications.py +38 -0
- endoreg_db/views/examination/get_findings.py +39 -0
- endoreg_db/views/examination/get_instruments.py +19 -0
- endoreg_db/views/examination/get_interventions.py +14 -0
- endoreg_db/views/finding/__init__.py +9 -0
- endoreg_db/views/finding/finding.py +116 -0
- endoreg_db/views/finding/get_classifications.py +14 -0
- endoreg_db/views/finding/get_interventions.py +17 -0
- endoreg_db/views/finding_classification/__init__.py +13 -0
- endoreg_db/views/finding_classification/base.py +0 -0
- endoreg_db/views/finding_classification/finding_classification.py +41 -0
- endoreg_db/views/finding_classification/get_classification_choices.py +54 -0
- endoreg_db/views/media/__init__.py +32 -0
- endoreg_db/views/media/pdf_media.py +411 -0
- endoreg_db/views/media/sensitive_metadata.py +372 -0
- endoreg_db/views/media/video_media.py +275 -0
- endoreg_db/views/meta/__init__.py +7 -0
- endoreg_db/views/meta/sensitive_meta_list.py +102 -0
- endoreg_db/views/meta/sensitive_meta_verification.py +74 -0
- endoreg_db/views/misc/__init__.py +29 -0
- endoreg_db/views/misc/center.py +14 -0
- endoreg_db/views/misc/csrf.py +8 -0
- endoreg_db/views/misc/gender.py +15 -0
- endoreg_db/views/misc/stats.py +255 -0
- endoreg_db/views/misc/upload_views.py +241 -0
- endoreg_db/views/patient/__init__.py +3 -0
- endoreg_db/views/patient/patient.py +253 -0
- endoreg_db/views/patient_examination/__init__.py +11 -0
- endoreg_db/views/patient_examination/patient_examination.py +141 -0
- endoreg_db/views/patient_examination/patient_examination_create.py +58 -0
- endoreg_db/views/patient_examination/patient_examination_detail.py +63 -0
- endoreg_db/views/patient_examination/patient_examination_list.py +72 -0
- endoreg_db/views/patient_examination/video.py +228 -0
- endoreg_db/views/patient_finding/__init__.py +7 -0
- endoreg_db/views/patient_finding/base.py +0 -0
- endoreg_db/views/patient_finding/patient_finding.py +71 -0
- endoreg_db/views/patient_finding/patient_finding_optimized.py +291 -0
- endoreg_db/views/patient_finding_classification/__init__.py +5 -0
- endoreg_db/views/patient_finding_classification/pfc_create.py +75 -0
- endoreg_db/views/report/__init__.py +7 -0
- endoreg_db/views/report/reimport.py +177 -0
- endoreg_db/views/report/report_stream.py +191 -0
- endoreg_db/views/requirement/__init__.py +11 -0
- endoreg_db/views/requirement/evaluate.py +278 -0
- endoreg_db/views/requirement/lookup.py +380 -0
- endoreg_db/views/requirement/lookup_store.py +183 -0
- endoreg_db/views/requirement/requirement_utils.py +87 -0
- endoreg_db/views/requirement_lookup/lookup.py +0 -0
- endoreg_db/views/requirement_lookup/lookup_store.py +0 -0
- endoreg_db/views/stats/__init__.py +13 -0
- endoreg_db/views/stats/stats_views.py +266 -0
- endoreg_db/views/video/__init__.py +49 -0
- endoreg_db/views/video/ai/__init__.py +8 -0
- endoreg_db/views/video/ai/label.py +159 -0
- endoreg_db/views/video/correction.py +529 -0
- endoreg_db/views/video/reimport.py +230 -0
- endoreg_db/views/video/segments_crud.py +709 -0
- endoreg_db/views/video/video_apply_mask.py +49 -0
- endoreg_db/views/video/video_correction.py +22 -0
- endoreg_db/views/video/video_download_processed.py +58 -0
- endoreg_db/views/video/video_examination_viewset.py +242 -0
- endoreg_db/views/video/video_metadata.py +101 -0
- endoreg_db/views/video/video_processing_history.py +25 -0
- endoreg_db/views/video/video_remove_frames.py +49 -0
- endoreg_db/views/video/video_stream.py +334 -0
- endoreg_db-0.8.9.32.dist-info/METADATA +404 -0
- endoreg_db-0.8.9.32.dist-info/RECORD +787 -0
- endoreg_db-0.8.9.32.dist-info/WHEEL +4 -0
- endoreg_db-0.8.9.32.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import shutil
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import TYPE_CHECKING, Dict, List, Optional, Set, Tuple
|
|
5
|
+
|
|
6
|
+
import cv2
|
|
7
|
+
from django.db import transaction
|
|
8
|
+
from tqdm import tqdm
|
|
9
|
+
|
|
10
|
+
from endoreg_db.utils.hashs import get_video_hash
|
|
11
|
+
from endoreg_db.utils.paths import STORAGE_DIR
|
|
12
|
+
from endoreg_db.utils.validate_endo_roi import validate_endo_roi
|
|
13
|
+
|
|
14
|
+
from ....utils.video.ffmpeg_wrapper import assemble_video_from_frames
|
|
15
|
+
from ...utils import anonymize_frame # Import from models.utils
|
|
16
|
+
from .video_file_segments import _get_outside_frame_numbers, _get_outside_frames
|
|
17
|
+
|
|
18
|
+
if TYPE_CHECKING:
|
|
19
|
+
from django.db.models import QuerySet
|
|
20
|
+
|
|
21
|
+
from ..frame import Frame
|
|
22
|
+
from .video_file import VideoFile
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _create_anonymized_frame_files(
|
|
28
|
+
video: "VideoFile",
|
|
29
|
+
anonymized_frame_dir: Path,
|
|
30
|
+
endo_roi: Dict[str, int],
|
|
31
|
+
frames: "QuerySet[Frame]",
|
|
32
|
+
outside_frame_numbers: Set[int],
|
|
33
|
+
censor_color: Tuple[int, int, int] = (0, 0, 0),
|
|
34
|
+
) -> List[Path]:
|
|
35
|
+
"""
|
|
36
|
+
Creates anonymized versions of frames, censoring outside the ROI or using censor_color for 'outside' frames.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
video: The VideoFile instance.
|
|
40
|
+
anonymized_frame_dir: Directory to save anonymized frames.
|
|
41
|
+
endo_roi: The endoscope region of interest dictionary.
|
|
42
|
+
frames: QuerySet of all Frame objects for the video.
|
|
43
|
+
outside_frame_numbers: Set of frame numbers labeled as 'outside'.
|
|
44
|
+
censor_color: BGR color tuple for censoring.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
List of paths to the generated anonymized frame files.
|
|
48
|
+
|
|
49
|
+
Raises:
|
|
50
|
+
RuntimeError: If anonymization fails for any frame.
|
|
51
|
+
"""
|
|
52
|
+
generated_paths = []
|
|
53
|
+
frame_iterator = frames.filter(is_extracted=True).iterator()
|
|
54
|
+
total_frames = frames.filter(is_extracted=True).count()
|
|
55
|
+
progress_bar = tqdm(
|
|
56
|
+
frame_iterator,
|
|
57
|
+
total=total_frames,
|
|
58
|
+
desc=f"Anonymizing frames for {video.video_hash}",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
for frame_obj in progress_bar:
|
|
62
|
+
try:
|
|
63
|
+
_frame_number = frame_obj.frame_number
|
|
64
|
+
target_path = (
|
|
65
|
+
anonymized_frame_dir / f"frame_{frame_obj.frame_number:07d}.jpg"
|
|
66
|
+
)
|
|
67
|
+
make_all_black = frame_obj.frame_number in outside_frame_numbers
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
source_path = frame_obj.file_path
|
|
71
|
+
if not isinstance(source_path, Path):
|
|
72
|
+
raise TypeError(
|
|
73
|
+
f"Frame.file_path did not return a Path object for frame {frame_obj.frame_number}"
|
|
74
|
+
)
|
|
75
|
+
except (AttributeError, TypeError, Exception) as path_err:
|
|
76
|
+
logger.error(
|
|
77
|
+
"Could not determine source path for Frame %d (PK: %s) using frame_obj.file_path: %s",
|
|
78
|
+
frame_obj.frame_number,
|
|
79
|
+
frame_obj.pk,
|
|
80
|
+
path_err,
|
|
81
|
+
)
|
|
82
|
+
raise RuntimeError(
|
|
83
|
+
f"Failed to get source path for frame {frame_obj.frame_number}"
|
|
84
|
+
) from path_err
|
|
85
|
+
|
|
86
|
+
if not source_path.exists():
|
|
87
|
+
error_msg = (
|
|
88
|
+
f"CRITICAL INCONSISTENCY: Source frame file missing for frame {frame_obj.frame_number} "
|
|
89
|
+
f"(PK: {frame_obj.pk}, Path: {source_path}) despite is_extracted=True for video {video.video_hash}. "
|
|
90
|
+
f"Halting anonymization."
|
|
91
|
+
)
|
|
92
|
+
logger.error(error_msg)
|
|
93
|
+
raise FileNotFoundError(error_msg)
|
|
94
|
+
|
|
95
|
+
anonymize_frame(
|
|
96
|
+
raw_frame_path=source_path,
|
|
97
|
+
target_frame_path=target_path,
|
|
98
|
+
endo_roi=endo_roi,
|
|
99
|
+
all_black=make_all_black,
|
|
100
|
+
censor_color=censor_color,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
generated_paths.append(target_path)
|
|
104
|
+
except (
|
|
105
|
+
FileNotFoundError,
|
|
106
|
+
IOError,
|
|
107
|
+
ValueError,
|
|
108
|
+
AttributeError,
|
|
109
|
+
TypeError,
|
|
110
|
+
Exception,
|
|
111
|
+
) as e:
|
|
112
|
+
logger.error(
|
|
113
|
+
"Error anonymizing frame %d (PK: %s): %s",
|
|
114
|
+
frame_obj.frame_number,
|
|
115
|
+
frame_obj.pk,
|
|
116
|
+
e,
|
|
117
|
+
exc_info=True,
|
|
118
|
+
)
|
|
119
|
+
raise RuntimeError(
|
|
120
|
+
f"Failed to anonymize frame {frame_obj.frame_number}"
|
|
121
|
+
) from e
|
|
122
|
+
|
|
123
|
+
if len(generated_paths) != total_frames:
|
|
124
|
+
logger.error(
|
|
125
|
+
"Mismatch in generated frames count. Expected %d, got %d.",
|
|
126
|
+
total_frames,
|
|
127
|
+
len(generated_paths),
|
|
128
|
+
)
|
|
129
|
+
raise RuntimeError(
|
|
130
|
+
"Anonymized frame generation resulted in incorrect number of files."
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
return generated_paths
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _censor_outside_frames(
|
|
137
|
+
video: "VideoFile",
|
|
138
|
+
outside_label_name: str = "outside",
|
|
139
|
+
censor_color: Tuple[int, int, int] = (0, 0, 0),
|
|
140
|
+
) -> bool:
|
|
141
|
+
"""
|
|
142
|
+
Overwrites frame files marked as 'outside' with a censored version (e.g., black).
|
|
143
|
+
This modifies the original raw frames directly. Use with caution. Requires frames to be extracted.
|
|
144
|
+
Raises ValueError if pre-condition not met. Returns True on success, False if any frame fails.
|
|
145
|
+
|
|
146
|
+
State Transitions:
|
|
147
|
+
- Pre-condition: Requires state.frames_extracted=True.
|
|
148
|
+
- Post-condition: No state changes.
|
|
149
|
+
"""
|
|
150
|
+
logger.warning(
|
|
151
|
+
"Starting direct censoring of 'outside' frames for video %s. This modifies raw frame files.",
|
|
152
|
+
video.video_hash,
|
|
153
|
+
)
|
|
154
|
+
state = video.get_or_create_state()
|
|
155
|
+
if not state.frames_extracted:
|
|
156
|
+
raise ValueError(
|
|
157
|
+
f"Frames not extracted for video {video.video_hash}. Cannot censor."
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
outside_frames = _get_outside_frames(video, outside_label_name)
|
|
161
|
+
if not outside_frames:
|
|
162
|
+
logger.info(
|
|
163
|
+
"No 'outside' frames found to censor for video %s.", video.video_hash
|
|
164
|
+
)
|
|
165
|
+
return True
|
|
166
|
+
|
|
167
|
+
censored_count = 0
|
|
168
|
+
error_count = 0
|
|
169
|
+
for frame_obj in outside_frames:
|
|
170
|
+
try:
|
|
171
|
+
frame_path = frame_obj.file_path
|
|
172
|
+
if not frame_path:
|
|
173
|
+
logger.warning(
|
|
174
|
+
"Could not get file path for frame %d. Skipping censoring.",
|
|
175
|
+
frame_obj.frame_number,
|
|
176
|
+
)
|
|
177
|
+
error_count += 1
|
|
178
|
+
continue
|
|
179
|
+
|
|
180
|
+
if not frame_path.exists():
|
|
181
|
+
logger.warning(
|
|
182
|
+
"Frame file %s not found for censoring. Skipping.", frame_path
|
|
183
|
+
)
|
|
184
|
+
continue
|
|
185
|
+
|
|
186
|
+
img = cv2.imread(str(frame_path))
|
|
187
|
+
if img is None:
|
|
188
|
+
logger.warning(
|
|
189
|
+
"Could not read frame %s for censoring. Skipping.", frame_path
|
|
190
|
+
)
|
|
191
|
+
continue
|
|
192
|
+
|
|
193
|
+
img[:] = censor_color
|
|
194
|
+
success = cv2.imwrite(str(frame_path), img)
|
|
195
|
+
if success:
|
|
196
|
+
censored_count += 1
|
|
197
|
+
else:
|
|
198
|
+
logger.error("Failed to write censored frame back to %s.", frame_path)
|
|
199
|
+
error_count += 1
|
|
200
|
+
|
|
201
|
+
except Exception as e:
|
|
202
|
+
logger.error(
|
|
203
|
+
"Error censoring frame %d (%s): %s",
|
|
204
|
+
frame_obj.frame_number,
|
|
205
|
+
getattr(frame_obj, "relative_path", "N/A"),
|
|
206
|
+
e,
|
|
207
|
+
exc_info=True,
|
|
208
|
+
)
|
|
209
|
+
error_count += 1
|
|
210
|
+
|
|
211
|
+
logger.info(
|
|
212
|
+
"Finished censoring for video %s. Censored: %d, Errors: %d",
|
|
213
|
+
video.video_hash,
|
|
214
|
+
censored_count,
|
|
215
|
+
error_count,
|
|
216
|
+
)
|
|
217
|
+
return error_count == 0
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def _make_temporary_anonymized_frames(
|
|
221
|
+
video: "VideoFile", roi_processing=True
|
|
222
|
+
) -> Tuple[Path, List[Path]]:
|
|
223
|
+
"""
|
|
224
|
+
Creates temporary anonymized frames in a separate directory.
|
|
225
|
+
Requires raw file and extracted frames. Raises ValueError or RuntimeError on failure.
|
|
226
|
+
|
|
227
|
+
State Transitions:
|
|
228
|
+
- Pre-condition: Requires state.frames_extracted=True (or triggers extraction).
|
|
229
|
+
- Post-condition: No state changes directly by this function.
|
|
230
|
+
"""
|
|
231
|
+
if video.is_processed:
|
|
232
|
+
raise ValueError(
|
|
233
|
+
f"Cannot create temporary anonymized frames for video {video.video_hash}: already processed."
|
|
234
|
+
)
|
|
235
|
+
if not video.has_raw:
|
|
236
|
+
raise ValueError(
|
|
237
|
+
f"Cannot create temporary anonymized frames for video {video.video_hash}: Raw file is missing."
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
temp_anonym_frame_dir = video.get_temp_anonymized_frame_dir()
|
|
241
|
+
temp_anonym_frame_dir.mkdir(parents=True, exist_ok=True)
|
|
242
|
+
logger.info(
|
|
243
|
+
"Creating temporary anonymized frames for video %s in %s",
|
|
244
|
+
video.video_hash,
|
|
245
|
+
temp_anonym_frame_dir,
|
|
246
|
+
)
|
|
247
|
+
if roi_processing:
|
|
248
|
+
endo_roi = video.get_endo_roi()
|
|
249
|
+
if not validate_endo_roi(endo_roi_dict=endo_roi):
|
|
250
|
+
raise ValueError(f"Endoscope ROI is not valid for video {video.video_hash}")
|
|
251
|
+
else:
|
|
252
|
+
endo_roi = {
|
|
253
|
+
"x": 0,
|
|
254
|
+
"y": 0,
|
|
255
|
+
"width": 0,
|
|
256
|
+
"height": 0,
|
|
257
|
+
} # Dummy ROI to skip processing
|
|
258
|
+
assert endo_roi is not None # For type checker
|
|
259
|
+
|
|
260
|
+
state = video.get_or_create_state()
|
|
261
|
+
if not state.frames_extracted:
|
|
262
|
+
logger.info(
|
|
263
|
+
"Raw frames not extracted for %s, extracting now.", video.video_hash
|
|
264
|
+
)
|
|
265
|
+
try:
|
|
266
|
+
if not video.extract_frames(overwrite=False):
|
|
267
|
+
raise RuntimeError(
|
|
268
|
+
f"Frame extraction method returned False unexpectedly for video {video.video_hash}."
|
|
269
|
+
)
|
|
270
|
+
state.refresh_from_db()
|
|
271
|
+
if not state.frames_extracted:
|
|
272
|
+
raise RuntimeError(
|
|
273
|
+
f"Frame extraction did not update state for video {video.video_hash}, cannot create anonymized frames."
|
|
274
|
+
)
|
|
275
|
+
except Exception as extract_e:
|
|
276
|
+
logger.error(
|
|
277
|
+
"Frame extraction failed during anonymization prep for video %s: %s",
|
|
278
|
+
video.video_hash,
|
|
279
|
+
extract_e,
|
|
280
|
+
exc_info=True,
|
|
281
|
+
)
|
|
282
|
+
raise RuntimeError(
|
|
283
|
+
f"Frame extraction failed for video {video.video_hash}, cannot create anonymized frames."
|
|
284
|
+
) from extract_e
|
|
285
|
+
|
|
286
|
+
all_frames = video.get_frames()
|
|
287
|
+
if not all_frames.exists():
|
|
288
|
+
raise FileNotFoundError(
|
|
289
|
+
f"No frame objects found for video {video.video_hash} after extraction attempt."
|
|
290
|
+
)
|
|
291
|
+
|
|
292
|
+
outside_frame_numbers = _get_outside_frame_numbers(video)
|
|
293
|
+
|
|
294
|
+
logger.info(
|
|
295
|
+
"Generating %d temporary anonymized frame files for video %s...",
|
|
296
|
+
all_frames.filter(is_extracted=True).count(),
|
|
297
|
+
video.video_hash,
|
|
298
|
+
)
|
|
299
|
+
generated_frame_paths = _create_anonymized_frame_files(
|
|
300
|
+
video=video,
|
|
301
|
+
anonymized_frame_dir=temp_anonym_frame_dir,
|
|
302
|
+
endo_roi=endo_roi,
|
|
303
|
+
frames=all_frames,
|
|
304
|
+
outside_frame_numbers=outside_frame_numbers,
|
|
305
|
+
)
|
|
306
|
+
logger.info(
|
|
307
|
+
"Generated %d temporary anonymized frame files for video %s.",
|
|
308
|
+
len(generated_frame_paths),
|
|
309
|
+
video.video_hash,
|
|
310
|
+
)
|
|
311
|
+
return temp_anonym_frame_dir, generated_frame_paths
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@transaction.atomic
|
|
315
|
+
def _anonymize(video: "VideoFile", delete_original_raw: bool = True) -> bool:
|
|
316
|
+
"""
|
|
317
|
+
Performs full anonymization of a video by censoring frames, assembling a processed video file, updating database records, and optionally deleting original raw assets.
|
|
318
|
+
|
|
319
|
+
Raises:
|
|
320
|
+
ValueError: If required preconditions are not met (e.g., frames not extracted, sensitive metadata not validated).
|
|
321
|
+
FileNotFoundError: If the raw video file is missing.
|
|
322
|
+
RuntimeError: If anonymization or video assembly fails.
|
|
323
|
+
|
|
324
|
+
Returns:
|
|
325
|
+
bool: True if anonymization completes successfully.
|
|
326
|
+
"""
|
|
327
|
+
state = video.get_or_create_state()
|
|
328
|
+
|
|
329
|
+
if state.anonymized:
|
|
330
|
+
logger.info(
|
|
331
|
+
"Video %s is already marked as anonymized in state. Skipping.",
|
|
332
|
+
video.video_hash,
|
|
333
|
+
)
|
|
334
|
+
return True
|
|
335
|
+
if not video.has_raw:
|
|
336
|
+
raise FileNotFoundError(
|
|
337
|
+
f"Raw file is missing for video {video.video_hash}, cannot anonymize."
|
|
338
|
+
)
|
|
339
|
+
if not state.frames_extracted:
|
|
340
|
+
raise ValueError(
|
|
341
|
+
f"Frames not extracted for video {video.video_hash}, cannot anonymize."
|
|
342
|
+
)
|
|
343
|
+
if not video.sensitive_meta or not video.sensitive_meta.is_verified:
|
|
344
|
+
raise ValueError(
|
|
345
|
+
f"Sensitive metadata for video {video.video_hash} is not validated. Cannot anonymize."
|
|
346
|
+
)
|
|
347
|
+
# outside_segments = video.get_outside_segments(only_validated=False)
|
|
348
|
+
# unvalidated_outside = outside_segments.filter(state__is_validated=False)
|
|
349
|
+
|
|
350
|
+
logger.info("Starting anonymization process for video %s", video.video_hash)
|
|
351
|
+
|
|
352
|
+
temp_anonym_frame_dir = None
|
|
353
|
+
anonymized_video_path = None
|
|
354
|
+
try:
|
|
355
|
+
temp_anonym_frame_dir, generated_frame_paths = (
|
|
356
|
+
_make_temporary_anonymized_frames(video)
|
|
357
|
+
)
|
|
358
|
+
if not generated_frame_paths:
|
|
359
|
+
raise RuntimeError(
|
|
360
|
+
f"Failed to generate temporary anonymized frames for video {video.video_hash}."
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
anonymized_video_path = video.get_target_anonymized_video_path()
|
|
364
|
+
anonymized_video_path.parent.mkdir(parents=True, exist_ok=True)
|
|
365
|
+
|
|
366
|
+
anonymized_video_path.unlink(missing_ok=True)
|
|
367
|
+
|
|
368
|
+
fps = video.get_fps()
|
|
369
|
+
if fps is None:
|
|
370
|
+
raise ValueError(
|
|
371
|
+
f"FPS could not be determined for {video.video_hash}, cannot assemble video."
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
logger.info(
|
|
375
|
+
"Assembling anonymized video for %s at %s",
|
|
376
|
+
video.video_hash,
|
|
377
|
+
anonymized_video_path,
|
|
378
|
+
)
|
|
379
|
+
assemble_video_from_frames(
|
|
380
|
+
frame_paths=generated_frame_paths,
|
|
381
|
+
output_path=anonymized_video_path,
|
|
382
|
+
fps=fps,
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
if not anonymized_video_path.exists():
|
|
386
|
+
raise RuntimeError(
|
|
387
|
+
f"Processed video file not found after assembly for {video.video_hash}: {anonymized_video_path}"
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
new_processed_hash = get_video_hash(anonymized_video_path)
|
|
391
|
+
if (
|
|
392
|
+
type(video)
|
|
393
|
+
.objects.filter(processed_video_hash=new_processed_hash)
|
|
394
|
+
.exclude(pk=video.pk)
|
|
395
|
+
.exists()
|
|
396
|
+
):
|
|
397
|
+
raise ValueError(
|
|
398
|
+
f"Processed video hash {new_processed_hash} already exists for another video (Video: {video.video_hash})."
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
video.processed_video_hash = new_processed_hash
|
|
402
|
+
video.processed_file.name = (
|
|
403
|
+
video.get_target_anonymized_video_path().relative_to(STORAGE_DIR).as_posix()
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
update_fields = [
|
|
407
|
+
"processed_video_hash",
|
|
408
|
+
"processed_file",
|
|
409
|
+
"frame_dir",
|
|
410
|
+
]
|
|
411
|
+
|
|
412
|
+
if delete_original_raw:
|
|
413
|
+
original_raw_file_path_to_delete = video.get_raw_file_path()
|
|
414
|
+
original_raw_frame_dir_to_delete = video.get_frame_dir_path()
|
|
415
|
+
|
|
416
|
+
video.raw_file.name = ""
|
|
417
|
+
|
|
418
|
+
update_fields.extend(["raw_file", "video_hash"])
|
|
419
|
+
|
|
420
|
+
transaction.on_commit(
|
|
421
|
+
lambda: _cleanup_raw_assets(
|
|
422
|
+
video_hash=video.video_hash,
|
|
423
|
+
raw_file_path=original_raw_file_path_to_delete,
|
|
424
|
+
raw_frame_dir=original_raw_frame_dir_to_delete,
|
|
425
|
+
)
|
|
426
|
+
)
|
|
427
|
+
|
|
428
|
+
video.save(update_fields=update_fields)
|
|
429
|
+
assert video.state is not None # For type checker
|
|
430
|
+
video.state.mark_anonymized(save=True)
|
|
431
|
+
video.refresh_from_db()
|
|
432
|
+
return True
|
|
433
|
+
|
|
434
|
+
except Exception as e:
|
|
435
|
+
logger.error(
|
|
436
|
+
"Anonymization failed for video %s: %s", video.video_hash, e, exc_info=True
|
|
437
|
+
)
|
|
438
|
+
if anonymized_video_path and anonymized_video_path.exists():
|
|
439
|
+
logger.warning(
|
|
440
|
+
"Cleaning up potentially orphaned processed file for video %s due to error: %s",
|
|
441
|
+
video.video_hash,
|
|
442
|
+
anonymized_video_path,
|
|
443
|
+
)
|
|
444
|
+
anonymized_video_path.unlink(missing_ok=True)
|
|
445
|
+
raise RuntimeError(f"Anonymization failed for video {video.video_hash}") from e
|
|
446
|
+
|
|
447
|
+
finally:
|
|
448
|
+
if temp_anonym_frame_dir and temp_anonym_frame_dir.exists():
|
|
449
|
+
logger.info(
|
|
450
|
+
"Cleaning up temporary anonymized frame directory for video %s: %s",
|
|
451
|
+
video.video_hash,
|
|
452
|
+
temp_anonym_frame_dir,
|
|
453
|
+
)
|
|
454
|
+
shutil.rmtree(temp_anonym_frame_dir)
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
def _cleanup_raw_assets(
|
|
458
|
+
video_hash: "str",
|
|
459
|
+
raw_file_path: Optional[Path] = None,
|
|
460
|
+
raw_frame_dir: Optional[Path] = None,
|
|
461
|
+
):
|
|
462
|
+
"""
|
|
463
|
+
Deletes the original raw video file and its extracted frames directory.
|
|
464
|
+
Called via transaction.on_commit after successful anonymization.
|
|
465
|
+
|
|
466
|
+
State Transitions:
|
|
467
|
+
- Sets state.frames_extracted=False.
|
|
468
|
+
"""
|
|
469
|
+
from endoreg_db.models import VideoFile, VideoState
|
|
470
|
+
|
|
471
|
+
logger.info(
|
|
472
|
+
"Performing post-commit cleanup of raw assets for video %s.", video_hash
|
|
473
|
+
)
|
|
474
|
+
try:
|
|
475
|
+
video_file = (
|
|
476
|
+
VideoFile.objects.select_related("state")
|
|
477
|
+
.filter(content_hash=video_hash)
|
|
478
|
+
.first()
|
|
479
|
+
)
|
|
480
|
+
if not video_file:
|
|
481
|
+
logger.error(
|
|
482
|
+
"VideoFile %s not found during post-commit cleanup.", video_hash
|
|
483
|
+
)
|
|
484
|
+
return
|
|
485
|
+
if not video_file.state:
|
|
486
|
+
logger.error(
|
|
487
|
+
"VideoState not found for VideoFile %s during post-commit cleanup.",
|
|
488
|
+
video_hash,
|
|
489
|
+
)
|
|
490
|
+
video_file.state = VideoState.objects.create(video_file=video_file)
|
|
491
|
+
|
|
492
|
+
if raw_file_path and raw_file_path.exists():
|
|
493
|
+
logger.info("Deleting original raw video file: %s", raw_file_path)
|
|
494
|
+
raw_file_path.unlink()
|
|
495
|
+
elif raw_file_path:
|
|
496
|
+
logger.warning(
|
|
497
|
+
"Original raw video file %s not found for post-commit deletion.",
|
|
498
|
+
raw_file_path,
|
|
499
|
+
)
|
|
500
|
+
|
|
501
|
+
if raw_frame_dir and raw_frame_dir.exists():
|
|
502
|
+
logger.info("Deleting original raw frame directory: %s", raw_frame_dir)
|
|
503
|
+
shutil.rmtree(raw_frame_dir, ignore_errors=True)
|
|
504
|
+
elif raw_frame_dir:
|
|
505
|
+
logger.warning(
|
|
506
|
+
"Original raw frame directory %s not found for post-commit deletion.",
|
|
507
|
+
raw_frame_dir,
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
if video_file.state.frames_extracted:
|
|
511
|
+
video_file.state.frames_extracted = False
|
|
512
|
+
video_file.state.save(update_fields=["frames_extracted"])
|
|
513
|
+
logger.info(
|
|
514
|
+
"Set state.frames_extracted=False for video %s after raw asset cleanup.",
|
|
515
|
+
video_hash,
|
|
516
|
+
)
|
|
517
|
+
|
|
518
|
+
except Exception as e:
|
|
519
|
+
logger.error(
|
|
520
|
+
"Error during post-commit cleanup of raw assets for video %s: %s",
|
|
521
|
+
video_hash,
|
|
522
|
+
e,
|
|
523
|
+
exc_info=True,
|
|
524
|
+
)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module: Video Frame Operations
|
|
3
|
+
|
|
4
|
+
This module aggregates various functionalities related to video frame management within the endoreg database system. It provides a unified interface to handle operations such as frame extraction, creation, deletion, and range management for video files.
|
|
5
|
+
|
|
6
|
+
Submodules:
|
|
7
|
+
_bulk_create_frames : Handles bulk creation of frame entries.
|
|
8
|
+
_create_frame_object : Constructs a frame object from frame data.
|
|
9
|
+
_delete_frames : Performs deletion of frame records.
|
|
10
|
+
_extract_frames : Extracts frames from video content.
|
|
11
|
+
_get_frame_number : Retrieves the frame number for a specific frame.
|
|
12
|
+
_get_frame_path : Constructs the filesystem path for a frame.
|
|
13
|
+
_get_frame_paths : Retrieves paths for multiple frames.
|
|
14
|
+
_get_frame_range : Determines the range of frame indices in a video.
|
|
15
|
+
_get_frame : Obtains details for a single frame.
|
|
16
|
+
_get_frames : Aggregates multiple frame details.
|
|
17
|
+
_initialize_frames : Initializes frame data for processing.
|
|
18
|
+
|
|
19
|
+
Usage:
|
|
20
|
+
Import the required functions directly from this module to perform specific video frame operations.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from ._bulk_create_frames import _bulk_create_frames
|
|
24
|
+
from ._create_frame_object import _create_frame_object
|
|
25
|
+
from ._delete_frames import _delete_frames
|
|
26
|
+
from ._extract_frames import _extract_frames
|
|
27
|
+
from ._get_frame import _get_frame
|
|
28
|
+
from ._get_frame_number import _get_frame_number
|
|
29
|
+
from ._get_frame_path import _get_frame_path
|
|
30
|
+
from ._get_frame_paths import _get_frame_paths
|
|
31
|
+
from ._get_frame_range import _get_frame_range
|
|
32
|
+
from ._get_frames import _get_frames
|
|
33
|
+
from ._initialize_frames import _initialize_frames
|
|
34
|
+
from ._mark_frames_extracted_status import _mark_frames_extracted_status
|
|
35
|
+
|
|
36
|
+
__all__ = [
|
|
37
|
+
"_bulk_create_frames",
|
|
38
|
+
"_create_frame_object",
|
|
39
|
+
"_delete_frames",
|
|
40
|
+
"_extract_frames",
|
|
41
|
+
"_get_frame_number",
|
|
42
|
+
"_get_frame_path",
|
|
43
|
+
"_get_frame_paths",
|
|
44
|
+
"_get_frame_range",
|
|
45
|
+
"_get_frame",
|
|
46
|
+
"_get_frames",
|
|
47
|
+
"_initialize_frames",
|
|
48
|
+
"_mark_frames_extracted_status",
|
|
49
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import TYPE_CHECKING, List
|
|
3
|
+
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from endoreg_db.models import Frame, VideoFile
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
__all__ = ["_bulk_create_frames"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _bulk_create_frames(video: "VideoFile", frames_to_create: List["Frame"]):
|
|
13
|
+
"""Helper function to perform bulk_create with ignore_conflicts."""
|
|
14
|
+
from endoreg_db.models import Frame
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
Frame.objects.bulk_create(frames_to_create, ignore_conflicts=True)
|
|
18
|
+
except Exception as e:
|
|
19
|
+
logger.error(
|
|
20
|
+
"Error during bulk creation of frames for video %s: %s",
|
|
21
|
+
video.video_hash,
|
|
22
|
+
e,
|
|
23
|
+
exc_info=True,
|
|
24
|
+
)
|
|
25
|
+
raise
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from endoreg_db.models import Frame, VideoFile
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
__all__ = ["_create_frame_object"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _create_frame_object(
|
|
13
|
+
video: "VideoFile", frame_number: int, relative_path: str, extracted: bool = False
|
|
14
|
+
) -> "Frame":
|
|
15
|
+
"""Instantiates a Frame object (does not save it)."""
|
|
16
|
+
from endoreg_db.models import Frame
|
|
17
|
+
|
|
18
|
+
return Frame(
|
|
19
|
+
video=video,
|
|
20
|
+
frame_number=frame_number,
|
|
21
|
+
relative_path=relative_path,
|
|
22
|
+
is_extracted=extracted,
|
|
23
|
+
)
|