elody 0.0.166__tar.gz → 0.0.168__tar.gz
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.
- {elody-0.0.166 → elody-0.0.168}/PKG-INFO +1 -1
- {elody-0.0.166 → elody-0.0.168}/pyproject.toml +1 -1
- {elody-0.0.166 → elody-0.0.168}/src/elody/csv.py +49 -5
- {elody-0.0.166 → elody-0.0.168}/src/elody/error_codes.py +4 -2
- {elody-0.0.166 → elody-0.0.168}/src/elody.egg-info/PKG-INFO +1 -1
- {elody-0.0.166 → elody-0.0.168}/LICENSE +0 -0
- {elody-0.0.166 → elody-0.0.168}/README.md +0 -0
- {elody-0.0.166 → elody-0.0.168}/setup.cfg +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/__init__.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/__init__.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/client.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/exceptions.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/job.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/loader.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/migration/__init__.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/migration/base_object_migrator.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/object_configurations/__init__.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/object_configurations/base_object_configuration.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/object_configurations/elody_configuration.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/object_configurations/job_configuration.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/__init__.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authentication/__init__.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authentication/base_user_tenant_validation_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authentication/multi_tenant_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/__init__.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/filter_generic_objects_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/filter_generic_objects_policy_v2.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_detail_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_mediafiles_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_metadata_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_relations_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_request_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_request_policy_v2.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/mediafile_derivatives_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/mediafile_download_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/multi_tenant_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/tenant_request_policy.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/helpers.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/permission_handler.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/policies/tenant_id_resolver.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/schemas.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/util.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody/validator.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody.egg-info/SOURCES.txt +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody.egg-info/dependency_links.txt +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody.egg-info/requires.txt +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/elody.egg-info/top_level.txt +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/tests/__init_.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/tests/data.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/tests/unit/__init__.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/tests/unit/test_csv.py +0 -0
- {elody-0.0.166 → elody-0.0.168}/src/tests/unit/test_utils.py +0 -0
|
@@ -2,6 +2,7 @@ import csv
|
|
|
2
2
|
import re
|
|
3
3
|
|
|
4
4
|
from io import StringIO
|
|
5
|
+
from elody.error_codes import ErrorCode, get_error_code, get_write
|
|
5
6
|
from elody.exceptions import (
|
|
6
7
|
ColumnNotFoundException,
|
|
7
8
|
IncorrectTypeException,
|
|
@@ -151,6 +152,7 @@ class CSVMultiObject(CSVParser):
|
|
|
151
152
|
self.external_file_sources = (
|
|
152
153
|
external_file_sources if external_file_sources else []
|
|
153
154
|
)
|
|
155
|
+
self.line_numbers = []
|
|
154
156
|
self.__fill_objects_from_csv()
|
|
155
157
|
self.__rename_top_level_fields()
|
|
156
158
|
|
|
@@ -160,6 +162,27 @@ class CSVMultiObject(CSVParser):
|
|
|
160
162
|
def get_errors(self):
|
|
161
163
|
return self.errors
|
|
162
164
|
|
|
165
|
+
def get_line_numbers(self):
|
|
166
|
+
return self.line_numbers
|
|
167
|
+
|
|
168
|
+
def get_line_number(self, entity_identifier=None, mediafile_identifier=None):
|
|
169
|
+
for line_number, line_info in enumerate(self.line_numbers, start=1):
|
|
170
|
+
if (
|
|
171
|
+
entity_identifier
|
|
172
|
+
and line_info.get("entity_identifier") != entity_identifier
|
|
173
|
+
):
|
|
174
|
+
continue
|
|
175
|
+
if (
|
|
176
|
+
mediafile_identifier
|
|
177
|
+
and line_info.get("mediafile_identifier") != mediafile_identifier
|
|
178
|
+
):
|
|
179
|
+
continue
|
|
180
|
+
return line_number
|
|
181
|
+
return None
|
|
182
|
+
|
|
183
|
+
def set_error(self, type, errors):
|
|
184
|
+
self.errors[type] = errors
|
|
185
|
+
|
|
163
186
|
def get_top_level_fields_mapping(self, type):
|
|
164
187
|
return self.top_level_fields_mapping.get(type, {})
|
|
165
188
|
|
|
@@ -187,7 +210,27 @@ class CSVMultiObject(CSVParser):
|
|
|
187
210
|
def __fill_objects_from_csv(self):
|
|
188
211
|
indexed_dict = dict()
|
|
189
212
|
external_mediafiles_ids = []
|
|
190
|
-
for row in self.reader:
|
|
213
|
+
for row_number, row in enumerate(self.reader, start=1):
|
|
214
|
+
normalized_mapping = {
|
|
215
|
+
key.lstrip("?"): value for key, value in self.index_mapping.items()
|
|
216
|
+
}
|
|
217
|
+
entity_identifier_column = normalized_mapping.get("entities")
|
|
218
|
+
mediafile_identifier_column = normalized_mapping.get("mediafiles")
|
|
219
|
+
entity_identifier = (
|
|
220
|
+
row.get(entity_identifier_column) if entity_identifier_column else None
|
|
221
|
+
)
|
|
222
|
+
mediafile_identifier = (
|
|
223
|
+
row.get(mediafile_identifier_column)
|
|
224
|
+
if mediafile_identifier_column
|
|
225
|
+
else None
|
|
226
|
+
)
|
|
227
|
+
self.line_numbers.append(
|
|
228
|
+
{
|
|
229
|
+
"line": row_number,
|
|
230
|
+
"entity_identifier": entity_identifier,
|
|
231
|
+
"mediafile_identifier": mediafile_identifier,
|
|
232
|
+
}
|
|
233
|
+
)
|
|
191
234
|
mandatory_columns = [
|
|
192
235
|
v for k, v in self.index_mapping.items() if not k.startswith("?")
|
|
193
236
|
]
|
|
@@ -250,7 +293,6 @@ class CSVMultiObject(CSVParser):
|
|
|
250
293
|
key not in self.index_mapping.values()
|
|
251
294
|
or self.include_indexed_field
|
|
252
295
|
) and self.__field_allowed(type, key, value):
|
|
253
|
-
# Map the metadata field to a unified key if applicable
|
|
254
296
|
metadata_info = self.metadata_field_mapping.get(key, {})
|
|
255
297
|
if metadata_info.get("target") == type or not metadata_info:
|
|
256
298
|
case_insensitive = metadata_info.get(
|
|
@@ -262,9 +304,11 @@ class CSVMultiObject(CSVParser):
|
|
|
262
304
|
if case_insensitive:
|
|
263
305
|
value = value.lower()
|
|
264
306
|
if options and value not in options:
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
)
|
|
307
|
+
if "invalid_value" not in self.get_errors():
|
|
308
|
+
self.set_error("invalid_value", list())
|
|
309
|
+
message = f'{get_error_code(ErrorCode.INVALID_VALUE, get_write())} | value:{value} | options:{options}| line_number:{row_number} - The value "{value}" is invalid, these are the valid values: {options}'
|
|
310
|
+
self.get_errors()["invalid_value"].append(message)
|
|
311
|
+
|
|
268
312
|
indexed_dict[type][id]["metadata"].append(
|
|
269
313
|
self._get_metadata_object(metadata_key, value, lang)
|
|
270
314
|
)
|
|
@@ -27,7 +27,7 @@ class ErrorCode(Enum):
|
|
|
27
27
|
XTENANT_HAS_NO_TENANT_DEFENING_ENTITY = ("1007", ["x_tenant_id"])
|
|
28
28
|
INSUFFICIENT_PERMISSIONS_WITHOUT_VARS = ("1008", [])
|
|
29
29
|
NO_GLOBAL_ROLES = ("1009", [])
|
|
30
|
-
NO_PERMISSION_TO_TENANT = ("1010", ["tenant_id"])
|
|
30
|
+
NO_PERMISSION_TO_TENANT = ("1010", ["tenant_id", "line_number"])
|
|
31
31
|
XTENANT_NOT_FOUND = ("1011", ["x_tenant_id"])
|
|
32
32
|
NO_DOWNLOAD_PERMISSION = ("1012", [])
|
|
33
33
|
|
|
@@ -71,6 +71,8 @@ class ErrorCode(Enum):
|
|
|
71
71
|
INVALID_FORMAT_FOR_TYPE = ("5013", ["type"])
|
|
72
72
|
NO_METADATA_AVAILABLE_FOR_ITEM = ("5014", ["id"])
|
|
73
73
|
INVALID_ACCEPT_HEADER = ("5015", [])
|
|
74
|
+
INVALID_VALUE = ("5016", ["value", "options", "line_number"])
|
|
75
|
+
ITEM_WITH_VALUE_FOR_KEY_NOT_FOUND = ("5017", ["key", "value", "line_number"])
|
|
74
76
|
|
|
75
77
|
# Filter error codes
|
|
76
78
|
NO_MATCHER_FOR_FILTER_REQUEST = ("6001", [])
|
|
@@ -93,7 +95,7 @@ class ErrorCode(Enum):
|
|
|
93
95
|
ARCHES_UNABLE_TO_CREATE_RELATION = ("11005", ["type", "value"])
|
|
94
96
|
|
|
95
97
|
# Digipolis error codes
|
|
96
|
-
NO_PERMISSION_TO_CREATE_INSTIUTION = ("12000", ["institution"])
|
|
98
|
+
NO_PERMISSION_TO_CREATE_INSTIUTION = ("12000", ["institution", "line_number"])
|
|
97
99
|
INSTITUTION_HAS_MISSING_DATA = ("12001", ["institution"])
|
|
98
100
|
INSTITUTION_NOT_FOUND = ("12002", [])
|
|
99
101
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/object_configurations/base_object_configuration.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/filter_generic_objects_policy.py
RENAMED
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/filter_generic_objects_policy_v2.py
RENAMED
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_detail_policy.py
RENAMED
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_mediafiles_policy.py
RENAMED
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_metadata_policy.py
RENAMED
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_relations_policy.py
RENAMED
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_request_policy.py
RENAMED
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/generic_object_request_policy_v2.py
RENAMED
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/mediafile_derivatives_policy.py
RENAMED
|
File without changes
|
{elody-0.0.166 → elody-0.0.168}/src/elody/policies/authorization/mediafile_download_policy.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|