edu-rdm-integration 0.8.6__py3-none-any.whl → 0.9.1__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/app_meta.py +16 -0
- edu_rdm_integration/collect_data/base/mixins.py +1 -1
- edu_rdm_integration/collect_data/non_calculated/base/caches.py +2 -2
- edu_rdm_integration/export_data/export.py +13 -3
- edu_rdm_integration/helpers.py +137 -0
- edu_rdm_integration/management/commands/check_upload_status.py +97 -0
- edu_rdm_integration/management/commands/collect_latest_models_data.py +20 -0
- edu_rdm_integration/management/commands/export_latest_entities_data.py +26 -0
- edu_rdm_integration/migrations/0008_transferredentity.py +43 -0
- edu_rdm_integration/models.py +16 -0
- edu_rdm_integration/registry/__init__.py +0 -0
- edu_rdm_integration/registry/actions.py +136 -0
- edu_rdm_integration/tasks.py +94 -0
- {edu_rdm_integration-0.8.6.dist-info → edu_rdm_integration-0.9.1.dist-info}/METADATA +43 -6
- {edu_rdm_integration-0.8.6.dist-info → edu_rdm_integration-0.9.1.dist-info}/RECORD +19 -10
- {edu_rdm_integration-0.8.6.dist-info → edu_rdm_integration-0.9.1.dist-info}/LICENSE +0 -0
- {edu_rdm_integration-0.8.6.dist-info → edu_rdm_integration-0.9.1.dist-info}/WHEEL +0 -0
- {edu_rdm_integration-0.8.6.dist-info → edu_rdm_integration-0.9.1.dist-info}/namespace_packages.txt +0 -0
- {edu_rdm_integration-0.8.6.dist-info → edu_rdm_integration-0.9.1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
from educommon import (
|
2
|
+
ioc,
|
3
|
+
)
|
4
|
+
|
5
|
+
from edu_rdm_integration.registry.actions import (
|
6
|
+
EntitySelectPack,
|
7
|
+
TransferredEntityPack,
|
8
|
+
)
|
9
|
+
|
10
|
+
|
11
|
+
def register_actions():
|
12
|
+
"""Регистрирует паки и экшны."""
|
13
|
+
ioc.get('main_controller').packs.extend((
|
14
|
+
TransferredEntityPack(),
|
15
|
+
EntitySelectPack(),
|
16
|
+
))
|
@@ -131,9 +131,9 @@ class BaseCollectingExportedDataFunctionCacheStorage(WebEduFunctionCacheStorage)
|
|
131
131
|
operation = LOG_OPERATION_MAP[log.operation]
|
132
132
|
|
133
133
|
if operation in (EntityLogOperation.CREATE, EntityLogOperation.DELETE):
|
134
|
-
fields = log.
|
134
|
+
fields = log.transformed_data
|
135
135
|
elif operation == EntityLogOperation.UPDATE:
|
136
|
-
fields = log.
|
136
|
+
fields = log.transformed_changes
|
137
137
|
else:
|
138
138
|
fields = {}
|
139
139
|
|
@@ -44,6 +44,9 @@ from django.utils.datastructures import (
|
|
44
44
|
from educommon import (
|
45
45
|
logger,
|
46
46
|
)
|
47
|
+
from educommon.async_task.models import (
|
48
|
+
RunningTask,
|
49
|
+
)
|
47
50
|
from educommon.utils.date import (
|
48
51
|
get_today_max_datetime,
|
49
52
|
)
|
@@ -126,12 +129,11 @@ class BaseExportEntitiesData(BaseOperationData):
|
|
126
129
|
#TODO Вынужденная мера, т.к. при запуске команды не производится проверка готовности конфигов приложений.
|
127
130
|
# Нужно переработать механизм конфигурирования клиента загрузчика.
|
128
131
|
"""
|
132
|
+
import uploader_client
|
129
133
|
from django.core.cache import (
|
130
134
|
DEFAULT_CACHE_ALIAS,
|
131
135
|
caches,
|
132
136
|
)
|
133
|
-
|
134
|
-
import uploader_client
|
135
137
|
from uploader_client.contrib.rdm.interfaces.configurations import (
|
136
138
|
RegionalDataMartUploaderConfig,
|
137
139
|
)
|
@@ -290,7 +292,7 @@ class BaseExportLatestEntitiesData(BaseExportEntitiesData):
|
|
290
292
|
"""Добавляет в описание асинхронной задачи список выгруженных сущностей."""
|
291
293
|
if exported_entities and self.task_id:
|
292
294
|
self.async_task.objects.filter(
|
293
|
-
|
295
|
+
pk=self.task_id,
|
294
296
|
).update(
|
295
297
|
description=Concat(
|
296
298
|
'description',
|
@@ -406,3 +408,11 @@ class BaseExportLatestEntitiesData(BaseExportEntitiesData):
|
|
406
408
|
|
407
409
|
class ExportEntitiesData(BaseExportEntitiesData):
|
408
410
|
"""Экспорт сущностей РВД за указанных период."""
|
411
|
+
|
412
|
+
|
413
|
+
class ExportLatestEntitiesData(BaseExportLatestEntitiesData):
|
414
|
+
"""Класс выгрузки сущностей с момента последней успешной выгрузки."""
|
415
|
+
|
416
|
+
def _get_async_task(self) -> Model:
|
417
|
+
"""Возвращает модель асинхронной задачи."""
|
418
|
+
return RunningTask
|
@@ -0,0 +1,137 @@
|
|
1
|
+
from concurrent.futures import (
|
2
|
+
ThreadPoolExecutor,
|
3
|
+
)
|
4
|
+
from json import (
|
5
|
+
JSONDecodeError,
|
6
|
+
)
|
7
|
+
from typing import (
|
8
|
+
TYPE_CHECKING,
|
9
|
+
Any,
|
10
|
+
Dict,
|
11
|
+
Optional,
|
12
|
+
Tuple,
|
13
|
+
)
|
14
|
+
|
15
|
+
from django.db import (
|
16
|
+
transaction,
|
17
|
+
)
|
18
|
+
from django.db.models import (
|
19
|
+
QuerySet,
|
20
|
+
)
|
21
|
+
from uploader_client.adapters import (
|
22
|
+
adapter,
|
23
|
+
)
|
24
|
+
|
25
|
+
from educommon import (
|
26
|
+
logger,
|
27
|
+
)
|
28
|
+
|
29
|
+
from edu_rdm_integration.enums import (
|
30
|
+
FileUploadStatusEnum,
|
31
|
+
)
|
32
|
+
from edu_rdm_integration.export_data.base.requests import (
|
33
|
+
RegionalDataMartStatusRequest,
|
34
|
+
)
|
35
|
+
from edu_rdm_integration.models import (
|
36
|
+
DataMartRequestStatus,
|
37
|
+
ExportingDataSubStageUploaderClientLog,
|
38
|
+
UploadStatusRequestLog,
|
39
|
+
)
|
40
|
+
|
41
|
+
|
42
|
+
if TYPE_CHECKING:
|
43
|
+
from uploader_client.models import (
|
44
|
+
Entry,
|
45
|
+
)
|
46
|
+
|
47
|
+
|
48
|
+
class UploadStatusHelper:
|
49
|
+
"""Хелпер проверки статуса загрузки данных в витрину."""
|
50
|
+
|
51
|
+
def __init__(self, in_progress_uploads: QuerySet) -> None:
|
52
|
+
self._in_progress_uploads = in_progress_uploads
|
53
|
+
|
54
|
+
def run(self, thread_count: int = 1) -> None:
|
55
|
+
"""Запускает проверки статусов."""
|
56
|
+
if thread_count > 1:
|
57
|
+
with ThreadPoolExecutor(max_workers=thread_count) as pool:
|
58
|
+
pool.map(self._process_upload, self._in_progress_uploads)
|
59
|
+
else:
|
60
|
+
for upload in self._in_progress_uploads:
|
61
|
+
self._process_upload(upload)
|
62
|
+
|
63
|
+
@classmethod
|
64
|
+
def send_upload_status_request(cls, request_id: str) -> Tuple[Optional[Dict[str, Any]], 'Entry']:
|
65
|
+
"""Формирует и отправляет запрос для получения статуса загрузки данных в витрину."""
|
66
|
+
request = RegionalDataMartStatusRequest(
|
67
|
+
request_id=request_id,
|
68
|
+
method='GET',
|
69
|
+
parameters={},
|
70
|
+
headers={
|
71
|
+
'Content-Type': 'application/json',
|
72
|
+
},
|
73
|
+
)
|
74
|
+
|
75
|
+
result = adapter.send(request)
|
76
|
+
|
77
|
+
response = None
|
78
|
+
|
79
|
+
if result.error:
|
80
|
+
logger.error(
|
81
|
+
f'Ошибка при получении статуса загрузки данных в витрину. Идентификатор загрузки: {request_id}. '
|
82
|
+
f'Ошибка: {result.error}, запрос: {result.log.request}, ответ: {result.log.response}',
|
83
|
+
)
|
84
|
+
else:
|
85
|
+
logger.info(
|
86
|
+
f'Получен ответ со статусом {result.response.status_code} и содержимым {result.response.text}. '
|
87
|
+
f'Идентификатор загрузки: {request_id}',
|
88
|
+
)
|
89
|
+
try:
|
90
|
+
response = result.response.json()
|
91
|
+
except JSONDecodeError:
|
92
|
+
logger.error(
|
93
|
+
f'Не удалось получить данные из ответа запроса статуса загрузки данных в витрину. '
|
94
|
+
f'Идентификатор загрузки: {request_id}, ответ: {result.response.text}',
|
95
|
+
)
|
96
|
+
|
97
|
+
return response, result.log
|
98
|
+
|
99
|
+
@classmethod
|
100
|
+
def update_upload_status(
|
101
|
+
cls,
|
102
|
+
upload: ExportingDataSubStageUploaderClientLog,
|
103
|
+
response: Optional[Dict[str, Any]],
|
104
|
+
log_entry: 'Entry',
|
105
|
+
) -> None:
|
106
|
+
"""Обновляет статус загрузки данных в витрину."""
|
107
|
+
request_status = None
|
108
|
+
|
109
|
+
if isinstance(response, dict):
|
110
|
+
request_status = DataMartRequestStatus.get_values_to_enum_data().get(response.get('code'))
|
111
|
+
|
112
|
+
if not request_status:
|
113
|
+
logger.error(
|
114
|
+
'Не удалось определить статус загрузки данных в витрину. Идентификатор загрузки: '
|
115
|
+
f'{upload.request_id}, данные ответа: {response}',
|
116
|
+
)
|
117
|
+
|
118
|
+
with transaction.atomic():
|
119
|
+
UploadStatusRequestLog.objects.create(
|
120
|
+
upload=upload,
|
121
|
+
entry=log_entry,
|
122
|
+
request_status_id=getattr(request_status, 'key', None),
|
123
|
+
)
|
124
|
+
|
125
|
+
if request_status in {DataMartRequestStatus.FAILED_PROCESSING, DataMartRequestStatus.REQUEST_ID_NOT_FOUND}:
|
126
|
+
upload.file_upload_status = FileUploadStatusEnum.ERROR
|
127
|
+
|
128
|
+
elif request_status == DataMartRequestStatus.SUCCESSFULLY_PROCESSED:
|
129
|
+
upload.file_upload_status = FileUploadStatusEnum.FINISHED
|
130
|
+
|
131
|
+
if upload.file_upload_status != FileUploadStatusEnum.IN_PROGRESS:
|
132
|
+
upload.save()
|
133
|
+
|
134
|
+
def _process_upload(self, upload: ExportingDataSubStageUploaderClientLog) -> None:
|
135
|
+
"""Обрабатывает запись загрузки данных в витрину."""
|
136
|
+
response, log_entry = self.send_upload_status_request(upload.request_id)
|
137
|
+
self.update_upload_status(upload, response, log_entry)
|
@@ -0,0 +1,97 @@
|
|
1
|
+
"""
|
2
|
+
Команда для проверки состояния отправленных в витрину данных.
|
3
|
+
|
4
|
+
Необязательные параметры:
|
5
|
+
--period_started_at - дата и время начала периода загрузки данных в витрину
|
6
|
+
--period_ended_at - дата и время конца периода загрузки данных в витрину
|
7
|
+
--thread_count - количество потоков для обработки
|
8
|
+
|
9
|
+
Пример использования:
|
10
|
+
python manage.py check_upload_status --period_started_at="01.11.2023 10:00:00" --thread_count=4
|
11
|
+
"""
|
12
|
+
from datetime import (
|
13
|
+
date,
|
14
|
+
datetime,
|
15
|
+
time,
|
16
|
+
)
|
17
|
+
from typing import (
|
18
|
+
TYPE_CHECKING,
|
19
|
+
Any,
|
20
|
+
Dict,
|
21
|
+
Tuple,
|
22
|
+
)
|
23
|
+
|
24
|
+
from django.core.management.base import (
|
25
|
+
BaseCommand,
|
26
|
+
)
|
27
|
+
|
28
|
+
from edu_rdm_integration.consts import (
|
29
|
+
DATETIME_FORMAT,
|
30
|
+
)
|
31
|
+
from edu_rdm_integration.enums import (
|
32
|
+
FileUploadStatusEnum,
|
33
|
+
)
|
34
|
+
from edu_rdm_integration.helpers import UploadStatusHelper
|
35
|
+
from edu_rdm_integration.models import (
|
36
|
+
ExportingDataSubStageUploaderClientLog,
|
37
|
+
)
|
38
|
+
|
39
|
+
|
40
|
+
if TYPE_CHECKING:
|
41
|
+
from django.core.management.base import (
|
42
|
+
CommandParser,
|
43
|
+
)
|
44
|
+
|
45
|
+
|
46
|
+
class Command(BaseCommand):
|
47
|
+
"""Команда для проверки состояния отправленных в витрину данных."""
|
48
|
+
|
49
|
+
help = 'Команда для проверки состояния отправленных в витрину данных' # noqa: A003
|
50
|
+
|
51
|
+
def add_arguments(self, parser: 'CommandParser') -> None:
|
52
|
+
"""Добавляет аргументы парсера."""
|
53
|
+
parser.add_argument(
|
54
|
+
'--period_started_at',
|
55
|
+
action='store',
|
56
|
+
dest='period_started_at',
|
57
|
+
type=lambda started_at: datetime.strptime(started_at, DATETIME_FORMAT),
|
58
|
+
default=datetime.combine(date.today(), time.min),
|
59
|
+
help=(
|
60
|
+
'Дата и время начала периода загрузки данных в витрину. Значение предоставляется в формате '
|
61
|
+
'"дд.мм.гггг чч:мм:сс". По умолчанию, сегодняшний день, время 00:00:00.'
|
62
|
+
),
|
63
|
+
)
|
64
|
+
|
65
|
+
parser.add_argument(
|
66
|
+
'--period_ended_at',
|
67
|
+
action='store',
|
68
|
+
dest='period_ended_at',
|
69
|
+
type=lambda ended_at: datetime.strptime(ended_at, DATETIME_FORMAT),
|
70
|
+
default=datetime.combine(date.today(), time.max),
|
71
|
+
help=(
|
72
|
+
'Дата и время конца периода загрузки данных в витрину. Значение предоставляется в формате '
|
73
|
+
'"дд.мм.гггг чч:мм:сс". По умолчанию, сегодняшний день, время 23:59:59.'
|
74
|
+
),
|
75
|
+
)
|
76
|
+
|
77
|
+
parser.add_argument(
|
78
|
+
'--thread_count',
|
79
|
+
default=1,
|
80
|
+
type=int,
|
81
|
+
help='Количество потоков для обработки. По умолчанию, 1.',
|
82
|
+
)
|
83
|
+
|
84
|
+
def handle(self, *args: Tuple[Any], **kwargs: Dict[str, Any]) -> None:
|
85
|
+
"""Обработчик команды."""
|
86
|
+
thread_count = kwargs['thread_count']
|
87
|
+
if thread_count < 1:
|
88
|
+
raise ValueError(f'Количество потоков {thread_count} должно быть больше 0.')
|
89
|
+
|
90
|
+
in_progress_attachment_uploads = ExportingDataSubStageUploaderClientLog.objects.filter(
|
91
|
+
created__gte=kwargs['period_started_at'],
|
92
|
+
created__lte=kwargs['period_ended_at'],
|
93
|
+
is_emulation=False,
|
94
|
+
file_upload_status=FileUploadStatusEnum.IN_PROGRESS,
|
95
|
+
)
|
96
|
+
|
97
|
+
UploadStatusHelper(in_progress_attachment_uploads).run(thread_count=thread_count)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
from edu_rdm_integration.collect_data.collect import (
|
2
|
+
BaseCollectLatestModelsData,
|
3
|
+
BaseCollectModelsData,
|
4
|
+
)
|
5
|
+
from edu_rdm_integration.management.general import (
|
6
|
+
BaseCollectModelDataCommand,
|
7
|
+
)
|
8
|
+
|
9
|
+
|
10
|
+
class Command(BaseCollectModelDataCommand):
|
11
|
+
"""
|
12
|
+
Команда для сбора на основе логов за период с последней сборки до указанной даты.
|
13
|
+
"""
|
14
|
+
|
15
|
+
def _prepare_collect_models_data_class(self, *args, **kwargs) -> BaseCollectModelsData:
|
16
|
+
return BaseCollectLatestModelsData(
|
17
|
+
models=kwargs.get('models'),
|
18
|
+
logs_period_started_at=kwargs.get('logs_period_started_at'),
|
19
|
+
logs_period_ended_at=kwargs.get('logs_period_ended_at'),
|
20
|
+
)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
from edu_rdm_integration.export_data.export import (
|
2
|
+
BaseExportEntitiesData,
|
3
|
+
ExportLatestEntitiesData,
|
4
|
+
)
|
5
|
+
from edu_rdm_integration.management.general import (
|
6
|
+
BaseExportEntityDataCommand,
|
7
|
+
)
|
8
|
+
|
9
|
+
|
10
|
+
class Command(BaseExportEntityDataCommand):
|
11
|
+
"""
|
12
|
+
Команда для экспорта данных за период с последней сборки до указанной даты.
|
13
|
+
"""
|
14
|
+
|
15
|
+
# flake8: noqa: A003
|
16
|
+
help = 'Команда для запуска функции экспорта данных для интеграции с "Региональная витрина данных"'
|
17
|
+
|
18
|
+
def _prepare_export_entities_data_class(self, *args, **kwargs) -> BaseExportEntitiesData:
|
19
|
+
"""Возвращает объект класса экспорта данных сущностей РВД."""
|
20
|
+
return ExportLatestEntitiesData(
|
21
|
+
entities=kwargs.get('entities'),
|
22
|
+
period_started_at=kwargs.get('period_started_at'),
|
23
|
+
period_ended_at=kwargs.get('period_ended_at'),
|
24
|
+
task_id=kwargs.get('task_id'),
|
25
|
+
update_modified=kwargs.get('update_modified'),
|
26
|
+
)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import django.db.models.deletion
|
2
|
+
from django.db import (
|
3
|
+
migrations,
|
4
|
+
models,
|
5
|
+
)
|
6
|
+
|
7
|
+
|
8
|
+
class Migration(migrations.Migration):
|
9
|
+
"""Миграция."""
|
10
|
+
|
11
|
+
dependencies = [
|
12
|
+
('edu_rdm_integration', '0007_delete_upload_status'),
|
13
|
+
]
|
14
|
+
|
15
|
+
operations = [
|
16
|
+
migrations.CreateModel(
|
17
|
+
name='TransferredEntity',
|
18
|
+
fields=[
|
19
|
+
(
|
20
|
+
'id',
|
21
|
+
models.AutoField(
|
22
|
+
auto_created=True,
|
23
|
+
primary_key=True,
|
24
|
+
serialize=False,
|
25
|
+
verbose_name='ID',
|
26
|
+
),
|
27
|
+
),
|
28
|
+
(
|
29
|
+
'entity',
|
30
|
+
models.OneToOneField(
|
31
|
+
on_delete=django.db.models.deletion.CASCADE,
|
32
|
+
to='edu_rdm_integration.RegionalDataMartEntityEnum',
|
33
|
+
verbose_name='Сущность',
|
34
|
+
),
|
35
|
+
),
|
36
|
+
],
|
37
|
+
options={
|
38
|
+
'verbose_name': 'Сущность, по которой должен быть произведен сбор и экспорт данных',
|
39
|
+
'verbose_name_plural': 'Сущности, по которым должен быть произведен сбор и экспорт данных',
|
40
|
+
'db_table': 'rdm_transferred_entity',
|
41
|
+
},
|
42
|
+
),
|
43
|
+
]
|
edu_rdm_integration/models.py
CHANGED
@@ -24,6 +24,7 @@ from django.db.models import (
|
|
24
24
|
FileField,
|
25
25
|
ForeignKey,
|
26
26
|
Manager,
|
27
|
+
OneToOneField,
|
27
28
|
SmallIntegerField,
|
28
29
|
UUIDField,
|
29
30
|
)
|
@@ -895,3 +896,18 @@ class UploaderClientLog(Entry):
|
|
895
896
|
|
896
897
|
class Meta:
|
897
898
|
proxy = True
|
899
|
+
|
900
|
+
|
901
|
+
class TransferredEntity(BaseObjectModel):
|
902
|
+
"""Сущность, по которой должен быть произведен сбор и экспорт данных."""
|
903
|
+
|
904
|
+
entity = OneToOneField(
|
905
|
+
to=RegionalDataMartEntityEnum,
|
906
|
+
verbose_name='Сущность',
|
907
|
+
on_delete=CASCADE,
|
908
|
+
)
|
909
|
+
|
910
|
+
class Meta:
|
911
|
+
db_table = 'rdm_transferred_entity'
|
912
|
+
verbose_name = 'Сущность, по которой должен быть произведен сбор и экспорт данных'
|
913
|
+
verbose_name_plural = 'Сущности, по которым должен быть произведен сбор и экспорт данных'
|
File without changes
|
@@ -0,0 +1,136 @@
|
|
1
|
+
from m3 import (
|
2
|
+
OperationResult,
|
3
|
+
)
|
4
|
+
from m3.actions import (
|
5
|
+
ControllerCache,
|
6
|
+
)
|
7
|
+
from m3_ext.ui.containers import (
|
8
|
+
ExtGridCheckBoxSelModel,
|
9
|
+
)
|
10
|
+
from objectpack.actions import (
|
11
|
+
BaseAction,
|
12
|
+
ObjectPack,
|
13
|
+
SelectorWindowAction,
|
14
|
+
)
|
15
|
+
|
16
|
+
from edu_rdm_integration.models import (
|
17
|
+
RegionalDataMartEntityEnum,
|
18
|
+
TransferredEntity,
|
19
|
+
)
|
20
|
+
|
21
|
+
|
22
|
+
class EntitySelectPack(ObjectPack):
|
23
|
+
"""Пак выбора сущностей для сбора и экспорта данных."""
|
24
|
+
|
25
|
+
title = 'Сущность РВД'
|
26
|
+
model = RegionalDataMartEntityEnum
|
27
|
+
_is_primary_for_model = False
|
28
|
+
|
29
|
+
list_sort_order = ('order_number', )
|
30
|
+
|
31
|
+
columns = [
|
32
|
+
{
|
33
|
+
'data_index': 'key',
|
34
|
+
'header': 'Сущность',
|
35
|
+
},
|
36
|
+
{
|
37
|
+
'data_index': 'title',
|
38
|
+
'header': 'Описание',
|
39
|
+
},
|
40
|
+
]
|
41
|
+
|
42
|
+
def get_rows_query(self, request, context):
|
43
|
+
"""Возвращает выборку из БД для получения списка данных.
|
44
|
+
|
45
|
+
Ранее выбранные сущности не отображаются в списке.
|
46
|
+
"""
|
47
|
+
query = super().get_rows_query(request, context)
|
48
|
+
|
49
|
+
return query.filter(transferredentity__isnull=True)
|
50
|
+
|
51
|
+
|
52
|
+
class TransferredEntityAddWindowAction(SelectorWindowAction):
|
53
|
+
"""Экшн показа окна выбора сущностей для сбора и экспорта данных."""
|
54
|
+
|
55
|
+
def configure_action(self, request, context):
|
56
|
+
"""Конфигурирует экшн."""
|
57
|
+
self.data_pack = ControllerCache.find_pack(EntitySelectPack)
|
58
|
+
self.callback_url = self.parent.save_action.absolute_url()
|
59
|
+
|
60
|
+
def configure_window(self, win, request, context):
|
61
|
+
"""Конфигурирует окно выбора."""
|
62
|
+
win.grid.sm = ExtGridCheckBoxSelModel()
|
63
|
+
win.grid.store.id_property = 'key'
|
64
|
+
|
65
|
+
return win
|
66
|
+
|
67
|
+
|
68
|
+
class TransferredEntitySaveAction(BaseAction):
|
69
|
+
"""Экшн сохранения выбранных сущностей для сбора и экспорта данных."""
|
70
|
+
|
71
|
+
def context_declaration(self):
|
72
|
+
"""Объявляет контекст экшна."""
|
73
|
+
return {
|
74
|
+
'id': {'type': 'str_list', 'default': []},
|
75
|
+
}
|
76
|
+
|
77
|
+
def run(self, request, context):
|
78
|
+
"""Обеспечивает выполнение запроса."""
|
79
|
+
self.parent.model.objects.bulk_create([
|
80
|
+
self.parent.model(entity_id=key)
|
81
|
+
for key in context.id
|
82
|
+
])
|
83
|
+
|
84
|
+
return OperationResult(success=True)
|
85
|
+
|
86
|
+
|
87
|
+
class TransferredEntityPack(ObjectPack):
|
88
|
+
"""Пак сущностей, по которым должен быть произведен сбор и экспорт данных."""
|
89
|
+
|
90
|
+
title = 'Сущности для сбора и экспорта данных'
|
91
|
+
model = TransferredEntity
|
92
|
+
|
93
|
+
can_delete = True
|
94
|
+
|
95
|
+
list_sort_order = ('entity__order_number', )
|
96
|
+
|
97
|
+
need_check_permission = True
|
98
|
+
|
99
|
+
columns = [
|
100
|
+
{
|
101
|
+
'data_index': 'entity.key',
|
102
|
+
'header': 'Сущность',
|
103
|
+
},
|
104
|
+
{
|
105
|
+
'data_index': 'entity.title',
|
106
|
+
'header': 'Описание',
|
107
|
+
},
|
108
|
+
]
|
109
|
+
|
110
|
+
def __init__(self):
|
111
|
+
super().__init__()
|
112
|
+
|
113
|
+
self.add_window_action = TransferredEntityAddWindowAction()
|
114
|
+
self.replace_action('new_window_action', self.add_window_action)
|
115
|
+
|
116
|
+
self.save_entity_action = TransferredEntitySaveAction()
|
117
|
+
self.replace_action('save_action', self.save_entity_action)
|
118
|
+
|
119
|
+
def configure_grid(self, grid, *args, **kwargs):
|
120
|
+
"""Конфигурирует грид."""
|
121
|
+
super().configure_grid(grid, *args, **kwargs)
|
122
|
+
|
123
|
+
grid.sm = ExtGridCheckBoxSelModel()
|
124
|
+
|
125
|
+
def extend_menu(self, menu):
|
126
|
+
"""Расширяет главное меню."""
|
127
|
+
return menu.SubMenu(
|
128
|
+
'Администрирование',
|
129
|
+
menu.SubMenu(
|
130
|
+
'Региональная витрина данных',
|
131
|
+
menu.Item(
|
132
|
+
self.title,
|
133
|
+
self.list_window_action,
|
134
|
+
),
|
135
|
+
),
|
136
|
+
)
|
@@ -0,0 +1,94 @@
|
|
1
|
+
from celery.schedules import (
|
2
|
+
crontab,
|
3
|
+
)
|
4
|
+
from django.conf import (
|
5
|
+
settings,
|
6
|
+
)
|
7
|
+
|
8
|
+
from educommon.async_task.models import (
|
9
|
+
AsyncTaskType,
|
10
|
+
)
|
11
|
+
from educommon.async_task.tasks import (
|
12
|
+
PeriodicAsyncTask,
|
13
|
+
)
|
14
|
+
|
15
|
+
from edu_rdm_integration.collect_data.helpers import (
|
16
|
+
set_failed_status_suspended_collecting_data_stages,
|
17
|
+
)
|
18
|
+
from edu_rdm_integration.consts import (
|
19
|
+
TASK_QUEUE_NAME,
|
20
|
+
)
|
21
|
+
from edu_rdm_integration.enums import (
|
22
|
+
FileUploadStatusEnum,
|
23
|
+
)
|
24
|
+
from edu_rdm_integration.export_data.helpers import (
|
25
|
+
set_failed_status_suspended_exporting_data_stages,
|
26
|
+
)
|
27
|
+
from edu_rdm_integration.helpers import (
|
28
|
+
UploadStatusHelper,
|
29
|
+
)
|
30
|
+
from edu_rdm_integration.models import (
|
31
|
+
ExportingDataSubStageUploaderClientLog,
|
32
|
+
)
|
33
|
+
|
34
|
+
|
35
|
+
class RDMCheckUploadStatus(PeriodicAsyncTask):
|
36
|
+
"""Периодическая задача для сбора статусов по загрузке файла в витрину."""
|
37
|
+
|
38
|
+
queue = TASK_QUEUE_NAME
|
39
|
+
routing_key = TASK_QUEUE_NAME
|
40
|
+
description = 'Сбор статусов загрузки данных в витрину "Региональная витрина данных"'
|
41
|
+
task_type = AsyncTaskType.UNKNOWN
|
42
|
+
run_every = crontab(
|
43
|
+
minute=settings.RDM_UPLOAD_STATUS_TASK_MINUTE,
|
44
|
+
hour=settings.RDM_UPLOAD_STATUS_TASK_HOUR,
|
45
|
+
day_of_week=settings.RDM_UPLOAD_STATUS_TASK_DAY_OF_WEEK,
|
46
|
+
)
|
47
|
+
|
48
|
+
def process(self, *args, **kwargs):
|
49
|
+
"""Выполнение."""
|
50
|
+
super().process(*args, **kwargs)
|
51
|
+
|
52
|
+
# Получаем незавершенные загрузки данных в витрину
|
53
|
+
in_progress_uploads = ExportingDataSubStageUploaderClientLog.objects.filter(
|
54
|
+
file_upload_status=FileUploadStatusEnum.IN_PROGRESS,
|
55
|
+
is_emulation=False,
|
56
|
+
)
|
57
|
+
|
58
|
+
UploadStatusHelper(in_progress_uploads).run()
|
59
|
+
|
60
|
+
|
61
|
+
class CheckSuspendedExportedStagePeriodicTask(PeriodicAsyncTask):
|
62
|
+
"""Периодическая задача поиска зависших этапов/подэтапов экспорта."""
|
63
|
+
|
64
|
+
queue = TASK_QUEUE_NAME
|
65
|
+
routing_key = TASK_QUEUE_NAME
|
66
|
+
description = 'Поиск зависших этапов/подэтапов экспорта в "Региональная витрина данных"'
|
67
|
+
task_type = AsyncTaskType.SYSTEM
|
68
|
+
run_every = crontab(
|
69
|
+
minute=settings.RDM_CHECK_SUSPEND_TASK_MINUTE,
|
70
|
+
hour=settings.RDM_CHECK_SUSPEND_TASK_HOUR,
|
71
|
+
day_of_week=settings.RDM_CHECK_SUSPEND_TASK_DAY_OF_WEEK,
|
72
|
+
)
|
73
|
+
|
74
|
+
def process(self, *args, **kwargs):
|
75
|
+
"""Выполнение задачи."""
|
76
|
+
super().process(*args, **kwargs)
|
77
|
+
|
78
|
+
change_status_collecting_result = set_failed_status_suspended_collecting_data_stages()
|
79
|
+
change_status_exporting_result = set_failed_status_suspended_exporting_data_stages()
|
80
|
+
|
81
|
+
task_result = {
|
82
|
+
'Прервано сборок': (
|
83
|
+
f'Этапов {change_status_collecting_result["change_stage_count"]}'
|
84
|
+
f' и подэтапов {change_status_collecting_result["change_sub_stage_count"]}'
|
85
|
+
),
|
86
|
+
'Прервано выгрузок': (
|
87
|
+
f'Этапов {change_status_exporting_result["change_stage_count"]}'
|
88
|
+
f' и подэтапов {change_status_exporting_result["change_sub_stage_count"]}'
|
89
|
+
),
|
90
|
+
}
|
91
|
+
|
92
|
+
self.set_progress(
|
93
|
+
values=task_result
|
94
|
+
)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: edu-rdm-integration
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.9.1
|
4
4
|
Summary: Интеграция с Региональной витриной данных
|
5
5
|
Home-page:
|
6
6
|
Download-URL:
|
@@ -28,7 +28,8 @@ Requires-Dist: setuptools <69,>=47.3.1
|
|
28
28
|
Requires-Dist: wheel <0.42,>=0.37.1
|
29
29
|
Requires-Dist: transliterate <2
|
30
30
|
Requires-Dist: Django <2.3,>=1.11
|
31
|
-
Requires-Dist:
|
31
|
+
Requires-Dist: celery ==4.4.7
|
32
|
+
Requires-Dist: educommon <4,>=3.7.0
|
32
33
|
Requires-Dist: function-tools <1,>=0.8.0
|
33
34
|
Requires-Dist: m3-db-utils <1,>=0.3.10
|
34
35
|
Requires-Dist: uploader-client <1,>=0.2.1
|
@@ -142,9 +143,7 @@ Requires-Dist: uploader-client <1,>=0.2.1
|
|
142
143
|
RDM_TRANSFER_TASK_HOUR = conf.get('rdm_transfer_task', 'HOUR')
|
143
144
|
RDM_TRANSFER_TASK_DAY_OF_WEEK = conf.get('rdm_transfer_task', 'DAY_OF_WEEK')
|
144
145
|
RDM_TRANSFER_TASK_TIMEDELTA = conf.get_int('rdm_transfer_task', 'TIMEDELTA')
|
145
|
-
|
146
|
-
RDM_TRANSFER_TASK_ENTITIES = conf.get_tuple('rdm_transfer_task', 'ENTITIES') or ()
|
147
|
-
|
146
|
+
|
148
147
|
# Настройка запуска периодической задачи статуса загрузки данных в витрину:
|
149
148
|
RDM_UPLOAD_STATUS_TASK_MINUTE = conf.get('rdm_upload_status_task', 'MINUTE')
|
150
149
|
RDM_UPLOAD_STATUS_TASK_HOUR = conf.get('rdm_upload_status_task', 'HOUR')
|
@@ -190,7 +189,6 @@ Requires-Dist: uploader-client <1,>=0.2.1
|
|
190
189
|
| RDM_TRANSFER_TASK_HOUR | Настройка запуска периодической задачи выгрузки данных. Час | '*/4' |
|
191
190
|
| RDM_TRANSFER_TASK_DAY_OF_WEEK | Настройка запуска периодической задачи выгрузки данных. День недели | '*' |
|
192
191
|
| RDM_TRANSFER_TASK_TIMEDELTA | Дельта между предыдущим и следующим запуском периодической задачи в секундах | 3600 |
|
193
|
-
| RDM_TRANSFER_TASK_ENTITIES | Сущности, по которым должен производиться сбор и выгрузка данных | '' |
|
194
192
|
| RDM_UPLOAD_STATUS_TASK_MINUTE | Настройка запуска периодической задачи статуса загрузки данных в витрину. Минута | '*/30' |
|
195
193
|
| RDM_UPLOAD_STATUS_TASK_HOUR | Настройка запуска периодической задачи статуса загрузки данных в витрину. Час | '*' |
|
196
194
|
| RDM_UPLOAD_STATUS_TASK_DAY_OF_WEEK | Настройка запуска периодической задачи статуса загрузки данных в витрину. День недели | '*' |
|
@@ -289,6 +287,45 @@ Requires-Dist: uploader-client <1,>=0.2.1
|
|
289
287
|
|
290
288
|
### Удалено
|
291
289
|
|
290
|
+
## [0.9.1] - 2024-01-11
|
291
|
+
|
292
|
+
Добавлен реестр выбора сущностей для сбора и выгрузки данных.
|
293
|
+
Удалена настройка RDM_TRANSFER_TASK_ENTITIES, вместо перечисления сущностей в конфиге используется реестр и модель
|
294
|
+
TransferredEntity.
|
295
|
+
|
296
|
+
### Добавлено
|
297
|
+
|
298
|
+
- [EDUSCHL-21112](https://jira.bars.group/browse/EDUSCHL-21112)
|
299
|
+
MINOR Добавлен реестр выбора сущностей для сбора и выгрузки данных.
|
300
|
+
|
301
|
+
### Удалено
|
302
|
+
|
303
|
+
- [EDUSCHL-21112](https://jira.bars.group/browse/EDUSCHL-21112)
|
304
|
+
MINOR Удалена настройка RDM_TRANSFER_TASK_ENTITIES.
|
305
|
+
|
306
|
+
|
307
|
+
## [0.9.0] - 2023-12-29
|
308
|
+
|
309
|
+
Из ЭШ перенесены периодические задачи по сбору статусов загрузки файлов в витрину, а также
|
310
|
+
по поиску зависших этапов/подэтапов экспорта.
|
311
|
+
|
312
|
+
Также из ЭШ перенесены менедж-команды:
|
313
|
+
- check_upload_status - проверка состояния отправленных данных в витрину,
|
314
|
+
- collect_lastest_models_data - сбор на основе логов за период с последней сборки до указанной даты,
|
315
|
+
- export_latest_entities_data - экспорт данных за период с последней сборки до указанной даты.
|
316
|
+
|
317
|
+
Типы получаемых из log_change.fields полей соответствуют типам полей из логируемых моделей.
|
318
|
+
|
319
|
+
### Добавлено
|
320
|
+
|
321
|
+
- [EDUSCHL-21013](https://jira.bars.group/browse/EDUSCHL-21013)
|
322
|
+
MINOR Перенесена часть асинхронных РВД задач из ЭШ, а также часть менедж-команд
|
323
|
+
|
324
|
+
### Изменено
|
325
|
+
|
326
|
+
- [EDUSCHL-20793](https://jira.bars.group/browse/EDUSCHL-20793)
|
327
|
+
MINOR Типы получаемых из log_change.fields полей должны соответствовать типам полей из логируемых моделей
|
328
|
+
|
292
329
|
|
293
330
|
## [0.8.6] - 2023-12-18
|
294
331
|
|
@@ -1,14 +1,17 @@
|
|
1
1
|
edu_rdm_integration/__init__.py,sha256=fVCvQ7QGI_iCyAeE8dMapyY8gOM617ye5GQqAVGPlZI,72
|
2
|
+
edu_rdm_integration/app_meta.py,sha256=v5IU69yaeLbyHF0Ln6iPN_IfizbtF3rCWrz2n71m8dU,337
|
2
3
|
edu_rdm_integration/app_settings.py,sha256=kideEO9SvYU8RXPB-8hTVosL4bAspPHNHtyz-R0F7v4,1822
|
3
4
|
edu_rdm_integration/apps.py,sha256=5OgNdmuqe26fbu4wYb69haQJe-XFO_rDbnU1vPqJU-U,3571
|
4
5
|
edu_rdm_integration/base.py,sha256=_G0qPTAXe6bXfgDHNiZMSsYt3sMuUhLKnHuQCWSFttU,1341
|
5
6
|
edu_rdm_integration/consts.py,sha256=FFwcMHNsfjP_s9LfkccLAHjJMEMp7ppPmrRlJcgV88k,1104
|
6
7
|
edu_rdm_integration/entities.py,sha256=mAjsYlcIbemo4xT5CSCr4payZubiBHB7Rb3Ow1CVsy0,14552
|
7
8
|
edu_rdm_integration/enums.py,sha256=6Gv_hpYrC6v75ZtBA_xBrHqvza9NbJKhMa1TdTHkzys,4048
|
9
|
+
edu_rdm_integration/helpers.py,sha256=-UjORR2Pj_zW9gcAz-Dqs2Qi-s8TIptKVUBJVUBjRus,4958
|
8
10
|
edu_rdm_integration/mapping.py,sha256=bwa2fJCbV4YjQcAgRrgT3hgM6dJhr_uBtQgx3L3F2Ck,473
|
9
|
-
edu_rdm_integration/models.py,sha256=
|
11
|
+
edu_rdm_integration/models.py,sha256=Wg8NYj4C6Xqw-15AsQGU0TWNzUjdwBW_YZDzmPqx3GY,29327
|
10
12
|
edu_rdm_integration/signals.py,sha256=3eRlpkDcFCF6TN80-QM8yBYLcyozzcmoPjz6r4_ApWg,73
|
11
13
|
edu_rdm_integration/storages.py,sha256=o5WqUG7SnkeuMt-z8spUi-IraivST-7KHzfY-M3v7FA,6807
|
14
|
+
edu_rdm_integration/tasks.py,sha256=XzRhcfv6u2LSANvWTNvocdw0UJZDKLn3MzenViYrAVE,3421
|
12
15
|
edu_rdm_integration/utils.py,sha256=vjme0N6tEXnHt6SaqjavZshjwc-mVv4X3Pz37a5YgTw,7092
|
13
16
|
edu_rdm_integration/adapters/__init__.py,sha256=cU0swn4Ny5ZQz5buWRcWsT1mpWuUFJaUlHf2l7TtEBo,83
|
14
17
|
edu_rdm_integration/adapters/apps.py,sha256=TyJTkSPs2qAHJ11fqbwLGk3Ea7ujtqWwbxqmvYNQxG8,363
|
@@ -37,7 +40,7 @@ edu_rdm_integration/collect_data/base/caches.py,sha256=3BaJxYBk9fi0aiAVzym-Jz8aN
|
|
37
40
|
edu_rdm_integration/collect_data/base/functions.py,sha256=HT23EyiD-H50p4NLx2_LtioktTHHFVLRmAgWdbuHErw,2379
|
38
41
|
edu_rdm_integration/collect_data/base/helpers.py,sha256=ONbPEELI_9ImpqCLrdIL3kb9aIQ2xQcF6XMa2C5KlDw,1017
|
39
42
|
edu_rdm_integration/collect_data/base/managers.py,sha256=s9eUpVlsTw58mFuDgSBO_EKUk9nXIWUqc_Dhc54Yhfw,6812
|
40
|
-
edu_rdm_integration/collect_data/base/mixins.py,sha256
|
43
|
+
edu_rdm_integration/collect_data/base/mixins.py,sha256=-KpOg8yXeu4AEEJt26iruBEa8ErQd5XXNrUOuOL9VP8,3192
|
41
44
|
edu_rdm_integration/collect_data/base/runners.py,sha256=OjhdTmMab6dCoIZp2zmXZTK4H5Haz__QHddwGxjOuB0,2829
|
42
45
|
edu_rdm_integration/collect_data/calculated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
43
46
|
edu_rdm_integration/collect_data/calculated/strategies.py,sha256=W9f-MlLENSoa9jHMLWTP7ktZL-7FVtkt2FLXrbmds-o,7629
|
@@ -58,7 +61,7 @@ edu_rdm_integration/collect_data/calculated/base/validators.py,sha256=xIaSIE9oKb
|
|
58
61
|
edu_rdm_integration/collect_data/non_calculated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
62
|
edu_rdm_integration/collect_data/non_calculated/strategies.py,sha256=eR-z94U0XN8BBuFS789PzxCPPfUoL3a2mcZb10Psqeg,7431
|
60
63
|
edu_rdm_integration/collect_data/non_calculated/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
61
|
-
edu_rdm_integration/collect_data/non_calculated/base/caches.py,sha256=
|
64
|
+
edu_rdm_integration/collect_data/non_calculated/base/caches.py,sha256=uGtNhqC-JVSJHYrY9JcFfdaUpe2t3F5jZSRodQBSzt4,6845
|
62
65
|
edu_rdm_integration/collect_data/non_calculated/base/consts.py,sha256=pds1t4eHzovm7Yz2o5je3UHqRE8gqfT2sL-IwpoBN_o,66
|
63
66
|
edu_rdm_integration/collect_data/non_calculated/base/enums.py,sha256=BSmwrkzYwEQhz9NbZCJsldY532PqgZJzxzsVk6ue0bM,93
|
64
67
|
edu_rdm_integration/collect_data/non_calculated/base/errors.py,sha256=dGawEQ2ItTxlFt9ynhYhpqx40Qmrlg2rOskH0DsNVnQ,297
|
@@ -76,7 +79,7 @@ edu_rdm_integration/enum_register/mixins.py,sha256=shLb8-9ySoY9kK1Wzb46I9wRKglQI
|
|
76
79
|
edu_rdm_integration/enum_register/register.py,sha256=5OWOjK-M0Erd_5CENpBaXhVtfL0pEaDl3Bev5QKNDJc,2218
|
77
80
|
edu_rdm_integration/export_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
78
81
|
edu_rdm_integration/export_data/consts.py,sha256=Z6Uho8oViMc0t1tyQFZfrPFBwPx6KnhUf_iZ0qgob8o,16
|
79
|
-
edu_rdm_integration/export_data/export.py,sha256=
|
82
|
+
edu_rdm_integration/export_data/export.py,sha256=Axij_T66EX7I_VjLeVaELuKharDNAVAWDsFlZpqf9EY,16879
|
80
83
|
edu_rdm_integration/export_data/generators.py,sha256=yLDOcHB1PoilJwXtKGxZQhDjpeKBzEWoosahbJJ4Ba4,4020
|
81
84
|
edu_rdm_integration/export_data/helpers.py,sha256=hU346RmQ17Ra2etFvxXI7JQlLyp_0KxH1jm-eeCqejc,2933
|
82
85
|
edu_rdm_integration/export_data/strategies.py,sha256=ocHskG-x54U-ESX56OlZPgOibkGkuv7VKmK7hVmqj_0,6725
|
@@ -129,10 +132,13 @@ edu_rdm_integration/function_templates/function_export_data_template/validators.
|
|
129
132
|
edu_rdm_integration/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
130
133
|
edu_rdm_integration/management/general.py,sha256=Yem9IcU9es_xA6Ap8v2IpAjNL1CI5VkkvQffUoJhQhY,13381
|
131
134
|
edu_rdm_integration/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
135
|
+
edu_rdm_integration/management/commands/check_upload_status.py,sha256=jGqFMLMgrirG_H2OxzxNG3Z3d1xvORIzWqzKBUtr22Y,3843
|
136
|
+
edu_rdm_integration/management/commands/collect_latest_models_data.py,sha256=4ObBFqYMkX5v1saV9V7PivYBm0RMcDCGNlMGx77UAjs,750
|
132
137
|
edu_rdm_integration/management/commands/collect_models_data.py,sha256=11RshcQiXk6Flz-8oiFuM5KSZ_8_c1111qkqmyiu5sw,1022
|
133
138
|
edu_rdm_integration/management/commands/datamart_status.py,sha256=ImpXHwRnbcgE5pcz2_QixfEQPSLU6WH1V8Vm7xnPidU,1211
|
134
139
|
edu_rdm_integration/management/commands/datamart_upload.py,sha256=folrNInlhBP5yLSNXtujah-rfk8oWYi1Z8i5k3bsIKw,1487
|
135
140
|
edu_rdm_integration/management/commands/export_entities_data.py,sha256=Mas1zwsH-zRl6exbzF81Y4KyLAOJo-uurkdb6sZccuc,920
|
141
|
+
edu_rdm_integration/management/commands/export_latest_entities_data.py,sha256=LTMWvcp2if76kW4GD74x8fA5FAfdDnnuaUBFFGjqjVk,1146
|
136
142
|
edu_rdm_integration/migrations/0001_initial.py,sha256=toNuYoHZePe5wJ6AKEW9oPOdt2OefmxDEDDJGYQIrFk,18719
|
137
143
|
edu_rdm_integration/migrations/0002_init_data_uploadstatus.py,sha256=p8EtwowHesoRvnOxeVMPCclUaCw2aQJZ8y5Zz7xbb8Q,737
|
138
144
|
edu_rdm_integration/migrations/0003_create_index_file_upload_status.py,sha256=TiLnqQ8bxkVI7sRa5-D3JQ6jopFYDoH1ytSxmU6USUo,735
|
@@ -140,16 +146,19 @@ edu_rdm_integration/migrations/0004_uploaderclientlog.py,sha256=Llw_cqPpYJSrbEuE
|
|
140
146
|
edu_rdm_integration/migrations/0005_auto_20231204_1224.py,sha256=YXWiwTImGg8FAO_Er0qxcvaS6V9iF2rSy_7z5r--C_U,1782
|
141
147
|
edu_rdm_integration/migrations/0006_request_status_data.py,sha256=g5JZtP0q0fOrbKCooGmCeGgtcqd9ZLIBP56h-ZH8IS8,3448
|
142
148
|
edu_rdm_integration/migrations/0007_delete_upload_status.py,sha256=GAQKX6N1vDDWiCTXLGg--0gzLQr7VveAPFYzC9QpUpU,457
|
149
|
+
edu_rdm_integration/migrations/0008_transferredentity.py,sha256=rE5av85AIYKGDy7nuFKLrHAhj0uaeUTRsFfIsXPtaxo,1427
|
143
150
|
edu_rdm_integration/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
151
|
+
edu_rdm_integration/registry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
152
|
+
edu_rdm_integration/registry/actions.py,sha256=y84gsGz-ZpkOdG85dNwk-J3zmPeEqp894K55puJNDiI,4146
|
144
153
|
edu_rdm_integration/uploader_log/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
145
154
|
edu_rdm_integration/uploader_log/actions.py,sha256=SGYYYNL4MdST1FYCZBCYAxj3_-PsJ8IcXBYwxpZqucg,6755
|
146
155
|
edu_rdm_integration/uploader_log/apps.py,sha256=tYJj4-sDlq8fLOSvw18L_yys7SILpTKWNmE2Qug6GnE,265
|
147
156
|
edu_rdm_integration/uploader_log/enums.py,sha256=rgSO3BL2rh2xpfm0Pt4waQW8fB1VMJLdsGmr3SXwH_U,266
|
148
157
|
edu_rdm_integration/uploader_log/managers.py,sha256=y5wTSMzF9hpOpIU_A7nIafL_LBU3QEie6LAYWoB-pBQ,3203
|
149
158
|
edu_rdm_integration/uploader_log/ui.py,sha256=YM9Buqp2wxE95Wf5gvAATBzuYzDOossK1sEmvFk07cI,2110
|
150
|
-
edu_rdm_integration-0.
|
151
|
-
edu_rdm_integration-0.
|
152
|
-
edu_rdm_integration-0.
|
153
|
-
edu_rdm_integration-0.
|
154
|
-
edu_rdm_integration-0.
|
155
|
-
edu_rdm_integration-0.
|
159
|
+
edu_rdm_integration-0.9.1.dist-info/LICENSE,sha256=uw43Gjjj-1vXWCItfSrNDpbejnOwZMrNerUh8oWbq8Q,3458
|
160
|
+
edu_rdm_integration-0.9.1.dist-info/METADATA,sha256=4dMio16uN6o1Y1WGWOL8EWMlYf8TgsLmF4kGBU14Id8,49997
|
161
|
+
edu_rdm_integration-0.9.1.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
162
|
+
edu_rdm_integration-0.9.1.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
163
|
+
edu_rdm_integration-0.9.1.dist-info/top_level.txt,sha256=nRJV0O14UtNE-jGIYG03sohgFnZClvf57H5m6VBXe9Y,20
|
164
|
+
edu_rdm_integration-0.9.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
{edu_rdm_integration-0.8.6.dist-info → edu_rdm_integration-0.9.1.dist-info}/namespace_packages.txt
RENAMED
File without changes
|
File without changes
|