endoreg-db 0.8.6.1__py3-none-any.whl → 0.8.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of endoreg-db might be problematic. Click here for more details.
- endoreg_db/authz/auth.py +74 -0
- endoreg_db/authz/backends.py +168 -0
- endoreg_db/authz/management/commands/list_routes.py +18 -0
- endoreg_db/authz/middleware.py +83 -0
- endoreg_db/authz/permissions.py +127 -0
- endoreg_db/authz/policy.py +218 -0
- endoreg_db/authz/views_auth.py +66 -0
- endoreg_db/config/env.py +13 -8
- endoreg_db/data/__init__.py +8 -31
- endoreg_db/data/_examples/disease.yaml +55 -0
- endoreg_db/data/_examples/disease_classification.yaml +13 -0
- endoreg_db/data/_examples/disease_classification_choice.yaml +62 -0
- endoreg_db/data/_examples/event.yaml +64 -0
- endoreg_db/data/_examples/examination.yaml +72 -0
- endoreg_db/data/_examples/finding/anatomy_colon.yaml +128 -0
- endoreg_db/data/_examples/finding/colonoscopy.yaml +40 -0
- endoreg_db/data/_examples/finding/colonoscopy_bowel_prep.yaml +56 -0
- endoreg_db/data/_examples/finding/complication.yaml +16 -0
- endoreg_db/data/_examples/finding/data.yaml +105 -0
- endoreg_db/data/_examples/finding/examination_setting.yaml +16 -0
- endoreg_db/data/_examples/finding/medication_related.yaml +18 -0
- endoreg_db/data/_examples/finding/outcome.yaml +12 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_bowel_preparation.yaml +68 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_jnet.yaml +22 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_kudo.yaml +25 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_circularity.yaml +20 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_planarity.yaml +24 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_size.yaml +68 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_lesion_surface.yaml +20 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_location.yaml +80 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_lst.yaml +21 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_nice.yaml +20 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_paris.yaml +26 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_sano.yaml +22 -0
- endoreg_db/data/_examples/finding_classification/colonoscopy_summary.yaml +53 -0
- endoreg_db/data/_examples/finding_classification/complication_generic.yaml +25 -0
- endoreg_db/data/_examples/finding_classification/examination_setting_generic.yaml +40 -0
- endoreg_db/data/_examples/finding_classification/histology_colo.yaml +51 -0
- endoreg_db/data/_examples/finding_classification/intervention_required.yaml +26 -0
- endoreg_db/data/_examples/finding_classification/medication_related.yaml +23 -0
- endoreg_db/data/_examples/finding_classification/visualized.yaml +33 -0
- endoreg_db/data/_examples/finding_classification_choice/bowel_preparation.yaml +78 -0
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_circularity_default.yaml +32 -0
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_jnet.yaml +15 -0
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_kudo.yaml +23 -0
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_lst.yaml +15 -0
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_nice.yaml +17 -0
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_paris.yaml +57 -0
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_planarity_default.yaml +49 -0
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_sano.yaml +14 -0
- endoreg_db/data/_examples/finding_classification_choice/colon_lesion_surface_intact_default.yaml +36 -0
- endoreg_db/data/_examples/finding_classification_choice/colonoscopy_location.yaml +229 -0
- endoreg_db/data/_examples/finding_classification_choice/colonoscopy_not_complete_reason.yaml +19 -0
- endoreg_db/data/_examples/finding_classification_choice/colonoscopy_size.yaml +82 -0
- endoreg_db/data/_examples/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +15 -0
- endoreg_db/data/_examples/finding_classification_choice/complication_generic_types.yaml +15 -0
- endoreg_db/data/_examples/finding_classification_choice/examination_setting_generic_types.yaml +15 -0
- endoreg_db/data/_examples/finding_classification_choice/histology.yaml +24 -0
- endoreg_db/data/_examples/finding_classification_choice/histology_polyp.yaml +20 -0
- endoreg_db/data/_examples/finding_classification_choice/outcome.yaml +19 -0
- endoreg_db/data/_examples/finding_classification_choice/yes_no_na.yaml +11 -0
- endoreg_db/data/_examples/finding_classification_type/colonoscopy_basic.yaml +48 -0
- endoreg_db/data/_examples/finding_intervention/endoscopy.yaml +43 -0
- endoreg_db/data/_examples/finding_intervention/endoscopy_colonoscopy.yaml +168 -0
- endoreg_db/data/_examples/finding_intervention/endoscopy_egd.yaml +128 -0
- endoreg_db/data/_examples/finding_intervention/endoscopy_ercp.yaml +32 -0
- endoreg_db/data/_examples/finding_intervention/endoscopy_eus_lower.yaml +9 -0
- endoreg_db/data/_examples/finding_intervention/endoscopy_eus_upper.yaml +36 -0
- endoreg_db/data/_examples/finding_intervention_type/endoscopy.yaml +15 -0
- endoreg_db/data/_examples/finding_type/data.yaml +43 -0
- endoreg_db/data/_examples/requirement/age.yaml +26 -0
- endoreg_db/data/_examples/requirement/colonoscopy_baseline_austria.yaml +45 -0
- endoreg_db/data/_examples/requirement/disease_cardiovascular.yaml +79 -0
- endoreg_db/data/_examples/requirement/disease_classification_choice_cardiovascular.yaml +41 -0
- endoreg_db/data/_examples/requirement/disease_hepatology.yaml +12 -0
- endoreg_db/data/_examples/requirement/disease_misc.yaml +12 -0
- endoreg_db/data/_examples/requirement/disease_renal.yaml +96 -0
- endoreg_db/data/_examples/requirement/endoscopy_bleeding_risk.yaml +59 -0
- endoreg_db/data/_examples/requirement/event_cardiology.yaml +251 -0
- endoreg_db/data/_examples/requirement/event_requirements.yaml +145 -0
- endoreg_db/data/_examples/requirement/finding_colon_polyp.yaml +50 -0
- endoreg_db/data/_examples/requirement/gender.yaml +25 -0
- endoreg_db/data/_examples/requirement/lab_value.yaml +441 -0
- endoreg_db/data/_examples/requirement/medication.yaml +93 -0
- endoreg_db/data/_examples/requirement_operator/age.yaml +13 -0
- endoreg_db/data/_examples/requirement_operator/lab_operators.yaml +129 -0
- endoreg_db/data/_examples/requirement_operator/model_operators.yaml +96 -0
- endoreg_db/data/_examples/requirement_set/01_endoscopy_generic.yaml +48 -0
- endoreg_db/data/_examples/requirement_set/colonoscopy_austria_screening.yaml +57 -0
- endoreg_db/data/_examples/yaml_examples.xlsx +0 -0
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +4 -3
- endoreg_db/data/event_classification/data.yaml +4 -0
- endoreg_db/data/event_classification_choice/data.yaml +9 -0
- endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +43 -70
- endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +22 -52
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +31 -62
- endoreg_db/data/finding_classification/histology_colo.yaml +28 -36
- endoreg_db/data/requirement/colon_polyp_intervention.yaml +49 -0
- endoreg_db/data/requirement/coloreg_colon_polyp.yaml +49 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +31 -12
- endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
- endoreg_db/data/requirement_set/02_endoscopy_bleeding_risk.yaml +46 -0
- endoreg_db/data/requirement_set/90_coloreg.yaml +178 -0
- endoreg_db/data/requirement_set/_old_ +109 -0
- endoreg_db/data/requirement_set_type/data.yaml +21 -0
- endoreg_db/data/setup_config.yaml +4 -4
- endoreg_db/data/tag/requirement_set_tags.yaml +21 -0
- endoreg_db/exceptions.py +5 -2
- endoreg_db/helpers/data_loader.py +1 -1
- endoreg_db/management/commands/create_model_meta_from_huggingface.py +21 -10
- endoreg_db/management/commands/create_multilabel_model_meta.py +299 -129
- endoreg_db/management/commands/import_video.py +9 -10
- endoreg_db/management/commands/import_video_with_classification.py +1 -1
- endoreg_db/management/commands/init_default_ai_model.py +1 -1
- endoreg_db/management/commands/list_routes.py +18 -0
- endoreg_db/management/commands/load_center_data.py +12 -12
- endoreg_db/management/commands/load_requirement_data.py +60 -31
- endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
- endoreg_db/management/commands/setup_endoreg_db.py +3 -3
- endoreg_db/management/commands/storage_management.py +271 -203
- endoreg_db/migrations/0001_initial.py +1799 -1300
- endoreg_db/migrations/0002_requirementset_depends_on.py +18 -0
- endoreg_db/migrations/_old/0001_initial.py +1857 -0
- endoreg_db/migrations/_old/0004_employee_city_employee_post_code_employee_street_and_more.py +68 -0
- endoreg_db/migrations/_old/0004_remove_casetemplate_rules_and_more.py +77 -0
- endoreg_db/migrations/_old/0005_merge_20251111_1003.py +14 -0
- endoreg_db/migrations/_old/0006_sensitivemeta_anonymized_text_and_more.py +68 -0
- endoreg_db/migrations/_old/0007_remove_rule_attribute_dtype_remove_rule_rule_type_and_more.py +89 -0
- endoreg_db/migrations/_old/0008_remove_event_event_classification_and_more.py +27 -0
- endoreg_db/migrations/_old/0009_alter_modelmeta_options_and_more.py +21 -0
- endoreg_db/models/__init__.py +78 -123
- endoreg_db/models/administration/__init__.py +21 -42
- endoreg_db/models/administration/ai/active_model.py +2 -2
- endoreg_db/models/administration/ai/ai_model.py +7 -6
- endoreg_db/models/administration/case/__init__.py +1 -15
- endoreg_db/models/administration/case/case.py +3 -3
- endoreg_db/models/administration/case/case_template/__init__.py +2 -14
- endoreg_db/models/administration/case/case_template/case_template.py +2 -124
- endoreg_db/models/administration/case/case_template/case_template_rule.py +2 -268
- endoreg_db/models/administration/case/case_template/case_template_rule_value.py +2 -85
- endoreg_db/models/administration/case/case_template/case_template_type.py +2 -25
- endoreg_db/models/administration/center/center.py +33 -19
- endoreg_db/models/administration/center/center_product.py +12 -9
- endoreg_db/models/administration/center/center_resource.py +25 -19
- endoreg_db/models/administration/center/center_shift.py +21 -17
- endoreg_db/models/administration/center/center_waste.py +16 -8
- endoreg_db/models/administration/person/__init__.py +2 -0
- endoreg_db/models/administration/person/employee/employee.py +10 -5
- endoreg_db/models/administration/person/employee/employee_qualification.py +9 -4
- endoreg_db/models/administration/person/employee/employee_type.py +12 -6
- endoreg_db/models/administration/person/examiner/examiner.py +13 -11
- endoreg_db/models/administration/person/patient/__init__.py +2 -0
- endoreg_db/models/administration/person/patient/patient.py +103 -100
- endoreg_db/models/administration/person/patient/patient_external_id.py +37 -0
- endoreg_db/models/administration/person/person.py +4 -0
- endoreg_db/models/administration/person/profession/__init__.py +8 -4
- endoreg_db/models/administration/person/user/portal_user_information.py +11 -7
- endoreg_db/models/administration/product/product.py +20 -15
- endoreg_db/models/administration/product/product_material.py +17 -18
- endoreg_db/models/administration/product/product_weight.py +12 -8
- endoreg_db/models/administration/product/reference_product.py +23 -55
- endoreg_db/models/administration/qualification/qualification.py +7 -3
- endoreg_db/models/administration/qualification/qualification_type.py +7 -3
- endoreg_db/models/administration/shift/scheduled_days.py +8 -5
- endoreg_db/models/administration/shift/shift.py +16 -12
- endoreg_db/models/administration/shift/shift_type.py +23 -31
- endoreg_db/models/label/__init__.py +7 -8
- endoreg_db/models/label/annotation/image_classification.py +10 -9
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +8 -5
- endoreg_db/models/label/label.py +15 -15
- endoreg_db/models/label/label_set.py +19 -6
- endoreg_db/models/label/label_type.py +1 -1
- endoreg_db/models/label/label_video_segment/_create_from_video.py +5 -8
- endoreg_db/models/label/label_video_segment/label_video_segment.py +76 -102
- endoreg_db/models/label/video_segmentation_label.py +4 -0
- endoreg_db/models/label/video_segmentation_labelset.py +4 -3
- endoreg_db/models/media/frame/frame.py +22 -22
- endoreg_db/models/media/pdf/raw_pdf.py +110 -182
- endoreg_db/models/media/pdf/report_file.py +25 -29
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +30 -46
- endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
- endoreg_db/models/media/video/__init__.py +1 -0
- endoreg_db/models/media/video/create_from_file.py +48 -56
- endoreg_db/models/media/video/pipe_2.py +8 -9
- endoreg_db/models/media/video/video_file.py +150 -108
- endoreg_db/models/media/video/video_file_ai.py +288 -74
- endoreg_db/models/media/video/video_file_anonymize.py +38 -38
- endoreg_db/models/media/video/video_file_frames/__init__.py +3 -1
- endoreg_db/models/media/video/video_file_frames/_bulk_create_frames.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_create_frame_object.py +7 -9
- endoreg_db/models/media/video/video_file_frames/_delete_frames.py +9 -8
- endoreg_db/models/media/video/video_file_frames/_extract_frames.py +38 -45
- endoreg_db/models/media/video/video_file_frames/_get_frame.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_get_frame_number.py +4 -18
- endoreg_db/models/media/video/video_file_frames/_get_frame_path.py +4 -3
- endoreg_db/models/media/video/video_file_frames/_get_frame_paths.py +7 -6
- endoreg_db/models/media/video/video_file_frames/_get_frame_range.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_get_frames.py +6 -8
- endoreg_db/models/media/video/video_file_frames/_initialize_frames.py +15 -25
- endoreg_db/models/media/video/video_file_frames/_manage_frame_range.py +26 -23
- endoreg_db/models/media/video/video_file_frames/_mark_frames_extracted_status.py +23 -14
- endoreg_db/models/media/video/video_file_io.py +109 -62
- endoreg_db/models/media/video/video_file_meta/get_crop_template.py +3 -3
- endoreg_db/models/media/video/video_file_meta/get_endo_roi.py +5 -3
- endoreg_db/models/media/video/video_file_meta/get_fps.py +37 -34
- endoreg_db/models/media/video/video_file_meta/initialize_video_specs.py +19 -25
- endoreg_db/models/media/video/video_file_meta/text_meta.py +41 -38
- endoreg_db/models/media/video/video_file_meta/video_meta.py +14 -7
- endoreg_db/models/media/video/video_file_segments.py +24 -17
- endoreg_db/models/media/video/video_metadata.py +19 -35
- endoreg_db/models/media/video/video_processing.py +96 -95
- endoreg_db/models/medical/contraindication/__init__.py +13 -3
- endoreg_db/models/medical/disease.py +22 -16
- endoreg_db/models/medical/event.py +31 -18
- endoreg_db/models/medical/examination/__init__.py +13 -6
- endoreg_db/models/medical/examination/examination.py +17 -18
- endoreg_db/models/medical/examination/examination_indication.py +26 -25
- endoreg_db/models/medical/examination/examination_time.py +16 -6
- endoreg_db/models/medical/examination/examination_time_type.py +9 -6
- endoreg_db/models/medical/examination/examination_type.py +3 -4
- endoreg_db/models/medical/finding/finding.py +38 -39
- endoreg_db/models/medical/finding/finding_classification.py +37 -48
- endoreg_db/models/medical/finding/finding_intervention.py +27 -22
- endoreg_db/models/medical/finding/finding_type.py +13 -12
- endoreg_db/models/medical/hardware/endoscope.py +20 -26
- endoreg_db/models/medical/hardware/endoscopy_processor.py +2 -2
- endoreg_db/models/medical/laboratory/lab_value.py +62 -91
- endoreg_db/models/medical/medication/medication.py +22 -10
- endoreg_db/models/medical/medication/medication_indication.py +29 -3
- endoreg_db/models/medical/medication/medication_indication_type.py +25 -14
- endoreg_db/models/medical/medication/medication_intake_time.py +31 -19
- endoreg_db/models/medical/medication/medication_schedule.py +27 -16
- endoreg_db/models/medical/organ/__init__.py +15 -12
- endoreg_db/models/medical/patient/medication_examples.py +1 -5
- endoreg_db/models/medical/patient/patient_disease.py +20 -23
- endoreg_db/models/medical/patient/patient_event.py +19 -22
- endoreg_db/models/medical/patient/patient_examination.py +48 -54
- endoreg_db/models/medical/patient/patient_examination_indication.py +16 -14
- endoreg_db/models/medical/patient/patient_finding.py +122 -139
- endoreg_db/models/medical/patient/patient_finding_classification.py +44 -49
- endoreg_db/models/medical/patient/patient_finding_intervention.py +8 -19
- endoreg_db/models/medical/patient/patient_lab_sample.py +28 -23
- endoreg_db/models/medical/patient/patient_lab_value.py +82 -89
- endoreg_db/models/medical/patient/patient_medication.py +27 -38
- endoreg_db/models/medical/patient/patient_medication_schedule.py +28 -36
- endoreg_db/models/medical/risk/risk.py +7 -6
- endoreg_db/models/medical/risk/risk_type.py +8 -5
- endoreg_db/models/metadata/model_meta.py +60 -29
- endoreg_db/models/metadata/model_meta_logic.py +125 -18
- endoreg_db/models/metadata/pdf_meta.py +19 -24
- endoreg_db/models/metadata/sensitive_meta.py +102 -85
- endoreg_db/models/metadata/sensitive_meta_logic.py +192 -173
- endoreg_db/models/metadata/video_meta.py +51 -31
- endoreg_db/models/metadata/video_prediction_logic.py +16 -23
- endoreg_db/models/metadata/video_prediction_meta.py +29 -33
- endoreg_db/models/other/distribution/date_value_distribution.py +89 -29
- endoreg_db/models/other/distribution/multiple_categorical_value_distribution.py +21 -5
- endoreg_db/models/other/distribution/numeric_value_distribution.py +114 -53
- endoreg_db/models/other/distribution/single_categorical_value_distribution.py +4 -3
- endoreg_db/models/other/emission/emission_factor.py +18 -8
- endoreg_db/models/other/gender.py +10 -5
- endoreg_db/models/other/information_source.py +25 -25
- endoreg_db/models/other/material.py +9 -5
- endoreg_db/models/other/resource.py +6 -4
- endoreg_db/models/other/tag.py +10 -5
- endoreg_db/models/other/transport_route.py +13 -8
- endoreg_db/models/other/unit.py +10 -6
- endoreg_db/models/other/waste.py +6 -5
- endoreg_db/models/requirement/requirement.py +580 -272
- endoreg_db/models/requirement/requirement_error.py +85 -0
- endoreg_db/models/requirement/requirement_evaluation/evaluate_with_dependencies.py +268 -0
- endoreg_db/models/requirement/requirement_evaluation/operator_evaluation_models.py +3 -6
- endoreg_db/models/requirement/requirement_evaluation/requirement_type_parser.py +90 -64
- endoreg_db/models/requirement/requirement_operator.py +36 -33
- endoreg_db/models/requirement/requirement_set.py +74 -57
- endoreg_db/models/state/__init__.py +4 -4
- endoreg_db/models/state/abstract.py +2 -2
- endoreg_db/models/state/anonymization.py +12 -0
- endoreg_db/models/state/audit_ledger.py +46 -47
- endoreg_db/models/state/label_video_segment.py +9 -0
- endoreg_db/models/state/raw_pdf.py +40 -46
- endoreg_db/models/state/sensitive_meta.py +6 -2
- endoreg_db/models/state/video.py +58 -53
- endoreg_db/models/upload_job.py +32 -55
- endoreg_db/models/utils.py +1 -2
- endoreg_db/root_urls.py +21 -2
- endoreg_db/serializers/__init__.py +0 -2
- endoreg_db/serializers/anonymization.py +18 -10
- endoreg_db/serializers/meta/report_meta.py +1 -1
- endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
- endoreg_db/serializers/misc/file_overview.py +11 -99
- endoreg_db/serializers/requirements/requirement_sets.py +92 -22
- endoreg_db/serializers/video/segmentation.py +2 -1
- endoreg_db/serializers/video/video_processing_history.py +20 -5
- endoreg_db/services/anonymization.py +75 -73
- endoreg_db/services/lookup_service.py +37 -24
- endoreg_db/services/pdf_import.py +166 -68
- endoreg_db/services/storage_aware_video_processor.py +140 -114
- endoreg_db/services/video_import.py +193 -283
- endoreg_db/urls/__init__.py +7 -20
- endoreg_db/urls/media.py +108 -67
- endoreg_db/urls/root_urls.py +29 -0
- endoreg_db/utils/__init__.py +15 -5
- endoreg_db/utils/ai/multilabel_classification_net.py +116 -20
- endoreg_db/utils/case_generator/__init__.py +3 -0
- endoreg_db/utils/dataloader.py +88 -16
- endoreg_db/utils/defaults/set_default_center.py +32 -0
- endoreg_db/utils/names.py +22 -16
- endoreg_db/utils/permissions.py +2 -1
- endoreg_db/utils/pipelines/process_video_dir.py +1 -1
- endoreg_db/utils/requirement_operator_logic/model_evaluators.py +414 -127
- endoreg_db/utils/setup_config.py +8 -5
- endoreg_db/utils/storage.py +115 -0
- endoreg_db/utils/validate_endo_roi.py +8 -2
- endoreg_db/utils/video/ffmpeg_wrapper.py +184 -188
- endoreg_db/views/__init__.py +0 -10
- endoreg_db/views/anonymization/media_management.py +198 -163
- endoreg_db/views/anonymization/overview.py +4 -1
- endoreg_db/views/anonymization/validate.py +174 -40
- endoreg_db/views/media/__init__.py +2 -0
- endoreg_db/views/media/pdf_media.py +131 -152
- endoreg_db/views/media/sensitive_metadata.py +46 -6
- endoreg_db/views/media/video_media.py +89 -82
- endoreg_db/views/media/video_segments.py +2 -3
- endoreg_db/views/meta/sensitive_meta_detail.py +0 -63
- endoreg_db/views/patient/patient.py +5 -4
- endoreg_db/views/pdf/pdf_stream.py +20 -21
- endoreg_db/views/pdf/reimport.py +11 -32
- endoreg_db/views/requirement/evaluate.py +188 -187
- endoreg_db/views/requirement/lookup.py +17 -3
- endoreg_db/views/requirement/requirement_utils.py +89 -0
- endoreg_db/views/video/__init__.py +0 -2
- endoreg_db/views/video/correction.py +2 -2
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/METADATA +7 -3
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/RECORD +341 -245
- endoreg_db/models/administration/permissions/__init__.py +0 -44
- endoreg_db/models/media/video/video_file_frames.py +0 -0
- endoreg_db/models/metadata/frame_ocr_result.py +0 -0
- endoreg_db/models/rule/__init__.py +0 -13
- endoreg_db/models/rule/rule.py +0 -27
- endoreg_db/models/rule/rule_applicator.py +0 -224
- endoreg_db/models/rule/rule_attribute_dtype.py +0 -17
- endoreg_db/models/rule/rule_type.py +0 -20
- endoreg_db/models/rule/ruleset.py +0 -17
- endoreg_db/serializers/video/video_metadata.py +0 -105
- endoreg_db/urls/report.py +0 -48
- endoreg_db/urls/video.py +0 -61
- endoreg_db/utils/case_generator/case_generator.py +0 -159
- endoreg_db/utils/case_generator/utils.py +0 -30
- endoreg_db/views/report/__init__.py +0 -9
- endoreg_db/views/report/report_list.py +0 -112
- endoreg_db/views/report/report_with_secure_url.py +0 -28
- endoreg_db/views/report/start_examination.py +0 -7
- endoreg_db/views.py +0 -0
- /endoreg_db/data/{requirement_set → _examples/requirement_set}/endoscopy_bleeding_risk.yaml +0 -0
- /endoreg_db/migrations/{0002_add_video_correction_models.py → _old/0002_add_video_correction_models.py} +0 -0
- /endoreg_db/migrations/{0003_add_center_display_name.py → _old/0003_add_center_display_name.py} +0 -0
- /endoreg_db/{models/media/video/refactor_plan.md → views/pdf/pdf_stream_views.py} +0 -0
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/WHEEL +0 -0
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.0.dist-info}/licenses/LICENSE +0 -0
endoreg_db/models/state/video.py
CHANGED
|
@@ -1,69 +1,71 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Defines state tracking models related to video processing.
|
|
3
3
|
"""
|
|
4
|
-
|
|
5
|
-
from .abstract import AbstractState
|
|
6
|
-
from typing import TYPE_CHECKING, Optional
|
|
4
|
+
|
|
7
5
|
import logging
|
|
8
6
|
from enum import Enum
|
|
7
|
+
from typing import TYPE_CHECKING, Optional
|
|
8
|
+
|
|
9
|
+
from django.db import models
|
|
10
|
+
|
|
11
|
+
from endoreg_db.models.state.anonymization import AnonymizationState
|
|
9
12
|
|
|
10
13
|
logger = logging.getLogger(__name__)
|
|
11
14
|
|
|
12
15
|
if TYPE_CHECKING:
|
|
13
16
|
from ..media import VideoFile
|
|
14
|
-
|
|
15
17
|
|
|
16
|
-
class AnonymizationStatus(str, Enum):
|
|
17
|
-
NOT_STARTED = "not_started"
|
|
18
|
-
EXTRACTING_FRAMES = "extracting_frames"
|
|
19
|
-
PROCESSING_ANONYMIZING = "processing_anonymization"
|
|
20
|
-
DONE = "done"
|
|
21
|
-
VALIDATED = "validated"
|
|
22
|
-
FAILED = "failed"
|
|
23
|
-
STARTED = "started"
|
|
24
18
|
|
|
25
19
|
class VideoState(models.Model):
|
|
26
20
|
"""
|
|
27
21
|
Tracks the processing state of a VideoFile instance.
|
|
28
22
|
Uses BooleanFields for clear, distinct states.
|
|
29
23
|
"""
|
|
24
|
+
|
|
25
|
+
|
|
30
26
|
# Frame related states
|
|
31
27
|
if TYPE_CHECKING:
|
|
32
|
-
video_file:
|
|
33
|
-
|
|
28
|
+
video_file: models.OneToOneField["VideoFile"]
|
|
29
|
+
|
|
34
30
|
frames_extracted = models.BooleanField(default=False, help_text="True if raw frames have been extracted to files.")
|
|
35
31
|
frames_initialized = models.BooleanField(default=False, help_text="True if Frame DB objects have been created.")
|
|
36
32
|
frame_count = models.PositiveIntegerField(null=True, blank=True, help_text="Number of frames extracted/initialized.")
|
|
37
33
|
|
|
38
34
|
# Metadata related states
|
|
39
|
-
video_meta_extracted = models.BooleanField(
|
|
40
|
-
|
|
35
|
+
video_meta_extracted = models.BooleanField(
|
|
36
|
+
default=False,
|
|
37
|
+
help_text="True if VideoMeta (technical specs) has been extracted.",
|
|
38
|
+
)
|
|
39
|
+
text_meta_extracted = models.BooleanField(
|
|
40
|
+
default=False, help_text="True if text metadata (OCR) has been extracted."
|
|
41
|
+
)
|
|
41
42
|
|
|
42
43
|
# AI / Annotation related states
|
|
43
44
|
initial_prediction_completed = models.BooleanField(default=False, help_text="True if initial AI prediction has run.")
|
|
44
45
|
lvs_created = models.BooleanField(default=False, help_text="True if LabelVideoSegments have been created from predictions.")
|
|
45
46
|
frame_annotations_generated = models.BooleanField(default=False, help_text="True if frame-level annotations have been generated from segments.")
|
|
46
|
-
|
|
47
|
+
|
|
47
48
|
# Processing state
|
|
48
|
-
sensitive_meta_processed = models.BooleanField(
|
|
49
|
+
sensitive_meta_processed = models.BooleanField(
|
|
50
|
+
default=False, help_text="True if the video has been fully processed, meaning a anonymized person was created."
|
|
51
|
+
)
|
|
49
52
|
|
|
50
53
|
# Anonymization state
|
|
51
54
|
anonymized = models.BooleanField(default=False, help_text="True if the anonymized video file has been created.")
|
|
52
55
|
anonymization_validated = models.BooleanField(default=False, help_text="True if the anonymization process has been validated and confirmed.")
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
|
|
55
57
|
processing_started = models.BooleanField(default=False, help_text="True if the processing has started, but not yet completed.")
|
|
56
|
-
|
|
58
|
+
|
|
57
59
|
# Timestamps
|
|
58
60
|
date_created = models.DateTimeField(auto_now_add=True)
|
|
59
61
|
date_modified = models.DateTimeField(auto_now=True)
|
|
60
|
-
|
|
62
|
+
|
|
61
63
|
# Segment Annotation State
|
|
62
64
|
segment_annotations_created = models.BooleanField(default=False, help_text="True if segment annotations have been created from LabelVideoSegments.")
|
|
63
65
|
segment_annotations_validated = models.BooleanField(default=False, help_text="True if segment annotations have been validated.")
|
|
64
|
-
|
|
66
|
+
|
|
65
67
|
was_created = models.BooleanField(default=True, help_text="True if this state was created for the first time.")
|
|
66
|
-
|
|
68
|
+
|
|
67
69
|
objects = models.Manager()
|
|
68
70
|
|
|
69
71
|
def __str__(self):
|
|
@@ -71,10 +73,11 @@ class VideoState(models.Model):
|
|
|
71
73
|
video_uuid = "Unknown"
|
|
72
74
|
try:
|
|
73
75
|
# Access the related VideoFile via the reverse relation 'video_file'
|
|
74
|
-
if hasattr(self,
|
|
76
|
+
if hasattr(self, "video_file") and self.video_file:
|
|
75
77
|
video_uuid = self.video_file.uuid
|
|
76
78
|
except Exception:
|
|
77
|
-
pass
|
|
79
|
+
pass # Ignore errors if relation doesn't exist or causes issues
|
|
80
|
+
pass # Ignore errors if relation doesn't exist or causes issues
|
|
78
81
|
|
|
79
82
|
states = [
|
|
80
83
|
f"FramesExtracted={self.frames_extracted}",
|
|
@@ -86,32 +89,36 @@ class VideoState(models.Model):
|
|
|
86
89
|
f"Anonymized={self.anonymized}",
|
|
87
90
|
f"AnonymizationValidated={self.anonymization_validated}",
|
|
88
91
|
f"SensitiveMetaProcessed={self.sensitive_meta_processed}",
|
|
89
|
-
f"FrameCount={self.frame_count}"
|
|
92
|
+
f"FrameCount={self.frame_count}"
|
|
93
|
+
if self.frame_count is not None
|
|
94
|
+
else "FrameCount=None",
|
|
90
95
|
f"SegmentAnnotationsCreated={self.segment_annotations_created}",
|
|
91
96
|
f"SegmentAnnotationsValidated={self.segment_annotations_validated}",
|
|
92
97
|
f"DateCreated={self.date_created.isoformat()}",
|
|
93
|
-
f"DateModified={self.date_modified.isoformat()}"
|
|
98
|
+
f"DateModified={self.date_modified.isoformat()}",
|
|
94
99
|
]
|
|
95
100
|
return f"VideoState(Video:{video_uuid}): {', '.join(states)}"
|
|
96
101
|
|
|
97
102
|
@property
|
|
98
|
-
def anonymization_status(self) ->
|
|
103
|
+
def anonymization_status(self) -> AnonymizationState:
|
|
99
104
|
"""
|
|
100
105
|
Fast, side‑effect‑free status resolution used by API & UI.
|
|
101
106
|
"""
|
|
102
107
|
if self.anonymization_validated:
|
|
103
|
-
return
|
|
108
|
+
return AnonymizationState.VALIDATED # Validation in Frontend completed -> Views related to this /home/admin/endoreg-db/endoreg_db/views/anonymization/validate.py
|
|
104
109
|
if self.sensitive_meta_processed:
|
|
105
|
-
return
|
|
110
|
+
return AnonymizationState.DONE_PROCESSING_ANONYMIZATION # /home/admin/endoreg-db/endoreg_db/services/video_import.py /home/admin/endoreg-db/endoreg_db/views/video/reimport.py
|
|
106
111
|
if self.frames_extracted and not self.anonymized:
|
|
107
|
-
return
|
|
112
|
+
return AnonymizationState.PROCESSING_ANONYMIZING
|
|
108
113
|
if self.was_created and not self.frames_extracted:
|
|
109
|
-
return
|
|
114
|
+
return AnonymizationState.EXTRACTING_FRAMES
|
|
110
115
|
if getattr(self, "processing_error", False):
|
|
111
|
-
return
|
|
116
|
+
return AnonymizationState.FAILED
|
|
112
117
|
if self.processing_started:
|
|
113
|
-
return
|
|
114
|
-
|
|
118
|
+
return AnonymizationState.STARTED
|
|
119
|
+
if self.anonymized:
|
|
120
|
+
return AnonymizationState.ANONYMIZED
|
|
121
|
+
return AnonymizationState.NOT_STARTED
|
|
115
122
|
|
|
116
123
|
# ---- Single‑responsibility mutators ---------------------------------
|
|
117
124
|
def mark_sensitive_meta_processed(self, *, save: bool = True) -> None:
|
|
@@ -122,7 +129,7 @@ class VideoState(models.Model):
|
|
|
122
129
|
def mark_anonymization_validated(self, *, save: bool = True) -> None:
|
|
123
130
|
"""
|
|
124
131
|
Mark the anonymization process as validated for this video state.
|
|
125
|
-
|
|
132
|
+
|
|
126
133
|
Parameters:
|
|
127
134
|
save (bool): If True, persist the change to the database immediately.
|
|
128
135
|
"""
|
|
@@ -133,7 +140,7 @@ class VideoState(models.Model):
|
|
|
133
140
|
def mark_frames_extracted(self, *, save: bool = True) -> None:
|
|
134
141
|
"""
|
|
135
142
|
Mark the video as having its frames extracted.
|
|
136
|
-
|
|
143
|
+
|
|
137
144
|
Parameters:
|
|
138
145
|
save (bool): If True, persist the change to the database immediately.
|
|
139
146
|
"""
|
|
@@ -144,7 +151,7 @@ class VideoState(models.Model):
|
|
|
144
151
|
def mark_frames_not_extracted(self, *, save: bool = True) -> None:
|
|
145
152
|
"""
|
|
146
153
|
Mark the video as having no extracted frames.
|
|
147
|
-
|
|
154
|
+
|
|
148
155
|
If `save` is True, updates the database record for this state.
|
|
149
156
|
"""
|
|
150
157
|
self.frames_extracted = False
|
|
@@ -154,7 +161,7 @@ class VideoState(models.Model):
|
|
|
154
161
|
def mark_anonymized(self, *, save: bool = True) -> None:
|
|
155
162
|
"""
|
|
156
163
|
Mark the video as anonymized by setting the anonymized flag to True.
|
|
157
|
-
|
|
164
|
+
|
|
158
165
|
Parameters:
|
|
159
166
|
save (bool): If True, immediately saves the updated state to the database.
|
|
160
167
|
"""
|
|
@@ -165,7 +172,7 @@ class VideoState(models.Model):
|
|
|
165
172
|
def mark_initial_prediction_completed(self, *, save: bool = True) -> None:
|
|
166
173
|
"""
|
|
167
174
|
Mark the initial AI prediction as completed for this video state.
|
|
168
|
-
|
|
175
|
+
|
|
169
176
|
Parameters:
|
|
170
177
|
save (bool): If True, persist the change to the database immediately.
|
|
171
178
|
"""
|
|
@@ -176,7 +183,7 @@ class VideoState(models.Model):
|
|
|
176
183
|
def mark_video_meta_extracted(self, *, save: bool = True) -> None:
|
|
177
184
|
"""
|
|
178
185
|
Mark the video metadata as extracted for this video state.
|
|
179
|
-
|
|
186
|
+
|
|
180
187
|
Parameters:
|
|
181
188
|
save (bool): If True, immediately saves the updated state to the database.
|
|
182
189
|
"""
|
|
@@ -187,45 +194,43 @@ class VideoState(models.Model):
|
|
|
187
194
|
def mark_text_meta_extracted(self, *, save: bool = True) -> None:
|
|
188
195
|
"""
|
|
189
196
|
Mark the video as having its text metadata extracted.
|
|
190
|
-
|
|
197
|
+
|
|
191
198
|
Parameters:
|
|
192
|
-
|
|
199
|
+
save (bool): If True, immediately saves the updated state to the database.
|
|
193
200
|
"""
|
|
194
201
|
self.text_meta_extracted = True
|
|
195
202
|
if save:
|
|
196
203
|
self.save(update_fields=["text_meta_extracted", "date_modified"])
|
|
197
|
-
|
|
204
|
+
|
|
198
205
|
def get_or_create_state(self):
|
|
199
206
|
"""
|
|
200
207
|
Get the current state of the video, or create a new one if it doesn't exist.
|
|
201
|
-
|
|
208
|
+
|
|
202
209
|
Returns:
|
|
203
210
|
VideoState: The current or newly created state.
|
|
204
211
|
"""
|
|
205
|
-
if not hasattr(self,
|
|
212
|
+
if not hasattr(self, "video_file"):
|
|
206
213
|
raise ValueError("This method requires a related VideoFile instance.")
|
|
207
|
-
|
|
214
|
+
|
|
208
215
|
# If the state already exists, return it
|
|
209
216
|
if self.video_file.state:
|
|
210
217
|
return self.video_file.state
|
|
211
|
-
|
|
218
|
+
|
|
212
219
|
# Otherwise, create a new state
|
|
213
220
|
new_state = VideoState(video_file=self.video_file)
|
|
214
221
|
new_state.save()
|
|
215
222
|
return new_state
|
|
216
|
-
|
|
223
|
+
|
|
217
224
|
def mark_processing_started(self, *, save: bool = True) -> None:
|
|
218
225
|
"""
|
|
219
226
|
Mark the processing as started for this video state.
|
|
220
|
-
|
|
227
|
+
|
|
221
228
|
Parameters:
|
|
222
229
|
save (bool): If True, immediately saves the updated state to the database.
|
|
223
230
|
"""
|
|
224
231
|
self.processing_started = True
|
|
225
232
|
if save:
|
|
226
233
|
self.save(update_fields=["processing_started", "date_modified"])
|
|
227
|
-
|
|
228
|
-
|
|
229
234
|
|
|
230
235
|
class Meta:
|
|
231
236
|
verbose_name = "Video Processing State"
|
endoreg_db/models/upload_job.py
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import uuid
|
|
2
|
+
from typing import TYPE_CHECKING, cast
|
|
3
|
+
|
|
2
4
|
from django.db import models
|
|
3
5
|
|
|
4
6
|
|
|
@@ -7,63 +9,38 @@ class UploadJob(models.Model):
|
|
|
7
9
|
Tracks file upload jobs and their processing status.
|
|
8
10
|
Supports both PDF and video file uploads with asynchronous processing.
|
|
9
11
|
"""
|
|
10
|
-
|
|
12
|
+
|
|
11
13
|
class Status(models.TextChoices):
|
|
12
|
-
PENDING =
|
|
13
|
-
PROCESSING =
|
|
14
|
-
ANONYMIZED =
|
|
15
|
-
ERROR =
|
|
16
|
-
|
|
17
|
-
id = models.UUIDField(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
upload_to='uploads/%Y/%m/%d/',
|
|
26
|
-
help_text="Uploaded file (PDF or video)"
|
|
27
|
-
)
|
|
28
|
-
|
|
29
|
-
status = models.CharField(
|
|
30
|
-
max_length=20,
|
|
31
|
-
choices=Status.choices,
|
|
32
|
-
default=Status.PENDING,
|
|
33
|
-
help_text="Current processing status of the upload"
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
content_type = models.CharField(
|
|
37
|
-
max_length=100,
|
|
38
|
-
blank=True,
|
|
39
|
-
help_text="MIME type of the uploaded file"
|
|
40
|
-
)
|
|
41
|
-
|
|
14
|
+
PENDING = "pending", "Pending"
|
|
15
|
+
PROCESSING = "processing", "Processing"
|
|
16
|
+
ANONYMIZED = "anonymized", "Anonymized"
|
|
17
|
+
ERROR = "error", "Error"
|
|
18
|
+
|
|
19
|
+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, help_text="Unique identifier for the upload job")
|
|
20
|
+
|
|
21
|
+
file = models.FileField(upload_to="uploads/%Y/%m/%d/", help_text="Uploaded file (PDF or video)")
|
|
22
|
+
|
|
23
|
+
status = models.CharField(max_length=20, choices=Status.choices, default=Status.PENDING, help_text="Current processing status of the upload")
|
|
24
|
+
|
|
25
|
+
content_type = models.CharField(max_length=100, blank=True, help_text="MIME type of the uploaded file")
|
|
26
|
+
|
|
42
27
|
sensitive_meta = models.ForeignKey(
|
|
43
|
-
|
|
44
|
-
null=True,
|
|
45
|
-
blank=True,
|
|
46
|
-
on_delete=models.SET_NULL,
|
|
47
|
-
help_text="Link to the created SensitiveMeta record after processing"
|
|
48
|
-
)
|
|
49
|
-
|
|
50
|
-
error_detail = models.TextField(
|
|
51
|
-
blank=True,
|
|
52
|
-
help_text="Error message if processing failed"
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
created_at = models.DateTimeField(
|
|
56
|
-
auto_now_add=True,
|
|
57
|
-
help_text="When the upload job was created"
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
updated_at = models.DateTimeField(
|
|
61
|
-
auto_now=True,
|
|
62
|
-
help_text="When the upload job was last updated"
|
|
28
|
+
"SensitiveMeta", null=True, blank=True, on_delete=models.SET_NULL, help_text="Link to the created SensitiveMeta record after processing"
|
|
63
29
|
)
|
|
64
30
|
|
|
31
|
+
error_detail = models.TextField(blank=True, help_text="Error message if processing failed")
|
|
32
|
+
|
|
33
|
+
created_at = models.DateTimeField(auto_now_add=True, help_text="When the upload job was created")
|
|
34
|
+
|
|
35
|
+
updated_at = models.DateTimeField(auto_now=True, help_text="When the upload job was last updated")
|
|
36
|
+
|
|
37
|
+
if TYPE_CHECKING:
|
|
38
|
+
from django.db.models.fields.files import FieldFile
|
|
39
|
+
|
|
40
|
+
file = cast(FieldFile, file)
|
|
41
|
+
|
|
65
42
|
class Meta:
|
|
66
|
-
ordering = [
|
|
43
|
+
ordering = ["-created_at"]
|
|
67
44
|
verbose_name = "Upload Job"
|
|
68
45
|
verbose_name_plural = "Upload Jobs"
|
|
69
46
|
|
|
@@ -83,17 +60,17 @@ class UploadJob(models.Model):
|
|
|
83
60
|
def mark_processing(self):
|
|
84
61
|
"""Mark the job as processing."""
|
|
85
62
|
self.status = self.Status.PROCESSING
|
|
86
|
-
self.save(update_fields=[
|
|
63
|
+
self.save(update_fields=["status", "updated_at"])
|
|
87
64
|
|
|
88
65
|
def mark_completed(self, sensitive_meta=None):
|
|
89
66
|
"""Mark the job as successfully completed."""
|
|
90
67
|
self.status = self.Status.ANONYMIZED
|
|
91
68
|
if sensitive_meta:
|
|
92
69
|
self.sensitive_meta = sensitive_meta
|
|
93
|
-
self.save(update_fields=[
|
|
70
|
+
self.save(update_fields=["status", "sensitive_meta", "updated_at"])
|
|
94
71
|
|
|
95
72
|
def mark_error(self, error_detail: str):
|
|
96
73
|
"""Mark the job as failed with error details."""
|
|
97
74
|
self.status = self.Status.ERROR
|
|
98
75
|
self.error_detail = error_detail
|
|
99
|
-
self.save(update_fields=[
|
|
76
|
+
self.save(update_fields=["status", "error_detail", "updated_at"])
|
endoreg_db/models/utils.py
CHANGED
|
@@ -6,13 +6,12 @@ from django.core.files import File
|
|
|
6
6
|
from django.core.files.storage import FileSystemStorage
|
|
7
7
|
import io
|
|
8
8
|
import os
|
|
9
|
-
from tqdm import tqdm
|
|
10
9
|
import numpy as np
|
|
11
10
|
import cv2
|
|
12
11
|
from typing import TYPE_CHECKING, List, Tuple
|
|
13
12
|
from pathlib import Path
|
|
14
13
|
if TYPE_CHECKING:
|
|
15
|
-
|
|
14
|
+
pass
|
|
16
15
|
|
|
17
16
|
from logging import getLogger
|
|
18
17
|
|
endoreg_db/root_urls.py
CHANGED
|
@@ -1,9 +1,28 @@
|
|
|
1
|
+
# endoreg_db/root_urls.py
|
|
2
|
+
from django.contrib import admin
|
|
1
3
|
from django.urls import include, path
|
|
4
|
+
from django.http import HttpResponse
|
|
5
|
+
from django.conf import settings
|
|
6
|
+
from django.conf.urls.static import static
|
|
2
7
|
|
|
3
|
-
# Import raw API urlpatterns (no prefix) from
|
|
8
|
+
# Import raw API urlpatterns (no prefix) from your API urls package
|
|
4
9
|
from endoreg_db.urls import urlpatterns as api_urlpatterns
|
|
5
10
|
|
|
6
|
-
|
|
11
|
+
def public_home(_request):
|
|
12
|
+
return HttpResponse("Public home – no login required.")
|
|
13
|
+
|
|
7
14
|
urlpatterns = [
|
|
15
|
+
path("", public_home, name="public_home"),
|
|
16
|
+
#path("admin/", admin.site.urls),
|
|
17
|
+
|
|
18
|
+
# Mount ALL API endpoints under /api/
|
|
8
19
|
path("api/", include((api_urlpatterns, "endoreg_db"), namespace="api")),
|
|
20
|
+
|
|
21
|
+
# OIDC (mozilla-django-oidc provides /oidc/authenticate/ and /oidc/callback/)
|
|
22
|
+
path("oidc/", include("mozilla_django_oidc.urls")),
|
|
9
23
|
]
|
|
24
|
+
|
|
25
|
+
# Serve static/media only in DEBUG (at root, not under /api/)
|
|
26
|
+
if settings.DEBUG:
|
|
27
|
+
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
|
|
28
|
+
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
|
@@ -48,7 +48,6 @@ from .patient_finding import (
|
|
|
48
48
|
)
|
|
49
49
|
from .pdf import RawPdfAnonyTextSerializer
|
|
50
50
|
from .report import ReportDataSerializer, ReportListSerializer, SecureFileUrlSerializer
|
|
51
|
-
from .video.video_metadata import VideoMetadataSerializer
|
|
52
51
|
from .video.video_processing_history import VideoProcessingHistorySerializer
|
|
53
52
|
from .video_examination import (
|
|
54
53
|
VideoExaminationCreateSerializer,
|
|
@@ -109,7 +108,6 @@ __all__ = [
|
|
|
109
108
|
"ReportDataSerializer",
|
|
110
109
|
"SecureFileUrlSerializer",
|
|
111
110
|
# Video Correction (Phase 1.1)
|
|
112
|
-
"VideoMetadataSerializer",
|
|
113
111
|
"VideoProcessingHistorySerializer",
|
|
114
112
|
# Video Examination
|
|
115
113
|
"VideoExaminationSerializer",
|
|
@@ -7,7 +7,6 @@ Unterstützt DD.MM.YYYY als Primärformat und YYYY-MM-DD als Fallback.
|
|
|
7
7
|
from rest_framework import serializers
|
|
8
8
|
from endoreg_db.models.metadata.sensitive_meta_logic import parse_any_date
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
class SensitiveMetaValidateSerializer(serializers.Serializer):
|
|
12
11
|
"""
|
|
13
12
|
Serializer für SensitiveMeta-Validierung mit deutscher Datums-Priorität.
|
|
@@ -19,11 +18,11 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
|
|
|
19
18
|
Alle Datumsfelder werden in date-Objekte konvertiert.
|
|
20
19
|
"""
|
|
21
20
|
|
|
22
|
-
patient_first_name = serializers.CharField(required=
|
|
23
|
-
patient_last_name = serializers.CharField(required=
|
|
24
|
-
patient_dob = serializers.CharField(required=
|
|
25
|
-
examination_date = serializers.CharField(required=
|
|
26
|
-
casenumber = serializers.CharField(required=
|
|
21
|
+
patient_first_name = serializers.CharField(required=True, allow_blank=True)
|
|
22
|
+
patient_last_name = serializers.CharField(required=True, allow_blank=True)
|
|
23
|
+
patient_dob = serializers.CharField(required=True, allow_blank=True)
|
|
24
|
+
examination_date = serializers.CharField(required=True, allow_blank=True)
|
|
25
|
+
casenumber = serializers.CharField(required=True, allow_blank=True)
|
|
27
26
|
anonymized_text = serializers.CharField(required=False, allow_blank=True)
|
|
28
27
|
patient_gender = serializers.CharField(required=False, allow_blank=True)
|
|
29
28
|
center_name = serializers.CharField(required=False, allow_blank=True)
|
|
@@ -31,6 +30,10 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
|
|
|
31
30
|
file_type = serializers.ChoiceField(
|
|
32
31
|
choices=['video', 'pdf'], required=False
|
|
33
32
|
) # Optional: "video" oder "pdf"
|
|
33
|
+
center_name = serializers.CharField(required=False, allow_blank=True)
|
|
34
|
+
external_id = serializers.CharField(required=False, allow_blank=True)
|
|
35
|
+
external_id_origin = serializers.CharField(required=False, allow_blank=True)
|
|
36
|
+
|
|
34
37
|
|
|
35
38
|
def validate_patient_dob(self, value):
|
|
36
39
|
"""
|
|
@@ -40,8 +43,11 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
|
|
|
40
43
|
- DD.MM.YYYY (z.B. "21.03.1994")
|
|
41
44
|
- YYYY-MM-DD (z.B. "1994-03-21")
|
|
42
45
|
"""
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
|
|
47
|
+
if value == '' or not value:
|
|
48
|
+
raise serializers.ValidationError(
|
|
49
|
+
"Ungültiges Datum. Kein Input! Erlaubte Formate: DD.MM.YYYY oder YYYY-MM-DD."
|
|
50
|
+
)
|
|
45
51
|
|
|
46
52
|
parsed_date = parse_any_date(value)
|
|
47
53
|
if not parsed_date:
|
|
@@ -58,8 +64,10 @@ class SensitiveMetaValidateSerializer(serializers.Serializer):
|
|
|
58
64
|
- DD.MM.YYYY (z.B. "15.02.2024")
|
|
59
65
|
- YYYY-MM-DD (z.B. "2024-02-15")
|
|
60
66
|
"""
|
|
61
|
-
if not value:
|
|
62
|
-
|
|
67
|
+
if value == '' or not value:
|
|
68
|
+
raise serializers.ValidationError(
|
|
69
|
+
"Ungültiges Datum. Kein Input! Erlaubte Formate: DD.MM.YYYY oder YYYY-MM-DD."
|
|
70
|
+
)
|
|
63
71
|
|
|
64
72
|
parsed_date = parse_any_date(value)
|
|
65
73
|
if not parsed_date:
|
|
@@ -12,7 +12,7 @@ class ReportMetaSerializer(serializers.ModelSerializer):
|
|
|
12
12
|
# Füge fehlende Zeitstempel-Felder hinzu
|
|
13
13
|
created_at = serializers.SerializerMethodField()
|
|
14
14
|
updated_at = serializers.SerializerMethodField()
|
|
15
|
-
casenumber = serializers.CharField(source='
|
|
15
|
+
casenumber = serializers.CharField(source='casenumber', allow_blank=True, allow_null=True)
|
|
16
16
|
|
|
17
17
|
class Meta:
|
|
18
18
|
model = SensitiveMeta
|