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
knora/xml2knora.py
DELETED
|
@@ -1,633 +0,0 @@
|
|
|
1
|
-
from typing import List, Set, Dict, Tuple, Optional, Union
|
|
2
|
-
from enum import Enum
|
|
3
|
-
from lxml import etree
|
|
4
|
-
from pprint import pprint
|
|
5
|
-
import os
|
|
6
|
-
import argparse
|
|
7
|
-
import base64
|
|
8
|
-
import json
|
|
9
|
-
import sys
|
|
10
|
-
import requests
|
|
11
|
-
import re
|
|
12
|
-
from knora import KnoraError, KnoraStandoffXml, Knora, Sipi
|
|
13
|
-
|
|
14
|
-
#==============================================================================
|
|
15
|
-
# Some type defitions
|
|
16
|
-
|
|
17
|
-
#
|
|
18
|
-
# A dictionary with key and values as strings
|
|
19
|
-
#
|
|
20
|
-
StrDict = Dict[str,str]
|
|
21
|
-
|
|
22
|
-
#
|
|
23
|
-
# A thing that can either be a string or StrDict
|
|
24
|
-
#
|
|
25
|
-
StrObj = Union[str,StrDict]
|
|
26
|
-
|
|
27
|
-
#
|
|
28
|
-
# A thing that either can be a single StrObj or a list of StrObj's
|
|
29
|
-
#
|
|
30
|
-
VarStrObj = Union[StrObj,List[StrObj]]
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# https://raw.githubusercontent.com/dhlab-basel/dasch-ark-resolver-data/master/data/shortcodes.csv
|
|
35
|
-
|
|
36
|
-
class MyError(BaseException):
|
|
37
|
-
"""
|
|
38
|
-
Used for error handling
|
|
39
|
-
"""
|
|
40
|
-
def __init__(self, msg: str):
|
|
41
|
-
self.message = msg
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
class KnoraValue:
|
|
45
|
-
"""
|
|
46
|
-
Represents a single knora value
|
|
47
|
-
|
|
48
|
-
A typical value has the form (example for complex text)
|
|
49
|
-
|
|
50
|
-
::
|
|
51
|
-
|
|
52
|
-
<text comment="a comment"
|
|
53
|
-
permissions="permissionId"
|
|
54
|
-
encoding="hex64"
|
|
55
|
-
resrefs="A77|B88">PHA+YnM6IHdhaHJzY2hlaW5sa</text>
|
|
56
|
-
|
|
57
|
-
All options are optional.
|
|
58
|
-
"""
|
|
59
|
-
resrefs: List[str]
|
|
60
|
-
comment: str
|
|
61
|
-
permissions: str
|
|
62
|
-
value: Union[str,KnoraStandoffXml]
|
|
63
|
-
is_richtext: bool
|
|
64
|
-
|
|
65
|
-
def __init__(self,
|
|
66
|
-
context: etree.iterparse,
|
|
67
|
-
node: Tuple,
|
|
68
|
-
type: str,
|
|
69
|
-
listname: Optional[str] = None) -> None:
|
|
70
|
-
"""
|
|
71
|
-
Constructor for parsing a value from a XML DOM
|
|
72
|
-
|
|
73
|
-
:param context: Context for DOM node traversal
|
|
74
|
-
:param node: The DOM node to be processed
|
|
75
|
-
:param type: The Value type ('text','color','date','decimal','geometry','geoname','list', etc.)
|
|
76
|
-
:param listname: Name of the list [optional] (used for list values)
|
|
77
|
-
"""
|
|
78
|
-
|
|
79
|
-
self.resrefs = None
|
|
80
|
-
self.comment = node.get('comment')
|
|
81
|
-
self.permissions = node.get('permissions')
|
|
82
|
-
if node.get('resrefs') is not None:
|
|
83
|
-
self.resrefs = node.attrib['resrefs'].split('|')
|
|
84
|
-
if node.get('encoding') == 'hex64':
|
|
85
|
-
#self.value = KnoraStandoffXml(
|
|
86
|
-
# '<?xml version="1.0" encoding="UTF-8"?>\n<text>' + \
|
|
87
|
-
# base64.b64decode("".join(node.itertext())).decode() + '</text>')
|
|
88
|
-
self.value = '<?xml version="1.0" encoding="UTF-8"?>\n<text>' + \
|
|
89
|
-
base64.b64decode("".join(node.itertext())).decode() + '</text>'
|
|
90
|
-
else:
|
|
91
|
-
if type == 'list':
|
|
92
|
-
self.value = listname + ':' + "".join(node.itertext())
|
|
93
|
-
else:
|
|
94
|
-
self.value = "".join(node.itertext())
|
|
95
|
-
while True:
|
|
96
|
-
event, subnode = next(context)
|
|
97
|
-
if event == 'start':
|
|
98
|
-
raise MyError(
|
|
99
|
-
'Unexpected start tag: "{}" value-tags may contain no other tags!'.format(subnode.tag))
|
|
100
|
-
else:
|
|
101
|
-
if subnode.tag == type:
|
|
102
|
-
break
|
|
103
|
-
else:
|
|
104
|
-
raise MyError('Unexpected end tag: "{}": </{}> expected!'.format(subnode.tag, type))
|
|
105
|
-
|
|
106
|
-
def print(self) -> None:
|
|
107
|
-
"""
|
|
108
|
-
Print value to stdout for debugging...
|
|
109
|
-
|
|
110
|
-
:return: None
|
|
111
|
-
"""
|
|
112
|
-
print(' Value: ' + self.value)
|
|
113
|
-
if self.comment:
|
|
114
|
-
print(' Comment:' + self.comment)
|
|
115
|
-
if self.resrefs is not None:
|
|
116
|
-
for i in self.resrefs:
|
|
117
|
-
print(' resref: ' + i)
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
class KnoraProperty:
|
|
121
|
-
"""
|
|
122
|
-
A class representing a knora property class
|
|
123
|
-
|
|
124
|
-
A typical property node has the form:
|
|
125
|
-
|
|
126
|
-
::
|
|
127
|
-
<text-prop name="mySimpleText">
|
|
128
|
-
…
|
|
129
|
-
</text-prop>
|
|
130
|
-
|
|
131
|
-
The option "name" is required an indicates the name of the knora property.
|
|
132
|
-
"""
|
|
133
|
-
name: str
|
|
134
|
-
type: str
|
|
135
|
-
values: List[KnoraValue]
|
|
136
|
-
|
|
137
|
-
def __init__(self, context: etree.iterparse, node: Tuple, type):
|
|
138
|
-
"""
|
|
139
|
-
Constructor to parse a property class from XML DOM
|
|
140
|
-
|
|
141
|
-
:param context: Context for DOM node traversal
|
|
142
|
-
:param node: The DOM node to be processed (representing a property class)
|
|
143
|
-
:param type: The Value type ('text','color','date','decimal','geometry','geoname','list', etc.)
|
|
144
|
-
"""
|
|
145
|
-
|
|
146
|
-
self.name = node.attrib['name'] # safe the property nam
|
|
147
|
-
listname = node.attrib.get('list') # safe the list name if given (only for lists)
|
|
148
|
-
self.type = type
|
|
149
|
-
self.values = []
|
|
150
|
-
|
|
151
|
-
#
|
|
152
|
-
# Now we start procssing tbe subnodes which should be value nodes
|
|
153
|
-
#
|
|
154
|
-
while True:
|
|
155
|
-
event, subnode = next(context)
|
|
156
|
-
if event == 'start':
|
|
157
|
-
if subnode.tag == type: # the subnode must correspond to the expected value type
|
|
158
|
-
self.values.append(KnoraValue(context, subnode, type, listname))
|
|
159
|
-
else:
|
|
160
|
-
raise MyError('Unexpected start tag: "{}" <property> may contain only <value> tags!'.format(subnode.tag))
|
|
161
|
-
else:
|
|
162
|
-
if subnode.tag == 'text-prop' or subnode.tag == 'color-prop' or \
|
|
163
|
-
subnode.tag == 'date-prop' or subnode.tag == 'decimal-prop' or \
|
|
164
|
-
subnode.tag == 'geometry-prop' or subnode.tag == 'geoname-prop' or \
|
|
165
|
-
subnode.tag == 'list-prop' or subnode.tag == 'iconclass-prop' or \
|
|
166
|
-
subnode.tag == 'integer-prop' or subnode.tag == 'interval-prop' or \
|
|
167
|
-
subnode.tag == 'period-prop' or subnode.tag == 'resptr-prop' or \
|
|
168
|
-
subnode.tag == 'resptr-prop' or subnode.tag == 'time-prop' or \
|
|
169
|
-
subnode.tag == 'uri-prop' or subnode.tag == 'boolean-prop':
|
|
170
|
-
break
|
|
171
|
-
else:
|
|
172
|
-
raise MyError('Unknown endtag for property: "{}"!'.format(subnode.tag))
|
|
173
|
-
|
|
174
|
-
def print(self) -> None:
|
|
175
|
-
"""
|
|
176
|
-
Print property class to stdout for debugging...
|
|
177
|
-
|
|
178
|
-
:return: None
|
|
179
|
-
"""
|
|
180
|
-
print(' Property: {} Type: {}'.format(self.name, self.type))
|
|
181
|
-
for value in self.values:
|
|
182
|
-
value.print()
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
class KnoraResource:
|
|
186
|
-
"""
|
|
187
|
-
A class representing a resource from the XML DOM.
|
|
188
|
-
|
|
189
|
-
A typical resource node looks like follows:
|
|
190
|
-
|
|
191
|
-
::
|
|
192
|
-
|
|
193
|
-
<resource label="obj_inst2"
|
|
194
|
-
restype="MyObject"
|
|
195
|
-
unique_id="obj_0002"
|
|
196
|
-
permissions="res-default">
|
|
197
|
-
|
|
198
|
-
The options ar as follows:
|
|
199
|
-
|
|
200
|
-
label : (required)
|
|
201
|
-
The knora label for the resource
|
|
202
|
-
|
|
203
|
-
restype : (required)
|
|
204
|
-
The resource type as defind in th knora project specific ontology
|
|
205
|
-
|
|
206
|
-
unique_id : (required)
|
|
207
|
-
An arbitrary unique id that ist used to refrencee this this resource from another one
|
|
208
|
-
|
|
209
|
-
permissions : (optional)
|
|
210
|
-
The reference ID of a permission set
|
|
211
|
-
|
|
212
|
-
"""
|
|
213
|
-
unique_id: str
|
|
214
|
-
label: str
|
|
215
|
-
restype: str
|
|
216
|
-
permissions: str
|
|
217
|
-
image: str
|
|
218
|
-
properties: List[KnoraProperty]
|
|
219
|
-
|
|
220
|
-
def __init__(self, context: etree.iterparse, node: Tuple) -> None:
|
|
221
|
-
"""
|
|
222
|
-
Constructor that parses a resource node from the XML DOM
|
|
223
|
-
|
|
224
|
-
:param context: Context for DOM node traversal
|
|
225
|
-
:param node: The DOM node to be processed (representing a resource)
|
|
226
|
-
"""
|
|
227
|
-
self.unique_id = node.attrib['unique_id'] # safe the unique id
|
|
228
|
-
self.label = node.attrib['label']
|
|
229
|
-
self.restype = node.attrib['restype']
|
|
230
|
-
self.permissions = node.attrib['permissions']
|
|
231
|
-
self.image = None
|
|
232
|
-
self.properties = []
|
|
233
|
-
while True:
|
|
234
|
-
#
|
|
235
|
-
# start processing the sub nodes
|
|
236
|
-
#
|
|
237
|
-
event, subnode = next(context)
|
|
238
|
-
if event == 'start':
|
|
239
|
-
if subnode.tag == 'image':
|
|
240
|
-
self.image = node.text
|
|
241
|
-
elif subnode.tag == 'text-prop':
|
|
242
|
-
self.properties.append(KnoraProperty(context, subnode, 'text'))
|
|
243
|
-
elif subnode.tag == 'color-prop':
|
|
244
|
-
self.properties.append(KnoraProperty(context, subnode, 'color'))
|
|
245
|
-
elif subnode.tag == 'date-prop':
|
|
246
|
-
self.properties.append(KnoraProperty(context, subnode, 'date'))
|
|
247
|
-
elif subnode.tag == 'decimal-prop':
|
|
248
|
-
self.properties.append(KnoraProperty(context, subnode, 'decimal'))
|
|
249
|
-
elif subnode.tag == 'geometry-prop':
|
|
250
|
-
self.properties.append(KnoraProperty(context, subnode, 'geometry'))
|
|
251
|
-
elif subnode.tag == 'geoname-prop':
|
|
252
|
-
self.properties.append(KnoraProperty(context, subnode, 'geoname'))
|
|
253
|
-
elif subnode.tag == 'list-prop':
|
|
254
|
-
self.properties.append(KnoraProperty(context, subnode, 'list'))
|
|
255
|
-
elif subnode.tag == 'iconclass-prop':
|
|
256
|
-
self.properties.append(KnoraProperty(context, subnode, 'iconclass'))
|
|
257
|
-
elif subnode.tag == 'integer-prop':
|
|
258
|
-
self.properties.append(KnoraProperty(context, subnode, 'integer'))
|
|
259
|
-
elif subnode.tag == 'interval-prop':
|
|
260
|
-
self.properties.append(KnoraProperty(context, subnode, 'interval'))
|
|
261
|
-
elif subnode.tag == 'period-prop':
|
|
262
|
-
self.properties.append(KnoraProperty(context, subnode, 'period'))
|
|
263
|
-
elif subnode.tag == 'resptr-prop':
|
|
264
|
-
self.properties.append(KnoraProperty(context, subnode, 'resptr'))
|
|
265
|
-
elif subnode.tag == 'time-prop':
|
|
266
|
-
self.properties.append(KnoraProperty(context, subnode, 'time'))
|
|
267
|
-
elif subnode.tag == 'uri-prop':
|
|
268
|
-
self.properties.append(KnoraProperty(context, subnode, 'uri'))
|
|
269
|
-
elif subnode.tag == 'boolean-prop':
|
|
270
|
-
self.properties.append(KnoraProperty(context, subnode, 'boolean'))
|
|
271
|
-
else:
|
|
272
|
-
raise MyError('Unexpected start tag: "{}" <resource> may contain only <property> or <image> tags!'.format(subnode.tag))
|
|
273
|
-
else:
|
|
274
|
-
if subnode.tag == 'resource':
|
|
275
|
-
break
|
|
276
|
-
elif subnode.tag == 'image':
|
|
277
|
-
self.image = "".join(subnode.itertext())
|
|
278
|
-
else:
|
|
279
|
-
raise MyError('Unexpected end tag: "{}" </resource> expected!'.format(subnode.tag))
|
|
280
|
-
|
|
281
|
-
def print(self):
|
|
282
|
-
"""
|
|
283
|
-
Print Resource to stdout for debugging...
|
|
284
|
-
|
|
285
|
-
:return: None
|
|
286
|
-
"""
|
|
287
|
-
print('Resource: id={} restype: {} label: {}'.format(self.unique_id, self.restype, self.label))
|
|
288
|
-
if self.image is not None:
|
|
289
|
-
print(' Image: ' + self.image)
|
|
290
|
-
for property in self.properties:
|
|
291
|
-
property.print()
|
|
292
|
-
|
|
293
|
-
def get_resptrs(self) -> List[str]:
|
|
294
|
-
"""
|
|
295
|
-
Return a list of all reesource id's that a referenced by this rsource
|
|
296
|
-
:return: List of resources identified by their unique id's
|
|
297
|
-
"""
|
|
298
|
-
resptrs: List[str] = []
|
|
299
|
-
for property in self.properties:
|
|
300
|
-
if property.type == 'resptr':
|
|
301
|
-
for value in property.values:
|
|
302
|
-
resptrs.append(value.value)
|
|
303
|
-
elif property.type == 'text':
|
|
304
|
-
for value in property.values:
|
|
305
|
-
if value.resrefs is not None:
|
|
306
|
-
resptrs.extend(value.resrefs)
|
|
307
|
-
return resptrs
|
|
308
|
-
|
|
309
|
-
def get_propvals(self,
|
|
310
|
-
resiri_lookup: StrDict,
|
|
311
|
-
permissions_lookup: StrDict) -> Dict[str, VarStrObj]:
|
|
312
|
-
"""
|
|
313
|
-
A function which retrieves...
|
|
314
|
-
|
|
315
|
-
:param resiri_lookup: Is used to solve internal unique_id's of resourcs to real IRI's
|
|
316
|
-
:param permissions_lookup: Is usd to resolve thee permission ID's to permission sets
|
|
317
|
-
:return: A dict of values with the property name as key and a single value. This dict represents
|
|
318
|
-
the JSON structure that Knora.create_resource() expects.
|
|
319
|
-
"""
|
|
320
|
-
propdata = {}
|
|
321
|
-
exp = re.compile(r'IRI:[^:]*:IRI') # regepx to parse the IRI's in RichText's
|
|
322
|
-
for property in self.properties:
|
|
323
|
-
vals: List[StrObj] = [] # == List[Union[str,StrDict]
|
|
324
|
-
for value in property.values:
|
|
325
|
-
v: str
|
|
326
|
-
if property.type == 'resptr': # we have a resptr, therefore simple lookup or IRI
|
|
327
|
-
iri = resiri_lookup.get(value.value)
|
|
328
|
-
if iri is not None:
|
|
329
|
-
v = iri
|
|
330
|
-
else:
|
|
331
|
-
v = value.value # if we do not find the unique_id, we assume it's a valid knora IRI
|
|
332
|
-
elif property.type == 'text': # we have a text which might have embedded references to other resources
|
|
333
|
-
if isinstance(value.value, KnoraStandoffXml):
|
|
334
|
-
irirefs = value.value.findall() # The IRI's must be embedded as "...IRI:unique_id:IRI..."
|
|
335
|
-
for iriref in irirefs:
|
|
336
|
-
resid = iriref.split(':')[1]
|
|
337
|
-
iri = resiri_lookup.get(resid)
|
|
338
|
-
value.value.replace(iriref, iri)
|
|
339
|
-
#tmpstr: str = value.value
|
|
340
|
-
#for iriref in irirefs:
|
|
341
|
-
# resid = iriref.split(':')[1]
|
|
342
|
-
# iri = resiri_lookup.get(resid)
|
|
343
|
-
# tmpstr.replace(iriref, iri)
|
|
344
|
-
#v = tmpstr
|
|
345
|
-
v = value.value
|
|
346
|
-
else:
|
|
347
|
-
v = value.value
|
|
348
|
-
|
|
349
|
-
if value.comment is None and value.permissions is None:
|
|
350
|
-
# no comment or prmissions
|
|
351
|
-
vals.append(v)
|
|
352
|
-
else:
|
|
353
|
-
# we have comment or permissions
|
|
354
|
-
tmp = {'value': v}
|
|
355
|
-
if value.comment is not None:
|
|
356
|
-
tmp['comment'] = value.comment
|
|
357
|
-
if value.permissions is not None:
|
|
358
|
-
tmp['permissions'] = permissions_lookup.get(value.permissions)
|
|
359
|
-
vals.append(tmp)
|
|
360
|
-
propdata[property.name] = vals if len(vals) > 1 else vals[0] # append a Union[StrObj,List[StrObj]]
|
|
361
|
-
return propdata
|
|
362
|
-
|
|
363
|
-
class Allow:
|
|
364
|
-
"""
|
|
365
|
-
Class representing a single right in a permission set definition
|
|
366
|
-
"""
|
|
367
|
-
group: str
|
|
368
|
-
permission: str
|
|
369
|
-
|
|
370
|
-
def __init__(self, context: etree.iterparse, node: Tuple) -> None:
|
|
371
|
-
"""
|
|
372
|
-
Constructor which parses the XML DOM allow element
|
|
373
|
-
|
|
374
|
-
:param context: Context for DOM node traversal
|
|
375
|
-
:param node: The DOM node to be processed (representing an single right in a permission set)
|
|
376
|
-
"""
|
|
377
|
-
self.group = node.attrib['group']
|
|
378
|
-
self.permission = "".join(node.itertext())
|
|
379
|
-
# UnknownUser | KnownUser | ProjectMember | Creator | ProjectAdmin | SystemAdmin
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
class Permission:
|
|
383
|
-
"""
|
|
384
|
-
A class representing a permission set
|
|
385
|
-
"""
|
|
386
|
-
id: str
|
|
387
|
-
allows: List[Allow]
|
|
388
|
-
|
|
389
|
-
def __init__(self, context: etree.iterparse, node: Tuple) -> None:
|
|
390
|
-
"""
|
|
391
|
-
Constructor which parses a XML DOM permissions element represrenting an named permission set
|
|
392
|
-
|
|
393
|
-
:param context: Context for DOM node traversal
|
|
394
|
-
:param node: The DOM node to be processed (representing an a permission set)
|
|
395
|
-
"""
|
|
396
|
-
self.allows = []
|
|
397
|
-
self.id = node.attrib['id']
|
|
398
|
-
while True:
|
|
399
|
-
event, subnode = next(context)
|
|
400
|
-
if event == 'start':
|
|
401
|
-
if subnode.tag == 'allow':
|
|
402
|
-
self.allows.append(Allow(context, subnode))
|
|
403
|
-
else:
|
|
404
|
-
raise MyError ('Unexpected tag: "{}" <allow> expected!'.format(subnode.tag))
|
|
405
|
-
else:
|
|
406
|
-
if subnode.tag == 'allow':
|
|
407
|
-
pass
|
|
408
|
-
elif subnode.tag == 'resource':
|
|
409
|
-
break
|
|
410
|
-
elif subnode.tag == 'permissions':
|
|
411
|
-
break
|
|
412
|
-
else:
|
|
413
|
-
raise MyError('Unexpected end tag: "{}" </resource> expected!'.format(subnode.tag))
|
|
414
|
-
|
|
415
|
-
def __str__(self):
|
|
416
|
-
allowstrs: List[str] = []
|
|
417
|
-
for allow in self.allows:
|
|
418
|
-
allowstrs.append("{} {}".format(allow.permission, allow.group))
|
|
419
|
-
return '|'.join(allowstrs)
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
def create_permission(con: Knora, permission: Permission) -> str:
|
|
423
|
-
"""
|
|
424
|
-
This function processes a Permission ans returns a Knora compatible permission string and
|
|
425
|
-
transforming/resolving all groupnames using the knora project information
|
|
426
|
-
|
|
427
|
-
:param con: Knora instance
|
|
428
|
-
:param permission: Permission instance
|
|
429
|
-
:return: Knora compatible permission string with resolved group names
|
|
430
|
-
"""
|
|
431
|
-
allowstrs: List[str] = []
|
|
432
|
-
for allow in permission.allows:
|
|
433
|
-
tmp = allow.group.split(':')
|
|
434
|
-
if len(tmp) > 1:
|
|
435
|
-
project_name = tmp[0]
|
|
436
|
-
group_name = tmp[1]
|
|
437
|
-
group_iri = con.get_group_by_pshortname_and_gname(project_name, group_name)
|
|
438
|
-
else:
|
|
439
|
-
group_iri= 'knora-admin:' + tmp[0]
|
|
440
|
-
allowstrs.append("{} {}".format(allow.permission, group_iri))
|
|
441
|
-
return '|'.join(allowstrs)
|
|
442
|
-
|
|
443
|
-
def do_sortorder(resources: List[KnoraResource]) -> List[KnoraResource]:
|
|
444
|
-
"""
|
|
445
|
-
Sort the list of resources such that resources that reference other resources are
|
|
446
|
-
added after the referenced resources. It will fail with an error if there are circular
|
|
447
|
-
references.
|
|
448
|
-
|
|
449
|
-
:param resources: List of resources before sorting
|
|
450
|
-
:return: Sorted list of resources
|
|
451
|
-
"""
|
|
452
|
-
#
|
|
453
|
-
# here we sort the resources according to outgoing resptrs
|
|
454
|
-
#
|
|
455
|
-
ok_resources: [KnoraResource] = []
|
|
456
|
-
notok_resources: [KnoraResource] = []
|
|
457
|
-
ok_resids : [str] = []
|
|
458
|
-
cnt = 0
|
|
459
|
-
notok_len = 9999999
|
|
460
|
-
while len(resources) > 0 and cnt < 10000:
|
|
461
|
-
for resource in resources:
|
|
462
|
-
resptrs = resource.get_resptrs()
|
|
463
|
-
if len(resptrs) == 0:
|
|
464
|
-
ok_resources.append(resource)
|
|
465
|
-
ok_resids.append(resource.unique_id)
|
|
466
|
-
else:
|
|
467
|
-
ok = True
|
|
468
|
-
for resptr in resptrs:
|
|
469
|
-
if resptr in ok_resids:
|
|
470
|
-
pass
|
|
471
|
-
else:
|
|
472
|
-
ok = False;
|
|
473
|
-
if ok:
|
|
474
|
-
ok_resources.append(resource)
|
|
475
|
-
ok_resids.append(resource.unique_id)
|
|
476
|
-
else:
|
|
477
|
-
notok_resources.append(resource)
|
|
478
|
-
resources = notok_resources
|
|
479
|
-
if not len(notok_resources) < notok_len:
|
|
480
|
-
print('Cannot resolve resptr dependencies. Giving up....')
|
|
481
|
-
print(len(notok_resources))
|
|
482
|
-
for r in notok_resources:
|
|
483
|
-
print('Resource {} has unresolvable resptrs to: '.format(r.unique_id), end= ' ')
|
|
484
|
-
for x in r.get_resptrs():
|
|
485
|
-
print(x, end=' ')
|
|
486
|
-
print('')
|
|
487
|
-
print('=============')
|
|
488
|
-
exit(5)
|
|
489
|
-
notok_len = len(notok_resources)
|
|
490
|
-
notok_resources = []
|
|
491
|
-
cnt += 1
|
|
492
|
-
print('{}. Ordering pass Finished!'.format(cnt))
|
|
493
|
-
print('Remaining: {}'.format(len(resources)))
|
|
494
|
-
return ok_resources
|
|
495
|
-
|
|
496
|
-
def program(args) -> None:
|
|
497
|
-
"""
|
|
498
|
-
This is the main program that starts everyting
|
|
499
|
-
|
|
500
|
-
:param args:
|
|
501
|
-
:return:
|
|
502
|
-
"""
|
|
503
|
-
|
|
504
|
-
#
|
|
505
|
-
# first we read the command line options
|
|
506
|
-
#
|
|
507
|
-
parser = argparse.ArgumentParser()
|
|
508
|
-
parser.add_argument("inproject", help="Shortname of project the data should be added to")
|
|
509
|
-
parser.add_argument("-s", "--server", type=str, default="http://0.0.0.0:3333", help="URL of the Knora server")
|
|
510
|
-
parser.add_argument("-S", "--sipi", type=str, default="http://0.0.0.0:1024", help="URL of SIPI server")
|
|
511
|
-
parser.add_argument("-u", "--user", type=str, default="root@example.com", help="Username for Knora")
|
|
512
|
-
parser.add_argument("-p", "--password", type=str, default="test", help="The password for login")
|
|
513
|
-
parser.add_argument("-F", "--folder", default="-", help="Input folder.")
|
|
514
|
-
parser.add_argument("-i", "--infile", default="-", help="Input file.")
|
|
515
|
-
parser.add_argument("-a", "--assets", default="-", help="Assets folder.")
|
|
516
|
-
parser.add_argument("-I", "--images", default="-", help="images folder.")
|
|
517
|
-
parser.add_argument("-V", "--validate", action='store_true', help="Do only validation of JSON, no upload of the ontology")
|
|
518
|
-
args = parser.parse_args(args)
|
|
519
|
-
|
|
520
|
-
current_dir = os.path.dirname(os.path.realpath(__file__))
|
|
521
|
-
|
|
522
|
-
#
|
|
523
|
-
# prepare (create) local directories to store all information
|
|
524
|
-
#
|
|
525
|
-
if args.folder == '-':
|
|
526
|
-
folder = args.inproject + ".dir"
|
|
527
|
-
else:
|
|
528
|
-
folder = args.folder
|
|
529
|
-
|
|
530
|
-
if args.assets == '-':
|
|
531
|
-
assets_path = os.path.join(folder, 'assets')
|
|
532
|
-
else:
|
|
533
|
-
assets_path = args.assets;
|
|
534
|
-
|
|
535
|
-
if args.images == '-':
|
|
536
|
-
images_path = os.path.join(folder, 'images')
|
|
537
|
-
else:
|
|
538
|
-
images_path = args.images
|
|
539
|
-
|
|
540
|
-
if args.infile == '-':
|
|
541
|
-
infile_path = os.path.join(folder, args.inproject) + '.xml'
|
|
542
|
-
else:
|
|
543
|
-
infile_path = args.infile
|
|
544
|
-
|
|
545
|
-
xmlschema_doc = etree.parse(os.path.join(current_dir, 'knora-data-schema.xsd'))
|
|
546
|
-
xmlschema = etree.XMLSchema(xmlschema_doc)
|
|
547
|
-
doc = etree.parse(infile_path)
|
|
548
|
-
xmlschema.assertValid(doc)
|
|
549
|
-
|
|
550
|
-
del xmlschema
|
|
551
|
-
del doc
|
|
552
|
-
del xmlschema_doc
|
|
553
|
-
|
|
554
|
-
print("The imput data file is syntactically correct and passed validation!")
|
|
555
|
-
|
|
556
|
-
if args.validate:
|
|
557
|
-
exit(0)
|
|
558
|
-
|
|
559
|
-
#
|
|
560
|
-
# read the XML file containing the data, including project shortcode
|
|
561
|
-
#
|
|
562
|
-
context: etree.iterparse = etree.iterparse(infile_path, events=("start", "end"))
|
|
563
|
-
resources: List[KnoraResource] = []
|
|
564
|
-
permissions: Dict[str,Permission] = {}
|
|
565
|
-
while True:
|
|
566
|
-
event, node = next(context)
|
|
567
|
-
if event == 'start':
|
|
568
|
-
if node.tag == 'knora':
|
|
569
|
-
ontology = node.attrib['ontology']
|
|
570
|
-
shortcode = node.attrib['shortcode']
|
|
571
|
-
elif event == 'start' and node.tag == 'resource':
|
|
572
|
-
resources.append(KnoraResource(context, node))
|
|
573
|
-
elif event == 'start' and node.tag == 'permissions':
|
|
574
|
-
permission = Permission(context, node)
|
|
575
|
-
permissions[permission.id] = permission
|
|
576
|
-
elif event == 'end':
|
|
577
|
-
if node.tag == 'knora':
|
|
578
|
-
break;
|
|
579
|
-
|
|
580
|
-
context = None # delete XML tree tto save memory
|
|
581
|
-
|
|
582
|
-
#
|
|
583
|
-
# sort the resources so that resources which do not likt to others come first
|
|
584
|
-
#
|
|
585
|
-
resources = do_sortorder(resources)
|
|
586
|
-
|
|
587
|
-
#
|
|
588
|
-
# connect to Knora
|
|
589
|
-
#
|
|
590
|
-
con = Knora(args.server)
|
|
591
|
-
con.login(args.user, args.password)
|
|
592
|
-
|
|
593
|
-
sipi = Sipi(args.sipi, con.get_token())
|
|
594
|
-
|
|
595
|
-
graph = con.get_ontology_graph(shortcode, ontology)
|
|
596
|
-
schema = con.create_schema(shortcode, ontology)
|
|
597
|
-
|
|
598
|
-
permissions_lookup: StrDict = {}
|
|
599
|
-
for p in permissions.items():
|
|
600
|
-
permissions_lookup[p[0]] = create_permission(con, p[1])
|
|
601
|
-
|
|
602
|
-
resiri_lookup: StrDict = {}
|
|
603
|
-
|
|
604
|
-
# cnt: int = 0
|
|
605
|
-
|
|
606
|
-
for resource in resources:
|
|
607
|
-
if resource.image is not None:
|
|
608
|
-
print('Uploading ' + resource.image + '...')
|
|
609
|
-
imgres = sipi.upload_image(resource.image)
|
|
610
|
-
print('Upload done: ' + imgres['uploadedFiles'][0]['internalFilename'])
|
|
611
|
-
fileref = imgres['uploadedFiles'][0]['internalFilename']
|
|
612
|
-
print('Uploading data...')
|
|
613
|
-
resinfo = con.create_resource(schema=schema,
|
|
614
|
-
res_class=resource.restype,
|
|
615
|
-
label=resource.label,
|
|
616
|
-
values=resource.get_propvals(resiri_lookup, permissions_lookup),
|
|
617
|
-
permissions=permissions_lookup.get(resource.permissions),
|
|
618
|
-
stillimage=fileref)
|
|
619
|
-
else:
|
|
620
|
-
resinfo = con.create_resource(schema=schema,
|
|
621
|
-
res_class=resource.restype,
|
|
622
|
-
label=resource.label,
|
|
623
|
-
values=resource.get_propvals(resiri_lookup, permissions_lookup),
|
|
624
|
-
permissions=permissions_lookup.get(resource.permissions))
|
|
625
|
-
resiri_lookup[resource.unique_id] = resinfo['iri']
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
def main():
|
|
629
|
-
program(sys.argv[1:])
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
if __name__ == '__main__':
|
|
633
|
-
program(sys.argv[1:])
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|