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,318 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
import regex
|
|
6
|
+
|
|
7
|
+
from dsp_tools.commands.get.legacy_models.helpers import ContextType
|
|
8
|
+
from dsp_tools.commands.get.legacy_models.helpers import OntoIri
|
|
9
|
+
from dsp_tools.error.exceptions import BaseError
|
|
10
|
+
from dsp_tools.utils.data_formats.iri_util import is_iri
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ContextIterator:
|
|
14
|
+
_context: Context
|
|
15
|
+
_prefixes: list[str]
|
|
16
|
+
_index: int
|
|
17
|
+
|
|
18
|
+
def __init__(self, context: Context):
|
|
19
|
+
self._context = context
|
|
20
|
+
self._prefixes = list(self._context.context)
|
|
21
|
+
self._index = 0
|
|
22
|
+
|
|
23
|
+
def __next__(self) -> tuple[Optional[str], Optional[OntoIri]]:
|
|
24
|
+
if len(self._context.context) == 0 and self._index == 0:
|
|
25
|
+
return None, None
|
|
26
|
+
elif self._index < len(self._context.context):
|
|
27
|
+
tmp = self._prefixes[self._index]
|
|
28
|
+
self._index += 1
|
|
29
|
+
return tmp, self._context.context[tmp]
|
|
30
|
+
else:
|
|
31
|
+
raise StopIteration
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class Context:
|
|
35
|
+
"""
|
|
36
|
+
This class holds a JSON-LD context with the ontology IRI's and the associated prefixes
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
_context: ContextType
|
|
40
|
+
_rcontext: dict[str, str]
|
|
41
|
+
|
|
42
|
+
common_ontologies = ContextType(
|
|
43
|
+
{
|
|
44
|
+
"foaf": OntoIri("http://xmlns.com/foaf/0.1/", False),
|
|
45
|
+
"dc": OntoIri("http://purl.org/dc/elements/1.1/", False),
|
|
46
|
+
"dcterms": OntoIri("http://purl.org/dc/terms/", False),
|
|
47
|
+
"dcmi": OntoIri("http://purl.org/dc/dcmitype/", False),
|
|
48
|
+
"skos": OntoIri("http://www.w3.org/2004/02/skos/core", True),
|
|
49
|
+
"bibtex": OntoIri("http://purl.org/net/nknouf/ns/bibtex", True),
|
|
50
|
+
"bibo": OntoIri("http://purl.org/ontology/bibo/", False),
|
|
51
|
+
"cidoc": OntoIri("http://purl.org/NET/cidoc-crm/core", True),
|
|
52
|
+
"schema": OntoIri("https://schema.org/", False),
|
|
53
|
+
"edm": OntoIri("http://www.europeana.eu/schemas/edm/", False),
|
|
54
|
+
"ebucore": OntoIri("http://www.ebu.ch/metadata/ontologies/ebucore/ebucore", True),
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
knora_ontologies = ContextType(
|
|
59
|
+
{
|
|
60
|
+
"knora-api": OntoIri("http://api.knora.org/ontology/knora-api/v2", True),
|
|
61
|
+
"salsah-gui": OntoIri("http://api.knora.org/ontology/salsah-gui/v2", True),
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
base_ontologies = ContextType(
|
|
66
|
+
{
|
|
67
|
+
"rdf": OntoIri("http://www.w3.org/1999/02/22-rdf-syntax-ns", True),
|
|
68
|
+
"rdfs": OntoIri("http://www.w3.org/2000/01/rdf-schema", True),
|
|
69
|
+
"owl": OntoIri("http://www.w3.org/2002/07/owl", True),
|
|
70
|
+
"xsd": OntoIri("http://www.w3.org/2001/XMLSchema", True),
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
def __init__(self, context: Optional[dict[str, str]] = None):
|
|
75
|
+
"""
|
|
76
|
+
THe Constructor of the Context. It takes one optional parameter which as a dict of
|
|
77
|
+
prefix - ontology-iri pairs. If the hashtag "#" is used to append element name, the
|
|
78
|
+
ontology-iri *must* end with "#"!
|
|
79
|
+
:param context: A dict of prefix - ontology-iri pairs
|
|
80
|
+
"""
|
|
81
|
+
self._context = ContextType({})
|
|
82
|
+
|
|
83
|
+
# add ontologies from context, if any
|
|
84
|
+
if context:
|
|
85
|
+
for prefix, onto in context.items():
|
|
86
|
+
self._context[prefix] = OntoIri(onto.removesuffix("#"), onto.endswith(("#", "/v2")))
|
|
87
|
+
|
|
88
|
+
# add standard ontologies (rdf, rdfs, owl, xsl)
|
|
89
|
+
for k, v in self.base_ontologies.items():
|
|
90
|
+
if not self._context.get(k):
|
|
91
|
+
self._context[k] = v
|
|
92
|
+
|
|
93
|
+
# add DSP-API internal ontologies (knora-api, salsah-gui)
|
|
94
|
+
for k, v in self.knora_ontologies.items():
|
|
95
|
+
if not self._context.get(k):
|
|
96
|
+
self._context[k] = v
|
|
97
|
+
|
|
98
|
+
self._rcontext = {v.iri: k for k, v in self._context.items()}
|
|
99
|
+
|
|
100
|
+
def __getitem__(self, key: str) -> OntoIri:
|
|
101
|
+
return self._context[key]
|
|
102
|
+
|
|
103
|
+
def __contains__(self, key: str) -> bool:
|
|
104
|
+
return key in self._context
|
|
105
|
+
|
|
106
|
+
def __iter__(self) -> ContextIterator:
|
|
107
|
+
return ContextIterator(self)
|
|
108
|
+
|
|
109
|
+
def __str__(self) -> str:
|
|
110
|
+
output = "Context:\n"
|
|
111
|
+
for prefix, val in self._context.items():
|
|
112
|
+
output += " " + prefix + ": " + val.iri + "\n"
|
|
113
|
+
return output
|
|
114
|
+
|
|
115
|
+
#
|
|
116
|
+
# now we have a lot of getters/setters
|
|
117
|
+
#
|
|
118
|
+
@property
|
|
119
|
+
def context(self) -> ContextType:
|
|
120
|
+
return self._context
|
|
121
|
+
|
|
122
|
+
@context.setter
|
|
123
|
+
def context(self, value: ContextType) -> None:
|
|
124
|
+
"""
|
|
125
|
+
Setter function for the context out of a dict in the form { prefix1 : iri1, prefix2, iri2, …}
|
|
126
|
+
|
|
127
|
+
:param value: Dictionary of context
|
|
128
|
+
:return: None
|
|
129
|
+
"""
|
|
130
|
+
if value is not None and isinstance(value, dict):
|
|
131
|
+
self._context = value
|
|
132
|
+
else:
|
|
133
|
+
raise BaseError("Error in parameter to context setter")
|
|
134
|
+
|
|
135
|
+
def add_context(self, prefix: str, iri: Optional[str] = None) -> None:
|
|
136
|
+
"""
|
|
137
|
+
Add a new context to a context instance
|
|
138
|
+
|
|
139
|
+
:param prefix: The prefix that should be used
|
|
140
|
+
:param iri: The IRI that belongs to this context prefix
|
|
141
|
+
:return: None
|
|
142
|
+
"""
|
|
143
|
+
match iri:
|
|
144
|
+
case None:
|
|
145
|
+
if prefix in self.knora_ontologies:
|
|
146
|
+
return
|
|
147
|
+
elif prefix in self.base_ontologies:
|
|
148
|
+
return
|
|
149
|
+
elif prefix in self.common_ontologies:
|
|
150
|
+
self._context[prefix] = self.common_ontologies[prefix]
|
|
151
|
+
case str():
|
|
152
|
+
if iri.endswith("#"):
|
|
153
|
+
iri = iri[:-1]
|
|
154
|
+
self._context[prefix] = OntoIri(iri, True)
|
|
155
|
+
else:
|
|
156
|
+
self._context[prefix] = OntoIri(iri, False)
|
|
157
|
+
self._rcontext[iri] = prefix
|
|
158
|
+
|
|
159
|
+
def iri_from_prefix(self, prefix: str) -> Optional[str]:
|
|
160
|
+
"""
|
|
161
|
+
Returns the full IRI belonging to this prefix, without trailing "#"!
|
|
162
|
+
|
|
163
|
+
:param prefix: Prefix of the context entry
|
|
164
|
+
:return: The full IRI without trailing "#"
|
|
165
|
+
"""
|
|
166
|
+
# if self.__is_iri(prefix):
|
|
167
|
+
if is_iri(prefix):
|
|
168
|
+
return prefix
|
|
169
|
+
if self._context.get(prefix) is not None:
|
|
170
|
+
return self._context.get(prefix).iri
|
|
171
|
+
else:
|
|
172
|
+
return None
|
|
173
|
+
|
|
174
|
+
def prefix_from_iri(self, iri: str) -> Optional[str]:
|
|
175
|
+
"""
|
|
176
|
+
Get the IRI from a full context that has or has not a trailing "#". It first searches in the normal list
|
|
177
|
+
of contexted. If the iri is not found there, it looks in the list common (external) ontologies. If the
|
|
178
|
+
ontology is found there, this ontology is added to the list of known ontology and it's prefix is returned.
|
|
179
|
+
If nothing is found, None is returns
|
|
180
|
+
|
|
181
|
+
:param iri: The full IRI with or without trailing "#", or
|
|
182
|
+
:return: the prefix of this context element, or None, if not found
|
|
183
|
+
"""
|
|
184
|
+
# if not self.__is_iri(iri):
|
|
185
|
+
if not is_iri(iri):
|
|
186
|
+
raise BaseError("String does not conform to IRI patter: " + iri)
|
|
187
|
+
if iri.endswith("#"):
|
|
188
|
+
iri = iri[:-1]
|
|
189
|
+
result = self._rcontext.get(iri)
|
|
190
|
+
if result is None:
|
|
191
|
+
entrylist = list(filter(lambda x: x[1].iri == iri, self.common_ontologies.items()))
|
|
192
|
+
if len(entrylist) == 1:
|
|
193
|
+
entry = entrylist[0]
|
|
194
|
+
self._context[entry[0]] = entry[1] # add to list of prefixes used
|
|
195
|
+
self._rcontext[entry[1].iri] = entry[0]
|
|
196
|
+
result = entry[0]
|
|
197
|
+
else:
|
|
198
|
+
tmp = iri.split("/")
|
|
199
|
+
if tmp[-1] == "v2":
|
|
200
|
+
#
|
|
201
|
+
# we have a knora ontology name "http://server/ontology/shortcode/shortname/v2"
|
|
202
|
+
self._context[tmp[-2]] = OntoIri(iri, True) # add to list of prefixes used
|
|
203
|
+
self._rcontext[iri] = tmp[-2]
|
|
204
|
+
else:
|
|
205
|
+
raise BaseError("Iri cannot be resolved to a well-known prefix!")
|
|
206
|
+
return result
|
|
207
|
+
|
|
208
|
+
def get_qualified_iri(self, val: Optional[str]) -> Optional[str]:
|
|
209
|
+
"""
|
|
210
|
+
Given an IRI, its fully qualified name is returned.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
val: The input IRI
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
the fully qualified IRI
|
|
217
|
+
"""
|
|
218
|
+
if not val:
|
|
219
|
+
return None
|
|
220
|
+
if is_iri(val):
|
|
221
|
+
return val
|
|
222
|
+
tmp = val.split(":")
|
|
223
|
+
if len(tmp) < 2:
|
|
224
|
+
raise BaseError("There is no separator to identify the prefix: " + val)
|
|
225
|
+
iri_info = self._context.get(tmp[0])
|
|
226
|
+
if iri_info is None:
|
|
227
|
+
entrylist = list(filter(lambda x: x[1].iri == tmp[0], self.common_ontologies.items()))
|
|
228
|
+
if len(entrylist) == 1:
|
|
229
|
+
entry = entrylist[0]
|
|
230
|
+
self._context[entry[0]] = entry[1] # add to list of prefixes used
|
|
231
|
+
self._rcontext[entry[1].iri] = entry[0]
|
|
232
|
+
iri_info = entry[1]
|
|
233
|
+
else:
|
|
234
|
+
raise BaseError("Ontology not known! Cannot generate fully qualified IRI")
|
|
235
|
+
if iri_info.hashtag:
|
|
236
|
+
return iri_info.iri + "#" + tmp[1]
|
|
237
|
+
else:
|
|
238
|
+
return iri_info.iri + tmp[1]
|
|
239
|
+
|
|
240
|
+
def get_prefixed_iri(self, iri: Optional[str]) -> Optional[str]:
|
|
241
|
+
"""
|
|
242
|
+
We reduce a fully qualified IRI to a short one in the form "prefix:name"
|
|
243
|
+
|
|
244
|
+
:param iri: Fully qualified IRI
|
|
245
|
+
:return: Return short from of IRI ("prefix:name")
|
|
246
|
+
"""
|
|
247
|
+
if iri is None:
|
|
248
|
+
return None
|
|
249
|
+
|
|
250
|
+
# check if the iri already has the form "prefix:name"
|
|
251
|
+
m = regex.match("([\\w-]+):([\\w-]+)", iri)
|
|
252
|
+
if m and m.span()[1] == len(iri):
|
|
253
|
+
return iri
|
|
254
|
+
|
|
255
|
+
if not is_iri(iri):
|
|
256
|
+
raise BaseError(f"The IRI '{iri}' does not conform to the IRI pattern.")
|
|
257
|
+
|
|
258
|
+
split_point = iri.find("#")
|
|
259
|
+
if split_point == -1:
|
|
260
|
+
split_point = iri.rfind("/")
|
|
261
|
+
onto_part = iri[: split_point + 1]
|
|
262
|
+
element = iri[split_point + 1 :]
|
|
263
|
+
else:
|
|
264
|
+
onto_part = iri[:split_point]
|
|
265
|
+
element = iri[split_point + 1 :]
|
|
266
|
+
|
|
267
|
+
prefix = self._rcontext.get(onto_part)
|
|
268
|
+
if prefix is None:
|
|
269
|
+
entry_list = list(filter(lambda x: x[1].iri == onto_part, self.common_ontologies.items()))
|
|
270
|
+
if len(entry_list) == 1:
|
|
271
|
+
entry = entry_list[0]
|
|
272
|
+
self._context[entry[0]] = entry[1] # add to list of prefixes used
|
|
273
|
+
self._rcontext[entry[1].iri] = entry[0]
|
|
274
|
+
prefix = entry[0]
|
|
275
|
+
else:
|
|
276
|
+
return None
|
|
277
|
+
return prefix + ":" + element
|
|
278
|
+
|
|
279
|
+
def reduce_iri(self, iri_str: str, onto_name: Optional[str] = None) -> str:
|
|
280
|
+
"""
|
|
281
|
+
Reduces an IRI to the form that is used within the definition JSON file. It expects the context object to have
|
|
282
|
+
entries (prefixes) for all IRIs:
|
|
283
|
+
- if it's an external IRI and the ontology can be extracted as prefix it returns: "prefix:name"
|
|
284
|
+
- if it's in the same ontology, it returns: ":name"
|
|
285
|
+
- if it's a system ontology ("knora-api" or "salsah-gui") it returns: "name"
|
|
286
|
+
- if the IRI can't be reduced, it's returned as is
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
iri_str: the IRI that should be reduced
|
|
290
|
+
onto_name: the name of the ontology
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
The reduced IRI if possible otherwise the fully qualified IRI
|
|
294
|
+
"""
|
|
295
|
+
knora_api = self.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
|
|
296
|
+
salsah_gui = self.prefix_from_iri("http://api.knora.org/ontology/salsah-gui/v2#")
|
|
297
|
+
|
|
298
|
+
if is_iri(iri_str):
|
|
299
|
+
if self.get_prefixed_iri(iri_str):
|
|
300
|
+
iri_str = self.get_prefixed_iri(iri_str)
|
|
301
|
+
tmp = iri_str.split(":")
|
|
302
|
+
if tmp[0] == knora_api or tmp[0] == salsah_gui:
|
|
303
|
+
return tmp[1]
|
|
304
|
+
elif tmp[0] == onto_name:
|
|
305
|
+
return ":" + tmp[1]
|
|
306
|
+
else:
|
|
307
|
+
return iri_str
|
|
308
|
+
|
|
309
|
+
def toJsonObj(self) -> dict[str, str]:
|
|
310
|
+
"""
|
|
311
|
+
Return a python object that can be jsonfied...
|
|
312
|
+
:return: Object to be jsonfied
|
|
313
|
+
"""
|
|
314
|
+
return {prefix: oinfo.iri + "#" if oinfo.hashtag else oinfo.iri for prefix, oinfo in self._context.items()}
|
|
315
|
+
|
|
316
|
+
def get_externals_used(self) -> dict[str, str]:
|
|
317
|
+
exclude = ["rdf", "rdfs", "owl", "xsd", "knora-api", "salsah-gui"]
|
|
318
|
+
return {prefix: onto.iri for prefix, onto in self._context.items() if prefix not in exclude}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module implements the handling (CRUD) of DSP groups.
|
|
3
|
+
|
|
4
|
+
CREATE:
|
|
5
|
+
* Instantiate a new object of the class Group with all required parameters
|
|
6
|
+
* Call the ``create``-method on the instance
|
|
7
|
+
|
|
8
|
+
READ:
|
|
9
|
+
* Instantiate a new object with ``iri``(IRI of group) given
|
|
10
|
+
* Call the ``read``-method on the instance
|
|
11
|
+
* Access the information that has been provided to the instance
|
|
12
|
+
|
|
13
|
+
UPDATE:
|
|
14
|
+
* You need an instance of an existing Project by reading an instance
|
|
15
|
+
* Change the attributes by assigning the new values
|
|
16
|
+
* Call the ``update```method on the instance
|
|
17
|
+
|
|
18
|
+
DELETE
|
|
19
|
+
* Instantiate a new objects with ``iri``(IRI of group) given, or use any instance that has the iri set
|
|
20
|
+
* Call the ``delete``-method on the instance
|
|
21
|
+
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
from typing import Any
|
|
27
|
+
from typing import Optional
|
|
28
|
+
from typing import Union
|
|
29
|
+
from urllib.parse import quote_plus
|
|
30
|
+
|
|
31
|
+
from dsp_tools.clients.connection import Connection
|
|
32
|
+
from dsp_tools.commands.get.legacy_models.model import Model
|
|
33
|
+
from dsp_tools.commands.get.legacy_models.project import Project
|
|
34
|
+
from dsp_tools.error.exceptions import BaseError
|
|
35
|
+
from dsp_tools.legacy_models.langstring import LangString
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Group(Model):
|
|
39
|
+
"""
|
|
40
|
+
This class represents a DSP group
|
|
41
|
+
|
|
42
|
+
Attributes
|
|
43
|
+
----------
|
|
44
|
+
|
|
45
|
+
con : Connection
|
|
46
|
+
A connection instance to a DSP server
|
|
47
|
+
|
|
48
|
+
iri : str
|
|
49
|
+
IRI of the group [get only, cannot be modified after creation of instance]
|
|
50
|
+
|
|
51
|
+
name : str
|
|
52
|
+
Name of the group
|
|
53
|
+
|
|
54
|
+
descriptions : LangString
|
|
55
|
+
Group descriptions in a given language (Languages.EN, Languages.DE, Languages.FR, Languages.IT, Languages.RM).
|
|
56
|
+
|
|
57
|
+
project : str | project
|
|
58
|
+
either the IRI of a project [get only, cannot be modified after creation of instance]
|
|
59
|
+
or an valid Project instance
|
|
60
|
+
|
|
61
|
+
selfjoin : boolean
|
|
62
|
+
A flag indicating if selfjoin is allowed in this group
|
|
63
|
+
|
|
64
|
+
status : boolean
|
|
65
|
+
A flag indicating if the group is active (True) or inactive/makred deleted (False)
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
PROJECT_MEMBER_GROUP: str = "http://www.knora.org/ontology/knora-admin#ProjectMember"
|
|
70
|
+
PROJECT_ADMIN_GROUP: str = "http://www.knora.org/ontology/knora-admin#ProjectAdmin"
|
|
71
|
+
ROUTE: str = "/admin/groups"
|
|
72
|
+
ROUTE_SLASH: str = ROUTE + "/"
|
|
73
|
+
|
|
74
|
+
_iri: Optional[str]
|
|
75
|
+
_name: str | None
|
|
76
|
+
_descriptions: LangString
|
|
77
|
+
_project: str
|
|
78
|
+
_selfjoin: bool
|
|
79
|
+
_status: bool
|
|
80
|
+
|
|
81
|
+
def __init__(
|
|
82
|
+
self,
|
|
83
|
+
con: Connection,
|
|
84
|
+
iri: Optional[str] = None,
|
|
85
|
+
name: Optional[str] = None,
|
|
86
|
+
descriptions: Optional[LangString] = None,
|
|
87
|
+
project: Optional[Union[str, Project]] = None,
|
|
88
|
+
selfjoin: Optional[bool] = None,
|
|
89
|
+
status: Optional[bool] = None,
|
|
90
|
+
) -> None:
|
|
91
|
+
super().__init__(con)
|
|
92
|
+
self._iri = iri
|
|
93
|
+
self._name = str(name) if name is not None else None
|
|
94
|
+
self._descriptions = LangString(descriptions)
|
|
95
|
+
if project is not None and isinstance(project, Project):
|
|
96
|
+
self._project = project.iri
|
|
97
|
+
else:
|
|
98
|
+
self._project = str(project) if project is not None else None
|
|
99
|
+
self._selfjoin = bool(selfjoin) if selfjoin is not None else None
|
|
100
|
+
self._status = bool(status) if status is not None else None
|
|
101
|
+
|
|
102
|
+
@property
|
|
103
|
+
def iri(self) -> Optional[str]:
|
|
104
|
+
return self._iri
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def name(self) -> Optional[str]:
|
|
108
|
+
return self._name
|
|
109
|
+
|
|
110
|
+
@name.setter
|
|
111
|
+
def name(self, value: str) -> None:
|
|
112
|
+
self._name = value
|
|
113
|
+
self._changed.add("name")
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def descriptions(self) -> LangString:
|
|
117
|
+
return self._descriptions
|
|
118
|
+
|
|
119
|
+
@descriptions.setter
|
|
120
|
+
def descriptions(self, value: Optional[LangString]) -> None:
|
|
121
|
+
self._descriptions = LangString(value)
|
|
122
|
+
self._changed.add("descriptions")
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
def project(self) -> str:
|
|
126
|
+
return self._project
|
|
127
|
+
|
|
128
|
+
@property
|
|
129
|
+
def selfjoin(self) -> bool:
|
|
130
|
+
return self._selfjoin
|
|
131
|
+
|
|
132
|
+
@selfjoin.setter
|
|
133
|
+
def selfjoin(self, value: bool) -> None:
|
|
134
|
+
self._selfjoin = value
|
|
135
|
+
self._changed.add("selfjoin")
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def status(self) -> bool:
|
|
139
|
+
return self._status
|
|
140
|
+
|
|
141
|
+
@status.setter
|
|
142
|
+
def status(self, value: bool) -> None:
|
|
143
|
+
self._status = value
|
|
144
|
+
self._changed.add("status")
|
|
145
|
+
|
|
146
|
+
@classmethod
|
|
147
|
+
def fromJsonObj(cls, con: Connection, json_obj: Any) -> Group:
|
|
148
|
+
group_id = json_obj.get("id")
|
|
149
|
+
if group_id is None:
|
|
150
|
+
raise BaseError('Group "id" is missing')
|
|
151
|
+
name = json_obj.get("name")
|
|
152
|
+
if name is None:
|
|
153
|
+
raise BaseError('Group "name" is missing')
|
|
154
|
+
descriptions = LangString.fromJsonObj(json_obj.get("descriptions"))
|
|
155
|
+
tmp = json_obj.get("project")
|
|
156
|
+
if tmp is None:
|
|
157
|
+
raise BaseError('Group "project" is missing')
|
|
158
|
+
project = tmp.get("id")
|
|
159
|
+
if project is None:
|
|
160
|
+
raise BaseError('Group "project" has no "id"')
|
|
161
|
+
selfjoin = json_obj.get("selfjoin")
|
|
162
|
+
if selfjoin is None:
|
|
163
|
+
raise BaseError("selfjoin is missing")
|
|
164
|
+
status = json_obj.get("status")
|
|
165
|
+
if status is None:
|
|
166
|
+
raise BaseError("Status is missing")
|
|
167
|
+
return cls(
|
|
168
|
+
con=con,
|
|
169
|
+
name=name,
|
|
170
|
+
iri=group_id,
|
|
171
|
+
descriptions=descriptions,
|
|
172
|
+
project=project,
|
|
173
|
+
selfjoin=selfjoin,
|
|
174
|
+
status=status,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
def create(self) -> Group:
|
|
178
|
+
jsonobj = self._toJsonObj_create()
|
|
179
|
+
result = self._con.post(Group.ROUTE, jsonobj)
|
|
180
|
+
return Group.fromJsonObj(self._con, result["group"])
|
|
181
|
+
|
|
182
|
+
def _toJsonObj_create(self):
|
|
183
|
+
tmp = {}
|
|
184
|
+
if self._name is None:
|
|
185
|
+
raise BaseError("There must be a valid name!")
|
|
186
|
+
tmp["name"] = self._name
|
|
187
|
+
if not self._descriptions.isEmpty():
|
|
188
|
+
tmp["descriptions"] = self._descriptions.toJsonObj()
|
|
189
|
+
if self._project is None:
|
|
190
|
+
raise BaseError("There must be a valid project!")
|
|
191
|
+
tmp["project"] = self._project
|
|
192
|
+
if self._selfjoin is None:
|
|
193
|
+
raise BaseError("There must be a valid value for selfjoin!")
|
|
194
|
+
tmp["selfjoin"] = self._selfjoin
|
|
195
|
+
if self._status is None:
|
|
196
|
+
raise BaseError("There must be a valid value for status!")
|
|
197
|
+
tmp["status"] = self._status
|
|
198
|
+
return tmp
|
|
199
|
+
|
|
200
|
+
def read(self) -> Group:
|
|
201
|
+
result = self._con.get(Group.ROUTE_SLASH + quote_plus(self._iri))
|
|
202
|
+
return Group.fromJsonObj(self._con, result["group"])
|
|
203
|
+
|
|
204
|
+
def update(self) -> Optional[Group]:
|
|
205
|
+
updated_group = None
|
|
206
|
+
jsonobj = self._toJsonObj_update()
|
|
207
|
+
if jsonobj:
|
|
208
|
+
result = self._con.put(Group.ROUTE_SLASH + quote_plus(self._iri), jsonobj)
|
|
209
|
+
updated_group = Group.fromJsonObj(self._con, result["group"])
|
|
210
|
+
if self._status is not None and "status" in self._changed:
|
|
211
|
+
jsonobj = {"status": self._status}
|
|
212
|
+
result = self._con.put(Group.ROUTE_SLASH + quote_plus(self._iri) + "/status", jsonobj)
|
|
213
|
+
updated_group = Group.fromJsonObj(self._con, result["group"])
|
|
214
|
+
return updated_group
|
|
215
|
+
|
|
216
|
+
def _toJsonObj_update(self) -> dict[str, Any]:
|
|
217
|
+
tmp = {}
|
|
218
|
+
if self._name is not None and "name" in self._changed:
|
|
219
|
+
tmp["name"] = self._name
|
|
220
|
+
if not self._descriptions.isEmpty() and "descriptions" in self._changed:
|
|
221
|
+
tmp["descriptions"] = self._descriptions.toJsonObj()
|
|
222
|
+
if self._selfjoin is not None and "selfjoin" in self._changed:
|
|
223
|
+
tmp["selfjoin"] = self._selfjoin
|
|
224
|
+
return tmp
|
|
225
|
+
|
|
226
|
+
@staticmethod
|
|
227
|
+
def getAllGroups(con: Connection) -> list[Group]:
|
|
228
|
+
result = con.get(Group.ROUTE)
|
|
229
|
+
return [Group.fromJsonObj(con, group_item) for group_item in result["groups"]]
|
|
230
|
+
|
|
231
|
+
@staticmethod
|
|
232
|
+
def getAllGroupsForProject(con: Connection, proj_iri: str) -> list[Group]:
|
|
233
|
+
return [g for g in Group.getAllGroups(con) if g.project == proj_iri]
|
|
234
|
+
|
|
235
|
+
def createDefinitionFileObj(self) -> dict[str, Any]:
|
|
236
|
+
return {
|
|
237
|
+
"name": self.name,
|
|
238
|
+
"descriptions": self.descriptions.createDefinitionFileObj(),
|
|
239
|
+
"selfjoin": self.selfjoin,
|
|
240
|
+
"status": self.status,
|
|
241
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from enum import unique
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True)
|
|
10
|
+
class OntoIri:
|
|
11
|
+
"""
|
|
12
|
+
Holds an ontology IRI
|
|
13
|
+
|
|
14
|
+
Attributes:
|
|
15
|
+
iri: the ontology IRI
|
|
16
|
+
hashtag: True if "#" is used to separate elements, False if element name is appended after "/"
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
iri: str
|
|
20
|
+
hashtag: bool
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
ContextType = dict[str, OntoIri]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@unique
|
|
27
|
+
class Cardinality(Enum):
|
|
28
|
+
C_1 = "1"
|
|
29
|
+
C_0_1 = "0-1"
|
|
30
|
+
C_1_n = "1-n"
|
|
31
|
+
C_0_n = "0-n"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class WithId:
|
|
35
|
+
"""
|
|
36
|
+
Class helper to get json-ld "@id" thingies
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
_tmp: str = None
|
|
40
|
+
|
|
41
|
+
def __init__(self, obj: Optional[dict[str, str]]):
|
|
42
|
+
if obj is None:
|
|
43
|
+
return
|
|
44
|
+
self._tmp = obj.get("@id")
|
|
45
|
+
|
|
46
|
+
def to_string(self) -> Optional[str]:
|
|
47
|
+
return self._tmp
|