oldaplib 0.3.27__tar.gz → 0.3.29__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {oldaplib-0.3.27 → oldaplib-0.3.29}/PKG-INFO +1 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/ontologies/shared.trig +122 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/connection.py +43 -71
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/datamodel.py +49 -47
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/context.py +3 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/objectfactory.py +145 -20
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/oldaplist.py +2 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/oldaplist_helpers.py +1 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/permissionset.py +26 -10
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/project.py +36 -20
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/user.py +74 -26
- oldaplib-0.3.29/oldaplib/src/version.py +1 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_anyuri.py +4 -4
- oldaplib-0.3.29/oldaplib/test/XXX_test_fasnacht.py +17 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_connection.py +0 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_context.py +4 -2
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_datamodel.py +2 -5
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_externalontologies.py +0 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_hasproperty.py +0 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_objectfactory.py +62 -6
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_oldaplist.py +1 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_oldaplist_helpers.py +1 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_oldaplistnode.py +0 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_permissionset.py +2 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_project.py +0 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_propertyclass.py +0 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_resourceclass.py +1 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_user.py +0 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_xsd_datatypes.py +1 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/instances_test.trig +14 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/pyproject.toml +1 -1
- oldaplib-0.3.27/oldaplib/apps/load_list.py +0 -45
- oldaplib-0.3.27/oldaplib/src/version.py +0 -1
- {oldaplib-0.3.27 → oldaplib-0.3.29}/README.md +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/__init__.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/ontologies/admin-testing.trig +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/ontologies/admin.trig +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/ontologies/example.trig +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/ontologies/oldap.trig +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/ontologies/oldap.ttl +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/ontologies/standard/.gitsave +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/__init__.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/cachesingleton.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/dtypes/__init__.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/dtypes/bnode.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/dtypes/languagein.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/dtypes/namespaceiri.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/dtypes/rdfset.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/dtypes/xsdset.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/__init__.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/action.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/adminpermissions.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/attributeclass.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/datapermissions.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/externalontologyattr.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/haspropertyattr.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/language.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/oldaplistattr.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/oldaplistnodeattr.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/owlpropertytype.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/permissionsetattr.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/projectattr.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/propertyclassattr.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/resourceclassattr.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/sparql_result_format.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/userattr.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/enums/xsd_datatypes.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/externalontology.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/globalconfig.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/hasproperty.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/Notify.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/__init__.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/attributechange.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/convert2datatype.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/irincname.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/json_encoder.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/langstring.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/numeric.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/observable_dict.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/observable_set.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/oldaperror.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/query_processor.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/semantic_version.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/serializeableset.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/serializer.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/singletonmeta.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/helpers/tools.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/iconnection.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/in_project.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/model.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/oldaplistnode.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/oldaplogging.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/propertyclass.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/resourceclass.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/userdataclass.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/__init__.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/floatingpoint.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/iri.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_base64binary.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_boolean.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_byte.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_date.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_datetime.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_datetimestamp.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_decimal.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_double.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_duration.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_float.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_gday.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_gmonth.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_gmonthday.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_gyear.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_gyearmonth.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_hexbinary.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_id.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_idref.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_int.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_integer.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_language.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_long.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_name.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_ncname.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_negativeinteger.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_nmtoken.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_nonnegativeinteger.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_nonpositiveinteger.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_normalizedstring.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_positiveinteger.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_qname.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_short.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_string.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_time.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_token.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_unsignedbyte.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_unsignedint.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_unsignedlong.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/src/xsd/xsd_unsignedshort.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/__init__.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_cache.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_dtypes.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_in_project.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_langstring.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_language_in.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_observable_dict.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_observable_set.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/test/test_semantic_version.py +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/Gender.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/collections_type.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/connection_test.trig +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/datamodel_test.trig +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/event_type.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/hlist_schema.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/institution_or_building_type.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/language.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/location_type.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/means_of_transportation.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/objectfactory_test.trig +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/playground_list.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/role.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/source_type-1.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/source_type.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/test_move_left_of_toL.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testdata/testlist.yaml +0 -0
- {oldaplib-0.3.27 → oldaplib-0.3.29}/oldaplib/testit.http +0 -0
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
@prefix sh: <http://www.w3.org/ns/shacl#> .
|
|
5
5
|
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
|
6
6
|
@prefix dcterms: <http://purl.org/dc/terms/> .
|
|
7
|
+
@prefix dcmitype: <http://purl.org/dc/dcmitype/> .
|
|
7
8
|
@prefix schema: <http://schema.org/> .
|
|
8
9
|
@prefix oldap: <http://oldap.org/base#> .
|
|
9
10
|
|
|
@@ -109,6 +110,90 @@ shared:shacl {
|
|
|
109
110
|
# Media object
|
|
110
111
|
###############################################################################
|
|
111
112
|
|
|
113
|
+
# dcmitype:CollectionShape a sh:NodeShape ;
|
|
114
|
+
# sh:targetClass shared:Collection ;
|
|
115
|
+
# dcterms:created "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
116
|
+
# dcterms:creator <https://orcid.org/0000-0003-1681-4036> ;
|
|
117
|
+
# dcterms:modified "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
118
|
+
# dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
|
|
119
|
+
# oldap:externalOntology "true"^^xsd:boolean ;
|
|
120
|
+
# rdfs:label "Collection"@en, "Sammlung"@de, "Collection"@fr, "Collezione"@it ;
|
|
121
|
+
# sh:property [
|
|
122
|
+
# sh:path rdf:type ;
|
|
123
|
+
# ] .
|
|
124
|
+
#
|
|
125
|
+
# dcmitype:DatasetShape a sh:NodeShape ;
|
|
126
|
+
# sh:targetClass shared:Dataset ;
|
|
127
|
+
# dcterms:created "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
128
|
+
# dcterms:creator <https://orcid.org/0000-0003-1681-4036> ;
|
|
129
|
+
# dcterms:modified "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
130
|
+
# dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
|
|
131
|
+
# oldap:externalOntology "true"^^xsd:boolean ;
|
|
132
|
+
# rdfs:label "Dataset"@en, "Dataset"@de, "Dataset"@fr, "Dataset"@it ;
|
|
133
|
+
# sh:property [
|
|
134
|
+
# sh:path rdf:type ;
|
|
135
|
+
# ] .
|
|
136
|
+
#
|
|
137
|
+
# dcmitype:StillImageShape a sh:NodeShape ;
|
|
138
|
+
# sh:targetClass shared:StillImage ;
|
|
139
|
+
# dcterms:created "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
140
|
+
# dcterms:creator <https://orcid.org/0000-0003-1681-4036> ;
|
|
141
|
+
# dcterms:modified "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
142
|
+
# dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
|
|
143
|
+
# oldap:externalOntology "true"^^xsd:boolean ;
|
|
144
|
+
# rdfs:label "StillImage"@en, "Standbild"@de, "Image fixe"@fr, "Immagine fissa"@it ;
|
|
145
|
+
# sh:property [
|
|
146
|
+
# sh:path rdf:type ;
|
|
147
|
+
# ] .
|
|
148
|
+
#
|
|
149
|
+
# dcmitype:ImageShape a sh:NodeShape ;
|
|
150
|
+
# sh:targetClass shared:Image ;
|
|
151
|
+
# dcterms:created "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
152
|
+
# dcterms:creator <https://orcid.org/0000-0003-1681-4036> ;
|
|
153
|
+
# dcterms:modified "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
154
|
+
# dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
|
|
155
|
+
# oldap:externalOntology "true"^^xsd:boolean ;
|
|
156
|
+
# rdfs:label "Image"@en, "Bild"@de, "Image"@fr, "Immagine"@it ;
|
|
157
|
+
# sh:property [
|
|
158
|
+
# sh:path rdf:type ;
|
|
159
|
+
# ] .
|
|
160
|
+
#
|
|
161
|
+
# dcmitype:MovingImageShape a sh:NodeShape ;
|
|
162
|
+
# sh:targetClass shared:MovingImage ;
|
|
163
|
+
# dcterms:created "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
164
|
+
# dcterms:creator <https://orcid.org/0000-0003-1681-4036> ;
|
|
165
|
+
# dcterms:modified "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
166
|
+
# dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
|
|
167
|
+
# oldap:externalOntology "true"^^xsd:boolean ;
|
|
168
|
+
# rdfs:label "MovingImage"@en, "Bewegtbild"@de, "Image animée"@fr, "Immagine in movimento"@it ;
|
|
169
|
+
# sh:property [
|
|
170
|
+
# sh:path rdf:type ;
|
|
171
|
+
# ] .
|
|
172
|
+
#
|
|
173
|
+
# dcmitype:SoundShape a sh:NodeShape ;
|
|
174
|
+
# sh:targetClass shared:Sound ;
|
|
175
|
+
# dcterms:created "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
176
|
+
# dcterms:creator <https://orcid.org/0000-0003-1681-4036> ;
|
|
177
|
+
# dcterms:modified "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
178
|
+
# dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
|
|
179
|
+
# oldap:externalOntology "true"^^xsd:boolean ;
|
|
180
|
+
# rdfs:label "Sound"@en, "Ton"@de, "Son"@fr, "Sound"@it ;
|
|
181
|
+
# sh:property [
|
|
182
|
+
# sh:path rdf:type ;
|
|
183
|
+
# ] .
|
|
184
|
+
#
|
|
185
|
+
# dcmitype:TextShape a sh:NodeShape ;
|
|
186
|
+
# sh:targetClass shared:Text ;
|
|
187
|
+
# dcterms:created "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
188
|
+
# dcterms:creator <https://orcid.org/0000-0003-1681-4036> ;
|
|
189
|
+
# dcterms:modified "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
190
|
+
# dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
|
|
191
|
+
# oldap:externalOntology "true"^^xsd:boolean ;
|
|
192
|
+
# rdfs:label "Text"@en, "Text"@de, "Texte"@fr, "Testo"@it ;
|
|
193
|
+
# sh:property [
|
|
194
|
+
# sh:path rdf:type ;
|
|
195
|
+
# ] .
|
|
196
|
+
|
|
112
197
|
shared:MediaObjectShape a sh:NodeShape ;
|
|
113
198
|
sh:targetClass shared:MediaObject ;
|
|
114
199
|
dcterms:created "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
@@ -117,12 +202,33 @@ shared:shacl {
|
|
|
117
202
|
dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
|
|
118
203
|
oldap:externalOntology "false"^^xsd:boolean ;
|
|
119
204
|
rdfs:label "MediaObject"@en, "Medienobjekt"@de, "MediaObject"@fr, "MediaObject"@it ;
|
|
120
|
-
rdfs:comment "Page of a book"@en, "Seite eines Buches"@de ;
|
|
121
205
|
sh:closed "true"^^xsd:boolean ;
|
|
122
206
|
sh:node oldap:ThingShape ;
|
|
123
207
|
sh:property [
|
|
124
208
|
sh:path rdf:type ;
|
|
125
209
|
] ;
|
|
210
|
+
sh:property [
|
|
211
|
+
sh:path dcterms:type ;
|
|
212
|
+
dcterms:creator <https://orcid.org/0000-0003-1681-4036> ;
|
|
213
|
+
dcterms:created "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
214
|
+
dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
|
|
215
|
+
dcterms:modified "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
216
|
+
oldap:statementProperty "false"^^xsd:boolean ;
|
|
217
|
+
oldap:externalOntology "false"^^xsd:boolean ;
|
|
218
|
+
sh:nodeKind sh:IRI ;
|
|
219
|
+
sh:in (
|
|
220
|
+
dcmitype:Collection
|
|
221
|
+
dcmitype:Dataset
|
|
222
|
+
dcmitype:StillImage
|
|
223
|
+
dcmitype:Image
|
|
224
|
+
dcmitype:MovingImage
|
|
225
|
+
dcmitype:Sound
|
|
226
|
+
dcmitype:Text
|
|
227
|
+
) ;
|
|
228
|
+
sh:minCount 1 ;
|
|
229
|
+
sh:maxCount 1 ;
|
|
230
|
+
sh:order "0.5"^^xsd:decimal ;
|
|
231
|
+
] ;
|
|
126
232
|
sh:property [
|
|
127
233
|
sh:path shared:originalName ;
|
|
128
234
|
schema:version "0.1.0"^^xsd:string ;
|
|
@@ -344,6 +450,15 @@ shared:onto {
|
|
|
344
450
|
# Media object
|
|
345
451
|
###########################################################################
|
|
346
452
|
|
|
453
|
+
# shared:mediaType rdf:type owl:ObjectProperty ;
|
|
454
|
+
# dcterms:creator <https://orcid.org/0000-0003-1681-4036> ;
|
|
455
|
+
# dcterms:created "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime ;
|
|
456
|
+
# dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
|
|
457
|
+
# dcterms:modified "2025-11-21T00:15:09.037880+01:00"^^xsd:dateTime .
|
|
458
|
+
# #owl:subPropertyOf dcterms:type ;
|
|
459
|
+
# rdfs:domain shared:MediaObject ;
|
|
460
|
+
# rdfs:range rdfs:Class ;
|
|
461
|
+
|
|
347
462
|
shared:originalName rdf:type owl:DatatypeProperty ;
|
|
348
463
|
rdfs:domain shared:MediaObject ;
|
|
349
464
|
rdfs:range xsd:string ;
|
|
@@ -401,6 +516,12 @@ shared:onto {
|
|
|
401
516
|
rdfs:label "MediaObject"@en, "Medienobjekt"@de, "MediaObject"@fr, "MediaObject"@it ;
|
|
402
517
|
rdfs:comment "Page of a book"@en, "Seite eines Buches"@de ;
|
|
403
518
|
rdfs:subClassOf oldap:Thing ,
|
|
519
|
+
[
|
|
520
|
+
rdf:type owl:Restriction ;
|
|
521
|
+
owl:onProperty dcterms:type ;
|
|
522
|
+
owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger ;
|
|
523
|
+
owl:onClass rdfs:Class ;
|
|
524
|
+
] ,
|
|
404
525
|
[
|
|
405
526
|
rdf:type owl:Restriction ;
|
|
406
527
|
owl:onProperty shared:originalName ;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
|
-
|
|
3
|
+
import time
|
|
4
4
|
|
|
5
5
|
import bcrypt
|
|
6
6
|
import jwt
|
|
@@ -338,80 +338,52 @@ class Connection(IConnection):
|
|
|
338
338
|
if not req.ok:
|
|
339
339
|
raise OldapError(req.text)
|
|
340
340
|
|
|
341
|
+
|
|
342
|
+
|
|
341
343
|
def upload_turtle(self, filename: str, graphname: Optional[str] = None) -> None:
|
|
342
344
|
"""
|
|
343
|
-
|
|
344
|
-
import and does not wait for the completion of the import process. The process itself may continue for some time
|
|
345
|
-
after the command is issued.
|
|
346
|
-
|
|
347
|
-
:param filename: Name of the file to be uploaded.
|
|
348
|
-
:type filename: str
|
|
349
|
-
:param graphname: Optional; the name of the RDF-graph into which the data is to be imported.
|
|
350
|
-
:type graphname: str or None
|
|
351
|
-
:return: None
|
|
352
|
-
:rtype: None
|
|
353
|
-
:raises OldapError: Raised when there are issues with the repository or during the HTTP request.
|
|
354
|
-
"""
|
|
355
|
-
# if not self._userdata:
|
|
356
|
-
# raise OldapErrorNoPermission("No permission")
|
|
357
|
-
# actor = self._userdata
|
|
358
|
-
# sysperms = actor.inProject.get(QName('oldap:SystemProject'))
|
|
359
|
-
# is_root: bool = False
|
|
360
|
-
# if sysperms and AdminPermission.ADMIN_OLDAP in sysperms:
|
|
361
|
-
# is_root = True
|
|
362
|
-
# if not is_root:
|
|
363
|
-
# raise OldapErrorNoPermission("No permission")
|
|
345
|
+
Upload a TTL/TRiG file to GraphDB using the RDF4J /statements endpoint.
|
|
364
346
|
|
|
347
|
+
This call is synchronous: when it returns without error, the data is loaded.
|
|
348
|
+
"""
|
|
365
349
|
logger = get_logger()
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
mime = ""
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
data =
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
"Content-Type": "application/json; charset=utf-8"
|
|
404
|
-
}
|
|
405
|
-
url = f"{self._server}/rest/repositories/{self._repo}/import/upload/text"
|
|
406
|
-
auth = HTTPBasicAuth(self._dbuser, self._dbpassword) if self._dbuser and self._dbpassword else None
|
|
407
|
-
req = requests.post(url,
|
|
408
|
-
headers=headers,
|
|
409
|
-
data=jsondata,
|
|
410
|
-
auth=auth)
|
|
411
|
-
if not req.ok:
|
|
412
|
-
logger.error(f'Upload of file "{filename}" failed: {req.text}')
|
|
413
|
-
raise OldapError(req.text)
|
|
414
|
-
logger.info(f'File "{filename}" uploaded.')
|
|
350
|
+
|
|
351
|
+
ext = Path(filename).suffix.lower()
|
|
352
|
+
if ext == ".ttl":
|
|
353
|
+
mime = "text/turtle"
|
|
354
|
+
elif ext == ".trig":
|
|
355
|
+
# use the standard MIME type for TriG
|
|
356
|
+
mime = "application/trig"
|
|
357
|
+
else:
|
|
358
|
+
raise OldapError(f"Unsupported RDF extension: {ext}")
|
|
359
|
+
|
|
360
|
+
with open(filename, "rb") as f:
|
|
361
|
+
data = f.read()
|
|
362
|
+
|
|
363
|
+
# RDF4J / GraphDB statements endpoint
|
|
364
|
+
url = f"{self._server.rstrip('/')}/repositories/{self._repo}/statements"
|
|
365
|
+
|
|
366
|
+
# Optional context: only use this if you really want to force
|
|
367
|
+
# all triples into a single named graph. For TriG you usually
|
|
368
|
+
# leave this empty so the quads' graph IRIs are respected.
|
|
369
|
+
params = {}
|
|
370
|
+
if graphname:
|
|
371
|
+
# GraphDB expects the context IRI wrapped in < > and URL-encoded
|
|
372
|
+
params["context"] = f"<{graphname}>"
|
|
373
|
+
|
|
374
|
+
auth = HTTPBasicAuth(self._dbuser, self._dbpassword) if self._dbuser and self._dbpassword else None
|
|
375
|
+
headers = {
|
|
376
|
+
"Content-Type": mime,
|
|
377
|
+
"Accept": "text/plain" # or */*, result body is usually empty
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
resp = requests.post(url, params=params, headers=headers, data=data, auth=auth)
|
|
381
|
+
|
|
382
|
+
if not resp.ok:
|
|
383
|
+
logger.error(f'Upload of file "{filename}" failed: {resp.status_code} {resp.text}')
|
|
384
|
+
raise OldapError(resp.text)
|
|
385
|
+
|
|
386
|
+
logger.info(f'File "{filename}" uploaded synchronously via /statements.')
|
|
415
387
|
|
|
416
388
|
def query(self, query: str, format: SparqlResultFormat = SparqlResultFormat.JSON) -> Any:
|
|
417
389
|
"""
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import io
|
|
1
2
|
from copy import deepcopy
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
from datetime import datetime
|
|
4
|
-
from typing import Dict, List, Optional, Union, Any, Self
|
|
5
|
+
from typing import Dict, List, Optional, Union, Any, Self, TextIO
|
|
5
6
|
|
|
6
7
|
from oldaplib.src.cachesingleton import CacheSingleton, CacheSingletonRedis
|
|
7
8
|
from oldaplib.src.dtypes.namespaceiri import NamespaceIRI
|
|
@@ -723,57 +724,58 @@ class DataModel(Model):
|
|
|
723
724
|
cache = CacheSingletonRedis()
|
|
724
725
|
cache.delete(Xsd_QName(self._project.projectShortName, 'shacl'))
|
|
725
726
|
|
|
726
|
-
|
|
727
|
-
def write_as_trig(self, filename: str, indent: int = 0, indent_inc: int = 4) -> None:
|
|
727
|
+
def __to_trig_format(self, f: TextIO, indent: int = 0, indent_inc: int = 4) -> None:
|
|
728
728
|
"""
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
:
|
|
738
|
-
|
|
739
|
-
to 0
|
|
740
|
-
:type indent: int
|
|
741
|
-
:param indent_inc: Number of characters to increment for each indent
|
|
742
|
-
level. Defaults to 4
|
|
743
|
-
:type indent_inc: int
|
|
729
|
+
Generates and writes TriG-formatted RDF data to the given TextIO object. The method constructs
|
|
730
|
+
SHACL and OWL ontology representations based on the internal state and configuration of the
|
|
731
|
+
object. SHACL validation shapes, ontology metadata, and RDF structure are included. This
|
|
732
|
+
method is primarily used for exporting RDF data in a standard, compliant format.
|
|
733
|
+
|
|
734
|
+
:param f: The output stream (e.g., a file or any TextIO object) where the generated TriG
|
|
735
|
+
data will be written.
|
|
736
|
+
:param indent: The base indentation level applied when formatting the output.
|
|
737
|
+
:param indent_inc: The number of spaces added for each level of indentation to format
|
|
738
|
+
nested structures cleanly.
|
|
744
739
|
:return: None
|
|
745
740
|
"""
|
|
741
|
+
timestamp = Xsd_dateTime.now()
|
|
742
|
+
blank = ''
|
|
743
|
+
context = Context(name=self._con.context_name)
|
|
744
|
+
f.write('\n')
|
|
745
|
+
f.write(context.turtle_context)
|
|
746
|
+
f.write(f'\n{blank:{indent * indent_inc}}{self.__graph}:shacl {{\n')
|
|
747
|
+
f.write(f'{blank:{(indent + 1) * indent_inc}}{self.__graph}:shapes schema:version {self.__version.toRdf} .\n')
|
|
748
|
+
f.write('\n')
|
|
749
|
+
for qname, onto in self.__extontos.items():
|
|
750
|
+
f.write(onto.create_shacl(timestamp=timestamp, indent=1))
|
|
751
|
+
f.write('\n\n')
|
|
752
|
+
for iri, prop in self.__propclasses.items():
|
|
753
|
+
if not prop.internal:
|
|
754
|
+
f.write(prop.create_shacl(timestamp=timestamp, indent=1))
|
|
755
|
+
f.write('\n\n')
|
|
756
|
+
for iri, resclass in self.__resclasses.items():
|
|
757
|
+
f.write(resclass.create_shacl(timestamp=timestamp, indent=1))
|
|
758
|
+
f.write('\n\n')
|
|
759
|
+
f.write(f'\n{blank:{indent * indent_inc}}}}\n')
|
|
760
|
+
|
|
761
|
+
f.write(f'{blank:{indent * indent_inc}}{self.__graph}:onto {{\n')
|
|
762
|
+
f.write(f'{blank:{(indent + 2) * indent_inc}}{self.__graph}:ontology owl:type owl:Ontology ;\n')
|
|
763
|
+
f.write(f'{blank:{(indent + 2) * indent_inc}}owl:versionInfo {self.__version.toRdf} .\n')
|
|
764
|
+
f.write('\n')
|
|
765
|
+
for iri, prop in self.__propclasses.items():
|
|
766
|
+
f.write(prop.create_owl_part1(timestamp=timestamp, indent=2))
|
|
767
|
+
for iri, resclass in self.__resclasses.items():
|
|
768
|
+
f.write(resclass.create_owl(timestamp=timestamp))
|
|
769
|
+
f.write(f'{blank:{indent * indent_inc}}}}\n')
|
|
770
|
+
|
|
771
|
+
def write_as_trig(self, filename: str, indent: int = 0, indent_inc: int = 4) -> None:
|
|
746
772
|
with open(filename, 'w') as f:
|
|
747
|
-
|
|
748
|
-
blank = ''
|
|
749
|
-
context = Context(name=self._con.context_name)
|
|
750
|
-
f.write('\n')
|
|
751
|
-
f.write(context.turtle_context)
|
|
752
|
-
f.write(f'\n{blank:{indent * indent_inc}}{self.__graph}:shacl {{\n')
|
|
753
|
-
f.write(f'{blank:{(indent + 1) * indent_inc}}{self.__graph}:shapes schema:version {self.__version.toRdf} .\n')
|
|
754
|
-
f.write('\n')
|
|
755
|
-
for qname, onto in self.__extontos.items():
|
|
756
|
-
f.write(onto.create_shacl(timestamp=timestamp, indent=1))
|
|
757
|
-
f.write('\n\n')
|
|
758
|
-
for iri, prop in self.__propclasses.items():
|
|
759
|
-
if not prop.internal:
|
|
760
|
-
f.write(prop.create_shacl(timestamp=timestamp, indent=1))
|
|
761
|
-
f.write('\n\n')
|
|
762
|
-
for iri, resclass in self.__resclasses.items():
|
|
763
|
-
f.write(resclass.create_shacl(timestamp=timestamp, indent=1))
|
|
764
|
-
f.write('\n\n')
|
|
765
|
-
f.write(f'\n{blank:{indent * indent_inc}}}}\n')
|
|
766
|
-
|
|
767
|
-
f.write(f'{blank:{indent * indent_inc}}{self.__graph}:onto {{\n')
|
|
768
|
-
f.write(f'{blank:{(indent + 2) * indent_inc}}{self.__graph}:ontology owl:type owl:Ontology ;\n')
|
|
769
|
-
f.write(f'{blank:{(indent + 2) * indent_inc}}owl:versionInfo {self.__version.toRdf} .\n')
|
|
770
|
-
f.write('\n')
|
|
771
|
-
for iri, prop in self.__propclasses.items():
|
|
772
|
-
f.write(prop.create_owl_part1(timestamp=timestamp, indent=2))
|
|
773
|
-
for iri, resclass in self.__resclasses.items():
|
|
774
|
-
f.write(resclass.create_owl(timestamp=timestamp))
|
|
775
|
-
f.write(f'{blank:{indent * indent_inc}}}}\n')
|
|
773
|
+
self.__to_trig_format(f, indent=indent, indent_inc=indent_inc)
|
|
776
774
|
|
|
775
|
+
def write_as_str(self, indent: int = 0, indent_inc: int = 4) -> str:
|
|
776
|
+
f = io.StringIO()
|
|
777
|
+
self.__to_trig_format(f, indent=indent, indent_inc=indent_inc)
|
|
778
|
+
return f.getvalue()
|
|
777
779
|
|
|
778
780
|
|
|
779
781
|
|
|
@@ -48,6 +48,7 @@ class ContextSingleton(type):
|
|
|
48
48
|
Xsd_NCName('schema'): NamespaceIRI('http://schema.org/'),
|
|
49
49
|
#Xsd_NCName('dc'): NamespaceIRI('http://purl.org/dc/elements/1.1/'),
|
|
50
50
|
Xsd_NCName('dcterms'): NamespaceIRI('http://purl.org/dc/terms/'),
|
|
51
|
+
Xsd_NCName('dcmitype'): NamespaceIRI('http://purl.org/dc/dcmitype/'),
|
|
51
52
|
#Xsd_NCName('foaf'): NamespaceIRI('http://xmlns.com/foaf/0.1/'),
|
|
52
53
|
Xsd_NCName('oldap'): NamespaceIRI('http://oldap.org/base#'),
|
|
53
54
|
Xsd_NCName('shared'): NamespaceIRI('http://oldap.org/shared#')
|
|
@@ -63,6 +64,7 @@ class ContextSingleton(type):
|
|
|
63
64
|
NamespaceIRI('http://schema.org/'): Xsd_NCName('schema'),
|
|
64
65
|
#NamespaceIRI('http://purl.org/dc/elements/1.1/'): Xsd_NCName('dc'),
|
|
65
66
|
NamespaceIRI('http://purl.org/dc/terms/'): Xsd_NCName('dcterms'),
|
|
67
|
+
NamespaceIRI('http://purl.org/dc/dcmitype/'): Xsd_NCName('dcmitype'),
|
|
66
68
|
#NamespaceIRI('http://xmlns.com/foaf/0.1/'): Xsd_NCName('foaf'),
|
|
67
69
|
NamespaceIRI('http://oldap.org/base#'): Xsd_NCName('oldap'),
|
|
68
70
|
NamespaceIRI('http://oldap.org/shared#'): Xsd_NCName('shared'),
|
|
@@ -237,7 +239,7 @@ class Context(metaclass=ContextSingleton):
|
|
|
237
239
|
return Xsd_QName(prefix, fragment, validate=validate)
|
|
238
240
|
return None
|
|
239
241
|
|
|
240
|
-
def qname2iri(self, qname: Xsd_QName | str, validate: bool = True) ->
|
|
242
|
+
def qname2iri(self, qname: Xsd_QName | str, validate: bool = True) -> Xsd_anyURI:
|
|
241
243
|
"""
|
|
242
244
|
Convert a QName into a IRI string.
|
|
243
245
|
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import re
|
|
2
|
+
import jwt
|
|
3
|
+
|
|
4
|
+
from datetime import datetime, timedelta
|
|
2
5
|
from enum import Flag, auto
|
|
3
6
|
from functools import partial
|
|
4
7
|
from typing import Type, Any, Self, cast
|
|
@@ -231,8 +234,25 @@ class ResourceInstance:
|
|
|
231
234
|
return # TODO: LangString does not yet allow multiple entries of the same language...
|
|
232
235
|
if property.get(PropClassAttr.IN):
|
|
233
236
|
#for val in values:
|
|
234
|
-
if
|
|
235
|
-
|
|
237
|
+
if property.datatype is None: # no defined datatype, e.h.sh:IRI
|
|
238
|
+
tmpinset = {str(x) for x in property[PropClassAttr.IN]}
|
|
239
|
+
if isinstance(values, (list, tuple, set, ObservableSet)):
|
|
240
|
+
for val in values:
|
|
241
|
+
if not str(val) in tmpinset:
|
|
242
|
+
raise OldapErrorValue(
|
|
243
|
+
f'Property {property} with IN={property[PropClassAttr.IN]} has invalid value "{val}"')
|
|
244
|
+
else:
|
|
245
|
+
if not str(values) in tmpinset:
|
|
246
|
+
raise OldapErrorValue(f'Property {property.property_class_iri} with IN={property[PropClassAttr.IN]} has invalid value "{values}"')
|
|
247
|
+
else:
|
|
248
|
+
if isinstance(values, (list, tuple, set, ObservableSet)):
|
|
249
|
+
for val in values:
|
|
250
|
+
if not val in property[PropClassAttr.IN]:
|
|
251
|
+
raise OldapErrorValue(
|
|
252
|
+
f'Property {property} with IN={property[PropClassAttr.IN]} has invalid value "{val}"')
|
|
253
|
+
else:
|
|
254
|
+
if not values in property[PropClassAttr.IN]:
|
|
255
|
+
raise OldapErrorValue(f'Property {property.property_class_iri} with IN={property[PropClassAttr.IN]} has invalid value "{values}"')
|
|
236
256
|
if property.get(PropClassAttr.MIN_LENGTH):
|
|
237
257
|
for val in values:
|
|
238
258
|
l = 0
|
|
@@ -1029,6 +1049,7 @@ class ResourceInstance:
|
|
|
1029
1049
|
limit: int = 100,
|
|
1030
1050
|
offset: int = 0,
|
|
1031
1051
|
indent: int = 0, indent_inc: int = 4) -> dict[Iri, dict[str, Xsd]]:
|
|
1052
|
+
# TODO: PROBLEM: does not work for properties which use MAX_COUNT > 1 !!!!!!!
|
|
1032
1053
|
"""
|
|
1033
1054
|
Retrieves all resources matching the specified parameters from a data store using a SPARQL query.
|
|
1034
1055
|
Depending on the `count_only` flag, it can return either a count of matching resources or detailed
|
|
@@ -1144,7 +1165,22 @@ class ResourceInstance:
|
|
|
1144
1165
|
return result
|
|
1145
1166
|
|
|
1146
1167
|
@staticmethod
|
|
1147
|
-
def get_media_object_by_id(con: IConnection, mediaObjectId: Xsd_string | str) -> dict[str, Xsd]
|
|
1168
|
+
def get_media_object_by_id(con: IConnection, mediaObjectId: Xsd_string | str) -> dict[str, Xsd]:
|
|
1169
|
+
"""
|
|
1170
|
+
Retrieves a media object by its ID from the system. This method queries a SPARQL endpoint
|
|
1171
|
+
to fetch details about the media object and constructs a resulting dictionary with the
|
|
1172
|
+
media object attributes and its associated metadata. Additionally, a signed JWT token
|
|
1173
|
+
is included in the result for security purposes.
|
|
1174
|
+
|
|
1175
|
+
:param con: A connection interface that provides access to the SPARQL endpoint and user context.
|
|
1176
|
+
:type con: IConnection
|
|
1177
|
+
:param mediaObjectId: The ID of the media object to be fetched, represented as an XSD string or a Python string.
|
|
1178
|
+
:type mediaObjectId: Xsd_string | str
|
|
1179
|
+
:return: A dictionary containing key-value pairs of media object attributes and metadata,
|
|
1180
|
+
with an additional JWT token for security. Returns None if the media object is not found.
|
|
1181
|
+
:rtype: dict[str, Xsd] | None
|
|
1182
|
+
:raises OldapErrorNotFound: Raised when the media object with the specified ID is not found.
|
|
1183
|
+
"""
|
|
1148
1184
|
if not isinstance(mediaObjectId, Xsd_string):
|
|
1149
1185
|
mediaObjectId = Xsd_string(mediaObjectId, validate=True)
|
|
1150
1186
|
blank = ''
|
|
@@ -1152,19 +1188,14 @@ class ResourceInstance:
|
|
|
1152
1188
|
sparql = context.sparql_context
|
|
1153
1189
|
|
|
1154
1190
|
sparql += f"""
|
|
1155
|
-
SELECT ?subject ?graph ?path ?
|
|
1191
|
+
SELECT ?subject ?graph ?path ?prop ?val ?permval
|
|
1156
1192
|
WHERE {{
|
|
1157
1193
|
VALUES ?inputImageId {{ {mediaObjectId.toRdf} }}
|
|
1158
|
-
|
|
1159
1194
|
?subject rdf:type shared:MediaObject .
|
|
1160
1195
|
GRAPH ?graph {{
|
|
1161
|
-
?subject shared:imageId ?inputImageId .
|
|
1162
|
-
?subject shared:originalName ?originalName .
|
|
1163
|
-
?subject shared:originalMimeType ?originalMimeType .
|
|
1164
|
-
?subject shared:serverUrl ?serverUrl .
|
|
1165
|
-
?subject shared:path ?path .
|
|
1166
|
-
?subject shared:protocol ?protocol .
|
|
1167
1196
|
?subject oldap:grantsPermission ?permset .
|
|
1197
|
+
?subject shared:imageId ?inputImageId .
|
|
1198
|
+
?subject ?prop ?val .
|
|
1168
1199
|
}}
|
|
1169
1200
|
GRAPH oldap:admin {{
|
|
1170
1201
|
{con.userIri.toRdf} oldap:hasPermissions ?permset .
|
|
@@ -1179,16 +1210,110 @@ class ResourceInstance:
|
|
|
1179
1210
|
print(sparql)
|
|
1180
1211
|
raise
|
|
1181
1212
|
res = QueryProcessor(context, jsonres)
|
|
1182
|
-
if len(res) == 0
|
|
1213
|
+
if len(res) == 0:
|
|
1183
1214
|
raise OldapErrorNotFound(f'Media object with id {mediaObjectId} not found.')
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1215
|
+
result: dict[str, Xsd] = {
|
|
1216
|
+
'iri': res[0].get('subject'),
|
|
1217
|
+
'graph': res[0].get('graph'),
|
|
1218
|
+
'permval': res[0].get('permval')
|
|
1219
|
+
}
|
|
1220
|
+
for r in res:
|
|
1221
|
+
if str(r['prop']) == 'rdf:type':
|
|
1222
|
+
continue
|
|
1223
|
+
if str(r['prop']) in {'oldap:createdBy', 'oldap:creationDate', 'oldap:lastModifiedBy', 'oldap:lastModificationDate',
|
|
1224
|
+
'shared:imageId', 'shared:originalName', 'shared:originalMimeType', 'shared:serverUrl', 'shared:path', 'shared:protocol'}:
|
|
1225
|
+
result[str(r['prop'])] = r['val']
|
|
1226
|
+
else:
|
|
1227
|
+
if result.get(str(r['prop'])) is None:
|
|
1228
|
+
result[str(r['prop'])] = []
|
|
1229
|
+
result[str(r['prop'])].append(r['val'])
|
|
1230
|
+
|
|
1231
|
+
expiration = datetime.now().astimezone() + timedelta(minutes=2)
|
|
1232
|
+
payload = {
|
|
1233
|
+
'userIri': str(con.userIri),
|
|
1234
|
+
'userid': str(con.userid),
|
|
1235
|
+
'id': str(mediaObjectId),
|
|
1236
|
+
'path': str(result.get('shared:path')),
|
|
1237
|
+
'permval': str(result.get('permval')),
|
|
1238
|
+
"exp": expiration.timestamp(),
|
|
1239
|
+
"iat": int(datetime.now().astimezone().timestamp()),
|
|
1240
|
+
"iss": "http://oldap.org"
|
|
1241
|
+
}
|
|
1242
|
+
token = jwt.encode(
|
|
1243
|
+
payload=payload,
|
|
1244
|
+
key=con.jwtkey,
|
|
1245
|
+
algorithm="HS256")
|
|
1246
|
+
result['token'] = token
|
|
1247
|
+
|
|
1248
|
+
return result
|
|
1249
|
+
|
|
1250
|
+
@staticmethod
|
|
1251
|
+
def get_media_object_by_iri(con: IConnection, mediaObjectIri: Iri | str) -> dict[str, Xsd] | None:
|
|
1252
|
+
if not isinstance(mediaObjectIri, Iri):
|
|
1253
|
+
mediaObjectIri = Iri(mediaObjectIri, validate=True)
|
|
1254
|
+
blank = ''
|
|
1255
|
+
context = Context(name=con.context_name)
|
|
1256
|
+
sparql = context.sparql_context
|
|
1257
|
+
|
|
1258
|
+
sparql += f"""
|
|
1259
|
+
SELECT ?graph ?prop ?val ?permval
|
|
1260
|
+
WHERE {{
|
|
1261
|
+
{mediaObjectIri.toRdf} rdf:type shared:MediaObject .
|
|
1262
|
+
GRAPH ?graph {{
|
|
1263
|
+
{mediaObjectIri.toRdf} oldap:grantsPermission ?permset .
|
|
1264
|
+
{mediaObjectIri.toRdf} shared:imageId ?inputImageId .
|
|
1265
|
+
{mediaObjectIri.toRdf} ?prop ?val .
|
|
1266
|
+
}}
|
|
1267
|
+
GRAPH oldap:admin {{
|
|
1268
|
+
{con.userIri.toRdf} oldap:hasPermissions ?permset .
|
|
1269
|
+
?permset oldap:givesPermission ?DataPermission .
|
|
1270
|
+
?DataPermission oldap:permissionValue ?permval .
|
|
1271
|
+
}}
|
|
1272
|
+
}}
|
|
1273
|
+
"""
|
|
1274
|
+
print(sparql)
|
|
1275
|
+
try:
|
|
1276
|
+
jsonres = con.query(sparql)
|
|
1277
|
+
except OldapError:
|
|
1278
|
+
print(sparql)
|
|
1279
|
+
raise
|
|
1280
|
+
res = QueryProcessor(context, jsonres)
|
|
1281
|
+
if len(res) == 0:
|
|
1282
|
+
raise OldapErrorNotFound(f'Media object with iri {mediaObjectIri} not found.')
|
|
1283
|
+
result: dict[str, Xsd] = {
|
|
1284
|
+
'iri': mediaObjectIri,
|
|
1285
|
+
'graph': res[0].get('graph'),
|
|
1286
|
+
'permval': res[0].get('permval')
|
|
1287
|
+
}
|
|
1288
|
+
for r in res:
|
|
1289
|
+
if str(r['prop']) == 'rdf:type':
|
|
1290
|
+
continue
|
|
1291
|
+
if str(r['prop']) in {'oldap:createdBy', 'oldap:creationDate', 'oldap:lastModifiedBy', 'oldap:lastModificationDate',
|
|
1292
|
+
'shared:imageId', 'shared:originalName', 'shared:originalMimeType', 'shared:serverUrl', 'shared:path', 'shared:protocol'}:
|
|
1293
|
+
result[str(r['prop'])] = r['val']
|
|
1294
|
+
else:
|
|
1295
|
+
if result.get(str(r['prop'])) is None:
|
|
1296
|
+
result[str(r['prop'])] = []
|
|
1297
|
+
result[str(r['prop'])].append(r['val'])
|
|
1298
|
+
|
|
1299
|
+
expiration = datetime.now().astimezone() + timedelta(minutes=2)
|
|
1300
|
+
payload = {
|
|
1301
|
+
'userIri': str(con.userIri),
|
|
1302
|
+
'userid': str(con.userid),
|
|
1303
|
+
'id': str(result.get('shared:imageId')),
|
|
1304
|
+
'path': str(result['shared:path']),
|
|
1305
|
+
'permval': str(result['permval']),
|
|
1306
|
+
"exp": expiration.timestamp(),
|
|
1307
|
+
"iat": int(datetime.now().astimezone().timestamp()),
|
|
1308
|
+
"iss": "http://oldap.org"
|
|
1309
|
+
}
|
|
1310
|
+
token = jwt.encode(
|
|
1311
|
+
payload=payload,
|
|
1312
|
+
key=con.jwtkey,
|
|
1313
|
+
algorithm="HS256")
|
|
1314
|
+
result['token'] = token
|
|
1315
|
+
|
|
1316
|
+
return result
|
|
1192
1317
|
|
|
1193
1318
|
|
|
1194
1319
|
def toJsonObject(self) -> dict[str, list[str] | str]:
|