elody 0.0.167__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.167 → elody-0.0.168}/PKG-INFO +1 -1
- {elody-0.0.167 → elody-0.0.168}/pyproject.toml +1 -1
- {elody-0.0.167 → elody-0.0.168}/src/elody/csv.py +41 -3
- {elody-0.0.167 → elody-0.0.168}/src/elody/error_codes.py +4 -4
- {elody-0.0.167 → elody-0.0.168}/src/elody.egg-info/PKG-INFO +1 -1
- {elody-0.0.167 → elody-0.0.168}/LICENSE +0 -0
- {elody-0.0.167 → elody-0.0.168}/README.md +0 -0
- {elody-0.0.167 → elody-0.0.168}/setup.cfg +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/__init__.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/__init__.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/client.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/exceptions.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/job.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/loader.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/migration/__init__.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/migration/base_object_migrator.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/object_configurations/__init__.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/object_configurations/base_object_configuration.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/object_configurations/elody_configuration.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/object_configurations/job_configuration.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/__init__.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authentication/__init__.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authentication/base_user_tenant_validation_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authentication/multi_tenant_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/__init__.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/filter_generic_objects_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/filter_generic_objects_policy_v2.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_detail_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_mediafiles_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_metadata_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_relations_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_request_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_request_policy_v2.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/mediafile_derivatives_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/mediafile_download_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/multi_tenant_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/tenant_request_policy.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/helpers.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/permission_handler.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/policies/tenant_id_resolver.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/schemas.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/util.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody/validator.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody.egg-info/SOURCES.txt +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody.egg-info/dependency_links.txt +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody.egg-info/requires.txt +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/elody.egg-info/top_level.txt +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/tests/__init_.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/tests/data.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/tests/unit/__init__.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/tests/unit/test_csv.py +0 -0
- {elody-0.0.167 → elody-0.0.168}/src/tests/unit/test_utils.py +0 -0
|
@@ -152,6 +152,7 @@ class CSVMultiObject(CSVParser):
|
|
|
152
152
|
self.external_file_sources = (
|
|
153
153
|
external_file_sources if external_file_sources else []
|
|
154
154
|
)
|
|
155
|
+
self.line_numbers = []
|
|
155
156
|
self.__fill_objects_from_csv()
|
|
156
157
|
self.__rename_top_level_fields()
|
|
157
158
|
|
|
@@ -161,6 +162,24 @@ class CSVMultiObject(CSVParser):
|
|
|
161
162
|
def get_errors(self):
|
|
162
163
|
return self.errors
|
|
163
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
|
+
|
|
164
183
|
def set_error(self, type, errors):
|
|
165
184
|
self.errors[type] = errors
|
|
166
185
|
|
|
@@ -191,7 +210,27 @@ class CSVMultiObject(CSVParser):
|
|
|
191
210
|
def __fill_objects_from_csv(self):
|
|
192
211
|
indexed_dict = dict()
|
|
193
212
|
external_mediafiles_ids = []
|
|
194
|
-
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
|
+
)
|
|
195
234
|
mandatory_columns = [
|
|
196
235
|
v for k, v in self.index_mapping.items() if not k.startswith("?")
|
|
197
236
|
]
|
|
@@ -254,7 +293,6 @@ class CSVMultiObject(CSVParser):
|
|
|
254
293
|
key not in self.index_mapping.values()
|
|
255
294
|
or self.include_indexed_field
|
|
256
295
|
) and self.__field_allowed(type, key, value):
|
|
257
|
-
# Map the metadata field to a unified key if applicable
|
|
258
296
|
metadata_info = self.metadata_field_mapping.get(key, {})
|
|
259
297
|
if metadata_info.get("target") == type or not metadata_info:
|
|
260
298
|
case_insensitive = metadata_info.get(
|
|
@@ -268,7 +306,7 @@ class CSVMultiObject(CSVParser):
|
|
|
268
306
|
if options and value not in options:
|
|
269
307
|
if "invalid_value" not in self.get_errors():
|
|
270
308
|
self.set_error("invalid_value", list())
|
|
271
|
-
message = f'{get_error_code(ErrorCode.INVALID_VALUE, get_write())} | value:{value} | options:{options} - The value "{value}" is invalid, these are the valid values: {options}'
|
|
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}'
|
|
272
310
|
self.get_errors()["invalid_value"].append(message)
|
|
273
311
|
|
|
274
312
|
indexed_dict[type][id]["metadata"].append(
|
|
@@ -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,8 +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"])
|
|
75
|
-
ITEM_WITH_VALUE_FOR_KEY_NOT_FOUND = ("5017", ["key", "value"])
|
|
74
|
+
INVALID_VALUE = ("5016", ["value", "options", "line_number"])
|
|
75
|
+
ITEM_WITH_VALUE_FOR_KEY_NOT_FOUND = ("5017", ["key", "value", "line_number"])
|
|
76
76
|
|
|
77
77
|
# Filter error codes
|
|
78
78
|
NO_MATCHER_FOR_FILTER_REQUEST = ("6001", [])
|
|
@@ -95,7 +95,7 @@ class ErrorCode(Enum):
|
|
|
95
95
|
ARCHES_UNABLE_TO_CREATE_RELATION = ("11005", ["type", "value"])
|
|
96
96
|
|
|
97
97
|
# Digipolis error codes
|
|
98
|
-
NO_PERMISSION_TO_CREATE_INSTIUTION = ("12000", ["institution"])
|
|
98
|
+
NO_PERMISSION_TO_CREATE_INSTIUTION = ("12000", ["institution", "line_number"])
|
|
99
99
|
INSTITUTION_HAS_MISSING_DATA = ("12001", ["institution"])
|
|
100
100
|
INSTITUTION_NOT_FOUND = ("12002", [])
|
|
101
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.167 → 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.167 → elody-0.0.168}/src/elody/policies/authorization/filter_generic_objects_policy.py
RENAMED
|
File without changes
|
{elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/filter_generic_objects_policy_v2.py
RENAMED
|
File without changes
|
{elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_detail_policy.py
RENAMED
|
File without changes
|
{elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_mediafiles_policy.py
RENAMED
|
File without changes
|
{elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_metadata_policy.py
RENAMED
|
File without changes
|
{elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_relations_policy.py
RENAMED
|
File without changes
|
{elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_request_policy.py
RENAMED
|
File without changes
|
{elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/generic_object_request_policy_v2.py
RENAMED
|
File without changes
|
{elody-0.0.167 → elody-0.0.168}/src/elody/policies/authorization/mediafile_derivatives_policy.py
RENAMED
|
File without changes
|
{elody-0.0.167 → 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
|