endoreg-db 0.6.4__py3-none-any.whl → 0.8.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 +26 -26
- endoreg_db/api_urls.py +4 -0
- endoreg_db/apps.py +12 -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/env.py +101 -0
- endoreg_db/data/__init__.py +12 -0
- endoreg_db/data/ai_model/data.yaml +1 -1
- endoreg_db/data/ai_model_label/label/polyp_classification.yaml +52 -0
- endoreg_db/data/ai_model_label/label-set/data.yaml +20 -1
- endoreg_db/data/ai_model_label/label-set/polyp_classifications.yaml +25 -0
- endoreg_db/data/center/data.yaml +13 -12
- endoreg_db/data/center_shift/ukw.yaml +9 -0
- endoreg_db/data/db_summary.csv +58 -0
- endoreg_db/data/db_summary.xlsx +0 -0
- endoreg_db/data/disease/misc.yaml +1 -2
- endoreg_db/data/endoscopy_processor/data.yaml +3 -0
- endoreg_db/data/event/cardiology.yaml +0 -13
- endoreg_db/data/examination/examinations/data.yaml +14 -9
- endoreg_db/data/examination_indication/endoscopy.yaml +30 -30
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +11 -11
- 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 +3 -46
- 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_morphology_classification_choice → finding_classification_choice}/colon_lesion_circularity_default.yaml +0 -2
- 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_morphology_classification_choice → finding_classification_choice}/colon_lesion_nice.yaml +4 -7
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_paris.yaml +0 -8
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_planarity_default.yaml +6 -13
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +14 -0
- endoreg_db/data/{finding_morphology_classification_choice → finding_classification_choice}/colon_lesion_surface_intact_default.yaml +3 -6
- endoreg_db/data/{finding_location_classification_choice/colonoscopy.yaml → finding_classification_choice/colonoscopy_location.yaml} +11 -22
- 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_colonoscopy.yaml +8 -3
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +6 -6
- endoreg_db/data/finding_type/data.yaml +23 -10
- endoreg_db/data/gender/data.yaml +8 -1
- endoreg_db/data/information_source/annotation.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/misc.yaml +43 -0
- endoreg_db/data/medication/anticoagulation.yaml +5 -5
- endoreg_db/data/medication/tah.yaml +5 -5
- endoreg_db/data/medication_intake_time/base.yaml +4 -4
- endoreg_db/data/names_first/first_names.yaml +3 -0
- endoreg_db/data/pdf_type/data.yaml +26 -2
- 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/report_reader_flag/rkh-histology-generic.yaml +10 -0
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +5 -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 +6 -6
- endoreg_db/data/requirement/disease_classification_choice_cardiovascular.yaml +9 -6
- endoreg_db/data/requirement/disease_hepatology.yaml +1 -1
- endoreg_db/data/requirement/disease_misc.yaml +3 -3
- endoreg_db/data/requirement/disease_renal.yaml +18 -2
- endoreg_db/data/requirement/{colonoscopy_indications.yaml → endoscopy_bleeding_risk.yaml} +6 -3
- endoreg_db/data/requirement/event_cardiology.yaml +17 -17
- 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 +352 -31
- 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 +36 -35
- endoreg_db/data/requirement_operator/model_operators.yaml +13 -7
- 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 +42 -2
- endoreg_db/data/requirement_type/requirement_types.yaml +82 -0
- endoreg_db/data/shift/endoscopy.yaml +21 -0
- endoreg_db/data/shift_type/base.yaml +35 -0
- endoreg_db/data/tag/requirement_set_tags.yaml +11 -0
- endoreg_db/data/unit/concentration.yaml +23 -0
- endoreg_db/exceptions.py +19 -0
- endoreg_db/forms/patient_finding_intervention_form.py +4 -5
- endoreg_db/forms/patient_form.py +7 -6
- endoreg_db/forms/questionnaires/__init__.py +1 -1
- endoreg_db/forms/questionnaires/tto_questionnaire.py +19 -19
- endoreg_db/helpers/count_db.py +45 -0
- endoreg_db/helpers/data_loader.py +208 -0
- endoreg_db/helpers/default_objects.py +359 -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_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 +422 -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 +2 -7
- endoreg_db/management/commands/load_base_db_data.py +1 -0
- endoreg_db/management/commands/load_endoscope_data.py +2 -2
- endoreg_db/management/commands/load_examination_indication_data.py +2 -3
- endoreg_db/management/commands/load_finding_data.py +49 -92
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +0 -1
- endoreg_db/management/commands/load_information_source.py +13 -7
- endoreg_db/management/commands/load_name_data.py +37 -0
- endoreg_db/management/commands/load_qualification_data.py +59 -0
- endoreg_db/management/commands/load_requirement_data.py +30 -6
- endoreg_db/management/commands/load_shift_data.py +60 -0
- endoreg_db/management/commands/load_tag_data.py +57 -0
- endoreg_db/management/commands/register_ai_model.py +1 -1
- 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/migrations/0001_initial.py +625 -813
- endoreg_db/migrations/0002_add_video_correction_models.py +52 -0
- endoreg_db/models/__init__.py +270 -307
- endoreg_db/models/administration/__init__.py +116 -0
- endoreg_db/models/{ai_model → administration/ai}/__init__.py +6 -1
- 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 +6 -1
- 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}/case_template.py +3 -3
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule.py +3 -10
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_rule_value.py +2 -4
- endoreg_db/models/{case_template → administration/case/case_template}/case_template_type.py +1 -3
- endoreg_db/models/{center → administration/center}/__init__.py +3 -1
- endoreg_db/models/administration/center/center.py +61 -0
- endoreg_db/models/administration/center/center_product.py +64 -0
- endoreg_db/models/{center → administration/center}/center_resource.py +19 -3
- 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 +1 -1
- endoreg_db/models/{persons → administration/person/names}/last_name.py +2 -3
- 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/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/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 +9 -0
- endoreg_db/models/{product → administration/product}/reference_product.py +26 -11
- 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 +45 -74
- 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/{annotation → label}/video_segmentation_labelset.py +7 -0
- endoreg_db/models/media/__init__.py +14 -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 +608 -0
- endoreg_db/models/media/pdf/report_file.py +162 -0
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +77 -0
- endoreg_db/models/media/video/__init__.py +4 -0
- endoreg_db/models/media/video/create_from_file.py +336 -0
- endoreg_db/models/media/video/pipe_1.py +195 -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 +680 -0
- endoreg_db/models/media/video/video_file_ai.py +443 -0
- endoreg_db/models/media/video/video_file_anonymize.py +348 -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 +129 -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 +166 -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_meta.py +11 -0
- endoreg_db/models/media/video/video_file_segments.py +209 -0
- endoreg_db/models/medical/__init__.py +146 -0
- endoreg_db/models/{contraindication → medical/contraindication}/__init__.py +1 -5
- endoreg_db/models/{disease.py → medical/disease.py} +60 -52
- endoreg_db/models/{event.py → medical/event.py} +31 -54
- endoreg_db/models/{examination → medical/examination}/__init__.py +1 -1
- endoreg_db/models/medical/examination/examination.py +148 -0
- endoreg_db/models/{examination → medical/examination}/examination_indication.py +64 -35
- endoreg_db/models/{examination → medical/examination}/examination_time.py +0 -4
- endoreg_db/models/{examination → medical/examination}/examination_time_type.py +1 -8
- endoreg_db/models/{examination → medical/examination}/examination_type.py +1 -7
- 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/{finding → medical/finding}/finding_intervention.py +2 -10
- endoreg_db/models/medical/finding/finding_type.py +35 -0
- endoreg_db/models/medical/hardware/__init__.py +8 -0
- endoreg_db/models/{hardware → medical/hardware}/endoscope.py +28 -23
- endoreg_db/models/medical/laboratory/__init__.py +5 -0
- endoreg_db/models/medical/laboratory/lab_value.py +419 -0
- endoreg_db/models/{medication → medical/medication}/medication.py +1 -3
- endoreg_db/models/{medication → medical/medication}/medication_indication_type.py +8 -3
- endoreg_db/models/{medication → medical/medication}/medication_intake_time.py +21 -3
- endoreg_db/models/{medication → medical/medication}/medication_schedule.py +13 -5
- endoreg_db/models/{organ → medical/organ}/__init__.py +3 -6
- 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/{persons → medical}/patient/patient_examination_indication.py +21 -9
- endoreg_db/models/medical/patient/patient_finding.py +357 -0
- endoreg_db/models/medical/patient/patient_finding_classification.py +207 -0
- endoreg_db/models/{patient → medical/patient}/patient_finding_intervention.py +15 -1
- endoreg_db/models/medical/patient/patient_lab_sample.py +148 -0
- endoreg_db/models/{persons → medical}/patient/patient_lab_value.py +40 -15
- endoreg_db/models/medical/patient/patient_medication.py +104 -0
- endoreg_db/models/medical/patient/patient_medication_schedule.py +136 -0
- endoreg_db/models/{risk → medical/risk}/risk_type.py +0 -4
- endoreg_db/models/{data_file/metadata → metadata}/__init__.py +6 -0
- endoreg_db/models/metadata/frame_ocr_result.py +0 -0
- endoreg_db/models/metadata/model_meta.py +193 -0
- endoreg_db/models/metadata/model_meta_logic.py +236 -0
- endoreg_db/models/{data_file/metadata → metadata}/pdf_meta.py +28 -13
- endoreg_db/models/metadata/sensitive_meta.py +288 -0
- endoreg_db/models/metadata/sensitive_meta_logic.py +643 -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 +17 -0
- endoreg_db/models/other/distribution/date_value_distribution.py +0 -2
- endoreg_db/models/other/distribution/numeric_value_distribution.py +30 -2
- endoreg_db/models/{emission → other/emission}/emission_factor.py +15 -6
- endoreg_db/models/{persons → other}/gender.py +8 -3
- endoreg_db/models/other/information_source.py +159 -0
- endoreg_db/models/other/material.py +10 -2
- endoreg_db/models/other/resource.py +6 -2
- endoreg_db/models/other/tag.py +27 -0
- endoreg_db/models/other/transport_route.py +13 -2
- endoreg_db/models/{unit.py → other/unit.py} +16 -6
- endoreg_db/models/other/waste.py +10 -3
- endoreg_db/models/requirement/requirement.py +556 -114
- endoreg_db/models/requirement/requirement_evaluation/__init__.py +4 -132
- 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 +80 -87
- endoreg_db/models/requirement/requirement_operator.py +132 -14
- endoreg_db/models/requirement/requirement_set.py +181 -21
- endoreg_db/models/rule/__init__.py +13 -0
- endoreg_db/models/{rules → rule}/rule.py +6 -3
- endoreg_db/models/{rules → rule}/rule_attribute_dtype.py +0 -2
- endoreg_db/models/{rules → rule}/rule_type.py +0 -2
- endoreg_db/models/{rules → rule}/ruleset.py +0 -2
- 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/models/video_metadata.py +66 -0
- endoreg_db/models/video_processing.py +153 -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 -10
- endoreg_db/serializers/{raw_pdf_meta_validation.py → _old/raw_pdf_meta_validation.py} +3 -3
- endoreg_db/serializers/{raw_video_meta_validation.py → _old/raw_video_meta_validation.py} +18 -14
- 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 +66 -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/ollama_api_docs.py +1528 -0
- endoreg_db/services/pdf_import.py +993 -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 +915 -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/urls/__init__.py +72 -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 +32 -0
- endoreg_db/urls/patient.py +19 -0
- endoreg_db/urls/pdf.py +0 -0
- endoreg_db/urls/report.py +78 -0
- endoreg_db/urls/requirements.py +13 -0
- endoreg_db/urls/sensitive_meta.py +36 -0
- endoreg_db/urls/stats.py +46 -0
- endoreg_db/urls/upload.py +20 -0
- endoreg_db/urls/video.py +119 -0
- endoreg_db/urls.py +6 -283
- endoreg_db/utils/__init__.py +66 -57
- endoreg_db/utils/ai/__init__.py +9 -0
- endoreg_db/{models/ai_model/utils.py → utils/ai/get.py} +1 -4
- endoreg_db/{models/ai_model/lightning → utils/ai}/inference_dataset.py +0 -1
- endoreg_db/{models/ai_model/lightning → utils/ai}/multilabel_classification_net.py +14 -10
- endoreg_db/{models/ai_model/lightning → utils/ai}/postprocess.py +15 -5
- endoreg_db/utils/ai/predict.py +291 -0
- endoreg_db/{models/ai_model/lightning → utils/ai}/preprocess.py +1 -1
- endoreg_db/utils/calc_duration_seconds.py +24 -0
- endoreg_db/utils/case_generator/__init__.py +0 -0
- endoreg_db/utils/check_video_files.py +148 -0
- endoreg_db/utils/dataloader.py +50 -12
- endoreg_db/utils/dates.py +21 -0
- endoreg_db/utils/env.py +33 -0
- endoreg_db/utils/extract_specific_frames.py +72 -0
- endoreg_db/utils/file_operations.py +29 -1
- endoreg_db/utils/fix_video_path_direct.py +141 -0
- endoreg_db/utils/frame_anonymization_utils.py +463 -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 +2 -0
- endoreg_db/utils/paths.py +100 -82
- 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/db_config.py +1 -1
- 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/translation.py +27 -0
- endoreg_db/utils/validate_video_detailed.py +357 -0
- endoreg_db/utils/video/__init__.py +19 -6
- endoreg_db/utils/video/extract_frames.py +37 -70
- endoreg_db/utils/video/ffmpeg_wrapper.py +772 -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 +282 -2
- 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 +63 -0
- endoreg_db/views/auth/__init__.py +13 -0
- endoreg_db/views/{views.py → auth/keycloak.py} +19 -13
- 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 +9 -0
- endoreg_db/views/media/pdf_media.py +386 -0
- endoreg_db/views/media/video_media.py +272 -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/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 +151 -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 +72 -0
- endoreg_db/views/video/correction.py +672 -0
- endoreg_db/views/video/media/__init__.py +23 -0
- endoreg_db/views/video/media/task_status.py +49 -0
- endoreg_db/views/video/media/video_analyze.py +52 -0
- endoreg_db/views/video/media/video_apply_mask.py +48 -0
- endoreg_db/views/video/media/video_correction.py +21 -0
- endoreg_db/views/video/media/video_download_processed.py +58 -0
- endoreg_db/views/video/media/video_media.py +158 -0
- endoreg_db/views/video/media/video_meta.py +29 -0
- endoreg_db/views/video/media/video_processing_history.py +24 -0
- endoreg_db/views/video/media/video_remove_frames.py +48 -0
- endoreg_db/views/video/media/video_reprocess.py +40 -0
- endoreg_db/views/video/reimport.py +192 -0
- endoreg_db/views/video/segmentation.py +274 -0
- endoreg_db/views/{views_for_timeline.py → video/timeline.py} +3 -3
- endoreg_db/views/video/video_examination_viewset.py +329 -0
- endoreg_db/views/video/video_stream.py +188 -0
- endoreg_db-0.8.1.dist-info/METADATA +384 -0
- endoreg_db-0.8.1.dist-info/RECORD +789 -0
- endoreg_db/data/agl_service/data.yaml +0 -19
- endoreg_db/data/finding_location_classification/colonoscopy.yaml +0 -46
- endoreg_db/data/finding_morphology_classification/colonoscopy.yaml +0 -48
- endoreg_db/data/finding_morphology_classification_choice/colonoscopy_size.yaml +0 -57
- endoreg_db/management/commands/_load_model_template.py +0 -41
- endoreg_db/management/commands/delete_all.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/load_active_model_data.py +0 -45
- endoreg_db/management/commands/load_g_play_data.py +0 -113
- endoreg_db/management/commands/load_logging_data.py +0 -39
- endoreg_db/management/commands/load_lx_data.py +0 -64
- endoreg_db/management/commands/load_medication_indication_data.py +0 -63
- endoreg_db/management/commands/load_medication_indication_type_data.py +0 -41
- endoreg_db/management/commands/load_medication_intake_time_data.py +0 -41
- endoreg_db/management/commands/load_medication_schedule_data.py +0 -55
- endoreg_db/management/commands/load_network_data.py +0 -57
- endoreg_db/migrations/0002_alter_frame_image_alter_rawframe_image.py +0 -23
- endoreg_db/migrations/0003_alter_frame_image_alter_rawframe_image.py +0 -23
- endoreg_db/migrations/0004_alter_rawvideofile_file_alter_video_file.py +0 -25
- endoreg_db/migrations/0005_rawvideofile_frame_count_and_more.py +0 -33
- endoreg_db/migrations/0006_frame_extracted_rawframe_extracted.py +0 -23
- endoreg_db/migrations/0007_rename_pseudo_patient_video_patient_and_more.py +0 -24
- endoreg_db/migrations/0008_remove_reportfile_patient_examination_and_more.py +0 -48
- endoreg_db/migrations/0009_requirementoperator_requirementsettype_and_more.py +0 -154
- endoreg_db/models/ai_model/active_model.py +0 -9
- endoreg_db/models/ai_model/ai_model.py +0 -90
- endoreg_db/models/ai_model/lightning/__init__.py +0 -3
- endoreg_db/models/ai_model/lightning/predict.py +0 -172
- endoreg_db/models/ai_model/lightning/prediction_visualizer.py +0 -55
- endoreg_db/models/ai_model/lightning/run_visualizer.py +0 -21
- endoreg_db/models/ai_model/model_meta.py +0 -240
- endoreg_db/models/annotation/__init__.py +0 -32
- endoreg_db/models/annotation/anonymized_image_annotation.py +0 -115
- endoreg_db/models/annotation/binary_classification_annotation_task.py +0 -117
- endoreg_db/models/annotation/image_classification.py +0 -86
- endoreg_db/models/annotation/video_segmentation_annotation.py +0 -52
- endoreg_db/models/case/__init__.py +0 -1
- endoreg_db/models/case/case.py +0 -34
- endoreg_db/models/center/center.py +0 -51
- endoreg_db/models/center/center_product.py +0 -33
- endoreg_db/models/center/center_waste.py +0 -16
- endoreg_db/models/data_file/__init__.py +0 -39
- endoreg_db/models/data_file/base_classes/__init__.py +0 -7
- endoreg_db/models/data_file/base_classes/abstract_frame.py +0 -98
- endoreg_db/models/data_file/base_classes/abstract_pdf.py +0 -127
- endoreg_db/models/data_file/base_classes/abstract_video.py +0 -806
- endoreg_db/models/data_file/base_classes/frame_helpers.py +0 -17
- endoreg_db/models/data_file/base_classes/prepare_bulk_frames.py +0 -19
- endoreg_db/models/data_file/base_classes/utils.py +0 -58
- endoreg_db/models/data_file/frame.py +0 -29
- endoreg_db/models/data_file/import_classes/__init__.py +0 -18
- 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 -254
- endoreg_db/models/data_file/import_classes/raw_video.py +0 -290
- endoreg_db/models/data_file/metadata/sensitive_meta.py +0 -290
- endoreg_db/models/data_file/metadata/video_meta.py +0 -199
- endoreg_db/models/data_file/report_file.py +0 -56
- endoreg_db/models/data_file/video/__init__.py +0 -11
- endoreg_db/models/data_file/video/import_meta.py +0 -25
- endoreg_db/models/data_file/video/video.py +0 -196
- endoreg_db/models/data_file/video_segment.py +0 -214
- endoreg_db/models/examination/examination.py +0 -67
- endoreg_db/models/finding/__init__.py +0 -11
- endoreg_db/models/finding/finding.py +0 -75
- endoreg_db/models/finding/finding_location_classification.py +0 -94
- endoreg_db/models/finding/finding_morphology_classification.py +0 -89
- endoreg_db/models/finding/finding_type.py +0 -22
- endoreg_db/models/hardware/__init__.py +0 -2
- endoreg_db/models/information_source.py +0 -65
- endoreg_db/models/laboratory/__init__.py +0 -1
- endoreg_db/models/laboratory/lab_value.py +0 -162
- endoreg_db/models/logging/__init__.py +0 -11
- endoreg_db/models/logging/agl_service.py +0 -19
- endoreg_db/models/logging/base.py +0 -22
- endoreg_db/models/logging/log_type.py +0 -23
- endoreg_db/models/logging/network_device.py +0 -27
- endoreg_db/models/lx/__init__.py +0 -4
- endoreg_db/models/lx/client.py +0 -57
- endoreg_db/models/lx/identity.py +0 -34
- endoreg_db/models/lx/permission.py +0 -18
- endoreg_db/models/lx/user.py +0 -16
- endoreg_db/models/network/__init__.py +0 -9
- endoreg_db/models/network/agl_service.py +0 -38
- endoreg_db/models/network/network_device.py +0 -58
- endoreg_db/models/network/network_device_type.py +0 -23
- endoreg_db/models/other/distribution.py +0 -5
- endoreg_db/models/patient/__init__.py +0 -24
- endoreg_db/models/patient/patient_examination.py +0 -182
- endoreg_db/models/patient/patient_finding.py +0 -143
- endoreg_db/models/patient/patient_finding_location.py +0 -120
- endoreg_db/models/patient/patient_finding_morphology.py +0 -166
- endoreg_db/models/permissions/__init__.py +0 -44
- endoreg_db/models/persons/__init__.py +0 -34
- endoreg_db/models/persons/examiner/__init__.py +0 -2
- endoreg_db/models/persons/examiner/examiner.py +0 -60
- endoreg_db/models/persons/examiner/examiner_type.py +0 -2
- endoreg_db/models/persons/patient/__init__.py +0 -8
- endoreg_db/models/persons/patient/patient.py +0 -389
- endoreg_db/models/persons/patient/patient_disease.py +0 -22
- endoreg_db/models/persons/patient/patient_event.py +0 -52
- endoreg_db/models/persons/patient/patient_lab_sample.py +0 -108
- endoreg_db/models/persons/patient/patient_medication.py +0 -59
- endoreg_db/models/persons/patient/patient_medication_schedule.py +0 -88
- endoreg_db/models/persons/portal_user_information.py +0 -27
- endoreg_db/models/prediction/__init__.py +0 -8
- endoreg_db/models/prediction/image_classification.py +0 -51
- endoreg_db/models/prediction/video_prediction_meta.py +0 -306
- endoreg_db/models/product/product.py +0 -110
- endoreg_db/models/product/product_group.py +0 -27
- endoreg_db/models/product/product_material.py +0 -28
- endoreg_db/models/questionnaires/__init__.py +0 -114
- endoreg_db/models/quiz/__init__.py +0 -9
- endoreg_db/models/quiz/quiz_answer.py +0 -41
- endoreg_db/models/quiz/quiz_question.py +0 -54
- 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 -14
- endoreg_db/serializers/center.py +0 -11
- endoreg_db/serializers/examination.py +0 -33
- endoreg_db/serializers/frame.py +0 -9
- endoreg_db/serializers/hardware.py +0 -21
- endoreg_db/serializers/label.py +0 -22
- endoreg_db/serializers/patient.py +0 -33
- endoreg_db/serializers/prediction.py +0 -10
- endoreg_db/serializers/raw_pdf_anony_text_validation.py +0 -137
- endoreg_db/serializers/report_file.py +0 -7
- endoreg_db/serializers/video.py +0 -20
- endoreg_db/serializers/video_segmentation.py +0 -574
- endoreg_db/tests.py +0 -3
- endoreg_db/utils/legacy_ocr.py +0 -201
- endoreg_db/utils/video/transcode_videofile.py +0 -111
- endoreg_db/views/patient_views.py +0 -90
- endoreg_db/views/raw_pdf_anony_text_validation_views.py +0 -95
- endoreg_db/views/raw_pdf_meta_validation_views.py +0 -111
- endoreg_db/views/raw_video_meta_validation_views.py +0 -148
- endoreg_db/views/report_views.py +0 -96
- endoreg_db/views/video_segmentation_views.py +0 -166
- endoreg_db-0.6.4.dist-info/METADATA +0 -161
- endoreg_db-0.6.4.dist-info/RECORD +0 -470
- /endoreg_db/{case_generator/__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 → data/shift/m2.yaml} +0 -0
- /endoreg_db/{queries/get/video_import_meta.py → factories/__init__.py} +0 -0
- /endoreg_db/{queries/get/video_prediction_meta.py → helpers/__init__.py} +0 -0
- /endoreg_db/models/{case_template → administration/case/case_template}/__init__.py +0 -0
- /endoreg_db/models/{persons → administration/person}/person.py +0 -0
- /endoreg_db/models/{product → administration/product}/__init__.py +0 -0
- /endoreg_db/models/{report_reader → media/pdf/report_reader}/__init__.py +0 -0
- /endoreg_db/models/{report_reader → media/pdf/report_reader}/report_reader_flag.py +0 -0
- /endoreg_db/models/{hardware → medical/hardware}/endoscopy_processor.py +0 -0
- /endoreg_db/models/{medication → medical/medication}/__init__.py +0 -0
- /endoreg_db/models/{medication → medical/medication}/medication_indication.py +0 -0
- /endoreg_db/models/{risk → medical/risk}/__init__.py +0 -0
- /endoreg_db/models/{risk → medical/risk}/risk.py +0 -0
- /endoreg_db/models/{emission → other/emission}/__init__.py +0 -0
- /endoreg_db/models/{rules → rule}/rule_applicator.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/case_generator.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/lab_sample_factory.py +0 -0
- /endoreg_db/{case_generator → utils/case_generator}/utils.py +0 -0
- /endoreg_db/views/{csrf.py → misc/csrf.py} +0 -0
- {endoreg_db-0.6.4.dist-info → endoreg_db-0.8.1.dist-info}/WHEEL +0 -0
- {endoreg_db-0.6.4.dist-info → endoreg_db-0.8.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Video Media Management View (Phase 1.2)
|
|
3
|
+
|
|
4
|
+
Provides CRUD operations for video files including listing, detail retrieval,
|
|
5
|
+
and metadata management for the media management system.
|
|
6
|
+
|
|
7
|
+
This complements VideoStreamView which handles the actual video streaming.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
from django.http import Http404
|
|
12
|
+
from rest_framework import status
|
|
13
|
+
from rest_framework.response import Response
|
|
14
|
+
from rest_framework.views import APIView
|
|
15
|
+
from django.db.models import Q
|
|
16
|
+
|
|
17
|
+
from endoreg_db.models import VideoFile
|
|
18
|
+
from endoreg_db.serializers.video.video_file_list import VideoFileListSerializer
|
|
19
|
+
from endoreg_db.serializers.video.video_file_detail import VideoDetailSerializer
|
|
20
|
+
from endoreg_db.utils.permissions import EnvironmentAwarePermission
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class VideoMediaView(APIView):
|
|
26
|
+
"""
|
|
27
|
+
Video Media Management API for CRUD operations on video files.
|
|
28
|
+
|
|
29
|
+
Endpoints:
|
|
30
|
+
- GET /api/media/videos/ - List all videos with filtering
|
|
31
|
+
- GET /api/media/videos/{id}/ - Get video details
|
|
32
|
+
- PATCH /api/media/videos/{id}/ - Update video metadata (future)
|
|
33
|
+
- DELETE /api/media/videos/{id}/ - Delete video (future)
|
|
34
|
+
|
|
35
|
+
Query Parameters:
|
|
36
|
+
- status: Filter by processing status (not_started, processing, done, failed, validated)
|
|
37
|
+
- search: Search in filename
|
|
38
|
+
- limit: Limit results (default: 50)
|
|
39
|
+
- offset: Pagination offset
|
|
40
|
+
|
|
41
|
+
Examples:
|
|
42
|
+
- GET /api/media/videos/?status=done&search=exam
|
|
43
|
+
- GET /api/media/videos/123/
|
|
44
|
+
|
|
45
|
+
Phase 1.2 Implementation:
|
|
46
|
+
- List and detail views implemented
|
|
47
|
+
- Filtering and search functionality
|
|
48
|
+
- Pagination support
|
|
49
|
+
- Error handling with proper HTTP status codes
|
|
50
|
+
- Integration with existing serializers
|
|
51
|
+
"""
|
|
52
|
+
permission_classes = [EnvironmentAwarePermission]
|
|
53
|
+
|
|
54
|
+
def get(self, request, pk=None):
|
|
55
|
+
"""
|
|
56
|
+
Handle GET requests for video listing or detail retrieval.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
request: HTTP request object
|
|
60
|
+
pk: Optional video ID for detail view
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
Response: JSON response with video data or list
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
Http404: If specific video not found
|
|
67
|
+
"""
|
|
68
|
+
if pk is not None:
|
|
69
|
+
# Detail view
|
|
70
|
+
return self._get_video_detail(pk)
|
|
71
|
+
else:
|
|
72
|
+
# List view
|
|
73
|
+
return self._list_videos(request)
|
|
74
|
+
|
|
75
|
+
def _get_video_detail(self, pk):
|
|
76
|
+
"""
|
|
77
|
+
Get detailed information for a specific video.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
pk: Video primary key
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Response: JSON response with video details
|
|
84
|
+
|
|
85
|
+
Raises:
|
|
86
|
+
Http404: If video not found
|
|
87
|
+
"""
|
|
88
|
+
try:
|
|
89
|
+
# Validate video_id is numeric
|
|
90
|
+
try:
|
|
91
|
+
video_id_int = int(pk)
|
|
92
|
+
except (ValueError, TypeError):
|
|
93
|
+
raise Http404("Invalid video ID format")
|
|
94
|
+
|
|
95
|
+
# Fetch video with related data
|
|
96
|
+
video = VideoFile.objects.select_related(
|
|
97
|
+
'state', 'sensitive_meta'
|
|
98
|
+
).get(pk=video_id_int)
|
|
99
|
+
|
|
100
|
+
# Serialize with request context for URL generation
|
|
101
|
+
serializer = VideoDetailSerializer(video, context={'request': self.request})
|
|
102
|
+
|
|
103
|
+
return Response(serializer.data)
|
|
104
|
+
|
|
105
|
+
except VideoFile.DoesNotExist:
|
|
106
|
+
raise Http404(f"Video with ID {pk} not found")
|
|
107
|
+
|
|
108
|
+
except Exception as e:
|
|
109
|
+
logger.error(f"Unexpected error in video detail view for ID {pk}: {str(e)}")
|
|
110
|
+
return Response(
|
|
111
|
+
{"error": "Failed to retrieve video details"},
|
|
112
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
def _list_videos(self, request):
|
|
116
|
+
"""
|
|
117
|
+
List videos with filtering, search, and pagination.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
request: HTTP request with query parameters
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Response: JSON response with paginated video list
|
|
124
|
+
"""
|
|
125
|
+
try:
|
|
126
|
+
# Start with all videos
|
|
127
|
+
queryset = VideoFile.objects.select_related('state', 'sensitive_meta').all()
|
|
128
|
+
|
|
129
|
+
# Apply filters
|
|
130
|
+
queryset = self._apply_filters(queryset, request.query_params)
|
|
131
|
+
|
|
132
|
+
# Apply search
|
|
133
|
+
search = request.query_params.get('search', '').strip()
|
|
134
|
+
if search:
|
|
135
|
+
queryset = queryset.filter(
|
|
136
|
+
Q(original_file_name__icontains=search)
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# Order by upload date (newest first)
|
|
140
|
+
queryset = queryset.order_by('-uploaded_at')
|
|
141
|
+
|
|
142
|
+
# Apply pagination
|
|
143
|
+
limit = min(int(request.query_params.get('limit', 50)), 100)
|
|
144
|
+
offset = int(request.query_params.get('offset', 0))
|
|
145
|
+
|
|
146
|
+
total_count = queryset.count()
|
|
147
|
+
videos = queryset[offset:offset + limit]
|
|
148
|
+
|
|
149
|
+
# Serialize
|
|
150
|
+
serializer = VideoFileListSerializer(videos, many=True)
|
|
151
|
+
|
|
152
|
+
return Response({
|
|
153
|
+
"count": total_count,
|
|
154
|
+
"next": self._get_next_url(request, offset, limit, total_count),
|
|
155
|
+
"previous": self._get_previous_url(request, offset, limit),
|
|
156
|
+
"results": serializer.data
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
except ValueError as e:
|
|
160
|
+
return Response(
|
|
161
|
+
{"error": f"Invalid query parameter: {str(e)}"},
|
|
162
|
+
status=status.HTTP_400_BAD_REQUEST
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
except Exception as e:
|
|
166
|
+
logger.error(f"Unexpected error in video list view: {str(e)}")
|
|
167
|
+
return Response(
|
|
168
|
+
{"error": "Failed to retrieve video list"},
|
|
169
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
def _apply_filters(self, queryset, query_params):
|
|
173
|
+
"""
|
|
174
|
+
Apply status and other filters to video queryset.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
queryset: Base queryset to filter
|
|
178
|
+
query_params: Request query parameters
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
QuerySet: Filtered queryset
|
|
182
|
+
"""
|
|
183
|
+
status_filter = query_params.get('status', '').strip().lower()
|
|
184
|
+
|
|
185
|
+
if status_filter:
|
|
186
|
+
if status_filter == 'not_started':
|
|
187
|
+
# Videos without state or with not_started status
|
|
188
|
+
queryset = queryset.filter(
|
|
189
|
+
Q(state__isnull=True) |
|
|
190
|
+
Q(state__frames_extracted=False, state__sensitive_meta_processed=False)
|
|
191
|
+
)
|
|
192
|
+
elif status_filter == 'processing':
|
|
193
|
+
# Videos in any processing state
|
|
194
|
+
queryset = queryset.filter(
|
|
195
|
+
state__frames_extracted=True,
|
|
196
|
+
state__sensitive_meta_processed=False
|
|
197
|
+
)
|
|
198
|
+
elif status_filter == 'done':
|
|
199
|
+
# Videos with anonymization complete but not validated
|
|
200
|
+
queryset = queryset.filter(
|
|
201
|
+
state__anonymized=True,
|
|
202
|
+
sensitive_meta__is_verified=False
|
|
203
|
+
)
|
|
204
|
+
elif status_filter == 'validated':
|
|
205
|
+
# Videos with human validation complete
|
|
206
|
+
queryset = queryset.filter(
|
|
207
|
+
state__anonymized=True,
|
|
208
|
+
sensitive_meta__is_verified=True
|
|
209
|
+
)
|
|
210
|
+
elif status_filter == 'failed':
|
|
211
|
+
# Failed videos (this might need adjustment based on actual failure tracking)
|
|
212
|
+
queryset = queryset.filter(
|
|
213
|
+
state__isnull=False,
|
|
214
|
+
state__frames_extracted=False,
|
|
215
|
+
state__sensitive_meta_processed=False
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
return queryset
|
|
219
|
+
|
|
220
|
+
def _get_next_url(self, request, offset, limit, total_count):
|
|
221
|
+
"""Generate next page URL for pagination."""
|
|
222
|
+
if offset + limit >= total_count:
|
|
223
|
+
return None
|
|
224
|
+
|
|
225
|
+
next_offset = offset + limit
|
|
226
|
+
return self._build_paginated_url(request, next_offset, limit)
|
|
227
|
+
|
|
228
|
+
def _get_previous_url(self, request, offset, limit):
|
|
229
|
+
"""Generate previous page URL for pagination."""
|
|
230
|
+
if offset <= 0:
|
|
231
|
+
return None
|
|
232
|
+
|
|
233
|
+
prev_offset = max(0, offset - limit)
|
|
234
|
+
return self._build_paginated_url(request, prev_offset, limit)
|
|
235
|
+
|
|
236
|
+
def _build_paginated_url(self, request, offset, limit):
|
|
237
|
+
"""Build URL with pagination parameters."""
|
|
238
|
+
params = request.query_params.copy()
|
|
239
|
+
params['offset'] = offset
|
|
240
|
+
params['limit'] = limit
|
|
241
|
+
|
|
242
|
+
base_url = request.build_absolute_uri(request.path)
|
|
243
|
+
if params:
|
|
244
|
+
return f"{base_url}?{params.urlencode()}"
|
|
245
|
+
return base_url
|
|
246
|
+
|
|
247
|
+
# Future implementation placeholders
|
|
248
|
+
def patch(self, request, pk):
|
|
249
|
+
"""
|
|
250
|
+
Update video metadata (Phase 1.2+ future enhancement).
|
|
251
|
+
|
|
252
|
+
Currently returns 501 Not Implemented.
|
|
253
|
+
"""
|
|
254
|
+
return Response(
|
|
255
|
+
{"error": "Video metadata updates not yet implemented"},
|
|
256
|
+
status=status.HTTP_501_NOT_IMPLEMENTED
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
def delete(self, request, pk):
|
|
260
|
+
"""
|
|
261
|
+
Delete video file (Phase 1.2+ future enhancement).
|
|
262
|
+
|
|
263
|
+
Currently returns 501 Not Implemented.
|
|
264
|
+
Use /api/media-management/force-remove/{id}/ instead.
|
|
265
|
+
"""
|
|
266
|
+
return Response(
|
|
267
|
+
{
|
|
268
|
+
"error": "Video deletion not yet implemented",
|
|
269
|
+
"alternative": f"Use DELETE /api/media-management/force-remove/{pk}/ instead"
|
|
270
|
+
},
|
|
271
|
+
status=status.HTTP_501_NOT_IMPLEMENTED
|
|
272
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from .available_files_list import AvailableFilesListView
|
|
2
|
+
from .sensitive_meta_detail import SensitiveMetaDetailView
|
|
3
|
+
from .sensitive_meta_list import SensitiveMetaListView
|
|
4
|
+
from .sensitive_meta_verification import SensitiveMetaVerificationView
|
|
5
|
+
from .report_meta import (
|
|
6
|
+
ReportFileMetadataView,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"AvailableFilesListView",
|
|
11
|
+
"SensitiveMetaDetailView",
|
|
12
|
+
"SensitiveMetaListView",
|
|
13
|
+
"SensitiveMetaVerificationView",
|
|
14
|
+
"ReportFileMetadataView",
|
|
15
|
+
]
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
from endoreg_db.models import RawPdfFile, VideoFile
|
|
2
|
+
from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from rest_framework import status
|
|
6
|
+
from rest_framework.response import Response
|
|
7
|
+
from rest_framework.views import APIView
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
class AvailableFilesListView(APIView):
|
|
12
|
+
"""
|
|
13
|
+
API endpoint to list available PDFs and videos for anonymization selection.
|
|
14
|
+
|
|
15
|
+
GET: Returns lists of available PDF and video files with their metadata
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
permission_classes = DEBUG_PERMISSIONS
|
|
19
|
+
|
|
20
|
+
def _validate_pagination_params(self, request):
|
|
21
|
+
"""Validates and returns pagination parameters, raising ValueError on failure."""
|
|
22
|
+
try:
|
|
23
|
+
limit = int(request.query_params.get('limit', 50))
|
|
24
|
+
offset = int(request.query_params.get('offset', 0))
|
|
25
|
+
except (ValueError, TypeError):
|
|
26
|
+
raise ValueError("Invalid 'limit' or 'offset' parameter. Must be integers.")
|
|
27
|
+
|
|
28
|
+
if limit < 0 or offset < 0:
|
|
29
|
+
raise ValueError("'limit' and 'offset' must be non-negative.")
|
|
30
|
+
|
|
31
|
+
if limit > 100:
|
|
32
|
+
logger.warning(f"Client requested limit of {limit}, capping at 100.")
|
|
33
|
+
limit = 100
|
|
34
|
+
|
|
35
|
+
return limit, offset
|
|
36
|
+
|
|
37
|
+
def get(self, request):
|
|
38
|
+
"""
|
|
39
|
+
List available PDF and video files for anonymization selection.
|
|
40
|
+
|
|
41
|
+
Query Parameters:
|
|
42
|
+
- type: Filter by file type ('pdf' or 'video')
|
|
43
|
+
- status: Filter by anonymization status
|
|
44
|
+
- limit: Number of results to return (default 50, max 100)
|
|
45
|
+
- offset: Offset for pagination (default 0)
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
{
|
|
49
|
+
"pdfs": [...],
|
|
50
|
+
"videos": [...],
|
|
51
|
+
"total_pdfs": N,
|
|
52
|
+
"total_videos": N
|
|
53
|
+
}
|
|
54
|
+
"""
|
|
55
|
+
try:
|
|
56
|
+
limit, offset = self._validate_pagination_params(request)
|
|
57
|
+
file_type = request.query_params.get('type', 'all').lower()
|
|
58
|
+
except ValueError as e:
|
|
59
|
+
return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST)
|
|
60
|
+
|
|
61
|
+
try:
|
|
62
|
+
response_data = {}
|
|
63
|
+
|
|
64
|
+
# Get PDFs if requested
|
|
65
|
+
if file_type in ['all', 'pdf']:
|
|
66
|
+
pdf_queryset = RawPdfFile.objects.select_related('sensitive_meta').all()
|
|
67
|
+
total_pdfs = pdf_queryset.count()
|
|
68
|
+
paginated_pdfs = pdf_queryset[offset:offset + limit]
|
|
69
|
+
|
|
70
|
+
pdf_list = []
|
|
71
|
+
for pdf in paginated_pdfs:
|
|
72
|
+
# Safely handle missing file attribute
|
|
73
|
+
file_name = 'Unknown'
|
|
74
|
+
file_path = None
|
|
75
|
+
if hasattr(pdf, 'file') and pdf.file:
|
|
76
|
+
file_name = pdf.file.name.split('/')[-1]
|
|
77
|
+
file_path = pdf.file.name
|
|
78
|
+
pdf_data = {
|
|
79
|
+
'id': pdf.id,
|
|
80
|
+
'filename': file_name,
|
|
81
|
+
'file_path': file_path,
|
|
82
|
+
'sensitive_meta_id': pdf.sensitive_meta_id,
|
|
83
|
+
'anonymized_text': getattr(pdf, 'anonymized_text', None),
|
|
84
|
+
'created_at': pdf.date_created if hasattr(pdf, 'created_at') else None,
|
|
85
|
+
'patient_info': None
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# Add patient info if available
|
|
89
|
+
if pdf.sensitive_meta:
|
|
90
|
+
pdf_data['patient_info'] = {
|
|
91
|
+
'patient_first_name': pdf.sensitive_meta.patient_first_name,
|
|
92
|
+
'patient_last_name': pdf.sensitive_meta.patient_last_name,
|
|
93
|
+
'patient_dob': pdf.sensitive_meta.patient_dob,
|
|
94
|
+
'examination_date': pdf.sensitive_meta.examination_date,
|
|
95
|
+
'center_name': pdf.sensitive_meta.center.name if pdf.sensitive_meta.center else None
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
pdf_list.append(pdf_data)
|
|
99
|
+
|
|
100
|
+
response_data['pdfs'] = pdf_list
|
|
101
|
+
response_data['total_pdfs'] = total_pdfs
|
|
102
|
+
|
|
103
|
+
# Get Videos if requested
|
|
104
|
+
if file_type in ['all', 'video']:
|
|
105
|
+
video_queryset = VideoFile.objects.select_related('sensitive_meta').all()
|
|
106
|
+
total_videos = video_queryset.count()
|
|
107
|
+
paginated_videos = video_queryset[offset:offset + limit]
|
|
108
|
+
|
|
109
|
+
video_list = []
|
|
110
|
+
for video in paginated_videos:
|
|
111
|
+
# Safely handle missing raw_file attribute
|
|
112
|
+
file_name = 'Unknown'
|
|
113
|
+
file_path = None
|
|
114
|
+
if hasattr(video, 'raw_file') and video.raw_file:
|
|
115
|
+
file_name = video.raw_file.name.split('/')[-1]
|
|
116
|
+
file_path = video.raw_file.name
|
|
117
|
+
video_data = {
|
|
118
|
+
'id': video.id,
|
|
119
|
+
'filename': file_name,
|
|
120
|
+
'file_path': file_path,
|
|
121
|
+
'sensitive_meta_id': video.sensitive_meta_id,
|
|
122
|
+
'patient_info': None
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
# Add patient info if available
|
|
126
|
+
if video.sensitive_meta:
|
|
127
|
+
video_data['patient_info'] = {
|
|
128
|
+
'patient_first_name': video.sensitive_meta.patient_first_name,
|
|
129
|
+
'patient_last_name': video.sensitive_meta.patient_last_name,
|
|
130
|
+
'patient_dob': video.sensitive_meta.patient_dob,
|
|
131
|
+
'examination_date': video.sensitive_meta.examination_date,
|
|
132
|
+
'center_name': video.sensitive_meta.center.name if video.sensitive_meta.center else None
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
video_list.append(video_data)
|
|
136
|
+
|
|
137
|
+
response_data['videos'] = video_list
|
|
138
|
+
response_data['total_videos'] = total_videos
|
|
139
|
+
|
|
140
|
+
return Response(response_data)
|
|
141
|
+
except Exception as e:
|
|
142
|
+
logger.error(f"Error listing available files: {e}", exc_info=True)
|
|
143
|
+
return Response(
|
|
144
|
+
{"error": "An unexpected error occurred while fetching files."},
|
|
145
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
146
|
+
)
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from endoreg_db.models import RawPdfFile
|
|
2
|
+
|
|
3
|
+
from django.shortcuts import get_object_or_404
|
|
4
|
+
from rest_framework import status
|
|
5
|
+
from rest_framework.response import Response
|
|
6
|
+
from rest_framework.views import APIView
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
import logging
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
class ReportFileMetadataView(APIView):
|
|
13
|
+
"""
|
|
14
|
+
API-Endpunkt für Report-Datei-Metadaten
|
|
15
|
+
GET /api/reports/{report_id}/file-metadata/
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def get(self, _request, report_id):
|
|
19
|
+
try:
|
|
20
|
+
report = get_object_or_404(RawPdfFile, id=report_id)
|
|
21
|
+
|
|
22
|
+
if not report.file:
|
|
23
|
+
return Response(
|
|
24
|
+
{"error": "Keine Datei für diesen Report verfügbar"},
|
|
25
|
+
status=status.HTTP_404_NOT_FOUND
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
metadata = self._get_file_metadata(report)
|
|
29
|
+
return Response(metadata)
|
|
30
|
+
|
|
31
|
+
except (ValueError, TypeError) as e:
|
|
32
|
+
logger.error("Fehler beim Laden der Datei-Metadaten: %s", str(e))
|
|
33
|
+
return Response(
|
|
34
|
+
{"error": "Metadaten konnten nicht geladen werden"},
|
|
35
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
def _get_file_metadata(self, report):
|
|
39
|
+
"""Sammelt Datei-Metadaten"""
|
|
40
|
+
file_path = Path(report.file.name)
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
file_size = report.file.size
|
|
44
|
+
except OSError:
|
|
45
|
+
file_size = 0
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
'filename': file_path.name,
|
|
49
|
+
'file_type': file_path.suffix.lower().lstrip('.'),
|
|
50
|
+
'file_size': file_size,
|
|
51
|
+
'upload_date': report.created_at if hasattr(report, 'created_at') else None,
|
|
52
|
+
'last_modified': report.updated_at if hasattr(report, 'updated_at') else None
|
|
53
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
from endoreg_db.models import SensitiveMeta
|
|
2
|
+
from endoreg_db.serializers import SensitiveMetaDetailSerializer, SensitiveMetaUpdateSerializer
|
|
3
|
+
|
|
4
|
+
from django.db import transaction
|
|
5
|
+
from django.shortcuts import get_object_or_404
|
|
6
|
+
from rest_framework import status
|
|
7
|
+
from rest_framework.response import Response
|
|
8
|
+
from rest_framework.views import APIView
|
|
9
|
+
|
|
10
|
+
from endoreg_db.utils.permissions import DEBUG_PERMISSIONS
|
|
11
|
+
import logging
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
class SensitiveMetaDetailView(APIView):
|
|
16
|
+
"""
|
|
17
|
+
API endpoint to retrieve and update SensitiveMeta details with verification state.
|
|
18
|
+
|
|
19
|
+
GET: Returns detailed SensitiveMeta information for annotation/verification
|
|
20
|
+
PATCH: Updates SensitiveMeta fields including verification state
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
permission_classes = DEBUG_PERMISSIONS # Changed from IsAuthenticated for development
|
|
24
|
+
|
|
25
|
+
def get(self, request, sensitive_meta_id=None):
|
|
26
|
+
"""
|
|
27
|
+
Retrieve SensitiveMeta details for display and annotation.
|
|
28
|
+
|
|
29
|
+
Supports both URL parameter and query parameter access patterns:
|
|
30
|
+
- /api/pdf/sensitivemeta/123/ (URL parameter)
|
|
31
|
+
- /api/pdf/sensitivemeta/?id=123 (query parameter - for backward compatibility)
|
|
32
|
+
- /api/pdf/sensitivemeta/ (list all - returns empty list instead of 400)
|
|
33
|
+
|
|
34
|
+
Returns detailed information suitable for user verification.
|
|
35
|
+
"""
|
|
36
|
+
# Handle both URL parameter and query parameter patterns
|
|
37
|
+
if not sensitive_meta_id:
|
|
38
|
+
sensitive_meta_id = request.query_params.get('id')
|
|
39
|
+
|
|
40
|
+
# If no ID provided, return empty list instead of error
|
|
41
|
+
if not sensitive_meta_id:
|
|
42
|
+
return Response([], status=status.HTTP_200_OK)
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
# Convert to int if it's a string
|
|
46
|
+
sensitive_meta_id = int(sensitive_meta_id)
|
|
47
|
+
|
|
48
|
+
# Get the SensitiveMeta instance with related data
|
|
49
|
+
sensitive_meta = SensitiveMeta.objects.select_related(
|
|
50
|
+
'center',
|
|
51
|
+
'patient_gender',
|
|
52
|
+
'pseudo_patient',
|
|
53
|
+
'pseudo_examination'
|
|
54
|
+
).prefetch_related(
|
|
55
|
+
'examiners',
|
|
56
|
+
'state'
|
|
57
|
+
).get(id=sensitive_meta_id)
|
|
58
|
+
|
|
59
|
+
# Serialize for display
|
|
60
|
+
serializer = SensitiveMetaDetailSerializer(sensitive_meta)
|
|
61
|
+
|
|
62
|
+
# Return direct data to match anonymization store expectations
|
|
63
|
+
# Instead of wrapping in "sensitive_meta" key, return data directly
|
|
64
|
+
response_data = serializer.data
|
|
65
|
+
|
|
66
|
+
logger.info(f"Retrieved SensitiveMeta {sensitive_meta_id} for user {request.user}")
|
|
67
|
+
return Response(response_data, status=status.HTTP_200_OK)
|
|
68
|
+
|
|
69
|
+
except ValueError:
|
|
70
|
+
return Response(
|
|
71
|
+
{"error": "Invalid sensitive_meta_id format. Must be an integer."},
|
|
72
|
+
status=status.HTTP_400_BAD_REQUEST
|
|
73
|
+
)
|
|
74
|
+
except SensitiveMeta.DoesNotExist:
|
|
75
|
+
return Response(
|
|
76
|
+
{"error": f"SensitiveMeta with ID {sensitive_meta_id} not found"},
|
|
77
|
+
status=status.HTTP_404_NOT_FOUND
|
|
78
|
+
)
|
|
79
|
+
except Exception as e:
|
|
80
|
+
logger.error(f"Error retrieving SensitiveMeta {sensitive_meta_id}: {e}")
|
|
81
|
+
return Response(
|
|
82
|
+
{"error": "Internal server error occurred"},
|
|
83
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
@transaction.atomic
|
|
87
|
+
def patch(self, request, sensitive_meta_id=None):
|
|
88
|
+
"""
|
|
89
|
+
Update SensitiveMeta fields including verification state.
|
|
90
|
+
|
|
91
|
+
Accepts partial updates for any field in SensitiveMetaUpdateSerializer.
|
|
92
|
+
Special handling for verification state changes.
|
|
93
|
+
"""
|
|
94
|
+
if not sensitive_meta_id:
|
|
95
|
+
return Response(
|
|
96
|
+
{"error": "sensitive_meta_id is required"},
|
|
97
|
+
status=status.HTTP_400_BAD_REQUEST
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
try:
|
|
101
|
+
# Get the SensitiveMeta instance
|
|
102
|
+
sensitive_meta = get_object_or_404(SensitiveMeta, id=sensitive_meta_id)
|
|
103
|
+
|
|
104
|
+
# Validate and update using serializer
|
|
105
|
+
serializer = SensitiveMetaUpdateSerializer(
|
|
106
|
+
sensitive_meta,
|
|
107
|
+
data=request.data,
|
|
108
|
+
partial=True
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
if serializer.is_valid():
|
|
112
|
+
updated_instance = serializer.save()
|
|
113
|
+
|
|
114
|
+
# Return updated data using detail serializer
|
|
115
|
+
response_serializer = SensitiveMetaDetailSerializer(updated_instance)
|
|
116
|
+
|
|
117
|
+
response_data = {
|
|
118
|
+
"message": "SensitiveMeta updated successfully",
|
|
119
|
+
"sensitive_meta": response_serializer.data,
|
|
120
|
+
"updated_fields": list(request.data.keys())
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
logger.info(
|
|
124
|
+
f"Updated SensitiveMeta {sensitive_meta_id} by user {request.user}. "
|
|
125
|
+
f"Fields: {list(request.data.keys())}"
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
return Response(response_data, status=status.HTTP_200_OK)
|
|
129
|
+
else:
|
|
130
|
+
return Response(
|
|
131
|
+
{
|
|
132
|
+
"error": "Validation failed",
|
|
133
|
+
"details": serializer.errors
|
|
134
|
+
},
|
|
135
|
+
status=status.HTTP_400_BAD_REQUEST
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
except SensitiveMeta.DoesNotExist:
|
|
139
|
+
return Response(
|
|
140
|
+
{"error": f"SensitiveMeta with ID {sensitive_meta_id} not found"},
|
|
141
|
+
status=status.HTTP_404_NOT_FOUND
|
|
142
|
+
)
|
|
143
|
+
except Exception as e:
|
|
144
|
+
logger.error(f"Error updating SensitiveMeta {sensitive_meta_id}: {e}")
|
|
145
|
+
return Response(
|
|
146
|
+
{"error": "Internal server error occurred"},
|
|
147
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
148
|
+
)
|