endoreg-db 0.3.4__py3-none-any.whl → 0.3.6__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.
- endoreg_db/admin.py +3 -3
- endoreg_db/apps.py +6 -6
- endoreg_db/data/__init__.py +65 -16
- endoreg_db/data/active_model/data.yaml +2 -2
- endoreg_db/data/case_template/rule/00_patient_lab_sample_add_default_value.yaml +167 -0
- endoreg_db/data/case_template/rule/01_patient-set-age.yaml +8 -0
- endoreg_db/data/case_template/rule/01_patient-set-gender.yaml +9 -0
- endoreg_db/data/case_template/rule/11_create_patient_lab_sample.yaml +23 -0
- endoreg_db/data/case_template/rule/12_create-patient_medication-anticoagulation.yaml +19 -0
- endoreg_db/data/case_template/rule/13_create-patient_medication_schedule-anticoagulation.yaml +19 -0
- endoreg_db/data/case_template/rule/19_create_patient.yaml +17 -0
- endoreg_db/data/case_template/rule_type/base_types.yaml +35 -0
- endoreg_db/data/case_template/rule_value_type/base_types.yaml +59 -0
- endoreg_db/data/case_template/template/base.yaml +8 -0
- endoreg_db/data/case_template/template_type/pre_endoscopy.yaml +3 -0
- endoreg_db/data/case_template/tmp/_rule_value +13 -0
- endoreg_db/data/case_template/tmp/rule/01_atrial_fibrillation.yaml +21 -0
- endoreg_db/data/case_template/tmp/rule/02_create_object.yaml +10 -0
- endoreg_db/data/case_template/tmp/template/atrial_fibrillation_low_risk.yaml +7 -0
- endoreg_db/data/center/data.yaml +60 -52
- endoreg_db/data/center_resource/green_endoscopy_dashboard_CenterResource.yaml +144 -0
- endoreg_db/data/center_waste/green_endoscopy_dashboard_CenterWaste.yaml +48 -0
- endoreg_db/data/disease/cardiovascular.yaml +37 -0
- endoreg_db/data/disease/hepatology.yaml +5 -0
- endoreg_db/data/disease/misc.yaml +6 -0
- endoreg_db/data/disease/renal.yaml +5 -0
- endoreg_db/data/disease_classification/chronic_kidney_disease.yaml +6 -0
- endoreg_db/data/disease_classification/coronary_vessel_disease.yaml +6 -0
- endoreg_db/data/disease_classification_choice/chronic_kidney_disease.yaml +41 -0
- endoreg_db/data/disease_classification_choice/coronary_vessel_disease.yaml +20 -0
- endoreg_db/data/distribution/date/patient.yaml +7 -0
- endoreg_db/data/distribution/single_categorical/patient.yaml +7 -0
- endoreg_db/data/emission_factor/green_endoscopy_dashboard_EmissionFactor.yaml +132 -0
- endoreg_db/data/endoscope_type/data.yaml +10 -10
- endoreg_db/data/endoscopy_processor/data.yaml +45 -45
- endoreg_db/data/event/cardiology.yaml +28 -0
- endoreg_db/data/event/neurology.yaml +14 -0
- endoreg_db/data/event/surgery.yaml +13 -0
- endoreg_db/data/event/thrombembolism.yaml +20 -0
- endoreg_db/data/examination/examinations/data.yaml +65 -16
- endoreg_db/data/examination/time/data.yaml +47 -47
- endoreg_db/data/examination/time-type/data.yaml +7 -7
- endoreg_db/data/examination/type/data.yaml +5 -5
- endoreg_db/data/gender/data.yaml +18 -0
- endoreg_db/data/information_source/data.yaml +30 -30
- endoreg_db/data/information_source/medication.yaml +6 -0
- endoreg_db/data/lab_value/cardiac_enzymes.yaml +31 -0
- endoreg_db/data/lab_value/coagulation.yaml +49 -0
- endoreg_db/data/lab_value/electrolytes.yaml +190 -0
- endoreg_db/data/lab_value/gastrointestinal_function.yaml +121 -0
- endoreg_db/data/lab_value/hematology.yaml +169 -0
- endoreg_db/data/lab_value/hormones.yaml +53 -0
- endoreg_db/data/lab_value/lipids.yaml +44 -0
- endoreg_db/data/lab_value/misc.yaml +30 -0
- endoreg_db/data/lab_value/renal_function.yaml +11 -0
- endoreg_db/data/label/label/data.yaml +62 -62
- endoreg_db/data/label/label-set/data.yaml +17 -17
- endoreg_db/data/label/label-type/data.yaml +6 -6
- endoreg_db/data/material/material.yaml +91 -0
- endoreg_db/data/medication/anticoagulation.yaml +65 -0
- endoreg_db/data/medication/tah.yaml +70 -0
- endoreg_db/data/medication_indication/anticoagulation.yaml +120 -0
- endoreg_db/data/medication_indication_type/data.yaml +11 -0
- endoreg_db/data/medication_indication_type/thrombembolism.yaml +41 -0
- endoreg_db/data/medication_intake_time/base.yaml +31 -0
- endoreg_db/data/medication_schedule/apixaban.yaml +95 -0
- endoreg_db/data/medication_schedule/ass.yaml +12 -0
- endoreg_db/data/medication_schedule/enoxaparin.yaml +26 -0
- endoreg_db/data/model_type/data.yaml +6 -6
- endoreg_db/data/patient_lab_sample_type/generic.yaml +6 -0
- endoreg_db/data/pdf_type/data.yaml +28 -28
- endoreg_db/data/product/green_endoscopy_dashboard_Product.yaml +66 -0
- endoreg_db/data/product_group/green_endoscopy_dashboard_ProductGroup.yaml +33 -0
- endoreg_db/data/product_material/green_endoscopy_dashboard_ProductMaterial.yaml +308 -0
- endoreg_db/data/product_weight/green_endoscopy_dashboard_ProductWeight.yaml +88 -0
- endoreg_db/data/profession/data.yaml +70 -70
- endoreg_db/data/reference_product/green_endoscopy_dashboard_ReferenceProduct.yaml +55 -0
- endoreg_db/data/report_reader_flag/ukw-examination-generic.yaml +26 -26
- endoreg_db/data/report_reader_flag/ukw-histology-generic.yaml +19 -19
- endoreg_db/data/resource/green_endoscopy_dashboard_Resource.yaml +15 -0
- endoreg_db/data/tmp/chronic_kidney_disease.yaml +0 -0
- endoreg_db/data/tmp/congestive_heart_failure.yaml +0 -0
- endoreg_db/data/transport_route/green_endoscopy_dashboard_TransportRoute.yaml +12 -0
- endoreg_db/data/unit/concentration.yaml +92 -0
- endoreg_db/data/unit/data.yaml +17 -17
- endoreg_db/data/unit/length.yaml +30 -30
- endoreg_db/data/unit/misc.yaml +20 -0
- endoreg_db/data/unit/rate.yaml +6 -0
- endoreg_db/data/unit/time.yaml +13 -0
- endoreg_db/data/unit/volume.yaml +35 -26
- endoreg_db/data/unit/weight.yaml +37 -30
- endoreg_db/data/waste/data.yaml +12 -0
- endoreg_db/forms/__init__.py +2 -2
- endoreg_db/forms/questionnaires/tto_questionnaire.py +23 -23
- endoreg_db/forms/settings/__init__.py +8 -8
- endoreg_db/forms/unit.py +5 -5
- endoreg_db/management/commands/_load_model_template.py +40 -40
- endoreg_db/management/commands/delete_all.py +18 -18
- endoreg_db/management/commands/delete_legacy_images.py +19 -19
- endoreg_db/management/commands/delete_legacy_videos.py +16 -16
- endoreg_db/management/commands/extract_legacy_video_frames.py +18 -18
- endoreg_db/management/commands/fetch_legacy_image_dataset.py +32 -32
- endoreg_db/management/commands/fix_auth_permission.py +20 -20
- endoreg_db/management/commands/import_legacy_images.py +94 -94
- endoreg_db/management/commands/import_legacy_videos.py +76 -76
- endoreg_db/management/commands/load_active_model_data.py +44 -44
- endoreg_db/management/commands/load_ai_model_data.py +44 -44
- endoreg_db/management/commands/load_base_db_data.py +128 -71
- endoreg_db/management/commands/load_center_data.py +42 -42
- endoreg_db/management/commands/load_disease_classification_choices_data.py +41 -0
- endoreg_db/management/commands/load_disease_classification_data.py +41 -0
- endoreg_db/management/commands/load_disease_data.py +40 -0
- endoreg_db/management/commands/load_distribution_data.py +66 -0
- endoreg_db/management/commands/load_endoscope_type_data.py +44 -44
- endoreg_db/management/commands/load_endoscopy_processor_data.py +44 -44
- endoreg_db/management/commands/load_event_data.py +41 -0
- endoreg_db/management/commands/load_examination_data.py +74 -74
- endoreg_db/management/commands/load_g_play_data.py +113 -0
- endoreg_db/management/commands/load_gender_data.py +44 -0
- endoreg_db/management/commands/load_green_endoscopy_wuerzburg_data.py +133 -0
- endoreg_db/management/commands/load_information_source.py +44 -44
- endoreg_db/management/commands/load_lab_value_data.py +50 -0
- endoreg_db/management/commands/load_label_data.py +66 -66
- endoreg_db/management/commands/load_medication_data.py +41 -0
- endoreg_db/management/commands/load_medication_indication_data.py +63 -0
- endoreg_db/management/commands/load_medication_indication_type_data.py +41 -0
- endoreg_db/management/commands/load_medication_intake_time_data.py +41 -0
- endoreg_db/management/commands/load_medication_schedule_data.py +55 -0
- endoreg_db/management/commands/load_pdf_type_data.py +60 -60
- endoreg_db/management/commands/load_profession_data.py +43 -43
- endoreg_db/management/commands/load_report_reader_flag.py +45 -45
- endoreg_db/management/commands/load_unit_data.py +45 -45
- endoreg_db/management/commands/load_user_groups.py +28 -28
- endoreg_db/management/commands/register_ai_model.py +65 -65
- endoreg_db/management/commands/reset_celery_schedule.py +9 -9
- endoreg_db/migrations/0001_initial.py +582 -582
- endoreg_db/migrations/0002_rawvideofile.py +26 -26
- endoreg_db/migrations/0003_rawvideofile_frames_required.py +18 -18
- endoreg_db/migrations/0004_rename_hash_rawvideofile_video_hash.py +18 -18
- endoreg_db/migrations/0005_ffmpegmeta_remove_videoimportmeta_center_and_more.py +56 -56
- endoreg_db/migrations/0006_rawvideofile_center_alter_videometa_processor.py +25 -25
- endoreg_db/migrations/0007_rawvideofile_processor.py +19 -19
- endoreg_db/migrations/0008_rename_frames_required_rawvideofile_state_frames_required.py +18 -18
- endoreg_db/migrations/0009_sensitivemeta_rawvideofile_sensitive_meta.py +31 -31
- endoreg_db/migrations/0010_rename_endoscope_serial_number_sensitivemeta_endoscope_sn.py +18 -18
- endoreg_db/migrations/0011_rawvideofile_state_sensitive_data_retrieved.py +18 -18
- endoreg_db/migrations/0012_rawvideofile_prediction_dir_and_more.py +109 -109
- endoreg_db/migrations/0013_rawpdffile.py +31 -31
- endoreg_db/migrations/0014_pdftype_alter_rawpdffile_file_pdfmeta.py +38 -38
- endoreg_db/migrations/0015_rename_report_processed_rawpdffile_state_report_processed_and_more.py +31 -31
- endoreg_db/migrations/0016_rawpdffile_state_report_processing_required.py +18 -18
- endoreg_db/migrations/0017_firstname_lastname_center_first_names_and_more.py +37 -37
- endoreg_db/migrations/0018_reportreaderflag_reportreaderconfig.py +37 -37
- endoreg_db/migrations/0019_pdftype_cut_off_above_lines_and_more.py +42 -42
- endoreg_db/migrations/0020_rename_endoscopy_info_line_pdftype_endoscope_info_line.py +18 -18
- endoreg_db/migrations/0021_alter_pdftype_endoscope_info_line.py +19 -19
- endoreg_db/migrations/0022_alter_pdftype_endoscope_info_line.py +19 -19
- endoreg_db/migrations/0023_ttoquestionnaire_alter_pdftype_endoscope_info_line.py +59 -59
- endoreg_db/migrations/0024_remove_ttoquestionnaire_infections_and_more.py +27 -27
- endoreg_db/migrations/0025_event_alter_rawpdffile_file_patientevent.py +42 -0
- endoreg_db/migrations/0026_disease_diseaseclassification_and_more.py +166 -0
- endoreg_db/migrations/0027_labvalue_abbreviation_labvalue_default_normal_range_and_more.py +38 -0
- endoreg_db/migrations/0028_alter_unit_abbreviation.py +18 -0
- endoreg_db/migrations/0029_medicationintaketime_and_more.py +75 -0
- endoreg_db/migrations/0030_medicationindicationtype_and_more.py +101 -0
- endoreg_db/migrations/0031_rename_adapt_to_liver_function_medication_adapt_to_age_and_more.py +38 -0
- endoreg_db/migrations/0032_alter_medicationschedule_therapy_duration_d.py +18 -0
- endoreg_db/migrations/0033_medicationindication_sources.py +18 -0
- endoreg_db/migrations/0034_alter_rawpdffile_file.py +20 -0
- endoreg_db/migrations/0035_alter_medicationindication_sources.py +18 -0
- endoreg_db/migrations/0036_alter_rawpdffile_file.py +20 -0
- endoreg_db/migrations/0037_alter_medicationindication_sources.py +18 -0
- endoreg_db/migrations/0038_emissionfactor_material_product_productgroup_and_more.py +164 -0
- endoreg_db/migrations/0039_referenceproduct_name.py +19 -0
- endoreg_db/migrations/0040_quizanswertype_quizquestiontype_quizquestion_and_more.py +50 -0
- endoreg_db/migrations/0041_gender_patientmedication_medication_indication_and_more.py +40 -0
- endoreg_db/migrations/0042_casetemplateruletype_casetemplaterulevalue_and_more.py +74 -0
- endoreg_db/migrations/0043_casetemplatetype_name_de_casetemplatetype_name_en.py +23 -0
- endoreg_db/migrations/0044_casetemplateruletype_name_de_and_more.py +23 -0
- endoreg_db/migrations/0045_casetemplaterulevalue_value_type.py +19 -0
- endoreg_db/migrations/0046_casetemplaterulevalue_target_field.py +18 -0
- endoreg_db/migrations/0047_casetemplaterule_target_model.py +18 -0
- endoreg_db/migrations/0048_remove_casetemplaterule_chained_rules_and_more.py +22 -0
- endoreg_db/migrations/0049_remove_casetemplaterule_rule_values.py +17 -0
- endoreg_db/migrations/0050_casetemplaterule_rule_values.py +18 -0
- endoreg_db/migrations/0051_remove_casetemplaterule_calling_rules_and_more.py +27 -0
- endoreg_db/migrations/0052_rename_case_template_type_casetemplate_template_type.py +18 -0
- endoreg_db/migrations/0053_patientlabsampletype_patientlabsample_and_more.py +38 -0
- endoreg_db/migrations/0054_multiplecategoricalvaluedistribution_and_more.py +69 -0
- endoreg_db/migrations/0055_remove_casetemplaterule_rule_values_and_more.py +59 -0
- endoreg_db/migrations/0056_datevaluedistribution_and_more.py +32 -0
- endoreg_db/migrations/0057_remove_datevaluedistribution_max_date_and_more.py +72 -0
- endoreg_db/migrations/0058_datevaluedistribution_description_and_more.py +28 -0
- endoreg_db/migrations/0059_casetemplaterule_rule_values.py +18 -0
- endoreg_db/migrations/0060_labvalue__default_date_value_distribution_and_more.py +44 -0
- endoreg_db/migrations/0061_remove_patientlabvalue_date_patientlabvalue_datetime.py +24 -0
- endoreg_db/migrations/0062_labvalue_numeric_precision.py +18 -0
- endoreg_db/migrations/0063_alter_labvalue_numeric_precision.py +18 -0
- endoreg_db/migrations/0064_casetemplaterule_extra_parameters_and_more.py +23 -0
- endoreg_db/migrations/0065_rename__date_value_distribution_casetemplaterule_date_value_distribution_and_more.py +58 -0
- endoreg_db/migrations/0066_alter_patientlabvalue_patient_and_more.py +29 -0
- endoreg_db/migrations/0067_alter_medicationindication_indication_type.py +19 -0
- endoreg_db/models/__init__.py +74 -57
- endoreg_db/models/ai_model/__init__.py +3 -3
- endoreg_db/models/ai_model/active_model.py +9 -9
- endoreg_db/models/ai_model/model_meta.py +24 -24
- endoreg_db/models/ai_model/model_type.py +25 -25
- endoreg_db/models/ai_model/utils.py +8 -8
- endoreg_db/models/annotation/__init__.py +1 -1
- endoreg_db/models/annotation/binary_classification_annotation_task.py +80 -80
- endoreg_db/models/annotation/image_classification.py +26 -26
- endoreg_db/models/case_template/__init__.py +6 -0
- endoreg_db/models/case_template/case_template.py +81 -0
- endoreg_db/models/case_template/case_template_rule.py +276 -0
- endoreg_db/models/case_template/case_template_rule_value.py +73 -0
- endoreg_db/models/case_template/case_template_type.py +28 -0
- endoreg_db/models/center/__init__.py +4 -0
- endoreg_db/models/{center.py → center/center.py} +24 -24
- endoreg_db/models/center/center_product.py +34 -0
- endoreg_db/models/center/center_resource.py +19 -0
- endoreg_db/models/center/center_waste.py +11 -0
- endoreg_db/models/data_file/__init__.py +5 -5
- endoreg_db/models/data_file/base_classes/__init__.py +2 -2
- endoreg_db/models/data_file/base_classes/abstract_frame.py +50 -50
- endoreg_db/models/data_file/base_classes/abstract_video.py +200 -200
- endoreg_db/models/data_file/frame.py +45 -45
- endoreg_db/models/data_file/import_classes/__init__.py +31 -31
- endoreg_db/models/data_file/import_classes/processing_functions/__init__.py +34 -34
- endoreg_db/models/data_file/import_classes/processing_functions/pdf.py +28 -28
- endoreg_db/models/data_file/import_classes/processing_functions/video.py +260 -260
- endoreg_db/models/data_file/import_classes/raw_pdf.py +188 -185
- endoreg_db/models/data_file/import_classes/raw_video.py +343 -343
- endoreg_db/models/data_file/metadata/__init__.py +3 -3
- endoreg_db/models/data_file/metadata/pdf_meta.py +70 -70
- endoreg_db/models/data_file/metadata/sensitive_meta.py +31 -31
- endoreg_db/models/data_file/metadata/video_meta.py +132 -131
- endoreg_db/models/data_file/report_file.py +89 -89
- endoreg_db/models/data_file/video/__init__.py +6 -6
- endoreg_db/models/data_file/video/import_meta.py +25 -25
- endoreg_db/models/data_file/video/video.py +25 -25
- endoreg_db/models/data_file/video_segment.py +107 -107
- endoreg_db/models/disease.py +56 -0
- endoreg_db/models/emission/__init__.py +1 -0
- endoreg_db/models/emission/emission_factor.py +20 -0
- endoreg_db/models/event.py +22 -0
- endoreg_db/models/examination/__init__.py +3 -3
- endoreg_db/models/examination/examination.py +26 -26
- endoreg_db/models/examination/examination_time.py +27 -27
- endoreg_db/models/examination/examination_time_type.py +24 -24
- endoreg_db/models/examination/examination_type.py +18 -18
- endoreg_db/models/hardware/__init__.py +1 -1
- endoreg_db/models/hardware/endoscope.py +44 -44
- endoreg_db/models/hardware/endoscopy_processor.py +143 -143
- endoreg_db/models/information_source.py +29 -22
- endoreg_db/models/label/label.py +84 -84
- endoreg_db/models/laboratory/__init__.py +1 -0
- endoreg_db/models/laboratory/lab_value.py +102 -0
- endoreg_db/models/legacy_data/__init__.py +3 -3
- endoreg_db/models/legacy_data/image.py +34 -34
- endoreg_db/models/medication/__init__.py +1 -0
- endoreg_db/models/medication/medication.py +148 -0
- endoreg_db/models/other/__init__.py +5 -0
- endoreg_db/models/other/distribution.py +215 -0
- endoreg_db/models/other/material.py +16 -0
- endoreg_db/models/other/resource.py +18 -0
- endoreg_db/models/other/transport_route.py +21 -0
- endoreg_db/models/other/waste.py +20 -0
- endoreg_db/models/patient_examination/__init__.py +35 -35
- endoreg_db/models/permissions/__init__.py +44 -44
- endoreg_db/models/persons/__init__.py +7 -6
- endoreg_db/models/persons/examiner/__init__.py +1 -1
- endoreg_db/models/persons/examiner/examiner.py +15 -15
- endoreg_db/models/persons/examiner/examiner_type.py +1 -1
- endoreg_db/models/persons/first_name.py +17 -17
- endoreg_db/models/persons/gender.py +22 -0
- endoreg_db/models/persons/last_name.py +19 -19
- endoreg_db/models/persons/patient/__init__.py +8 -0
- endoreg_db/models/persons/patient/case/__init__.py +0 -0
- endoreg_db/models/persons/patient/case/case.py +30 -0
- endoreg_db/models/persons/patient/patient.py +216 -0
- endoreg_db/models/persons/patient/patient_disease.py +16 -0
- endoreg_db/models/persons/patient/patient_event.py +22 -0
- endoreg_db/models/persons/patient/patient_lab_sample.py +106 -0
- endoreg_db/models/persons/patient/patient_lab_value.py +176 -0
- endoreg_db/models/persons/patient/patient_medication.py +44 -0
- endoreg_db/models/persons/patient/patient_medication_schedule.py +28 -0
- endoreg_db/models/persons/person.py +31 -34
- endoreg_db/models/persons/portal_user_information.py +27 -29
- endoreg_db/models/prediction/__init__.py +1 -1
- endoreg_db/models/prediction/image_classification.py +37 -37
- endoreg_db/models/prediction/video_prediction_meta.py +244 -244
- endoreg_db/models/product/__init__.py +5 -0
- endoreg_db/models/product/product.py +97 -0
- endoreg_db/models/product/product_group.py +19 -0
- endoreg_db/models/product/product_material.py +24 -0
- endoreg_db/models/product/product_weight.py +26 -0
- endoreg_db/models/product/reference_product.py +99 -0
- endoreg_db/models/questionnaires/__init__.py +114 -114
- endoreg_db/models/quiz/__init__.py +2 -0
- endoreg_db/models/quiz/quiz_answer.py +41 -0
- endoreg_db/models/quiz/quiz_question.py +54 -0
- endoreg_db/models/report_reader/__init__.py +1 -1
- endoreg_db/models/report_reader/report_reader_config.py +53 -53
- endoreg_db/models/report_reader/report_reader_flag.py +19 -19
- endoreg_db/models/rules/__init__.py +5 -0
- endoreg_db/models/rules/rule.py +24 -0
- endoreg_db/models/rules/rule_applicator.py +224 -0
- endoreg_db/models/rules/rule_attribute_dtype.py +19 -0
- endoreg_db/models/rules/rule_type.py +22 -0
- endoreg_db/models/rules/ruleset.py +19 -0
- endoreg_db/models/unit.py +21 -19
- endoreg_db/queries/__init__.py +4 -4
- endoreg_db/queries/annotations/__init__.py +2 -2
- endoreg_db/queries/annotations/legacy.py +159 -159
- endoreg_db/queries/get/__init__.py +5 -5
- endoreg_db/queries/get/center.py +42 -42
- endoreg_db/queries/get/model.py +13 -13
- endoreg_db/queries/get/patient.py +14 -14
- endoreg_db/queries/get/patient_examination.py +20 -20
- endoreg_db/queries/get/report_file.py +33 -33
- endoreg_db/queries/get/video.py +31 -31
- endoreg_db/serializers/__init__.py +9 -9
- endoreg_db/serializers/ai_model.py +18 -18
- endoreg_db/serializers/annotation.py +17 -17
- endoreg_db/serializers/center.py +11 -11
- endoreg_db/serializers/examination.py +32 -32
- endoreg_db/serializers/frame.py +13 -13
- endoreg_db/serializers/hardware.py +20 -20
- endoreg_db/serializers/label.py +22 -22
- endoreg_db/serializers/patient.py +10 -10
- endoreg_db/serializers/prediction.py +15 -15
- endoreg_db/serializers/report_file.py +7 -7
- endoreg_db/serializers/video.py +27 -27
- endoreg_db/tests.py +3 -3
- endoreg_db/utils/cropping.py +28 -28
- endoreg_db/utils/dataloader.py +92 -185
- endoreg_db/utils/file_operations.py +30 -30
- endoreg_db/utils/hashs.py +33 -33
- endoreg_db/utils/legacy_ocr.py +201 -201
- endoreg_db/utils/ocr.py +197 -197
- endoreg_db/utils/uuid.py +4 -4
- endoreg_db/utils/video_metadata.py +87 -87
- endoreg_db/views.py +3 -3
- {endoreg_db-0.3.4.dist-info → endoreg_db-0.3.6.dist-info}/LICENSE +674 -674
- {endoreg_db-0.3.4.dist-info → endoreg_db-0.3.6.dist-info}/METADATA +2 -2
- endoreg_db-0.3.6.dist-info/RECORD +357 -0
- {endoreg_db-0.3.4.dist-info → endoreg_db-0.3.6.dist-info}/WHEEL +1 -1
- endoreg_db/models/persons/patient.py +0 -58
- endoreg_db/models.py +0 -3
- endoreg_db-0.3.4.dist-info/RECORD +0 -185
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from .sensitive_meta import SensitiveMeta
|
|
2
|
-
from .pdf_meta import PdfMeta, PdfType
|
|
3
|
-
from .video_meta import VideoMeta, FFMpegMeta, VideoImportMeta
|
|
1
|
+
from .sensitive_meta import SensitiveMeta
|
|
2
|
+
from .pdf_meta import PdfMeta, PdfType
|
|
3
|
+
from .video_meta import VideoMeta, FFMpegMeta, VideoImportMeta
|
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
|
|
3
|
-
# import endoreg_center_id from django settings
|
|
4
|
-
from django.conf import settings
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# import File class
|
|
8
|
-
from django.core.files import File
|
|
9
|
-
|
|
10
|
-
# # check if endoreg_center_id is set
|
|
11
|
-
# if not hasattr(settings, 'ENDOREG_CENTER_ID'):
|
|
12
|
-
# ENDOREG_CENTER_ID = 9999
|
|
13
|
-
# else:
|
|
14
|
-
# ENDOREG_CENTER_ID = settings.ENDOREG_CENTER_ID
|
|
15
|
-
|
|
16
|
-
class PdfType(models.Model):
|
|
17
|
-
name = models.CharField(max_length=255)
|
|
18
|
-
|
|
19
|
-
patient_info_line = models.ForeignKey(
|
|
20
|
-
"ReportReaderFlag",
|
|
21
|
-
related_name="pdf_type_patient_info_line",
|
|
22
|
-
on_delete=models.CASCADE
|
|
23
|
-
)
|
|
24
|
-
endoscope_info_line = models.ForeignKey(
|
|
25
|
-
"ReportReaderFlag",
|
|
26
|
-
related_name="pdf_type_endoscopy_info_line",
|
|
27
|
-
on_delete=models.CASCADE,
|
|
28
|
-
)
|
|
29
|
-
examiner_info_line = models.ForeignKey(
|
|
30
|
-
"ReportReaderFlag",
|
|
31
|
-
related_name="pdf_type_examiner_info_line",
|
|
32
|
-
on_delete=models.CASCADE
|
|
33
|
-
)
|
|
34
|
-
cut_off_above_lines = models.ManyToManyField(
|
|
35
|
-
"ReportReaderFlag",
|
|
36
|
-
related_name="pdf_type_cut_off_above_lines",
|
|
37
|
-
)
|
|
38
|
-
cut_off_below_lines = models.ManyToManyField(
|
|
39
|
-
"ReportReaderFlag",
|
|
40
|
-
related_name="pdf_type_cut_off_below_lines",
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def __str__(self):
|
|
45
|
-
summary = f"{self.name}"
|
|
46
|
-
# add lines to summary
|
|
47
|
-
summary += f"\nPatient Info Line: {self.patient_info_line.value}"
|
|
48
|
-
summary += f"\nEndoscope Info Line: {self.endoscope_info_line.value}"
|
|
49
|
-
summary += f"\nExaminer Info Line: {self.examiner_info_line.value}"
|
|
50
|
-
summary += f"\nCut Off Above Lines: {[_.value for _ in self.cut_off_above_lines.all()]}"
|
|
51
|
-
summary += f"\nCut Off Below Lines: {[_.value for _ in self.cut_off_below_lines.all()]}"
|
|
52
|
-
|
|
53
|
-
return summary
|
|
54
|
-
|
|
55
|
-
class PdfMeta(models.Model):
|
|
56
|
-
pdf_type = models.ForeignKey(PdfType, on_delete=models.CASCADE)
|
|
57
|
-
date = models.DateField()
|
|
58
|
-
time = models.TimeField()
|
|
59
|
-
pdf_hash = models.CharField(max_length=255, unique=True)
|
|
60
|
-
|
|
61
|
-
def __str__(self):
|
|
62
|
-
return self.pdf_hash
|
|
63
|
-
|
|
64
|
-
@classmethod
|
|
65
|
-
def create_from_file(cls, pdf_file):
|
|
66
|
-
pdf_file = File(pdf_file)
|
|
67
|
-
pdf_meta = cls(file=pdf_file)
|
|
68
|
-
pdf_meta.save()
|
|
69
|
-
return pdf_meta
|
|
70
|
-
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
# import endoreg_center_id from django settings
|
|
4
|
+
from django.conf import settings
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# import File class
|
|
8
|
+
from django.core.files import File
|
|
9
|
+
|
|
10
|
+
# # check if endoreg_center_id is set
|
|
11
|
+
# if not hasattr(settings, 'ENDOREG_CENTER_ID'):
|
|
12
|
+
# ENDOREG_CENTER_ID = 9999
|
|
13
|
+
# else:
|
|
14
|
+
# ENDOREG_CENTER_ID = settings.ENDOREG_CENTER_ID
|
|
15
|
+
|
|
16
|
+
class PdfType(models.Model):
|
|
17
|
+
name = models.CharField(max_length=255)
|
|
18
|
+
|
|
19
|
+
patient_info_line = models.ForeignKey(
|
|
20
|
+
"ReportReaderFlag",
|
|
21
|
+
related_name="pdf_type_patient_info_line",
|
|
22
|
+
on_delete=models.CASCADE
|
|
23
|
+
)
|
|
24
|
+
endoscope_info_line = models.ForeignKey(
|
|
25
|
+
"ReportReaderFlag",
|
|
26
|
+
related_name="pdf_type_endoscopy_info_line",
|
|
27
|
+
on_delete=models.CASCADE,
|
|
28
|
+
)
|
|
29
|
+
examiner_info_line = models.ForeignKey(
|
|
30
|
+
"ReportReaderFlag",
|
|
31
|
+
related_name="pdf_type_examiner_info_line",
|
|
32
|
+
on_delete=models.CASCADE
|
|
33
|
+
)
|
|
34
|
+
cut_off_above_lines = models.ManyToManyField(
|
|
35
|
+
"ReportReaderFlag",
|
|
36
|
+
related_name="pdf_type_cut_off_above_lines",
|
|
37
|
+
)
|
|
38
|
+
cut_off_below_lines = models.ManyToManyField(
|
|
39
|
+
"ReportReaderFlag",
|
|
40
|
+
related_name="pdf_type_cut_off_below_lines",
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def __str__(self):
|
|
45
|
+
summary = f"{self.name}"
|
|
46
|
+
# add lines to summary
|
|
47
|
+
summary += f"\nPatient Info Line: {self.patient_info_line.value}"
|
|
48
|
+
summary += f"\nEndoscope Info Line: {self.endoscope_info_line.value}"
|
|
49
|
+
summary += f"\nExaminer Info Line: {self.examiner_info_line.value}"
|
|
50
|
+
summary += f"\nCut Off Above Lines: {[_.value for _ in self.cut_off_above_lines.all()]}"
|
|
51
|
+
summary += f"\nCut Off Below Lines: {[_.value for _ in self.cut_off_below_lines.all()]}"
|
|
52
|
+
|
|
53
|
+
return summary
|
|
54
|
+
|
|
55
|
+
class PdfMeta(models.Model):
|
|
56
|
+
pdf_type = models.ForeignKey(PdfType, on_delete=models.CASCADE)
|
|
57
|
+
date = models.DateField()
|
|
58
|
+
time = models.TimeField()
|
|
59
|
+
pdf_hash = models.CharField(max_length=255, unique=True)
|
|
60
|
+
|
|
61
|
+
def __str__(self):
|
|
62
|
+
return self.pdf_hash
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def create_from_file(cls, pdf_file):
|
|
66
|
+
pdf_file = File(pdf_file)
|
|
67
|
+
pdf_meta = cls(file=pdf_file)
|
|
68
|
+
pdf_meta.save()
|
|
69
|
+
return pdf_meta
|
|
70
|
+
|
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
|
|
3
|
-
class SensitiveMeta(models.Model):
|
|
4
|
-
examination_date = models.DateField(blank=True, null=True)
|
|
5
|
-
patient_first_name = models.CharField(max_length=255, blank=True, null=True)
|
|
6
|
-
patient_last_name = models.CharField(max_length=255, blank=True, null=True)
|
|
7
|
-
patient_dob = models.DateField(blank=True, null=True)
|
|
8
|
-
endoscope_type = models.CharField(max_length=255, blank=True, null=True)
|
|
9
|
-
endoscope_sn = models.CharField(max_length=255, blank=True, null=True)
|
|
10
|
-
|
|
11
|
-
@classmethod
|
|
12
|
-
def create_from_dict(cls, data: dict):
|
|
13
|
-
# data can contain more fields than the model has
|
|
14
|
-
field_names = [_.name for _ in cls._meta.fields]
|
|
15
|
-
selected_data = {k: v for k, v in data.items() if k in field_names}
|
|
16
|
-
|
|
17
|
-
return cls.objects.create(**selected_data)
|
|
18
|
-
|
|
19
|
-
def update_from_dict(self, data: dict):
|
|
20
|
-
# data can contain more fields than the model has
|
|
21
|
-
field_names = [_.name for _ in self._meta.fields]
|
|
22
|
-
selected_data = {k: v for k, v in data.items() if k in field_names}
|
|
23
|
-
|
|
24
|
-
for k, v in selected_data.items():
|
|
25
|
-
setattr(self, k, v)
|
|
26
|
-
|
|
27
|
-
self.save()
|
|
28
|
-
|
|
29
|
-
def __str__(self):
|
|
30
|
-
return f"SensitiveMeta: {self.examination_date} {self.patient_first_name} {self.patient_last_name} (*{self.patient_dob})"
|
|
31
|
-
|
|
1
|
+
from django.db import models
|
|
2
|
+
|
|
3
|
+
class SensitiveMeta(models.Model):
|
|
4
|
+
examination_date = models.DateField(blank=True, null=True)
|
|
5
|
+
patient_first_name = models.CharField(max_length=255, blank=True, null=True)
|
|
6
|
+
patient_last_name = models.CharField(max_length=255, blank=True, null=True)
|
|
7
|
+
patient_dob = models.DateField(blank=True, null=True)
|
|
8
|
+
endoscope_type = models.CharField(max_length=255, blank=True, null=True)
|
|
9
|
+
endoscope_sn = models.CharField(max_length=255, blank=True, null=True)
|
|
10
|
+
|
|
11
|
+
@classmethod
|
|
12
|
+
def create_from_dict(cls, data: dict):
|
|
13
|
+
# data can contain more fields than the model has
|
|
14
|
+
field_names = [_.name for _ in cls._meta.fields]
|
|
15
|
+
selected_data = {k: v for k, v in data.items() if k in field_names}
|
|
16
|
+
|
|
17
|
+
return cls.objects.create(**selected_data)
|
|
18
|
+
|
|
19
|
+
def update_from_dict(self, data: dict):
|
|
20
|
+
# data can contain more fields than the model has
|
|
21
|
+
field_names = [_.name for _ in self._meta.fields]
|
|
22
|
+
selected_data = {k: v for k, v in data.items() if k in field_names}
|
|
23
|
+
|
|
24
|
+
for k, v in selected_data.items():
|
|
25
|
+
setattr(self, k, v)
|
|
26
|
+
|
|
27
|
+
self.save()
|
|
28
|
+
|
|
29
|
+
def __str__(self):
|
|
30
|
+
return f"SensitiveMeta: {self.examination_date} {self.patient_first_name} {self.patient_last_name} (*{self.patient_dob})"
|
|
31
|
+
|
|
@@ -1,132 +1,133 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
import ffmpeg
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
# import endoreg_center_id from django settings
|
|
6
|
-
from django.conf import settings
|
|
7
|
-
|
|
8
|
-
# check if endoreg_center_id is set
|
|
9
|
-
if not hasattr(settings, 'ENDOREG_CENTER_ID'):
|
|
10
|
-
ENDOREG_CENTER_ID = 9999
|
|
11
|
-
else:
|
|
12
|
-
ENDOREG_CENTER_ID = settings.ENDOREG_CENTER_ID
|
|
13
|
-
|
|
14
|
-
# VideoMeta
|
|
15
|
-
class VideoMeta(models.Model):
|
|
16
|
-
processor = models.ForeignKey('EndoscopyProcessor', on_delete=models.CASCADE, blank=True, null=True)
|
|
17
|
-
endoscope = models.ForeignKey('Endoscope', on_delete=models.CASCADE, blank=True, null=True)
|
|
18
|
-
center = models.ForeignKey('Center', on_delete=models.CASCADE)
|
|
19
|
-
import_meta = models.OneToOneField('VideoImportMeta', on_delete=models.CASCADE, blank=True, null=True)
|
|
20
|
-
ffmpeg_meta = models.OneToOneField('FFMpegMeta', on_delete=models.CASCADE, blank=True, null=True)
|
|
21
|
-
|
|
22
|
-
def __str__(self):
|
|
23
|
-
|
|
24
|
-
processor_name = self.processor.name if self.processor is not None else "None"
|
|
25
|
-
endoscope_name = self.endoscope.name if self.endoscope is not None else "None"
|
|
26
|
-
center_name = self.center.name if self.center is not None else "None"
|
|
27
|
-
|
|
28
|
-
result_html = ""
|
|
29
|
-
|
|
30
|
-
result_html += f"Processor: {processor_name}<br>"
|
|
31
|
-
result_html += f"Endoscope: {endoscope_name}<br>"
|
|
32
|
-
result_html += f"Center: {center_name}<br>"
|
|
33
|
-
|
|
34
|
-
return result_html
|
|
35
|
-
|
|
36
|
-
# import meta should be created when video meta is created
|
|
37
|
-
def save(self, *args, **kwargs):
|
|
38
|
-
if self.import_meta is None:
|
|
39
|
-
self.import_meta = VideoImportMeta.objects.create()
|
|
40
|
-
super(VideoMeta, self).save(*args, **kwargs)
|
|
41
|
-
|
|
42
|
-
def initialize_ffmpeg_meta(self, file_path):
|
|
43
|
-
"""Initializes FFMpeg metadata for the video file if not already done."""
|
|
44
|
-
self.ffmpeg_meta = FFMpegMeta.create_from_file(Path(file_path))
|
|
45
|
-
self.save()
|
|
46
|
-
|
|
47
|
-
def update_meta(self, file_path):
|
|
48
|
-
"""Updates the video metadata from the file."""
|
|
49
|
-
self.initialize_ffmpeg_meta(file_path)
|
|
50
|
-
self.save()
|
|
51
|
-
|
|
52
|
-
def get_endo_roi(self):
|
|
53
|
-
endo_roi = self.processor.get_roi_endoscope_image()
|
|
54
|
-
return endo_roi
|
|
55
|
-
|
|
56
|
-
def get_fps(self):
|
|
57
|
-
if not self.ffmpeg_meta:
|
|
58
|
-
return None
|
|
59
|
-
|
|
60
|
-
return self.ffmpeg_meta.frame_rate
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
class FFMpegMeta(models.Model):
|
|
64
|
-
# Existing fields
|
|
65
|
-
duration = models.FloatField(blank=True, null=True)
|
|
66
|
-
width = models.IntegerField(blank=True, null=True)
|
|
67
|
-
height = models.IntegerField(blank=True, null=True)
|
|
68
|
-
frame_rate = models.FloatField(blank=True, null=True)
|
|
69
|
-
|
|
70
|
-
# New fields for comprehensive information
|
|
71
|
-
video_codec = models.CharField(max_length=50, blank=True, null=True)
|
|
72
|
-
audio_codec = models.CharField(max_length=50, blank=True, null=True)
|
|
73
|
-
audio_channels = models.IntegerField(blank=True, null=True)
|
|
74
|
-
audio_sample_rate = models.IntegerField(blank=True, null=True)
|
|
75
|
-
|
|
76
|
-
# Existing __str__ method can be updated to include new fields
|
|
77
|
-
|
|
78
|
-
@classmethod
|
|
79
|
-
def create_from_file(cls, file_path: Path):
|
|
80
|
-
"""Creates an FFMpegMeta instance from a video file using ffmpeg probe."""
|
|
81
|
-
try:
|
|
82
|
-
probe = ffmpeg.probe(
|
|
83
|
-
except ffmpeg.Error as e:
|
|
84
|
-
print(e.stderr)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
'
|
|
99
|
-
'
|
|
100
|
-
'
|
|
101
|
-
'
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
'
|
|
110
|
-
'
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
result_html += f"Video
|
|
129
|
-
result_html += f"
|
|
130
|
-
result_html += f"
|
|
131
|
-
result_html += f"
|
|
1
|
+
from django.db import models
|
|
2
|
+
import ffmpeg
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
# import endoreg_center_id from django settings
|
|
6
|
+
from django.conf import settings
|
|
7
|
+
|
|
8
|
+
# check if endoreg_center_id is set
|
|
9
|
+
if not hasattr(settings, 'ENDOREG_CENTER_ID'):
|
|
10
|
+
ENDOREG_CENTER_ID = 9999
|
|
11
|
+
else:
|
|
12
|
+
ENDOREG_CENTER_ID = settings.ENDOREG_CENTER_ID
|
|
13
|
+
|
|
14
|
+
# VideoMeta
|
|
15
|
+
class VideoMeta(models.Model):
|
|
16
|
+
processor = models.ForeignKey('EndoscopyProcessor', on_delete=models.CASCADE, blank=True, null=True)
|
|
17
|
+
endoscope = models.ForeignKey('Endoscope', on_delete=models.CASCADE, blank=True, null=True)
|
|
18
|
+
center = models.ForeignKey('Center', on_delete=models.CASCADE)
|
|
19
|
+
import_meta = models.OneToOneField('VideoImportMeta', on_delete=models.CASCADE, blank=True, null=True)
|
|
20
|
+
ffmpeg_meta = models.OneToOneField('FFMpegMeta', on_delete=models.CASCADE, blank=True, null=True)
|
|
21
|
+
|
|
22
|
+
def __str__(self):
|
|
23
|
+
|
|
24
|
+
processor_name = self.processor.name if self.processor is not None else "None"
|
|
25
|
+
endoscope_name = self.endoscope.name if self.endoscope is not None else "None"
|
|
26
|
+
center_name = self.center.name if self.center is not None else "None"
|
|
27
|
+
|
|
28
|
+
result_html = ""
|
|
29
|
+
|
|
30
|
+
result_html += f"Processor: {processor_name}<br>"
|
|
31
|
+
result_html += f"Endoscope: {endoscope_name}<br>"
|
|
32
|
+
result_html += f"Center: {center_name}<br>"
|
|
33
|
+
|
|
34
|
+
return result_html
|
|
35
|
+
|
|
36
|
+
# import meta should be created when video meta is created
|
|
37
|
+
def save(self, *args, **kwargs):
|
|
38
|
+
if self.import_meta is None:
|
|
39
|
+
self.import_meta = VideoImportMeta.objects.create()
|
|
40
|
+
super(VideoMeta, self).save(*args, **kwargs)
|
|
41
|
+
|
|
42
|
+
def initialize_ffmpeg_meta(self, file_path):
|
|
43
|
+
"""Initializes FFMpeg metadata for the video file if not already done."""
|
|
44
|
+
self.ffmpeg_meta = FFMpegMeta.create_from_file(Path(file_path))
|
|
45
|
+
self.save()
|
|
46
|
+
|
|
47
|
+
def update_meta(self, file_path):
|
|
48
|
+
"""Updates the video metadata from the file."""
|
|
49
|
+
self.initialize_ffmpeg_meta(file_path)
|
|
50
|
+
self.save()
|
|
51
|
+
|
|
52
|
+
def get_endo_roi(self):
|
|
53
|
+
endo_roi = self.processor.get_roi_endoscope_image()
|
|
54
|
+
return endo_roi
|
|
55
|
+
|
|
56
|
+
def get_fps(self):
|
|
57
|
+
if not self.ffmpeg_meta:
|
|
58
|
+
return None
|
|
59
|
+
|
|
60
|
+
return self.ffmpeg_meta.frame_rate
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class FFMpegMeta(models.Model):
|
|
64
|
+
# Existing fields
|
|
65
|
+
duration = models.FloatField(blank=True, null=True)
|
|
66
|
+
width = models.IntegerField(blank=True, null=True)
|
|
67
|
+
height = models.IntegerField(blank=True, null=True)
|
|
68
|
+
frame_rate = models.FloatField(blank=True, null=True)
|
|
69
|
+
|
|
70
|
+
# New fields for comprehensive information
|
|
71
|
+
video_codec = models.CharField(max_length=50, blank=True, null=True)
|
|
72
|
+
audio_codec = models.CharField(max_length=50, blank=True, null=True)
|
|
73
|
+
audio_channels = models.IntegerField(blank=True, null=True)
|
|
74
|
+
audio_sample_rate = models.IntegerField(blank=True, null=True)
|
|
75
|
+
|
|
76
|
+
# Existing __str__ method can be updated to include new fields
|
|
77
|
+
|
|
78
|
+
@classmethod
|
|
79
|
+
def create_from_file(cls, file_path: Path):
|
|
80
|
+
"""Creates an FFMpegMeta instance from a video file using ffmpeg probe."""
|
|
81
|
+
try:
|
|
82
|
+
probe = ffmpeg.probe(file_path.resolve().as_posix())
|
|
83
|
+
except: # ffmpeg.Error as e:
|
|
84
|
+
# print(e.stderr)
|
|
85
|
+
print(f"Error while probing {file_path}")
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
|
|
89
|
+
audio_streams = [stream for stream in probe['streams'] if stream['codec_type'] == 'audio']
|
|
90
|
+
|
|
91
|
+
# Check for the existence of a video stream
|
|
92
|
+
if video_stream is None:
|
|
93
|
+
print(f"No video stream found in {file_path}")
|
|
94
|
+
return None
|
|
95
|
+
|
|
96
|
+
# Extract and store video metadata
|
|
97
|
+
metadata = {
|
|
98
|
+
'duration': float(video_stream.get('duration', 0)),
|
|
99
|
+
'width': int(video_stream.get('width', 0)),
|
|
100
|
+
'height': int(video_stream.get('height', 0)),
|
|
101
|
+
'frame_rate': float(next(iter(video_stream.get('avg_frame_rate', '').split('/')), 0)),
|
|
102
|
+
'video_codec': video_stream.get('codec_name', ''),
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# If there are audio streams, extract and store audio metadata from the first stream
|
|
106
|
+
if audio_streams:
|
|
107
|
+
first_audio_stream = audio_streams[0]
|
|
108
|
+
metadata.update({
|
|
109
|
+
'audio_codec': first_audio_stream.get('codec_name', ''),
|
|
110
|
+
'audio_channels': int(first_audio_stream.get('channels', 0)),
|
|
111
|
+
'audio_sample_rate': int(first_audio_stream.get('sample_rate', 0)),
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
# Create and return the FFMpegMeta instance
|
|
115
|
+
return cls.objects.create(**metadata)
|
|
116
|
+
|
|
117
|
+
class VideoImportMeta(models.Model):
|
|
118
|
+
|
|
119
|
+
video_anonymized = models.BooleanField(default=False)
|
|
120
|
+
video_patient_data_detected = models.BooleanField(default=False)
|
|
121
|
+
outside_detected = models.BooleanField(default=False)
|
|
122
|
+
patient_data_removed = models.BooleanField(default=False)
|
|
123
|
+
outside_removed = models.BooleanField(default=False)
|
|
124
|
+
|
|
125
|
+
def __str__(self):
|
|
126
|
+
result_html = ""
|
|
127
|
+
|
|
128
|
+
result_html += f"Video anonymized: {self.video_anonymized}<br>"
|
|
129
|
+
result_html += f"Video patient data detected: {self.video_patient_data_detected}<br>"
|
|
130
|
+
result_html += f"Outside detected: {self.outside_detected}<br>"
|
|
131
|
+
result_html += f"Patient data removed: {self.patient_data_removed}<br>"
|
|
132
|
+
result_html += f"Outside removed: {self.outside_removed}<br>"
|
|
132
133
|
return result_html
|
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
from django.db import models
|
|
2
|
-
from ..center import Center
|
|
3
|
-
import hashlib
|
|
4
|
-
from datetime import date, time
|
|
5
|
-
|
|
6
|
-
class ReportFile(models.Model):
|
|
7
|
-
pdf = models.FileField(upload_to="raw_report_pdfs", blank=True, null=True)
|
|
8
|
-
pdf_hash = models.CharField(max_length=255, unique=True)
|
|
9
|
-
center = models.ForeignKey(Center, on_delete=models.CASCADE)
|
|
10
|
-
meta = models.JSONField(blank=True, null=True)
|
|
11
|
-
text = models.TextField(blank=True, null=True)
|
|
12
|
-
text_anonymized = models.TextField(blank=True, null=True)
|
|
13
|
-
patient = models.ForeignKey("Patient", on_delete=models.CASCADE, blank=True, null=True)
|
|
14
|
-
examiner = models.ForeignKey("Examiner", on_delete=models.CASCADE, blank=True, null=True)
|
|
15
|
-
date = models.DateField(blank=True, null=True)
|
|
16
|
-
time = models.TimeField(blank=True, null=True)
|
|
17
|
-
|
|
18
|
-
def get_pdf_hash(self):
|
|
19
|
-
#FIXME should use endoreg_db.utils.get_pdf_hash in future
|
|
20
|
-
pdf = self.pdf
|
|
21
|
-
pdf_hash = None
|
|
22
|
-
|
|
23
|
-
if pdf:
|
|
24
|
-
# Open the file in binary mode and read its contents
|
|
25
|
-
with pdf.open(mode='rb') as f:
|
|
26
|
-
pdf_contents = f.read()
|
|
27
|
-
# Create a hash object using SHA-256 algorithm
|
|
28
|
-
hash_object = hashlib.sha256(pdf_contents, usedforsecurity=False)
|
|
29
|
-
# Get the hexadecimal representation of the hash
|
|
30
|
-
pdf_hash = hash_object.hexdigest()
|
|
31
|
-
assert len(pdf_hash) <= 255, "Hash length exceeds 255 characters"
|
|
32
|
-
|
|
33
|
-
return pdf_hash
|
|
34
|
-
|
|
35
|
-
def initialize_metadata_in_db(self, report_meta=None):
|
|
36
|
-
if not report_meta:
|
|
37
|
-
report_meta = self.meta
|
|
38
|
-
self.set_examination_date_and_time(report_meta)
|
|
39
|
-
self.patient, created = self.get_or_create_patient(report_meta)
|
|
40
|
-
self.examiner, created = self.get_or_create_examiner(report_meta)
|
|
41
|
-
self.save()
|
|
42
|
-
|
|
43
|
-
def get_or_create_patient(self, report_meta=None):
|
|
44
|
-
from ..persons import Patient
|
|
45
|
-
if not report_meta:
|
|
46
|
-
report_meta = self.meta
|
|
47
|
-
patient_first_name = report_meta['patient_first_name']
|
|
48
|
-
patient_last_name = report_meta['patient_last_name']
|
|
49
|
-
patient_dob = report_meta['patient_dob']
|
|
50
|
-
|
|
51
|
-
patient, created = Patient.objects.get_or_create(
|
|
52
|
-
first_name=patient_first_name,
|
|
53
|
-
last_name=patient_last_name,
|
|
54
|
-
dob=patient_dob
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
return patient, created
|
|
58
|
-
|
|
59
|
-
def get_or_create_examiner(self, report_meta= None):
|
|
60
|
-
from ..persons import Examiner
|
|
61
|
-
if not report_meta:
|
|
62
|
-
report_meta = self.meta
|
|
63
|
-
examiner_first_name = report_meta['examiner_first_name']
|
|
64
|
-
examiner_last_name = report_meta['examiner_last_name']
|
|
65
|
-
examiner_center = self.center
|
|
66
|
-
|
|
67
|
-
examiner, created = Examiner.objects.get_or_create(
|
|
68
|
-
first_name=examiner_first_name,
|
|
69
|
-
last_name=examiner_last_name,
|
|
70
|
-
center=examiner_center
|
|
71
|
-
)
|
|
72
|
-
|
|
73
|
-
return examiner, created
|
|
74
|
-
|
|
75
|
-
def set_examination_date_and_time(self, report_meta=None):
|
|
76
|
-
if not report_meta:
|
|
77
|
-
report_meta = self.meta
|
|
78
|
-
examination_date_str = report_meta['examination_date']
|
|
79
|
-
examination_time_str = report_meta['examination_time']
|
|
80
|
-
|
|
81
|
-
if examination_date_str:
|
|
82
|
-
# TODO: get django DateField compatible date from string (e.g. "2021-01-01")
|
|
83
|
-
self.date = date.fromisoformat(examination_date_str)
|
|
84
|
-
if examination_time_str:
|
|
85
|
-
# TODO: get django TimeField compatible time from string (e.g. "12:00")
|
|
86
|
-
self.time = time.fromisoformat(examination_time_str)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
1
|
+
from django.db import models
|
|
2
|
+
from ..center import Center
|
|
3
|
+
import hashlib
|
|
4
|
+
from datetime import date, time
|
|
5
|
+
|
|
6
|
+
class ReportFile(models.Model):
|
|
7
|
+
pdf = models.FileField(upload_to="raw_report_pdfs", blank=True, null=True)
|
|
8
|
+
pdf_hash = models.CharField(max_length=255, unique=True)
|
|
9
|
+
center = models.ForeignKey(Center, on_delete=models.CASCADE)
|
|
10
|
+
meta = models.JSONField(blank=True, null=True)
|
|
11
|
+
text = models.TextField(blank=True, null=True)
|
|
12
|
+
text_anonymized = models.TextField(blank=True, null=True)
|
|
13
|
+
patient = models.ForeignKey("Patient", on_delete=models.CASCADE, blank=True, null=True)
|
|
14
|
+
examiner = models.ForeignKey("Examiner", on_delete=models.CASCADE, blank=True, null=True)
|
|
15
|
+
date = models.DateField(blank=True, null=True)
|
|
16
|
+
time = models.TimeField(blank=True, null=True)
|
|
17
|
+
|
|
18
|
+
def get_pdf_hash(self):
|
|
19
|
+
#FIXME should use endoreg_db.utils.get_pdf_hash in future
|
|
20
|
+
pdf = self.pdf
|
|
21
|
+
pdf_hash = None
|
|
22
|
+
|
|
23
|
+
if pdf:
|
|
24
|
+
# Open the file in binary mode and read its contents
|
|
25
|
+
with pdf.open(mode='rb') as f:
|
|
26
|
+
pdf_contents = f.read()
|
|
27
|
+
# Create a hash object using SHA-256 algorithm
|
|
28
|
+
hash_object = hashlib.sha256(pdf_contents, usedforsecurity=False)
|
|
29
|
+
# Get the hexadecimal representation of the hash
|
|
30
|
+
pdf_hash = hash_object.hexdigest()
|
|
31
|
+
assert len(pdf_hash) <= 255, "Hash length exceeds 255 characters"
|
|
32
|
+
|
|
33
|
+
return pdf_hash
|
|
34
|
+
|
|
35
|
+
def initialize_metadata_in_db(self, report_meta=None):
|
|
36
|
+
if not report_meta:
|
|
37
|
+
report_meta = self.meta
|
|
38
|
+
self.set_examination_date_and_time(report_meta)
|
|
39
|
+
self.patient, created = self.get_or_create_patient(report_meta)
|
|
40
|
+
self.examiner, created = self.get_or_create_examiner(report_meta)
|
|
41
|
+
self.save()
|
|
42
|
+
|
|
43
|
+
def get_or_create_patient(self, report_meta=None):
|
|
44
|
+
from ..persons import Patient
|
|
45
|
+
if not report_meta:
|
|
46
|
+
report_meta = self.meta
|
|
47
|
+
patient_first_name = report_meta['patient_first_name']
|
|
48
|
+
patient_last_name = report_meta['patient_last_name']
|
|
49
|
+
patient_dob = report_meta['patient_dob']
|
|
50
|
+
|
|
51
|
+
patient, created = Patient.objects.get_or_create(
|
|
52
|
+
first_name=patient_first_name,
|
|
53
|
+
last_name=patient_last_name,
|
|
54
|
+
dob=patient_dob
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return patient, created
|
|
58
|
+
|
|
59
|
+
def get_or_create_examiner(self, report_meta= None):
|
|
60
|
+
from ..persons import Examiner
|
|
61
|
+
if not report_meta:
|
|
62
|
+
report_meta = self.meta
|
|
63
|
+
examiner_first_name = report_meta['examiner_first_name']
|
|
64
|
+
examiner_last_name = report_meta['examiner_last_name']
|
|
65
|
+
examiner_center = self.center
|
|
66
|
+
|
|
67
|
+
examiner, created = Examiner.objects.get_or_create(
|
|
68
|
+
first_name=examiner_first_name,
|
|
69
|
+
last_name=examiner_last_name,
|
|
70
|
+
center=examiner_center
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
return examiner, created
|
|
74
|
+
|
|
75
|
+
def set_examination_date_and_time(self, report_meta=None):
|
|
76
|
+
if not report_meta:
|
|
77
|
+
report_meta = self.meta
|
|
78
|
+
examination_date_str = report_meta['examination_date']
|
|
79
|
+
examination_time_str = report_meta['examination_time']
|
|
80
|
+
|
|
81
|
+
if examination_date_str:
|
|
82
|
+
# TODO: get django DateField compatible date from string (e.g. "2021-01-01")
|
|
83
|
+
self.date = date.fromisoformat(examination_date_str)
|
|
84
|
+
if examination_time_str:
|
|
85
|
+
# TODO: get django TimeField compatible time from string (e.g. "12:00")
|
|
86
|
+
self.time = time.fromisoformat(examination_time_str)
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
|