endoreg-db 0.8.4.4__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_ai_model_data.py +2 -1
- 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 +14 -10
- 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 +249 -177
- 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_1.py +30 -33
- endoreg_db/models/media/video/pipe_2.py +8 -9
- endoreg_db/models/media/video/video_file.py +359 -204
- 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 +139 -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 +383 -43
- 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 +26 -57
- 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/__init__.py +1 -1
- endoreg_db/serializers/misc/file_overview.py +33 -91
- endoreg_db/serializers/misc/{vop_patient_data.py → sensitive_patient_data.py} +1 -1
- 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/serializers/video_examination.py +198 -0
- endoreg_db/services/anonymization.py +75 -73
- endoreg_db/services/lookup_service.py +256 -73
- endoreg_db/services/lookup_store.py +174 -30
- endoreg_db/services/pdf_import.py +711 -310
- endoreg_db/services/storage_aware_video_processor.py +140 -114
- endoreg_db/services/video_import.py +266 -117
- endoreg_db/urls/__init__.py +27 -27
- endoreg_db/urls/label_video_segments.py +2 -0
- endoreg_db/urls/media.py +108 -66
- 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 +5 -12
- 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 -150
- 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 +187 -260
- endoreg_db/views/meta/sensitive_meta_detail.py +0 -63
- endoreg_db/views/patient/patient.py +5 -4
- endoreg_db/views/pdf/__init__.py +5 -8
- endoreg_db/views/pdf/pdf_stream.py +186 -0
- endoreg_db/views/pdf/pdf_stream_views.py +0 -127
- endoreg_db/views/pdf/reimport.py +86 -91
- endoreg_db/views/requirement/evaluate.py +188 -187
- endoreg_db/views/requirement/lookup.py +186 -288
- endoreg_db/views/requirement/requirement_utils.py +89 -0
- endoreg_db/views/video/__init__.py +0 -4
- endoreg_db/views/video/correction.py +2 -2
- endoreg_db/views/video/video_examination_viewset.py +202 -289
- {endoreg_db-0.8.4.4.dist-info → endoreg_db-0.8.8.0.dist-info}/METADATA +7 -3
- {endoreg_db-0.8.4.4.dist-info → endoreg_db-0.8.8.0.dist-info}/RECORD +350 -255
- endoreg_db/models/administration/permissions/__init__.py +0 -44
- endoreg_db/models/media/video/refactor_plan.md +0 -0
- 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/pdf/pdf_media.py +0 -239
- 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/video/video_media.py +0 -158
- 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-0.8.4.4.dist-info → endoreg_db-0.8.8.0.dist-info}/WHEEL +0 -0
- {endoreg_db-0.8.4.4.dist-info → endoreg_db-0.8.8.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
# from django.contrib.contenttypes.models import ContentType
|
|
2
|
-
# from django.contrib.auth.models import Permission
|
|
3
|
-
# from endoreg_db.models import * # Import your models here
|
|
4
|
-
# from django.db import transaction
|
|
5
|
-
|
|
6
|
-
# # Step 1: Define model to category mappings
|
|
7
|
-
# # Assuming every model class name is unique across your entire Django project
|
|
8
|
-
# model_categories = {
|
|
9
|
-
# 'SensitiveModel1': 'sensitive',
|
|
10
|
-
# 'SensitiveModel2': 'sensitive',
|
|
11
|
-
# 'DevelopmentModel1': 'development',
|
|
12
|
-
# 'DevelopmentModel2': 'development',
|
|
13
|
-
# # Add all models you have, mapping them to either 'sensitive', 'development', or 'all'
|
|
14
|
-
# }
|
|
15
|
-
|
|
16
|
-
# # Step 2: Define permissions for each category
|
|
17
|
-
# category_permissions = {
|
|
18
|
-
# 'sensitive': ['view', 'edit', 'delete'],
|
|
19
|
-
# 'development': ['view', 'edit'],
|
|
20
|
-
# 'all': ['view'],
|
|
21
|
-
# }
|
|
22
|
-
|
|
23
|
-
# @transaction.atomic
|
|
24
|
-
# def create_permissions_for_all_models():
|
|
25
|
-
# for model_class_name, category in model_categories.items():
|
|
26
|
-
# model_class = globals().get(model_class_name)
|
|
27
|
-
# if model_class is None:
|
|
28
|
-
# print(f"Model {model_class_name} not found.")
|
|
29
|
-
# continue
|
|
30
|
-
|
|
31
|
-
# content_type = ContentType.objects.get_for_model(model_class)
|
|
32
|
-
# permissions = category_permissions.get(category, [])
|
|
33
|
-
|
|
34
|
-
# for permission_codename in permissions:
|
|
35
|
-
# permission_name = f"Can {permission_codename} {model_class_name}"
|
|
36
|
-
# permission, created = Permission.objects.get_or_create(
|
|
37
|
-
# codename=f"{permission_codename}_{model_class_name.lower()}",
|
|
38
|
-
# defaults={'name': permission_name, 'content_type': content_type},
|
|
39
|
-
# )
|
|
40
|
-
# if created:
|
|
41
|
-
# print(f"Created permission: {permission_name}")
|
|
42
|
-
|
|
43
|
-
# # Run the function to create and assign permissions based on categories
|
|
44
|
-
# create_permissions_for_all_models()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
from .rule_type import RuleType
|
|
2
|
-
from .rule import Rule
|
|
3
|
-
from .ruleset import Ruleset
|
|
4
|
-
from .rule_attribute_dtype import RuleAttributeDType
|
|
5
|
-
from .rule_applicator import RuleApplicator
|
|
6
|
-
|
|
7
|
-
__all__ = [
|
|
8
|
-
"RuleType",
|
|
9
|
-
"Rule",
|
|
10
|
-
"Ruleset",
|
|
11
|
-
"RuleAttributeDType",
|
|
12
|
-
"RuleApplicator",
|
|
13
|
-
]
|
endoreg_db/models/rule/rule.py
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
|
|
3
|
-
class RuleManager(models.Manager):
|
|
4
|
-
def get_by_natural_key(self, name):
|
|
5
|
-
return self.get(name=name)
|
|
6
|
-
|
|
7
|
-
class Rule(models.Model):
|
|
8
|
-
name = models.CharField(max_length=255, unique=True)
|
|
9
|
-
description = models.TextField(blank=True, null=True)
|
|
10
|
-
attribute_key = models.CharField(max_length=255)
|
|
11
|
-
rule_type = models.ForeignKey("RuleType", on_delete=models.CASCADE)
|
|
12
|
-
attribute_dtype = models.ForeignKey("RuleAttributeDType", on_delete=models.CASCADE)
|
|
13
|
-
|
|
14
|
-
objects = RuleManager()
|
|
15
|
-
|
|
16
|
-
class Meta:
|
|
17
|
-
verbose_name = 'Rule'
|
|
18
|
-
verbose_name_plural = 'Rules'
|
|
19
|
-
|
|
20
|
-
def natural_key(self):
|
|
21
|
-
"""
|
|
22
|
-
Return a tuple representing the natural key for this Rule instance.
|
|
23
|
-
|
|
24
|
-
Returns:
|
|
25
|
-
tuple: A one-element tuple containing the Rule's unique name.
|
|
26
|
-
"""
|
|
27
|
-
return (self.name,)
|
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
from .rule import Rule
|
|
2
|
-
import random
|
|
3
|
-
from django.core.exceptions import ValidationError
|
|
4
|
-
|
|
5
|
-
class RuleApplicator:
|
|
6
|
-
"""
|
|
7
|
-
A class to apply different types of rules to a Django model instance based on the Rule configuration.
|
|
8
|
-
"""
|
|
9
|
-
|
|
10
|
-
def get_rule_by_name(self, rule_name):
|
|
11
|
-
"""
|
|
12
|
-
A helper method to fetch a rule by name. This can be further customized.
|
|
13
|
-
"""
|
|
14
|
-
# get rule by name which is natural key
|
|
15
|
-
rule = Rule.objects.get_by_natural_key(rule_name)
|
|
16
|
-
return rule
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def apply(self, obj, rule):
|
|
20
|
-
"""
|
|
21
|
-
Applies a specified rule to an object based on the rule type and attributes.
|
|
22
|
-
|
|
23
|
-
Parameters:
|
|
24
|
-
obj (Django model instance): The object to which the rule is applied.
|
|
25
|
-
rule (Rule): The rule instance containing the rule_type and attribute details.
|
|
26
|
-
"""
|
|
27
|
-
rule_type_method = self.get_rule_type_method(rule.rule_type.name)
|
|
28
|
-
if rule_type_method:
|
|
29
|
-
rule_type_method(obj, rule)
|
|
30
|
-
|
|
31
|
-
else:
|
|
32
|
-
raise ValueError(f"Unsupported rule type: {rule.rule_type.name}")
|
|
33
|
-
|
|
34
|
-
def apply_rule_by_name(self, obj, rule_name):
|
|
35
|
-
"""
|
|
36
|
-
A helper method to apply a rule and get a value. This can be further customized.
|
|
37
|
-
"""
|
|
38
|
-
rule = self.get_rule_by_name(rule_name)
|
|
39
|
-
self.apply(obj, rule)
|
|
40
|
-
|
|
41
|
-
def apply_rules_by_name(self, obj, rule_names):
|
|
42
|
-
"""
|
|
43
|
-
A helper method to apply multiple rules and get values. This can be further customized.
|
|
44
|
-
"""
|
|
45
|
-
rules = [self.get_rule_by_name(rule_name) for rule_name in rule_names]
|
|
46
|
-
for rule in rules:
|
|
47
|
-
self.apply(obj, rule)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def get_rule_type_method(self, rule_type_name):
|
|
51
|
-
"""
|
|
52
|
-
Maps rule type name to the corresponding method.
|
|
53
|
-
"""
|
|
54
|
-
return getattr(self, f"handle_{rule_type_name}", None)
|
|
55
|
-
|
|
56
|
-
def parse_attribute_path(self, obj, attribute_key):
|
|
57
|
-
"""
|
|
58
|
-
Parses the attribute path and applies the value to the correct attribute of a nested object.
|
|
59
|
-
"""
|
|
60
|
-
parts = attribute_key.split('.')
|
|
61
|
-
model_name = parts[0]
|
|
62
|
-
if model_name.lower() != obj.__class__.__name__.lower():
|
|
63
|
-
raise ValidationError(f"Model type mismatch: expected {model_name}, got {obj.__class__.__name__}")
|
|
64
|
-
|
|
65
|
-
# Navigate through the nested attributes
|
|
66
|
-
target = obj
|
|
67
|
-
for part in parts[1:-1]:
|
|
68
|
-
target = getattr(target, part)
|
|
69
|
-
|
|
70
|
-
return target, parts[-1]
|
|
71
|
-
|
|
72
|
-
def set_attribute_value(self, obj, rule):
|
|
73
|
-
"""
|
|
74
|
-
Generic method to set attribute value considering nested paths.
|
|
75
|
-
"""
|
|
76
|
-
target, attribute = self.parse_attribute_path(obj, rule.attribute_key)
|
|
77
|
-
setattr(target, attribute, rule.attribute_dict['value'])
|
|
78
|
-
target.save()
|
|
79
|
-
|
|
80
|
-
#####
|
|
81
|
-
|
|
82
|
-
def handle_case_attribute_set_value(self, obj, rule):
|
|
83
|
-
"""
|
|
84
|
-
Sets a specific attribute to a given value.
|
|
85
|
-
"""
|
|
86
|
-
self.set_attribute_value(obj, rule.attribute_key, rule.attribute_dict["value"])
|
|
87
|
-
|
|
88
|
-
def handle_case_attribute_set_value_range_uniform(self, obj, rule):
|
|
89
|
-
"""
|
|
90
|
-
Sets an attribute to a value within a specified range, selected uniformly.
|
|
91
|
-
"""
|
|
92
|
-
if not hasattr(rule, 'attribute_dtype') or rule.attribute_dtype.name not in ['numeric', 'ordered_categorical']:
|
|
93
|
-
raise ValidationError("Attribute dtype must be numeric or ordered_categorical")
|
|
94
|
-
min_val = rule.attribute_dict["value_min"]
|
|
95
|
-
max_val = rule.attribute_dict["value_max"]
|
|
96
|
-
value = random.uniform(min_val, max_val)
|
|
97
|
-
self.set_attribute_value(obj, rule.attribute_key, value)
|
|
98
|
-
|
|
99
|
-
def handle_case_attribute_set_value_range_norm_dist(self, obj, rule):
|
|
100
|
-
"""
|
|
101
|
-
Sets an attribute to a value within a specified range, based on a normal distribution.
|
|
102
|
-
"""
|
|
103
|
-
if rule.attribute_dtype.name in ['float', "integer"]:
|
|
104
|
-
raise ValidationError("Attribute dtype must be float or integer")
|
|
105
|
-
mean = rule.attribute_dict["value_mean"]
|
|
106
|
-
std_dev = rule.attribute_dict["value_sd"]
|
|
107
|
-
value = random.normalvariate(mean, std_dev)
|
|
108
|
-
self.set_attribute_value(obj, rule.attribute_key, value)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def handle_case_attribute_set_from_list_uniform(self, obj, rule):
|
|
112
|
-
"""
|
|
113
|
-
Selects an attribute value uniformly from a list of choices.
|
|
114
|
-
"""
|
|
115
|
-
choices = rule.attribute_dict["value_choices"]
|
|
116
|
-
value = random.choice(choices)
|
|
117
|
-
self.set_attribute_value(obj, rule.attribute_key, value)
|
|
118
|
-
|
|
119
|
-
def handle_case_attribute_set_from_prop_tuple_list(self, obj, rule):
|
|
120
|
-
"""
|
|
121
|
-
Selects an attribute value based on a list of value-probability tuples.
|
|
122
|
-
"""
|
|
123
|
-
prop_list = rule.attribute_dict["value_prop_tuple_list"]
|
|
124
|
-
total = sum(prop for _, prop in prop_list)
|
|
125
|
-
pick = random.uniform(0, total)
|
|
126
|
-
current = 0
|
|
127
|
-
for value, prop in prop_list:
|
|
128
|
-
current += prop
|
|
129
|
-
if current > pick:
|
|
130
|
-
self.set_attribute_value(obj, rule.attribute_key, value)
|
|
131
|
-
break
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
#####
|
|
135
|
-
|
|
136
|
-
def handle_case_add_patient(self, obj, rule):
|
|
137
|
-
"""Function to add a patient to a case. If the patient already exists, raise an error. Requires the following
|
|
138
|
-
rules in the rule_dict:
|
|
139
|
-
- gender_rule
|
|
140
|
-
- dob_rule
|
|
141
|
-
- event_rules
|
|
142
|
-
- disease_rules
|
|
143
|
-
"""
|
|
144
|
-
from endoreg_db.models import Patient, PatientEvent, PatientDisease, Case
|
|
145
|
-
|
|
146
|
-
# Check if the
|
|
147
|
-
obj:Case = obj
|
|
148
|
-
if obj.patient:
|
|
149
|
-
raise ValueError("Patient already exists in the case")
|
|
150
|
-
|
|
151
|
-
patient = Patient()
|
|
152
|
-
self.apply_rule_by_name(patient, rule.attribute_dict["patient_gender_rule"])
|
|
153
|
-
self.apply_rule_by_name(patient, rule.attribute_dict["patient_dob_rule"])
|
|
154
|
-
self.apply_rules_by_name(patient, rule.attribute_dict["patient_event_rules"])
|
|
155
|
-
self.apply_rules_by_name(patient, rule.attribute_dict["patient_disease_rules"])
|
|
156
|
-
|
|
157
|
-
def handle_case_add_polyp(self, obj, rule):
|
|
158
|
-
"""
|
|
159
|
-
Adds a polyp to the case, processing various polyp characteristics. Requires Rules for each attribute:
|
|
160
|
-
- polyp_location_organ_rule (single rule)
|
|
161
|
-
- polyp_location_organ_part_rule (single rule)
|
|
162
|
-
- polyp_morphology_classification_shape_choices_rule (list of rules)
|
|
163
|
-
- polyp_morphology_classification_chromo_choices_rule (list of rules)
|
|
164
|
-
- polyp_intervention_type_rule (single rule)
|
|
165
|
-
- polyp_intervention_instrument_rule (single rule)
|
|
166
|
-
- polyp_size_mm_rule (single rule)
|
|
167
|
-
|
|
168
|
-
"""
|
|
169
|
-
# Example: create and add a polyp instance based on the rules
|
|
170
|
-
from endoreg_db.models import Polyp # Ensure you have a Polyp model and adjust the import
|
|
171
|
-
from endoreg_db.models import Location
|
|
172
|
-
from endoreg_db.models import EndoscopicIntervention
|
|
173
|
-
from endoreg_db.models import PolypMorphology
|
|
174
|
-
|
|
175
|
-
assert obj.examination.type != None, "Examination type is required"
|
|
176
|
-
|
|
177
|
-
location = Location()
|
|
178
|
-
location.organ = self.apply_rule_by_name(location, rule.attribute_dict["polyp_location_organ_rule"])
|
|
179
|
-
location.organ_part = self.apply_rule_by_name(location, rule.attribute_dict["polyp_location_organ_part_rule"])
|
|
180
|
-
location.save()
|
|
181
|
-
|
|
182
|
-
morphology = PolypMorphology()
|
|
183
|
-
# M2M to ClassificationChoice (linked to Classification which has name as natural key)
|
|
184
|
-
morphology.shape_classification_choices = self.apply_rules_by_name(morphology, rule.attribute_dict["polyp_morphology_classification_shape_choices_rules"])
|
|
185
|
-
# M2M to ClassificationChoice (linked to Classification which has name as natural key)
|
|
186
|
-
morphology.chromo_classification_choices = self.apply_rules_by_name(morphology, rule.attribute_dict["polyp_morphology_classification_chromo_choices_rules"])
|
|
187
|
-
morphology.save()
|
|
188
|
-
|
|
189
|
-
intervention = EndoscopicIntervention()
|
|
190
|
-
intervention.type = self.apply_rule_by_name(intervention, rule.attribute_dict["polyp_intervention_type_rule"])
|
|
191
|
-
intervention.instrument = self.apply_rule_by_name(intervention, rule.attribute_dict["polyp_intervention_instrument_rule"])
|
|
192
|
-
intervention.save()
|
|
193
|
-
|
|
194
|
-
polyp = Polyp()
|
|
195
|
-
polyp.size_mm = self.apply_rule_by_name(polyp, rule.attribute_dict["polyp_size_mm_rule"])
|
|
196
|
-
polyp.location = location
|
|
197
|
-
polyp.morphology = morphology
|
|
198
|
-
polyp.intervention = intervention
|
|
199
|
-
|
|
200
|
-
polyp.save()
|
|
201
|
-
|
|
202
|
-
obj.polyps.add(polyp)
|
|
203
|
-
obj.save()
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
# def handle_case_add_esophageal_varices(self, obj, rule):
|
|
207
|
-
# """
|
|
208
|
-
# Handles adding esophageal varices to a case based on the rule.
|
|
209
|
-
# """
|
|
210
|
-
# # Similar to the polyp case, create and add esophageal varices based on the attributes
|
|
211
|
-
# from endoreg_db.models import EsophagealVarices # Ensure this model exists
|
|
212
|
-
# varices = EsophagealVarices()
|
|
213
|
-
# varices.origin = self.apply_rule_by_name(obj, rule.attribute_dict["esophageal_varices_origin_rule"])
|
|
214
|
-
# varices.classification = self.apply_rule_by_name(obj, rule.attribute_dict["esophageal_varices_classification_rule"])
|
|
215
|
-
# varices.location_extent = self.apply_rule_by_name(obj, rule.attribute_dict["esophageal_varices_location_extent_rule"])
|
|
216
|
-
# varices.save()
|
|
217
|
-
# # Assuming a relationship setup
|
|
218
|
-
# obj.esophageal_varices.add(varices)
|
|
219
|
-
# obj.save()
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class RuleAttributeDtypeManager(models.Manager):
|
|
5
|
-
def get_by_natural_key(self, name):
|
|
6
|
-
return self.get(name=name)
|
|
7
|
-
|
|
8
|
-
class RuleAttributeDType(models.Model):
|
|
9
|
-
name = models.CharField(max_length=255, unique=True)
|
|
10
|
-
|
|
11
|
-
objects = RuleAttributeDtypeManager()
|
|
12
|
-
|
|
13
|
-
def natural_key(self):
|
|
14
|
-
return (self.name,)
|
|
15
|
-
|
|
16
|
-
def __str__(self):
|
|
17
|
-
return self.name
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
|
|
3
|
-
class RuleTypeManager(models.Manager):
|
|
4
|
-
def get_by_natural_key(self, name):
|
|
5
|
-
return self.get(name=name)
|
|
6
|
-
|
|
7
|
-
class RuleType(models.Model):
|
|
8
|
-
name = models.CharField(max_length=255, unique=True)
|
|
9
|
-
|
|
10
|
-
objects = RuleTypeManager()
|
|
11
|
-
|
|
12
|
-
def natural_key(self):
|
|
13
|
-
return (self.name,)
|
|
14
|
-
|
|
15
|
-
def __str__(self):
|
|
16
|
-
return self.name
|
|
17
|
-
|
|
18
|
-
class Meta:
|
|
19
|
-
verbose_name = 'Rule Type'
|
|
20
|
-
verbose_name_plural = 'Rule Types'
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
|
|
3
|
-
class RulesetManager(models.Manager):
|
|
4
|
-
def get_by_natural_key(self, name):
|
|
5
|
-
return self.get(name=name)
|
|
6
|
-
|
|
7
|
-
class Ruleset(models.Model):
|
|
8
|
-
name = models.CharField(max_length=255, unique=True)
|
|
9
|
-
rules = models.ManyToManyField('Rule')
|
|
10
|
-
|
|
11
|
-
objects = RulesetManager()
|
|
12
|
-
|
|
13
|
-
def natural_key(self):
|
|
14
|
-
return (self.name,)
|
|
15
|
-
|
|
16
|
-
def __str__(self):
|
|
17
|
-
return self.name
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Video Metadata Serializer
|
|
3
|
-
|
|
4
|
-
Serializes VideoMetadata model for API responses.
|
|
5
|
-
Created as part of Phase 1.1: Video Correction API Endpoints.
|
|
6
|
-
"""
|
|
7
|
-
from rest_framework import serializers
|
|
8
|
-
from endoreg_db.models.media.video import VideoMetadata
|
|
9
|
-
import json
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class VideoMetadataSerializer(serializers.ModelSerializer):
|
|
13
|
-
"""
|
|
14
|
-
Serializer for VideoMetadata model.
|
|
15
|
-
|
|
16
|
-
Provides analysis results (sensitive frame count, ratio, frame IDs)
|
|
17
|
-
for the correction UI.
|
|
18
|
-
"""
|
|
19
|
-
sensitive_frame_ids_list = serializers.SerializerMethodField()
|
|
20
|
-
sensitive_percentage = serializers.ReadOnlyField()
|
|
21
|
-
has_analysis = serializers.ReadOnlyField()
|
|
22
|
-
|
|
23
|
-
class Meta:
|
|
24
|
-
model = VideoMetadata
|
|
25
|
-
fields = [
|
|
26
|
-
'id',
|
|
27
|
-
'video',
|
|
28
|
-
'sensitive_frame_count',
|
|
29
|
-
'sensitive_ratio',
|
|
30
|
-
'sensitive_frame_ids',
|
|
31
|
-
'sensitive_frame_ids_list',
|
|
32
|
-
'sensitive_percentage',
|
|
33
|
-
'has_analysis',
|
|
34
|
-
'analyzed_at',
|
|
35
|
-
]
|
|
36
|
-
read_only_fields = ['id', 'analyzed_at']
|
|
37
|
-
|
|
38
|
-
def get_sensitive_frame_ids_list(self, obj) -> list:
|
|
39
|
-
"""
|
|
40
|
-
Parse sensitive_frame_ids from JSON string to Python list.
|
|
41
|
-
|
|
42
|
-
Returns:
|
|
43
|
-
list: Frame indices (0-based), or empty list if no analysis
|
|
44
|
-
"""
|
|
45
|
-
if not obj.sensitive_frame_ids:
|
|
46
|
-
return []
|
|
47
|
-
|
|
48
|
-
try:
|
|
49
|
-
return json.loads(obj.sensitive_frame_ids)
|
|
50
|
-
except (json.JSONDecodeError, TypeError):
|
|
51
|
-
return []
|
|
52
|
-
|
|
53
|
-
def validate_sensitive_frame_ids(self, value):
|
|
54
|
-
"""
|
|
55
|
-
Validate that sensitive_frame_ids is a valid JSON array.
|
|
56
|
-
|
|
57
|
-
Args:
|
|
58
|
-
value: JSON string representing frame IDs
|
|
59
|
-
|
|
60
|
-
Returns:
|
|
61
|
-
str: Validated JSON string
|
|
62
|
-
|
|
63
|
-
Raises:
|
|
64
|
-
ValidationError: If value is not valid JSON or not an array
|
|
65
|
-
"""
|
|
66
|
-
if not value:
|
|
67
|
-
return value
|
|
68
|
-
|
|
69
|
-
try:
|
|
70
|
-
parsed = json.loads(value)
|
|
71
|
-
if not isinstance(parsed, list):
|
|
72
|
-
raise serializers.ValidationError(
|
|
73
|
-
"sensitive_frame_ids must be a JSON array"
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
# Validate all elements are integers
|
|
77
|
-
if not all(isinstance(x, int) for x in parsed):
|
|
78
|
-
raise serializers.ValidationError(
|
|
79
|
-
"All frame IDs must be integers"
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
return value
|
|
83
|
-
except json.JSONDecodeError:
|
|
84
|
-
raise serializers.ValidationError(
|
|
85
|
-
"sensitive_frame_ids must be valid JSON"
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
def validate_sensitive_ratio(self, value):
|
|
89
|
-
"""
|
|
90
|
-
Validate that sensitive_ratio is between 0.0 and 1.0.
|
|
91
|
-
|
|
92
|
-
Args:
|
|
93
|
-
value: Ratio value
|
|
94
|
-
|
|
95
|
-
Returns:
|
|
96
|
-
float: Validated ratio
|
|
97
|
-
|
|
98
|
-
Raises:
|
|
99
|
-
ValidationError: If value is outside valid range
|
|
100
|
-
"""
|
|
101
|
-
if value is not None and (value < 0.0 or value > 1.0):
|
|
102
|
-
raise serializers.ValidationError(
|
|
103
|
-
"sensitive_ratio must be between 0.0 and 1.0"
|
|
104
|
-
)
|
|
105
|
-
return value
|
endoreg_db/urls/report.py
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
from django.urls import path
|
|
2
|
-
from endoreg_db.views import (
|
|
3
|
-
ReportListView,
|
|
4
|
-
ReportWithSecureUrlView,
|
|
5
|
-
ReportFileMetadataView,
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
url_patterns = [ # ---------------------------------------------------------------------------------------
|
|
9
|
-
# REPORT SERVICE ENDPOINTS
|
|
10
|
-
#
|
|
11
|
-
# Neue API-Endpunkte für den Report-Service mit sicheren URLs
|
|
12
|
-
#
|
|
13
|
-
# Diese Endpunkte ermöglichen es dem Frontend (UniversalReportViewer),
|
|
14
|
-
# Reports mit zeitlich begrenzten, sicheren URLs zu laden und anzuzeigen.
|
|
15
|
-
#
|
|
16
|
-
# Verwendung im Frontend:
|
|
17
|
-
# - loadReportWithSecureUrl(reportId)
|
|
18
|
-
# - generateSecureUrl(reportId, fileType)
|
|
19
|
-
# - validateCurrentUrl()
|
|
20
|
-
#
|
|
21
|
-
# ---------------------------------------------------------------------------------------
|
|
22
|
-
|
|
23
|
-
# API-Endpunkt für paginierte Report-Listen mit Filterung
|
|
24
|
-
# GET /api/reports/?page=1&page_size=20&status=pending&file_type=pdf&patient_name=John
|
|
25
|
-
# Lädt eine paginierte Liste aller Reports mit optionalen Filtern
|
|
26
|
-
path('reports/',
|
|
27
|
-
ReportListView.as_view(),
|
|
28
|
-
name='report_list'
|
|
29
|
-
),
|
|
30
|
-
|
|
31
|
-
# API-Endpunkt für Reports mit automatischer sicherer URL-Generierung
|
|
32
|
-
# GET /api/reports/{report_id}/with-secure-url/
|
|
33
|
-
# Lädt Report-Daten inklusive Metadaten und generiert automatisch eine sichere URL
|
|
34
|
-
path(
|
|
35
|
-
'reports/<int:report_id>/with-secure-url/',
|
|
36
|
-
ReportWithSecureUrlView.as_view(),
|
|
37
|
-
name='report_with_secure_url'
|
|
38
|
-
),
|
|
39
|
-
|
|
40
|
-
# API-Endpunkt für Report-Datei-Metadaten
|
|
41
|
-
# GET /api/reports/{report_id}/file-metadata/
|
|
42
|
-
# Gibt Datei-Metadaten zurück (Größe, Typ, Datum, etc.)
|
|
43
|
-
path(
|
|
44
|
-
'reports/<int:report_id>/file-metadata/',
|
|
45
|
-
ReportFileMetadataView.as_view(),
|
|
46
|
-
name='report_file_metadata'
|
|
47
|
-
),
|
|
48
|
-
]
|
endoreg_db/urls/video.py
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
from django.urls import path
|
|
2
|
-
|
|
3
|
-
from endoreg_db.views import (
|
|
4
|
-
SensitiveMetaDetailView,
|
|
5
|
-
VideoLabelView,
|
|
6
|
-
# Note: VideoStreamView moved to modern media framework. See: endoreg_db/urls/media.py
|
|
7
|
-
# Note: All Video Correction Views moved to modern media framework. See: endoreg_db/urls/media.py
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
url_patterns = [
|
|
11
|
-
# Video Label segments API endpoint
|
|
12
|
-
# GET /api/videos/<int:video_id>/labels/<str:label_name>/
|
|
13
|
-
# Retrieves time segments and frame predictions for a specific label on a video
|
|
14
|
-
path(
|
|
15
|
-
'videos/<int:video_id>/labels/<str:label_name>/',
|
|
16
|
-
VideoLabelView.as_view(),
|
|
17
|
-
name='video_label_segments'
|
|
18
|
-
),
|
|
19
|
-
|
|
20
|
-
# ---------------------------------------------------------------------------------------
|
|
21
|
-
# VIDEO STREAMING - MOVED TO MODERN MEDIA FRAMEWORK
|
|
22
|
-
#
|
|
23
|
-
# Video streaming endpoint has been migrated to the media framework
|
|
24
|
-
# as of October 14, 2025. Please use the new endpoints:
|
|
25
|
-
#
|
|
26
|
-
# OLD → NEW:
|
|
27
|
-
# GET /api/videostream/<pk>/ → GET /api/media/videos/<pk>/
|
|
28
|
-
# GET /api/videostream/<pk>/ → GET /api/media/videos/<pk>/stream/
|
|
29
|
-
#
|
|
30
|
-
# See: endoreg_db/urls/media.py for new URL registrations
|
|
31
|
-
# ---------------------------------------------------------------------------------------
|
|
32
|
-
|
|
33
|
-
# Note: Video Re-import moved to modern media framework
|
|
34
|
-
# See: endoreg_db/urls/media.py - POST /api/media/videos/<int:pk>/reimport/
|
|
35
|
-
|
|
36
|
-
# Video Sensitive Meta endpoints (for video anonymization)
|
|
37
|
-
# GET /api/video/sensitivemeta/<int:sensitive_meta_id>/
|
|
38
|
-
# PATCH /api/video/sensitivemeta/<int:sensitive_meta_id>/
|
|
39
|
-
path(
|
|
40
|
-
'video/sensitivemeta/<int:sensitive_meta_id>/',
|
|
41
|
-
SensitiveMetaDetailView.as_view(),
|
|
42
|
-
name='video_sensitive_meta_detail'
|
|
43
|
-
),
|
|
44
|
-
|
|
45
|
-
# ---------------------------------------------------------------------------------------
|
|
46
|
-
# VIDEO CORRECTION API ENDPOINTS - MOVED TO MODERN MEDIA FRAMEWORK
|
|
47
|
-
#
|
|
48
|
-
# All video correction endpoints have been migrated to the modern media framework
|
|
49
|
-
# as of October 14, 2025. Please use the new endpoints:
|
|
50
|
-
#
|
|
51
|
-
# OLD → NEW:
|
|
52
|
-
# GET /api/video-metadata/<id>/ → GET /api/media/videos/<pk>/metadata/
|
|
53
|
-
# GET /api/video-processing-history/<id>/ → GET /api/media/videos/<pk>/processing-history/
|
|
54
|
-
# POST /api/video-analyze/<id>/ → POST /api/media/videos/<pk>/analyze/
|
|
55
|
-
# POST /api/video-apply-mask/<id>/ → POST /api/media/videos/<pk>/apply-mask/
|
|
56
|
-
# POST /api/video-remove-frames/<id>/ → POST /api/media/videos/<pk>/remove-frames/
|
|
57
|
-
# POST /api/video-reprocess/<id>/ → POST /api/media/videos/<pk>/reprocess/
|
|
58
|
-
#
|
|
59
|
-
# See: endoreg_db/urls/media.py for new URL registrations
|
|
60
|
-
# ---------------------------------------------------------------------------------------
|
|
61
|
-
]
|