endoreg-db 0.8.6.1__py3-none-any.whl → 0.8.8.9__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 +2 -11
- endoreg_db/data/ai_model_meta/default_multilabel_classification.yaml +3 -3
- endoreg_db/data/event_classification/data.yaml +4 -0
- endoreg_db/data/event_classification_choice/data.yaml +9 -0
- endoreg_db/data/examination/examinations/data.yaml +114 -14
- endoreg_db/data/examination/time-type/data.yaml +0 -3
- endoreg_db/data/examination_indication/endoscopy.yaml +108 -173
- endoreg_db/data/examination_indication_classification/endoscopy.yaml +0 -70
- endoreg_db/data/examination_indication_classification_choice/endoscopy.yaml +33 -37
- endoreg_db/data/finding/00_generic.yaml +35 -0
- endoreg_db/data/finding/00_generic_complication.yaml +9 -0
- endoreg_db/data/finding/01_gastroscopy_baseline.yaml +88 -0
- endoreg_db/data/finding/01_gastroscopy_observation.yaml +113 -0
- endoreg_db/data/finding/02_colonoscopy_baseline.yaml +53 -0
- endoreg_db/data/finding/02_colonoscopy_hidden.yaml +119 -0
- endoreg_db/data/finding/02_colonoscopy_observation.yaml +152 -0
- endoreg_db/data/finding_classification/00_generic.yaml +44 -0
- endoreg_db/data/finding_classification/00_generic_histology.yaml +28 -0
- endoreg_db/data/finding_classification/00_generic_lesion.yaml +52 -0
- endoreg_db/data/finding_classification/02_colonoscopy_baseline.yaml +83 -0
- endoreg_db/data/finding_classification/02_colonoscopy_histology.yaml +13 -0
- endoreg_db/data/finding_classification/02_colonoscopy_other.yaml +12 -0
- endoreg_db/data/finding_classification/02_colonoscopy_polyp.yaml +101 -0
- endoreg_db/data/finding_classification_choice/{yes_no_na.yaml → 00_generic.yaml} +5 -1
- endoreg_db/data/finding_classification_choice/{examination_setting_generic_types.yaml → 00_generic_baseline.yaml} +10 -2
- endoreg_db/data/finding_classification_choice/{complication_generic_types.yaml → 00_generic_complication.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology.yaml → 00_generic_histology.yaml} +1 -4
- endoreg_db/data/finding_classification_choice/00_generic_lesion.yaml +158 -0
- endoreg_db/data/finding_classification_choice/{bowel_preparation.yaml → 02_colonoscopy_bowel_preparation.yaml} +1 -30
- endoreg_db/data/finding_classification_choice/{colonoscopy_not_complete_reason.yaml → 02_colonoscopy_generic.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{histology_polyp.yaml → 02_colonoscopy_histology.yaml} +1 -1
- endoreg_db/data/finding_classification_choice/{colonoscopy_location.yaml → 02_colonoscopy_location.yaml} +23 -4
- endoreg_db/data/finding_classification_choice/02_colonoscopy_other.yaml +34 -0
- endoreg_db/data/finding_classification_choice/02_colonoscopy_polyp_advanced_imaging.yaml +76 -0
- endoreg_db/data/finding_classification_choice/{colon_lesion_paris.yaml → 02_colonoscopy_polyp_morphology.yaml} +26 -8
- endoreg_db/data/finding_classification_choice/02_colonoscopy_size.yaml +27 -0
- endoreg_db/data/finding_classification_type/{colonoscopy_basic.yaml → 00_generic.yaml} +18 -13
- endoreg_db/data/finding_classification_type/02_colonoscopy.yaml +9 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy.yaml +59 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_ablation.yaml +44 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_bleeding.yaml +55 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_resection.yaml +85 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_stenosis.yaml +17 -0
- endoreg_db/data/finding_intervention/00_generic_endoscopy_stent.yaml +9 -0
- endoreg_db/data/finding_intervention/01_gastroscopy.yaml +19 -0
- endoreg_db/data/finding_intervention/04_eus.yaml +39 -0
- endoreg_db/data/finding_intervention/05_ercp.yaml +3 -0
- endoreg_db/data/finding_type/data.yaml +8 -12
- endoreg_db/data/requirement/01_patient_data.yaml +93 -0
- endoreg_db/data/requirement/old/colon_polyp_intervention.yaml +49 -0
- endoreg_db/data/requirement/old/coloreg_colon_polyp.yaml +49 -0
- endoreg_db/data/requirement_operator/new_operators.yaml +36 -0
- endoreg_db/data/requirement_set/01_endoscopy_generic.yaml +29 -12
- endoreg_db/data/requirement_set/01_laboratory.yaml +13 -0
- endoreg_db/data/requirement_set/{endoscopy_bleeding_risk.yaml → 02_endoscopy_bleeding_risk.yaml} +0 -6
- endoreg_db/data/requirement_set/90_coloreg.yaml +190 -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 +4 -2
- endoreg_db/forms/examination_form.py +1 -1
- endoreg_db/helpers/data_loader.py +125 -53
- endoreg_db/helpers/default_objects.py +116 -81
- endoreg_db/import_files/__init__.py +27 -0
- endoreg_db/import_files/context/__init__.py +7 -0
- endoreg_db/import_files/context/default_sensitive_meta.py +81 -0
- endoreg_db/import_files/context/ensure_center.py +17 -0
- endoreg_db/import_files/context/file_lock.py +66 -0
- endoreg_db/import_files/context/import_context.py +43 -0
- endoreg_db/import_files/context/validate_directories.py +56 -0
- endoreg_db/import_files/file_storage/__init__.py +15 -0
- endoreg_db/import_files/file_storage/create_report_file.py +76 -0
- endoreg_db/import_files/file_storage/create_video_file.py +75 -0
- endoreg_db/import_files/file_storage/sensitive_meta_storage.py +39 -0
- endoreg_db/import_files/file_storage/state_management.py +400 -0
- endoreg_db/import_files/file_storage/storage.py +36 -0
- endoreg_db/import_files/import_service.md +26 -0
- endoreg_db/import_files/processing/__init__.py +11 -0
- endoreg_db/import_files/processing/report_processing/report_anonymization.py +94 -0
- endoreg_db/import_files/processing/sensitive_meta_adapter.py +51 -0
- endoreg_db/import_files/processing/video_processing/video_anonymization.py +107 -0
- endoreg_db/import_files/processing/video_processing/video_cleanup_on_error.py +119 -0
- endoreg_db/import_files/pseudonymization/fake.py +52 -0
- endoreg_db/import_files/pseudonymization/k_anonymity.py +182 -0
- endoreg_db/import_files/pseudonymization/k_pseudonymity.py +128 -0
- endoreg_db/import_files/report_import_service.py +141 -0
- endoreg_db/import_files/video_import_service.py +150 -0
- 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_report.py +130 -65
- endoreg_db/management/commands/import_video.py +9 -10
- endoreg_db/management/commands/import_video_with_classification.py +2 -2
- endoreg_db/management/commands/list_routes.py +18 -0
- endoreg_db/management/commands/load_ai_model_data.py +5 -5
- endoreg_db/management/commands/load_ai_model_label_data.py +9 -7
- endoreg_db/management/commands/load_base_db_data.py +5 -134
- endoreg_db/management/commands/load_center_data.py +12 -12
- endoreg_db/management/commands/load_contraindication_data.py +14 -16
- endoreg_db/management/commands/load_disease_classification_choices_data.py +15 -18
- endoreg_db/management/commands/load_disease_classification_data.py +15 -18
- endoreg_db/management/commands/load_disease_data.py +25 -28
- endoreg_db/management/commands/load_endoscope_data.py +20 -27
- endoreg_db/management/commands/load_event_data.py +14 -16
- endoreg_db/management/commands/load_examination_data.py +31 -44
- endoreg_db/management/commands/load_examination_indication_data.py +20 -21
- endoreg_db/management/commands/load_finding_data.py +52 -80
- endoreg_db/management/commands/load_information_source.py +21 -23
- endoreg_db/management/commands/load_lab_value_data.py +17 -26
- endoreg_db/management/commands/load_medication_data.py +13 -12
- endoreg_db/management/commands/load_organ_data.py +15 -19
- endoreg_db/management/commands/load_pdf_type_data.py +19 -18
- endoreg_db/management/commands/load_profession_data.py +14 -17
- endoreg_db/management/commands/load_qualification_data.py +20 -23
- endoreg_db/management/commands/load_report_reader_flag_data.py +17 -19
- endoreg_db/management/commands/load_requirement_data.py +62 -39
- endoreg_db/management/commands/load_requirement_set_tags.py +95 -0
- endoreg_db/management/commands/load_risk_data.py +7 -6
- endoreg_db/management/commands/load_shift_data.py +20 -23
- endoreg_db/management/commands/load_tag_data.py +8 -11
- endoreg_db/management/commands/load_unit_data.py +17 -19
- endoreg_db/management/commands/setup_endoreg_db.py +3 -3
- endoreg_db/management/commands/start_filewatcher.py +46 -37
- endoreg_db/management/commands/storage_management.py +271 -203
- endoreg_db/management/commands/validate_video_files.py +1 -5
- endoreg_db/migrations/0001_initial.py +297 -250
- 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 +129 -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 +8 -9
- endoreg_db/models/label/annotation/image_classification.py +10 -9
- endoreg_db/models/label/annotation/video_segmentation_annotation.py +23 -28
- 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 +98 -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 +194 -194
- endoreg_db/models/media/pdf/report_file.py +25 -29
- endoreg_db/models/media/pdf/report_reader/report_reader_config.py +55 -47
- endoreg_db/models/media/pdf/report_reader/report_reader_flag.py +23 -7
- endoreg_db/models/media/processing_history/__init__.py +5 -0
- endoreg_db/models/media/processing_history/processing_history.py +96 -0
- endoreg_db/models/media/video/__init__.py +1 -0
- endoreg_db/models/media/video/create_from_file.py +139 -77
- endoreg_db/models/media/video/pipe_2.py +8 -9
- endoreg_db/models/media/video/video_file.py +174 -112
- 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 +113 -61
- 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/README.md +1 -0
- 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 +39 -20
- endoreg_db/models/medical/examination/examination_indication.py +30 -95
- endoreg_db/models/medical/examination/examination_time.py +23 -8
- 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 +32 -40
- endoreg_db/models/medical/finding/finding_classification.py +42 -72
- endoreg_db/models/medical/finding/finding_intervention.py +25 -22
- endoreg_db/models/medical/finding/finding_type.py +13 -12
- endoreg_db/models/medical/hardware/endoscope.py +26 -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 +6 -6
- 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 +31 -24
- endoreg_db/models/metadata/sensitive_meta.py +105 -85
- endoreg_db/models/metadata/sensitive_meta_logic.py +198 -103
- 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 +50 -29
- 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/report/report.py +6 -0
- endoreg_db/models/requirement/requirement.py +329 -361
- 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 +103 -112
- 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 +49 -51
- endoreg_db/models/state/label_video_segment.py +9 -0
- endoreg_db/models/state/raw_pdf.py +101 -68
- endoreg_db/models/state/sensitive_meta.py +6 -2
- endoreg_db/models/state/video.py +110 -90
- endoreg_db/models/upload_job.py +35 -34
- endoreg_db/models/utils.py +28 -25
- endoreg_db/queries/__init__.py +3 -1
- endoreg_db/root_urls.py +21 -2
- endoreg_db/schemas/examination_evaluation.py +1 -1
- endoreg_db/serializers/__init__.py +2 -10
- endoreg_db/serializers/anonymization.py +18 -10
- endoreg_db/serializers/label_video_segment/label_video_segment.py +2 -29
- endoreg_db/serializers/meta/__init__.py +1 -6
- endoreg_db/serializers/meta/sensitive_meta_detail.py +63 -118
- endoreg_db/serializers/misc/file_overview.py +11 -99
- endoreg_db/serializers/misc/sensitive_patient_data.py +50 -26
- endoreg_db/serializers/patient_examination/patient_examination.py +3 -3
- endoreg_db/serializers/pdf/anony_text_validation.py +39 -23
- endoreg_db/serializers/requirements/requirement_sets.py +92 -22
- endoreg_db/serializers/video/segmentation.py +2 -1
- endoreg_db/serializers/video/video_file_list.py +65 -34
- endoreg_db/serializers/video/video_processing_history.py +20 -5
- endoreg_db/services/__old/pdf_import.py +1487 -0
- endoreg_db/services/__old/video_import.py +1306 -0
- endoreg_db/services/anonymization.py +128 -89
- endoreg_db/services/lookup_service.py +65 -52
- endoreg_db/services/lookup_store.py +2 -2
- endoreg_db/services/pdf_import.py +0 -1382
- endoreg_db/services/report_import.py +10 -0
- endoreg_db/services/video_import.py +6 -1255
- endoreg_db/tasks/upload_tasks.py +79 -70
- endoreg_db/tasks/video_ingest.py +8 -4
- endoreg_db/urls/__init__.py +5 -32
- endoreg_db/urls/ai.py +32 -0
- endoreg_db/urls/media.py +121 -83
- 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 +142 -40
- endoreg_db/utils/defaults/set_default_center.py +32 -0
- endoreg_db/utils/names.py +22 -16
- endoreg_db/utils/paths.py +110 -46
- endoreg_db/utils/permissions.py +2 -1
- endoreg_db/utils/pipelines/Readme.md +1 -1
- endoreg_db/utils/pipelines/process_video_dir.py +1 -1
- endoreg_db/utils/requirement_operator_logic/_old/model_evaluators.py +655 -0
- endoreg_db/utils/requirement_operator_logic/new_operator_logic.py +97 -0
- 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 +85 -183
- endoreg_db/views/ai/__init__.py +8 -0
- endoreg_db/views/ai/label.py +155 -0
- endoreg_db/views/anonymization/media_management.py +202 -166
- endoreg_db/views/anonymization/overview.py +99 -67
- endoreg_db/views/anonymization/validate.py +182 -44
- endoreg_db/views/media/__init__.py +7 -20
- endoreg_db/views/media/pdf_media.py +197 -174
- endoreg_db/views/media/sensitive_metadata.py +193 -138
- endoreg_db/views/media/video_media.py +89 -82
- endoreg_db/views/meta/__init__.py +0 -8
- endoreg_db/views/misc/__init__.py +1 -7
- endoreg_db/views/misc/upload_views.py +94 -93
- endoreg_db/views/patient/patient.py +5 -4
- endoreg_db/views/report/__init__.py +5 -7
- endoreg_db/views/{pdf → report}/reimport.py +22 -22
- endoreg_db/views/{pdf/pdf_stream.py → report/report_stream.py} +46 -39
- endoreg_db/views/requirement/evaluate.py +188 -187
- endoreg_db/views/requirement/lookup.py +17 -3
- endoreg_db/views/requirement/lookup_store.py +22 -90
- endoreg_db/views/requirement/requirement_utils.py +89 -0
- endoreg_db/views/video/__init__.py +23 -24
- endoreg_db/views/video/correction.py +201 -172
- endoreg_db/views/video/reimport.py +1 -1
- endoreg_db/views/{media/video_segments.py → video/segments_crud.py} +77 -40
- endoreg_db/views/video/{video_meta.py → video_meta_stats.py} +2 -2
- endoreg_db/views/video/video_stream.py +7 -8
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/METADATA +7 -3
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/RECORD +391 -413
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/WHEEL +1 -1
- endoreg_db/data/finding/anatomy_colon.yaml +0 -128
- endoreg_db/data/finding/colonoscopy.yaml +0 -40
- endoreg_db/data/finding/colonoscopy_bowel_prep.yaml +0 -56
- endoreg_db/data/finding/complication.yaml +0 -16
- endoreg_db/data/finding/data.yaml +0 -105
- endoreg_db/data/finding/examination_setting.yaml +0 -16
- endoreg_db/data/finding/medication_related.yaml +0 -18
- endoreg_db/data/finding/outcome.yaml +0 -12
- endoreg_db/data/finding_classification/colonoscopy_bowel_preparation.yaml +0 -95
- endoreg_db/data/finding_classification/colonoscopy_jnet.yaml +0 -22
- endoreg_db/data/finding_classification/colonoscopy_kudo.yaml +0 -25
- endoreg_db/data/finding_classification/colonoscopy_lesion_circularity.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_lesion_planarity.yaml +0 -24
- endoreg_db/data/finding_classification/colonoscopy_lesion_size.yaml +0 -68
- endoreg_db/data/finding_classification/colonoscopy_lesion_surface.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_location.yaml +0 -80
- endoreg_db/data/finding_classification/colonoscopy_lst.yaml +0 -21
- endoreg_db/data/finding_classification/colonoscopy_nice.yaml +0 -20
- endoreg_db/data/finding_classification/colonoscopy_paris.yaml +0 -26
- endoreg_db/data/finding_classification/colonoscopy_sano.yaml +0 -22
- endoreg_db/data/finding_classification/colonoscopy_summary.yaml +0 -53
- endoreg_db/data/finding_classification/complication_generic.yaml +0 -25
- endoreg_db/data/finding_classification/examination_setting_generic.yaml +0 -40
- endoreg_db/data/finding_classification/histology_colo.yaml +0 -51
- endoreg_db/data/finding_classification/intervention_required.yaml +0 -26
- endoreg_db/data/finding_classification/medication_related.yaml +0 -23
- endoreg_db/data/finding_classification/visualized.yaml +0 -33
- endoreg_db/data/finding_classification_choice/colon_lesion_circularity_default.yaml +0 -32
- endoreg_db/data/finding_classification_choice/colon_lesion_jnet.yaml +0 -15
- endoreg_db/data/finding_classification_choice/colon_lesion_kudo.yaml +0 -23
- endoreg_db/data/finding_classification_choice/colon_lesion_lst.yaml +0 -15
- endoreg_db/data/finding_classification_choice/colon_lesion_nice.yaml +0 -17
- endoreg_db/data/finding_classification_choice/colon_lesion_planarity_default.yaml +0 -49
- endoreg_db/data/finding_classification_choice/colon_lesion_sano.yaml +0 -14
- endoreg_db/data/finding_classification_choice/colon_lesion_surface_intact_default.yaml +0 -36
- endoreg_db/data/finding_classification_choice/colonoscopy_size.yaml +0 -82
- endoreg_db/data/finding_classification_choice/colonoscopy_summary_worst_finding.yaml +0 -15
- endoreg_db/data/finding_classification_choice/outcome.yaml +0 -19
- endoreg_db/data/finding_intervention/endoscopy.yaml +0 -43
- endoreg_db/data/finding_intervention/endoscopy_colonoscopy.yaml +0 -168
- endoreg_db/data/finding_intervention/endoscopy_egd.yaml +0 -128
- endoreg_db/data/finding_intervention/endoscopy_ercp.yaml +0 -32
- endoreg_db/data/finding_intervention/endoscopy_eus_lower.yaml +0 -9
- endoreg_db/data/finding_intervention/endoscopy_eus_upper.yaml +0 -36
- endoreg_db/data/finding_morphology_classification_type/colonoscopy.yaml +0 -79
- endoreg_db/data/requirement/age.yaml +0 -26
- endoreg_db/data/requirement/gender.yaml +0 -25
- endoreg_db/management/commands/init_default_ai_model.py +0 -112
- endoreg_db/management/commands/reset_celery_schedule.py +0 -9
- endoreg_db/management/commands/validate_video.py +0 -204
- endoreg_db/migrations/0002_add_video_correction_models.py +0 -52
- endoreg_db/migrations/0003_add_center_display_name.py +0 -30
- endoreg_db/models/administration/permissions/__init__.py +0 -44
- 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/renames.yml +0 -8
- endoreg_db/serializers/_old/raw_pdf_meta_validation.py +0 -223
- endoreg_db/serializers/_old/raw_video_meta_validation.py +0 -179
- endoreg_db/serializers/_old/video.py +0 -71
- endoreg_db/serializers/meta/pdf_file_meta_extraction.py +0 -115
- endoreg_db/serializers/meta/report_meta.py +0 -53
- endoreg_db/serializers/report/__init__.py +0 -9
- endoreg_db/serializers/report/mixins.py +0 -45
- endoreg_db/serializers/report/report.py +0 -105
- endoreg_db/serializers/report/report_list.py +0 -22
- endoreg_db/serializers/report/secure_file_url.py +0 -26
- endoreg_db/serializers/video/video_metadata.py +0 -105
- endoreg_db/services/requirements_object.py +0 -147
- endoreg_db/services/storage_aware_video_processor.py +0 -344
- endoreg_db/urls/files.py +0 -6
- endoreg_db/urls/label_video_segment_validate.py +0 -33
- endoreg_db/urls/label_video_segments.py +0 -46
- 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/utils/requirement_operator_logic/model_evaluators.py +0 -368
- endoreg_db/views/label/__init__.py +0 -5
- endoreg_db/views/label/label.py +0 -15
- endoreg_db/views/label_video_segment/__init__.py +0 -16
- endoreg_db/views/label_video_segment/create_lvs_from_annotation.py +0 -44
- endoreg_db/views/label_video_segment/get_lvs_by_name_and_video.py +0 -50
- endoreg_db/views/label_video_segment/label_video_segment.py +0 -77
- endoreg_db/views/label_video_segment/label_video_segment_by_label.py +0 -174
- endoreg_db/views/label_video_segment/label_video_segment_detail.py +0 -73
- endoreg_db/views/label_video_segment/update_lvs_from_annotation.py +0 -46
- endoreg_db/views/label_video_segment/validate.py +0 -226
- endoreg_db/views/media/segments.py +0 -71
- endoreg_db/views/meta/available_files_list.py +0 -146
- endoreg_db/views/meta/report_meta.py +0 -53
- endoreg_db/views/meta/sensitive_meta_detail.py +0 -148
- endoreg_db/views/misc/secure_file_serving_view.py +0 -80
- endoreg_db/views/misc/secure_file_url_view.py +0 -84
- endoreg_db/views/misc/secure_url_validate.py +0 -79
- endoreg_db/views/patient_examination/DEPRECATED_video_backup.py +0 -164
- endoreg_db/views/patient_finding_location/__init__.py +0 -5
- endoreg_db/views/patient_finding_location/pfl_create.py +0 -70
- endoreg_db/views/patient_finding_morphology/__init__.py +0 -5
- endoreg_db/views/patient_finding_morphology/pfm_create.py +0 -70
- endoreg_db/views/pdf/__init__.py +0 -8
- 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/segmentation.py +0 -274
- endoreg_db/views/video/task_status.py +0 -49
- endoreg_db/views/video/timeline.py +0 -46
- endoreg_db/views/video/video_analyze.py +0 -52
- endoreg_db/views.py +0 -0
- /endoreg_db/data/requirement/{colonoscopy_baseline_austria.yaml → old/colonoscopy_baseline_austria.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_cardiovascular.yaml → old/disease_cardiovascular.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_classification_choice_cardiovascular.yaml → old/disease_classification_choice_cardiovascular.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_hepatology.yaml → old/disease_hepatology.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_misc.yaml → old/disease_misc.yaml} +0 -0
- /endoreg_db/data/requirement/{disease_renal.yaml → old/disease_renal.yaml} +0 -0
- /endoreg_db/data/requirement/{endoscopy_bleeding_risk.yaml → old/endoscopy_bleeding_risk.yaml} +0 -0
- /endoreg_db/data/requirement/{event_cardiology.yaml → old/event_cardiology.yaml} +0 -0
- /endoreg_db/data/requirement/{event_requirements.yaml → old/event_requirements.yaml} +0 -0
- /endoreg_db/data/requirement/{finding_colon_polyp.yaml → old/finding_colon_polyp.yaml} +0 -0
- /endoreg_db/{migrations/__init__.py → data/requirement/old/gender.yaml} +0 -0
- /endoreg_db/data/requirement/{lab_value.yaml → old/lab_value.yaml} +0 -0
- /endoreg_db/data/requirement/{medication.yaml → old/medication.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{age.yaml → _old/age.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{lab_operators.yaml → _old/lab_operators.yaml} +0 -0
- /endoreg_db/data/requirement_operator/{model_operators.yaml → _old/model_operators.yaml} +0 -0
- /endoreg_db/{models/media/video/refactor_plan.md → import_files/pseudonymization/__init__.py} +0 -0
- /endoreg_db/{models/media/video/video_file_frames.py → import_files/pseudonymization/pseudonymize.py} +0 -0
- /endoreg_db/models/{metadata/frame_ocr_result.py → report/__init__.py} +0 -0
- /endoreg_db/{urls/sensitive_meta.py → models/report/images.py} +0 -0
- /endoreg_db/utils/requirement_operator_logic/{lab_value_operators.py → _old/lab_value_operators.py} +0 -0
- {endoreg_db-0.8.6.1.dist-info → endoreg_db-0.8.8.9.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import RawPdfFile
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
from django.http import Http404, HttpResponse
|
|
5
|
-
from django.shortcuts import get_object_or_404
|
|
6
|
-
from rest_framework import status
|
|
7
|
-
from rest_framework.response import Response
|
|
8
|
-
from rest_framework.views import APIView
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
import logging
|
|
13
|
-
from ...utils.paths import data_paths # Added for centralized path management
|
|
14
|
-
logger = logging.getLogger(__name__)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class SecureFileServingView(APIView):
|
|
19
|
-
"""
|
|
20
|
-
Serviert Dateien über sichere URLs mit Token-Validierung
|
|
21
|
-
GET /api/reports/{report_id}/secure-file/?token={token}
|
|
22
|
-
"""
|
|
23
|
-
|
|
24
|
-
def get(self, request, report_id):
|
|
25
|
-
token = request.GET.get('token')
|
|
26
|
-
|
|
27
|
-
if not token:
|
|
28
|
-
return Response(
|
|
29
|
-
{"error": "Token ist erforderlich"},
|
|
30
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
try:
|
|
34
|
-
report = get_object_or_404(RawPdfFile, id=report_id)
|
|
35
|
-
|
|
36
|
-
if not report.file:
|
|
37
|
-
raise Http404("Datei nicht gefunden")
|
|
38
|
-
|
|
39
|
-
# Token validieren (hier würde normalerweise eine Token-Speicherung/Validierung stattfinden)
|
|
40
|
-
# Für diese Implementierung nehmen wir an, dass das Token gültig ist
|
|
41
|
-
|
|
42
|
-
# Datei servieren
|
|
43
|
-
return self._serve_file(report.file)
|
|
44
|
-
|
|
45
|
-
except (ValueError, TypeError, OSError) as e:
|
|
46
|
-
logger.error("Fehler beim Servieren der Datei: %s", str(e))
|
|
47
|
-
raise Http404("Datei konnte nicht geladen werden") from e
|
|
48
|
-
|
|
49
|
-
def _serve_file(self, file_field):
|
|
50
|
-
"""Serviert die Datei als HTTP-Response"""
|
|
51
|
-
try:
|
|
52
|
-
file_path = Path(file_field.path)
|
|
53
|
-
|
|
54
|
-
with open(file_field.path, 'rb') as f:
|
|
55
|
-
response = HttpResponse(
|
|
56
|
-
f.read(),
|
|
57
|
-
content_type=self._get_content_type(file_path.suffix)
|
|
58
|
-
)
|
|
59
|
-
response['Content-Disposition'] = f'inline; filename="{file_path.name}"'
|
|
60
|
-
return response
|
|
61
|
-
|
|
62
|
-
except (OSError, IOError) as e:
|
|
63
|
-
logger.error("Fehler beim Lesen der Datei: %s", str(e))
|
|
64
|
-
raise Http404("Datei konnte nicht gelesen werden") from e
|
|
65
|
-
|
|
66
|
-
def _get_content_type(self, file_extension):
|
|
67
|
-
"""Ermittelt den Content-Type basierend auf der Dateiendung"""
|
|
68
|
-
content_types = {
|
|
69
|
-
'.pdf': 'application/pdf',
|
|
70
|
-
'.jpg': 'image/jpeg',
|
|
71
|
-
'.jpeg': 'image/jpeg',
|
|
72
|
-
'.png': 'image/png',
|
|
73
|
-
'.gif': 'image/gif',
|
|
74
|
-
'.bmp': 'image/bmp',
|
|
75
|
-
'.webp': 'image/webp',
|
|
76
|
-
'.txt': 'text/plain',
|
|
77
|
-
'.doc': 'application/msword',
|
|
78
|
-
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
79
|
-
}
|
|
80
|
-
return content_types.get(file_extension.lower(), 'application/octet-stream')
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
from endoreg_db.models import RawPdfFile
|
|
2
|
-
from endoreg_db.serializers.report.secure_file_url import SecureFileUrlSerializer
|
|
3
|
-
|
|
4
|
-
from django.shortcuts import get_object_or_404
|
|
5
|
-
from django.utils import timezone
|
|
6
|
-
from rest_framework import status
|
|
7
|
-
from rest_framework.response import Response
|
|
8
|
-
from rest_framework.views import APIView
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
import uuid
|
|
12
|
-
from datetime import timedelta
|
|
13
|
-
from pathlib import Path
|
|
14
|
-
|
|
15
|
-
import logging
|
|
16
|
-
from ...utils.paths import data_paths # Added for centralized path management
|
|
17
|
-
logger = logging.getLogger(__name__)
|
|
18
|
-
|
|
19
|
-
class SecureFileUrlView(APIView):
|
|
20
|
-
"""
|
|
21
|
-
API-Endpunkt für sichere URL-Generierung
|
|
22
|
-
POST /api/secure-file-urls/
|
|
23
|
-
"""
|
|
24
|
-
|
|
25
|
-
def post(self, request):
|
|
26
|
-
report_id = request.data.get('report_id')
|
|
27
|
-
file_type = request.data.get('file_type', 'pdf')
|
|
28
|
-
|
|
29
|
-
if not report_id:
|
|
30
|
-
return Response(
|
|
31
|
-
{"error": "report_id ist erforderlich"},
|
|
32
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
try:
|
|
36
|
-
report = get_object_or_404(RawPdfFile, id=report_id)
|
|
37
|
-
|
|
38
|
-
if not report.file:
|
|
39
|
-
return Response(
|
|
40
|
-
{"error": "Keine Datei für diesen Report verfügbar"},
|
|
41
|
-
status=status.HTTP_404_NOT_FOUND
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
# Sichere URL generieren
|
|
45
|
-
secure_url_data = self._generate_secure_url(report, request, file_type)
|
|
46
|
-
serializer = SecureFileUrlSerializer(data=secure_url_data)
|
|
47
|
-
|
|
48
|
-
if serializer.is_valid():
|
|
49
|
-
return Response(serializer.data)
|
|
50
|
-
else:
|
|
51
|
-
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
|
52
|
-
|
|
53
|
-
except (ValueError, TypeError) as e:
|
|
54
|
-
logger.error("Fehler beim Generieren der sicheren URL: %s", str(e))
|
|
55
|
-
return Response(
|
|
56
|
-
{"error": "Sichere URL konnte nicht generiert werden"},
|
|
57
|
-
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
def _generate_secure_url(self, report, request, file_type):
|
|
61
|
-
"""Generiert eine sichere URL mit Token"""
|
|
62
|
-
token = str(uuid.uuid4())
|
|
63
|
-
expires_at = timezone.now() + timedelta(hours=2)
|
|
64
|
-
|
|
65
|
-
secure_url = request.build_absolute_uri(
|
|
66
|
-
f"/api/reports/{report.id}/secure-file/?token={token}"
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
# Dateigröße ermitteln
|
|
70
|
-
file_size = 0
|
|
71
|
-
try:
|
|
72
|
-
if report.file:
|
|
73
|
-
file_size = report.file.size
|
|
74
|
-
except OSError:
|
|
75
|
-
# Datei nicht verfügbar
|
|
76
|
-
file_size = 0
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
'url': secure_url,
|
|
80
|
-
'expires_at': expires_at,
|
|
81
|
-
'file_type': file_type,
|
|
82
|
-
'original_filename': Path(report.file.name).name if report.file else 'unknown',
|
|
83
|
-
'file_size': file_size
|
|
84
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# endoreg_db/views/misc/secure_url_validate.py
|
|
2
|
-
|
|
3
|
-
from urllib.parse import urlparse
|
|
4
|
-
|
|
5
|
-
from django.core.exceptions import ValidationError
|
|
6
|
-
from django.core.validators import URLValidator
|
|
7
|
-
|
|
8
|
-
from rest_framework import status
|
|
9
|
-
from rest_framework.decorators import api_view, throttle_classes
|
|
10
|
-
from rest_framework.response import Response
|
|
11
|
-
from rest_framework.throttling import ScopedRateThrottle
|
|
12
|
-
|
|
13
|
-
import logging
|
|
14
|
-
logger = logging.getLogger(__name__)
|
|
15
|
-
|
|
16
|
-
# Accept only http/https; adjust if you later need custom schemes
|
|
17
|
-
_url_validator = URLValidator(schemes=["http", "https"])
|
|
18
|
-
_MAX_URL_LENGTH = 2048 # pragmatic upper bound to avoid abuse
|
|
19
|
-
|
|
20
|
-
@api_view(['GET'])
|
|
21
|
-
@throttle_classes([ScopedRateThrottle]) # 429s will be returned automatically if exceeded
|
|
22
|
-
def validate_secure_url(request):
|
|
23
|
-
"""
|
|
24
|
-
Validiert eine sichere URL
|
|
25
|
-
GET /api/validate-secure-url/?url={url}
|
|
26
|
-
"""
|
|
27
|
-
url = request.GET.get('url')
|
|
28
|
-
|
|
29
|
-
if not url:
|
|
30
|
-
return Response(
|
|
31
|
-
{"error": "URL Parameter ist erforderlich"},
|
|
32
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
# Basic length guardrails
|
|
36
|
-
if len(url) > _MAX_URL_LENGTH:
|
|
37
|
-
return Response(
|
|
38
|
-
{"error": "URL ist zu lang"},
|
|
39
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
# Syntactic + scheme validation
|
|
43
|
-
try:
|
|
44
|
-
_url_validator(url)
|
|
45
|
-
except ValidationError:
|
|
46
|
-
return Response(
|
|
47
|
-
{"error": "Ungültiges URL-Format (erlaubt sind http/https)"},
|
|
48
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
49
|
-
)
|
|
50
|
-
|
|
51
|
-
# Extra cheap sanity checks (netloc must exist, no data/file/javascript, etc.)
|
|
52
|
-
parsed = urlparse(url)
|
|
53
|
-
if not parsed.netloc:
|
|
54
|
-
return Response(
|
|
55
|
-
{"error": "Ungültige URL: Hostname fehlt"},
|
|
56
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
try:
|
|
60
|
-
# Hier würde normalerweise eine Token-Validierung stattfinden
|
|
61
|
-
# Für diese Implementierung geben wir immer True zurück
|
|
62
|
-
is_valid = True
|
|
63
|
-
|
|
64
|
-
return Response({
|
|
65
|
-
"is_valid": is_valid,
|
|
66
|
-
"message": "URL ist gültig" if is_valid else "URL ist ungültig oder abgelaufen"
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
except (ValueError, TypeError) as e:
|
|
70
|
-
logger.error("Fehler bei URL-Validierung: %s", str(e))
|
|
71
|
-
return Response(
|
|
72
|
-
{"error": "URL-Validierung fehlgeschlagen"},
|
|
73
|
-
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
# Assign a throttle scope so we can configure a specific rate in settings
|
|
77
|
-
validate_secure_url.throttle_scope = "secure-url-validate"
|
|
78
|
-
|
|
79
|
-
# for update got to base_settings.py
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
# from rest_framework import viewsets, status
|
|
2
|
-
# from rest_framework.response import Response
|
|
3
|
-
# from django.shortcuts import get_object_or_404
|
|
4
|
-
# from endoreg_db.models import Examination, VideoFile, Finding, FindingClassification
|
|
5
|
-
# from django.db import transaction
|
|
6
|
-
# from django.utils import timezone
|
|
7
|
-
# import logging
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# class VideoExaminationViewSet(viewsets.ModelViewSet):
|
|
11
|
-
# """
|
|
12
|
-
# ViewSet for Video Examination CRUD operations
|
|
13
|
-
# Handles POST and PATCH for video examinations at timestamps
|
|
14
|
-
# """
|
|
15
|
-
# def get_queryset(self):
|
|
16
|
-
# return []
|
|
17
|
-
|
|
18
|
-
# def create(self, request, *args, **kwargs):
|
|
19
|
-
|
|
20
|
-
# logger = logging.getLogger(__name__)
|
|
21
|
-
# try:
|
|
22
|
-
# data = request.data
|
|
23
|
-
# required_fields = ['videoId', 'timestamp', 'examinationTypeId', 'findingId']
|
|
24
|
-
# for field in required_fields:
|
|
25
|
-
# if field not in data or data[field] is None:
|
|
26
|
-
# return Response({'error': f'Missing or null required field: {field}'}, status=status.HTTP_400_BAD_REQUEST)
|
|
27
|
-
# try:
|
|
28
|
-
# video_id = int(data['videoId'])
|
|
29
|
-
# timestamp = float(data['timestamp'])
|
|
30
|
-
# examination_type_id = int(data['examinationTypeId'])
|
|
31
|
-
# finding_id = int(data['findingId'])
|
|
32
|
-
# except (ValueError, TypeError) as e:
|
|
33
|
-
# return Response({'error': f'Invalid data type in request: {str(e)}'}, status=status.HTTP_400_BAD_REQUEST)
|
|
34
|
-
# if timestamp < 0:
|
|
35
|
-
# return Response({'error': 'Timestamp cannot be negative'}, status=status.HTTP_400_BAD_REQUEST)
|
|
36
|
-
# with transaction.atomic():
|
|
37
|
-
# try:
|
|
38
|
-
# video = VideoFile.objects.get(id=video_id)
|
|
39
|
-
# except VideoFile.DoesNotExist:
|
|
40
|
-
# return Response({'error': 'Video not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
41
|
-
# try:
|
|
42
|
-
# examination = Examination.objects.get(id=examination_type_id)
|
|
43
|
-
# except Examination.DoesNotExist:
|
|
44
|
-
# return Response({'error': 'Examination type not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
45
|
-
# try:
|
|
46
|
-
# finding = Finding.objects.get(id=finding_id)
|
|
47
|
-
# except Finding.DoesNotExist:
|
|
48
|
-
# return Response({'error': 'Finding not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
49
|
-
# if data.get('locationClassificationId'):
|
|
50
|
-
# try:
|
|
51
|
-
# FindingClassification.objects.get(id=data['locationClassificationId'], classification_types__name__iexact="location")
|
|
52
|
-
# except FindingClassification.DoesNotExist:
|
|
53
|
-
# return Response({'error': 'Location classification not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
54
|
-
# if data.get('morphologyClassificationId'):
|
|
55
|
-
# try:
|
|
56
|
-
# FindingClassification.objects.get(id=data['morphologyClassificationId'], classification_types__name__iexact="morphology")
|
|
57
|
-
# except FindingClassification.DoesNotExist:
|
|
58
|
-
# return Response({'error': 'Morphology classification not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
59
|
-
# examination_data = {
|
|
60
|
-
# 'id': f"exam_{video.id}_{timestamp}_{examination.id}",
|
|
61
|
-
# 'video_id': video_id,
|
|
62
|
-
# 'timestamp': timestamp,
|
|
63
|
-
# 'examination_type': examination.name,
|
|
64
|
-
# 'finding': finding.name,
|
|
65
|
-
# 'location_classification': data.get('locationClassificationId'),
|
|
66
|
-
# 'location_choice': data.get('locationChoiceId'),
|
|
67
|
-
# 'morphology_classification': data.get('morphologyClassificationId'),
|
|
68
|
-
# 'morphology_choice': data.get('morphologyChoiceId'),
|
|
69
|
-
# 'interventions': data.get('interventionIds', []),
|
|
70
|
-
# 'notes': data.get('notes', ''),
|
|
71
|
-
# 'created_at': timezone.now().isoformat()
|
|
72
|
-
# }
|
|
73
|
-
# logger.info(f"Created video examination for video {video_id} at timestamp {timestamp}")
|
|
74
|
-
# return Response(examination_data, status=status.HTTP_201_CREATED)
|
|
75
|
-
# except Exception as e:
|
|
76
|
-
# logger.error(f"Unexpected error creating examination: {str(e)}")
|
|
77
|
-
# return Response({'error': 'Internal server error while creating examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
78
|
-
|
|
79
|
-
# def update(self, request, *args, **kwargs):
|
|
80
|
-
# logger = logging.getLogger(__name__)
|
|
81
|
-
# try:
|
|
82
|
-
# examination_id = kwargs.get('pk')
|
|
83
|
-
# if not examination_id:
|
|
84
|
-
# return Response({'error': 'Examination ID is required'}, status=status.HTTP_400_BAD_REQUEST)
|
|
85
|
-
# data = request.data
|
|
86
|
-
# if 'videoId' in data:
|
|
87
|
-
# try:
|
|
88
|
-
# data['videoId'] = int(data['videoId'])
|
|
89
|
-
# except (ValueError, TypeError):
|
|
90
|
-
# return Response({'error': 'Invalid videoId format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
91
|
-
# if 'timestamp' in data:
|
|
92
|
-
# try:
|
|
93
|
-
# timestamp = float(data['timestamp'])
|
|
94
|
-
# if timestamp < 0:
|
|
95
|
-
# return Response({'error': 'Timestamp cannot be negative'}, status=status.HTTP_400_BAD_REQUEST)
|
|
96
|
-
# data['timestamp'] = timestamp
|
|
97
|
-
# except (ValueError, TypeError):
|
|
98
|
-
# return Response({'error': 'Invalid timestamp format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
99
|
-
# with transaction.atomic():
|
|
100
|
-
# if 'videoId' in data:
|
|
101
|
-
# try:
|
|
102
|
-
# VideoFile.objects.get(id=data['videoId'])
|
|
103
|
-
# except VideoFile.DoesNotExist:
|
|
104
|
-
# return Response({'error': 'Video not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
105
|
-
# if 'examinationTypeId' in data:
|
|
106
|
-
# try:
|
|
107
|
-
# examination_type_id = int(data['examinationTypeId'])
|
|
108
|
-
# Examination.objects.get(id=examination_type_id)
|
|
109
|
-
# except (ValueError, TypeError):
|
|
110
|
-
# return Response({'error': 'Invalid examination type ID format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
111
|
-
# except Examination.DoesNotExist:
|
|
112
|
-
# return Response({'error': 'Examination type not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
113
|
-
# if 'findingId' in data:
|
|
114
|
-
# try:
|
|
115
|
-
# finding_id = int(data['findingId'])
|
|
116
|
-
# Finding.objects.get(id=finding_id)
|
|
117
|
-
# except (ValueError, TypeError):
|
|
118
|
-
# return Response({'error': 'Invalid finding ID format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
119
|
-
# except Finding.DoesNotExist:
|
|
120
|
-
# return Response({'error': 'Finding not found'}, status=status.HTTP_404_NOT_FOUND)
|
|
121
|
-
# examination_data = {
|
|
122
|
-
# 'id': examination_id,
|
|
123
|
-
# 'video_id': data.get('videoId'),
|
|
124
|
-
# 'timestamp': data.get('timestamp'),
|
|
125
|
-
# 'examination_type': data.get('examinationTypeId'),
|
|
126
|
-
# 'finding': data.get('findingId'),
|
|
127
|
-
# 'location_classification': data.get('locationClassificationId'),
|
|
128
|
-
# 'location_choice': data.get('locationChoiceId'),
|
|
129
|
-
# 'morphology_classification': data.get('morphologyClassificationId'),
|
|
130
|
-
# 'morphology_choice': data.get('morphologyChoiceId'),
|
|
131
|
-
# 'interventions': data.get('interventionIds', []),
|
|
132
|
-
# 'notes': data.get('notes', ''),
|
|
133
|
-
# 'updated_at': '2024-01-01T00:00:00Z'
|
|
134
|
-
# }
|
|
135
|
-
# logger.info(f"Updated video examination {examination_id}")
|
|
136
|
-
# return Response(examination_data, status=status.HTTP_200_OK)
|
|
137
|
-
# except Exception as e:
|
|
138
|
-
# logger.error(f"Unexpected error updating examination {examination_id}: {str(e)}")
|
|
139
|
-
# return Response({'error': 'Internal server error while updating examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
140
|
-
|
|
141
|
-
# def destroy(self, request, *args, **kwargs):
|
|
142
|
-
# logger = logging.getLogger(__name__)
|
|
143
|
-
# try:
|
|
144
|
-
# examination_id = kwargs.get('pk')
|
|
145
|
-
# if not examination_id:
|
|
146
|
-
# return Response({'error': 'Examination ID is required'}, status=status.HTTP_400_BAD_REQUEST)
|
|
147
|
-
# try:
|
|
148
|
-
# if not str(examination_id).strip():
|
|
149
|
-
# return Response({'error': 'Invalid examination ID format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
150
|
-
# except (ValueError, TypeError):
|
|
151
|
-
# return Response({'error': 'Invalid examination ID format'}, status=status.HTTP_400_BAD_REQUEST)
|
|
152
|
-
# with transaction.atomic():
|
|
153
|
-
# logger.info(f"Deleted video examination {examination_id}")
|
|
154
|
-
# return Response({'message': f'Examination {examination_id} deleted successfully'}, status=status.HTTP_204_NO_CONTENT)
|
|
155
|
-
# except Exception as e:
|
|
156
|
-
# logger.error(f"Unexpected error deleting examination {examination_id}: {str(e)}")
|
|
157
|
-
# return Response({'error': 'Internal server error while deleting examination'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
158
|
-
|
|
159
|
-
# from rest_framework.decorators import api_view
|
|
160
|
-
# @api_view(["GET"])
|
|
161
|
-
# def get_examinations_for_video(request, video_id):
|
|
162
|
-
# _video = get_object_or_404(VideoFile, id=video_id)
|
|
163
|
-
# #TODO no functionality implemented yet
|
|
164
|
-
# return Response([])
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
from endoreg_db.serializers.patient_finding.patient_finding import PatientFindingSerializer
|
|
2
|
-
from rest_framework.viewsets import ModelViewSet
|
|
3
|
-
from rest_framework.decorators import api_view, permission_classes
|
|
4
|
-
from rest_framework.response import Response
|
|
5
|
-
from rest_framework import status
|
|
6
|
-
from endoreg_db.models.medical.patient.patient_finding import PatientFinding
|
|
7
|
-
from endoreg_db.models.medical.patient.patient_finding_location import PatientFindingLocation
|
|
8
|
-
from endoreg_db.models.medical.patient.patient_finding_morphology import PatientFindingMorphology
|
|
9
|
-
from endoreg_db.models import ( FindingLocationClassificationChoice, FindingMorphologyClassificationChoice )
|
|
10
|
-
from rest_framework import serializers
|
|
11
|
-
from utils.permissions import EnvironmentAwarePermission
|
|
12
|
-
|
|
13
|
-
class PatientFindingViewSet(ModelViewSet):
|
|
14
|
-
queryset = PatientFinding.objects.all()
|
|
15
|
-
serializer_class = PatientFindingSerializer
|
|
16
|
-
|
|
17
|
-
@api_view(['POST'])
|
|
18
|
-
@permission_classes([EnvironmentAwarePermission])
|
|
19
|
-
def create_patient_finding_location(request):
|
|
20
|
-
"""
|
|
21
|
-
Create a patient finding location relationship.
|
|
22
|
-
Expected payload: {
|
|
23
|
-
"patient_finding_id": 1,
|
|
24
|
-
"location_classification_choice_id": 2
|
|
25
|
-
}
|
|
26
|
-
"""
|
|
27
|
-
try:
|
|
28
|
-
patient_finding_id = request.data.get('patient_finding_id')
|
|
29
|
-
choice_id = request.data.get('location_classification_choice_id')
|
|
30
|
-
|
|
31
|
-
if not patient_finding_id or not choice_id:
|
|
32
|
-
return Response(
|
|
33
|
-
{'detail': 'patient_finding_id and location_classification_choice_id are required'},
|
|
34
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
# Get the objects
|
|
38
|
-
try:
|
|
39
|
-
patient_finding = PatientFinding.objects.get(id=patient_finding_id)
|
|
40
|
-
except PatientFinding.DoesNotExist:
|
|
41
|
-
return Response(
|
|
42
|
-
{'detail': f'PatientFinding with id {patient_finding_id} not found'},
|
|
43
|
-
status=status.HTTP_404_NOT_FOUND
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
try:
|
|
47
|
-
choice = FindingLocationClassificationChoice.objects.get(id=choice_id)
|
|
48
|
-
except FindingLocationClassificationChoice.DoesNotExist:
|
|
49
|
-
return Response(
|
|
50
|
-
{'detail': f'LocationClassificationChoice with id {choice_id} not found'},
|
|
51
|
-
status=status.HTTP_404_NOT_FOUND
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
# Create the relationship
|
|
55
|
-
patient_finding_location = PatientFindingLocation.objects.create(
|
|
56
|
-
patient_finding=patient_finding,
|
|
57
|
-
location_classification_choice=choice
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
return Response({
|
|
61
|
-
'id': patient_finding_location.id,
|
|
62
|
-
'patient_finding_id': patient_finding.id,
|
|
63
|
-
'location_classification_choice_id': choice.id
|
|
64
|
-
}, status=status.HTTP_201_CREATED)
|
|
65
|
-
|
|
66
|
-
except Exception as e:
|
|
67
|
-
return Response(
|
|
68
|
-
{'detail': f'Error creating patient finding location: {str(e)}'},
|
|
69
|
-
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
70
|
-
)
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
from endoreg_db.serializers.patient_finding.patient_finding import PatientFindingSerializer
|
|
2
|
-
from rest_framework.viewsets import ModelViewSet
|
|
3
|
-
from rest_framework.decorators import api_view, permission_classes
|
|
4
|
-
from rest_framework.response import Response
|
|
5
|
-
from rest_framework import status
|
|
6
|
-
from endoreg_db.models.medical.patient.patient_finding import PatientFinding
|
|
7
|
-
from endoreg_db.models.medical.patient.patient_finding_location import PatientFindingLocation
|
|
8
|
-
from endoreg_db.models.medical.patient.patient_finding_morphology import PatientFindingMorphology
|
|
9
|
-
from endoreg_db.models import ( FindingLocationClassificationChoice, FindingMorphologyClassificationChoice)
|
|
10
|
-
from rest_framework import serializers
|
|
11
|
-
from utils.permissions import EnvironmentAwarePermission
|
|
12
|
-
|
|
13
|
-
class PatientFindingViewSet(ModelViewSet):
|
|
14
|
-
queryset = PatientFinding.objects.all()
|
|
15
|
-
serializer_class = PatientFindingSerializer
|
|
16
|
-
|
|
17
|
-
@api_view(['POST'])
|
|
18
|
-
@permission_classes([EnvironmentAwarePermission])
|
|
19
|
-
def create_patient_finding_morphology(request):
|
|
20
|
-
"""
|
|
21
|
-
Create a patient finding morphology relationship.
|
|
22
|
-
Expected payload: {
|
|
23
|
-
"patient_finding_id": 1,
|
|
24
|
-
"morphology_classification_choice_id": 2
|
|
25
|
-
}
|
|
26
|
-
"""
|
|
27
|
-
try:
|
|
28
|
-
patient_finding_id = request.data.get('patient_finding_id')
|
|
29
|
-
choice_id = request.data.get('morphology_classification_choice_id')
|
|
30
|
-
|
|
31
|
-
if not patient_finding_id or not choice_id:
|
|
32
|
-
return Response(
|
|
33
|
-
{'detail': 'patient_finding_id and morphology_classification_choice_id are required'},
|
|
34
|
-
status=status.HTTP_400_BAD_REQUEST
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
# Get the objects
|
|
38
|
-
try:
|
|
39
|
-
patient_finding = PatientFinding.objects.get(id=patient_finding_id)
|
|
40
|
-
except PatientFinding.DoesNotExist:
|
|
41
|
-
return Response(
|
|
42
|
-
{'detail': f'PatientFinding with id {patient_finding_id} not found'},
|
|
43
|
-
status=status.HTTP_404_NOT_FOUND
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
try:
|
|
47
|
-
choice = FindingMorphologyClassificationChoice.objects.get(id=choice_id)
|
|
48
|
-
except FindingMorphologyClassificationChoice.DoesNotExist:
|
|
49
|
-
return Response(
|
|
50
|
-
{'detail': f'MorphologyClassificationChoice with id {choice_id} not found'},
|
|
51
|
-
status=status.HTTP_404_NOT_FOUND
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
# Create the relationship
|
|
55
|
-
patient_finding_morphology = PatientFindingMorphology.objects.create(
|
|
56
|
-
patient_finding=patient_finding,
|
|
57
|
-
morphology_classification_choice=choice
|
|
58
|
-
)
|
|
59
|
-
|
|
60
|
-
return Response({
|
|
61
|
-
'id': patient_finding_morphology.id,
|
|
62
|
-
'patient_finding_id': patient_finding.id,
|
|
63
|
-
'morphology_classification_choice_id': choice.id
|
|
64
|
-
}, status=status.HTTP_201_CREATED)
|
|
65
|
-
|
|
66
|
-
except Exception as e:
|
|
67
|
-
return Response(
|
|
68
|
-
{'detail': f'Error creating patient finding morphology: {str(e)}'},
|
|
69
|
-
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
70
|
-
)
|