educommon 3.13.0__py3-none-any.whl → 3.13.2__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.
- educommon/__init__.py +0 -1
- educommon/about/ui/actions.py +16 -30
- educommon/about/ui/ui.py +3 -12
- educommon/about/utils.py +6 -5
- educommon/async_task/__init__.py +0 -1
- educommon/async_task/actions.py +18 -13
- educommon/async_task/apps.py +4 -0
- educommon/async_task/locker.py +2 -5
- educommon/async_task/migrations/0001_initial.py +55 -9
- educommon/async_task/migrations/0002_task_type_and_status_data.py +94 -89
- educommon/async_task/migrations/0003_alter_runningtask_options.py +0 -1
- educommon/async_task/models.py +9 -6
- educommon/async_task/tasks.py +11 -7
- educommon/async_task/ui.py +16 -35
- educommon/async_tasks/__init__.py +0 -1
- educommon/async_tasks/apps.py +4 -0
- educommon/async_tasks/locks.py +11 -21
- educommon/async_tasks/migrations/0001_initial.py +68 -8
- educommon/async_tasks/migrations/0002_load_initial_data.py +0 -1
- educommon/async_tasks/models.py +9 -29
- educommon/async_tasks/tasks.py +25 -54
- educommon/audit_log/__init__.py +1 -0
- educommon/audit_log/actions.py +27 -36
- educommon/audit_log/app_meta.py +7 -4
- educommon/audit_log/apps.py +44 -29
- educommon/audit_log/constants.py +7 -4
- educommon/audit_log/error_log/actions.py +1 -3
- educommon/audit_log/helpers.py +2 -4
- educommon/audit_log/management/commands/reinstall_audit_log.py +11 -7
- educommon/audit_log/migrations/0001_initial.py +91 -16
- educommon/audit_log/migrations/0002_install_audit_log.py +13 -13
- educommon/audit_log/migrations/0003_logproxy.py +1 -3
- educommon/audit_log/migrations/0004_reinstall_audit_log.py +1 -4
- educommon/audit_log/migrations/0005_postgresql_error.py +4 -2
- educommon/audit_log/migrations/0006_auto_20200806_1707.py +3 -4
- educommon/audit_log/migrations/0007_create_selective_tables_function.py +8 -5
- educommon/audit_log/migrations/0008_table_logged.py +0 -1
- educommon/audit_log/migrations/0009_reinstall_audit_log.py +0 -1
- educommon/audit_log/models.py +36 -42
- educommon/audit_log/permissions.py +11 -9
- educommon/audit_log/proxies.py +12 -23
- educommon/audit_log/ui.py +18 -15
- educommon/audit_log/utils/__init__.py +28 -60
- educommon/audit_log/utils/operations.py +16 -2
- educommon/auth/__init__.py +0 -3
- educommon/auth/rbac/__init__.py +2 -4
- educommon/auth/rbac/actions.py +148 -145
- educommon/auth/rbac/app_meta.py +9 -6
- educommon/auth/rbac/backends/base.py +2 -8
- educommon/auth/rbac/backends/caching.py +27 -37
- educommon/auth/rbac/backends/simple.py +1 -4
- educommon/auth/rbac/checker.py +1 -3
- educommon/auth/rbac/management/commands/rbac.py +6 -11
- educommon/auth/rbac/manager.py +18 -47
- educommon/auth/rbac/migrations/0001_initial.py +73 -12
- educommon/auth/rbac/migrations/0002_model_modifier_metaclass_fix.py +7 -6
- educommon/auth/rbac/migrations/0003_permission_hidden.py +1 -5
- educommon/auth/rbac/migrations/0004_auto_20171024_1245.py +26 -19
- educommon/auth/rbac/models.py +63 -68
- educommon/auth/rbac/permissions.py +6 -7
- educommon/auth/rbac/ui.py +83 -84
- educommon/auth/rbac/utils.py +10 -11
- educommon/auth/rbac/validators.py +4 -5
- educommon/auth/simple_auth/__init__.py +1 -5
- educommon/auth/simple_auth/actions.py +79 -92
- educommon/auth/simple_auth/app_meta.py +2 -9
- educommon/auth/simple_auth/checkers.py +3 -3
- educommon/auth/simple_auth/migrations/0001_initial.py +23 -4
- educommon/auth/simple_auth/validators.py +0 -1
- educommon/contingent/actions.py +7 -7
- educommon/contingent/app_meta.py +1 -4
- educommon/contingent/base.py +10 -15
- educommon/contingent/catalogs.py +424 -540
- educommon/contingent/contingent_plugin/actions.py +4 -15
- educommon/contingent/contingent_plugin/apps.py +10 -4
- educommon/contingent/contingent_plugin/migrations/0001_initial.py +5 -6
- educommon/contingent/contingent_plugin/migrations/0002_add_contingent_model_deleted.py +6 -11
- educommon/contingent/contingent_plugin/model_views.py +2 -12
- educommon/contingent/contingent_plugin/models.py +2 -7
- educommon/contingent/contingent_plugin/observer.py +14 -13
- educommon/contingent/contingent_plugin/plugin_meta.py +1 -3
- educommon/contingent/contingent_plugin/storage.py +8 -7
- educommon/contingent/contingent_plugin/utils.py +6 -6
- educommon/django/db/fields.py +72 -86
- educommon/django/db/migration/__init__.py +3 -7
- educommon/django/db/migration/operations.py +29 -51
- educommon/django/db/mixins/__init__.py +16 -10
- educommon/django/db/mixins/date_interval.py +47 -75
- educommon/django/db/mixins/validation.py +26 -26
- educommon/django/db/model_view/__init__.py +18 -22
- educommon/django/db/models.py +9 -8
- educommon/django/db/observer.py +9 -27
- educommon/django/db/partitioning/__init__.py +66 -92
- educommon/django/db/partitioning/management/commands/apply_partitioning.py +3 -13
- educommon/django/db/partitioning/management/commands/clear_table.py +18 -14
- educommon/django/db/partitioning/management/commands/split_table.py +18 -13
- educommon/django/db/routers.py +6 -15
- educommon/django/db/signals.py +4 -2
- educommon/django/db/utils.py +14 -19
- educommon/django/db/validators/__init__.py +1 -0
- educommon/django/db/validators/simple.py +72 -100
- educommon/django/storages/atcfs/api.py +39 -53
- educommon/django/storages/atcfs/app_meta.py +1 -1
- educommon/django/storages/atcfs/management/commands/atcfs_migrate.py +42 -55
- educommon/django/storages/atcfs/models.py +0 -3
- educommon/django/storages/atcfs/monkey_patching.py +18 -12
- educommon/django/storages/atcfs/storage.py +14 -23
- educommon/extjs/fields/input_params.py +15 -45
- educommon/importer/XLSReader.py +143 -241
- educommon/importer/__init__.py +86 -4
- educommon/importer/api.py +53 -84
- educommon/importer/constants.py +4 -14
- educommon/importer/loggers.py +16 -26
- educommon/importer/proxy.py +131 -176
- educommon/importer/proxy_import.py +11 -12
- educommon/importer/report.py +4 -6
- educommon/importer/ui.py +32 -26
- educommon/importer/validators.py +4 -7
- educommon/integration_entities/helpers.py +14 -18
- educommon/ioc/__init__.py +3 -6
- educommon/logger/loggers.py +10 -14
- educommon/m3/__init__.py +20 -38
- educommon/m3/extensions/__init__.py +1 -0
- educommon/m3/extensions/listeners/__init__.py +22 -38
- educommon/m3/extensions/listeners/delete_check/listeners.py +31 -41
- educommon/m3/extensions/listeners/delete_check/mixins.py +20 -25
- educommon/m3/extensions/listeners/delete_check/signals.py +2 -2
- educommon/m3/extensions/listeners/delete_check/ui.py +15 -14
- educommon/m3/extensions/listeners/delete_check/utils.py +9 -11
- educommon/m3/extensions/ui.py +15 -33
- educommon/m3/transaction_context.py +17 -19
- educommon/objectpack/actions.py +70 -88
- educommon/objectpack/apps.py +5 -0
- educommon/objectpack/filters.py +9 -15
- educommon/objectpack/ui.py +59 -77
- educommon/report/__init__.py +9 -5
- educommon/report/actions.py +29 -32
- educommon/report/constructor/__init__.py +5 -8
- educommon/report/constructor/app_meta.py +1 -3
- educommon/report/constructor/apps.py +1 -0
- educommon/report/constructor/base.py +33 -80
- educommon/report/constructor/builders/excel/_base.py +138 -286
- educommon/report/constructor/builders/excel/_header.py +2 -9
- educommon/report/constructor/builders/excel/product.py +13 -34
- educommon/report/constructor/builders/excel/with_merged_cells.py +18 -14
- educommon/report/constructor/config.py +2 -0
- educommon/report/constructor/editor/actions.py +101 -215
- educommon/report/constructor/editor/ui.py +71 -93
- educommon/report/constructor/exceptions.py +6 -12
- educommon/report/constructor/migrations/0001_initial.py +36 -44
- educommon/report/constructor/migrations/0002_report_filters.py +86 -72
- educommon/report/constructor/migrations/0003_reportfilter_exclude.py +5 -5
- educommon/report/constructor/migrations/0004_reportfilter_fields.py +22 -18
- educommon/report/constructor/migrations/0005_reportcolumn_visible.py +5 -4
- educommon/report/constructor/migrations/0006_reportsorting.py +21 -17
- educommon/report/constructor/migrations/0007_include_available_units.py +14 -14
- educommon/report/constructor/migrations/0008_auto_20170407_1318.py +4 -5
- educommon/report/constructor/migrations/0009_auto_20180405_0642.py +1 -4
- educommon/report/constructor/migrations/0010_add_aggregate_fields.py +7 -8
- educommon/report/constructor/mixins.py +14 -15
- educommon/report/constructor/models.py +76 -124
- educommon/report/constructor/utils.py +3 -8
- educommon/report/constructor/validators.py +1 -3
- educommon/report/reporter.py +25 -43
- educommon/report/utils.py +14 -40
- educommon/rest/actions.py +7 -11
- educommon/rest/context.py +6 -16
- educommon/rest/controllers.py +10 -10
- educommon/rest/mixins.py +29 -27
- educommon/secure_media/app_meta.py +9 -9
- educommon/utils/__init__.py +3 -2
- educommon/utils/caching.py +1 -3
- educommon/utils/conversion.py +1 -3
- educommon/utils/crypto.py +1 -2
- educommon/utils/date.py +13 -26
- educommon/utils/db/__init__.py +17 -26
- educommon/utils/db/postgresql.py +1 -4
- educommon/utils/fonts/__init__.py +3 -4
- educommon/utils/licence/__init__.py +5 -16
- educommon/utils/misc.py +9 -18
- educommon/utils/object_grid.py +55 -62
- educommon/utils/phone_number/modelfields.py +1 -3
- educommon/utils/phone_number/phone_number.py +5 -8
- educommon/utils/phone_number/validators.py +8 -23
- educommon/utils/plugins.py +15 -28
- educommon/utils/registry.py +2 -1
- educommon/utils/seqtools.py +1 -3
- educommon/utils/serializer.py +9 -16
- educommon/utils/storage.py +3 -2
- educommon/utils/system.py +1 -3
- educommon/utils/system_app/management/commands/delete_objects.py +17 -34
- educommon/utils/ui.py +87 -84
- educommon/utils/xml/__init__.py +2 -7
- educommon/utils/xml/resolver.py +1 -0
- educommon/ws_log/actions.py +31 -76
- educommon/ws_log/base.py +6 -20
- educommon/ws_log/migrations/0001_initial.py +25 -8
- educommon/ws_log/migrations/0002_auto_20160628_1334.py +0 -1
- educommon/ws_log/migrations/0003_add_fields_to_smev_logs.py +20 -4
- educommon/ws_log/migrations/0004_auto_20160727_1600.py +7 -6
- educommon/ws_log/migrations/0005_auto_20161130_1615.py +14 -4
- educommon/ws_log/migrations/0006_auto_20170327_1027.py +3 -2
- educommon/ws_log/migrations/0007_auto_20180607_1040.py +8 -9
- educommon/ws_log/migrations/0008_auto_20180713_1445.py +23 -10
- educommon/ws_log/migrations/0009_auto_20201130_1553.py +7 -2
- educommon/ws_log/models.py +21 -35
- educommon/ws_log/provider.py +2 -1
- educommon/ws_log/report.py +8 -13
- educommon/ws_log/smev/applications.py +12 -27
- educommon/ws_log/smev/exceptions.py +2 -3
- educommon/ws_log/ui.py +32 -32
- educommon/ws_log/utils.py +1 -3
- {educommon-3.13.0.dist-info → educommon-3.13.2.dist-info}/METADATA +26 -14
- educommon-3.13.2.dist-info/RECORD +354 -0
- educommon/utils/patches.py +0 -27
- educommon/version.conf +0 -11
- educommon-3.13.0.dist-info/RECORD +0 -357
- educommon-3.13.0.dist-info/dependency_links.txt +0 -1
- {educommon-3.13.0.dist-info → educommon-3.13.2.dist-info}/WHEEL +0 -0
- {educommon-3.13.0.dist-info → educommon-3.13.2.dist-info}/top_level.txt +0 -0
educommon/importer/__init__.py
CHANGED
@@ -1,5 +1,87 @@
|
|
1
|
-
from educommon.importer.proxy import
|
2
|
-
|
3
|
-
|
1
|
+
from educommon.importer.proxy import (
|
2
|
+
SafeDict,
|
3
|
+
ProxySaveError,
|
4
|
+
ProxyCriticalError,
|
5
|
+
ProxyWarning,
|
6
|
+
_ImportProxy,
|
7
|
+
ModelProxy,
|
8
|
+
CacheProxy,
|
9
|
+
ContextAdapterProxy,
|
10
|
+
LayoutModelProxy,
|
11
|
+
MultiProxyLoader,
|
12
|
+
LayoutProxyLoader,
|
13
|
+
fabricate_proxies,
|
4
14
|
)
|
5
|
-
from educommon.importer.
|
15
|
+
from educommon.importer.proxy_import import ProxyLoader
|
16
|
+
from educommon.importer.XLSReader import (
|
17
|
+
SUBTREE_CAN_BE_EMPTY,
|
18
|
+
START_ROW,
|
19
|
+
HEADER_PARSER,
|
20
|
+
END_ROW,
|
21
|
+
MATCH_IF_EXACT,
|
22
|
+
MATCH_IF_STARTS_WITH,
|
23
|
+
MATCH_IF_CONTAINS,
|
24
|
+
CellValueError,
|
25
|
+
EmptyObligatoryCellError,
|
26
|
+
BaseCell,
|
27
|
+
StringCell,
|
28
|
+
MaybeStringCell,
|
29
|
+
RawCell,
|
30
|
+
MaybeRawCell,
|
31
|
+
IntCell,
|
32
|
+
MaybeIntCell,
|
33
|
+
MaybeNonNegativeIntCell,
|
34
|
+
BooleanCell,
|
35
|
+
MaybeTrueCell,
|
36
|
+
MaybeFalseCell,
|
37
|
+
EnumCell,
|
38
|
+
DateCell,
|
39
|
+
MaybeDateCell,
|
40
|
+
SimpleColumnMatcher,
|
41
|
+
RegexColumnMatcher,
|
42
|
+
DynamicStartRow,
|
43
|
+
XLSLoader,
|
44
|
+
)
|
45
|
+
|
46
|
+
__all__ = [
|
47
|
+
'SafeDict',
|
48
|
+
'ProxySaveError',
|
49
|
+
'ProxyCriticalError',
|
50
|
+
'ProxyWarning',
|
51
|
+
'_ImportProxy',
|
52
|
+
'ModelProxy',
|
53
|
+
'CacheProxy',
|
54
|
+
'ContextAdapterProxy',
|
55
|
+
'LayoutModelProxy',
|
56
|
+
'MultiProxyLoader',
|
57
|
+
'LayoutProxyLoader',
|
58
|
+
'fabricate_proxies',
|
59
|
+
'ProxyLoader',
|
60
|
+
'SUBTREE_CAN_BE_EMPTY',
|
61
|
+
'START_ROW',
|
62
|
+
'HEADER_PARSER',
|
63
|
+
'END_ROW',
|
64
|
+
'MATCH_IF_EXACT',
|
65
|
+
'MATCH_IF_STARTS_WITH',
|
66
|
+
'MATCH_IF_CONTAINS',
|
67
|
+
'CellValueError',
|
68
|
+
'EmptyObligatoryCellError',
|
69
|
+
'BaseCell',
|
70
|
+
'StringCell',
|
71
|
+
'MaybeStringCell',
|
72
|
+
'RawCell',
|
73
|
+
'MaybeRawCell',
|
74
|
+
'IntCell',
|
75
|
+
'MaybeIntCell',
|
76
|
+
'MaybeNonNegativeIntCell',
|
77
|
+
'BooleanCell',
|
78
|
+
'MaybeTrueCell',
|
79
|
+
'MaybeFalseCell',
|
80
|
+
'EnumCell',
|
81
|
+
'DateCell',
|
82
|
+
'MaybeDateCell',
|
83
|
+
'SimpleColumnMatcher',
|
84
|
+
'RegexColumnMatcher',
|
85
|
+
'DynamicStartRow',
|
86
|
+
'XLSLoader',
|
87
|
+
]
|
educommon/importer/api.py
CHANGED
@@ -69,45 +69,43 @@ class BaseImportPack(BasePack):
|
|
69
69
|
"""Вызов окна подтверждения импорта при наличии ошибок."""
|
70
70
|
|
71
71
|
def __init__(self):
|
72
|
-
super(
|
72
|
+
super().__init__()
|
73
|
+
|
73
74
|
self.import_window_action = BaseImportWindowAction()
|
74
75
|
self.import_action = BaseImportAction()
|
75
76
|
self.import_with_confirm_action = ImportWithConfirmAction()
|
76
|
-
self.actions.extend(
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
77
|
+
self.actions.extend(
|
78
|
+
[
|
79
|
+
self.import_window_action,
|
80
|
+
self.import_action,
|
81
|
+
self.import_with_confirm_action,
|
82
|
+
]
|
83
|
+
)
|
81
84
|
|
82
85
|
def declare_context(self, action):
|
83
86
|
"""Объявлен параметр для пропуска записей с ошибками."""
|
84
|
-
params = super(
|
87
|
+
params = super().declare_context(action)
|
85
88
|
|
86
89
|
if action in (self.import_action, self.import_with_confirm_action):
|
87
|
-
params.update(
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
90
|
+
params.update(
|
91
|
+
{
|
92
|
+
'ignore_bad_rows': dict(type='boolean', default=False),
|
93
|
+
# ID компоненты окна импорта
|
94
|
+
'import_window_id': dict(type='str'),
|
95
|
+
}
|
96
|
+
)
|
92
97
|
|
93
98
|
return params
|
94
99
|
|
95
|
-
def _make_proxies_config(
|
96
|
-
self, memory_file, file_name, initial_context, loaders=None
|
97
|
-
):
|
100
|
+
def _make_proxies_config(self, memory_file, file_name, initial_context, loaders=None):
|
98
101
|
"""Автогенерация прокси у загрузчиков для областей ячеек"""
|
99
102
|
xls_loader = XLSLoader(memory_file)
|
100
103
|
loaders = loaders or self.get_loaders()
|
101
104
|
# только страницы, для которых определены загрузчики
|
102
105
|
loaders = dict( # имена сделаю большими и без пробелов
|
103
|
-
(str(name).strip().upper(), loader_cls)
|
104
|
-
for name, loader_cls in loaders.items()
|
105
|
-
)
|
106
|
-
sheets = (
|
107
|
-
sheet
|
108
|
-
for sheet in xls_loader._book.sheets()
|
109
|
-
if sheet.name.strip().upper() in loaders
|
106
|
+
(str(name).strip().upper(), loader_cls) for name, loader_cls in loaders.items()
|
110
107
|
)
|
108
|
+
sheets = (sheet for sheet in xls_loader._book.sheets() if sheet.name.strip().upper() in loaders)
|
111
109
|
for sheet in sheets:
|
112
110
|
loader_cls = loaders.get(sheet.name.strip().upper())
|
113
111
|
# только если загрузчик имеет прокси, определяющие некую область
|
@@ -121,43 +119,31 @@ class BaseImportPack(BasePack):
|
|
121
119
|
# Сейчас для загрузки динамически генерируется наследник загрузчика
|
122
120
|
# со своим атрибутом proxies, и в нем не должно быть
|
123
121
|
# сгенерированных классов прокси.
|
124
|
-
assert all((
|
125
|
-
not getattr(proxy[1], 'was_fabricated', False)
|
126
|
-
for proxy in loader_cls.proxies
|
127
|
-
))
|
122
|
+
assert all((not getattr(proxy[1], 'was_fabricated', False) for proxy in loader_cls.proxies))
|
128
123
|
# разбор шапок колонок, начиная со строки заголовков START_ROW
|
129
124
|
start_row = loader_cls.xlsreader_extra.get(START_ROW, 0)
|
130
125
|
head_data = [cell_val for cell_val in sheet.row_values(start_row)]
|
131
|
-
for layout_str, ancestor_cls in getattr(
|
132
|
-
loader_cls, 'layout_proxies_template', []
|
133
|
-
):
|
126
|
+
for layout_str, ancestor_cls in getattr(loader_cls, 'layout_proxies_template', []):
|
134
127
|
# сгенерированные прокси для этой области
|
135
|
-
proxies = fabricate_proxies(
|
136
|
-
ancestor_cls, layout_str, head_data
|
137
|
-
)
|
128
|
+
proxies = fabricate_proxies(ancestor_cls, layout_str, head_data)
|
138
129
|
# дополнение загрузчика сгенерированными прокси
|
139
|
-
for
|
130
|
+
for key, proxy in proxies:
|
140
131
|
if hasattr(loader_cls, 'add_proxy'):
|
141
|
-
loader_cls.add_proxy(
|
142
|
-
key, proxy, add_log, initial_context
|
143
|
-
)
|
132
|
+
loader_cls.add_proxy(key, proxy, add_log, initial_context)
|
144
133
|
# будет еще одно чтение
|
145
134
|
memory_file.seek(0)
|
146
135
|
|
147
136
|
def get_loaders(self, request=None, context=None, book=None, **kwargs):
|
148
|
-
"""
|
149
|
-
Получение постраничных загрузчиков
|
150
|
-
"""
|
137
|
+
"""Получение постраничных загрузчиков."""
|
151
138
|
assert self.loaders, 'Не определены прокси загрузки!'
|
152
139
|
loaders = self.loaders.copy()
|
140
|
+
|
153
141
|
return loaders
|
154
142
|
|
155
143
|
def set_initial_context(self, request, context):
|
156
|
-
"""
|
157
|
-
Метод позволяет изменять начальный контекст
|
158
|
-
прокси загрузчика в зависимости от контекста,
|
159
|
-
"""
|
144
|
+
"""Метод позволяет изменять начальный контекст прокси загрузчика в зависимости от контекста."""
|
160
145
|
initial_context = {}
|
146
|
+
|
161
147
|
return initial_context
|
162
148
|
|
163
149
|
def get_import_loader(self, request, context):
|
@@ -180,10 +166,12 @@ class BaseImportPack(BasePack):
|
|
180
166
|
# Создаем копии классов загрузчиков для текущего импорта.
|
181
167
|
loaders = {
|
182
168
|
name: type(
|
183
|
-
loader_cls.__name__ + 'SafeCopy',
|
184
|
-
|
185
|
-
if hasattr(loader_cls, 'proxies') else {}
|
186
|
-
)
|
169
|
+
loader_cls.__name__ + 'SafeCopy',
|
170
|
+
(loader_cls,),
|
171
|
+
{'proxies': copy(loader_cls.proxies)} if hasattr(loader_cls, 'proxies') else {},
|
172
|
+
)
|
173
|
+
if loader_cls
|
174
|
+
else loader_cls
|
187
175
|
for name, loader_cls in loaders.items()
|
188
176
|
}
|
189
177
|
|
@@ -191,12 +179,8 @@ class BaseImportPack(BasePack):
|
|
191
179
|
# которые заранее невозможно задекларировать в описании
|
192
180
|
self._make_proxies_config(_file, file_name, initial_context, loaders)
|
193
181
|
|
194
|
-
ignore_bad_rows =
|
195
|
-
|
196
|
-
result_logger_cls = (
|
197
|
-
self.separate_import_logger_cls if self.separate_logs
|
198
|
-
else self.default_import_logger_cls
|
199
|
-
)
|
182
|
+
ignore_bad_rows = context.ignore_bad_rows if self.confirm_save_on_errors else True
|
183
|
+
result_logger_cls = self.separate_import_logger_cls if self.separate_logs else self.default_import_logger_cls
|
200
184
|
# Загрузчик
|
201
185
|
loader = ProxyLoader(
|
202
186
|
loaders=loaders,
|
@@ -211,34 +195,28 @@ class BaseImportPack(BasePack):
|
|
211
195
|
return loader
|
212
196
|
|
213
197
|
def make_import(self, request, context):
|
214
|
-
"""Метод осуществляет импорт. Возвращает (лог, True/False)"""
|
198
|
+
"""Метод осуществляет импорт. Возвращает (лог, True/False)."""
|
215
199
|
loader = self.get_import_loader(request, context)
|
216
200
|
res = loader.load()
|
217
201
|
|
218
202
|
return loader.message, res
|
219
203
|
|
220
204
|
def get_import_window_params(self, params, request, context):
|
221
|
-
"""Параметры передаваемые окну
|
205
|
+
"""Параметры передаваемые окну импорта."""
|
222
206
|
params['extensions'] = self.extensions
|
207
|
+
|
223
208
|
return params
|
224
209
|
|
225
210
|
def get_import_result_window_params(self, params, request, context):
|
226
211
|
"""Параметры передаваемые окну результата импорта."""
|
227
|
-
params['title'] =
|
228
|
-
self.result_window_title or
|
229
|
-
self.title + ': проверка шаблона'
|
230
|
-
)
|
212
|
+
params['title'] = self.result_window_title or self.title + ': проверка шаблона'
|
231
213
|
|
232
214
|
return params
|
233
215
|
|
234
216
|
def extend_menu(self, menu):
|
235
|
-
"""Размещение в
|
217
|
+
"""Размещение в меню."""
|
236
218
|
return menu.SubMenu(
|
237
|
-
'Администрирование',
|
238
|
-
menu.SubMenu(
|
239
|
-
'Импорт',
|
240
|
-
menu.Item(self.title, self.import_window_action)
|
241
|
-
)
|
219
|
+
'Администрирование', menu.SubMenu('Импорт', menu.Item(self.title, self.import_window_action))
|
242
220
|
)
|
243
221
|
|
244
222
|
|
@@ -251,19 +229,17 @@ class BaseImportWindowAction(BaseWindowAction):
|
|
251
229
|
self.win = self.parent.import_window()
|
252
230
|
|
253
231
|
def set_window_params(self):
|
254
|
-
super(
|
232
|
+
super().set_window_params()
|
233
|
+
|
255
234
|
params = self.win_params.copy()
|
256
235
|
params['title'] = self.parent.title
|
257
236
|
|
258
237
|
if not self.parent.confirm_save_on_errors:
|
259
238
|
params['form_url'] = self.parent.import_action.get_absolute_url()
|
260
239
|
else:
|
261
|
-
params['form_url'] = (
|
262
|
-
self.parent.import_with_confirm_action.get_absolute_url())
|
240
|
+
params['form_url'] = self.parent.import_with_confirm_action.get_absolute_url()
|
263
241
|
|
264
|
-
self.win_params = self.parent.get_import_window_params(
|
265
|
-
params, self.request, self.context
|
266
|
-
)
|
242
|
+
self.win_params = self.parent.get_import_window_params(params, self.request, self.context)
|
267
243
|
|
268
244
|
def configure_window(self):
|
269
245
|
pass
|
@@ -284,8 +260,7 @@ class BaseImportAction(BaseAction):
|
|
284
260
|
'"Microsoft Excel 97/2003 (.xls)"'
|
285
261
|
)
|
286
262
|
|
287
|
-
return multiline_text_window_result(
|
288
|
-
success=success, data=log_msg, title=self.parent.title)
|
263
|
+
return multiline_text_window_result(success=success, data=log_msg, title=self.parent.title)
|
289
264
|
|
290
265
|
|
291
266
|
class ImportWithConfirmAction(BaseAction):
|
@@ -301,21 +276,17 @@ class ImportWithConfirmAction(BaseAction):
|
|
301
276
|
def create_window(self, request, context, **params):
|
302
277
|
"""Создание окна результата логгера."""
|
303
278
|
win = self.result_window()
|
304
|
-
win.set_params(self.parent.get_import_result_window_params(
|
305
|
-
params, request, context))
|
279
|
+
win.set_params(self.parent.get_import_result_window_params(params, request, context))
|
306
280
|
|
307
281
|
return win
|
308
282
|
|
309
|
-
def get_window_params_by_import_result(
|
310
|
-
self, import_was_success, import_logger, request, context):
|
283
|
+
def get_window_params_by_import_result(self, import_was_success, import_logger, request, context):
|
311
284
|
"""Формирует параметры окна результата из данных логгера."""
|
312
285
|
return dict(
|
313
286
|
result_text=import_logger.get_pretty_log(),
|
314
287
|
import_window_id=context.import_window_id,
|
315
288
|
hide_confirm_button=(
|
316
|
-
context.ignore_bad_rows or
|
317
|
-
import_was_success or
|
318
|
-
import_logger.have_errors_in_all_rows()
|
289
|
+
context.ignore_bad_rows or import_was_success or import_logger.have_errors_in_all_rows()
|
319
290
|
),
|
320
291
|
ignore_bad_rows=context.ignore_bad_rows,
|
321
292
|
exit_from_import_on_close=import_was_success,
|
@@ -334,9 +305,7 @@ class ImportWithConfirmAction(BaseAction):
|
|
334
305
|
'"Microsoft Excel 97/2003 (.xls)"'
|
335
306
|
)
|
336
307
|
import_was_success = not loader.result_logger.has_error()
|
337
|
-
params = self.get_window_params_by_import_result(
|
338
|
-
import_was_success, loader.result_logger, request, context)
|
308
|
+
params = self.get_window_params_by_import_result(import_was_success, loader.result_logger, request, context)
|
339
309
|
win = self.create_window(request, context, **params)
|
340
310
|
|
341
|
-
return OperationResult(
|
342
|
-
success=import_was_success, code=win.get_script())
|
311
|
+
return OperationResult(success=import_was_success, code=win.get_script())
|
educommon/importer/constants.py
CHANGED
@@ -1,17 +1,7 @@
|
|
1
|
-
IMPORT_SUCCESS_MSG =
|
2
|
-
'Проверка шаблона прошла успешно. '
|
3
|
-
'Файл успешно загружен!'
|
4
|
-
)
|
1
|
+
IMPORT_SUCCESS_MSG = 'Проверка шаблона прошла успешно. Файл успешно загружен!'
|
5
2
|
IMPORT_SUCCESS_WITH_ERRORS_MSG = (
|
6
|
-
'Данные из шаблона импорта, по которым не '
|
7
|
-
'выявлено ошибок, успешно загружены в систему!'
|
8
|
-
)
|
9
|
-
ALL_ROWS_HAVE_ERRORS_MSG = (
|
10
|
-
'Все строки файла содержат ошибки, '
|
11
|
-
'скорректируйте файл и повторите импорт.'
|
3
|
+
'Данные из шаблона импорта, по которым не выявлено ошибок, успешно загружены в систему!'
|
12
4
|
)
|
5
|
+
ALL_ROWS_HAVE_ERRORS_MSG = 'Все строки файла содержат ошибки, скорректируйте файл и повторите импорт.'
|
13
6
|
|
14
|
-
IMPORT_FAIL_WITH_CRITICAL_ERROR =
|
15
|
-
'При загрузке возникла критическая ошибка, '
|
16
|
-
'скорректируйте файл и повторите импорт.'
|
17
|
-
)
|
7
|
+
IMPORT_FAIL_WITH_CRITICAL_ERROR = 'При загрузке возникла критическая ошибка, скорректируйте файл и повторите импорт.'
|
educommon/importer/loggers.py
CHANGED
@@ -20,28 +20,28 @@ class BaseImportLogger:
|
|
20
20
|
"""
|
21
21
|
|
22
22
|
def on_sheet_errors(self, sheet, errors, *args, **kwargs):
|
23
|
-
raise
|
23
|
+
raise NotImplementedError
|
24
24
|
|
25
25
|
def on_header_errors(self, header_info, errors, *args, **kwargs):
|
26
|
-
raise
|
26
|
+
raise NotImplementedError
|
27
27
|
|
28
28
|
def on_row_processed(self, row_info, *args, **kwargs):
|
29
|
-
raise
|
29
|
+
raise NotImplementedError
|
30
30
|
|
31
31
|
def on_row_errors(self, row_info, errors, warnings=None, *args, **kwargs):
|
32
|
-
raise
|
32
|
+
raise NotImplementedError
|
33
33
|
|
34
34
|
def on_critical_error(self, row_info, errors, *args, **kwargs):
|
35
|
-
raise
|
35
|
+
raise NotImplementedError
|
36
36
|
|
37
37
|
def on_row_save(self, row_info, *args, **kwargs):
|
38
|
-
raise
|
38
|
+
raise NotImplementedError
|
39
39
|
|
40
40
|
def on_row_save_rollback(self, row_info, *args, **kwargs):
|
41
|
-
raise
|
41
|
+
raise NotImplementedError
|
42
42
|
|
43
43
|
def on_save_rollback(self, *args, **kwargs):
|
44
|
-
raise
|
44
|
+
raise NotImplementedError
|
45
45
|
|
46
46
|
|
47
47
|
class ImportLogger(BaseImportLogger):
|
@@ -94,10 +94,7 @@ class ImportLogger(BaseImportLogger):
|
|
94
94
|
self.rows_warnings.setdefault(row_info, []).extend(warnings)
|
95
95
|
|
96
96
|
def on_critical_error(self, row_info, error, *args, **kwargs):
|
97
|
-
self.critical_error_msg = '{0}\n {1}'.format(
|
98
|
-
self._get_row_label(row_info),
|
99
|
-
error
|
100
|
-
)
|
97
|
+
self.critical_error_msg = '{0}\n {1}'.format(self._get_row_label(row_info), error)
|
101
98
|
|
102
99
|
def on_row_save(self, row_info, *args, **kwargs):
|
103
100
|
if row_info not in self.saved_rows:
|
@@ -139,7 +136,9 @@ class ImportLogger(BaseImportLogger):
|
|
139
136
|
@staticmethod
|
140
137
|
def _get_row_label(row_info):
|
141
138
|
"""Возвращает информацию о строке в читаемом виде."""
|
142
|
-
|
139
|
+
sheet_name, sheet_num, row_num = row_info
|
140
|
+
|
141
|
+
return f'Лист "{sheet_name}" ({sheet_num}), строка {row_num}:'
|
143
142
|
|
144
143
|
@staticmethod
|
145
144
|
def _sort_rows_info(rows_info, key=lambda x: x[2]):
|
@@ -178,10 +177,7 @@ class ImportLogger(BaseImportLogger):
|
|
178
177
|
rows_numbers = sorted([x[2] for x in self.saved_rows])
|
179
178
|
series = find_series(iter(rows_numbers))
|
180
179
|
|
181
|
-
result = ', '.join(
|
182
|
-
'{}-{}'.format(x, y) if x != y else str(x)
|
183
|
-
for x, y in series
|
184
|
-
)
|
180
|
+
result = ', '.join('{}-{}'.format(x, y) if x != y else str(x) for x, y in series)
|
185
181
|
return 'Загружены строки : {0}.'.format(result)
|
186
182
|
|
187
183
|
if self.critical_error_msg is not None:
|
@@ -212,9 +208,7 @@ class ImportLogger(BaseImportLogger):
|
|
212
208
|
if self.load_errors:
|
213
209
|
add_lines(self.load_errors, 0, 1)
|
214
210
|
# Список строк с любыми ошибками
|
215
|
-
rows_with_errors = list(
|
216
|
-
set(chain(self.rows_errors, self.rows_warnings))
|
217
|
-
)
|
211
|
+
rows_with_errors = list(set(chain(self.rows_errors, self.rows_warnings)))
|
218
212
|
|
219
213
|
for row in self._sort_rows_info(rows_with_errors):
|
220
214
|
row_errors = self.rows_errors.get(row, [])
|
@@ -239,12 +233,8 @@ class SeparateImportLogger(ImportLogger):
|
|
239
233
|
|
240
234
|
def get_pretty_log(self):
|
241
235
|
"""При наличии ошибок разделяет их на разные блоки."""
|
242
|
-
if
|
243
|
-
|
244
|
-
and not self.rows_errors
|
245
|
-
or self.ignore_bad_rows
|
246
|
-
):
|
247
|
-
return super(SeparateImportLogger, self).get_pretty_log()
|
236
|
+
if self.critical_error_msg is not None and not self.rows_errors or self.ignore_bad_rows:
|
237
|
+
return super().get_pretty_log()
|
248
238
|
|
249
239
|
result_lines = []
|
250
240
|
add_lines = partial(self._add_text_lines, result_lines)
|