dsp-tools 9.1.0.post11__py3-none-any.whl → 18.3.0.post13__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.
- dsp_tools/__init__.py +4 -0
- dsp_tools/cli/args.py +36 -0
- dsp_tools/cli/call_action.py +51 -231
- dsp_tools/cli/call_action_files_only.py +101 -0
- dsp_tools/cli/call_action_with_network.py +207 -0
- dsp_tools/cli/create_parsers.py +156 -58
- dsp_tools/cli/entry_point.py +56 -26
- dsp_tools/cli/utils.py +87 -0
- dsp_tools/clients/CLAUDE.md +420 -0
- dsp_tools/clients/authentication_client.py +14 -0
- dsp_tools/clients/authentication_client_live.py +66 -0
- dsp_tools/{utils → clients}/connection.py +2 -18
- dsp_tools/clients/connection_live.py +233 -0
- dsp_tools/clients/fuseki_metrics.py +60 -0
- dsp_tools/clients/group_user_clients.py +35 -0
- dsp_tools/clients/group_user_clients_live.py +181 -0
- dsp_tools/clients/legal_info_client.py +23 -0
- dsp_tools/clients/legal_info_client_live.py +132 -0
- dsp_tools/clients/list_client.py +49 -0
- dsp_tools/clients/list_client_live.py +166 -0
- dsp_tools/clients/metadata_client.py +24 -0
- dsp_tools/clients/metadata_client_live.py +47 -0
- dsp_tools/clients/ontology_clients.py +49 -0
- dsp_tools/clients/ontology_create_client_live.py +166 -0
- dsp_tools/clients/ontology_get_client_live.py +80 -0
- dsp_tools/clients/permissions_client.py +68 -0
- dsp_tools/clients/project_client.py +16 -0
- dsp_tools/clients/project_client_live.py +66 -0
- dsp_tools/commands/create/communicate_problems.py +24 -0
- dsp_tools/commands/create/create.py +134 -0
- dsp_tools/commands/create/create_on_server/cardinalities.py +111 -0
- dsp_tools/commands/create/create_on_server/classes.py +99 -0
- dsp_tools/commands/create/create_on_server/complete_ontologies.py +116 -0
- dsp_tools/commands/create/create_on_server/default_permissions.py +134 -0
- dsp_tools/commands/create/create_on_server/group_users.py +165 -0
- dsp_tools/commands/create/create_on_server/lists.py +163 -0
- dsp_tools/commands/create/create_on_server/mappers.py +12 -0
- dsp_tools/commands/create/create_on_server/onto_utils.py +74 -0
- dsp_tools/commands/create/create_on_server/ontology.py +52 -0
- dsp_tools/commands/create/create_on_server/project.py +68 -0
- dsp_tools/commands/create/create_on_server/properties.py +119 -0
- dsp_tools/commands/create/exceptions.py +29 -0
- dsp_tools/commands/create/lists_only.py +66 -0
- dsp_tools/commands/create/models/create_problems.py +87 -0
- dsp_tools/commands/create/models/parsed_ontology.py +88 -0
- dsp_tools/commands/create/models/parsed_project.py +81 -0
- dsp_tools/commands/create/models/rdf_ontology.py +12 -0
- dsp_tools/commands/create/models/server_project_info.py +100 -0
- dsp_tools/commands/create/parsing/parse_lists.py +45 -0
- dsp_tools/commands/create/parsing/parse_ontology.py +243 -0
- dsp_tools/commands/create/parsing/parse_project.py +149 -0
- dsp_tools/commands/create/parsing/parsing_utils.py +40 -0
- dsp_tools/commands/create/project_validate.py +595 -0
- dsp_tools/commands/create/serialisation/ontology.py +119 -0
- dsp_tools/commands/create/serialisation/project.py +44 -0
- dsp_tools/commands/excel2json/CLAUDE.md +101 -0
- dsp_tools/commands/excel2json/json_header.py +57 -23
- dsp_tools/commands/excel2json/{new_lists → lists}/compliance_checks.py +26 -26
- dsp_tools/commands/excel2json/{new_lists/make_new_lists.py → lists/make_lists.py} +19 -18
- dsp_tools/commands/excel2json/{new_lists → lists}/models/input_error.py +1 -12
- dsp_tools/commands/excel2json/{new_lists → lists}/models/serialise.py +9 -5
- dsp_tools/commands/excel2json/{new_lists → lists}/utils.py +4 -4
- dsp_tools/commands/excel2json/models/input_error.py +31 -11
- dsp_tools/commands/excel2json/models/json_header.py +53 -15
- dsp_tools/commands/excel2json/models/ontology.py +4 -3
- dsp_tools/commands/excel2json/{lists.py → old_lists.py} +26 -112
- dsp_tools/commands/excel2json/project.py +78 -34
- dsp_tools/commands/excel2json/properties.py +57 -36
- dsp_tools/commands/excel2json/resources.py +32 -12
- dsp_tools/commands/excel2json/utils.py +20 -1
- dsp_tools/commands/excel2xml/__init__.py +2 -2
- dsp_tools/commands/excel2xml/excel2xml_cli.py +7 -15
- dsp_tools/commands/excel2xml/excel2xml_lib.py +138 -493
- dsp_tools/commands/excel2xml/propertyelement.py +5 -5
- dsp_tools/commands/{project → get}/get.py +29 -13
- dsp_tools/commands/get/get_permissions.py +257 -0
- dsp_tools/commands/get/get_permissions_legacy.py +89 -0
- dsp_tools/commands/{project/models → get/legacy_models}/context.py +6 -6
- dsp_tools/commands/{project/models → get/legacy_models}/group.py +5 -10
- dsp_tools/commands/{project/models → get/legacy_models}/listnode.py +5 -35
- dsp_tools/commands/{project/models → get/legacy_models}/model.py +1 -1
- dsp_tools/commands/{project/models → get/legacy_models}/ontology.py +9 -14
- dsp_tools/commands/{project/models → get/legacy_models}/project.py +13 -6
- dsp_tools/commands/{project/models → get/legacy_models}/propertyclass.py +9 -16
- dsp_tools/commands/{project/models → get/legacy_models}/resourceclass.py +8 -46
- dsp_tools/commands/{project/models → get/legacy_models}/user.py +19 -60
- dsp_tools/commands/get/models/permissions_models.py +10 -0
- dsp_tools/commands/id2iri.py +20 -10
- dsp_tools/commands/ingest_xmlupload/bulk_ingest_client.py +81 -56
- dsp_tools/commands/ingest_xmlupload/create_resources/apply_ingest_id.py +4 -10
- dsp_tools/commands/ingest_xmlupload/create_resources/upload_xml.py +97 -37
- dsp_tools/commands/ingest_xmlupload/create_resources/user_information.py +2 -2
- dsp_tools/commands/ingest_xmlupload/ingest_files/ingest_files.py +9 -10
- dsp_tools/commands/ingest_xmlupload/upload_files/filechecker.py +3 -3
- dsp_tools/commands/ingest_xmlupload/upload_files/input_error.py +2 -10
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_failures.py +12 -2
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_files.py +8 -9
- dsp_tools/commands/resume_xmlupload/resume_xmlupload.py +18 -18
- dsp_tools/commands/start_stack.py +126 -77
- dsp_tools/commands/update_legal/CLAUDE.md +344 -0
- dsp_tools/commands/update_legal/__init__.py +0 -0
- dsp_tools/commands/update_legal/core.py +182 -0
- dsp_tools/commands/update_legal/csv_operations.py +135 -0
- dsp_tools/commands/update_legal/models.py +87 -0
- dsp_tools/commands/update_legal/xml_operations.py +247 -0
- dsp_tools/commands/validate_data/CLAUDE.md +159 -0
- dsp_tools/commands/validate_data/__init__.py +0 -0
- dsp_tools/commands/validate_data/constants.py +59 -0
- dsp_tools/commands/validate_data/mappers.py +143 -0
- dsp_tools/commands/validate_data/models/__init__.py +0 -0
- dsp_tools/commands/validate_data/models/api_responses.py +45 -0
- dsp_tools/commands/validate_data/models/input_problems.py +119 -0
- dsp_tools/commands/validate_data/models/rdf_like_data.py +117 -0
- dsp_tools/commands/validate_data/models/validation.py +106 -0
- dsp_tools/commands/validate_data/prepare_data/__init__.py +0 -0
- dsp_tools/commands/validate_data/prepare_data/get_rdf_like_data.py +296 -0
- dsp_tools/commands/validate_data/prepare_data/make_data_graph.py +91 -0
- dsp_tools/commands/validate_data/prepare_data/prepare_data.py +184 -0
- dsp_tools/commands/validate_data/process_validation_report/__init__.py +0 -0
- dsp_tools/commands/validate_data/process_validation_report/get_user_validation_message.py +358 -0
- dsp_tools/commands/validate_data/process_validation_report/query_validation_result.py +507 -0
- dsp_tools/commands/validate_data/process_validation_report/reformat_validation_results.py +150 -0
- dsp_tools/commands/validate_data/shacl_cli_validator.py +70 -0
- dsp_tools/commands/validate_data/sparql/__init__.py +0 -0
- dsp_tools/commands/{xml_validate/sparql/resource_shacl.py → validate_data/sparql/cardinality_shacl.py} +45 -47
- dsp_tools/commands/validate_data/sparql/construct_shacl.py +92 -0
- dsp_tools/commands/validate_data/sparql/legal_info_shacl.py +36 -0
- dsp_tools/commands/validate_data/sparql/value_shacl.py +357 -0
- dsp_tools/commands/validate_data/utils.py +59 -0
- dsp_tools/commands/validate_data/validate_data.py +283 -0
- dsp_tools/commands/validate_data/validation/__init__.py +0 -0
- dsp_tools/commands/validate_data/validation/check_duplicate_files.py +55 -0
- dsp_tools/commands/validate_data/validation/check_for_unknown_classes.py +67 -0
- dsp_tools/commands/validate_data/validation/get_validation_report.py +94 -0
- dsp_tools/commands/validate_data/validation/validate_ontology.py +107 -0
- dsp_tools/commands/xmlupload/CLAUDE.md +292 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/__init__.py +0 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/constants.py +63 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/jsonld_utils.py +44 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_file_value.py +77 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_resource_and_values.py +114 -0
- dsp_tools/commands/xmlupload/make_rdf_graph/make_values.py +262 -0
- dsp_tools/commands/xmlupload/models/bitstream_info.py +18 -0
- dsp_tools/commands/xmlupload/models/formatted_text_value.py +0 -25
- dsp_tools/commands/xmlupload/models/ingest.py +56 -70
- dsp_tools/commands/xmlupload/models/input_problems.py +6 -14
- dsp_tools/commands/xmlupload/models/lookup_models.py +21 -0
- dsp_tools/commands/xmlupload/models/permission.py +0 -39
- dsp_tools/commands/xmlupload/models/{deserialise/xmlpermission.py → permissions_parsed.py} +2 -2
- dsp_tools/commands/xmlupload/models/processed/__init__.py +0 -0
- dsp_tools/commands/xmlupload/models/processed/file_values.py +29 -0
- dsp_tools/commands/xmlupload/models/processed/res.py +27 -0
- dsp_tools/commands/xmlupload/models/processed/values.py +101 -0
- dsp_tools/commands/xmlupload/models/rdf_models.py +26 -0
- dsp_tools/commands/xmlupload/models/upload_clients.py +3 -3
- dsp_tools/commands/xmlupload/models/upload_state.py +2 -4
- dsp_tools/commands/xmlupload/prepare_xml_input/__init__.py +0 -0
- dsp_tools/commands/xmlupload/{ark2iri.py → prepare_xml_input/ark2iri.py} +1 -1
- dsp_tools/commands/xmlupload/prepare_xml_input/get_processed_resources.py +252 -0
- dsp_tools/commands/xmlupload/{iiif_uri_validator.py → prepare_xml_input/iiif_uri_validator.py} +2 -14
- dsp_tools/commands/xmlupload/{list_client.py → prepare_xml_input/list_client.py} +15 -10
- dsp_tools/commands/xmlupload/prepare_xml_input/prepare_xml_input.py +67 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/read_validate_xml_file.py +58 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/transform_input_values.py +118 -0
- dsp_tools/commands/xmlupload/resource_create_client.py +7 -468
- dsp_tools/commands/xmlupload/richtext_id2iri.py +37 -0
- dsp_tools/commands/xmlupload/stash/{construct_and_analyze_graph.py → analyse_circular_reference_graph.py} +64 -157
- dsp_tools/commands/xmlupload/stash/create_info_for_graph.py +53 -0
- dsp_tools/commands/xmlupload/stash/graph_models.py +13 -8
- dsp_tools/commands/xmlupload/stash/stash_circular_references.py +48 -115
- dsp_tools/commands/xmlupload/stash/stash_models.py +4 -9
- dsp_tools/commands/xmlupload/stash/upload_stashed_resptr_props.py +34 -40
- dsp_tools/commands/xmlupload/stash/upload_stashed_xml_texts.py +98 -108
- dsp_tools/commands/xmlupload/upload_config.py +8 -0
- dsp_tools/commands/xmlupload/write_diagnostic_info.py +14 -9
- dsp_tools/commands/xmlupload/xmlupload.py +214 -192
- dsp_tools/config/__init__.py +0 -0
- dsp_tools/config/logger_config.py +69 -0
- dsp_tools/{utils → config}/warnings_config.py +4 -1
- dsp_tools/error/__init__.py +0 -0
- dsp_tools/error/custom_warnings.py +39 -0
- dsp_tools/error/exceptions.py +204 -0
- dsp_tools/error/problems.py +10 -0
- dsp_tools/error/xmllib_errors.py +20 -0
- dsp_tools/error/xmllib_warnings.py +54 -0
- dsp_tools/error/xmllib_warnings_util.py +159 -0
- dsp_tools/error/xsd_validation_error_msg.py +19 -0
- dsp_tools/legacy_models/__init__.py +0 -0
- dsp_tools/{models → legacy_models}/datetimestamp.py +7 -7
- dsp_tools/{models → legacy_models}/langstring.py +1 -1
- dsp_tools/{models → legacy_models}/projectContext.py +4 -4
- dsp_tools/resources/schema/data.xsd +108 -83
- dsp_tools/resources/schema/lists-only.json +4 -23
- dsp_tools/resources/schema/project.json +80 -35
- dsp_tools/resources/schema/properties-only.json +1 -4
- dsp_tools/resources/start-stack/docker-compose.override-host.j2 +11 -0
- dsp_tools/resources/start-stack/docker-compose.yml +34 -30
- dsp_tools/resources/start-stack/dsp-app-config.json +45 -0
- dsp_tools/resources/start-stack/dsp-app-config.override-host.j2 +26 -0
- dsp_tools/resources/validate_data/api-shapes-resource-cardinalities.ttl +191 -0
- dsp_tools/resources/validate_data/api-shapes.ttl +804 -0
- dsp_tools/resources/validate_data/shacl-cli-image.yml +4 -0
- dsp_tools/resources/validate_data/validate-ontology.ttl +99 -0
- dsp_tools/utils/ansi_colors.py +32 -0
- dsp_tools/utils/data_formats/__init__.py +0 -0
- dsp_tools/utils/{date_util.py → data_formats/date_util.py} +13 -1
- dsp_tools/utils/data_formats/iri_util.py +30 -0
- dsp_tools/utils/{shared.py → data_formats/shared.py} +1 -35
- dsp_tools/utils/{uri_util.py → data_formats/uri_util.py} +12 -2
- dsp_tools/utils/fuseki_bloating.py +63 -0
- dsp_tools/utils/json_parsing.py +22 -0
- dsp_tools/utils/rdf_constants.py +42 -0
- dsp_tools/utils/rdflib_utils.py +10 -0
- dsp_tools/utils/replace_id_with_iri.py +66 -0
- dsp_tools/utils/request_utils.py +238 -0
- dsp_tools/utils/xml_parsing/__init__.py +0 -0
- dsp_tools/utils/xml_parsing/get_lookups.py +32 -0
- dsp_tools/utils/xml_parsing/get_parsed_resources.py +325 -0
- dsp_tools/utils/xml_parsing/models/__init__.py +0 -0
- dsp_tools/utils/xml_parsing/models/parsed_resource.py +76 -0
- dsp_tools/utils/xml_parsing/parse_clean_validate_xml.py +137 -0
- dsp_tools/xmllib/CLAUDE.md +302 -0
- dsp_tools/xmllib/__init__.py +49 -0
- dsp_tools/xmllib/general_functions.py +877 -0
- dsp_tools/xmllib/internal/__init__.py +0 -0
- dsp_tools/xmllib/internal/checkers.py +162 -0
- dsp_tools/xmllib/internal/circumvent_circular_imports.py +36 -0
- dsp_tools/xmllib/internal/constants.py +46 -0
- dsp_tools/xmllib/internal/input_converters.py +155 -0
- dsp_tools/xmllib/internal/serialise_file_value.py +57 -0
- dsp_tools/xmllib/internal/serialise_resource.py +177 -0
- dsp_tools/xmllib/internal/serialise_values.py +152 -0
- dsp_tools/xmllib/internal/type_aliases.py +11 -0
- dsp_tools/xmllib/models/config_options.py +28 -0
- dsp_tools/xmllib/models/date_formats.py +48 -0
- dsp_tools/xmllib/models/dsp_base_resources.py +1380 -400
- dsp_tools/xmllib/models/internal/__init__.py +0 -0
- dsp_tools/xmllib/models/internal/file_values.py +172 -0
- dsp_tools/xmllib/models/internal/geometry.py +162 -0
- dsp_tools/xmllib/models/{migration_metadata.py → internal/migration_metadata.py} +14 -10
- dsp_tools/xmllib/models/internal/serialise_permissions.py +66 -0
- dsp_tools/xmllib/models/internal/values.py +342 -0
- dsp_tools/xmllib/models/licenses/__init__.py +0 -0
- dsp_tools/xmllib/models/licenses/other.py +59 -0
- dsp_tools/xmllib/models/licenses/recommended.py +107 -0
- dsp_tools/xmllib/models/permissions.py +41 -0
- dsp_tools/xmllib/models/res.py +1782 -0
- dsp_tools/xmllib/models/root.py +313 -26
- dsp_tools/xmllib/value_checkers.py +310 -47
- dsp_tools/xmllib/value_converters.py +765 -8
- dsp_tools-18.3.0.post13.dist-info/METADATA +90 -0
- dsp_tools-18.3.0.post13.dist-info/RECORD +286 -0
- dsp_tools-18.3.0.post13.dist-info/WHEEL +4 -0
- {dsp_tools-9.1.0.post11.dist-info → dsp_tools-18.3.0.post13.dist-info}/entry_points.txt +1 -0
- dsp_tools/commands/project/create/project_create.py +0 -1107
- dsp_tools/commands/project/create/project_create_lists.py +0 -204
- dsp_tools/commands/project/create/project_validate.py +0 -453
- dsp_tools/commands/project/models/project_definition.py +0 -12
- dsp_tools/commands/rosetta.py +0 -124
- dsp_tools/commands/template.py +0 -30
- dsp_tools/commands/xml_validate/api_connection.py +0 -122
- dsp_tools/commands/xml_validate/deserialise_input.py +0 -135
- dsp_tools/commands/xml_validate/make_data_rdf.py +0 -193
- dsp_tools/commands/xml_validate/models/data_deserialised.py +0 -108
- dsp_tools/commands/xml_validate/models/data_rdf.py +0 -214
- dsp_tools/commands/xml_validate/models/input_problems.py +0 -191
- dsp_tools/commands/xml_validate/models/validation.py +0 -29
- dsp_tools/commands/xml_validate/reformat_validaton_result.py +0 -89
- dsp_tools/commands/xml_validate/sparql/construct_shapes.py +0 -16
- dsp_tools/commands/xml_validate/xml_validate.py +0 -151
- dsp_tools/commands/xmlupload/check_consistency_with_ontology.py +0 -253
- dsp_tools/commands/xmlupload/models/deserialise/deserialise_value.py +0 -236
- dsp_tools/commands/xmlupload/models/deserialise/xmlresource.py +0 -171
- dsp_tools/commands/xmlupload/models/namespace_context.py +0 -39
- dsp_tools/commands/xmlupload/models/ontology_lookup_models.py +0 -161
- dsp_tools/commands/xmlupload/models/ontology_problem_models.py +0 -178
- dsp_tools/commands/xmlupload/models/serialise/jsonld_serialiser.py +0 -40
- dsp_tools/commands/xmlupload/models/serialise/serialise_value.py +0 -51
- dsp_tools/commands/xmlupload/ontology_client.py +0 -92
- dsp_tools/commands/xmlupload/project_client.py +0 -91
- dsp_tools/commands/xmlupload/read_validate_xml_file.py +0 -99
- dsp_tools/models/custom_warnings.py +0 -31
- dsp_tools/models/exceptions.py +0 -90
- dsp_tools/resources/0100-template-repo/template.json +0 -45
- dsp_tools/resources/0100-template-repo/template.xml +0 -27
- dsp_tools/resources/start-stack/docker-compose-validation.yml +0 -5
- dsp_tools/resources/start-stack/start-stack-config.yml +0 -4
- dsp_tools/resources/xml_validate/api-shapes.ttl +0 -411
- dsp_tools/resources/xml_validate/replace_namespace.xslt +0 -61
- dsp_tools/utils/connection_live.py +0 -383
- dsp_tools/utils/iri_util.py +0 -14
- dsp_tools/utils/logger_config.py +0 -41
- dsp_tools/utils/set_encoder.py +0 -20
- dsp_tools/utils/xml_utils.py +0 -145
- dsp_tools/utils/xml_validation.py +0 -197
- dsp_tools/utils/xml_validation_models.py +0 -68
- dsp_tools/xmllib/models/file_values.py +0 -78
- dsp_tools/xmllib/models/resource.py +0 -415
- dsp_tools/xmllib/models/values.py +0 -428
- dsp_tools-9.1.0.post11.dist-info/METADATA +0 -130
- dsp_tools-9.1.0.post11.dist-info/RECORD +0 -167
- dsp_tools-9.1.0.post11.dist-info/WHEEL +0 -4
- dsp_tools-9.1.0.post11.dist-info/licenses/LICENSE +0 -674
- /dsp_tools/{commands/excel2json/new_lists → clients}/__init__.py +0 -0
- /dsp_tools/commands/{excel2json/new_lists/models → create}/__init__.py +0 -0
- /dsp_tools/commands/{project → create/create_on_server}/__init__.py +0 -0
- /dsp_tools/commands/{project/create → create/models}/__init__.py +0 -0
- /dsp_tools/commands/{project/models → create/parsing}/__init__.py +0 -0
- /dsp_tools/commands/{xml_validate → create/serialisation}/__init__.py +0 -0
- /dsp_tools/commands/{xml_validate/models → excel2json/lists}/__init__.py +0 -0
- /dsp_tools/commands/{xml_validate/sparql → excel2json/lists/models}/__init__.py +0 -0
- /dsp_tools/commands/excel2json/{new_lists → lists}/models/deserialise.py +0 -0
- /dsp_tools/commands/{xmlupload/models/deserialise → get}/__init__.py +0 -0
- /dsp_tools/commands/{xmlupload/models/serialise → get/legacy_models}/__init__.py +0 -0
- /dsp_tools/commands/{project/models → get/legacy_models}/helpers.py +0 -0
- /dsp_tools/{models → commands/get/models}/__init__.py +0 -0
|
@@ -1,332 +1,42 @@
|
|
|
1
1
|
import copy
|
|
2
2
|
import dataclasses
|
|
3
|
-
import datetime
|
|
4
3
|
import difflib
|
|
5
4
|
import json
|
|
6
5
|
import os
|
|
7
|
-
import uuid
|
|
8
6
|
import warnings
|
|
7
|
+
from collections.abc import Iterable
|
|
9
8
|
from pathlib import Path
|
|
10
9
|
from typing import Any
|
|
11
|
-
from typing import Iterable
|
|
12
10
|
from typing import Optional
|
|
13
11
|
from typing import Union
|
|
14
12
|
|
|
15
13
|
import regex
|
|
16
14
|
from lxml import etree
|
|
17
15
|
from lxml.builder import E
|
|
18
|
-
from namedentities.core import numeric_entities # type: ignore[import-untyped]
|
|
19
|
-
from regex import Match
|
|
20
16
|
|
|
21
17
|
from dsp_tools.commands.excel2xml.propertyelement import PropertyElement
|
|
22
|
-
from dsp_tools.
|
|
23
|
-
from dsp_tools.
|
|
24
|
-
from dsp_tools.
|
|
25
|
-
from dsp_tools.utils.date_util import is_full_date
|
|
26
|
-
from dsp_tools.utils.shared import check_notna
|
|
27
|
-
from dsp_tools.utils.shared import simplify_name
|
|
28
|
-
from dsp_tools.utils.uri_util import is_iiif_uri
|
|
29
|
-
from dsp_tools.utils.uri_util import is_uri
|
|
30
|
-
from dsp_tools.utils.
|
|
18
|
+
from dsp_tools.error.custom_warnings import DspToolsUserWarning
|
|
19
|
+
from dsp_tools.error.exceptions import BaseError
|
|
20
|
+
from dsp_tools.legacy_models.datetimestamp import DateTimeStamp
|
|
21
|
+
from dsp_tools.utils.data_formats.date_util import is_full_date
|
|
22
|
+
from dsp_tools.utils.data_formats.shared import check_notna
|
|
23
|
+
from dsp_tools.utils.data_formats.shared import simplify_name
|
|
24
|
+
from dsp_tools.utils.data_formats.uri_util import is_iiif_uri
|
|
25
|
+
from dsp_tools.utils.data_formats.uri_util import is_uri
|
|
26
|
+
from dsp_tools.utils.xml_parsing.parse_clean_validate_xml import parse_and_validate_xml_file
|
|
27
|
+
from dsp_tools.xmllib import find_dates_in_string as find_dates_in_string # noqa: PLC0414 (explicit re-export)
|
|
28
|
+
from dsp_tools.xmllib.general_functions import make_xsd_compatible_id
|
|
29
|
+
from dsp_tools.xmllib.general_functions import make_xsd_compatible_id_with_uuid
|
|
30
|
+
from dsp_tools.xmllib.internal.input_converters import numeric_entities
|
|
31
31
|
|
|
32
32
|
# ruff: noqa: E501, UP031 (line-too-long, use f-string over percent formatting)
|
|
33
33
|
|
|
34
|
+
make_xsd_id_compatible = make_xsd_compatible_id_with_uuid
|
|
35
|
+
make_xsd_id_compatible_without_uuid = make_xsd_compatible_id
|
|
34
36
|
|
|
35
37
|
xml_namespace_map = {None: "https://dasch.swiss/schema", "xsi": "http://www.w3.org/2001/XMLSchema-instance"}
|
|
36
38
|
|
|
37
39
|
|
|
38
|
-
def make_xsd_id_compatible(string: str) -> str:
|
|
39
|
-
"""
|
|
40
|
-
An xsd:ID may not contain all types of special characters.
|
|
41
|
-
This function replaces illegal characters with "_" and appends a random UUID.
|
|
42
|
-
The UUID will be different each time the function is called.
|
|
43
|
-
|
|
44
|
-
The string must contain at least one Unicode letter (matching the regex ``\\p{L}``),
|
|
45
|
-
underscore, !, ?, or number, but must not be `None`, `<NA>`, `N/A`, or `-`.
|
|
46
|
-
Otherwise, a BaseError will be raised.
|
|
47
|
-
|
|
48
|
-
Args:
|
|
49
|
-
string: input string
|
|
50
|
-
|
|
51
|
-
Raises:
|
|
52
|
-
BaseError: if the input cannot be transformed to an xsd:ID
|
|
53
|
-
|
|
54
|
-
Returns:
|
|
55
|
-
an xsd ID based on the input string, with a UUID attached.
|
|
56
|
-
"""
|
|
57
|
-
res = make_xsd_id_compatible_without_uuid(string)
|
|
58
|
-
_uuid = uuid.uuid4()
|
|
59
|
-
res = f"{res}_{_uuid}"
|
|
60
|
-
return res
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def make_xsd_id_compatible_without_uuid(string: str) -> str:
|
|
64
|
-
"""
|
|
65
|
-
An xsd:ID may not contain all types of special characters.
|
|
66
|
-
This function replaces illegal characters with "_".
|
|
67
|
-
|
|
68
|
-
The string must contain at least one Unicode letter (matching the regex ``\\p{L}``),
|
|
69
|
-
underscore, !, ?, or number, but must not be `None`, `<NA>`, `N/A`, or `-`.
|
|
70
|
-
Otherwise, a BaseError will be raised.
|
|
71
|
-
|
|
72
|
-
Args:
|
|
73
|
-
string: input string
|
|
74
|
-
|
|
75
|
-
Raises:
|
|
76
|
-
BaseError: if the input cannot be transformed to an xsd:ID
|
|
77
|
-
|
|
78
|
-
Returns:
|
|
79
|
-
an xsd ID compatible string based on the input string
|
|
80
|
-
"""
|
|
81
|
-
if not isinstance(string, str) or not check_notna(string):
|
|
82
|
-
raise BaseError(f"The input '{string}' cannot be transformed to an xsd:ID")
|
|
83
|
-
# if start of string is neither letter nor underscore, add an underscore
|
|
84
|
-
res = regex.sub(r"^(?=[^A-Za-z_])", "_", string)
|
|
85
|
-
# replace all illegal characters by underscore
|
|
86
|
-
res = regex.sub(r"[^\w_\-.]", "_", res, flags=regex.ASCII)
|
|
87
|
-
return res
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
def _find_french_bc_date(
|
|
91
|
-
string: str,
|
|
92
|
-
lookbehind: str,
|
|
93
|
-
lookahead: str,
|
|
94
|
-
) -> Optional[str]:
|
|
95
|
-
french_bc_regex = r"av(?:\. |\.| )J\.?-?C\.?"
|
|
96
|
-
if not regex.search(french_bc_regex, string):
|
|
97
|
-
return None
|
|
98
|
-
|
|
99
|
-
year_regex = r"\d{1,5}"
|
|
100
|
-
sep_regex = r" ?- ?"
|
|
101
|
-
|
|
102
|
-
year_range_regex = rf"{lookbehind}({year_regex}){sep_regex}({year_regex}) {french_bc_regex}{lookahead}"
|
|
103
|
-
year_range = regex.search(year_range_regex, string)
|
|
104
|
-
if year_range:
|
|
105
|
-
start_year = int(year_range.group(1))
|
|
106
|
-
end_year = int(year_range.group(2))
|
|
107
|
-
if end_year > start_year:
|
|
108
|
-
return None
|
|
109
|
-
return f"GREGORIAN:BC:{start_year}:BC:{end_year}"
|
|
110
|
-
|
|
111
|
-
single_year_regex = rf"{lookbehind}({year_regex}) {french_bc_regex}{lookahead}"
|
|
112
|
-
single_year = regex.search(single_year_regex, string)
|
|
113
|
-
if single_year:
|
|
114
|
-
start_year = int(single_year.group(1))
|
|
115
|
-
return f"GREGORIAN:BC:{start_year}:BC:{start_year}"
|
|
116
|
-
|
|
117
|
-
return None
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
def find_date_in_string(string: str) -> Optional[str]:
|
|
121
|
-
"""
|
|
122
|
-
Checks if a string contains a date value (single date, or date range),
|
|
123
|
-
and returns the first found date as DSP-formatted string.
|
|
124
|
-
Returns None if no date was found.
|
|
125
|
-
|
|
126
|
-
Notes:
|
|
127
|
-
- All dates are interpreted in the Christian era and the Gregorian calendar.
|
|
128
|
-
- BC dates are only supported in French notation (e.g. 1000-900 av. J.-C.).
|
|
129
|
-
- The years 0000-2999 are supported, in 3/4-digit form.
|
|
130
|
-
- Dates written with slashes are always interpreted in a European manner: 5/11/2021 is the 5th of November.
|
|
131
|
-
- In the European notation, 2-digit years are expanded to 4 digits, with the current year as watershed:
|
|
132
|
-
- 30.4.24 -> 30.04.2024
|
|
133
|
-
- 30.4.25 -> 30.04.1925
|
|
134
|
-
|
|
135
|
-
Currently supported date formats:
|
|
136
|
-
- 0476-09-04 -> GREGORIAN:CE:0476-09-04:CE:0476-09-04
|
|
137
|
-
- 0476_09_04 -> GREGORIAN:CE:0476-09-04:CE:0476-09-04
|
|
138
|
-
- 30.4.2021 -> GREGORIAN:CE:2021-04-30:CE:2021-04-30
|
|
139
|
-
- 30.4.21 -> GREGORIAN:CE:2021-04-30:CE:2021-04-30
|
|
140
|
-
- 5/11/2021 -> GREGORIAN:CE:2021-11-05:CE:2021-11-05
|
|
141
|
-
- Jan 26, 1993 -> GREGORIAN:CE:1993-01-26:CE:1993-01-26
|
|
142
|
-
- 28.2.-1.12.1515 -> GREGORIAN:CE:1515-02-28:CE:1515-12-01
|
|
143
|
-
- 25.-26.2.0800 -> GREGORIAN:CE:0800-02-25:CE:0800-02-26
|
|
144
|
-
- 1.9.2022-3.1.2024 -> GREGORIAN:CE:2022-09-01:CE:2024-01-03
|
|
145
|
-
- 1848 -> GREGORIAN:CE:1848:CE:1848
|
|
146
|
-
- 1849/1850 -> GREGORIAN:CE:1849:CE:1850
|
|
147
|
-
- 1849/50 -> GREGORIAN:CE:1849:CE:1850
|
|
148
|
-
- 1845-50 -> GREGORIAN:CE:1845:CE:1850
|
|
149
|
-
- 840-50 -> GREGORIAN:CE:840:CE:850
|
|
150
|
-
- 840-1 -> GREGORIAN:CE:840:CE:841
|
|
151
|
-
- 1000-900 av. J.-C. -> GREGORIAN:BC:1000:BC:900
|
|
152
|
-
- 45 av. J.-C. -> GREGORIAN:BC:45:BC:45
|
|
153
|
-
|
|
154
|
-
Args:
|
|
155
|
-
string: string to check
|
|
156
|
-
|
|
157
|
-
Returns:
|
|
158
|
-
DSP-formatted date string, or None
|
|
159
|
-
|
|
160
|
-
Examples:
|
|
161
|
-
>>> if find_date_in_string(row["Epoch"]):
|
|
162
|
-
>>> resource.append(make_date_prop(":hasDate", find_date_in_string(row["Epoch"]))
|
|
163
|
-
|
|
164
|
-
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#date-prop
|
|
165
|
-
"""
|
|
166
|
-
|
|
167
|
-
# sanitize input, just in case that the method was called on an empty or N/A cell
|
|
168
|
-
if not check_notna(string):
|
|
169
|
-
return None
|
|
170
|
-
try:
|
|
171
|
-
return _find_date_in_string_throwing(string)
|
|
172
|
-
except ValueError:
|
|
173
|
-
return None
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
_months_dict = {
|
|
177
|
-
"January": 1,
|
|
178
|
-
"Jan": 1,
|
|
179
|
-
"February": 2,
|
|
180
|
-
"Feb": 2,
|
|
181
|
-
"March": 3,
|
|
182
|
-
"Mar": 3,
|
|
183
|
-
"April": 4,
|
|
184
|
-
"Apr": 4,
|
|
185
|
-
"May": 5,
|
|
186
|
-
"June": 6,
|
|
187
|
-
"Jun": 6,
|
|
188
|
-
"July": 7,
|
|
189
|
-
"Jul": 7,
|
|
190
|
-
"August": 8,
|
|
191
|
-
"Aug": 8,
|
|
192
|
-
"September": 9,
|
|
193
|
-
"Sept": 9,
|
|
194
|
-
"October": 10,
|
|
195
|
-
"Oct": 10,
|
|
196
|
-
"November": 11,
|
|
197
|
-
"Nov": 11,
|
|
198
|
-
"December": 12,
|
|
199
|
-
"Dec": 12,
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
def _find_date_in_string_throwing(string: str) -> str | None:
|
|
204
|
-
"""
|
|
205
|
-
This function is the same as find_date_in_string(), but may raise a ValueError instead of returning None.
|
|
206
|
-
"""
|
|
207
|
-
year_regex = r"([0-2]?[0-9][0-9][0-9])"
|
|
208
|
-
year_regex_2_or_4_digits = r"((?:[0-2]?[0-9])?[0-9][0-9])"
|
|
209
|
-
month_regex = r"([0-1]?[0-9])"
|
|
210
|
-
day_regex = r"([0-3]?[0-9])"
|
|
211
|
-
sep_regex = r"[\./]"
|
|
212
|
-
lookbehind = r"(?<![0-9A-Za-z])"
|
|
213
|
-
lookahead = r"(?![0-9A-Za-z])"
|
|
214
|
-
|
|
215
|
-
if french_bc_date := _find_french_bc_date(string=string, lookbehind=lookbehind, lookahead=lookahead):
|
|
216
|
-
return french_bc_date
|
|
217
|
-
|
|
218
|
-
# template: 2021-01-01 | 2015_01_02
|
|
219
|
-
iso_date = regex.search(rf"{lookbehind}{year_regex}[_-]([0-1][0-9])[_-]([0-3][0-9]){lookahead}", string)
|
|
220
|
-
|
|
221
|
-
# template: 6.-8.3.1948 | 6/2/1947 - 24.03.1948
|
|
222
|
-
eur_date_range_regex = (
|
|
223
|
-
rf"{lookbehind}"
|
|
224
|
-
rf"{day_regex}{sep_regex}(?:{month_regex}{sep_regex}{year_regex_2_or_4_digits}?)? ?(?:-|:|to) ?"
|
|
225
|
-
rf"{day_regex}{sep_regex}{month_regex}{sep_regex}{year_regex_2_or_4_digits}"
|
|
226
|
-
rf"{lookahead}"
|
|
227
|
-
)
|
|
228
|
-
eur_date_range = regex.search(eur_date_range_regex, string)
|
|
229
|
-
|
|
230
|
-
# template: 1.4.2021 | 5/11/2021
|
|
231
|
-
eur_date_regex = rf"{lookbehind}{day_regex}{sep_regex}{month_regex}{sep_regex}{year_regex_2_or_4_digits}{lookahead}"
|
|
232
|
-
eur_date = regex.search(
|
|
233
|
-
eur_date_regex,
|
|
234
|
-
string,
|
|
235
|
-
)
|
|
236
|
-
|
|
237
|
-
# template: March 9, 1908 | March5,1908 | May 11, 1906
|
|
238
|
-
all_months = "|".join(_months_dict)
|
|
239
|
-
monthname_date_regex = rf"{lookbehind}({all_months}) ?{day_regex}, ?{year_regex}{lookahead}"
|
|
240
|
-
monthname_date = regex.search(monthname_date_regex, string)
|
|
241
|
-
|
|
242
|
-
# template: 1849/50 | 1849-50 | 1849/1850
|
|
243
|
-
year_range = regex.search(lookbehind + year_regex + r"[/-](\d{1,4})" + lookahead, string)
|
|
244
|
-
|
|
245
|
-
# template: 1907
|
|
246
|
-
year_only = regex.search(rf"{lookbehind}{year_regex}{lookahead}", string)
|
|
247
|
-
|
|
248
|
-
res: str | None = None
|
|
249
|
-
if iso_date:
|
|
250
|
-
res = _from_iso_date(iso_date)
|
|
251
|
-
elif eur_date_range:
|
|
252
|
-
res = _from_eur_date_range(eur_date_range)
|
|
253
|
-
elif eur_date:
|
|
254
|
-
res = _from_eur_date(eur_date)
|
|
255
|
-
elif monthname_date:
|
|
256
|
-
res = _from_monthname_date(monthname_date)
|
|
257
|
-
elif year_range:
|
|
258
|
-
res = _from_year_range(year_range)
|
|
259
|
-
elif year_only:
|
|
260
|
-
year = int(year_only.group(0))
|
|
261
|
-
res = f"GREGORIAN:CE:{year}:CE:{year}"
|
|
262
|
-
return res
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
def _from_iso_date(iso_date: Match[str]) -> str:
|
|
266
|
-
year = int(iso_date.group(1))
|
|
267
|
-
month = int(iso_date.group(2))
|
|
268
|
-
day = int(iso_date.group(3))
|
|
269
|
-
date = datetime.date(year, month, day)
|
|
270
|
-
return f"GREGORIAN:CE:{date.isoformat()}:CE:{date.isoformat()}"
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
def _expand_2_digit_year(year: int) -> int:
|
|
274
|
-
current_year = datetime.date.today().year - 2000
|
|
275
|
-
if year <= current_year:
|
|
276
|
-
return year + 2000
|
|
277
|
-
elif year <= 99:
|
|
278
|
-
return year + 1900
|
|
279
|
-
else:
|
|
280
|
-
return year
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
def _from_eur_date_range(eur_date_range: Match[str]) -> str:
|
|
284
|
-
startday = int(eur_date_range.group(1))
|
|
285
|
-
startmonth = int(eur_date_range.group(2)) if eur_date_range.group(2) else int(eur_date_range.group(5))
|
|
286
|
-
startyear = int(eur_date_range.group(3)) if eur_date_range.group(3) else int(eur_date_range.group(6))
|
|
287
|
-
startyear = _expand_2_digit_year(startyear)
|
|
288
|
-
endday = int(eur_date_range.group(4))
|
|
289
|
-
endmonth = int(eur_date_range.group(5))
|
|
290
|
-
endyear = int(eur_date_range.group(6))
|
|
291
|
-
endyear = _expand_2_digit_year(endyear)
|
|
292
|
-
startdate = datetime.date(startyear, startmonth, startday)
|
|
293
|
-
enddate = datetime.date(endyear, endmonth, endday)
|
|
294
|
-
if enddate < startdate:
|
|
295
|
-
raise ValueError
|
|
296
|
-
return f"GREGORIAN:CE:{startdate.isoformat()}:CE:{enddate.isoformat()}"
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
def _from_eur_date(eur_date: Match[str]) -> str:
|
|
300
|
-
startday = int(eur_date.group(1))
|
|
301
|
-
startmonth = int(eur_date.group(2))
|
|
302
|
-
startyear = int(eur_date.group(3))
|
|
303
|
-
startyear = _expand_2_digit_year(startyear)
|
|
304
|
-
date = datetime.date(startyear, startmonth, startday)
|
|
305
|
-
return f"GREGORIAN:CE:{date.isoformat()}:CE:{date.isoformat()}"
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
def _from_monthname_date(monthname_date: Match[str]) -> str:
|
|
309
|
-
day = int(monthname_date.group(2))
|
|
310
|
-
month = _months_dict[monthname_date.group(1)]
|
|
311
|
-
year = int(monthname_date.group(3))
|
|
312
|
-
date = datetime.date(year, month, day)
|
|
313
|
-
return f"GREGORIAN:CE:{date.isoformat()}:CE:{date.isoformat()}"
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
def _from_year_range(year_range: Match[str]) -> str:
|
|
317
|
-
startyear = int(year_range.group(1))
|
|
318
|
-
endyear = int(year_range.group(2))
|
|
319
|
-
if endyear // 10 == 0:
|
|
320
|
-
# endyear is only 1-digit: add the first 2-3 digits of startyear
|
|
321
|
-
endyear = startyear // 10 * 10 + endyear
|
|
322
|
-
elif endyear // 100 == 0:
|
|
323
|
-
# endyear is only 2-digit: add the first 1-2 digits of startyear
|
|
324
|
-
endyear = startyear // 100 * 100 + endyear
|
|
325
|
-
if endyear <= startyear:
|
|
326
|
-
raise ValueError
|
|
327
|
-
return f"GREGORIAN:CE:{startyear}:CE:{endyear}"
|
|
328
|
-
|
|
329
|
-
|
|
330
40
|
def prepare_value(
|
|
331
41
|
value: Union[PropertyElement, str, int, float, bool, Iterable[Union[PropertyElement, str, int, float, bool]]],
|
|
332
42
|
) -> list[PropertyElement]:
|
|
@@ -384,15 +94,15 @@ def make_root(
|
|
|
384
94
|
|
|
385
95
|
def append_permissions(root_element: etree._Element) -> etree._Element:
|
|
386
96
|
"""
|
|
387
|
-
After having created a root element, call this
|
|
388
|
-
"
|
|
97
|
+
After having created a root element, call this function to append the standard permission definitions "public",
|
|
98
|
+
"limited_view", and "private" to it. These definitions are a good basis to
|
|
389
99
|
start with, but remember that they can be adapted, and that other permissions can be defined instead of these.
|
|
390
100
|
|
|
391
101
|
Args:
|
|
392
102
|
root_element: The XML root element `<knora>` created by make_root()
|
|
393
103
|
|
|
394
104
|
Returns:
|
|
395
|
-
The root element with the
|
|
105
|
+
The root element with the permission definition blocks appended
|
|
396
106
|
|
|
397
107
|
Examples:
|
|
398
108
|
>>> root = excel2xml.make_root(shortcode=shortcode, default_ontology=default_ontology)
|
|
@@ -406,33 +116,24 @@ def append_permissions(root_element: etree._Element) -> etree._Element:
|
|
|
406
116
|
# lxml.builder.E is a more sophisticated element factory than etree.Element.
|
|
407
117
|
# E.tag is equivalent to E("tag") and results in <tag>
|
|
408
118
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
root_element.append(
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
prop_default.append(ALLOW("CR", group="ProjectAdmin"))
|
|
428
|
-
prop_default.append(ALLOW("CR", group="Creator"))
|
|
429
|
-
root_element.append(prop_default)
|
|
430
|
-
|
|
431
|
-
prop_restricted = PERMISSIONS(id="prop-restricted")
|
|
432
|
-
prop_restricted.append(ALLOW("M", group="ProjectMember"))
|
|
433
|
-
prop_restricted.append(ALLOW("CR", group="ProjectAdmin"))
|
|
434
|
-
prop_restricted.append(ALLOW("CR", group="Creator"))
|
|
435
|
-
root_element.append(prop_restricted)
|
|
119
|
+
_public = PERMISSIONS(id="public")
|
|
120
|
+
_public.append(ALLOW("V", group="UnknownUser"))
|
|
121
|
+
_public.append(ALLOW("V", group="KnownUser"))
|
|
122
|
+
_public.append(ALLOW("D", group="ProjectMember"))
|
|
123
|
+
_public.append(ALLOW("CR", group="ProjectAdmin"))
|
|
124
|
+
root_element.append(_public)
|
|
125
|
+
|
|
126
|
+
_private_view = PERMISSIONS(id="limited_view")
|
|
127
|
+
_private_view.append(ALLOW("RV", group="UnknownUser"))
|
|
128
|
+
_private_view.append(ALLOW("RV", group="KnownUser"))
|
|
129
|
+
_private_view.append(ALLOW("D", group="ProjectMember"))
|
|
130
|
+
_private_view.append(ALLOW("CR", group="ProjectAdmin"))
|
|
131
|
+
root_element.append(_private_view)
|
|
132
|
+
|
|
133
|
+
_private = PERMISSIONS(id="private")
|
|
134
|
+
_private.append(ALLOW("D", group="ProjectMember"))
|
|
135
|
+
_private.append(ALLOW("CR", group="ProjectAdmin"))
|
|
136
|
+
root_element.append(_private)
|
|
436
137
|
|
|
437
138
|
return root_element
|
|
438
139
|
|
|
@@ -441,7 +142,7 @@ def make_resource( # noqa: D417 (undocumented-param)
|
|
|
441
142
|
label: str,
|
|
442
143
|
restype: str,
|
|
443
144
|
id: str,
|
|
444
|
-
permissions: str = "
|
|
145
|
+
permissions: str = "public",
|
|
445
146
|
ark: Optional[str] = None,
|
|
446
147
|
iri: Optional[str] = None,
|
|
447
148
|
creation_date: Optional[str] = None,
|
|
@@ -496,7 +197,7 @@ def make_resource( # noqa: D417 (undocumented-param)
|
|
|
496
197
|
|
|
497
198
|
def make_bitstream_prop(
|
|
498
199
|
path: Union[str, os.PathLike[Any]],
|
|
499
|
-
permissions: str = "
|
|
200
|
+
permissions: str = "public",
|
|
500
201
|
check: bool = False,
|
|
501
202
|
calling_resource: str = "",
|
|
502
203
|
) -> etree._Element:
|
|
@@ -540,7 +241,7 @@ def make_bitstream_prop(
|
|
|
540
241
|
|
|
541
242
|
def make_iiif_uri_prop(
|
|
542
243
|
iiif_uri: str,
|
|
543
|
-
permissions: str = "
|
|
244
|
+
permissions: str = "public",
|
|
544
245
|
calling_resource: str = "",
|
|
545
246
|
) -> etree._Element:
|
|
546
247
|
"""
|
|
@@ -622,7 +323,7 @@ def make_boolean_prop(
|
|
|
622
323
|
- true: (True, "true", "True", "1", 1, "yes", "Yes")
|
|
623
324
|
- false: (False, "false", "False", "0", 0, "no", "No")
|
|
624
325
|
|
|
625
|
-
Unless provided as PropertyElement, the permissions of the value default to "
|
|
326
|
+
Unless provided as PropertyElement, the permissions of the value default to "public".
|
|
626
327
|
|
|
627
328
|
Args:
|
|
628
329
|
name: the name of this property as defined in the onto
|
|
@@ -638,11 +339,11 @@ def make_boolean_prop(
|
|
|
638
339
|
Examples:
|
|
639
340
|
>>> excel2xml.make_boolean_prop(":testproperty", "no")
|
|
640
341
|
<boolean-prop name=":testproperty">
|
|
641
|
-
<boolean permissions="
|
|
342
|
+
<boolean permissions="public">false</boolean>
|
|
642
343
|
</boolean-prop>
|
|
643
|
-
>>> excel2xml.make_boolean_prop(":testproperty", excel2xml.PropertyElement("1", permissions="
|
|
344
|
+
>>> excel2xml.make_boolean_prop(":testproperty", excel2xml.PropertyElement("1", permissions="private", comment="example"))
|
|
644
345
|
<boolean-prop name=":testproperty">
|
|
645
|
-
<boolean permissions="
|
|
346
|
+
<boolean permissions="private" comment="example">true</boolean>
|
|
646
347
|
</boolean-prop>
|
|
647
348
|
|
|
648
349
|
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#boolean-prop
|
|
@@ -651,7 +352,7 @@ def make_boolean_prop(
|
|
|
651
352
|
# validate input
|
|
652
353
|
if isinstance(value, PropertyElement):
|
|
653
354
|
value_new = dataclasses.replace(value, value=_format_bool(value.value, name, calling_resource))
|
|
654
|
-
elif isinstance(value,
|
|
355
|
+
elif isinstance(value, str | bool | int):
|
|
655
356
|
value_new = PropertyElement(_format_bool(value, name, calling_resource))
|
|
656
357
|
else:
|
|
657
358
|
raise BaseError(
|
|
@@ -685,7 +386,7 @@ def make_color_prop(
|
|
|
685
386
|
) -> etree._Element:
|
|
686
387
|
"""
|
|
687
388
|
Make a `<color-prop>` from one or more colors. The color(s) can be provided as string or as PropertyElement with a
|
|
688
|
-
string inside. If provided as string, the permissions default to "
|
|
389
|
+
string inside. If provided as string, the permissions default to "public".
|
|
689
390
|
|
|
690
391
|
Args:
|
|
691
392
|
name: the name of this property as defined in the onto
|
|
@@ -701,16 +402,16 @@ def make_color_prop(
|
|
|
701
402
|
Examples:
|
|
702
403
|
>>> excel2xml.make_color_prop(":testproperty", "#00ff66")
|
|
703
404
|
<color-prop name=":testproperty">
|
|
704
|
-
<color permissions="
|
|
405
|
+
<color permissions="public">#00ff66</color>
|
|
705
406
|
</color-prop>
|
|
706
|
-
>>> excel2xml.make_color_prop(":testproperty", excel2xml.PropertyElement("#00ff66", permissions="
|
|
407
|
+
>>> excel2xml.make_color_prop(":testproperty", excel2xml.PropertyElement("#00ff66", permissions="private", comment="example"))
|
|
707
408
|
<color-prop name=":testproperty">
|
|
708
|
-
<color permissions="
|
|
409
|
+
<color permissions="private" comment="example">#00ff66</color>
|
|
709
410
|
</color-prop>
|
|
710
411
|
>>> excel2xml.make_color_prop(":testproperty", ["#00ff66", "#000000"])
|
|
711
412
|
<color-prop name=":testproperty">
|
|
712
|
-
<color permissions="
|
|
713
|
-
<color permissions="
|
|
413
|
+
<color permissions="public">#00ff66</color>
|
|
414
|
+
<color permissions="public">#000000</color>
|
|
714
415
|
</color-prop>
|
|
715
416
|
|
|
716
417
|
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#color-prop
|
|
@@ -756,7 +457,7 @@ def make_date_prop(
|
|
|
756
457
|
) -> etree._Element:
|
|
757
458
|
"""
|
|
758
459
|
Make a `<date-prop>` from one or more dates/date ranges. The date(s) can be provided as string or as PropertyElement
|
|
759
|
-
with a string inside. If provided as string, the permissions default to "
|
|
460
|
+
with a string inside. If provided as string, the permissions default to "public".
|
|
760
461
|
|
|
761
462
|
Args:
|
|
762
463
|
name: the name of this property as defined in the onto
|
|
@@ -772,20 +473,20 @@ def make_date_prop(
|
|
|
772
473
|
Examples:
|
|
773
474
|
>>> excel2xml.make_date_prop(":testproperty", "GREGORIAN:CE:2014-01-31")
|
|
774
475
|
<date-prop name=":testproperty">
|
|
775
|
-
<date permissions="
|
|
476
|
+
<date permissions="public">GREGORIAN:CE:2014-01-31</date>
|
|
776
477
|
</date-prop>
|
|
777
|
-
>>> excel2xml.make_date_prop(":testproperty", excel2xml.PropertyElement("GREGORIAN:CE:2014-01-31", permissions="
|
|
478
|
+
>>> excel2xml.make_date_prop(":testproperty", excel2xml.PropertyElement("GREGORIAN:CE:2014-01-31", permissions="private", comment="example"))
|
|
778
479
|
<date-prop name=":testproperty">
|
|
779
|
-
<date permissions="
|
|
480
|
+
<date permissions="private" comment="example">
|
|
780
481
|
GREGORIAN:CE:2014-01-31
|
|
781
482
|
</date>
|
|
782
483
|
</date-prop>
|
|
783
484
|
>>> excel2xml.make_date_prop(":testproperty", ["GREGORIAN:CE:1930-09-02:CE:1930-09-03", "GREGORIAN:CE:1930-09-02:CE:1930-09-03"])
|
|
784
485
|
<date-prop name=":testproperty">
|
|
785
|
-
<date permissions="
|
|
486
|
+
<date permissions="public">
|
|
786
487
|
GREGORIAN:CE:1930-09-02:CE:1930-09-03
|
|
787
488
|
</date>
|
|
788
|
-
<date permissions="
|
|
489
|
+
<date permissions="public">
|
|
789
490
|
GREGORIAN:CE:1930-09-02:CE:1930-09-03
|
|
790
491
|
</date>
|
|
791
492
|
</date-prop>
|
|
@@ -834,7 +535,7 @@ def make_decimal_prop(
|
|
|
834
535
|
"""
|
|
835
536
|
Make a `<decimal-prop>` from one or more decimal numbers. The decimal(s) can be provided as string, float, or as
|
|
836
537
|
PropertyElement with a string/float inside. If provided as string/float, the permissions default to
|
|
837
|
-
"
|
|
538
|
+
"public".
|
|
838
539
|
|
|
839
540
|
Args:
|
|
840
541
|
name: the name of this property as defined in the onto
|
|
@@ -850,16 +551,16 @@ def make_decimal_prop(
|
|
|
850
551
|
Examples:
|
|
851
552
|
>>> excel2xml.make_decimal_prop(":testproperty", "3.14159")
|
|
852
553
|
<decimal-prop name=":testproperty">
|
|
853
|
-
<decimal permissions="
|
|
554
|
+
<decimal permissions="public">3.14159</decimal>
|
|
854
555
|
</decimal-prop>
|
|
855
|
-
>>> excel2xml.make_decimal_prop(":testproperty", excel2xml.PropertyElement("3.14159", permissions="
|
|
556
|
+
>>> excel2xml.make_decimal_prop(":testproperty", excel2xml.PropertyElement("3.14159", permissions="private", comment="example"))
|
|
856
557
|
<decimal-prop name=":testproperty">
|
|
857
|
-
<decimal permissions="
|
|
558
|
+
<decimal permissions="private" comment="example">3.14159</decimal>
|
|
858
559
|
</decimal-prop>
|
|
859
560
|
>>> excel2xml.make_decimal_prop(":testproperty", ["3.14159", "2.718"])
|
|
860
561
|
<decimal-prop name=":testproperty">
|
|
861
|
-
<decimal permissions="
|
|
862
|
-
<decimal permissions="
|
|
562
|
+
<decimal permissions="public">3.14159</decimal>
|
|
563
|
+
<decimal permissions="public">2.718</decimal>
|
|
863
564
|
</decimal-prop>
|
|
864
565
|
|
|
865
566
|
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#decimal-prop
|
|
@@ -907,7 +608,7 @@ def make_geometry_prop(
|
|
|
907
608
|
) -> etree._Element:
|
|
908
609
|
"""
|
|
909
610
|
Make a `<geometry-prop>` from one or more areas of an image. The area(s) can be provided as JSON-string or as
|
|
910
|
-
PropertyElement with the JSON-string inside. If provided as string, the permissions default to "
|
|
611
|
+
PropertyElement with the JSON-string inside. If provided as string, the permissions default to "public".
|
|
911
612
|
|
|
912
613
|
Args:
|
|
913
614
|
name: the name of this property as defined in the onto
|
|
@@ -923,16 +624,16 @@ def make_geometry_prop(
|
|
|
923
624
|
Examples:
|
|
924
625
|
>>> excel2xml.make_geometry_prop(":testproperty", json_string)
|
|
925
626
|
<geometry-prop name=":testproperty">
|
|
926
|
-
<geometry permissions="
|
|
627
|
+
<geometry permissions="public">{JSON}</geometry>
|
|
927
628
|
</geometry-prop>
|
|
928
|
-
>>> excel2xml.make_geometry_prop(":testproperty", excel2xml.PropertyElement(json_string, permissions="
|
|
629
|
+
>>> excel2xml.make_geometry_prop(":testproperty", excel2xml.PropertyElement(json_string, permissions="private", comment="example"))
|
|
929
630
|
<geometry-prop name=":testproperty">
|
|
930
|
-
<geometry permissions="
|
|
631
|
+
<geometry permissions="private" comment="example">{JSON}</geometry>
|
|
931
632
|
</geometry-prop>
|
|
932
633
|
>>> excel2xml.make_geometry_prop(":testproperty", [json_string1, json_string2])
|
|
933
634
|
<geometry-prop name=":testproperty">
|
|
934
|
-
<geometry permissions="
|
|
935
|
-
<geometry permissions="
|
|
635
|
+
<geometry permissions="public">{JSON}</geometry>
|
|
636
|
+
<geometry permissions="public">{JSON}</geometry>
|
|
936
637
|
</geometry-prop>
|
|
937
638
|
|
|
938
639
|
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#geometry-prop
|
|
@@ -992,7 +693,7 @@ def make_geoname_prop(
|
|
|
992
693
|
"""
|
|
993
694
|
Make a `<geoname-prop>` from one or more geonames.org IDs. The ID(s) can be provided as string, integer, or as
|
|
994
695
|
PropertyElement with a string/integer inside. If provided as string/integer, the permissions default to
|
|
995
|
-
"
|
|
696
|
+
"public".
|
|
996
697
|
|
|
997
698
|
Args:
|
|
998
699
|
name: the name of this property as defined in the onto
|
|
@@ -1008,16 +709,16 @@ def make_geoname_prop(
|
|
|
1008
709
|
Examples:
|
|
1009
710
|
>>> excel2xml.make_geoname_prop(":testproperty", "2761369")
|
|
1010
711
|
<geoname-prop name=":testproperty">
|
|
1011
|
-
<geoname permissions="
|
|
712
|
+
<geoname permissions="public">2761369</geoname>
|
|
1012
713
|
</geoname-prop>
|
|
1013
|
-
>>> excel2xml.make_geoname_prop(":testproperty", excel2xml.PropertyElement("2761369", permissions="
|
|
714
|
+
>>> excel2xml.make_geoname_prop(":testproperty", excel2xml.PropertyElement("2761369", permissions="private", comment="example"))
|
|
1014
715
|
<geoname-prop name=":testproperty">
|
|
1015
|
-
<geoname permissions="
|
|
716
|
+
<geoname permissions="private" comment="example">2761369</geoname>
|
|
1016
717
|
</geoname-prop>
|
|
1017
718
|
>>> excel2xml.make_geoname_prop(":testproperty", ["2761369", "1010101"])
|
|
1018
719
|
<geoname-prop name=":testproperty">
|
|
1019
|
-
<geoname permissions="
|
|
1020
|
-
<geoname permissions="
|
|
720
|
+
<geoname permissions="public">2761369</geoname>
|
|
721
|
+
<geoname permissions="public">1010101</geoname>
|
|
1021
722
|
</geoname-prop>
|
|
1022
723
|
|
|
1023
724
|
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#geoname-prop
|
|
@@ -1064,7 +765,7 @@ def make_integer_prop(
|
|
|
1064
765
|
"""
|
|
1065
766
|
Make a `<integer-prop>` from one or more integers. The integers can be provided as string, integer, or as
|
|
1066
767
|
PropertyElement with a string/integer inside. If provided as string/integer, the permissions default to
|
|
1067
|
-
"
|
|
768
|
+
"public".
|
|
1068
769
|
|
|
1069
770
|
Args:
|
|
1070
771
|
name: the name of this property as defined in the onto
|
|
@@ -1080,16 +781,16 @@ def make_integer_prop(
|
|
|
1080
781
|
Examples:
|
|
1081
782
|
>>> excel2xml.make_integer_prop(":testproperty", "2761369")
|
|
1082
783
|
<integer-prop name=":testproperty">
|
|
1083
|
-
<integer permissions="
|
|
784
|
+
<integer permissions="public">2761369</integer>
|
|
1084
785
|
</integer-prop>
|
|
1085
|
-
>>> excel2xml.make_integer_prop(":testproperty", excel2xml.PropertyElement("2761369", permissions="
|
|
786
|
+
>>> excel2xml.make_integer_prop(":testproperty", excel2xml.PropertyElement("2761369", permissions="private", comment="example"))
|
|
1086
787
|
<integer-prop name=":testproperty">
|
|
1087
|
-
<integer permissions="
|
|
788
|
+
<integer permissions="private" comment="example">2761369</integer>
|
|
1088
789
|
</integer-prop>
|
|
1089
790
|
>>> excel2xml.make_integer_prop(":testproperty", ["2761369", "1010101"])
|
|
1090
791
|
<integer-prop name=":testproperty">
|
|
1091
|
-
<integer permissions="
|
|
1092
|
-
<integer permissions="
|
|
792
|
+
<integer permissions="public">2761369</integer>
|
|
793
|
+
<integer permissions="public">1010101</integer>
|
|
1093
794
|
</integer-prop>
|
|
1094
795
|
|
|
1095
796
|
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#integer-prop
|
|
@@ -1138,7 +839,7 @@ def make_list_prop(
|
|
|
1138
839
|
) -> etree._Element:
|
|
1139
840
|
"""
|
|
1140
841
|
Make a `<list-prop>` from one or more list nodes. The name(s) of the list node(s) can be provided as string or as
|
|
1141
|
-
PropertyElement with a string inside. If provided as string, the permissions default to "
|
|
842
|
+
PropertyElement with a string inside. If provided as string, the permissions default to "public".
|
|
1142
843
|
|
|
1143
844
|
Args:
|
|
1144
845
|
list_name: the name of the list as defined in the onto
|
|
@@ -1155,16 +856,16 @@ def make_list_prop(
|
|
|
1155
856
|
Examples:
|
|
1156
857
|
>>> excel2xml.make_list_prop("mylist", ":testproperty", "first_node")
|
|
1157
858
|
<list-prop list="mylist" name=":testproperty">
|
|
1158
|
-
<list permissions="
|
|
859
|
+
<list permissions="public">first_node</list>
|
|
1159
860
|
</list-prop>
|
|
1160
|
-
>>> excel2xml.make_list_prop("mylist", ":testproperty", excel2xml.PropertyElement("first_node", permissions="
|
|
861
|
+
>>> excel2xml.make_list_prop("mylist", ":testproperty", excel2xml.PropertyElement("first_node", permissions="private", comment="example"))
|
|
1161
862
|
<list-prop list="mylist" name=":testproperty">
|
|
1162
|
-
<list permissions="
|
|
863
|
+
<list permissions="private" comment="example">first_node</list>
|
|
1163
864
|
</list-prop>
|
|
1164
865
|
>>> excel2xml.make_list_prop("mylist", ":testproperty", ["first_node", "second_node"])
|
|
1165
866
|
<list-prop list="mylist" name=":testproperty">
|
|
1166
|
-
<list permissions="
|
|
1167
|
-
<list permissions="
|
|
867
|
+
<list permissions="public">first_node</list>
|
|
868
|
+
<list permissions="public">second_node</list>
|
|
1168
869
|
</list-prop>
|
|
1169
870
|
|
|
1170
871
|
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#list-prop
|
|
@@ -1211,7 +912,7 @@ def make_resptr_prop(
|
|
|
1211
912
|
) -> etree._Element:
|
|
1212
913
|
"""
|
|
1213
914
|
Make a `<resptr-prop>` from one or more IDs of other resources. The ID(s) can be provided as string or as
|
|
1214
|
-
PropertyElement with a string inside. If provided as string, the permissions default to "
|
|
915
|
+
PropertyElement with a string inside. If provided as string, the permissions default to "public".
|
|
1215
916
|
|
|
1216
917
|
Args:
|
|
1217
918
|
name: the name of this property as defined in the onto
|
|
@@ -1227,16 +928,16 @@ def make_resptr_prop(
|
|
|
1227
928
|
Examples:
|
|
1228
929
|
>>> excel2xml.make_resptr_prop(":testproperty", "resource_1")
|
|
1229
930
|
<resptr-prop name=":testproperty">
|
|
1230
|
-
<resptr permissions="
|
|
931
|
+
<resptr permissions="public">resource_1</resptr>
|
|
1231
932
|
</resptr-prop>
|
|
1232
|
-
>>> excel2xml.make_resptr_prop(":testproperty", excel2xml.PropertyElement("resource_1", permissions="
|
|
933
|
+
>>> excel2xml.make_resptr_prop(":testproperty", excel2xml.PropertyElement("resource_1", permissions="private", comment="example"))
|
|
1233
934
|
<resptr-prop name=":testproperty">
|
|
1234
|
-
<resptr permissions="
|
|
935
|
+
<resptr permissions="private" comment="example">resource_1</resptr>
|
|
1235
936
|
</resptr-prop>
|
|
1236
937
|
>>> excel2xml.make_resptr_prop(":testproperty", ["resource_1", "resource_2"])
|
|
1237
938
|
<resptr-prop name=":testproperty">
|
|
1238
|
-
<resptr permissions="
|
|
1239
|
-
<resptr permissions="
|
|
939
|
+
<resptr permissions="public">resource_1</resptr>
|
|
940
|
+
<resptr permissions="public">resource_2</resptr>
|
|
1240
941
|
</resptr-prop>
|
|
1241
942
|
|
|
1242
943
|
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#resptr-prop
|
|
@@ -1282,7 +983,7 @@ def make_text_prop(
|
|
|
1282
983
|
) -> etree._Element:
|
|
1283
984
|
"""
|
|
1284
985
|
Make a `<text-prop>` from one or more strings. The string(s) can be provided as string or as PropertyElement with a
|
|
1285
|
-
string inside. If provided as string, the encoding defaults to utf8, and the permissions to "
|
|
986
|
+
string inside. If provided as string, the encoding defaults to utf8, and the permissions to "public".
|
|
1286
987
|
|
|
1287
988
|
Args:
|
|
1288
989
|
name: the name of this property as defined in the onto
|
|
@@ -1300,16 +1001,16 @@ def make_text_prop(
|
|
|
1300
1001
|
Examples:
|
|
1301
1002
|
>>> excel2xml.make_text_prop(":testproperty", "first text")
|
|
1302
1003
|
<text-prop name=":testproperty">
|
|
1303
|
-
<text encoding="utf8" permissions="
|
|
1004
|
+
<text encoding="utf8" permissions="public">first text</text>
|
|
1304
1005
|
</text-prop>
|
|
1305
|
-
>>> excel2xml.make_text_prop(":testproperty", excel2xml.PropertyElement("first text", permissions="
|
|
1006
|
+
>>> excel2xml.make_text_prop(":testproperty", excel2xml.PropertyElement("first text", permissions="private", encoding="xml"))
|
|
1306
1007
|
<text-prop name=":testproperty">
|
|
1307
|
-
<text encoding="xml" permissions="
|
|
1008
|
+
<text encoding="xml" permissions="private">first text</text>
|
|
1308
1009
|
</text-prop>
|
|
1309
1010
|
>>> excel2xml.make_text_prop(":testproperty", ["first text", "second text"])
|
|
1310
1011
|
<text-prop name=":testproperty">
|
|
1311
|
-
<text encoding="utf8" permissions="
|
|
1312
|
-
<text encoding="utf8" permissions="
|
|
1012
|
+
<text encoding="utf8" permissions="public">first text</text>
|
|
1013
|
+
<text encoding="utf8" permissions="public">second text</text>
|
|
1313
1014
|
</text-prop>
|
|
1314
1015
|
|
|
1315
1016
|
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#text-prop
|
|
@@ -1361,7 +1062,6 @@ def make_text_prop(
|
|
|
1361
1062
|
def _add_richtext_to_etree_element(richtext: str, element: etree._Element) -> etree._Element:
|
|
1362
1063
|
new_element = copy.deepcopy(element)
|
|
1363
1064
|
escaped_text = _escape_reserved_chars(richtext)
|
|
1364
|
-
# transform named entities (=character references) to numeric entities, e.g. ->  
|
|
1365
1065
|
num_ent = numeric_entities(escaped_text)
|
|
1366
1066
|
pseudo_xml = f"<ignore-this>{num_ent}</ignore-this>"
|
|
1367
1067
|
try:
|
|
@@ -1436,7 +1136,7 @@ def make_time_prop(
|
|
|
1436
1136
|
"""
|
|
1437
1137
|
Make a `<time-prop>` from one or more datetime values of the form "2009-10-10T12:00:00-05:00". The time(s) can be
|
|
1438
1138
|
provided as string or as PropertyElement with a string inside. If provided as string, the permissions default to
|
|
1439
|
-
"
|
|
1139
|
+
"public".
|
|
1440
1140
|
|
|
1441
1141
|
Args:
|
|
1442
1142
|
name: the name of this property as defined in the onto
|
|
@@ -1452,22 +1152,22 @@ def make_time_prop(
|
|
|
1452
1152
|
Examples:
|
|
1453
1153
|
>>> excel2xml.make_time_prop(":testproperty", "2009-10-10T12:00:00-05:00")
|
|
1454
1154
|
<time-prop name=":testproperty">
|
|
1455
|
-
<time permissions="
|
|
1155
|
+
<time permissions="public">
|
|
1456
1156
|
2009-10-10T12:00:00-05:00
|
|
1457
1157
|
</time>
|
|
1458
1158
|
</time-prop>
|
|
1459
|
-
>>> excel2xml.make_time_prop(":testproperty", excel2xml.PropertyElement("2009-10-10T12:00:00-05:00", permissions="
|
|
1159
|
+
>>> excel2xml.make_time_prop(":testproperty", excel2xml.PropertyElement("2009-10-10T12:00:00-05:00", permissions="private", comment="example"))
|
|
1460
1160
|
<time-prop name=":testproperty">
|
|
1461
|
-
<time permissions="
|
|
1161
|
+
<time permissions="private" comment="example">
|
|
1462
1162
|
2009-10-10T12:00:00-05:00
|
|
1463
1163
|
</time>
|
|
1464
1164
|
</time-prop>
|
|
1465
1165
|
>>> excel2xml.make_time_prop(":testproperty", ["2009-10-10T12:00:00-05:00", "1901-01-01T01:00:00-00:00"])
|
|
1466
1166
|
<time-prop name=":testproperty">
|
|
1467
|
-
<time permissions="
|
|
1167
|
+
<time permissions="public">
|
|
1468
1168
|
2009-10-10T12:00:00-05:00
|
|
1469
1169
|
</time>
|
|
1470
|
-
<time permissions="
|
|
1170
|
+
<time permissions="public">
|
|
1471
1171
|
1901-01-01T01:00:00-00:002
|
|
1472
1172
|
</time>
|
|
1473
1173
|
</time-prop>
|
|
@@ -1516,7 +1216,7 @@ def make_uri_prop(
|
|
|
1516
1216
|
) -> etree._Element:
|
|
1517
1217
|
"""
|
|
1518
1218
|
Make an `<uri-prop>` from one or more URIs. The URI(s) can be provided as string or as PropertyElement with a string
|
|
1519
|
-
inside. If provided as string, the permissions default to "
|
|
1219
|
+
inside. If provided as string, the permissions default to "public".
|
|
1520
1220
|
|
|
1521
1221
|
Args:
|
|
1522
1222
|
name: the name of this property as defined in the onto
|
|
@@ -1532,16 +1232,16 @@ def make_uri_prop(
|
|
|
1532
1232
|
Examples:
|
|
1533
1233
|
>>> excel2xml.make_uri_prop(":testproperty", "www.test.com")
|
|
1534
1234
|
<uri-prop name=":testproperty">
|
|
1535
|
-
<uri permissions="
|
|
1235
|
+
<uri permissions="public">www.test.com</uri>
|
|
1536
1236
|
</uri-prop>
|
|
1537
|
-
>>> excel2xml.make_uri_prop(":testproperty", excel2xml.PropertyElement("www.test.com", permissions="
|
|
1237
|
+
>>> excel2xml.make_uri_prop(":testproperty", excel2xml.PropertyElement("www.test.com", permissions="private", comment="example"))
|
|
1538
1238
|
<uri-prop name=":testproperty">
|
|
1539
|
-
<uri permissions="
|
|
1239
|
+
<uri permissions="private" comment="example">www.test.com</uri>
|
|
1540
1240
|
</uri-prop>
|
|
1541
1241
|
>>> excel2xml.make_uri_prop(":testproperty", ["www.1.com", "www.2.com"])
|
|
1542
1242
|
<uri-prop name=":testproperty">
|
|
1543
|
-
<uri permissions="
|
|
1544
|
-
<uri permissions="
|
|
1243
|
+
<uri permissions="public">www.1.com</uri>
|
|
1244
|
+
<uri permissions="public">www.2.com</uri>
|
|
1545
1245
|
</uri-prop>
|
|
1546
1246
|
|
|
1547
1247
|
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#uri-prop
|
|
@@ -1583,7 +1283,7 @@ def make_uri_prop(
|
|
|
1583
1283
|
def make_region( # noqa: D417 (undocumented-param)
|
|
1584
1284
|
label: str,
|
|
1585
1285
|
id: str,
|
|
1586
|
-
permissions: str = "
|
|
1286
|
+
permissions: str = "public",
|
|
1587
1287
|
ark: Optional[str] = None,
|
|
1588
1288
|
iri: Optional[str] = None,
|
|
1589
1289
|
creation_date: Optional[str] = None,
|
|
@@ -1637,65 +1337,10 @@ def make_region( # noqa: D417 (undocumented-param)
|
|
|
1637
1337
|
)
|
|
1638
1338
|
|
|
1639
1339
|
|
|
1640
|
-
def make_annotation( # noqa: D417 (undocumented-param)
|
|
1641
|
-
label: str,
|
|
1642
|
-
id: str,
|
|
1643
|
-
permissions: str = "res-default",
|
|
1644
|
-
ark: Optional[str] = None,
|
|
1645
|
-
iri: Optional[str] = None,
|
|
1646
|
-
creation_date: Optional[str] = None,
|
|
1647
|
-
) -> etree._Element:
|
|
1648
|
-
"""
|
|
1649
|
-
Creates an empty annotation element, with the attributes as specified by the arguments.
|
|
1650
|
-
|
|
1651
|
-
Args:
|
|
1652
|
-
The arguments correspond 1:1 to the attributes of the `<annotation>` element.
|
|
1653
|
-
|
|
1654
|
-
Raises:
|
|
1655
|
-
Warning: if both an ARK and an IRI are provided
|
|
1656
|
-
BaseError: if the creation date is invalid
|
|
1657
|
-
|
|
1658
|
-
Returns:
|
|
1659
|
-
The annotation element, without any children, but with the attributes
|
|
1660
|
-
`<annotation label=label id=id permissions=permissions ark=ark iri=iri></annotation>`
|
|
1661
|
-
|
|
1662
|
-
Examples:
|
|
1663
|
-
>>> annotation = excel2xml.make_annotation("label", "id")
|
|
1664
|
-
>>> annotation.append(excel2xml.make_text_prop("hasComment", "This is a comment"))
|
|
1665
|
-
>>> annotation.append(excel2xml.make_resptr_prop("isAnnotationOf", "resource_0"))
|
|
1666
|
-
>>> root.append(annotation)
|
|
1667
|
-
|
|
1668
|
-
See https://docs.dasch.swiss/latest/DSP-TOOLS/file-formats/xml-data-file/#annotation
|
|
1669
|
-
"""
|
|
1670
|
-
|
|
1671
|
-
kwargs = {"label": label, "id": id, "permissions": permissions, "nsmap": xml_namespace_map}
|
|
1672
|
-
if ark:
|
|
1673
|
-
kwargs["ark"] = ark
|
|
1674
|
-
if iri:
|
|
1675
|
-
kwargs["iri"] = iri
|
|
1676
|
-
if ark and iri:
|
|
1677
|
-
warning = f"Both ARK and IRI were provided for resource '{label}' ({id}). The ARK will override the IRI."
|
|
1678
|
-
warnings.warn(DspToolsUserWarning(warning))
|
|
1679
|
-
if creation_date:
|
|
1680
|
-
try:
|
|
1681
|
-
DateTimeStamp(creation_date)
|
|
1682
|
-
except BaseError:
|
|
1683
|
-
raise BaseError(
|
|
1684
|
-
f"The annotation '{label}' (ID: {id}) has an invalid creation date '{creation_date}'. "
|
|
1685
|
-
f"Did you perhaps forget the timezone?"
|
|
1686
|
-
) from None
|
|
1687
|
-
kwargs["creation_date"] = creation_date
|
|
1688
|
-
|
|
1689
|
-
return etree.Element(
|
|
1690
|
-
"{%s}annotation" % xml_namespace_map[None],
|
|
1691
|
-
**kwargs, # type: ignore[arg-type]
|
|
1692
|
-
)
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
1340
|
def make_link( # noqa: D417 (undocumented-param)
|
|
1696
1341
|
label: str,
|
|
1697
1342
|
id: str,
|
|
1698
|
-
permissions: str = "
|
|
1343
|
+
permissions: str = "public",
|
|
1699
1344
|
ark: Optional[str] = None,
|
|
1700
1345
|
iri: Optional[str] = None,
|
|
1701
1346
|
creation_date: Optional[str] = None,
|
|
@@ -1750,7 +1395,7 @@ def make_link( # noqa: D417 (undocumented-param)
|
|
|
1750
1395
|
def make_audio_segment( # noqa: D417 (undocumented-param)
|
|
1751
1396
|
label: str,
|
|
1752
1397
|
id: str,
|
|
1753
|
-
permissions: str = "
|
|
1398
|
+
permissions: str = "public",
|
|
1754
1399
|
) -> etree._Element:
|
|
1755
1400
|
"""
|
|
1756
1401
|
Creates an empty `<audio-segment>` element, with the attributes as specified by the arguments.
|
|
@@ -1782,7 +1427,7 @@ def make_audio_segment( # noqa: D417 (undocumented-param)
|
|
|
1782
1427
|
def make_video_segment( # noqa: D417 (undocumented-param)
|
|
1783
1428
|
label: str,
|
|
1784
1429
|
id: str,
|
|
1785
|
-
permissions: str = "
|
|
1430
|
+
permissions: str = "public",
|
|
1786
1431
|
) -> etree._Element:
|
|
1787
1432
|
"""
|
|
1788
1433
|
Creates an empty `<video-segment>` element, with the attributes as specified by the arguments.
|
|
@@ -1812,14 +1457,14 @@ def make_video_segment( # noqa: D417 (undocumented-param)
|
|
|
1812
1457
|
|
|
1813
1458
|
|
|
1814
1459
|
def make_isSegmentOf_prop(
|
|
1815
|
-
target_id: str, permissions: str = "
|
|
1460
|
+
target_id: str, permissions: str = "public", comment: str | None = None, calling_resource: str = ""
|
|
1816
1461
|
) -> etree._Element:
|
|
1817
1462
|
"""
|
|
1818
1463
|
Make a `<isSegmentOf>` property for a `<video-segment>` or `<audio-segment>`.
|
|
1819
1464
|
|
|
1820
1465
|
Args:
|
|
1821
1466
|
target_id: ID of target video/audio resource
|
|
1822
|
-
permissions: defaults to "
|
|
1467
|
+
permissions: defaults to "public".
|
|
1823
1468
|
comment: optional comment for this property. Defaults to None.
|
|
1824
1469
|
calling_resource: the name of the parent resource (for better error messages)
|
|
1825
1470
|
|
|
@@ -1849,14 +1494,14 @@ def make_isSegmentOf_prop(
|
|
|
1849
1494
|
|
|
1850
1495
|
|
|
1851
1496
|
def make_relatesTo_prop(
|
|
1852
|
-
target_id: str, permissions: str = "
|
|
1497
|
+
target_id: str, permissions: str = "public", comment: str | None = None, calling_resource: str = ""
|
|
1853
1498
|
) -> etree._Element:
|
|
1854
1499
|
"""
|
|
1855
1500
|
Make a `<relatesTo>` property for a `<video-segment>` or `<audio-segment>`.
|
|
1856
1501
|
|
|
1857
1502
|
Args:
|
|
1858
1503
|
target_id: ID of the related resource
|
|
1859
|
-
permissions: defaults to "
|
|
1504
|
+
permissions: defaults to "public".
|
|
1860
1505
|
comment: optional comment for this property. Defaults to None.
|
|
1861
1506
|
calling_resource: the name of the parent resource (for better error messages)
|
|
1862
1507
|
|
|
@@ -1889,7 +1534,7 @@ def make_relatesTo_prop(
|
|
|
1889
1534
|
def make_hasSegmentBounds_prop(
|
|
1890
1535
|
segment_start: int | float,
|
|
1891
1536
|
segment_end: int | float,
|
|
1892
|
-
permissions: str = "
|
|
1537
|
+
permissions: str = "public",
|
|
1893
1538
|
comment: str | None = None,
|
|
1894
1539
|
calling_resource: str = "",
|
|
1895
1540
|
) -> etree._Element:
|
|
@@ -1899,7 +1544,7 @@ def make_hasSegmentBounds_prop(
|
|
|
1899
1544
|
Args:
|
|
1900
1545
|
segment_start: start, in seconds, counted from the beginning of the audio/video
|
|
1901
1546
|
segment_end: end, in seconds, counted from the beginning of the audio/video
|
|
1902
|
-
permissions: Defaults to "
|
|
1547
|
+
permissions: Defaults to "public".
|
|
1903
1548
|
comment: Optional comment for this property. Defaults to None.
|
|
1904
1549
|
calling_resource: the name of the parent resource (for better error messages)
|
|
1905
1550
|
|
|
@@ -1916,7 +1561,7 @@ def make_hasSegmentBounds_prop(
|
|
|
1916
1561
|
Returns:
|
|
1917
1562
|
an etree._Element that can be appended to an audio/video segment with `segment.append(make_hasSegmentBounds_prop(...))`
|
|
1918
1563
|
"""
|
|
1919
|
-
if not isinstance(segment_start,
|
|
1564
|
+
if not isinstance(segment_start, int | float) or not isinstance(segment_end, int | float):
|
|
1920
1565
|
try:
|
|
1921
1566
|
segment_start = float(segment_start)
|
|
1922
1567
|
segment_end = float(segment_end)
|
|
@@ -1927,11 +1572,7 @@ def make_hasSegmentBounds_prop(
|
|
|
1927
1572
|
f"but you provided: {segment_start=} and {segment_end=}"
|
|
1928
1573
|
)
|
|
1929
1574
|
warnings.warn(DspToolsUserWarning(msg))
|
|
1930
|
-
if (
|
|
1931
|
-
isinstance(segment_start, (int, float))
|
|
1932
|
-
and isinstance(segment_end, (int, float))
|
|
1933
|
-
and segment_start > segment_end
|
|
1934
|
-
):
|
|
1575
|
+
if isinstance(segment_start, int | float) and isinstance(segment_end, int | float) and segment_start > segment_end:
|
|
1935
1576
|
msg = (
|
|
1936
1577
|
f"Validation Error in resource '{calling_resource}', property 'hasSegmentBounds': "
|
|
1937
1578
|
f"The start of an audio/video segment must be less than the end, "
|
|
@@ -1950,14 +1591,14 @@ def make_hasSegmentBounds_prop(
|
|
|
1950
1591
|
|
|
1951
1592
|
|
|
1952
1593
|
def make_hasTitle_prop(
|
|
1953
|
-
title: str, permissions: str = "
|
|
1594
|
+
title: str, permissions: str = "public", comment: str | None = None, calling_resource: str = ""
|
|
1954
1595
|
) -> etree._Element:
|
|
1955
1596
|
"""
|
|
1956
1597
|
Make a `<hasTitle>` property for a `<video-segment>` or `<audio-segment>`.
|
|
1957
1598
|
|
|
1958
1599
|
Args:
|
|
1959
1600
|
title: the title of the segment
|
|
1960
|
-
permissions: defaults to "
|
|
1601
|
+
permissions: defaults to "public".
|
|
1961
1602
|
comment: optional comment for this property. Defaults to None.
|
|
1962
1603
|
calling_resource: the name of the parent resource (for better error messages)
|
|
1963
1604
|
|
|
@@ -1987,14 +1628,14 @@ def make_hasTitle_prop(
|
|
|
1987
1628
|
|
|
1988
1629
|
|
|
1989
1630
|
def make_hasKeyword_prop(
|
|
1990
|
-
keyword: str, permissions: str = "
|
|
1631
|
+
keyword: str, permissions: str = "public", comment: str | None = None, calling_resource: str = ""
|
|
1991
1632
|
) -> etree._Element:
|
|
1992
1633
|
"""
|
|
1993
1634
|
Make a `<hasKeyword>` property for a `<video-segment>` or `<audio-segment>`.
|
|
1994
1635
|
|
|
1995
1636
|
Args:
|
|
1996
1637
|
keyword: a keyword of the segment
|
|
1997
|
-
permissions: defaults to "
|
|
1638
|
+
permissions: defaults to "public".
|
|
1998
1639
|
comment: optional comment for this property. Defaults to None.
|
|
1999
1640
|
calling_resource: the name of the parent resource (for better error messages)
|
|
2000
1641
|
|
|
@@ -2025,14 +1666,14 @@ def make_hasKeyword_prop(
|
|
|
2025
1666
|
|
|
2026
1667
|
|
|
2027
1668
|
def make_hasComment_prop(
|
|
2028
|
-
comment_text: str, permissions: str = "
|
|
1669
|
+
comment_text: str, permissions: str = "public", comment: str | None = None, calling_resource: str = ""
|
|
2029
1670
|
) -> etree._Element:
|
|
2030
1671
|
"""
|
|
2031
1672
|
Make a `<hasComment>` property for a `<video-segment>` or `<audio-segment>`.
|
|
2032
1673
|
|
|
2033
1674
|
Args:
|
|
2034
1675
|
comment_text: a text with some background info about the segment. Can be formatted with tags.
|
|
2035
|
-
permissions: defaults to "
|
|
1676
|
+
permissions: defaults to "public".
|
|
2036
1677
|
comment: optional comment for this property. Defaults to None.
|
|
2037
1678
|
calling_resource: the name of the parent resource (for better error messages)
|
|
2038
1679
|
|
|
@@ -2063,14 +1704,14 @@ def make_hasComment_prop(
|
|
|
2063
1704
|
|
|
2064
1705
|
|
|
2065
1706
|
def make_hasDescription_prop(
|
|
2066
|
-
description: str, permissions: str = "
|
|
1707
|
+
description: str, permissions: str = "public", comment: str | None = None, calling_resource: str = ""
|
|
2067
1708
|
) -> etree._Element:
|
|
2068
1709
|
"""
|
|
2069
1710
|
Make a `<hasDescription>` property for a `<video-segment>` or `<audio-segment>`.
|
|
2070
1711
|
|
|
2071
1712
|
Args:
|
|
2072
1713
|
description: a text with some background info about the segment. Can be formatted with tags.
|
|
2073
|
-
permissions: defaults to "
|
|
1714
|
+
permissions: defaults to "public".
|
|
2074
1715
|
comment: optional comment for this property. Defaults to None.
|
|
2075
1716
|
calling_resource: the name of the parent resource (for better error messages)
|
|
2076
1717
|
|
|
@@ -2161,7 +1802,7 @@ def create_json_excel_list_mapping(
|
|
|
2161
1802
|
excel_values_new = []
|
|
2162
1803
|
for val in excel_values:
|
|
2163
1804
|
if isinstance(val, str):
|
|
2164
|
-
excel_values_new.extend([x.strip() for x in val.split(sep) if x])
|
|
1805
|
+
excel_values_new.extend([x.strip() for x in val.split(sep) if x.strip()])
|
|
2165
1806
|
|
|
2166
1807
|
# read the list of the JSON project (works also for nested lists)
|
|
2167
1808
|
with open(path_to_json, encoding="utf-8") as f:
|
|
@@ -2287,6 +1928,11 @@ def write_xml(
|
|
|
2287
1928
|
Warning:
|
|
2288
1929
|
if the XML is not valid according to the schema
|
|
2289
1930
|
"""
|
|
1931
|
+
warn_msg = (
|
|
1932
|
+
"The excel2xml lib is deprecated in favor of the xmllib. It will be removed in a future release.\n"
|
|
1933
|
+
"See the xmllib docs: https://docs.dasch.swiss/latest/DSP-TOOLS/xmllib-docs/xmlroot/"
|
|
1934
|
+
)
|
|
1935
|
+
warnings.warn(DspToolsUserWarning(warn_msg))
|
|
2290
1936
|
etree.indent(root, space=" ")
|
|
2291
1937
|
xml_string = etree.tostring(
|
|
2292
1938
|
root,
|
|
@@ -2294,11 +1940,10 @@ def write_xml(
|
|
|
2294
1940
|
pretty_print=True,
|
|
2295
1941
|
doctype='<?xml version="1.0" encoding="UTF-8"?>',
|
|
2296
1942
|
)
|
|
2297
|
-
xml_string = xml_string.replace(r"\'", "'")
|
|
2298
1943
|
with open(filepath, "w", encoding="utf-8") as f:
|
|
2299
1944
|
f.write(xml_string)
|
|
2300
1945
|
try:
|
|
2301
|
-
|
|
1946
|
+
parse_and_validate_xml_file(input_file=filepath)
|
|
2302
1947
|
print(f"The XML file was successfully saved to {filepath}")
|
|
2303
1948
|
except BaseError as err:
|
|
2304
1949
|
msg = (
|