edu-rdm-integration 3.9.2__py3-none-any.whl → 3.10.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- edu_rdm_integration/__init__.py +0 -1
- edu_rdm_integration/adapters/apps.py +15 -2
- edu_rdm_integration/adapters/caches.py +25 -12
- edu_rdm_integration/adapters/errors.py +13 -2
- edu_rdm_integration/adapters/functions.py +53 -14
- edu_rdm_integration/adapters/helpers.py +34 -8
- edu_rdm_integration/adapters/managers.py +41 -5
- edu_rdm_integration/adapters/presenters.py +26 -2
- edu_rdm_integration/adapters/receivers.py +16 -2
- edu_rdm_integration/adapters/results.py +50 -4
- edu_rdm_integration/adapters/runners.py +79 -20
- edu_rdm_integration/adapters/strategies.py +56 -54
- edu_rdm_integration/adapters/validators.py +43 -4
- edu_rdm_integration/apps.py +3 -23
- edu_rdm_integration/collect_and_export_data/__init__.py +1 -1
- edu_rdm_integration/collect_and_export_data/apps.py +1 -0
- edu_rdm_integration/collect_and_export_data/migrations/0001_initial.py +107 -17
- edu_rdm_integration/collect_and_export_data/migrations/0002_auto_20250204_1413.py +4 -2
- edu_rdm_integration/{consts.py → core/consts.py} +0 -11
- edu_rdm_integration/{enums.py → core/enums.py} +7 -54
- edu_rdm_integration/core/helpers.py +331 -0
- edu_rdm_integration/core/operations.py +71 -0
- edu_rdm_integration/core/redis_cache.py +20 -0
- edu_rdm_integration/{collect_and_export_data → core/registry}/actions.py +6 -12
- edu_rdm_integration/core/registry/apps.py +11 -0
- edu_rdm_integration/{collect_and_export_data → core/registry}/ui.py +1 -1
- edu_rdm_integration/{storages.py → core/storages.py} +8 -17
- edu_rdm_integration/{utils.py → core/utils.py} +29 -91
- edu_rdm_integration/migrations/0001_initial.py +294 -44
- edu_rdm_integration/migrations/0002_init_data_uploadstatus.py +1 -3
- edu_rdm_integration/migrations/0003_create_index_file_upload_status.py +0 -1
- edu_rdm_integration/migrations/0004_uploaderclientlog.py +1 -2
- edu_rdm_integration/migrations/0005_auto_20231204_1224.py +16 -4
- edu_rdm_integration/migrations/0006_request_status_data.py +60 -58
- edu_rdm_integration/migrations/0007_delete_upload_status.py +0 -1
- edu_rdm_integration/migrations/0009_auto_20240522_1619.py +1 -5
- edu_rdm_integration/migrations/0010_transferredentity_export_enabled.py +0 -1
- edu_rdm_integration/migrations/0011_exportingdatasubstageentity.py +16 -3
- edu_rdm_integration/migrations/0012_exportingdatasubstageattachment_attachment_size.py +0 -1
- edu_rdm_integration/migrations/0013_set_attachment_size.py +8 -12
- edu_rdm_integration/migrations/0014_uploaddatacommand.py +33 -6
- edu_rdm_integration/migrations/0015_set_exporting_sub_stage_status.py +1 -5
- edu_rdm_integration/migrations/0016_transferredentity_queue_level.py +2 -2
- edu_rdm_integration/migrations/0017_delete_uploaddatacommand.py +3 -2
- edu_rdm_integration/migrations/__init__.py +1 -0
- edu_rdm_integration/{registry → pipelines/transfer}/actions.py +13 -26
- edu_rdm_integration/pipelines/transfer/app_meta.py +18 -0
- edu_rdm_integration/pipelines/transfer/apps.py +19 -0
- edu_rdm_integration/pipelines/transfer/enums.py +34 -0
- edu_rdm_integration/pipelines/transfer/migrations/0001_initial.py +57 -0
- edu_rdm_integration/{base.py → pipelines/transfer/mixins.py} +29 -53
- edu_rdm_integration/pipelines/transfer/models.py +48 -0
- edu_rdm_integration/{tasks.py → pipelines/transfer/tasks.py} +51 -150
- edu_rdm_integration/{registry → pipelines/transfer}/ui.py +4 -10
- edu_rdm_integration/rdm_entities/apps.py +11 -0
- edu_rdm_integration/{entities.py → rdm_entities/entities.py} +67 -57
- edu_rdm_integration/rdm_entities/migrations/0001_initial.py +44 -0
- edu_rdm_integration/{enum_register → rdm_entities}/mixins.py +8 -59
- edu_rdm_integration/rdm_entities/models.py +63 -0
- edu_rdm_integration/rdm_entities/utils.py +33 -0
- edu_rdm_integration/rdm_models/apps.py +16 -0
- edu_rdm_integration/rdm_models/migrations/0001_initial.py +40 -0
- edu_rdm_integration/rdm_models/mixins.py +67 -0
- edu_rdm_integration/rdm_models/models.py +73 -0
- edu_rdm_integration/rdm_models/utils.py +23 -0
- edu_rdm_integration/stages/collect_data/apps.py +11 -0
- edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/functions.py-tpl +2 -2
- edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/managers.py-tpl +1 -1
- edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/runners.py-tpl +1 -1
- edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/tests.py-tpl +2 -1
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/caches.py +2 -2
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/functions.py +15 -18
- edu_rdm_integration/stages/collect_data/functions/base/helpers.py +20 -0
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/managers.py +20 -27
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/mixins.py +38 -55
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/runners.py +2 -5
- edu_rdm_integration/stages/collect_data/functions/calculated/base/__init__.py +0 -0
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/caches.py +3 -7
- edu_rdm_integration/stages/collect_data/functions/calculated/base/errors.py +7 -0
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/functions.py +8 -16
- edu_rdm_integration/stages/collect_data/functions/calculated/base/helpers.py +24 -0
- edu_rdm_integration/stages/collect_data/functions/calculated/base/managers.py +19 -0
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/presenters.py +1 -3
- edu_rdm_integration/stages/collect_data/functions/calculated/base/results.py +12 -0
- edu_rdm_integration/stages/collect_data/functions/calculated/base/runners.py +28 -0
- edu_rdm_integration/stages/collect_data/functions/calculated/base/validators.py +20 -0
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/strategies.py +32 -70
- edu_rdm_integration/stages/collect_data/functions/non_calculated/__init__.py +0 -0
- edu_rdm_integration/stages/collect_data/functions/non_calculated/base/__init__.py +0 -0
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/caches.py +13 -22
- edu_rdm_integration/stages/collect_data/functions/non_calculated/base/errors.py +7 -0
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/functions.py +8 -16
- edu_rdm_integration/stages/collect_data/functions/non_calculated/base/helpers.py +24 -0
- edu_rdm_integration/stages/collect_data/functions/non_calculated/base/managers.py +19 -0
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/presenters.py +1 -3
- edu_rdm_integration/stages/collect_data/functions/non_calculated/base/results.py +12 -0
- edu_rdm_integration/stages/collect_data/functions/non_calculated/base/runners.py +28 -0
- edu_rdm_integration/stages/collect_data/functions/non_calculated/base/validators.py +20 -0
- edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/strategies.py +32 -70
- edu_rdm_integration/{collect_data → stages/collect_data}/generators.py +9 -14
- edu_rdm_integration/stages/collect_data/helpers.py +154 -0
- edu_rdm_integration/stages/collect_data/management/__init__.py +0 -0
- edu_rdm_integration/stages/collect_data/management/base.py +100 -0
- edu_rdm_integration/stages/collect_data/management/commands/__init__.py +0 -0
- edu_rdm_integration/{management → stages/collect_data/management}/commands/collect_latest_models_data.py +5 -7
- edu_rdm_integration/{management → stages/collect_data/management}/commands/collect_models_data.py +5 -7
- edu_rdm_integration/stages/collect_data/migrations/0001_initial.py +187 -0
- edu_rdm_integration/stages/collect_data/migrations/0002_edurdmcollectdatacommandprogress.py +105 -0
- edu_rdm_integration/stages/collect_data/migrations/__init__.py +0 -0
- edu_rdm_integration/stages/collect_data/mixins.py +56 -0
- edu_rdm_integration/stages/collect_data/models.py +318 -0
- edu_rdm_integration/{collect_data/collect.py → stages/collect_data/operations.py} +30 -43
- edu_rdm_integration/stages/collect_data/registry/__init__.py +0 -0
- edu_rdm_integration/{collect_data → stages/collect_data/registry}/actions.py +17 -20
- edu_rdm_integration/stages/collect_data/registry/apps.py +11 -0
- edu_rdm_integration/{collect_data → stages/collect_data/registry}/ui.py +8 -15
- edu_rdm_integration/{collect_data → stages/collect_data}/tests.py +2 -2
- edu_rdm_integration/stages/export_data/__init__.py +0 -0
- edu_rdm_integration/stages/export_data/apps.py +11 -0
- edu_rdm_integration/stages/export_data/function_templates/__init__.py +0 -0
- edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/functions.py-tpl +2 -2
- edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/managers.py-tpl +2 -2
- edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/runners.py-tpl +2 -2
- edu_rdm_integration/stages/export_data/functions/__init__.py +0 -0
- edu_rdm_integration/stages/export_data/functions/base/__init__.py +0 -0
- edu_rdm_integration/{export_data → stages/export_data/functions}/base/caches.py +3 -8
- edu_rdm_integration/stages/export_data/functions/base/errors.py +7 -0
- edu_rdm_integration/{export_data → stages/export_data/functions}/base/functions.py +28 -59
- edu_rdm_integration/{export_data → stages/export_data/functions}/base/helpers.py +7 -17
- edu_rdm_integration/{export_data → stages/export_data/functions}/base/managers.py +19 -28
- edu_rdm_integration/stages/export_data/functions/base/presenters.py +11 -0
- edu_rdm_integration/{export_data → stages/export_data/functions}/base/requests.py +13 -40
- edu_rdm_integration/stages/export_data/functions/base/results.py +12 -0
- edu_rdm_integration/{export_data → stages/export_data/functions}/base/runners.py +9 -21
- edu_rdm_integration/stages/export_data/functions/base/validators.py +20 -0
- edu_rdm_integration/{export_data → stages/export_data}/generators.py +7 -6
- edu_rdm_integration/stages/export_data/helpers.py +203 -0
- edu_rdm_integration/stages/export_data/management/__init__.py +0 -0
- edu_rdm_integration/stages/export_data/management/base.py +101 -0
- edu_rdm_integration/stages/export_data/management/commands/__init__.py +0 -0
- edu_rdm_integration/{management → stages/export_data/management}/commands/export_entities_data.py +5 -7
- edu_rdm_integration/{management → stages/export_data/management}/commands/export_latest_entities_data.py +5 -7
- edu_rdm_integration/stages/export_data/migrations/0001_initial.py +324 -0
- edu_rdm_integration/stages/export_data/migrations/__init__.py +0 -0
- edu_rdm_integration/stages/export_data/mixins.py +50 -0
- edu_rdm_integration/stages/export_data/models.py +362 -0
- edu_rdm_integration/{export_data/export.py → stages/export_data/operations.py} +13 -152
- edu_rdm_integration/stages/export_data/registry/__init__.py +0 -0
- edu_rdm_integration/{export_data → stages/export_data/registry}/actions.py +18 -18
- edu_rdm_integration/stages/export_data/registry/apps.py +11 -0
- edu_rdm_integration/{export_data → stages/export_data/registry}/ui.py +5 -7
- edu_rdm_integration/{export_data → stages/export_data}/strategies.py +30 -68
- edu_rdm_integration/stages/service/__init__.py +0 -0
- edu_rdm_integration/stages/service/apps.py +19 -0
- edu_rdm_integration/stages/service/tasks.py +63 -0
- edu_rdm_integration/stages/upload_data/__init__.py +0 -0
- edu_rdm_integration/stages/upload_data/apps.py +19 -0
- edu_rdm_integration/stages/upload_data/consts.py +10 -0
- edu_rdm_integration/{export_data → stages/upload_data}/dataclasses.py +1 -0
- edu_rdm_integration/stages/upload_data/enums.py +17 -0
- edu_rdm_integration/{export_data/export_manager.py → stages/upload_data/export_managers.py} +73 -68
- edu_rdm_integration/stages/upload_data/helpers.py +164 -0
- edu_rdm_integration/stages/upload_data/management/__init__.py +0 -0
- edu_rdm_integration/stages/upload_data/management/base.py +134 -0
- edu_rdm_integration/stages/upload_data/management/commands/__init__.py +0 -0
- edu_rdm_integration/{management → stages/upload_data/management}/commands/async_fix_attachment_size.py +32 -54
- edu_rdm_integration/{management → stages/upload_data/management}/commands/check_upload_status.py +7 -6
- edu_rdm_integration/{management → stages/upload_data/management}/commands/datamart_status.py +3 -3
- edu_rdm_integration/{management → stages/upload_data/management}/commands/datamart_upload.py +4 -4
- edu_rdm_integration/stages/upload_data/migrations/0001_initial.py +161 -0
- edu_rdm_integration/stages/upload_data/migrations/__init__.py +0 -0
- edu_rdm_integration/stages/upload_data/models.py +175 -0
- edu_rdm_integration/stages/upload_data/operations.py +156 -0
- edu_rdm_integration/{export_data/queue.py → stages/upload_data/queues.py} +10 -8
- edu_rdm_integration/stages/upload_data/tasks.py +103 -0
- edu_rdm_integration/stages/upload_data/uploader_log/__init__.py +0 -0
- edu_rdm_integration/{uploader_log → stages/upload_data/uploader_log}/actions.py +14 -16
- edu_rdm_integration/stages/upload_data/uploader_log/apps.py +11 -0
- edu_rdm_integration/{uploader_log → stages/upload_data/uploader_log}/managers.py +15 -30
- edu_rdm_integration/stages/upload_data/uploader_log/migrations/0001_initial.py +31 -0
- edu_rdm_integration/stages/upload_data/uploader_log/migrations/__init__.py +0 -0
- edu_rdm_integration/stages/upload_data/uploader_log/models.py +86 -0
- edu_rdm_integration/{uploader_log → stages/upload_data/uploader_log}/ui.py +8 -6
- {edu_rdm_integration-3.9.2.dist-info → edu_rdm_integration-3.10.0.dist-info}/METADATA +238 -238
- edu_rdm_integration-3.10.0.dist-info/RECORD +255 -0
- edu_rdm_integration/app_meta.py +0 -16
- edu_rdm_integration/app_settings.py +0 -77
- edu_rdm_integration/collect_and_export_data/models.py +0 -67
- edu_rdm_integration/collect_and_export_data/utils.py +0 -224
- edu_rdm_integration/collect_data/base/helpers.py +0 -26
- edu_rdm_integration/collect_data/calculated/base/errors.py +0 -9
- edu_rdm_integration/collect_data/calculated/base/helpers.py +0 -32
- edu_rdm_integration/collect_data/calculated/base/managers.py +0 -23
- edu_rdm_integration/collect_data/calculated/base/results.py +0 -16
- edu_rdm_integration/collect_data/calculated/base/runners.py +0 -36
- edu_rdm_integration/collect_data/calculated/base/validators.py +0 -28
- edu_rdm_integration/collect_data/helpers.py +0 -92
- edu_rdm_integration/collect_data/non_calculated/base/errors.py +0 -9
- edu_rdm_integration/collect_data/non_calculated/base/helpers.py +0 -32
- edu_rdm_integration/collect_data/non_calculated/base/managers.py +0 -23
- edu_rdm_integration/collect_data/non_calculated/base/results.py +0 -16
- edu_rdm_integration/collect_data/non_calculated/base/runners.py +0 -36
- edu_rdm_integration/collect_data/non_calculated/base/validators.py +0 -28
- edu_rdm_integration/enum_register/register.py +0 -79
- edu_rdm_integration/export_data/base/errors.py +0 -9
- edu_rdm_integration/export_data/base/presenters.py +0 -13
- edu_rdm_integration/export_data/base/results.py +0 -16
- edu_rdm_integration/export_data/base/validators.py +0 -28
- edu_rdm_integration/export_data/helpers.py +0 -92
- edu_rdm_integration/helpers.py +0 -412
- edu_rdm_integration/management/general.py +0 -327
- edu_rdm_integration/models.py +0 -982
- edu_rdm_integration/redis_cache.py +0 -51
- edu_rdm_integration/uploader_log/apps.py +0 -10
- edu_rdm_integration-3.9.2.dist-info/RECORD +0 -198
- /edu_rdm_integration/{collect_and_export_data/migrations → core}/__init__.py +0 -0
- /edu_rdm_integration/{mapping.py → core/mapping.py} +0 -0
- /edu_rdm_integration/{collect_data → core/registry}/__init__.py +0 -0
- /edu_rdm_integration/{templates → core/registry/templates}/ui-js/start-task.js +0 -0
- /edu_rdm_integration/{signals.py → core/signals.py} +0 -0
- /edu_rdm_integration/{typing.py → core/typing.py} +0 -0
- /edu_rdm_integration/{collect_data/base → pipelines}/__init__.py +0 -0
- /edu_rdm_integration/{collect_data/calculated → pipelines/transfer}/__init__.py +0 -0
- /edu_rdm_integration/{collect_data/calculated/base → pipelines/transfer/migrations}/__init__.py +0 -0
- /edu_rdm_integration/{templates → pipelines/transfer/templates}/ui-js/transferred-entity-list.js +0 -0
- /edu_rdm_integration/{collect_data/non_calculated → rdm_entities}/__init__.py +0 -0
- /edu_rdm_integration/{collect_data/non_calculated/base → rdm_entities/migrations}/__init__.py +0 -0
- /edu_rdm_integration/{enum_register → rdm_models}/__init__.py +0 -0
- /edu_rdm_integration/{export_data → rdm_models/migrations}/__init__.py +0 -0
- /edu_rdm_integration/{export_data/base → stages}/__init__.py +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data}/__init__.py +0 -0
- /edu_rdm_integration/{collect_data/const.py → stages/collect_data/consts.py} +0 -0
- /edu_rdm_integration/{management → stages/collect_data/function_templates}/__init__.py +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/__init__.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/apps.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/caches.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/consts.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/enums.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/errors.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/helpers.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/presenters.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/results.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/strings.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/collect_data/function_templates}/function_collect_data_template/validators.py-tpl +0 -0
- /edu_rdm_integration/{management/commands → stages/collect_data/functions}/__init__.py +0 -0
- /edu_rdm_integration/{registry → stages/collect_data/functions/base}/__init__.py +0 -0
- /edu_rdm_integration/{collect_data → stages/collect_data/functions}/base/consts.py +0 -0
- /edu_rdm_integration/{uploader_log → stages/collect_data/functions/calculated}/__init__.py +0 -0
- /edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/consts.py +0 -0
- /edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/enums.py +0 -0
- /edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/strings.py +0 -0
- /edu_rdm_integration/{collect_data → stages/collect_data/functions}/calculated/base/tests.py +0 -0
- /edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/consts.py +0 -0
- /edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/enums.py +0 -0
- /edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/strings.py +0 -0
- /edu_rdm_integration/{collect_data → stages/collect_data/functions}/non_calculated/base/tests.py +0 -0
- /edu_rdm_integration/{export_data → stages/export_data}/consts.py +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/__init__.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/apps.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/caches.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/consts.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/enums.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/errors.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/helpers.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/presenters.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/results.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/strings.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/tests.py-tpl +0 -0
- /edu_rdm_integration/{function_templates → stages/export_data/function_templates}/function_export_data_template/validators.py-tpl +0 -0
- /edu_rdm_integration/{export_data → stages/export_data/functions}/base/consts.py +0 -0
- /edu_rdm_integration/{export_data → stages/export_data/functions}/base/enums.py +0 -0
- /edu_rdm_integration/{export_data → stages/export_data/functions}/base/strings.py +0 -0
- /edu_rdm_integration/{export_data → stages/export_data/functions}/base/tests.py +0 -0
- /edu_rdm_integration/{templates → stages/export_data/registry/templates}/ui-js/stage_for_export.js +0 -0
- /edu_rdm_integration/{uploader_log → stages/upload_data/uploader_log}/enums.py +0 -0
- /edu_rdm_integration/{uploader_log → stages/upload_data/uploader_log}/templates/ui-js/object-grid-buttons.js +0 -0
- {edu_rdm_integration-3.9.2.dist-info → edu_rdm_integration-3.10.0.dist-info}/WHEEL +0 -0
- {edu_rdm_integration-3.9.2.dist-info → edu_rdm_integration-3.10.0.dist-info}/licenses/LICENSE +0 -0
- {edu_rdm_integration-3.9.2.dist-info → edu_rdm_integration-3.10.0.dist-info}/top_level.txt +0 -0
@@ -1,79 +0,0 @@
|
|
1
|
-
import inspect
|
2
|
-
import sys
|
3
|
-
from importlib import (
|
4
|
-
import_module,
|
5
|
-
)
|
6
|
-
from operator import (
|
7
|
-
attrgetter,
|
8
|
-
)
|
9
|
-
from typing import (
|
10
|
-
Iterable,
|
11
|
-
)
|
12
|
-
|
13
|
-
from django.apps import (
|
14
|
-
apps,
|
15
|
-
)
|
16
|
-
from django.db import (
|
17
|
-
models,
|
18
|
-
)
|
19
|
-
|
20
|
-
from educommon.integration_entities.entities import (
|
21
|
-
BaseEntity,
|
22
|
-
)
|
23
|
-
from m3_db_utils.mixins import (
|
24
|
-
BaseEnumRegisterMixin,
|
25
|
-
)
|
26
|
-
|
27
|
-
from edu_rdm_integration.enum_register.mixins import (
|
28
|
-
EntityEnumRegisterMixin,
|
29
|
-
ModelEnumRegisterMixin,
|
30
|
-
)
|
31
|
-
|
32
|
-
|
33
|
-
def register_classes(classes: Iterable[type[BaseEnumRegisterMixin]]) -> None:
|
34
|
-
"""Вызывает метод регистрации в модель-перечисление
|
35
|
-
у переданных классов.
|
36
|
-
|
37
|
-
Args:
|
38
|
-
classes: Классы, поддерживающие интерфейс регистрации.
|
39
|
-
"""
|
40
|
-
classes = sorted(classes, key=attrgetter('order_number'))
|
41
|
-
|
42
|
-
for enum_class in classes:
|
43
|
-
enum_class.register()
|
44
|
-
|
45
|
-
|
46
|
-
def is_register_model(model: models.Model) -> bool:
|
47
|
-
"""Проверяет, является ли класс регистрируемой моделью."""
|
48
|
-
return issubclass(model, ModelEnumRegisterMixin)
|
49
|
-
|
50
|
-
|
51
|
-
def is_register_entity(class_) -> bool:
|
52
|
-
"""Проверяет, является ли класс регистрируемой сущностью."""
|
53
|
-
return (
|
54
|
-
inspect.isclass(class_) and
|
55
|
-
issubclass(class_, BaseEntity) and
|
56
|
-
issubclass(class_, EntityEnumRegisterMixin)
|
57
|
-
)
|
58
|
-
|
59
|
-
|
60
|
-
def register_models() -> None:
|
61
|
-
"""Регистрирует модели в RegionalDataMartModelEnum."""
|
62
|
-
register_classes([
|
63
|
-
m for m in apps.get_models() if is_register_model(m)
|
64
|
-
])
|
65
|
-
|
66
|
-
|
67
|
-
def register_entities(import_path: str) -> None:
|
68
|
-
"""Находит регистрируемые сущности в модуле по переданному пути и
|
69
|
-
регистрирует в RegionalDataMartEntityEnum.
|
70
|
-
|
71
|
-
Args:
|
72
|
-
import_path: Путь до пакета, хранящего классы сущностей;
|
73
|
-
"""
|
74
|
-
import_module(import_path)
|
75
|
-
entities_module = sys.modules[import_path]
|
76
|
-
|
77
|
-
register_classes([
|
78
|
-
c[1] for c in inspect.getmembers(entities_module, is_register_entity)
|
79
|
-
])
|
@@ -1,13 +0,0 @@
|
|
1
|
-
from abc import (
|
2
|
-
ABCMeta,
|
3
|
-
)
|
4
|
-
|
5
|
-
from edu_rdm_integration.adapters.presenters import (
|
6
|
-
WebEduResultPresenter,
|
7
|
-
)
|
8
|
-
|
9
|
-
|
10
|
-
class BaseExportDataResultPresenter(WebEduResultPresenter, metaclass=ABCMeta):
|
11
|
-
"""
|
12
|
-
Презентер результата работы функций выгрузки данных для интеграции с "Региональная витрина данных".
|
13
|
-
"""
|
@@ -1,16 +0,0 @@
|
|
1
|
-
from edu_rdm_integration.adapters.results import (
|
2
|
-
WebEduFunctionResult,
|
3
|
-
WebEduRunnerResult,
|
4
|
-
)
|
5
|
-
|
6
|
-
|
7
|
-
class BaseExportDataRunnerResult(WebEduRunnerResult):
|
8
|
-
"""
|
9
|
-
Базовый класс результатов работы ранеров функций выгрузки данных для интеграции с "Региональная витрина данных".
|
10
|
-
"""
|
11
|
-
|
12
|
-
|
13
|
-
class BaseExportDataFunctionResult(WebEduFunctionResult):
|
14
|
-
"""
|
15
|
-
Базовый класс результатов работы функций выгрузки данных для интеграции с "Региональная витрина данных".
|
16
|
-
"""
|
@@ -1,28 +0,0 @@
|
|
1
|
-
from edu_rdm_integration.adapters.validators import (
|
2
|
-
WebEduFunctionValidator,
|
3
|
-
WebEduRunnerValidator,
|
4
|
-
)
|
5
|
-
|
6
|
-
|
7
|
-
class BaseExportDataRunnerValidator(WebEduRunnerValidator):
|
8
|
-
"""
|
9
|
-
Базовый класс валидаторов ранеров функций выгрузки данных для интеграции с "Региональная витрина данных".
|
10
|
-
"""
|
11
|
-
|
12
|
-
def validate(self, runnable):
|
13
|
-
"""
|
14
|
-
Выполнение валидации.
|
15
|
-
"""
|
16
|
-
super().validate(runnable=runnable)
|
17
|
-
|
18
|
-
|
19
|
-
class BaseExportDataFunctionValidator(WebEduFunctionValidator):
|
20
|
-
"""
|
21
|
-
Базовый класс валидаторов функций выгрузки данных для интеграции с "Региональная витрина данных".
|
22
|
-
"""
|
23
|
-
|
24
|
-
def validate(self, runnable):
|
25
|
-
"""
|
26
|
-
Выполнение валидации.
|
27
|
-
"""
|
28
|
-
super().validate(runnable=runnable)
|
@@ -1,92 +0,0 @@
|
|
1
|
-
from datetime import (
|
2
|
-
date,
|
3
|
-
datetime,
|
4
|
-
time,
|
5
|
-
timedelta,
|
6
|
-
)
|
7
|
-
|
8
|
-
from django.conf import (
|
9
|
-
settings,
|
10
|
-
)
|
11
|
-
from django.db.models import (
|
12
|
-
OuterRef,
|
13
|
-
Subquery,
|
14
|
-
Value,
|
15
|
-
)
|
16
|
-
from django.db.models.functions import (
|
17
|
-
Coalesce,
|
18
|
-
)
|
19
|
-
from django.db.transaction import (
|
20
|
-
atomic,
|
21
|
-
)
|
22
|
-
|
23
|
-
from educommon import (
|
24
|
-
logger,
|
25
|
-
)
|
26
|
-
|
27
|
-
from edu_rdm_integration.models import (
|
28
|
-
ExportingDataStage,
|
29
|
-
ExportingDataStageStatus,
|
30
|
-
ExportingDataSubStage,
|
31
|
-
ExportingDataSubStageStatus,
|
32
|
-
)
|
33
|
-
|
34
|
-
|
35
|
-
@atomic
|
36
|
-
def set_failed_status_suspended_exporting_data_stages() -> dict[str, int]:
|
37
|
-
"""Установить статус 'Завершено с ошибками' для зависших этапов и подэтапов экспорта.
|
38
|
-
|
39
|
-
Экспорт считается зависшим в случае если за определенное в параметре RDM_CHECK_SUSPEND_TASK_STAGE_TIMEOUT время,
|
40
|
-
отсутствуют изменения в связанных подэтапах. Параметр RDM_CHECK_SUSPEND_TASK_STAGE_TIMEOUT определяется
|
41
|
-
в настройках приложения.
|
42
|
-
"""
|
43
|
-
changed_status_result = {
|
44
|
-
'change_stage_count': 0,
|
45
|
-
'change_sub_stage_count': 0,
|
46
|
-
}
|
47
|
-
|
48
|
-
current_datetime = datetime.now()
|
49
|
-
suspended_time_at = current_datetime - timedelta(minutes=settings.RDM_CHECK_SUSPEND_TASK_STAGE_TIMEOUT)
|
50
|
-
|
51
|
-
suspended_stage_ids = set(
|
52
|
-
ExportingDataStage.objects.annotate(
|
53
|
-
last_sub_stage_started_at=Coalesce(
|
54
|
-
Subquery(
|
55
|
-
ExportingDataSubStage.objects.filter(
|
56
|
-
stage_id=OuterRef('pk')
|
57
|
-
).values('started_at').order_by('-started_at')[:1]
|
58
|
-
),
|
59
|
-
Value(datetime.combine(date.min, time.min))
|
60
|
-
)
|
61
|
-
).filter(
|
62
|
-
last_sub_stage_started_at__lt=suspended_time_at,
|
63
|
-
status__in=(
|
64
|
-
ExportingDataStageStatus.CREATED.key,
|
65
|
-
ExportingDataStageStatus.IN_PROGRESS.key,
|
66
|
-
),
|
67
|
-
).values_list('pk', flat=True)
|
68
|
-
)
|
69
|
-
|
70
|
-
if suspended_stage_ids:
|
71
|
-
logger.info(f'find suspended ExportingDataStage: {", ".join(map(str, suspended_stage_ids))}..')
|
72
|
-
|
73
|
-
change_stage_count = ExportingDataStage.objects.filter(
|
74
|
-
pk__in=suspended_stage_ids,
|
75
|
-
).update(
|
76
|
-
status=ExportingDataStageStatus.FAILED.key,
|
77
|
-
ended_at=current_datetime,
|
78
|
-
)
|
79
|
-
|
80
|
-
change_sub_stage_count = ExportingDataSubStage.objects.filter(
|
81
|
-
stage_id__in=suspended_stage_ids,
|
82
|
-
).update(
|
83
|
-
status=ExportingDataSubStageStatus.FAILED.key,
|
84
|
-
ended_at=current_datetime,
|
85
|
-
)
|
86
|
-
|
87
|
-
changed_status_result.update({
|
88
|
-
'change_stage_count': change_stage_count,
|
89
|
-
'change_sub_stage_count': change_sub_stage_count,
|
90
|
-
})
|
91
|
-
|
92
|
-
return changed_status_result
|
edu_rdm_integration/helpers.py
DELETED
@@ -1,412 +0,0 @@
|
|
1
|
-
import heapq
|
2
|
-
import os
|
3
|
-
from concurrent.futures import (
|
4
|
-
ThreadPoolExecutor,
|
5
|
-
)
|
6
|
-
from json import (
|
7
|
-
JSONDecodeError,
|
8
|
-
)
|
9
|
-
from typing import (
|
10
|
-
TYPE_CHECKING,
|
11
|
-
Any,
|
12
|
-
Iterable,
|
13
|
-
Optional,
|
14
|
-
Union,
|
15
|
-
)
|
16
|
-
|
17
|
-
from django.conf import (
|
18
|
-
settings,
|
19
|
-
)
|
20
|
-
from django.db import (
|
21
|
-
transaction,
|
22
|
-
)
|
23
|
-
from django.db.models import (
|
24
|
-
CharField,
|
25
|
-
OuterRef,
|
26
|
-
QuerySet,
|
27
|
-
Subquery,
|
28
|
-
)
|
29
|
-
from django.db.models.functions import (
|
30
|
-
Cast,
|
31
|
-
Least,
|
32
|
-
)
|
33
|
-
from django.utils.html import (
|
34
|
-
format_html,
|
35
|
-
)
|
36
|
-
from django.utils.safestring import (
|
37
|
-
mark_safe,
|
38
|
-
)
|
39
|
-
from uploader_client.adapters import (
|
40
|
-
adapter,
|
41
|
-
)
|
42
|
-
|
43
|
-
from educommon import (
|
44
|
-
logger,
|
45
|
-
)
|
46
|
-
|
47
|
-
from edu_rdm_integration.collect_and_export_data.models import (
|
48
|
-
AbstractExportDataCommandProgress,
|
49
|
-
)
|
50
|
-
from edu_rdm_integration.enums import (
|
51
|
-
FileUploadStatusEnum,
|
52
|
-
)
|
53
|
-
from edu_rdm_integration.export_data.base.requests import (
|
54
|
-
RegionalDataMartStatusRequest,
|
55
|
-
)
|
56
|
-
from edu_rdm_integration.export_data.consts import (
|
57
|
-
TOTAL_ATTACHMENTS_SIZE_KEY,
|
58
|
-
)
|
59
|
-
from edu_rdm_integration.models import (
|
60
|
-
CollectingDataStageStatus,
|
61
|
-
CollectingExportedDataStage,
|
62
|
-
DataMartRequestStatus,
|
63
|
-
ExportingDataStage,
|
64
|
-
ExportingDataStageStatus,
|
65
|
-
ExportingDataSubStageStatus,
|
66
|
-
ExportingDataSubStageUploaderClientLog,
|
67
|
-
UploadStatusRequestLog,
|
68
|
-
)
|
69
|
-
from edu_rdm_integration.redis_cache import (
|
70
|
-
AbstractCache,
|
71
|
-
)
|
72
|
-
|
73
|
-
|
74
|
-
if TYPE_CHECKING:
|
75
|
-
from datetime import (
|
76
|
-
datetime,
|
77
|
-
)
|
78
|
-
|
79
|
-
from uploader_client.models import (
|
80
|
-
Entry,
|
81
|
-
)
|
82
|
-
|
83
|
-
from edu_rdm_integration.collect_data.non_calculated.base.managers import (
|
84
|
-
BaseCollectingExportedDataRunnerManager,
|
85
|
-
)
|
86
|
-
from edu_rdm_integration.export_data.base.managers import (
|
87
|
-
BaseExportDataRunnerManager,
|
88
|
-
)
|
89
|
-
|
90
|
-
|
91
|
-
FAILED_STATUSES = {
|
92
|
-
DataMartRequestStatus.FAILED_PROCESSING,
|
93
|
-
DataMartRequestStatus.REQUEST_ID_NOT_FOUND,
|
94
|
-
DataMartRequestStatus.FLC_ERROR,
|
95
|
-
}
|
96
|
-
|
97
|
-
|
98
|
-
class UploadStatusHelper:
|
99
|
-
"""Хелпер проверки статуса загрузки данных в витрину."""
|
100
|
-
|
101
|
-
def __init__(self, in_progress_uploads: QuerySet, cache: AbstractCache) -> None:
|
102
|
-
self._in_progress_uploads = in_progress_uploads
|
103
|
-
self.cache = cache
|
104
|
-
|
105
|
-
def run(self, thread_count: int = 1) -> None:
|
106
|
-
"""Запускает проверки статусов."""
|
107
|
-
if thread_count > 1:
|
108
|
-
with ThreadPoolExecutor(max_workers=thread_count) as pool:
|
109
|
-
pool.map(self._process_upload, self._in_progress_uploads)
|
110
|
-
else:
|
111
|
-
for upload in self._in_progress_uploads:
|
112
|
-
self._process_upload(upload)
|
113
|
-
|
114
|
-
@classmethod
|
115
|
-
def send_upload_status_request(cls, request_id: str) -> tuple[Optional[dict[str, Any]], 'Entry']:
|
116
|
-
"""Формирует и отправляет запрос для получения статуса загрузки данных в витрину."""
|
117
|
-
request = RegionalDataMartStatusRequest(
|
118
|
-
request_id=request_id,
|
119
|
-
method='GET',
|
120
|
-
parameters={},
|
121
|
-
headers={
|
122
|
-
'Content-Type': 'application/json',
|
123
|
-
},
|
124
|
-
)
|
125
|
-
|
126
|
-
result = adapter.send(request)
|
127
|
-
|
128
|
-
response = None
|
129
|
-
|
130
|
-
if result.error:
|
131
|
-
logger.warning(
|
132
|
-
f'Ошибка при получении статуса загрузки данных в витрину. Идентификатор загрузки: {request_id}. '
|
133
|
-
f'Ошибка: {result.error}, запрос: {result.log.request}, ответ: {result.log.response}',
|
134
|
-
)
|
135
|
-
else:
|
136
|
-
logger.info(
|
137
|
-
f'Получен ответ со статусом {result.response.status_code} и содержимым {result.response.text}. '
|
138
|
-
f'Идентификатор загрузки: {request_id}',
|
139
|
-
)
|
140
|
-
try:
|
141
|
-
response = result.response.json()
|
142
|
-
except JSONDecodeError:
|
143
|
-
logger.error(
|
144
|
-
f'Не удалось получить данные из ответа запроса статуса загрузки данных в витрину. '
|
145
|
-
f'Идентификатор загрузки: {request_id}, ответ: {result.response.text}',
|
146
|
-
)
|
147
|
-
|
148
|
-
return response, result.log
|
149
|
-
|
150
|
-
@classmethod
|
151
|
-
def update_upload_status(
|
152
|
-
cls,
|
153
|
-
upload: ExportingDataSubStageUploaderClientLog,
|
154
|
-
response: Optional[dict[str, Any]],
|
155
|
-
log_entry: 'Entry',
|
156
|
-
) -> None:
|
157
|
-
"""Обновляет статус загрузки данных в витрину."""
|
158
|
-
request_status = None
|
159
|
-
|
160
|
-
if isinstance(response, dict):
|
161
|
-
request_status = DataMartRequestStatus.get_values_to_enum_data().get(response.get('code'))
|
162
|
-
|
163
|
-
if not request_status:
|
164
|
-
logger.error(
|
165
|
-
'Не удалось определить статус загрузки данных в витрину. Идентификатор загрузки: '
|
166
|
-
f'{upload.request_id}, данные ответа: {response}',
|
167
|
-
)
|
168
|
-
|
169
|
-
with transaction.atomic():
|
170
|
-
UploadStatusRequestLog.objects.create(
|
171
|
-
upload=upload,
|
172
|
-
entry=log_entry,
|
173
|
-
request_status_id=getattr(request_status, 'key', None),
|
174
|
-
)
|
175
|
-
|
176
|
-
if request_status in FAILED_STATUSES:
|
177
|
-
upload.file_upload_status = FileUploadStatusEnum.ERROR
|
178
|
-
upload.sub_stage.status_id = ExportingDataSubStageStatus.PROCESS_ERROR.key
|
179
|
-
upload.sub_stage.save()
|
180
|
-
|
181
|
-
elif request_status == DataMartRequestStatus.SUCCESSFULLY_PROCESSED:
|
182
|
-
upload.file_upload_status = FileUploadStatusEnum.FINISHED
|
183
|
-
|
184
|
-
if upload.file_upload_status != FileUploadStatusEnum.IN_PROGRESS:
|
185
|
-
upload.save()
|
186
|
-
|
187
|
-
def _process_upload(self, upload: ExportingDataSubStageUploaderClientLog) -> None:
|
188
|
-
"""Обрабатывает запись загрузки данных в витрину."""
|
189
|
-
response, log_entry = self.send_upload_status_request(upload.request_id)
|
190
|
-
self.update_upload_status(upload, response, log_entry)
|
191
|
-
# Обновим размер файлов в кеш (с блокировкой на время обновления)
|
192
|
-
with self.cache.lock(f'{TOTAL_ATTACHMENTS_SIZE_KEY}:lock', timeout=300):
|
193
|
-
queue_total_file_size = self.cache.get(TOTAL_ATTACHMENTS_SIZE_KEY) or 0
|
194
|
-
if queue_total_file_size:
|
195
|
-
queue_total_file_size -= upload.attachment.attachment_size
|
196
|
-
if queue_total_file_size > 0:
|
197
|
-
self.cache.set(
|
198
|
-
TOTAL_ATTACHMENTS_SIZE_KEY,
|
199
|
-
queue_total_file_size,
|
200
|
-
timeout=settings.RDM_REDIS_CACHE_TIMEOUT_SECONDS,
|
201
|
-
)
|
202
|
-
|
203
|
-
|
204
|
-
class Graph:
|
205
|
-
"""Граф связей между моделями.
|
206
|
-
|
207
|
-
Предназначен для поиска кратчайшей связи между моделями и дальнейшего построения lookup`а
|
208
|
-
до необходимого поля модели с последующим использованием его в фильтре.
|
209
|
-
Вершинами графа выступают наименования моделей. Ребро содержит наименования модели связанной
|
210
|
-
с другой моделью и наименования поля, через которое осуществляется связь.
|
211
|
-
Вместо наименования поля может быть наименование обратной связи между моделями,
|
212
|
-
в случае если данная связь является связью OneToOne.
|
213
|
-
"""
|
214
|
-
|
215
|
-
def __init__(self):
|
216
|
-
self.vertices: dict[str, dict[str, Optional[str]]] = {}
|
217
|
-
"""Словарь для хранения данных графа."""
|
218
|
-
|
219
|
-
def add_vertex(self, vertex: str):
|
220
|
-
"""Добавление вершины."""
|
221
|
-
if vertex not in self.vertices:
|
222
|
-
self.vertices[vertex] = {}
|
223
|
-
|
224
|
-
def add_edge(self, vertex1: str, vertex2: str, edge_name: str):
|
225
|
-
"""Добавление связи."""
|
226
|
-
if vertex1 in self.vertices and vertex2 in self.vertices:
|
227
|
-
self.vertices[vertex1][vertex2] = edge_name
|
228
|
-
if vertex1 not in self.vertices[vertex2]:
|
229
|
-
self.vertices[vertex2][vertex1] = None
|
230
|
-
|
231
|
-
def remove_vertex(self, vertex: str):
|
232
|
-
"""Удаление вершины."""
|
233
|
-
if vertex in self.vertices:
|
234
|
-
del self.vertices[vertex]
|
235
|
-
|
236
|
-
# Удаляем связанные с удаленной вершиной ребра
|
237
|
-
for neighbour in self.vertices:
|
238
|
-
if vertex in self.vertices[neighbour]:
|
239
|
-
self.vertices[neighbour].pop(vertex)
|
240
|
-
|
241
|
-
def remove_edge(self, vertex1: str, vertex2: str):
|
242
|
-
"""Удаление связи."""
|
243
|
-
if vertex1 in self.vertices and vertex2 in self.vertices:
|
244
|
-
self.vertices[vertex1].pop(vertex2, None)
|
245
|
-
self.vertices[vertex2].pop(vertex1, None)
|
246
|
-
|
247
|
-
def get_vertices(self) -> list[str]:
|
248
|
-
"""Получение списка всех вершин."""
|
249
|
-
return list(self.vertices)
|
250
|
-
|
251
|
-
def get_edges(self) -> list[tuple[str, str, Optional[str]]]:
|
252
|
-
"""Получение всех связей."""
|
253
|
-
edges = []
|
254
|
-
|
255
|
-
for vertex, neighbors in self.vertices.items():
|
256
|
-
for neighboring_vertex, edge_name in neighbors.items():
|
257
|
-
edge = (vertex, neighboring_vertex, edge_name)
|
258
|
-
edges.append(edge)
|
259
|
-
|
260
|
-
return edges
|
261
|
-
|
262
|
-
def __contains__(self, vertex: str) -> bool:
|
263
|
-
return vertex in self.vertices
|
264
|
-
|
265
|
-
def __iter__(self):
|
266
|
-
return iter(self.vertices)
|
267
|
-
|
268
|
-
def __getitem__(self, vertex: str):
|
269
|
-
return self.vertices.get(vertex, {})
|
270
|
-
|
271
|
-
def get_edges_between_vertices(
|
272
|
-
self, from_vertex: str, to_vertex: str, required_edge_name: bool = True
|
273
|
-
) -> list[str]:
|
274
|
-
"""Получение списка наименований ребер между вершинами."""
|
275
|
-
if from_vertex not in self.vertices and to_vertex not in self.vertices:
|
276
|
-
return []
|
277
|
-
|
278
|
-
path = []
|
279
|
-
edge_weight = 1
|
280
|
-
|
281
|
-
# Инициализация расстояния между вершинами
|
282
|
-
distances = {vertex: float('inf') for vertex in self}
|
283
|
-
distances[from_vertex] = 0
|
284
|
-
|
285
|
-
priority_queue = [(0, from_vertex)]
|
286
|
-
|
287
|
-
while priority_queue:
|
288
|
-
current_distance, current_vertex = heapq.heappop(priority_queue)
|
289
|
-
|
290
|
-
# Если достигнута конечная вершина, заканчиваем цикл
|
291
|
-
if current_vertex == to_vertex:
|
292
|
-
break
|
293
|
-
|
294
|
-
# Проверяем все смежные вершины и обновляем расстояния, если находим более короткий путь
|
295
|
-
for neighbor, edge_name in self[current_vertex].items():
|
296
|
-
distance = current_distance + edge_weight
|
297
|
-
if distance < distances[neighbor]:
|
298
|
-
distances[neighbor] = distance
|
299
|
-
heapq.heappush(priority_queue, (distance, neighbor))
|
300
|
-
|
301
|
-
# Восстанавливаем путь от конечной вершины к начальной
|
302
|
-
current_vertex = to_vertex
|
303
|
-
while current_vertex != from_vertex:
|
304
|
-
previous_vertex = edge_name = None
|
305
|
-
|
306
|
-
for neighbor in self[current_vertex]:
|
307
|
-
if distances[current_vertex] == distances[neighbor] + 1:
|
308
|
-
for neighbor_vertex, edge_name in self[neighbor].items():
|
309
|
-
if neighbor_vertex == current_vertex:
|
310
|
-
break
|
311
|
-
|
312
|
-
previous_vertex = neighbor
|
313
|
-
break
|
314
|
-
|
315
|
-
if required_edge_name and not edge_name:
|
316
|
-
path = []
|
317
|
-
break
|
318
|
-
|
319
|
-
path.append(edge_name)
|
320
|
-
current_vertex = previous_vertex
|
321
|
-
|
322
|
-
# Инвертируем путь и возвращаем его
|
323
|
-
path.reverse()
|
324
|
-
|
325
|
-
return path
|
326
|
-
|
327
|
-
|
328
|
-
def save_command_log_link(
|
329
|
-
command: AbstractExportDataCommandProgress,
|
330
|
-
log_dir: str
|
331
|
-
) -> None:
|
332
|
-
"""Сохраняет ссылку на лог команды."""
|
333
|
-
log_file = os.path.join(settings.MEDIA_ROOT, log_dir, f'{command.id}.log')
|
334
|
-
if os.path.exists(log_file):
|
335
|
-
command.logs_link = os.path.join(log_dir, f'{command.id}.log')
|
336
|
-
command.save()
|
337
|
-
|
338
|
-
|
339
|
-
def get_collecting_managers_max_period_ended_dates(
|
340
|
-
collecting_managers: Iterable['BaseCollectingExportedDataRunnerManager'],
|
341
|
-
) -> dict[str, 'datetime']:
|
342
|
-
"""Возвращает дату и время завершения последнего успешного этапа сбора для менеджеров Функций сбора."""
|
343
|
-
managers_last_period_ended = (
|
344
|
-
CollectingExportedDataStage.objects.filter(
|
345
|
-
manager_id__in=[manager.uuid for manager in collecting_managers],
|
346
|
-
id=Subquery(
|
347
|
-
CollectingExportedDataStage.objects.filter(
|
348
|
-
manager_id=OuterRef('manager_id'),
|
349
|
-
status_id=CollectingDataStageStatus.FINISHED.key,
|
350
|
-
)
|
351
|
-
.order_by('-id')
|
352
|
-
.values('id')[:1]
|
353
|
-
),
|
354
|
-
)
|
355
|
-
.annotate(
|
356
|
-
str_manager_id=Cast('manager_id', output_field=CharField()),
|
357
|
-
last_period_ended_at=Least('logs_period_ended_at', 'started_at'),
|
358
|
-
)
|
359
|
-
.values_list(
|
360
|
-
'str_manager_id',
|
361
|
-
'last_period_ended_at',
|
362
|
-
)
|
363
|
-
)
|
364
|
-
|
365
|
-
return {manager_id: last_period_ended_at for manager_id, last_period_ended_at in managers_last_period_ended}
|
366
|
-
|
367
|
-
|
368
|
-
def get_exporting_managers_max_period_ended_dates(
|
369
|
-
exporting_managers: Iterable['BaseExportDataRunnerManager'],
|
370
|
-
) -> dict[str, 'datetime']:
|
371
|
-
"""Возвращает дату и время последнего успешного этапа экспорта для менеджеров Функций экспорта."""
|
372
|
-
managers_last_period_ended = (
|
373
|
-
ExportingDataStage.objects.filter(
|
374
|
-
manager_id__in=[manager.uuid for manager in exporting_managers],
|
375
|
-
id=Subquery(
|
376
|
-
ExportingDataStage.objects.filter(
|
377
|
-
manager_id=OuterRef('manager_id'),
|
378
|
-
status_id=ExportingDataStageStatus.FINISHED.key,
|
379
|
-
)
|
380
|
-
.order_by('-id')
|
381
|
-
.values('id')[:1]
|
382
|
-
),
|
383
|
-
)
|
384
|
-
.annotate(
|
385
|
-
str_manager_id=Cast('manager_id', output_field=CharField()),
|
386
|
-
last_period_ended_at=Least('period_ended_at', 'started_at'),
|
387
|
-
)
|
388
|
-
.values_list(
|
389
|
-
'str_manager_id',
|
390
|
-
'last_period_ended_at',
|
391
|
-
)
|
392
|
-
)
|
393
|
-
|
394
|
-
return {manager_id: last_period_ended_at for manager_id, last_period_ended_at in managers_last_period_ended}
|
395
|
-
|
396
|
-
|
397
|
-
def make_download_link(fieldfile, text='Cкачать', show_filename=False):
|
398
|
-
"""Возвращает html ссылку для скачивания файла.
|
399
|
-
|
400
|
-
Если show_filename == True, использует имя файла как текст ссылки
|
401
|
-
"""
|
402
|
-
link = mark_safe('')
|
403
|
-
if fieldfile:
|
404
|
-
link_text = os.path.basename(fieldfile.name) if show_filename else text
|
405
|
-
link = make_link(fieldfile.url, link_text)
|
406
|
-
|
407
|
-
return link
|
408
|
-
|
409
|
-
|
410
|
-
def make_link(url, text):
|
411
|
-
"""Возвращает экаранированную html ссылку файла."""
|
412
|
-
return format_html('<a href="{}" target="_blank" download>{}</a>', url, text)
|