endoreg-db 0.8.5.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/__init__.py +0 -0
- endoreg_db/admin.py +92 -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 +18 -0
- 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/__init__.py +0 -0
- endoreg_db/config/env.py +101 -0
- endoreg_db/data/__init__.py +144 -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 +91 -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/examination/examinations/data.yaml +72 -0
- endoreg_db/data/examination/time/data.yaml +48 -0
- endoreg_db/data/examination/time-type/data.yaml +8 -0
- endoreg_db/data/examination/type/data.yaml +17 -0
- 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 -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/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 -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 +11 -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 +19 -0
- endoreg_db/factories/__init__.py +0 -0
- endoreg_db/forms/__init__.py +5 -0
- 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 -0
- endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -0
- endoreg_db/forms/settings/__init__.py +8 -0
- endoreg_db/forms/unit.py +6 -0
- 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 -0
- endoreg_db/management/commands/load_ai_model_label_data.py +59 -0
- endoreg_db/management/commands/load_base_db_data.py +192 -0
- endoreg_db/management/commands/load_center_data.py +68 -0
- endoreg_db/management/commands/load_contraindication_data.py +41 -0
- endoreg_db/management/commands/load_disease_classification_choices_data.py +41 -0
- endoreg_db/management/commands/load_disease_classification_data.py +41 -0
- endoreg_db/management/commands/load_disease_data.py +62 -0
- endoreg_db/management/commands/load_distribution_data.py +66 -0
- endoreg_db/management/commands/load_endoscope_data.py +68 -0
- endoreg_db/management/commands/load_event_data.py +41 -0
- endoreg_db/management/commands/load_examination_data.py +75 -0
- 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 +44 -0
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +132 -0
- endoreg_db/management/commands/load_information_source.py +51 -0
- endoreg_db/management/commands/load_lab_value_data.py +50 -0
- endoreg_db/management/commands/load_medication_data.py +103 -0
- endoreg_db/management/commands/load_name_data.py +37 -0
- endoreg_db/management/commands/load_organ_data.py +43 -0
- endoreg_db/management/commands/load_pdf_type_data.py +61 -0
- endoreg_db/management/commands/load_profession_data.py +44 -0
- endoreg_db/management/commands/load_qualification_data.py +59 -0
- endoreg_db/management/commands/load_report_reader_flag_data.py +46 -0
- 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 +46 -0
- endoreg_db/management/commands/load_user_groups.py +28 -0
- endoreg_db/management/commands/register_ai_model.py +64 -0
- endoreg_db/management/commands/reset_celery_schedule.py +9 -0
- 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 -0
- endoreg_db/migrations/0002_add_video_correction_models.py +52 -0
- endoreg_db/migrations/0003_add_center_display_name.py +30 -0
- endoreg_db/migrations/__init__.py +0 -0
- endoreg_db/models/__init__.py +359 -0
- 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/administration/ai/model_type.py +41 -0
- endoreg_db/models/administration/case/__init__.py +19 -0
- endoreg_db/models/administration/case/case.py +114 -0
- endoreg_db/models/administration/case/case_template/__init__.py +15 -0
- endoreg_db/models/administration/case/case_template/case_template.py +125 -0
- endoreg_db/models/administration/case/case_template/case_template_rule.py +269 -0
- endoreg_db/models/administration/case/case_template/case_template_rule_value.py +86 -0
- endoreg_db/models/administration/case/case_template/case_template_type.py +26 -0
- endoreg_db/models/administration/center/__init__.py +13 -0
- 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/administration/person/names/first_name.py +18 -0
- endoreg_db/models/administration/person/names/last_name.py +19 -0
- endoreg_db/models/administration/person/patient/__init__.py +5 -0
- endoreg_db/models/administration/person/patient/patient.py +460 -0
- endoreg_db/models/administration/person/person.py +31 -0
- 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/administration/product/product_weight.py +47 -0
- endoreg_db/models/administration/product/reference_product.py +130 -0
- 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 -0
- 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 -0
- 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 +613 -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/media/pdf/report_reader/report_reader_flag.py +20 -0
- 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 +699 -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/medical/hardware/endoscopy_processor.py +182 -0
- 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/medical/patient/patient_lab_value.py +222 -0
- 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/metadata/pdf_meta.py +89 -0
- endoreg_db/models/metadata/sensitive_meta.py +288 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +730 -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 -0
- 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/other/gender.py +27 -0
- endoreg_db/models/other/information_source.py +159 -0
- endoreg_db/models/other/material.py +28 -0
- endoreg_db/models/other/resource.py +22 -0
- endoreg_db/models/other/tag.py +27 -0
- endoreg_db/models/other/transport_route.py +33 -0
- endoreg_db/models/other/unit.py +32 -0
- endoreg_db/models/other/waste.py +27 -0
- 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/rule/rule.py +27 -0
- endoreg_db/models/rule/rule_applicator.py +224 -0
- endoreg_db/models/rule/rule_attribute_dtype.py +17 -0
- endoreg_db/models/rule/rule_type.py +20 -0
- endoreg_db/models/rule/ruleset.py +17 -0
- 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 +5 -0
- endoreg_db/queries/annotations/__init__.py +3 -0
- endoreg_db/queries/annotations/legacy.py +158 -0
- endoreg_db/queries/sanity/__init_.py +0 -0
- 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 +147 -0
- 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 +152 -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/misc/vop_patient_data.py +120 -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/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 +241 -0
- endoreg_db/services/lookup_store.py +122 -0
- endoreg_db/services/pdf_import.py +1159 -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 +1258 -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 +70 -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 +44 -0
- endoreg_db/urls/media.py +226 -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 -0
- endoreg_db/utils/ai/__init__.py +9 -0
- endoreg_db/utils/ai/get.py +5 -0
- 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 +29 -0
- endoreg_db/utils/dataloader.py +175 -0
- 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 -0
- 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 -0
- 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 -0
- 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 -0
- 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 +272 -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 +386 -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 +11 -0
- endoreg_db/views/pdf/pdf_media.py +239 -0
- endoreg_db/views/pdf/pdf_stream_views.py +127 -0
- endoreg_db/views/pdf/reimport.py +161 -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 +483 -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 +61 -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 +329 -0
- endoreg_db/views/video/video_media.py +158 -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 -0
- endoreg_db-0.8.5.1.dist-info/METADATA +383 -0
- endoreg_db-0.8.5.1.dist-info/RECORD +794 -0
- endoreg_db-0.8.5.1.dist-info/WHEEL +4 -0
- endoreg_db-0.8.5.1.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
from django.db import transaction
|
|
2
|
+
from rest_framework import serializers
|
|
3
|
+
|
|
4
|
+
from endoreg_db.models import LabelVideoSegment, VideoPredictionMeta
|
|
5
|
+
from endoreg_db.serializers.label_video_segment import LabelVideoSegmentSerializer
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
class LabelSegmentUpdateSerializer(serializers.Serializer):
|
|
11
|
+
"""
|
|
12
|
+
Serializer for updating label segments.
|
|
13
|
+
|
|
14
|
+
- Ensures that the segments stored in the database match exactly with what is sent from the frontend.
|
|
15
|
+
- Updates existing segments if their `start_frame_number` matches but `end_frame_number` has changed.
|
|
16
|
+
- Inserts new segments if they are not already present in the database.
|
|
17
|
+
- Deletes extra segments from the database if they are no longer in the frontend data.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
video_id = serializers.IntegerField()
|
|
21
|
+
label_id = serializers.IntegerField()
|
|
22
|
+
segments = serializers.ListField(
|
|
23
|
+
child=serializers.DictField(
|
|
24
|
+
child=serializers.FloatField() # Ensure we handle float values
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
def validate(self, data):
|
|
29
|
+
"""
|
|
30
|
+
Validate that the input data contains a non-empty list of segments with valid frame numbers.
|
|
31
|
+
|
|
32
|
+
Raises a validation error if any segment is missing required fields or if a segment's start frame exceeds its end frame.
|
|
33
|
+
"""
|
|
34
|
+
if not data.get("segments"):
|
|
35
|
+
raise serializers.ValidationError("No segments provided.")
|
|
36
|
+
|
|
37
|
+
for segment in data["segments"]:
|
|
38
|
+
if "start_frame_number" not in segment or "end_frame_number" not in segment:
|
|
39
|
+
raise serializers.ValidationError(
|
|
40
|
+
"Each segment must have `start_frame_number` and `end_frame_number`."
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if segment["start_frame_number"] > segment["end_frame_number"]:
|
|
44
|
+
raise serializers.ValidationError(
|
|
45
|
+
"Start frame must be less than or equal to end frame."
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
return data
|
|
49
|
+
|
|
50
|
+
def save(self):
|
|
51
|
+
"""
|
|
52
|
+
Synchronizes label segments in the database to match the provided frontend data for a specific video and label.
|
|
53
|
+
|
|
54
|
+
Compares incoming segments to existing database entries, updating segments with changed end frames, creating new segments as needed, and deleting segments that are no longer present. All changes are performed within a transaction to ensure consistency. Raises a validation error if no prediction metadata exists for the specified video.
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
dict: A dictionary containing serialized updated segments, newly created segments, and the count of deleted segments.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
video_id = self.validated_data["video_id"]
|
|
61
|
+
label_id = self.validated_data["label_id"]
|
|
62
|
+
new_segments = self.validated_data["segments"] # Remove new_keys assignment
|
|
63
|
+
|
|
64
|
+
# Fetch the correct `prediction_meta_id` based on `video_id`
|
|
65
|
+
prediction_meta_entry = VideoPredictionMeta.objects.filter(
|
|
66
|
+
video_file_id=video_id # Changed from video_id to video_file_id
|
|
67
|
+
).first()
|
|
68
|
+
if not prediction_meta_entry:
|
|
69
|
+
raise serializers.ValidationError(
|
|
70
|
+
{"error": "No prediction metadata found for this video."}
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
prediction_meta_id = (
|
|
74
|
+
prediction_meta_entry.id
|
|
75
|
+
) # Get the correct prediction_meta_id
|
|
76
|
+
|
|
77
|
+
existing_segments = LabelVideoSegment.objects.filter(
|
|
78
|
+
video_file_id=video_id, label_id=label_id # FIXED: video_file_id instead of video_id
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Convert existing segments into a dictionary for quick lookup
|
|
82
|
+
# Key format: (start_frame_number, end_frame_number)
|
|
83
|
+
existing_segments_dict = {
|
|
84
|
+
(float(seg.start_frame_number), float(seg.end_frame_number)): seg
|
|
85
|
+
for seg in existing_segments
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# Prepare lists for batch processing
|
|
89
|
+
# Initialize sets to track updates and new entries
|
|
90
|
+
updated_segments = set()
|
|
91
|
+
new_entries = []
|
|
92
|
+
existing_keys = set()
|
|
93
|
+
new_keys = set()
|
|
94
|
+
|
|
95
|
+
# Iterate through the validated data to update or create label video segments
|
|
96
|
+
print(f" Before Update: Found {existing_segments.count()} existing segments.")
|
|
97
|
+
logger.debug(f"Before Update: Found %d existing segments.", existing_segments.count())
|
|
98
|
+
logger.debug(f"New Segments Received: %d", len(new_segments))
|
|
99
|
+
logger.debug(f"Using prediction_meta_id: %d", prediction_meta_id)
|
|
100
|
+
with transaction.atomic():
|
|
101
|
+
for segment in new_segments:
|
|
102
|
+
start_frame = float(segment["start_frame_number"])
|
|
103
|
+
end_frame = float(segment["end_frame_number"])
|
|
104
|
+
|
|
105
|
+
if (start_frame, end_frame) in existing_keys:
|
|
106
|
+
# If segment with exact start_frame and end_frame already exists, no change is needed
|
|
107
|
+
continue
|
|
108
|
+
else:
|
|
109
|
+
# Check if a segment exists with the same start_frame but different end_frame
|
|
110
|
+
existing_segment = LabelVideoSegment.objects.filter(
|
|
111
|
+
video_file_id=video_id, # Changed from video_id to video_file_id
|
|
112
|
+
label_id=label_id,
|
|
113
|
+
start_frame_number=start_frame,
|
|
114
|
+
).first()
|
|
115
|
+
|
|
116
|
+
if existing_segment:
|
|
117
|
+
# If a segment with the same_start_frame exists but the end_frame is different, update it
|
|
118
|
+
if float(existing_segment.end_frame_number) != end_frame:
|
|
119
|
+
existing_segment.end_frame_number = end_frame
|
|
120
|
+
existing_segment.save()
|
|
121
|
+
updated_segments.append(existing_segment)
|
|
122
|
+
else: # Added else block to create new segment if not existing
|
|
123
|
+
new_entries.append(
|
|
124
|
+
LabelVideoSegment(
|
|
125
|
+
video_file_id=video_id, # Changed from video_id to video_file_id
|
|
126
|
+
label_id=label_id,
|
|
127
|
+
start_frame_number=start_frame,
|
|
128
|
+
end_frame_number=end_frame,
|
|
129
|
+
prediction_meta_id=prediction_meta_id,
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
print(
|
|
133
|
+
f" Adding new segment: Start {start_frame} → End {end_frame}"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Delete segments that are no longer present in the frontend data
|
|
137
|
+
# Segments to delete are those in existing_keys but not in new_keys
|
|
138
|
+
keys_to_delete = existing_keys - set((float(s['start_frame_number']), float(s['end_frame_number'])) for s in new_segments)
|
|
139
|
+
segments_to_delete_ids = [existing_segments_dict[key].id for key in keys_to_delete]
|
|
140
|
+
|
|
141
|
+
if segments_to_delete_ids:
|
|
142
|
+
LabelVideoSegment.objects.filter(id__in=segments_to_delete_ids).delete()
|
|
143
|
+
deleted_count = len(segments_to_delete_ids)
|
|
144
|
+
else:
|
|
145
|
+
deleted_count = 0
|
|
146
|
+
|
|
147
|
+
# Insert new segments in bulk for efficiency
|
|
148
|
+
if new_entries:
|
|
149
|
+
LabelVideoSegment.objects.bulk_create(new_entries)
|
|
150
|
+
|
|
151
|
+
logger.debug(
|
|
152
|
+
"After Update: Updated %d segments, Added %d, Deleted %d",
|
|
153
|
+
len(updated_segments), len(new_entries), deleted_count
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
"updated_segments": LabelVideoSegmentSerializer(
|
|
159
|
+
updated_segments, many=True
|
|
160
|
+
).data,
|
|
161
|
+
"new_segments": LabelVideoSegmentSerializer(new_entries, many=True).data,
|
|
162
|
+
"deleted_segments": deleted_count,
|
|
163
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from .pdf_file_meta_extraction import PDFFileForMetaSerializer
|
|
2
|
+
from .report_meta import (
|
|
3
|
+
ReportMetaSerializer,
|
|
4
|
+
)
|
|
5
|
+
from .sensitive_meta_detail import SensitiveMetaDetailSerializer
|
|
6
|
+
from .sensitive_meta_update import SensitiveMetaUpdateSerializer
|
|
7
|
+
from .sensitive_meta_verification import SensitiveMetaVerificationSerializer
|
|
8
|
+
from .video_meta import (
|
|
9
|
+
VideoMetaSerializer,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"PDFFileForMetaSerializer",
|
|
14
|
+
"ReportMetaSerializer",
|
|
15
|
+
"SensitiveMetaDetailSerializer",
|
|
16
|
+
"SensitiveMetaUpdateSerializer",
|
|
17
|
+
"SensitiveMetaVerificationSerializer",
|
|
18
|
+
"VideoMetaSerializer",
|
|
19
|
+
]
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from rest_framework import serializers
|
|
3
|
+
from django.conf import settings
|
|
4
|
+
from ...models import RawPdfFile, SensitiveMeta
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PDFFileForMetaSerializer(serializers.ModelSerializer):
|
|
8
|
+
"""
|
|
9
|
+
Serializer to fetch PDF metadata along with linked `SensitiveMeta` details.
|
|
10
|
+
Implements validation and ensures Vue.js can process errors easily.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# Fetch patient details from `SensitiveMeta`
|
|
14
|
+
patient_first_name = serializers.CharField(source="sensitive_meta.patient_first_name", read_only=True)
|
|
15
|
+
patient_last_name = serializers.CharField(source="sensitive_meta.patient_last_name", read_only=True)
|
|
16
|
+
patient_dob = serializers.CharField(source="sensitive_meta.patient_dob", read_only=True)
|
|
17
|
+
examination_date = serializers.CharField(source="sensitive_meta.examination_date", read_only=True)
|
|
18
|
+
|
|
19
|
+
# PDF file URL where Vue.js can fetch the document
|
|
20
|
+
pdf_url = serializers.SerializerMethodField()
|
|
21
|
+
|
|
22
|
+
# Full absolute path of the PDF file
|
|
23
|
+
full_pdf_path = serializers.SerializerMethodField()
|
|
24
|
+
|
|
25
|
+
# Direct file path from the database
|
|
26
|
+
file = serializers.SerializerMethodField()
|
|
27
|
+
|
|
28
|
+
class Meta:
|
|
29
|
+
model = RawPdfFile
|
|
30
|
+
fields = ['id', 'file', 'pdf_url', 'full_pdf_path',
|
|
31
|
+
'sensitive_meta_id', 'patient_first_name',
|
|
32
|
+
'patient_last_name', 'patient_dob', 'examination_date']
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def get_next_pdf(last_id=None):
|
|
36
|
+
"""
|
|
37
|
+
Retrieves the first available PDF if `last_id` is NOT provided.
|
|
38
|
+
Otherwise, fetches the next available PDF where `id > last_id`.
|
|
39
|
+
"""
|
|
40
|
+
query_filter = {}
|
|
41
|
+
if last_id is not None:
|
|
42
|
+
try:
|
|
43
|
+
query_filter = {"id__gt": int(last_id)}
|
|
44
|
+
except ValueError:
|
|
45
|
+
# If last_id is not a valid integer, treat it as if no ID was provided.
|
|
46
|
+
# This prevents a crash and safely defaults to fetching the first PDF.
|
|
47
|
+
query_filter = {}
|
|
48
|
+
|
|
49
|
+
# Get the next available PDF
|
|
50
|
+
pdf_entry = RawPdfFile.objects.select_related("sensitive_meta").filter(**query_filter).order_by('id').first()
|
|
51
|
+
|
|
52
|
+
return pdf_entry # Returns a model instance or None
|
|
53
|
+
|
|
54
|
+
def get_pdf_url(self, obj):
|
|
55
|
+
"""
|
|
56
|
+
Generates an absolute URL for accessing the PDF associated with the given object.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
The full URL as a string if the file exists; otherwise, None.
|
|
60
|
+
"""
|
|
61
|
+
request = self.context.get('request')
|
|
62
|
+
print("---------------------here :",obj.file)
|
|
63
|
+
if request and obj.file:
|
|
64
|
+
return request.build_absolute_uri(f"/pdf/sensitivemeta/?id={obj.id}") # Constructs full API endpoint
|
|
65
|
+
return None # Return None if file is missing
|
|
66
|
+
|
|
67
|
+
def get_file(self, obj):
|
|
68
|
+
"""
|
|
69
|
+
Retrieves the relative file path of the PDF from the database.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
The relative file path as a string, or None if no file is linked.
|
|
73
|
+
"""
|
|
74
|
+
if not obj.file:
|
|
75
|
+
return None # No file linked
|
|
76
|
+
return str(obj.file.name).strip() # Ensures clean output
|
|
77
|
+
|
|
78
|
+
def get_full_pdf_path(self, obj):
|
|
79
|
+
"""
|
|
80
|
+
Constructs the full absolute file path using `settings.MEDIA_ROOT`.
|
|
81
|
+
"""
|
|
82
|
+
if not obj.file:
|
|
83
|
+
return None # No file linked
|
|
84
|
+
|
|
85
|
+
pdf_relative_path = str(obj.file.name)
|
|
86
|
+
|
|
87
|
+
full_path = Path(settings.MEDIA_ROOT) / pdf_relative_path
|
|
88
|
+
|
|
89
|
+
return str(full_path) if full_path.exists() else None # Returns path or None if file is missing
|
|
90
|
+
|
|
91
|
+
def validate(self, data):
|
|
92
|
+
"""
|
|
93
|
+
Validate input data to ensure a PDF file is provided and the referenced sensitive_meta_id exists.
|
|
94
|
+
|
|
95
|
+
Raises:
|
|
96
|
+
serializers.ValidationError: If the PDF file is missing or the sensitive_meta_id does not correspond to an existing SensitiveMeta record.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
dict: The validated input data if all checks pass.
|
|
100
|
+
"""
|
|
101
|
+
errors = {}
|
|
102
|
+
|
|
103
|
+
if 'file' in data and not data['file']:
|
|
104
|
+
errors['file'] = "A valid PDF file is required."
|
|
105
|
+
|
|
106
|
+
if 'sensitive_meta_id' in data and not SensitiveMeta.objects.filter(id=data['sensitive_meta_id']).exists():
|
|
107
|
+
errors['sensitive_meta_id'] = "The provided sensitive_meta_id does not exist."
|
|
108
|
+
|
|
109
|
+
if errors:
|
|
110
|
+
raise serializers.ValidationError(errors) # Returns structured error response
|
|
111
|
+
|
|
112
|
+
return data # Returns validated data
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from endoreg_db.models import SensitiveMeta
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from django.utils import timezone
|
|
5
|
+
from rest_framework import serializers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ReportMetaSerializer(serializers.ModelSerializer):
|
|
9
|
+
"""
|
|
10
|
+
Serializer für Report-Metadaten basierend auf SensitiveMeta
|
|
11
|
+
"""
|
|
12
|
+
# Füge fehlende Zeitstempel-Felder hinzu
|
|
13
|
+
created_at = serializers.SerializerMethodField()
|
|
14
|
+
updated_at = serializers.SerializerMethodField()
|
|
15
|
+
casenumber = serializers.CharField(source='case_number', allow_blank=True, allow_null=True)
|
|
16
|
+
|
|
17
|
+
class Meta:
|
|
18
|
+
model = SensitiveMeta
|
|
19
|
+
fields = [
|
|
20
|
+
'id', 'patient_first_name', 'patient_last_name',
|
|
21
|
+
'patient_gender', 'patient_dob', 'examination_date',
|
|
22
|
+
'casenumber', 'created_at', 'updated_at'
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
def get_created_at(self, obj):
|
|
26
|
+
"""
|
|
27
|
+
Retrieve the `created_at` timestamp from the SensitiveMeta instance, or return the current time if unavailable.
|
|
28
|
+
|
|
29
|
+
Parameters:
|
|
30
|
+
obj: The SensitiveMeta instance being serialized.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
datetime: The `created_at` timestamp, or the current time as a fallback.
|
|
34
|
+
"""
|
|
35
|
+
if hasattr(obj, 'created_at') and obj.created_at:
|
|
36
|
+
return obj.created_at
|
|
37
|
+
# Fallback wenn SensitiveMeta kein created_at hat
|
|
38
|
+
return timezone.now()
|
|
39
|
+
|
|
40
|
+
def get_updated_at(self, obj):
|
|
41
|
+
"""
|
|
42
|
+
Return the `updated_at` timestamp from the SensitiveMeta instance, or fall back to the `created_at` timestamp if `updated_at` is missing or null.
|
|
43
|
+
|
|
44
|
+
Parameters:
|
|
45
|
+
obj: The SensitiveMeta instance being serialized.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
A datetime representing when the instance was last updated, or created if no update timestamp is available.
|
|
49
|
+
"""
|
|
50
|
+
if hasattr(obj, 'updated_at') and obj.updated_at:
|
|
51
|
+
return obj.updated_at
|
|
52
|
+
# Fallback wenn SensitiveMeta kein updated_at hat
|
|
53
|
+
return self.get_created_at(obj)
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from ...models import SensitiveMeta
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
class SensitiveMetaDetailSerializer(serializers.ModelSerializer):
|
|
9
|
+
"""
|
|
10
|
+
Serializer for displaying SensitiveMeta details with verification state.
|
|
11
|
+
Includes all relevant fields for annotation and verification.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
# State verification fields
|
|
15
|
+
is_verified = serializers.SerializerMethodField()
|
|
16
|
+
dob_verified = serializers.SerializerMethodField()
|
|
17
|
+
names_verified = serializers.SerializerMethodField()
|
|
18
|
+
|
|
19
|
+
# Related fields for better display
|
|
20
|
+
center_name = serializers.CharField(source="center.name", read_only=True)
|
|
21
|
+
patient_gender_name = serializers.CharField(source="patient_gender.name", read_only=True)
|
|
22
|
+
|
|
23
|
+
# Examiner information
|
|
24
|
+
examiners_display = serializers.SerializerMethodField()
|
|
25
|
+
|
|
26
|
+
# Formatted dates for display
|
|
27
|
+
patient_dob_display = serializers.SerializerMethodField()
|
|
28
|
+
examination_date_display = serializers.SerializerMethodField()
|
|
29
|
+
|
|
30
|
+
# Hash displays (last 8 characters for security)
|
|
31
|
+
patient_hash_display = serializers.SerializerMethodField()
|
|
32
|
+
examination_hash_display = serializers.SerializerMethodField()
|
|
33
|
+
|
|
34
|
+
class Meta:
|
|
35
|
+
model = SensitiveMeta
|
|
36
|
+
fields = [
|
|
37
|
+
'id',
|
|
38
|
+
'patient_first_name',
|
|
39
|
+
'patient_last_name',
|
|
40
|
+
'patient_dob',
|
|
41
|
+
'patient_dob_display',
|
|
42
|
+
'examination_date',
|
|
43
|
+
'examination_date_display',
|
|
44
|
+
'center_name',
|
|
45
|
+
'patient_gender_name',
|
|
46
|
+
'endoscope_type',
|
|
47
|
+
'endoscope_sn',
|
|
48
|
+
'patient_hash_display',
|
|
49
|
+
'examination_hash_display',
|
|
50
|
+
'examiners_display',
|
|
51
|
+
'is_verified',
|
|
52
|
+
'dob_verified',
|
|
53
|
+
'names_verified',
|
|
54
|
+
]
|
|
55
|
+
read_only_fields = [
|
|
56
|
+
'id',
|
|
57
|
+
'patient_hash_display',
|
|
58
|
+
'examination_hash_display',
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
def get_is_verified(self, obj):
|
|
62
|
+
"""
|
|
63
|
+
Return the overall verification status of the given SensitiveMeta instance.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
bool: True if the instance is verified; False if the verification attribute is missing.
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
Exception: Propagates unexpected exceptions after logging.
|
|
70
|
+
"""
|
|
71
|
+
try:
|
|
72
|
+
return obj.is_verified
|
|
73
|
+
except AttributeError:
|
|
74
|
+
return False
|
|
75
|
+
except Exception as e:
|
|
76
|
+
logger.exception(f"Unexpected error in get_is_verified for SensitiveMeta {getattr(obj, 'pk', None)}: {e}")
|
|
77
|
+
raise
|
|
78
|
+
|
|
79
|
+
def get_dob_verified(self, obj):
|
|
80
|
+
"""
|
|
81
|
+
Return the date of birth verification status for the given object.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
bool: True if the date of birth is verified; otherwise, False if unavailable or on error.
|
|
85
|
+
"""
|
|
86
|
+
try:
|
|
87
|
+
return obj.state.dob_verified
|
|
88
|
+
except Exception:
|
|
89
|
+
return False
|
|
90
|
+
|
|
91
|
+
def get_names_verified(self, obj):
|
|
92
|
+
"""
|
|
93
|
+
Return whether the patient's names have been verified.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
bool: True if the names are verified; False if not verified or if an error occurs.
|
|
97
|
+
"""
|
|
98
|
+
try:
|
|
99
|
+
return obj.state.names_verified
|
|
100
|
+
except Exception:
|
|
101
|
+
return False
|
|
102
|
+
|
|
103
|
+
def get_examiners_display(self, obj):
|
|
104
|
+
"""
|
|
105
|
+
Return a list of examiner full names for the given SensitiveMeta instance.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
list[str]: List of examiner names in "First Last" format, or an empty list if unavailable.
|
|
109
|
+
"""
|
|
110
|
+
try:
|
|
111
|
+
if obj.pk:
|
|
112
|
+
examiners = obj.examiners.all()
|
|
113
|
+
return [f"{e.first_name} {e.last_name}" for e in examiners]
|
|
114
|
+
return []
|
|
115
|
+
except Exception as e:
|
|
116
|
+
logger.warning(f"Error getting examiners for SensitiveMeta {obj.pk}: {e}")
|
|
117
|
+
return []
|
|
118
|
+
|
|
119
|
+
def get_patient_dob_display(self, obj):
|
|
120
|
+
"""
|
|
121
|
+
Return the patient's date of birth formatted as "YYYY-MM-DD" for display.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
str or None: Formatted date string if available, otherwise None.
|
|
125
|
+
"""
|
|
126
|
+
if obj.patient_dob:
|
|
127
|
+
return obj.patient_dob.strftime("%Y-%m-%d")
|
|
128
|
+
return None
|
|
129
|
+
|
|
130
|
+
def get_examination_date_display(self, obj):
|
|
131
|
+
"""
|
|
132
|
+
Return the examination date formatted as "YYYY-MM-DD" for display.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
str or None: Formatted examination date string, or None if not set.
|
|
136
|
+
"""
|
|
137
|
+
if obj.examination_date:
|
|
138
|
+
return obj.examination_date.strftime("%Y-%m-%d")
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
def get_patient_hash_display(self, obj):
|
|
142
|
+
"""
|
|
143
|
+
Return the last eight characters of the patient's hash, prefixed with ellipsis, or None if not available.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
str or None: Truncated patient hash for display, or None if the hash is not set.
|
|
147
|
+
"""
|
|
148
|
+
if obj.patient_hash:
|
|
149
|
+
return f"...{obj.patient_hash[-8:]}"
|
|
150
|
+
return None
|
|
151
|
+
|
|
152
|
+
def get_examination_hash_display(self, obj):
|
|
153
|
+
"""
|
|
154
|
+
Return the last eight characters of the examination hash, prefixed with ellipsis, or None if not available.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
str or None: Truncated examination hash for display, or None if the hash is not set.
|
|
158
|
+
"""
|
|
159
|
+
if obj.examination_hash:
|
|
160
|
+
return f"...{obj.examination_hash[-8:]}"
|
|
161
|
+
return None
|
|
162
|
+
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
from rest_framework import serializers
|
|
2
|
+
from django.db import transaction
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from ...models import SensitiveMeta, Center, Gender
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger(__name__)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SensitiveMetaUpdateSerializer(serializers.ModelSerializer):
|
|
12
|
+
"""
|
|
13
|
+
Serializer for updating SensitiveMeta fields including verification state.
|
|
14
|
+
Handles partial updates and state management.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
# Verification state fields
|
|
18
|
+
dob_verified = serializers.BooleanField(required=False)
|
|
19
|
+
names_verified = serializers.BooleanField(required=False)
|
|
20
|
+
|
|
21
|
+
# Center can be updated by name
|
|
22
|
+
center_name = serializers.CharField(write_only=True, required=False)
|
|
23
|
+
|
|
24
|
+
# Gender can be updated by name
|
|
25
|
+
patient_gender_name = serializers.CharField(write_only=True, required=False)
|
|
26
|
+
|
|
27
|
+
class Meta:
|
|
28
|
+
model = SensitiveMeta
|
|
29
|
+
fields = [
|
|
30
|
+
'patient_first_name',
|
|
31
|
+
'patient_last_name',
|
|
32
|
+
'patient_dob',
|
|
33
|
+
'examination_date',
|
|
34
|
+
'center_name',
|
|
35
|
+
'patient_gender_name',
|
|
36
|
+
'endoscope_type',
|
|
37
|
+
'endoscope_sn',
|
|
38
|
+
'examiner_first_name',
|
|
39
|
+
'examiner_last_name',
|
|
40
|
+
'dob_verified',
|
|
41
|
+
'names_verified',
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
def validate_center_name(self, value):
|
|
45
|
+
"""
|
|
46
|
+
Validates that a center with the given natural key exists.
|
|
47
|
+
|
|
48
|
+
Raises a validation error if the specified center does not exist.
|
|
49
|
+
"""
|
|
50
|
+
if value:
|
|
51
|
+
try:
|
|
52
|
+
Center.objects.get_by_natural_key(value)
|
|
53
|
+
return value
|
|
54
|
+
except Center.DoesNotExist:
|
|
55
|
+
raise serializers.ValidationError(f"Center '{value}' does not exist.")
|
|
56
|
+
return value
|
|
57
|
+
|
|
58
|
+
def validate_patient_gender_name(self, value):
|
|
59
|
+
"""
|
|
60
|
+
Validates that a gender with the given name exists.
|
|
61
|
+
|
|
62
|
+
Raises a validation error if no matching Gender is found.
|
|
63
|
+
"""
|
|
64
|
+
if value:
|
|
65
|
+
try:
|
|
66
|
+
Gender.objects.get(name=value)
|
|
67
|
+
return value
|
|
68
|
+
except Gender.DoesNotExist:
|
|
69
|
+
raise serializers.ValidationError(f"Gender '{value}' does not exist.")
|
|
70
|
+
return value
|
|
71
|
+
|
|
72
|
+
def validate(self, data):
|
|
73
|
+
"""
|
|
74
|
+
Validate that patient first and last names, if provided, are not empty strings.
|
|
75
|
+
|
|
76
|
+
Raises a validation error if either `patient_first_name` or `patient_last_name` is present but empty.
|
|
77
|
+
"""
|
|
78
|
+
# Ensure names are not empty if provided
|
|
79
|
+
first_name = data.get('patient_first_name')
|
|
80
|
+
if first_name is not None and not first_name.strip():
|
|
81
|
+
raise serializers.ValidationError({
|
|
82
|
+
'patient_first_name': 'First name cannot be empty.'
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
last_name = data.get('patient_last_name')
|
|
86
|
+
if last_name is not None and not last_name.strip():
|
|
87
|
+
raise serializers.ValidationError({
|
|
88
|
+
'patient_last_name': 'Last name cannot be empty.'
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
return data
|
|
92
|
+
|
|
93
|
+
@transaction.atomic
|
|
94
|
+
def update(self, instance, validated_data):
|
|
95
|
+
"""
|
|
96
|
+
Updates a SensitiveMeta instance with provided data, including related center, gender, and verification state fields.
|
|
97
|
+
|
|
98
|
+
Handles assignment of related Center and Gender objects by name, updates model fields, and manages verification state flags (`dob_verified`, `names_verified`) in the associated state object if provided.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
SensitiveMeta: The updated SensitiveMeta instance.
|
|
102
|
+
"""
|
|
103
|
+
# Extract verification state data
|
|
104
|
+
dob_verified = validated_data.pop('dob_verified', None)
|
|
105
|
+
names_verified = validated_data.pop('names_verified', None)
|
|
106
|
+
|
|
107
|
+
# Extract and handle center update
|
|
108
|
+
center_name = validated_data.pop('center_name', None)
|
|
109
|
+
if center_name:
|
|
110
|
+
try:
|
|
111
|
+
center = Center.objects.get_by_natural_key(center_name)
|
|
112
|
+
instance.center = center
|
|
113
|
+
except Center.DoesNotExist:
|
|
114
|
+
logger.error(f"Center '{center_name}' not found during update")
|
|
115
|
+
raise serializers.ValidationError(f"Center '{center_name}' does not exist.")
|
|
116
|
+
|
|
117
|
+
# Extract and handle gender update
|
|
118
|
+
patient_gender_name = validated_data.pop('patient_gender_name', None)
|
|
119
|
+
if patient_gender_name:
|
|
120
|
+
try:
|
|
121
|
+
gender = Gender.objects.get(name=patient_gender_name)
|
|
122
|
+
instance.patient_gender = gender
|
|
123
|
+
except Gender.DoesNotExist:
|
|
124
|
+
logger.error(f"Gender '{patient_gender_name}' not found during update")
|
|
125
|
+
raise serializers.ValidationError(f"Gender '{patient_gender_name}' does not exist.")
|
|
126
|
+
|
|
127
|
+
# Update regular fields using the model's update_from_dict method
|
|
128
|
+
if validated_data:
|
|
129
|
+
instance.update_from_dict(validated_data)
|
|
130
|
+
|
|
131
|
+
# Update verification state if provided
|
|
132
|
+
if dob_verified is not None or names_verified is not None:
|
|
133
|
+
# Ensure state exists
|
|
134
|
+
state = instance.get_or_create_state()
|
|
135
|
+
|
|
136
|
+
if dob_verified is not None:
|
|
137
|
+
state.dob_verified = dob_verified
|
|
138
|
+
logger.info(f"Updated DOB verification for SensitiveMeta {instance.pk}: {dob_verified}")
|
|
139
|
+
|
|
140
|
+
if names_verified is not None:
|
|
141
|
+
state.names_verified = names_verified
|
|
142
|
+
logger.info(f"Updated names verification for SensitiveMeta {instance.pk}: {names_verified}")
|
|
143
|
+
|
|
144
|
+
state.save()
|
|
145
|
+
|
|
146
|
+
return instance
|
|
147
|
+
|
|
148
|
+
|