dsp-tools 0.9.13__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 +5 -0
- dsp_tools/cli/args.py +47 -0
- dsp_tools/cli/call_action.py +85 -0
- 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 +479 -0
- dsp_tools/cli/entry_point.py +322 -0
- 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/clients/connection.py +35 -0
- 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 +321 -0
- dsp_tools/commands/excel2json/lists/__init__.py +0 -0
- dsp_tools/commands/excel2json/lists/compliance_checks.py +292 -0
- dsp_tools/commands/excel2json/lists/make_lists.py +247 -0
- dsp_tools/commands/excel2json/lists/models/__init__.py +0 -0
- dsp_tools/commands/excel2json/lists/models/deserialise.py +30 -0
- dsp_tools/commands/excel2json/lists/models/input_error.py +216 -0
- dsp_tools/commands/excel2json/lists/models/serialise.py +57 -0
- dsp_tools/commands/excel2json/lists/utils.py +81 -0
- dsp_tools/commands/excel2json/models/__init__.py +0 -0
- dsp_tools/commands/excel2json/models/input_error.py +416 -0
- dsp_tools/commands/excel2json/models/json_header.py +175 -0
- dsp_tools/commands/excel2json/models/list_node_name.py +16 -0
- dsp_tools/commands/excel2json/models/ontology.py +76 -0
- dsp_tools/commands/excel2json/old_lists.py +328 -0
- dsp_tools/commands/excel2json/project.py +280 -0
- dsp_tools/commands/excel2json/properties.py +370 -0
- dsp_tools/commands/excel2json/resources.py +336 -0
- dsp_tools/commands/excel2json/utils.py +352 -0
- dsp_tools/commands/excel2xml/__init__.py +7 -0
- dsp_tools/commands/excel2xml/excel2xml_cli.py +523 -0
- dsp_tools/commands/excel2xml/excel2xml_lib.py +1953 -0
- dsp_tools/commands/excel2xml/propertyelement.py +47 -0
- dsp_tools/commands/get/__init__.py +0 -0
- dsp_tools/commands/get/get.py +166 -0
- dsp_tools/commands/get/get_permissions.py +257 -0
- dsp_tools/commands/get/get_permissions_legacy.py +89 -0
- dsp_tools/commands/get/legacy_models/__init__.py +0 -0
- dsp_tools/commands/get/legacy_models/context.py +318 -0
- dsp_tools/commands/get/legacy_models/group.py +241 -0
- dsp_tools/commands/get/legacy_models/helpers.py +47 -0
- dsp_tools/commands/get/legacy_models/listnode.py +390 -0
- dsp_tools/commands/get/legacy_models/model.py +12 -0
- dsp_tools/commands/get/legacy_models/ontology.py +324 -0
- dsp_tools/commands/get/legacy_models/project.py +366 -0
- dsp_tools/commands/get/legacy_models/propertyclass.py +417 -0
- dsp_tools/commands/get/legacy_models/resourceclass.py +676 -0
- dsp_tools/commands/get/legacy_models/user.py +438 -0
- dsp_tools/commands/get/models/__init__.py +0 -0
- dsp_tools/commands/get/models/permissions_models.py +10 -0
- dsp_tools/commands/id2iri.py +258 -0
- dsp_tools/commands/ingest_xmlupload/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/bulk_ingest_client.py +178 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/apply_ingest_id.py +69 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/upload_xml.py +166 -0
- dsp_tools/commands/ingest_xmlupload/create_resources/user_information.py +121 -0
- dsp_tools/commands/ingest_xmlupload/ingest_files/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/ingest_files/ingest_files.py +64 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/__init__.py +0 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/filechecker.py +20 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/input_error.py +57 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_failures.py +66 -0
- dsp_tools/commands/ingest_xmlupload/upload_files/upload_files.py +67 -0
- dsp_tools/commands/resume_xmlupload/__init__.py +0 -0
- dsp_tools/commands/resume_xmlupload/resume_xmlupload.py +96 -0
- dsp_tools/commands/start_stack.py +428 -0
- 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/validate_data/sparql/cardinality_shacl.py +209 -0
- 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/__init__.py +0 -0
- dsp_tools/commands/xmlupload/iri_resolver.py +21 -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/__init__.py +0 -0
- dsp_tools/commands/xmlupload/models/bitstream_info.py +18 -0
- dsp_tools/commands/xmlupload/models/formatted_text_value.py +10 -0
- dsp_tools/commands/xmlupload/models/ingest.py +143 -0
- dsp_tools/commands/xmlupload/models/input_problems.py +58 -0
- dsp_tools/commands/xmlupload/models/lookup_models.py +21 -0
- dsp_tools/commands/xmlupload/models/permission.py +45 -0
- dsp_tools/commands/xmlupload/models/permissions_parsed.py +93 -0
- 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 +14 -0
- dsp_tools/commands/xmlupload/models/upload_state.py +20 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/__init__.py +0 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/ark2iri.py +55 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/get_processed_resources.py +252 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/iiif_uri_validator.py +50 -0
- dsp_tools/commands/xmlupload/prepare_xml_input/list_client.py +120 -0
- 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 +25 -0
- dsp_tools/commands/xmlupload/richtext_id2iri.py +37 -0
- dsp_tools/commands/xmlupload/stash/__init__.py +0 -0
- dsp_tools/commands/xmlupload/stash/analyse_circular_reference_graph.py +236 -0
- dsp_tools/commands/xmlupload/stash/create_info_for_graph.py +53 -0
- dsp_tools/commands/xmlupload/stash/graph_models.py +87 -0
- dsp_tools/commands/xmlupload/stash/stash_circular_references.py +68 -0
- dsp_tools/commands/xmlupload/stash/stash_models.py +109 -0
- dsp_tools/commands/xmlupload/stash/upload_stashed_resptr_props.py +106 -0
- dsp_tools/commands/xmlupload/stash/upload_stashed_xml_texts.py +196 -0
- dsp_tools/commands/xmlupload/upload_config.py +76 -0
- dsp_tools/commands/xmlupload/write_diagnostic_info.py +27 -0
- dsp_tools/commands/xmlupload/xmlupload.py +516 -0
- dsp_tools/config/__init__.py +0 -0
- dsp_tools/config/logger_config.py +69 -0
- dsp_tools/config/warnings_config.py +32 -0
- 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/legacy_models/datetimestamp.py +81 -0
- dsp_tools/legacy_models/langstring.py +253 -0
- dsp_tools/legacy_models/projectContext.py +49 -0
- dsp_tools/py.typed +0 -0
- dsp_tools/resources/schema/data.xsd +648 -0
- dsp_tools/resources/schema/lists-only.json +72 -0
- dsp_tools/resources/schema/project.json +1258 -0
- dsp_tools/resources/schema/properties-only.json +874 -0
- dsp_tools/resources/schema/resources-only.json +140 -0
- dsp_tools/resources/start-stack/docker-compose.override-host.j2 +11 -0
- dsp_tools/resources/start-stack/docker-compose.override.yml +11 -0
- dsp_tools/resources/start-stack/docker-compose.yml +88 -0
- 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/__init__.py +0 -0
- dsp_tools/utils/ansi_colors.py +32 -0
- dsp_tools/utils/data_formats/__init__.py +0 -0
- dsp_tools/utils/data_formats/date_util.py +166 -0
- dsp_tools/utils/data_formats/iri_util.py +30 -0
- dsp_tools/utils/data_formats/shared.py +81 -0
- dsp_tools/utils/data_formats/uri_util.py +76 -0
- 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/__init__.py +0 -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 +1542 -0
- 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/internal/migration_metadata.py +55 -0
- 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 +348 -0
- dsp_tools/xmllib/value_checkers.py +434 -0
- dsp_tools/xmllib/value_converters.py +777 -0
- 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-18.3.0.post13.dist-info/entry_points.txt +3 -0
- dsp_tools-0.9.13.dist-info/LICENSE +0 -674
- dsp_tools-0.9.13.dist-info/METADATA +0 -144
- dsp_tools-0.9.13.dist-info/RECORD +0 -71
- dsp_tools-0.9.13.dist-info/WHEEL +0 -5
- dsp_tools-0.9.13.dist-info/entry_points.txt +0 -3
- dsp_tools-0.9.13.dist-info/top_level.txt +0 -1
- dsplib/models/connection.py +0 -272
- dsplib/models/group.py +0 -296
- dsplib/models/helpers.py +0 -505
- dsplib/models/langstring.py +0 -277
- dsplib/models/listnode.py +0 -578
- dsplib/models/model.py +0 -20
- dsplib/models/ontology.py +0 -448
- dsplib/models/permission.py +0 -112
- dsplib/models/project.py +0 -547
- dsplib/models/propertyclass.py +0 -505
- dsplib/models/resource.py +0 -366
- dsplib/models/resourceclass.py +0 -810
- dsplib/models/sipi.py +0 -30
- dsplib/models/user.py +0 -731
- dsplib/models/value.py +0 -1000
- dsplib/utils/knora-data-schema.xsd +0 -454
- dsplib/utils/knora-schema-lists.json +0 -83
- dsplib/utils/knora-schema.json +0 -434
- dsplib/utils/onto_commons.py +0 -24
- dsplib/utils/onto_create_lists.py +0 -73
- dsplib/utils/onto_create_ontology.py +0 -442
- dsplib/utils/onto_get.py +0 -58
- dsplib/utils/onto_validate.py +0 -33
- dsplib/utils/xml_upload.py +0 -539
- dsplib/widgets/doublepassword.py +0 -80
- knora/MLS-import-libraries.py +0 -84
- knora/dsp_tools.py +0 -96
- knora/dsplib/models/connection.py +0 -272
- knora/dsplib/models/group.py +0 -296
- knora/dsplib/models/helpers.py +0 -506
- knora/dsplib/models/langstring.py +0 -277
- knora/dsplib/models/listnode.py +0 -578
- knora/dsplib/models/model.py +0 -20
- knora/dsplib/models/ontology.py +0 -448
- knora/dsplib/models/permission.py +0 -112
- knora/dsplib/models/project.py +0 -583
- knora/dsplib/models/propertyclass.py +0 -505
- knora/dsplib/models/resource.py +0 -416
- knora/dsplib/models/resourceclass.py +0 -811
- knora/dsplib/models/sipi.py +0 -35
- knora/dsplib/models/user.py +0 -731
- knora/dsplib/models/value.py +0 -1000
- knora/dsplib/utils/knora-data-schema.xsd +0 -464
- knora/dsplib/utils/knora-schema-lists.json +0 -83
- knora/dsplib/utils/knora-schema.json +0 -444
- knora/dsplib/utils/onto_commons.py +0 -24
- knora/dsplib/utils/onto_create_lists.py +0 -73
- knora/dsplib/utils/onto_create_ontology.py +0 -451
- knora/dsplib/utils/onto_get.py +0 -58
- knora/dsplib/utils/onto_validate.py +0 -33
- knora/dsplib/utils/xml_upload.py +0 -540
- knora/dsplib/widgets/doublepassword.py +0 -80
- knora/knora.py +0 -2108
- knora/test.py +0 -99
- knora/testit.py +0 -76
- knora/xml2knora.py +0 -633
- {dsplib → dsp_tools/cli}/__init__.py +0 -0
- {dsplib/models → dsp_tools/clients}/__init__.py +0 -0
- {dsplib/utils → dsp_tools/commands}/__init__.py +0 -0
- {dsplib/widgets → dsp_tools/commands/create}/__init__.py +0 -0
- {knora → dsp_tools/commands/create/create_on_server}/__init__.py +0 -0
- {knora/dsplib → dsp_tools/commands/create/models}/__init__.py +0 -0
- {knora/dsplib/models → dsp_tools/commands/create/parsing}/__init__.py +0 -0
- {knora/dsplib/utils → dsp_tools/commands/create/serialisation}/__init__.py +0 -0
- {knora/dsplib/widgets → dsp_tools/commands/excel2json}/__init__.py +0 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from dataclasses import field
|
|
6
|
+
from typing import Protocol
|
|
7
|
+
|
|
8
|
+
from dsp_tools.commands.excel2json.models.input_error import ExcelFileProblem
|
|
9
|
+
from dsp_tools.commands.excel2json.models.input_error import PositionInExcel
|
|
10
|
+
from dsp_tools.commands.excel2json.models.input_error import grand_separator
|
|
11
|
+
from dsp_tools.commands.excel2json.models.input_error import list_separator
|
|
12
|
+
from dsp_tools.commands.excel2json.models.input_error import medium_separator
|
|
13
|
+
from dsp_tools.error.problems import Problem
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class ListCreationProblem:
|
|
18
|
+
excel_problems: list[Problem]
|
|
19
|
+
|
|
20
|
+
def execute_error_protocol(self) -> str:
|
|
21
|
+
title = "\nThe excel file(s) used to create the list section have the following problem(s):\n\n"
|
|
22
|
+
msg = [problem.execute_error_protocol() for problem in self.excel_problems]
|
|
23
|
+
return title + grand_separator.join(msg)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class SheetProblem(Protocol):
|
|
28
|
+
excel_name: str
|
|
29
|
+
|
|
30
|
+
def execute_error_protocol(self) -> str:
|
|
31
|
+
raise NotImplementedError
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class CollectedSheetProblems:
|
|
36
|
+
sheet_problems: list[SheetProblem]
|
|
37
|
+
|
|
38
|
+
def execute_error_protocol(self) -> str:
|
|
39
|
+
file_problems = self._group_and_sort_by_excel_name()
|
|
40
|
+
return grand_separator.join([x.execute_error_protocol() for x in file_problems])
|
|
41
|
+
|
|
42
|
+
def _group_and_sort_by_excel_name(self) -> list[ExcelFileProblem]:
|
|
43
|
+
file_dict: dict[str, list[Problem]] = defaultdict(list)
|
|
44
|
+
for problem in self.sheet_problems:
|
|
45
|
+
file_dict[problem.excel_name].append(problem)
|
|
46
|
+
file_list = [ExcelFileProblem(k, v) for k, v in file_dict.items()]
|
|
47
|
+
return sorted(file_list, key=lambda x: x.filename)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dataclass
|
|
51
|
+
class DuplicatesInSheetProblem(SheetProblem):
|
|
52
|
+
excel_name: str
|
|
53
|
+
sheet_name: str
|
|
54
|
+
rows: list[int]
|
|
55
|
+
|
|
56
|
+
def execute_error_protocol(self) -> str:
|
|
57
|
+
msg = [
|
|
58
|
+
f"The excel sheet '{self.sheet_name}' contains rows that are completely identical "
|
|
59
|
+
f"(excluding the column 'ID (optional)'). The following rows are duplicates:"
|
|
60
|
+
]
|
|
61
|
+
msg.extend([f"{x + 2}" for x in self.rows])
|
|
62
|
+
return list_separator.join(msg)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@dataclass
|
|
66
|
+
class MultipleListPerSheetProblem(SheetProblem):
|
|
67
|
+
excel_name: str
|
|
68
|
+
sheet_name: str
|
|
69
|
+
list_names: list[str]
|
|
70
|
+
|
|
71
|
+
def execute_error_protocol(self) -> str:
|
|
72
|
+
return (
|
|
73
|
+
f"Per Excel sheet only one list is allowed.\n"
|
|
74
|
+
f"The sheet '{self.sheet_name}' has more than one list, namely the following: {', '.join(self.list_names)}"
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass
|
|
79
|
+
class ListSheetComplianceProblem(SheetProblem):
|
|
80
|
+
excel_name: str
|
|
81
|
+
sheet_name: str
|
|
82
|
+
problems: list[Problem]
|
|
83
|
+
|
|
84
|
+
def execute_error_protocol(self) -> str:
|
|
85
|
+
msg = [f"The excel sheet '{self.sheet_name}' has the following problem(s):"]
|
|
86
|
+
msg.extend([x.execute_error_protocol() for x in self.problems])
|
|
87
|
+
return list_separator.join(msg)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@dataclass
|
|
91
|
+
class ListSheetContentProblem(SheetProblem):
|
|
92
|
+
excel_name: str
|
|
93
|
+
sheet_name: str
|
|
94
|
+
problems: list[Problem]
|
|
95
|
+
|
|
96
|
+
def execute_error_protocol(self) -> str:
|
|
97
|
+
msg = [f"The Excel sheet '{self.sheet_name}' has the following problem(s):"]
|
|
98
|
+
msg.extend([problem.execute_error_protocol() for problem in self.problems])
|
|
99
|
+
return list_separator.join(msg)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@dataclass
|
|
103
|
+
class MissingTranslationsSheetProblem(SheetProblem):
|
|
104
|
+
excel_name: str
|
|
105
|
+
sheet: str
|
|
106
|
+
node_problems: list[MissingNodeTranslationProblem]
|
|
107
|
+
|
|
108
|
+
def execute_error_protocol(self) -> str:
|
|
109
|
+
msg = [
|
|
110
|
+
f"The excel sheet '{self.sheet}' has the following problem(s):\n"
|
|
111
|
+
"In one list, all the nodes must be translated into all the languages used. "
|
|
112
|
+
"For the following nodes, the translations are missing:"
|
|
113
|
+
]
|
|
114
|
+
nodes_sorted = sorted(self.node_problems, key=lambda x: x.index_num)
|
|
115
|
+
msg.extend([x.execute_error_protocol() for x in nodes_sorted])
|
|
116
|
+
return list_separator.join(msg)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
@dataclass(frozen=True)
|
|
120
|
+
class DuplicatesListNameProblem:
|
|
121
|
+
all_duplicate_names: list[ListInformation]
|
|
122
|
+
|
|
123
|
+
def execute_error_protocol(self) -> str:
|
|
124
|
+
msg = [
|
|
125
|
+
"The name of the list must be unique across all the excel sheets.\n"
|
|
126
|
+
"The following sheets have lists with the same name:"
|
|
127
|
+
]
|
|
128
|
+
sorted_list = sorted(self.all_duplicate_names, key=lambda x: x.excel_name)
|
|
129
|
+
msg.extend([x.execute_error_protocol() for x in sorted_list])
|
|
130
|
+
return list_separator.join(msg)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
@dataclass(frozen=True)
|
|
134
|
+
class ListInformation:
|
|
135
|
+
excel_name: str
|
|
136
|
+
excel_sheet: str
|
|
137
|
+
list_name: str
|
|
138
|
+
|
|
139
|
+
def execute_error_protocol(self) -> str:
|
|
140
|
+
return f"Excel file: '{self.excel_name}', Sheet: '{self.excel_sheet}', List: '{self.list_name}'"
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@dataclass(frozen=True)
|
|
144
|
+
class DuplicatesCustomIDInProblem:
|
|
145
|
+
duplicate_ids: list[DuplicateIDProblem]
|
|
146
|
+
|
|
147
|
+
def execute_error_protocol(self) -> str:
|
|
148
|
+
msg = [
|
|
149
|
+
"No duplicates are allowed in the 'ID (optional)' column. At the following locations, IDs are duplicated:"
|
|
150
|
+
]
|
|
151
|
+
sorted_ids = sorted(self.duplicate_ids, key=lambda x: x.custom_id)
|
|
152
|
+
msg.extend([x.execute_error_protocol() for x in sorted_ids])
|
|
153
|
+
return medium_separator.join(msg)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@dataclass
|
|
157
|
+
class DuplicateIDProblem:
|
|
158
|
+
custom_id: str | int | float = field(default="")
|
|
159
|
+
excel_locations: list[PositionInExcel] = field(default_factory=list)
|
|
160
|
+
|
|
161
|
+
def execute_error_protocol(self) -> str:
|
|
162
|
+
msg = [f"ID: '{self.custom_id}'"]
|
|
163
|
+
msg.extend([str(x) for x in sorted(self.excel_locations, key=lambda x: str(x.excel_filename))])
|
|
164
|
+
return list_separator.join(msg)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
@dataclass(frozen=True)
|
|
168
|
+
class MissingNodeTranslationProblem:
|
|
169
|
+
empty_columns: list[str]
|
|
170
|
+
index_num: int
|
|
171
|
+
|
|
172
|
+
def execute_error_protocol(self) -> str:
|
|
173
|
+
return f"Row Number: {self.index_num + 2} | Column(s): {', '.join(sorted(self.empty_columns))}"
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@dataclass(frozen=True)
|
|
177
|
+
class NodesPerRowProblem:
|
|
178
|
+
column_names: list[str]
|
|
179
|
+
index_num: int
|
|
180
|
+
should_be_empty: bool
|
|
181
|
+
|
|
182
|
+
def execute_error_protocol(self) -> str:
|
|
183
|
+
if self.should_be_empty:
|
|
184
|
+
description = "Column(s) that must be empty"
|
|
185
|
+
else:
|
|
186
|
+
description = "Column(s) that must be filled"
|
|
187
|
+
return f"Row Number: {self.index_num + 2}, {description}: {', '.join(self.column_names)}"
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
@dataclass(frozen=True)
|
|
191
|
+
class MinimumRowsProblem:
|
|
192
|
+
def execute_error_protocol(self) -> str:
|
|
193
|
+
return (
|
|
194
|
+
"The Excel sheet must contain at least two rows, "
|
|
195
|
+
"one for the list name and one row for a minimum of one node."
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
@dataclass(frozen=True)
|
|
200
|
+
class MissingNodeColumn:
|
|
201
|
+
def execute_error_protocol(self) -> str:
|
|
202
|
+
return (
|
|
203
|
+
"At least one column for the node names in the format '[lang]_[column_number]' is required. "
|
|
204
|
+
"The allowed language tags are: en, de, fr, it, rm."
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
@dataclass
|
|
209
|
+
class MissingExpectedColumn:
|
|
210
|
+
missing_cols: set[str]
|
|
211
|
+
|
|
212
|
+
def execute_error_protocol(self) -> str:
|
|
213
|
+
return (
|
|
214
|
+
f"All nodes and lists must be translated into the same languages. "
|
|
215
|
+
f"Based on the languages used, the following column(s) are missing: {', '.join(self.missing_cols)}"
|
|
216
|
+
)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from dataclasses import field
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass
|
|
9
|
+
class ListNode:
|
|
10
|
+
id_: str
|
|
11
|
+
labels: dict[str, str]
|
|
12
|
+
comments: dict[str, str]
|
|
13
|
+
parent_id: str
|
|
14
|
+
sub_nodes: list[ListNode] = field(default_factory=list)
|
|
15
|
+
|
|
16
|
+
def to_dict(self) -> dict[str, Any]:
|
|
17
|
+
node = self._make_own_node()
|
|
18
|
+
if self.sub_nodes:
|
|
19
|
+
node["nodes"] = self._make_subnodes()
|
|
20
|
+
return node
|
|
21
|
+
|
|
22
|
+
def _make_subnodes(self) -> list[dict[str, Any]]:
|
|
23
|
+
return [nd.to_dict() for nd in self.sub_nodes]
|
|
24
|
+
|
|
25
|
+
def _make_own_node(self) -> dict[str, Any]:
|
|
26
|
+
sorted_labels = {k: self.labels[k] for k in sorted(self.labels.keys())}
|
|
27
|
+
d = {"name": self.id_, "labels": sorted_labels}
|
|
28
|
+
if self.comments:
|
|
29
|
+
sorted_comments = {k: self.comments[k] for k in sorted(self.comments.keys())}
|
|
30
|
+
d["comments"] = sorted_comments
|
|
31
|
+
return d
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class ListRoot:
|
|
36
|
+
id_: str
|
|
37
|
+
labels: dict[str, str]
|
|
38
|
+
nodes: list[ListNode]
|
|
39
|
+
comments: dict[str, str]
|
|
40
|
+
|
|
41
|
+
def to_dict(self) -> dict[str, Any]:
|
|
42
|
+
lst_root = self._make_list_root()
|
|
43
|
+
lst_root["nodes"] = self._make_nodes()
|
|
44
|
+
return lst_root
|
|
45
|
+
|
|
46
|
+
def _make_nodes(self) -> list[dict[str, Any]]:
|
|
47
|
+
return [nd.to_dict() for nd in self.nodes]
|
|
48
|
+
|
|
49
|
+
def _make_list_root(self) -> dict[str, Any]:
|
|
50
|
+
sorted_labels = {k: self.labels[k] for k in sorted(self.labels.keys())}
|
|
51
|
+
lst = {"name": self.id_, "labels": sorted_labels}
|
|
52
|
+
if self.comments:
|
|
53
|
+
sorted_comments = {k: self.comments[k] for k in sorted(self.comments.keys())}
|
|
54
|
+
lst["comments"] = sorted_comments
|
|
55
|
+
else:
|
|
56
|
+
lst["comments"] = sorted_labels
|
|
57
|
+
return lst
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
import pandas as pd
|
|
6
|
+
import regex
|
|
7
|
+
|
|
8
|
+
from dsp_tools.commands.excel2json.lists.models.deserialise import ColumnNodes
|
|
9
|
+
from dsp_tools.commands.excel2json.lists.models.deserialise import Columns
|
|
10
|
+
from dsp_tools.error.exceptions import InputError
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_lang_string_from_column_name(col_str: str, ending: str = r"(\d+|list|comments)") -> str | None:
|
|
14
|
+
"""Gets the language tag of one string."""
|
|
15
|
+
if res := regex.search(rf"^(en|de|fr|it|rm)_{ending}$", col_str):
|
|
16
|
+
return res.group(1)
|
|
17
|
+
return None
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_columns_of_preferred_lang(
|
|
21
|
+
columns: pd.Index[str], preferred_language: str, ending: str = r"(\d+|list|comments)"
|
|
22
|
+
) -> list[str]:
|
|
23
|
+
"""Get all the columns that contain the preferred language tag."""
|
|
24
|
+
return sorted(col for col in columns if regex.search(rf"^{preferred_language}_{ending}$", col))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_column_info(df_cols: pd.Index[Any]) -> Columns:
|
|
28
|
+
"""
|
|
29
|
+
Constructs and returns all the columns that should be present in the df based on the languages used.
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
df_cols: columns of the df
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Object with column info
|
|
36
|
+
"""
|
|
37
|
+
hierarchy_nums = get_hierarchy_nums(df_cols)
|
|
38
|
+
all_langs = get_all_languages_for_columns(df_cols)
|
|
39
|
+
preferred_lang = get_preferred_language_from_columns(df_cols)
|
|
40
|
+
node_cols = []
|
|
41
|
+
for n in hierarchy_nums:
|
|
42
|
+
node_cols.append(ColumnNodes(level_num=int(n), columns=[f"{lang}_{n}" for lang in all_langs]))
|
|
43
|
+
comment_cols = []
|
|
44
|
+
if get_all_languages_for_columns(df_cols, r"comments"):
|
|
45
|
+
comment_cols = [f"{lang}_comments" for lang in all_langs]
|
|
46
|
+
list_columns = [f"{lang}_list" for lang in all_langs]
|
|
47
|
+
return Columns(
|
|
48
|
+
preferred_lang=preferred_lang, list_cols=list_columns, comment_cols=comment_cols, node_cols=node_cols
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def get_hierarchy_nums(columns: pd.Index[str]) -> list[int]:
|
|
53
|
+
"""Get all the numbers that are used in the column names that contain a language tag."""
|
|
54
|
+
return sorted(
|
|
55
|
+
list(set(int(res.group(2)) for x in columns if (res := regex.search(r"^(en|de|fr|it|rm)_(\d+)$", x))))
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_all_languages_for_columns(columns: pd.Index[str], ending: str = r"(\d+|list|comments)") -> set[str]:
|
|
60
|
+
"""Get all the language tags for all the columns."""
|
|
61
|
+
return set(res for x in columns if (res := get_lang_string_from_column_name(x, ending)))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_preferred_language_from_columns(columns: pd.Index[str], ending: str = r"(\d+|list|comments)") -> str:
|
|
65
|
+
"""Get the language tag of the preferred language."""
|
|
66
|
+
match = {res.group(1) for x in columns if (res := regex.search(rf"^(en|de|fr|it|rm)_{ending}+$", x))}
|
|
67
|
+
if "en" in match:
|
|
68
|
+
return "en"
|
|
69
|
+
elif "de" in match:
|
|
70
|
+
return "de"
|
|
71
|
+
elif "fr" in match:
|
|
72
|
+
return "fr"
|
|
73
|
+
elif "it" in match:
|
|
74
|
+
return "it"
|
|
75
|
+
elif "rm" in match:
|
|
76
|
+
return "rm"
|
|
77
|
+
msg = (
|
|
78
|
+
f"The columns may only contain the languages: 'en', 'de', 'fr', 'it', 'rm'.\n"
|
|
79
|
+
f"The columns are: {' '.join(columns)}"
|
|
80
|
+
)
|
|
81
|
+
raise InputError(msg)
|
|
File without changes
|