endoreg-db 0.3.6__py3-none-any.whl → 0.8.6.1__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/admin.py +92 -3
- endoreg_db/api_urls.py +4 -0
- endoreg_db/apps.py +18 -6
- endoreg_db/assets/dummy_model.ckpt +1 -0
- endoreg_db/codemods/readme.md +88 -0
- endoreg_db/codemods/rename_datetime_fields.py +92 -0
- endoreg_db/config/env.py +101 -0
- endoreg_db/data/__init__.py +144 -65
- endoreg_db/data/ai_model/data.yaml +7 -0
- endoreg_db/data/{label → ai_model_label}/label/data.yaml +88 -62
- 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/{label → ai_model_label}/label-type/data.yaml +6 -6
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +27 -0
- endoreg_db/data/{model_type → ai_model_type}/data.yaml +6 -6
- 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 -167
- endoreg_db/data/case_template/rule/01_patient-set-age.yaml +7 -7
- endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +8 -8
- endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +22 -22
- endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +18 -18
- endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +18 -18
- endoreg_db/data/case_template/rule/19_create_patient.yaml +16 -16
- endoreg_db/data/case_template/rule_type/base_types.yaml +35 -35
- endoreg_db/data/case_template/rule_value_type/base_types.yaml +58 -58
- endoreg_db/data/case_template/template/base.yaml +7 -7
- endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +2 -2
- endoreg_db/data/case_template/tmp/_rule_value +13 -13
- endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -21
- endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +9 -9
- endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +6 -6
- endoreg_db/data/center/data.yaml +90 -59
- endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -144
- endoreg_db/data/center_shift/ukw.yaml +9 -0
- endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -48
- 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 -37
- endoreg_db/data/disease/hepatology.yaml +4 -4
- endoreg_db/data/disease/misc.yaml +5 -6
- endoreg_db/data/disease/renal.yaml +4 -4
- endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +6 -6
- endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +5 -5
- endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +41 -41
- endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +19 -19
- endoreg_db/data/distribution/date/patient.yaml +6 -6
- endoreg_db/data/distribution/numeric/data.yaml +14 -0
- endoreg_db/data/distribution/single_categorical/patient.yaml +6 -6
- endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -132
- endoreg_db/data/endoscope/data.yaml +93 -0
- endoreg_db/data/endoscope_type/data.yaml +10 -10
- endoreg_db/data/endoscopy_processor/data.yaml +50 -45
- endoreg_db/data/event/cardiology.yaml +15 -28
- endoreg_db/data/event/neurology.yaml +13 -13
- endoreg_db/data/event/surgery.yaml +12 -12
- endoreg_db/data/event/thrombembolism.yaml +19 -19
- endoreg_db/data/examination/examinations/data.yaml +72 -66
- endoreg_db/data/examination/time/data.yaml +47 -47
- endoreg_db/data/examination/time-type/data.yaml +7 -7
- endoreg_db/data/examination/type/data.yaml +17 -5
- endoreg_db/data/examination_indication/endoscopy.yaml +424 -0
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +160 -0
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +101 -0
- endoreg_db/data/examination_requirement_set/colonoscopy.yaml +15 -0
- endoreg_db/data/finding/anatomy_colon.yaml +128 -0
- endoreg_db/data/finding/colonoscopy.yaml +40 -0
- endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +56 -0
- endoreg_db/data/finding/complication.yaml +16 -0
- endoreg_db/data/finding/data.yaml +105 -0
- endoreg_db/data/finding/examination_setting.yaml +16 -0
- endoreg_db/data/finding/medication_related.yaml +18 -0
- endoreg_db/data/finding/outcome.yaml +12 -0
- endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +95 -0
- endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +22 -0
- endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +25 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +68 -0
- endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +80 -0
- endoreg_db/data/finding_classification/colonoscopy_lst.yaml +21 -0
- endoreg_db/data/finding_classification/colonoscopy_nice.yaml +20 -0
- endoreg_db/data/finding_classification/colonoscopy_paris.yaml +26 -0
- endoreg_db/data/finding_classification/colonoscopy_sano.yaml +22 -0
- endoreg_db/data/finding_classification/colonoscopy_summary.yaml +53 -0
- endoreg_db/data/finding_classification/complication_generic.yaml +25 -0
- endoreg_db/data/finding_classification/examination_setting_generic.yaml +40 -0
- endoreg_db/data/finding_classification/histology_colo.yaml +51 -0
- endoreg_db/data/finding_classification/intervention_required.yaml +26 -0
- endoreg_db/data/finding_classification/medication_related.yaml +23 -0
- endoreg_db/data/finding_classification/visualized.yaml +33 -0
- endoreg_db/data/finding_classification_choice/bowel_preparation.yaml +78 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +32 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +15 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +17 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_paris.yaml +57 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +49 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +14 -0
- endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +36 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_location.yaml +229 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +82 -0
- endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
- endoreg_db/data/finding_classification_choice/complication_generic_types.yaml +15 -0
- endoreg_db/data/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
- endoreg_db/data/finding_classification_choice/histology.yaml +24 -0
- endoreg_db/data/finding_classification_choice/histology_polyp.yaml +20 -0
- endoreg_db/data/finding_classification_choice/outcome.yaml +19 -0
- endoreg_db/data/finding_classification_choice/yes_no_na.yaml +11 -0
- endoreg_db/data/finding_classification_type/colonoscopy_basic.yaml +48 -0
- endoreg_db/data/finding_intervention/endoscopy.yaml +43 -0
- endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +168 -0
- endoreg_db/data/finding_intervention/endoscopy_egd.yaml +128 -0
- endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +32 -0
- endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +9 -0
- endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +36 -0
- endoreg_db/data/finding_intervention_type/endoscopy.yaml +15 -0
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +79 -0
- endoreg_db/data/finding_type/data.yaml +43 -0
- endoreg_db/data/gender/data.yaml +42 -18
- endoreg_db/data/information_source/annotation.yaml +6 -0
- endoreg_db/data/information_source/data.yaml +30 -30
- endoreg_db/data/information_source/endoscopy_guidelines.yaml +7 -0
- endoreg_db/data/information_source/medication.yaml +5 -5
- 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 -31
- endoreg_db/data/lab_value/coagulation.yaml +54 -49
- endoreg_db/data/lab_value/electrolytes.yaml +228 -190
- endoreg_db/data/lab_value/gastrointestinal_function.yaml +133 -121
- endoreg_db/data/lab_value/hematology.yaml +184 -169
- endoreg_db/data/lab_value/hormones.yaml +59 -53
- endoreg_db/data/lab_value/lipids.yaml +53 -44
- endoreg_db/data/lab_value/misc.yaml +76 -30
- endoreg_db/data/lab_value/renal_function.yaml +12 -11
- 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/medication/anticoagulation.yaml +64 -64
- endoreg_db/data/medication/tah.yaml +69 -69
- endoreg_db/data/medication_indication/anticoagulation.yaml +115 -120
- endoreg_db/data/medication_indication_type/data.yaml +10 -10
- endoreg_db/data/medication_indication_type/thrombembolism.yaml +40 -40
- endoreg_db/data/medication_intake_time/base.yaml +30 -30
- endoreg_db/data/medication_schedule/apixaban.yaml +94 -94
- endoreg_db/data/medication_schedule/ass.yaml +12 -12
- endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -26
- 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 +5 -5
- endoreg_db/data/pdf_type/data.yaml +46 -28
- endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -66
- endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -33
- endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -308
- endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -88
- endoreg_db/data/profession/data.yaml +70 -70
- 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 -55
- endoreg_db/data/report_reader_flag/rkh-histology-generic.yaml +10 -0
- endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +30 -26
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +24 -19
- endoreg_db/data/requirement/age.yaml +26 -0
- endoreg_db/data/requirement/colonoscopy_baseline_austria.yaml +45 -0
- endoreg_db/data/requirement/disease_cardiovascular.yaml +79 -0
- endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +41 -0
- endoreg_db/data/requirement/disease_hepatology.yaml +12 -0
- endoreg_db/data/requirement/disease_misc.yaml +12 -0
- endoreg_db/data/requirement/disease_renal.yaml +96 -0
- endoreg_db/data/requirement/endoscopy_bleeding_risk.yaml +59 -0
- endoreg_db/data/requirement/event_cardiology.yaml +251 -0
- endoreg_db/data/requirement/event_requirements.yaml +145 -0
- endoreg_db/data/requirement/finding_colon_polyp.yaml +50 -0
- endoreg_db/data/requirement/gender.yaml +25 -0
- endoreg_db/data/requirement/lab_value.yaml +441 -0
- endoreg_db/data/requirement/medication.yaml +93 -0
- endoreg_db/data/requirement_operator/age.yaml +13 -0
- endoreg_db/data/requirement_operator/lab_operators.yaml +129 -0
- endoreg_db/data/requirement_operator/model_operators.yaml +96 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +48 -0
- endoreg_db/data/requirement_set/colonoscopy_austria_screening.yaml +57 -0
- endoreg_db/data/requirement_set/endoscopy_bleeding_risk.yaml +52 -0
- endoreg_db/data/requirement_set_type/data.yaml +20 -0
- endoreg_db/data/requirement_type/requirement_types.yaml +165 -0
- endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -15
- 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 +11 -0
- endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -12
- endoreg_db/data/unit/concentration.yaml +115 -92
- endoreg_db/data/unit/data.yaml +17 -17
- endoreg_db/data/unit/length.yaml +30 -30
- endoreg_db/data/unit/misc.yaml +19 -19
- endoreg_db/data/unit/rate.yaml +5 -5
- endoreg_db/data/unit/time.yaml +48 -13
- endoreg_db/data/unit/volume.yaml +35 -35
- endoreg_db/data/unit/weight.yaml +37 -37
- endoreg_db/data/waste/data.yaml +11 -11
- endoreg_db/exceptions.py +19 -0
- endoreg_db/factories/__init__.py +0 -0
- endoreg_db/forms/__init__.py +5 -3
- endoreg_db/forms/examination_form.py +11 -0
- endoreg_db/forms/patient_finding_intervention_form.py +18 -0
- endoreg_db/forms/patient_form.py +27 -0
- endoreg_db/forms/questionnaires/__init__.py +1 -1
- endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -23
- endoreg_db/forms/settings/__init__.py +8 -8
- endoreg_db/forms/unit.py +5 -5
- endoreg_db/helpers/__init__.py +0 -0
- endoreg_db/helpers/count_db.py +45 -0
- endoreg_db/helpers/data_loader.py +208 -0
- endoreg_db/helpers/default_objects.py +378 -0
- endoreg_db/helpers/download_segmentation_model.py +31 -0
- endoreg_db/helpers/interact.py +6 -0
- endoreg_db/helpers/test_video_helper.py +119 -0
- endoreg_db/logger_conf.py +140 -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 +125 -0
- endoreg_db/management/commands/create_model_meta_from_huggingface.py +115 -0
- endoreg_db/management/commands/create_multilabel_model_meta.py +214 -0
- endoreg_db/management/commands/fix_missing_patient_data.py +172 -0
- endoreg_db/management/commands/fix_video_paths.py +165 -0
- endoreg_db/management/commands/import_fallback_video.py +203 -0
- endoreg_db/management/commands/import_report.py +298 -0
- endoreg_db/management/commands/import_video.py +423 -0
- endoreg_db/management/commands/import_video_with_classification.py +367 -0
- endoreg_db/management/commands/init_default_ai_model.py +112 -0
- endoreg_db/management/commands/load_ai_model_data.py +77 -45
- endoreg_db/management/commands/load_ai_model_label_data.py +59 -0
- endoreg_db/management/commands/load_base_db_data.py +192 -128
- endoreg_db/management/commands/load_center_data.py +68 -43
- endoreg_db/management/commands/{load_medication_intake_time_data.py → load_contraindication_data.py} +40 -40
- endoreg_db/management/commands/load_disease_classification_choices_data.py +40 -40
- endoreg_db/management/commands/load_disease_classification_data.py +40 -40
- endoreg_db/management/commands/load_disease_data.py +61 -39
- endoreg_db/management/commands/load_distribution_data.py +65 -65
- endoreg_db/management/commands/{load_endoscope_type_data.py → load_endoscope_data.py} +67 -44
- endoreg_db/management/commands/load_event_data.py +40 -40
- endoreg_db/management/commands/load_examination_data.py +74 -74
- endoreg_db/management/commands/load_examination_indication_data.py +86 -0
- endoreg_db/management/commands/load_finding_data.py +128 -0
- endoreg_db/management/commands/load_gender_data.py +43 -43
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +131 -132
- endoreg_db/management/commands/load_information_source.py +50 -44
- endoreg_db/management/commands/load_lab_value_data.py +49 -49
- endoreg_db/management/commands/load_medication_data.py +103 -41
- endoreg_db/management/commands/load_name_data.py +37 -0
- endoreg_db/management/commands/{load_medication_indication_type_data.py → load_organ_data.py} +42 -40
- endoreg_db/management/commands/load_pdf_type_data.py +60 -60
- endoreg_db/management/commands/load_profession_data.py +43 -43
- endoreg_db/management/commands/load_qualification_data.py +59 -0
- endoreg_db/management/commands/{load_report_reader_flag.py → load_report_reader_flag_data.py} +45 -45
- endoreg_db/management/commands/load_requirement_data.py +180 -0
- endoreg_db/management/commands/load_risk_data.py +56 -0
- endoreg_db/management/commands/load_shift_data.py +60 -0
- endoreg_db/management/commands/load_tag_data.py +57 -0
- endoreg_db/management/commands/load_unit_data.py +45 -45
- endoreg_db/management/commands/load_user_groups.py +28 -28
- endoreg_db/management/commands/register_ai_model.py +64 -65
- endoreg_db/management/commands/reset_celery_schedule.py +9 -9
- endoreg_db/management/commands/setup_endoreg_db.py +381 -0
- endoreg_db/management/commands/start_filewatcher.py +106 -0
- endoreg_db/management/commands/storage_management.py +548 -0
- endoreg_db/management/commands/summarize_db_content.py +189 -0
- endoreg_db/management/commands/validate_video.py +204 -0
- endoreg_db/management/commands/validate_video_files.py +161 -0
- endoreg_db/management/commands/video_validation.py +22 -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 +1857 -582
- endoreg_db/migrations/0002_add_video_correction_models.py +52 -0
- endoreg_db/migrations/0003_add_center_display_name.py +30 -0
- endoreg_db/models/__init__.py +359 -74
- endoreg_db/models/administration/__init__.py +116 -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 +156 -0
- endoreg_db/models/{ai_model → administration/ai}/model_type.py +41 -26
- endoreg_db/models/administration/case/__init__.py +19 -0
- endoreg_db/models/administration/case/case.py +114 -0
- endoreg_db/models/{case_template → administration/case/case_template}/__init__.py +15 -6
- endoreg_db/models/{case_template → administration/case/case_template}/case_template.py +125 -81
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule.py +269 -276
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule_value.py +86 -73
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_type.py +26 -28
- endoreg_db/models/{center → administration/center}/__init__.py +13 -4
- endoreg_db/models/administration/center/center.py +67 -0
- endoreg_db/models/administration/center/center_product.py +64 -0
- endoreg_db/models/administration/center/center_resource.py +49 -0
- endoreg_db/models/administration/center/center_shift.py +88 -0
- endoreg_db/models/administration/center/center_waste.py +30 -0
- endoreg_db/models/administration/permissions/__init__.py +44 -0
- endoreg_db/models/administration/person/__init__.py +24 -0
- endoreg_db/models/administration/person/employee/__init__.py +3 -0
- endoreg_db/models/administration/person/employee/employee.py +35 -0
- endoreg_db/models/administration/person/employee/employee_qualification.py +39 -0
- endoreg_db/models/administration/person/employee/employee_type.py +42 -0
- endoreg_db/models/administration/person/examiner/__init__.py +4 -0
- endoreg_db/models/administration/person/examiner/examiner.py +54 -0
- endoreg_db/models/administration/person/names/__init__.py +0 -0
- endoreg_db/models/{persons → administration/person/names}/first_name.py +18 -18
- endoreg_db/models/{persons → administration/person/names}/last_name.py +18 -19
- endoreg_db/models/administration/person/patient/__init__.py +5 -0
- endoreg_db/models/administration/person/patient/patient.py +460 -0
- endoreg_db/models/{persons → administration/person}/person.py +31 -31
- endoreg_db/models/administration/person/profession/__init__.py +24 -0
- endoreg_db/models/administration/person/user/__init__.py +5 -0
- endoreg_db/models/administration/person/user/portal_user_information.py +37 -0
- endoreg_db/models/administration/product/__init__.py +14 -0
- endoreg_db/models/administration/product/product.py +97 -0
- endoreg_db/models/administration/product/product_group.py +39 -0
- endoreg_db/models/administration/product/product_material.py +54 -0
- endoreg_db/models/{product → administration/product}/product_weight.py +47 -26
- endoreg_db/models/{product → administration/product}/reference_product.py +130 -99
- endoreg_db/models/administration/qualification/__init__.py +7 -0
- endoreg_db/models/administration/qualification/qualification.py +37 -0
- endoreg_db/models/administration/qualification/qualification_type.py +35 -0
- endoreg_db/models/administration/shift/__init__.py +9 -0
- endoreg_db/models/administration/shift/scheduled_days.py +69 -0
- endoreg_db/models/administration/shift/shift.py +51 -0
- endoreg_db/models/administration/shift/shift_type.py +108 -0
- endoreg_db/models/label/__init__.py +24 -1
- endoreg_db/models/label/annotation/__init__.py +12 -0
- endoreg_db/models/label/annotation/image_classification.py +84 -0
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +66 -0
- endoreg_db/models/label/label.py +83 -84
- endoreg_db/models/label/label_set.py +53 -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 +41 -0
- endoreg_db/models/label/label_video_segment/label_video_segment.py +511 -0
- endoreg_db/models/label/video_segmentation_label.py +31 -0
- endoreg_db/models/label/video_segmentation_labelset.py +27 -0
- endoreg_db/models/media/__init__.py +16 -0
- endoreg_db/models/media/frame/__init__.py +3 -0
- endoreg_db/models/media/frame/frame.py +111 -0
- endoreg_db/models/media/pdf/__init__.py +11 -0
- endoreg_db/models/media/pdf/raw_pdf.py +757 -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 +77 -0
- endoreg_db/models/{report_reader → media/pdf/report_reader}/report_reader_flag.py +19 -19
- endoreg_db/models/media/video/__init__.py +8 -0
- endoreg_db/models/media/video/create_from_file.py +358 -0
- endoreg_db/models/media/video/pipe_1.py +213 -0
- endoreg_db/models/media/video/pipe_2.py +105 -0
- endoreg_db/models/media/video/refactor_plan.md +0 -0
- endoreg_db/models/media/video/video_file.py +825 -0
- endoreg_db/models/media/video/video_file_ai.py +443 -0
- endoreg_db/models/media/video/video_file_anonymize.py +349 -0
- endoreg_db/models/media/video/video_file_frames/__init__.py +47 -0
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +22 -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 +104 -0
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +174 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +28 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +20 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +34 -0
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +27 -0
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +129 -0
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +141 -0
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +65 -0
- endoreg_db/models/media/video/video_file_frames.py +0 -0
- endoreg_db/models/media/video/video_file_io.py +168 -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 +45 -0
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +39 -0
- endoreg_db/models/media/video/video_file_meta/get_fps.py +147 -0
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +143 -0
- endoreg_db/models/media/video/video_file_meta/text_meta.py +134 -0
- endoreg_db/models/media/video/video_file_meta/video_meta.py +70 -0
- endoreg_db/models/media/video/video_file_segments.py +209 -0
- endoreg_db/models/media/video/video_metadata.py +65 -0
- endoreg_db/models/media/video/video_processing.py +152 -0
- endoreg_db/models/medical/__init__.py +146 -0
- endoreg_db/models/medical/contraindication/__init__.py +17 -0
- endoreg_db/models/medical/disease.py +156 -0
- endoreg_db/models/medical/event.py +137 -0
- endoreg_db/models/medical/examination/__init__.py +9 -0
- endoreg_db/models/medical/examination/examination.py +148 -0
- endoreg_db/models/medical/examination/examination_indication.py +278 -0
- endoreg_db/models/medical/examination/examination_time.py +49 -0
- endoreg_db/models/medical/examination/examination_time_type.py +41 -0
- endoreg_db/models/medical/examination/examination_type.py +48 -0
- endoreg_db/models/medical/finding/__init__.py +18 -0
- endoreg_db/models/medical/finding/finding.py +96 -0
- endoreg_db/models/medical/finding/finding_classification.py +142 -0
- endoreg_db/models/medical/finding/finding_intervention.py +52 -0
- endoreg_db/models/medical/finding/finding_type.py +35 -0
- endoreg_db/models/medical/hardware/__init__.py +8 -0
- endoreg_db/models/medical/hardware/endoscope.py +65 -0
- endoreg_db/models/{hardware → medical/hardware}/endoscopy_processor.py +182 -143
- endoreg_db/models/medical/laboratory/__init__.py +5 -0
- endoreg_db/models/medical/laboratory/lab_value.py +419 -0
- endoreg_db/models/medical/medication/__init__.py +19 -0
- endoreg_db/models/medical/medication/medication.py +31 -0
- endoreg_db/models/medical/medication/medication_indication.py +50 -0
- endoreg_db/models/medical/medication/medication_indication_type.py +39 -0
- endoreg_db/models/medical/medication/medication_intake_time.py +44 -0
- endoreg_db/models/medical/medication/medication_schedule.py +45 -0
- endoreg_db/models/medical/organ/__init__.py +35 -0
- endoreg_db/models/medical/patient/__init__.py +56 -0
- endoreg_db/models/medical/patient/medication_examples.py +38 -0
- endoreg_db/models/medical/patient/patient_disease.py +63 -0
- endoreg_db/models/medical/patient/patient_event.py +75 -0
- endoreg_db/models/medical/patient/patient_examination.py +249 -0
- endoreg_db/models/medical/patient/patient_examination_indication.py +44 -0
- endoreg_db/models/medical/patient/patient_finding.py +357 -0
- endoreg_db/models/medical/patient/patient_finding_classification.py +207 -0
- endoreg_db/models/medical/patient/patient_finding_intervention.py +40 -0
- endoreg_db/models/medical/patient/patient_lab_sample.py +148 -0
- endoreg_db/models/{persons → medical}/patient/patient_lab_value.py +222 -176
- endoreg_db/models/medical/patient/patient_medication.py +104 -0
- endoreg_db/models/medical/patient/patient_medication_schedule.py +136 -0
- endoreg_db/models/medical/risk/__init__.py +7 -0
- endoreg_db/models/medical/risk/risk.py +72 -0
- endoreg_db/models/medical/risk/risk_type.py +51 -0
- endoreg_db/models/metadata/__init__.py +19 -0
- endoreg_db/models/metadata/frame_ocr_result.py +0 -0
- endoreg_db/models/metadata/model_meta.py +206 -0
- endoreg_db/models/metadata/model_meta_logic.py +343 -0
- endoreg_db/models/{data_file/metadata → metadata}/pdf_meta.py +89 -70
- endoreg_db/models/metadata/sensitive_meta.py +288 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +1048 -0
- endoreg_db/models/metadata/video_meta.py +332 -0
- endoreg_db/models/metadata/video_prediction_logic.py +190 -0
- endoreg_db/models/metadata/video_prediction_meta.py +270 -0
- endoreg_db/models/other/__init__.py +40 -5
- endoreg_db/models/other/distribution/__init__.py +44 -0
- endoreg_db/models/other/distribution/base_value_distribution.py +20 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +89 -0
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +32 -0
- endoreg_db/models/other/distribution/numeric_value_distribution.py +125 -0
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +22 -0
- endoreg_db/models/other/emission/__init__.py +5 -0
- endoreg_db/models/other/emission/emission_factor.py +94 -0
- endoreg_db/models/{persons → other}/gender.py +27 -22
- endoreg_db/models/other/information_source.py +159 -0
- endoreg_db/models/other/material.py +28 -16
- endoreg_db/models/other/resource.py +21 -17
- endoreg_db/models/other/tag.py +27 -0
- endoreg_db/models/other/transport_route.py +33 -21
- endoreg_db/models/{unit.py → other/unit.py} +32 -22
- endoreg_db/models/other/waste.py +27 -20
- endoreg_db/models/requirement/__init__.py +11 -0
- endoreg_db/models/requirement/requirement.py +767 -0
- endoreg_db/models/requirement/requirement_evaluation/__init__.py +6 -0
- endoreg_db/models/requirement/requirement_evaluation/get_values.py +40 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +9 -0
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +95 -0
- endoreg_db/models/requirement/requirement_operator.py +176 -0
- endoreg_db/models/requirement/requirement_set.py +287 -0
- endoreg_db/models/rule/__init__.py +13 -0
- endoreg_db/models/{rules → rule}/rule.py +27 -24
- endoreg_db/models/{rules → rule}/rule_applicator.py +224 -224
- endoreg_db/models/{rules → rule}/rule_attribute_dtype.py +16 -18
- endoreg_db/models/{rules → rule}/rule_type.py +19 -21
- endoreg_db/models/{rules → rule}/ruleset.py +17 -19
- endoreg_db/models/state/__init__.py +12 -0
- endoreg_db/models/state/abstract.py +11 -0
- endoreg_db/models/state/audit_ledger.py +150 -0
- endoreg_db/models/state/label_video_segment.py +22 -0
- endoreg_db/models/state/raw_pdf.py +187 -0
- endoreg_db/models/state/sensitive_meta.py +46 -0
- endoreg_db/models/state/video.py +232 -0
- endoreg_db/models/upload_job.py +99 -0
- endoreg_db/models/utils.py +135 -0
- endoreg_db/queries/__init__.py +4 -4
- endoreg_db/queries/annotations/__init__.py +2 -2
- endoreg_db/queries/annotations/legacy.py +158 -159
- endoreg_db/renames.yml +8 -0
- endoreg_db/root_urls.py +9 -0
- endoreg_db/schemas/__init__.py +0 -0
- endoreg_db/schemas/examination_evaluation.py +27 -0
- endoreg_db/serializers/Frames_NICE_and_PARIS_classifications.py +775 -0
- endoreg_db/serializers/__init__.py +118 -10
- endoreg_db/serializers/_old/raw_pdf_meta_validation.py +223 -0
- endoreg_db/serializers/_old/raw_video_meta_validation.py +179 -0
- endoreg_db/serializers/_old/video.py +71 -0
- endoreg_db/serializers/administration/__init__.py +14 -0
- endoreg_db/serializers/administration/ai/__init__.py +10 -0
- endoreg_db/serializers/administration/ai/active_model.py +10 -0
- endoreg_db/serializers/administration/ai/ai_model.py +18 -0
- endoreg_db/serializers/administration/ai/model_type.py +10 -0
- endoreg_db/serializers/administration/center.py +9 -0
- endoreg_db/serializers/administration/gender.py +9 -0
- endoreg_db/serializers/anonymization.py +69 -0
- endoreg_db/serializers/evaluation/examination_evaluation.py +1 -0
- endoreg_db/serializers/examination/__init__.py +10 -0
- endoreg_db/serializers/examination/base.py +46 -0
- endoreg_db/serializers/examination/dropdown.py +21 -0
- endoreg_db/serializers/examination_serializer.py +12 -0
- endoreg_db/serializers/finding/__init__.py +5 -0
- endoreg_db/serializers/finding/finding.py +54 -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 +13 -0
- endoreg_db/serializers/label/__init__.py +7 -0
- endoreg_db/serializers/label/image_classification_annotation.py +62 -0
- endoreg_db/serializers/label/label.py +15 -0
- endoreg_db/serializers/label_video_segment/__init__.py +7 -0
- endoreg_db/serializers/label_video_segment/_lvs_create.py +149 -0
- endoreg_db/serializers/label_video_segment/_lvs_update.py +138 -0
- endoreg_db/serializers/label_video_segment/_lvs_validate.py +149 -0
- endoreg_db/serializers/label_video_segment/label_video_segment.py +344 -0
- endoreg_db/serializers/label_video_segment/label_video_segment_annotation.py +99 -0
- endoreg_db/serializers/label_video_segment/label_video_segment_update.py +163 -0
- endoreg_db/serializers/meta/__init__.py +19 -0
- endoreg_db/serializers/meta/pdf_file_meta_extraction.py +115 -0
- endoreg_db/serializers/meta/report_meta.py +53 -0
- endoreg_db/serializers/meta/sensitive_meta_detail.py +162 -0
- endoreg_db/serializers/meta/sensitive_meta_update.py +148 -0
- endoreg_db/serializers/meta/sensitive_meta_verification.py +59 -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 +182 -0
- endoreg_db/serializers/misc/sensitive_patient_data.py +120 -0
- endoreg_db/serializers/misc/stats.py +33 -0
- endoreg_db/serializers/misc/translatable_field_mix_in.py +44 -0
- endoreg_db/serializers/misc/upload_job.py +71 -0
- endoreg_db/serializers/patient/__init__.py +11 -0
- endoreg_db/serializers/patient/patient.py +86 -0
- endoreg_db/serializers/patient/patient_dropdown.py +27 -0
- endoreg_db/serializers/patient_examination/__init__.py +7 -0
- endoreg_db/serializers/patient_examination/patient_examination.py +141 -0
- endoreg_db/serializers/patient_finding/__init__.py +15 -0
- endoreg_db/serializers/patient_finding/patient_finding.py +31 -0
- endoreg_db/serializers/patient_finding/patient_finding_classification.py +39 -0
- endoreg_db/serializers/patient_finding/patient_finding_detail.py +53 -0
- endoreg_db/serializers/patient_finding/patient_finding_intervention.py +26 -0
- endoreg_db/serializers/patient_finding/patient_finding_list.py +41 -0
- endoreg_db/serializers/patient_finding/patient_finding_write.py +126 -0
- endoreg_db/serializers/pdf/__init__.py +5 -0
- endoreg_db/serializers/pdf/anony_text_validation.py +85 -0
- endoreg_db/serializers/report/__init__.py +9 -0
- endoreg_db/serializers/report/mixins.py +45 -0
- endoreg_db/serializers/report/report.py +105 -0
- endoreg_db/serializers/report/report_list.py +22 -0
- endoreg_db/serializers/report/secure_file_url.py +26 -0
- endoreg_db/serializers/requirements/requirement_schema.py +25 -0
- endoreg_db/serializers/requirements/requirement_sets.py +29 -0
- endoreg_db/serializers/sensitive_meta_serializer.py +282 -0
- endoreg_db/serializers/video/__init__.py +7 -0
- endoreg_db/serializers/video/segmentation.py +263 -0
- endoreg_db/serializers/video/video_file_brief.py +10 -0
- endoreg_db/serializers/video/video_file_detail.py +83 -0
- endoreg_db/serializers/video/video_file_list.py +67 -0
- endoreg_db/serializers/video/video_metadata.py +105 -0
- endoreg_db/serializers/video/video_processing_history.py +153 -0
- endoreg_db/serializers/video_examination.py +198 -0
- endoreg_db/services/__init__.py +5 -0
- endoreg_db/services/anonymization.py +223 -0
- endoreg_db/services/examination_evaluation.py +149 -0
- endoreg_db/services/finding_description_service.py +0 -0
- endoreg_db/services/lookup_service.py +411 -0
- endoreg_db/services/lookup_store.py +266 -0
- endoreg_db/services/pdf_import.py +1382 -0
- endoreg_db/services/polling_coordinator.py +288 -0
- endoreg_db/services/pseudonym_service.py +89 -0
- endoreg_db/services/requirements_object.py +147 -0
- endoreg_db/services/segment_sync.py +155 -0
- endoreg_db/services/storage_aware_video_processor.py +344 -0
- endoreg_db/services/video_import.py +1259 -0
- endoreg_db/tasks/upload_tasks.py +207 -0
- endoreg_db/tasks/video_ingest.py +157 -0
- endoreg_db/tasks/video_processing_tasks.py +327 -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 +83 -0
- endoreg_db/urls/anonymization.py +32 -0
- endoreg_db/urls/auth.py +16 -0
- endoreg_db/urls/classification.py +39 -0
- endoreg_db/urls/examination.py +54 -0
- endoreg_db/urls/files.py +6 -0
- endoreg_db/urls/label_video_segment_validate.py +33 -0
- endoreg_db/urls/label_video_segments.py +46 -0
- endoreg_db/urls/media.py +227 -0
- endoreg_db/urls/patient.py +19 -0
- endoreg_db/urls/report.py +48 -0
- endoreg_db/urls/requirements.py +13 -0
- endoreg_db/urls/sensitive_meta.py +0 -0
- endoreg_db/urls/stats.py +46 -0
- endoreg_db/urls/upload.py +20 -0
- endoreg_db/urls/video.py +61 -0
- endoreg_db/urls.py +9 -0
- endoreg_db/utils/__init__.py +88 -1
- endoreg_db/utils/ai/__init__.py +9 -0
- endoreg_db/{models/ai_model/utils.py → utils/ai/get.py} +5 -8
- endoreg_db/utils/ai/inference_dataset.py +52 -0
- endoreg_db/utils/ai/multilabel_classification_net.py +159 -0
- endoreg_db/utils/ai/postprocess.py +63 -0
- endoreg_db/utils/ai/predict.py +291 -0
- endoreg_db/utils/ai/preprocess.py +68 -0
- endoreg_db/utils/calc_duration_seconds.py +24 -0
- endoreg_db/utils/case_generator/__init__.py +0 -0
- endoreg_db/utils/case_generator/case_generator.py +159 -0
- endoreg_db/utils/case_generator/lab_sample_factory.py +33 -0
- endoreg_db/utils/case_generator/utils.py +30 -0
- endoreg_db/utils/check_video_files.py +148 -0
- endoreg_db/utils/cropping.py +28 -28
- endoreg_db/utils/dataloader.py +175 -92
- endoreg_db/utils/dates.py +60 -0
- endoreg_db/utils/env.py +33 -0
- endoreg_db/utils/extract_specific_frames.py +72 -0
- endoreg_db/utils/file_operations.py +58 -30
- endoreg_db/utils/fix_video_path_direct.py +141 -0
- endoreg_db/utils/frame_anonymization_utils.py +463 -0
- endoreg_db/utils/hashs.py +153 -34
- endoreg_db/utils/links/__init__.py +0 -0
- endoreg_db/utils/links/requirement_link.py +193 -0
- endoreg_db/utils/mime_types.py +0 -0
- endoreg_db/utils/names.py +76 -0
- endoreg_db/utils/ocr.py +190 -197
- endoreg_db/utils/parse_and_generate_yaml.py +46 -0
- endoreg_db/utils/paths.py +95 -0
- endoreg_db/utils/permissions.py +143 -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 +120 -0
- endoreg_db/utils/product/__init__.py +0 -0
- endoreg_db/utils/product/sum_emissions.py +20 -0
- endoreg_db/utils/product/sum_weights.py +18 -0
- endoreg_db/utils/pydantic_models/__init__.py +6 -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/lab_value_operators.py +578 -0
- endoreg_db/utils/requirement_operator_logic/model_evaluators.py +368 -0
- endoreg_db/utils/setup_config.py +177 -0
- endoreg_db/utils/translation.py +27 -0
- endoreg_db/utils/uuid.py +4 -4
- endoreg_db/utils/validate_endo_roi.py +19 -0
- endoreg_db/utils/validate_subcategory_dict.py +91 -0
- endoreg_db/utils/validate_video_detailed.py +357 -0
- endoreg_db/utils/video/__init__.py +26 -0
- endoreg_db/utils/video/extract_frames.py +88 -0
- endoreg_db/utils/video/ffmpeg_wrapper.py +835 -0
- endoreg_db/utils/video/names.py +42 -0
- endoreg_db/utils/video/streaming_processor.py +312 -0
- endoreg_db/utils/video/video_splitter.py +94 -0
- endoreg_db/views/Frames_NICE_and_PARIS_classifications_views.py +238 -0
- endoreg_db/views/__init__.py +275 -0
- endoreg_db/views/anonymization/__init__.py +27 -0
- endoreg_db/views/anonymization/media_management.py +454 -0
- endoreg_db/views/anonymization/overview.py +216 -0
- endoreg_db/views/anonymization/validate.py +107 -0
- endoreg_db/views/auth/__init__.py +13 -0
- endoreg_db/views/auth/keycloak.py +113 -0
- endoreg_db/views/examination/__init__.py +33 -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 +59 -0
- endoreg_db/views/examination/get_finding_classifications.py +36 -0
- endoreg_db/views/examination/get_findings.py +41 -0
- endoreg_db/views/examination/get_instruments.py +18 -0
- endoreg_db/views/examination/get_interventions.py +14 -0
- endoreg_db/views/finding/__init__.py +9 -0
- endoreg_db/views/finding/finding.py +112 -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 +42 -0
- endoreg_db/views/finding_classification/get_classification_choices.py +55 -0
- endoreg_db/views/label/__init__.py +5 -0
- endoreg_db/views/label/label.py +15 -0
- endoreg_db/views/label_video_segment/__init__.py +16 -0
- endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +44 -0
- endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +50 -0
- endoreg_db/views/label_video_segment/label_video_segment.py +77 -0
- endoreg_db/views/label_video_segment/label_video_segment_by_label.py +174 -0
- endoreg_db/views/label_video_segment/label_video_segment_detail.py +73 -0
- endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +46 -0
- endoreg_db/views/label_video_segment/validate.py +226 -0
- endoreg_db/views/media/__init__.py +45 -0
- endoreg_db/views/media/pdf_media.py +388 -0
- endoreg_db/views/media/segments.py +71 -0
- endoreg_db/views/media/sensitive_metadata.py +314 -0
- endoreg_db/views/media/video_media.py +272 -0
- endoreg_db/views/media/video_segments.py +524 -0
- endoreg_db/views/meta/__init__.py +15 -0
- endoreg_db/views/meta/available_files_list.py +146 -0
- endoreg_db/views/meta/report_meta.py +53 -0
- endoreg_db/views/meta/sensitive_meta_detail.py +148 -0
- endoreg_db/views/meta/sensitive_meta_list.py +104 -0
- endoreg_db/views/meta/sensitive_meta_verification.py +71 -0
- endoreg_db/views/misc/__init__.py +63 -0
- endoreg_db/views/misc/center.py +13 -0
- endoreg_db/views/misc/csrf.py +7 -0
- endoreg_db/views/misc/gender.py +14 -0
- endoreg_db/views/misc/secure_file_serving_view.py +80 -0
- endoreg_db/views/misc/secure_file_url_view.py +84 -0
- endoreg_db/views/misc/secure_url_validate.py +79 -0
- endoreg_db/views/misc/stats.py +220 -0
- endoreg_db/views/misc/translation.py +182 -0
- endoreg_db/views/misc/upload_views.py +240 -0
- endoreg_db/views/patient/__init__.py +5 -0
- endoreg_db/views/patient/patient.py +210 -0
- endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +164 -0
- endoreg_db/views/patient_examination/__init__.py +11 -0
- endoreg_db/views/patient_examination/patient_examination.py +140 -0
- endoreg_db/views/patient_examination/patient_examination_create.py +63 -0
- endoreg_db/views/patient_examination/patient_examination_detail.py +66 -0
- endoreg_db/views/patient_examination/patient_examination_list.py +68 -0
- endoreg_db/views/patient_examination/video.py +194 -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 +64 -0
- endoreg_db/views/patient_finding/patient_finding_optimized.py +259 -0
- endoreg_db/views/patient_finding_classification/__init__.py +5 -0
- endoreg_db/views/patient_finding_classification/pfc_create.py +67 -0
- endoreg_db/views/patient_finding_location/__init__.py +5 -0
- endoreg_db/views/patient_finding_location/pfl_create.py +70 -0
- endoreg_db/views/patient_finding_morphology/__init__.py +5 -0
- endoreg_db/views/patient_finding_morphology/pfm_create.py +70 -0
- endoreg_db/views/pdf/__init__.py +8 -0
- endoreg_db/views/pdf/pdf_stream.py +187 -0
- endoreg_db/views/pdf/reimport.py +177 -0
- endoreg_db/views/report/__init__.py +9 -0
- endoreg_db/views/report/report_list.py +112 -0
- endoreg_db/views/report/report_with_secure_url.py +28 -0
- endoreg_db/views/report/start_examination.py +7 -0
- endoreg_db/views/requirement/__init__.py +10 -0
- endoreg_db/views/requirement/evaluate.py +279 -0
- endoreg_db/views/requirement/lookup.py +367 -0
- endoreg_db/views/requirement/lookup_store.py +252 -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 +229 -0
- endoreg_db/views/video/__init__.py +59 -0
- endoreg_db/views/video/correction.py +530 -0
- endoreg_db/views/video/reimport.py +195 -0
- endoreg_db/views/video/segmentation.py +274 -0
- endoreg_db/views/video/task_status.py +49 -0
- endoreg_db/views/video/timeline.py +46 -0
- endoreg_db/views/video/video_analyze.py +52 -0
- endoreg_db/views/video/video_apply_mask.py +48 -0
- endoreg_db/views/video/video_correction.py +21 -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_meta.py +29 -0
- endoreg_db/views/video/video_processing_history.py +24 -0
- endoreg_db/views/video/video_remove_frames.py +48 -0
- endoreg_db/views/video/video_stream.py +306 -0
- endoreg_db/views.py +0 -3
- endoreg_db-0.8.6.1.dist-info/METADATA +383 -0
- endoreg_db-0.8.6.1.dist-info/RECORD +793 -0
- {endoreg_db-0.3.6.dist-info → endoreg_db-0.8.6.1.dist-info}/WHEEL +1 -1
- {endoreg_db-0.3.6.dist-info → endoreg_db-0.8.6.1.dist-info/licenses}/LICENSE +674 -674
- endoreg_db/data/active_model/data.yaml +0 -3
- endoreg_db/data/label/label-set/data.yaml +0 -18
- endoreg_db/management/commands/_load_model_template.py +0 -41
- endoreg_db/management/commands/delete_all.py +0 -18
- endoreg_db/management/commands/delete_legacy_images.py +0 -19
- endoreg_db/management/commands/delete_legacy_videos.py +0 -17
- endoreg_db/management/commands/extract_legacy_video_frames.py +0 -18
- endoreg_db/management/commands/fetch_legacy_image_dataset.py +0 -32
- endoreg_db/management/commands/fix_auth_permission.py +0 -20
- endoreg_db/management/commands/import_legacy_images.py +0 -94
- endoreg_db/management/commands/import_legacy_videos.py +0 -76
- endoreg_db/management/commands/load_active_model_data.py +0 -45
- endoreg_db/management/commands/load_endoscopy_processor_data.py +0 -45
- endoreg_db/management/commands/load_g_play_data.py +0 -113
- endoreg_db/management/commands/load_label_data.py +0 -67
- endoreg_db/management/commands/load_medication_indication_data.py +0 -63
- endoreg_db/management/commands/load_medication_schedule_data.py +0 -55
- endoreg_db/migrations/0002_rawvideofile.py +0 -26
- endoreg_db/migrations/0003_rawvideofile_frames_required.py +0 -18
- endoreg_db/migrations/0004_rename_hash_rawvideofile_video_hash.py +0 -18
- endoreg_db/migrations/0005_ffmpegmeta_remove_videoimportmeta_center_and_more.py +0 -56
- endoreg_db/migrations/0006_rawvideofile_center_alter_videometa_processor.py +0 -25
- endoreg_db/migrations/0007_rawvideofile_processor.py +0 -19
- endoreg_db/migrations/0008_rename_frames_required_rawvideofile_state_frames_required.py +0 -18
- endoreg_db/migrations/0009_sensitivemeta_rawvideofile_sensitive_meta.py +0 -31
- endoreg_db/migrations/0010_rename_endoscope_serial_number_sensitivemeta_endoscope_sn.py +0 -18
- endoreg_db/migrations/0011_rawvideofile_state_sensitive_data_retrieved.py +0 -18
- endoreg_db/migrations/0012_rawvideofile_prediction_dir_and_more.py +0 -109
- endoreg_db/migrations/0013_rawpdffile.py +0 -31
- endoreg_db/migrations/0014_pdftype_alter_rawpdffile_file_pdfmeta.py +0 -38
- endoreg_db/migrations/0015_rename_report_processed_rawpdffile_state_report_processed_and_more.py +0 -31
- endoreg_db/migrations/0016_rawpdffile_state_report_processing_required.py +0 -18
- endoreg_db/migrations/0017_firstname_lastname_center_first_names_and_more.py +0 -37
- endoreg_db/migrations/0018_reportreaderflag_reportreaderconfig.py +0 -37
- endoreg_db/migrations/0019_pdftype_cut_off_above_lines_and_more.py +0 -42
- endoreg_db/migrations/0020_rename_endoscopy_info_line_pdftype_endoscope_info_line.py +0 -18
- endoreg_db/migrations/0021_alter_pdftype_endoscope_info_line.py +0 -19
- endoreg_db/migrations/0022_alter_pdftype_endoscope_info_line.py +0 -19
- endoreg_db/migrations/0023_ttoquestionnaire_alter_pdftype_endoscope_info_line.py +0 -59
- endoreg_db/migrations/0024_remove_ttoquestionnaire_infections_and_more.py +0 -27
- endoreg_db/migrations/0025_event_alter_rawpdffile_file_patientevent.py +0 -42
- endoreg_db/migrations/0026_disease_diseaseclassification_and_more.py +0 -166
- endoreg_db/migrations/0027_labvalue_abbreviation_labvalue_default_normal_range_and_more.py +0 -38
- endoreg_db/migrations/0028_alter_unit_abbreviation.py +0 -18
- endoreg_db/migrations/0029_medicationintaketime_and_more.py +0 -75
- endoreg_db/migrations/0030_medicationindicationtype_and_more.py +0 -101
- endoreg_db/migrations/0031_rename_adapt_to_liver_function_medication_adapt_to_age_and_more.py +0 -38
- endoreg_db/migrations/0032_alter_medicationschedule_therapy_duration_d.py +0 -18
- endoreg_db/migrations/0033_medicationindication_sources.py +0 -18
- endoreg_db/migrations/0034_alter_rawpdffile_file.py +0 -20
- endoreg_db/migrations/0035_alter_medicationindication_sources.py +0 -18
- endoreg_db/migrations/0036_alter_rawpdffile_file.py +0 -20
- endoreg_db/migrations/0037_alter_medicationindication_sources.py +0 -18
- endoreg_db/migrations/0038_emissionfactor_material_product_productgroup_and_more.py +0 -164
- endoreg_db/migrations/0039_referenceproduct_name.py +0 -19
- endoreg_db/migrations/0040_quizanswertype_quizquestiontype_quizquestion_and_more.py +0 -50
- endoreg_db/migrations/0041_gender_patientmedication_medication_indication_and_more.py +0 -40
- endoreg_db/migrations/0042_casetemplateruletype_casetemplaterulevalue_and_more.py +0 -74
- endoreg_db/migrations/0043_casetemplatetype_name_de_casetemplatetype_name_en.py +0 -23
- endoreg_db/migrations/0044_casetemplateruletype_name_de_and_more.py +0 -23
- endoreg_db/migrations/0045_casetemplaterulevalue_value_type.py +0 -19
- endoreg_db/migrations/0046_casetemplaterulevalue_target_field.py +0 -18
- endoreg_db/migrations/0047_casetemplaterule_target_model.py +0 -18
- endoreg_db/migrations/0048_remove_casetemplaterule_chained_rules_and_more.py +0 -22
- endoreg_db/migrations/0049_remove_casetemplaterule_rule_values.py +0 -17
- endoreg_db/migrations/0050_casetemplaterule_rule_values.py +0 -18
- endoreg_db/migrations/0051_remove_casetemplaterule_calling_rules_and_more.py +0 -27
- endoreg_db/migrations/0052_rename_case_template_type_casetemplate_template_type.py +0 -18
- endoreg_db/migrations/0053_patientlabsampletype_patientlabsample_and_more.py +0 -38
- endoreg_db/migrations/0054_multiplecategoricalvaluedistribution_and_more.py +0 -69
- endoreg_db/migrations/0055_remove_casetemplaterule_rule_values_and_more.py +0 -59
- endoreg_db/migrations/0056_datevaluedistribution_and_more.py +0 -32
- endoreg_db/migrations/0057_remove_datevaluedistribution_max_date_and_more.py +0 -72
- endoreg_db/migrations/0058_datevaluedistribution_description_and_more.py +0 -28
- endoreg_db/migrations/0059_casetemplaterule_rule_values.py +0 -18
- endoreg_db/migrations/0060_labvalue__default_date_value_distribution_and_more.py +0 -44
- endoreg_db/migrations/0061_remove_patientlabvalue_date_patientlabvalue_datetime.py +0 -24
- endoreg_db/migrations/0062_labvalue_numeric_precision.py +0 -18
- endoreg_db/migrations/0063_alter_labvalue_numeric_precision.py +0 -18
- endoreg_db/migrations/0064_casetemplaterule_extra_parameters_and_more.py +0 -23
- endoreg_db/migrations/0065_rename__date_value_distribution_casetemplaterule_date_value_distribution_and_more.py +0 -58
- endoreg_db/migrations/0066_alter_patientlabvalue_patient_and_more.py +0 -29
- endoreg_db/migrations/0067_alter_medicationindication_indication_type.py +0 -19
- endoreg_db/models/ai_model/__init__.py +0 -3
- endoreg_db/models/ai_model/active_model.py +0 -9
- endoreg_db/models/ai_model/model_meta.py +0 -24
- endoreg_db/models/annotation/__init__.py +0 -2
- endoreg_db/models/annotation/binary_classification_annotation_task.py +0 -80
- endoreg_db/models/annotation/image_classification.py +0 -27
- endoreg_db/models/center/center.py +0 -25
- endoreg_db/models/center/center_product.py +0 -34
- endoreg_db/models/center/center_resource.py +0 -19
- endoreg_db/models/center/center_waste.py +0 -11
- endoreg_db/models/data_file/__init__.py +0 -6
- endoreg_db/models/data_file/base_classes/__init__.py +0 -2
- endoreg_db/models/data_file/base_classes/abstract_frame.py +0 -51
- endoreg_db/models/data_file/base_classes/abstract_video.py +0 -201
- endoreg_db/models/data_file/frame.py +0 -45
- endoreg_db/models/data_file/import_classes/__init__.py +0 -32
- endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +0 -35
- endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +0 -28
- endoreg_db/models/data_file/import_classes/processing_functions/video.py +0 -260
- endoreg_db/models/data_file/import_classes/raw_pdf.py +0 -188
- endoreg_db/models/data_file/import_classes/raw_video.py +0 -343
- endoreg_db/models/data_file/metadata/__init__.py +0 -3
- endoreg_db/models/data_file/metadata/sensitive_meta.py +0 -31
- endoreg_db/models/data_file/metadata/video_meta.py +0 -133
- endoreg_db/models/data_file/report_file.py +0 -89
- endoreg_db/models/data_file/video/__init__.py +0 -7
- endoreg_db/models/data_file/video/import_meta.py +0 -25
- endoreg_db/models/data_file/video/video.py +0 -25
- endoreg_db/models/data_file/video_segment.py +0 -107
- endoreg_db/models/disease.py +0 -56
- endoreg_db/models/emission/__init__.py +0 -1
- endoreg_db/models/emission/emission_factor.py +0 -20
- endoreg_db/models/event.py +0 -22
- endoreg_db/models/examination/__init__.py +0 -4
- endoreg_db/models/examination/examination.py +0 -26
- endoreg_db/models/examination/examination_time.py +0 -27
- endoreg_db/models/examination/examination_time_type.py +0 -24
- endoreg_db/models/examination/examination_type.py +0 -18
- endoreg_db/models/hardware/__init__.py +0 -2
- endoreg_db/models/hardware/endoscope.py +0 -44
- endoreg_db/models/information_source.py +0 -29
- endoreg_db/models/laboratory/__init__.py +0 -1
- endoreg_db/models/laboratory/lab_value.py +0 -102
- endoreg_db/models/legacy_data/__init__.py +0 -3
- endoreg_db/models/legacy_data/image.py +0 -34
- endoreg_db/models/medication/__init__.py +0 -1
- endoreg_db/models/medication/medication.py +0 -148
- endoreg_db/models/other/distribution.py +0 -215
- endoreg_db/models/patient_examination/__init__.py +0 -35
- endoreg_db/models/permissions/__init__.py +0 -44
- endoreg_db/models/persons/__init__.py +0 -7
- endoreg_db/models/persons/examiner/__init__.py +0 -2
- endoreg_db/models/persons/examiner/examiner.py +0 -16
- endoreg_db/models/persons/examiner/examiner_type.py +0 -2
- endoreg_db/models/persons/patient/__init__.py +0 -8
- endoreg_db/models/persons/patient/case/case.py +0 -30
- endoreg_db/models/persons/patient/patient.py +0 -216
- endoreg_db/models/persons/patient/patient_disease.py +0 -16
- endoreg_db/models/persons/patient/patient_event.py +0 -22
- endoreg_db/models/persons/patient/patient_lab_sample.py +0 -106
- endoreg_db/models/persons/patient/patient_medication.py +0 -44
- endoreg_db/models/persons/patient/patient_medication_schedule.py +0 -28
- endoreg_db/models/persons/portal_user_information.py +0 -27
- endoreg_db/models/prediction/__init__.py +0 -2
- endoreg_db/models/prediction/image_classification.py +0 -37
- endoreg_db/models/prediction/video_prediction_meta.py +0 -244
- endoreg_db/models/product/__init__.py +0 -5
- endoreg_db/models/product/product.py +0 -97
- endoreg_db/models/product/product_group.py +0 -19
- endoreg_db/models/product/product_material.py +0 -24
- endoreg_db/models/questionnaires/__init__.py +0 -114
- endoreg_db/models/quiz/__init__.py +0 -2
- endoreg_db/models/quiz/quiz_answer.py +0 -41
- endoreg_db/models/quiz/quiz_question.py +0 -54
- endoreg_db/models/report_reader/__init__.py +0 -2
- endoreg_db/models/report_reader/report_reader_config.py +0 -53
- endoreg_db/models/rules/__init__.py +0 -5
- endoreg_db/queries/get/__init__.py +0 -6
- endoreg_db/queries/get/center.py +0 -42
- endoreg_db/queries/get/model.py +0 -13
- endoreg_db/queries/get/patient.py +0 -14
- endoreg_db/queries/get/patient_examination.py +0 -20
- endoreg_db/queries/get/report_file.py +0 -33
- endoreg_db/queries/get/video.py +0 -31
- endoreg_db/serializers/ai_model.py +0 -19
- endoreg_db/serializers/annotation.py +0 -17
- endoreg_db/serializers/center.py +0 -11
- endoreg_db/serializers/examination.py +0 -33
- endoreg_db/serializers/frame.py +0 -13
- endoreg_db/serializers/hardware.py +0 -21
- endoreg_db/serializers/label.py +0 -22
- endoreg_db/serializers/patient.py +0 -10
- endoreg_db/serializers/prediction.py +0 -15
- endoreg_db/serializers/report_file.py +0 -7
- endoreg_db/serializers/video.py +0 -27
- endoreg_db/tests.py +0 -3
- endoreg_db/utils/legacy_ocr.py +0 -201
- endoreg_db/utils/video_metadata.py +0 -87
- endoreg_db-0.3.6.dist-info/METADATA +0 -33
- endoreg_db-0.3.6.dist-info/RECORD +0 -357
- /endoreg_db/{models/persons/patient/case/__init__.py → api/serializers/finding_descriptions.py} +0 -0
- /endoreg_db/{queries/get/annotation.py → api/views/finding_descriptions.py} +0 -0
- /endoreg_db/{queries/get/prediction.py → config/__init__.py} +0 -0
- /endoreg_db/{queries/get/video_import_meta.py → data/case_template/rule_value/.init} +0 -0
- /endoreg_db/{queries/get/video_prediction_meta.py → data/distribution/multiple_categorical/.init} +0 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import TYPE_CHECKING, Optional
|
|
3
|
+
# --- Fix Imports ---
|
|
4
|
+
from ....metadata import SensitiveMeta
|
|
5
|
+
from ....metadata.sensitive_meta_logic import update_or_create_sensitive_meta_from_dict
|
|
6
|
+
# --- End Fix ---
|
|
7
|
+
from django.db import transaction
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from ..video_file import VideoFile
|
|
11
|
+
# SensitiveMeta is already imported above
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _update_text_metadata(
|
|
17
|
+
video: "VideoFile",
|
|
18
|
+
extracted_data_dict: Optional[dict] = None,
|
|
19
|
+
ocr_frame_fraction: float = 0.01,
|
|
20
|
+
cap: int = 10,
|
|
21
|
+
overwrite: bool = False,
|
|
22
|
+
) -> Optional["SensitiveMeta"]:
|
|
23
|
+
"""
|
|
24
|
+
Extracts text from a fraction of video frames, updates or creates SensitiveMeta,
|
|
25
|
+
and potentially updates the VideoFile's date field. Requires frames to be extracted.
|
|
26
|
+
Raises ValueError if pre-conditions not met, RuntimeError on processing failure.
|
|
27
|
+
|
|
28
|
+
State Transitions:
|
|
29
|
+
- Pre-condition: Requires state.frames_extracted=True.
|
|
30
|
+
- Post-condition: Sets state.text_meta_extracted=True (even if no text found).
|
|
31
|
+
"""
|
|
32
|
+
logger.debug(f"Updating text metadata for video {video.uuid}")
|
|
33
|
+
state = video.get_or_create_state()
|
|
34
|
+
|
|
35
|
+
# --- Pre-condition Checks ---
|
|
36
|
+
if not state.frames_extracted:
|
|
37
|
+
# Attempt to extract frames automatically if they're not available
|
|
38
|
+
logger.warning(f"Frames not extracted for video {video.uuid}. Attempting automatic frame extraction...")
|
|
39
|
+
try:
|
|
40
|
+
success = video.extract_frames(overwrite=False)
|
|
41
|
+
if success:
|
|
42
|
+
# Refresh state after frame extraction
|
|
43
|
+
state.refresh_from_db()
|
|
44
|
+
if state.frames_extracted:
|
|
45
|
+
logger.info(f"Successfully extracted frames for video {video.uuid}")
|
|
46
|
+
else:
|
|
47
|
+
# Force update the state if extraction was successful but state wasn't updated
|
|
48
|
+
state.frames_extracted = True
|
|
49
|
+
state.save(update_fields=['frames_extracted'])
|
|
50
|
+
logger.info(f"Corrected frames_extracted state for video {video.uuid}")
|
|
51
|
+
else:
|
|
52
|
+
raise ValueError(f"Cannot update text metadata for video {video.uuid}: Frame extraction failed.")
|
|
53
|
+
except Exception as e:
|
|
54
|
+
logger.error(f"Failed to extract frames for video {video.uuid}: {e}")
|
|
55
|
+
raise ValueError(f"Cannot update text metadata for video {video.uuid}: Frames not extracted and automatic extraction failed: {e}")
|
|
56
|
+
|
|
57
|
+
if state.text_meta_extracted and not overwrite:
|
|
58
|
+
logger.info("Text already extracted for video %s and overwrite=False. Skipping.", video.uuid) # Changed to info
|
|
59
|
+
return video.sensitive_meta # Return existing meta if available
|
|
60
|
+
# --- End Pre-condition Checks ---
|
|
61
|
+
|
|
62
|
+
# Extract text using the AI helper function
|
|
63
|
+
# _extract_text_from_video_frames raises ValueError on pre-condition failure
|
|
64
|
+
try:
|
|
65
|
+
if not extracted_data_dict:
|
|
66
|
+
extracted_data_dict = video.extract_text_from_frames(
|
|
67
|
+
frame_fraction=ocr_frame_fraction, cap=cap
|
|
68
|
+
)
|
|
69
|
+
except Exception as text_extract_e:
|
|
70
|
+
logger.error("Failed during text extraction step for video %s: %s", video.uuid, text_extract_e, exc_info=True)
|
|
71
|
+
raise RuntimeError(f"Text extraction failed for video {video.uuid}") from text_extract_e
|
|
72
|
+
|
|
73
|
+
# --- Atomic Update Block ---
|
|
74
|
+
try:
|
|
75
|
+
with transaction.atomic():
|
|
76
|
+
# Refresh state in case it changed
|
|
77
|
+
state.refresh_from_db()
|
|
78
|
+
sensitive_meta_instance = video.sensitive_meta # Get current instance
|
|
79
|
+
|
|
80
|
+
if not extracted_data_dict:
|
|
81
|
+
logger.warning("No text extracted for video %s; skipping SensitiveMeta update.", video.uuid)
|
|
82
|
+
# Mark state as retrieved even if no data found, to avoid re-running unless overwrite=True
|
|
83
|
+
if not state.text_meta_extracted:
|
|
84
|
+
state.text_meta_extracted = True
|
|
85
|
+
state.save(update_fields=['text_meta_extracted'])
|
|
86
|
+
return sensitive_meta_instance # Return existing meta if available
|
|
87
|
+
|
|
88
|
+
# Add center info if not already present in extracted data
|
|
89
|
+
if 'center_name' not in extracted_data_dict and video.center:
|
|
90
|
+
extracted_data_dict['center_name'] = video.center.name
|
|
91
|
+
logger.debug("Data for SensitiveMeta update for video %s: %s", video.uuid, extracted_data_dict)
|
|
92
|
+
|
|
93
|
+
# Pass the Class, the data dict, and the current instance (or None)
|
|
94
|
+
# This function might raise exceptions if data is invalid
|
|
95
|
+
sensitive_meta, created = update_or_create_sensitive_meta_from_dict(
|
|
96
|
+
SensitiveMeta, # Pass the class
|
|
97
|
+
extracted_data_dict,
|
|
98
|
+
instance=sensitive_meta_instance # Pass current instance via keyword
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Update VideoFile fields if necessary
|
|
102
|
+
update_fields_video = []
|
|
103
|
+
if created or sensitive_meta != sensitive_meta_instance: # Check if relation needs update
|
|
104
|
+
video.sensitive_meta = sensitive_meta
|
|
105
|
+
update_fields_video.append('sensitive_meta')
|
|
106
|
+
|
|
107
|
+
if not video.date and sensitive_meta and extracted_data_dict.get('date'):
|
|
108
|
+
extracted_date = extracted_data_dict.get('date')
|
|
109
|
+
if extracted_date: # Ensure date is not None or empty
|
|
110
|
+
video.date = extracted_date
|
|
111
|
+
update_fields_video.append("date")
|
|
112
|
+
|
|
113
|
+
# Save VideoFile if fields changed
|
|
114
|
+
if update_fields_video:
|
|
115
|
+
video.save(update_fields=update_fields_video)
|
|
116
|
+
|
|
117
|
+
# Update state
|
|
118
|
+
if not state.text_meta_extracted:
|
|
119
|
+
state.text_meta_extracted = True
|
|
120
|
+
state.save(update_fields=['text_meta_extracted'])
|
|
121
|
+
|
|
122
|
+
# Mark sensitive meta as processed when updated via text metadata
|
|
123
|
+
if sensitive_meta:
|
|
124
|
+
state.mark_sensitive_meta_processed(save=True)
|
|
125
|
+
logger.info(f"Marked sensitive_meta_processed=True for video {video.uuid} after text metadata update")
|
|
126
|
+
|
|
127
|
+
logger.info("Successfully updated/created SensitiveMeta and state for video %s.", video.uuid) # Changed to info
|
|
128
|
+
return sensitive_meta
|
|
129
|
+
|
|
130
|
+
except Exception as e:
|
|
131
|
+
logger.error("Failed to update/create SensitiveMeta or state for video %s: %s", video.uuid, e, exc_info=True)
|
|
132
|
+
# Re-raise exception for the pipeline to catch
|
|
133
|
+
raise RuntimeError(f"Failed to update/create SensitiveMeta or state for video {video.uuid}") from e
|
|
134
|
+
# --- End Atomic Update Block ---
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
if TYPE_CHECKING:
|
|
5
|
+
from ..video_file import VideoFile
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
def _update_video_meta(video: "VideoFile", save_instance: bool = True):
|
|
10
|
+
"""
|
|
11
|
+
Updates or creates the technical VideoMeta from the raw video file.
|
|
12
|
+
Raises FileNotFoundError or ValueError on pre-condition failure, RuntimeError on processing failure.
|
|
13
|
+
"""
|
|
14
|
+
from ....metadata import VideoMeta # Local import
|
|
15
|
+
|
|
16
|
+
logger.debug("Updating technical VideoMeta for video %s (from raw file).", video.uuid)
|
|
17
|
+
|
|
18
|
+
if not video.has_raw:
|
|
19
|
+
# DEFENSIVE: Log warning and skip instead of crashing
|
|
20
|
+
logger.warning(f"Raw video file path not available for {video.uuid}. Skipping VideoMeta update - this may indicate the video was processed and raw file moved.")
|
|
21
|
+
return # Graceful skip instead of FileNotFoundError
|
|
22
|
+
|
|
23
|
+
raw_video_path = video.get_raw_file_path() # Use helper
|
|
24
|
+
if not raw_video_path or not raw_video_path.exists():
|
|
25
|
+
# DEFENSIVE: Log warning and skip instead of crashing production pipeline
|
|
26
|
+
logger.warning(f"Raw video file path {raw_video_path} does not exist for video {video.uuid}. Skipping VideoMeta update - this typically happens after video processing when raw files are moved to processed location.")
|
|
27
|
+
return # Graceful skip instead of FileNotFoundError that crashes production
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
vm = video.video_meta
|
|
31
|
+
if vm:
|
|
32
|
+
logger.info("Updating existing VideoMeta (PK: %s) for video %s.", vm.pk, video.uuid)
|
|
33
|
+
vm.update_meta(raw_video_path) # Assuming this method exists and raises on error
|
|
34
|
+
vm.save()
|
|
35
|
+
else:
|
|
36
|
+
if not video.center or not video.processor:
|
|
37
|
+
# Raise exception
|
|
38
|
+
raise ValueError(f"Cannot create VideoMeta for {video.uuid}: Center or Processor is missing.")
|
|
39
|
+
|
|
40
|
+
logger.info("Creating new VideoMeta for video %s.", video.uuid)
|
|
41
|
+
# Assuming create_from_file exists and raises on error
|
|
42
|
+
video.video_meta = VideoMeta.create_from_file(
|
|
43
|
+
video_path=raw_video_path,
|
|
44
|
+
center=video.center,
|
|
45
|
+
processor=video.processor,
|
|
46
|
+
save_instance=True # Let create_from_file handle saving
|
|
47
|
+
)
|
|
48
|
+
logger.info("Created and linked VideoMeta (PK: %s) for video %s.", video.video_meta.pk, video.uuid)
|
|
49
|
+
|
|
50
|
+
# Save the VideoFile instance itself if requested and if video_meta was linked/updated
|
|
51
|
+
if save_instance:
|
|
52
|
+
update_fields = ["video_meta"]
|
|
53
|
+
# Check if derived fields also need updating
|
|
54
|
+
if video.video_meta:
|
|
55
|
+
meta_fields = ["fps", "duration", "frame_count", "width", "height"]
|
|
56
|
+
for field in meta_fields:
|
|
57
|
+
# Check if field is None on video but has value on meta
|
|
58
|
+
if getattr(video, field) is None and getattr(video.video_meta, field, None) is not None:
|
|
59
|
+
# No need to set attribute here, save method handles it
|
|
60
|
+
update_fields.append(field)
|
|
61
|
+
# Ensure update_fields has unique values before saving
|
|
62
|
+
unique_update_fields = list(set(update_fields))
|
|
63
|
+
if unique_update_fields:
|
|
64
|
+
video.save(update_fields=unique_update_fields)
|
|
65
|
+
logger.info("Saved video %s after VideoMeta update (Fields: %s).", video.uuid, unique_update_fields)
|
|
66
|
+
|
|
67
|
+
except Exception as e:
|
|
68
|
+
logger.error("Failed to update/create VideoMeta for video %s: %s", video.uuid, e, exc_info=True)
|
|
69
|
+
# Re-raise exception
|
|
70
|
+
raise RuntimeError(f"Failed to update/create VideoMeta for video {video.uuid}") from e
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from typing import TYPE_CHECKING, List, Dict, Tuple, Set
|
|
3
|
+
from icecream import ic
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from django.db.models import Q # Import Q for complex queries
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from .video_file import VideoFile
|
|
9
|
+
from ...label import LabelVideoSegment
|
|
10
|
+
from ...metadata import VideoPredictionMeta
|
|
11
|
+
from ..frame import Frame
|
|
12
|
+
from django.db.models import QuerySet
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
def _convert_sequences_to_db_segments(
|
|
17
|
+
video: "VideoFile",
|
|
18
|
+
sequences: Dict[str, List[Tuple[int, int]]],
|
|
19
|
+
video_prediction_meta: "VideoPredictionMeta",
|
|
20
|
+
):
|
|
21
|
+
"""
|
|
22
|
+
Converts predicted sequences into LabelVideoSegment database objects
|
|
23
|
+
and ensures their corresponding state objects are created.
|
|
24
|
+
"""
|
|
25
|
+
from ...label import Label, LabelVideoSegment # Local import for models
|
|
26
|
+
|
|
27
|
+
logger.info("Converting sequences to LabelVideoSegments for video %s, prediction meta %s", video.uuid, video_prediction_meta.pk)
|
|
28
|
+
created_count = 0
|
|
29
|
+
skipped_count = 0
|
|
30
|
+
error_count = 0
|
|
31
|
+
state_created_count = 0
|
|
32
|
+
state_error_count = 0
|
|
33
|
+
|
|
34
|
+
processed_labels = set()
|
|
35
|
+
|
|
36
|
+
for label_name, sequence_list in sequences.items():
|
|
37
|
+
if not sequence_list:
|
|
38
|
+
continue
|
|
39
|
+
|
|
40
|
+
processed_labels.add(label_name)
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
label = Label.objects.get(name=label_name) # require pre-existing label
|
|
44
|
+
except Exception as e:
|
|
45
|
+
logger.error("Could not get or create Label '%s': %s", label_name, e, exc_info=True)
|
|
46
|
+
error_count += len(sequence_list)
|
|
47
|
+
continue
|
|
48
|
+
|
|
49
|
+
segments_to_create = []
|
|
50
|
+
for start_frame, end_frame in sequence_list:
|
|
51
|
+
if start_frame > end_frame or start_frame < 0:
|
|
52
|
+
logger.warning("Skipping invalid sequence for label '%s': start=%d, end=%d", label_name, start_frame, end_frame)
|
|
53
|
+
skipped_count += 1
|
|
54
|
+
continue
|
|
55
|
+
|
|
56
|
+
segments_to_create.append(
|
|
57
|
+
LabelVideoSegment(
|
|
58
|
+
video_file=video,
|
|
59
|
+
label=label,
|
|
60
|
+
start_frame_number=start_frame,
|
|
61
|
+
end_frame_number=end_frame,
|
|
62
|
+
prediction_meta=video_prediction_meta,
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
if segments_to_create:
|
|
67
|
+
try:
|
|
68
|
+
LabelVideoSegment.objects.bulk_create(segments_to_create, ignore_conflicts=True)
|
|
69
|
+
created_count += len(segments_to_create)
|
|
70
|
+
logger.debug("Bulk created %d segments for label '%s'", len(segments_to_create), label_name)
|
|
71
|
+
except Exception as e:
|
|
72
|
+
logger.error("Error bulk creating segments for label '%s': %s", label_name, e, exc_info=True)
|
|
73
|
+
error_count += len(segments_to_create)
|
|
74
|
+
|
|
75
|
+
newly_created_segments = LabelVideoSegment.objects.filter(
|
|
76
|
+
video_file=video,
|
|
77
|
+
prediction_meta=video_prediction_meta,
|
|
78
|
+
label__name__in=processed_labels
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
logger.info("Attempting to create state objects for %d potentially new segments (Video: %s, PredictionMeta: %s)",
|
|
82
|
+
newly_created_segments.count(), video.uuid, video_prediction_meta.pk)
|
|
83
|
+
|
|
84
|
+
for segment in newly_created_segments:
|
|
85
|
+
try:
|
|
86
|
+
_state, created = segment.get_or_create_state()
|
|
87
|
+
if created:
|
|
88
|
+
state_created_count += 1
|
|
89
|
+
except Exception as e:
|
|
90
|
+
logger.error("Failed to get or create state for segment %s (Video: %s): %s", segment.pk, video.uuid, e, exc_info=True)
|
|
91
|
+
state_error_count += 1
|
|
92
|
+
|
|
93
|
+
logger.info(
|
|
94
|
+
"LabelVideoSegment conversion finished for video %s. Segments Created: %d, Skipped: %d, Errors: %d. States Created: %d, State Errors: %d",
|
|
95
|
+
video.uuid, created_count, skipped_count, error_count, state_created_count, state_error_count
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _sequences_to_label_video_segments(
|
|
100
|
+
video: "VideoFile",
|
|
101
|
+
video_prediction_meta: "VideoPredictionMeta",
|
|
102
|
+
):
|
|
103
|
+
"""Converts stored sequences on the video object to LabelVideoSegments."""
|
|
104
|
+
if not video.sequences:
|
|
105
|
+
return
|
|
106
|
+
|
|
107
|
+
if not video_prediction_meta:
|
|
108
|
+
return
|
|
109
|
+
|
|
110
|
+
_convert_sequences_to_db_segments(
|
|
111
|
+
video=video,
|
|
112
|
+
sequences=video.sequences,
|
|
113
|
+
video_prediction_meta=video_prediction_meta,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def _get_outside_segments(video: "VideoFile", outside_label_name: str = "outside") -> "QuerySet[LabelVideoSegment]":
|
|
118
|
+
"""Gets LabelVideoSegments marked with the 'outside' label."""
|
|
119
|
+
from ...label import Label, LabelVideoSegment # Local import for models
|
|
120
|
+
|
|
121
|
+
try:
|
|
122
|
+
outside_label = Label.objects.get(name__iexact=outside_label_name)
|
|
123
|
+
return video.label_video_segments.filter(label=outside_label)
|
|
124
|
+
except Label.DoesNotExist:
|
|
125
|
+
logger.warning("Label '%s' not found in the database.", outside_label_name)
|
|
126
|
+
return LabelVideoSegment.objects.none()
|
|
127
|
+
except AttributeError:
|
|
128
|
+
logger.error("VideoFile instance does not have 'label_video_segments' related manager.")
|
|
129
|
+
return LabelVideoSegment.objects.none()
|
|
130
|
+
except Exception as e:
|
|
131
|
+
logger.error("Error getting '%s' segments for video %s: %s", outside_label_name, video.uuid, e, exc_info=True)
|
|
132
|
+
return LabelVideoSegment.objects.none()
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _get_outside_frame_numbers(video: "VideoFile", outside_label_name: str = "outside") -> Set[int]:
|
|
136
|
+
"""
|
|
137
|
+
Gets a set of frame numbers corresponding to segments labeled as 'outside'.
|
|
138
|
+
"""
|
|
139
|
+
outside_segments = _get_outside_segments(video, outside_label_name)
|
|
140
|
+
frame_numbers = set()
|
|
141
|
+
for segment in outside_segments:
|
|
142
|
+
frame_numbers.update(range(segment.start_frame_number, segment.end_frame_number + 1))
|
|
143
|
+
if frame_numbers:
|
|
144
|
+
logger.info("Found %d frame numbers marked as '%s' for video %s.", len(frame_numbers), outside_label_name, video.uuid)
|
|
145
|
+
else:
|
|
146
|
+
logger.info("No frame numbers marked as '%s' found for video %s.", outside_label_name, video.uuid)
|
|
147
|
+
return frame_numbers
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _get_outside_frames(video: "VideoFile", outside_label_name: str = "outside") -> "QuerySet[Frame]":
|
|
151
|
+
"""
|
|
152
|
+
Gets a QuerySet of all unique Frame objects that fall within any segment
|
|
153
|
+
labeled with the specified 'outside_label_name'.
|
|
154
|
+
"""
|
|
155
|
+
from ..frame import Frame # Local import
|
|
156
|
+
|
|
157
|
+
outside_segments = _get_outside_segments(video, outside_label_name)
|
|
158
|
+
if not outside_segments.exists():
|
|
159
|
+
return Frame.objects.none()
|
|
160
|
+
|
|
161
|
+
q_objects: Q | None = None
|
|
162
|
+
for segment in outside_segments:
|
|
163
|
+
clause = Q(frame_number__gte=segment.start_frame_number,
|
|
164
|
+
frame_number__lt=segment.end_frame_number)
|
|
165
|
+
q_objects = clause if q_objects is None else q_objects | clause
|
|
166
|
+
|
|
167
|
+
if q_objects is None:
|
|
168
|
+
return Frame.objects.none()
|
|
169
|
+
|
|
170
|
+
try:
|
|
171
|
+
return video.frames.filter(q_objects).distinct().order_by('frame_number')
|
|
172
|
+
except Exception as e:
|
|
173
|
+
logger.error("Error filtering outside frames for video %s: %s", video.uuid, e, exc_info=True)
|
|
174
|
+
return Frame.objects.none()
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _get_outside_frame_paths(video: "VideoFile", outside_label_name: str = "outside") -> List["Path"]:
|
|
178
|
+
"""Gets the file paths of frames that fall within 'outside' segments."""
|
|
179
|
+
from pathlib import Path # Local import
|
|
180
|
+
frames = _get_outside_frames(video, outside_label_name=outside_label_name)
|
|
181
|
+
frame_paths = []
|
|
182
|
+
for frame in frames:
|
|
183
|
+
try:
|
|
184
|
+
frame_paths.append(Path(frame.image.path))
|
|
185
|
+
except Exception as e:
|
|
186
|
+
logger.warning("Could not get path for frame %s (Number: %d): %s", frame.pk, frame.frame_number, e)
|
|
187
|
+
ic(f"Could not get path for frame {frame.pk}: {e}")
|
|
188
|
+
|
|
189
|
+
logger.info("Found %d frame paths within '%s' segments for video %s", len(frame_paths), outside_label_name, video.uuid)
|
|
190
|
+
return frame_paths
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _label_segments_to_frame_annotations(video: "VideoFile"):
|
|
194
|
+
"""Generates frame annotations based on existing LabelVideoSegments."""
|
|
195
|
+
logger.info("Generating frame annotations from segments for video %s", video.uuid)
|
|
196
|
+
processed_count = 0
|
|
197
|
+
try:
|
|
198
|
+
for lvs in video.label_video_segments.all():
|
|
199
|
+
lvs_duration = lvs.get_segment_len_in_s()
|
|
200
|
+
if lvs_duration >= 3:
|
|
201
|
+
try:
|
|
202
|
+
lvs.generate_annotations()
|
|
203
|
+
processed_count += 1
|
|
204
|
+
except Exception as e:
|
|
205
|
+
logger.error("Error generating annotations for segment %s (Video %s): %s", lvs.pk, video.uuid, e)
|
|
206
|
+
logger.info("Processed %d segments for frame annotations for video %s", processed_count, video.uuid)
|
|
207
|
+
except AttributeError:
|
|
208
|
+
logger.error("Could not generate frame annotations for video %s. 'label_video_segments' related manager not found.", video.uuid)
|
|
209
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Video Metadata Model
|
|
3
|
+
|
|
4
|
+
Stores analysis results for videos (sensitive frames, detection statistics).
|
|
5
|
+
Created as part of Phase 1.1: Video Correction API Endpoints.
|
|
6
|
+
"""
|
|
7
|
+
from django.db import models
|
|
8
|
+
from .video_file import VideoFile
|
|
9
|
+
|
|
10
|
+
class VideoMetadata(models.Model):
|
|
11
|
+
"""
|
|
12
|
+
Stores analysis results for videos after sensitive frame detection.
|
|
13
|
+
|
|
14
|
+
This model holds the output of frame analysis operations (MiniCPM, OCR+LLM)
|
|
15
|
+
and provides metrics for the correction UI.
|
|
16
|
+
"""
|
|
17
|
+
video = models.OneToOneField(
|
|
18
|
+
VideoFile,
|
|
19
|
+
on_delete=models.CASCADE,
|
|
20
|
+
related_name='metadata',
|
|
21
|
+
help_text="Video file this metadata belongs to"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# Analysis Results
|
|
25
|
+
sensitive_frame_count = models.IntegerField(
|
|
26
|
+
null=True,
|
|
27
|
+
blank=True,
|
|
28
|
+
help_text="Number of frames detected as containing sensitive information"
|
|
29
|
+
)
|
|
30
|
+
sensitive_ratio = models.FloatField(
|
|
31
|
+
null=True,
|
|
32
|
+
blank=True,
|
|
33
|
+
help_text="Ratio of sensitive frames to total frames (0.0-1.0)"
|
|
34
|
+
)
|
|
35
|
+
sensitive_frame_ids = models.TextField(
|
|
36
|
+
null=True,
|
|
37
|
+
blank=True,
|
|
38
|
+
help_text="JSON array of sensitive frame indices (0-based)"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Metadata
|
|
42
|
+
analyzed_at = models.DateTimeField(
|
|
43
|
+
auto_now=True,
|
|
44
|
+
help_text="Timestamp of last analysis"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
class Meta:
|
|
48
|
+
db_table = 'video_metadata'
|
|
49
|
+
verbose_name = 'Video Metadata'
|
|
50
|
+
verbose_name_plural = 'Video Metadata'
|
|
51
|
+
|
|
52
|
+
def __str__(self):
|
|
53
|
+
return f"Metadata for {self.video.uuid} ({self.sensitive_frame_count or 0} sensitive frames)"
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def has_analysis(self) -> bool:
|
|
57
|
+
"""Check if this video has been analyzed."""
|
|
58
|
+
return self.sensitive_frame_count is not None
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def sensitive_percentage(self) -> float:
|
|
62
|
+
"""Get sensitivity as percentage (0-100)."""
|
|
63
|
+
if self.sensitive_ratio is not None:
|
|
64
|
+
return self.sensitive_ratio * 100
|
|
65
|
+
return 0.0
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Video Processing History Model
|
|
3
|
+
|
|
4
|
+
Tracks all video correction operations (masking, frame removal, reprocessing).
|
|
5
|
+
Created as part of Phase 1.1: Video Correction API Endpoints.
|
|
6
|
+
"""
|
|
7
|
+
from django.db import models
|
|
8
|
+
from django.utils import timezone
|
|
9
|
+
from .video_file import VideoFile
|
|
10
|
+
|
|
11
|
+
class VideoProcessingHistory(models.Model):
|
|
12
|
+
"""
|
|
13
|
+
History of all video processing operations.
|
|
14
|
+
|
|
15
|
+
Stores configuration and results of masking, frame removal, and reprocessing
|
|
16
|
+
operations for audit trail and download access.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
# Operation Types
|
|
20
|
+
OPERATION_MASKING = 'mask_overlay'
|
|
21
|
+
OPERATION_FRAME_REMOVAL = 'frame_removal'
|
|
22
|
+
OPERATION_ANALYSIS = 'analysis'
|
|
23
|
+
OPERATION_REPROCESSING = 'reprocessing'
|
|
24
|
+
|
|
25
|
+
OPERATION_CHOICES = [
|
|
26
|
+
(OPERATION_MASKING, 'Mask Overlay'),
|
|
27
|
+
(OPERATION_FRAME_REMOVAL, 'Frame Removal'),
|
|
28
|
+
(OPERATION_ANALYSIS, 'Sensitivity Analysis'),
|
|
29
|
+
(OPERATION_REPROCESSING, 'Full Reprocessing'),
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
# Status Types
|
|
33
|
+
STATUS_PENDING = 'pending'
|
|
34
|
+
STATUS_RUNNING = 'running'
|
|
35
|
+
STATUS_SUCCESS = 'success'
|
|
36
|
+
STATUS_FAILURE = 'failure'
|
|
37
|
+
STATUS_CANCELLED = 'cancelled'
|
|
38
|
+
|
|
39
|
+
STATUS_CHOICES = [
|
|
40
|
+
(STATUS_PENDING, 'Pending'),
|
|
41
|
+
(STATUS_RUNNING, 'Running'),
|
|
42
|
+
(STATUS_SUCCESS, 'Success'),
|
|
43
|
+
(STATUS_FAILURE, 'Failure'),
|
|
44
|
+
(STATUS_CANCELLED, 'Cancelled'),
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
video = models.ForeignKey(
|
|
48
|
+
VideoFile,
|
|
49
|
+
on_delete=models.CASCADE,
|
|
50
|
+
related_name='processing_history',
|
|
51
|
+
help_text="Video file this operation was performed on"
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
operation = models.CharField(
|
|
55
|
+
max_length=50,
|
|
56
|
+
choices=OPERATION_CHOICES,
|
|
57
|
+
help_text="Type of processing operation"
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
status = models.CharField(
|
|
61
|
+
max_length=20,
|
|
62
|
+
choices=STATUS_CHOICES,
|
|
63
|
+
default=STATUS_PENDING,
|
|
64
|
+
help_text="Current status of the operation"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Configuration & Results
|
|
68
|
+
config = models.JSONField(
|
|
69
|
+
default=dict,
|
|
70
|
+
help_text="Operation configuration (mask settings, frame list, etc.)"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
output_file = models.CharField(
|
|
74
|
+
max_length=500,
|
|
75
|
+
blank=True,
|
|
76
|
+
help_text="Path to output file (relative to MEDIA_ROOT)"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
details = models.TextField(
|
|
80
|
+
blank=True,
|
|
81
|
+
help_text="Additional details or error messages"
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
# Celery Integration
|
|
85
|
+
task_id = models.CharField(
|
|
86
|
+
max_length=100,
|
|
87
|
+
blank=True,
|
|
88
|
+
help_text="Celery task ID for progress tracking"
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# Timestamps
|
|
92
|
+
created_at = models.DateTimeField(
|
|
93
|
+
auto_now_add=True,
|
|
94
|
+
help_text="When the operation was started"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
completed_at = models.DateTimeField(
|
|
98
|
+
null=True,
|
|
99
|
+
blank=True,
|
|
100
|
+
help_text="When the operation completed (success or failure)"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
class Meta:
|
|
104
|
+
db_table = 'video_processing_history'
|
|
105
|
+
verbose_name = 'Video Processing History'
|
|
106
|
+
verbose_name_plural = 'Video Processing Histories'
|
|
107
|
+
ordering = ['-created_at']
|
|
108
|
+
indexes = [
|
|
109
|
+
models.Index(fields=['video', '-created_at']),
|
|
110
|
+
models.Index(fields=['task_id']),
|
|
111
|
+
models.Index(fields=['status']),
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
def __str__(self):
|
|
115
|
+
return f"{self.get_operation_display()} on {self.video.uuid} - {self.get_status_display()}"
|
|
116
|
+
|
|
117
|
+
def mark_running(self, save=True):
|
|
118
|
+
"""Mark operation as running."""
|
|
119
|
+
self.status = self.STATUS_RUNNING
|
|
120
|
+
if save:
|
|
121
|
+
self.save(update_fields=['status'])
|
|
122
|
+
|
|
123
|
+
def mark_success(self, output_file=None, details=None, save=True):
|
|
124
|
+
"""Mark operation as successful."""
|
|
125
|
+
self.status = self.STATUS_SUCCESS
|
|
126
|
+
self.completed_at = timezone.now()
|
|
127
|
+
if output_file:
|
|
128
|
+
self.output_file = output_file
|
|
129
|
+
if details:
|
|
130
|
+
self.details = details
|
|
131
|
+
if save:
|
|
132
|
+
self.save(update_fields=['status', 'completed_at', 'output_file', 'details'])
|
|
133
|
+
|
|
134
|
+
def mark_failure(self, error_message, save=True):
|
|
135
|
+
"""Mark operation as failed."""
|
|
136
|
+
self.status = self.STATUS_FAILURE
|
|
137
|
+
self.completed_at = timezone.now()
|
|
138
|
+
self.details = error_message
|
|
139
|
+
if save:
|
|
140
|
+
self.save(update_fields=['status', 'completed_at', 'details'])
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
def duration(self):
|
|
144
|
+
"""Calculate operation duration if completed."""
|
|
145
|
+
if self.completed_at and self.created_at:
|
|
146
|
+
return (self.completed_at - self.created_at).total_seconds()
|
|
147
|
+
return None
|
|
148
|
+
|
|
149
|
+
@property
|
|
150
|
+
def is_complete(self) -> bool:
|
|
151
|
+
"""Check if operation is in a terminal state."""
|
|
152
|
+
return self.status in [self.STATUS_SUCCESS, self.STATUS_FAILURE, self.STATUS_CANCELLED]
|