oldaplib 0.4.5__py3-none-any.whl → 0.4.6__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.
@@ -211,6 +211,11 @@ class Language(Enum):
211
211
  def toRdf(self) -> str:
212
212
  return f'"{self.name.lower()}"^^xsd:string'
213
213
 
214
+ @property
215
+ def shortlang(self) -> str:
216
+ """Return the language short name in lowercase (e.g., 'de' for Language.DE)"""
217
+ return self.name.lower()
218
+
214
219
 
215
220
  if __name__ == "__main__":
216
221
  print(Language.EN.toRdf)
oldaplib/src/model.py CHANGED
@@ -222,7 +222,10 @@ class Model:
222
222
  del self._attributes[attr]
223
223
  else:
224
224
  if not isinstance(value, attr.datatype):
225
- self._attributes[attr] = attr.datatype(value, validate=True)
225
+ try:
226
+ self._attributes[attr] = attr.datatype(value, validate=True)
227
+ except Exception as err:
228
+ raise Exception(f"Failed to set attribute '{attr}' with value '{value}': {err}")
226
229
  else:
227
230
  self._attributes[attr] = value
228
231
  if hasattr(self._attributes[attr], 'set_notifier') and hasattr(self, 'notifier'):
@@ -1,11 +1,12 @@
1
1
  import re
2
2
  import textwrap
3
+ from dataclasses import dataclass
3
4
  from pprint import pprint
4
5
 
5
6
  import jwt
6
7
 
7
8
  from datetime import datetime, timedelta
8
- from enum import Flag, auto
9
+ from enum import Flag, auto, Enum
9
10
  from functools import partial
10
11
  from typing import Type, Any, Self, cast, Dict
11
12
 
@@ -24,7 +25,7 @@ from oldaplib.src.helpers.langstring import LangString
24
25
  from oldaplib.src.helpers.observable_dict import ObservableDict
25
26
  from oldaplib.src.helpers.observable_set import ObservableSet
26
27
  from oldaplib.src.helpers.oldaperror import OldapErrorNotFound, OldapErrorValue, OldapErrorInconsistency, \
27
- OldapErrorNoPermission, OldapError, OldapErrorUpdateFailed, OldapErrorInUse, OldapErrorAlreadyExists
28
+ OldapErrorNoPermission, OldapError, OldapErrorUpdateFailed, OldapErrorInUse, OldapErrorAlreadyExists, OldapErrorType
28
29
  from oldaplib.src.helpers.query_processor import QueryProcessor
29
30
  from oldaplib.src.iconnection import IConnection
30
31
  from oldaplib.src.project import Project
@@ -40,10 +41,14 @@ from oldaplib.src.xsd.xsd_string import Xsd_string
40
41
 
41
42
  ValueType = LangString | ObservableSet | Xsd | Dict[Xsd_QName, DataPermission] | ObservableDict
42
43
 
43
- class SortBy(Flag):
44
- PROPVAL = auto()
45
- CREATED = auto()
46
- LASTMOD = auto()
44
+ class SortDir(str, Enum):
45
+ asc = "asc"
46
+ desc = "desc"
47
+
48
+ @dataclass(frozen=True)
49
+ class SortBy:
50
+ property: Xsd_QName
51
+ dir: SortDir = SortDir.asc
47
52
 
48
53
 
49
54
  #@strict
@@ -167,7 +172,7 @@ class ResourceInstance:
167
172
  raise OldapErrorValue(f'{self.name}: Property {prop_iri} with MIN_COUNT={hasprop[HasPropertyAttr.MIN_COUNT]} is missing')
168
173
  elif isinstance(self._values[prop_iri], ObservableSet) and len(self._values[prop_iri]) < 1:
169
174
  raise OldapErrorValue(f'{self.name}: Property {prop_iri} with MIN_COUNT={hasprop[HasPropertyAttr.MIN_COUNT]} is missing')
170
- if hasprop.get(HasPropertyAttr.MAX_COUNT): # testing for MAX_COUNT conformance
175
+ if hasprop.get(HasPropertyAttr.MAX_COUNT) and hasprop[HasPropertyAttr.MAX_COUNT] > 0: # testing for MAX_COUNT conformance
171
176
  if isinstance(self._values.get(prop_iri), ObservableSet) and len(self._values[prop_iri]) > hasprop[HasPropertyAttr.MAX_COUNT]:
172
177
  raise OldapErrorValue(f'{self.name}: Property {prop_iri} with MAX_COUNT={hasprop[HasPropertyAttr.MIN_COUNT]} has to many values (n={len(self._values[prop_iri])})')
173
178
  if self._values.get(prop_iri):
@@ -375,12 +380,12 @@ class ResourceInstance:
375
380
  raise OldapErrorValue(
376
381
  f'{self.name}: Property {prop_iri} with MIN_COUNT={hasprop[HasPropertyAttr.MIN_COUNT]} has not enough values (n={n}).')
377
382
 
378
- if hasprop.get(HasPropertyAttr.MAX_COUNT): # testing for MAX_COUNT conformance
383
+ if hasprop.get(HasPropertyAttr.MAX_COUNT) and hasprop[HasPropertyAttr.MAX_COUNT] > 0: # testing for MAX_COUNT conformance
379
384
  n = len(self._values[prop_iri])
380
385
  if n > hasprop[HasPropertyAttr.MAX_COUNT]:
381
386
  self._values[prop_iri].undo()
382
387
  raise OldapErrorValue(
383
- f'{self.name}: Property {prop_iri} with MAX_COUNT={hasprop[HasPropertyAttr.MIN_COUNT]} has to many values (n={n}).')
388
+ f'{self.name}: Property {prop_iri} with MAX_COUNT={hasprop[HasPropertyAttr.MAX_COUNT]} has to many values (n={n}).')
384
389
 
385
390
  self._changeset[prop_iri] = AttributeChange(None, Action.MODIFY)
386
391
 
@@ -454,7 +459,7 @@ class ResourceInstance:
454
459
  elif isinstance(value, (list, tuple, set, ObservableSet)) and len(value) < hasprop[HasPropertyAttr.MIN_COUNT]:
455
460
  raise OldapErrorValue(
456
461
  f'{self.name}: Property {attr} with MIN_COUNT={hasprop[HasPropertyAttr.MIN_COUNT]} has not enough values')
457
- if hasprop.get(HasPropertyAttr.MAX_COUNT): # testing for MAX_COUNT conformance
462
+ if hasprop.get(HasPropertyAttr.MAX_COUNT) and hasprop[HasPropertyAttr.MAX_COUNT] > 0: # testing for MAX_COUNT conformance
458
463
  if isinstance(value, (list, tuple, set, ObservableSet)) and len(value) > hasprop[HasPropertyAttr.MAX_COUNT]:
459
464
  raise OldapErrorValue(
460
465
  f'{self.name}: Property {attr} with MAX_COUNT={hasprop[HasPropertyAttr.MIN_COUNT]} has to many values (n={len(value)})')
@@ -1095,74 +1100,75 @@ class ResourceInstance:
1095
1100
  for r in res:
1096
1101
  roles[r['role']] = DataPermission.from_qname(r['dataperm'])
1097
1102
  data[Xsd_QName('oldap:attachedToRole')] = roles
1098
-
1103
+ #data[Xsd_QName('virtual:resourceIri')] = iri
1099
1104
  return data
1100
1105
 
1101
1106
  @staticmethod
1102
1107
  def search_fulltext(con: IConnection,
1103
1108
  projectShortName: Xsd_NCName | str,
1104
- s: str,
1109
+ searchstr: str,
1105
1110
  resClass: Xsd_QName | str | None = None,
1106
1111
  countOnly: bool = False,
1107
- sortBy: SortBy | None = None,
1112
+ sortBy: list[SortBy] = [],
1108
1113
  limit: int = 100,
1109
1114
  offset: int = 0,
1110
1115
  indent: int = 0, indent_inc: int = 4) -> int | dict[Iri, dict[str, Xsd]]:
1111
1116
  """
1112
- Search for entities in a project using a full-text search query, with optional filters and sorting
1113
- based on resource class and properties.
1114
-
1115
- :param con: The connection instance to interact with the SPARQL endpoint or database.
1116
- :type con: IConnection
1117
- :param projectShortName: The project short name (identifier). Can be provided as an Xsd_NCName or a
1118
- string. If a string, it is automatically validated and converted to an Xsd_NCName.
1119
- :type projectShortName: Xsd_NCName | str
1120
- :param s: The full-text search query to identify entities matching the specified string values.
1121
- :type s: str
1122
- :param resClass: An optional entity class (Xsd_QName) used to filter results. If provided as a string,
1123
- it is validated and converted to Xsd_QName.
1124
- :type resClass: Xsd_QName | str | None
1125
- :param countOnly: If True, only the count of matching entities will be returned. Defaults to False.
1126
- :type countOnly: bool
1127
- :param sortBy: Optional sorting criterion for the results, such as creation date, last modification date,
1128
- or property values. Defaults to None.
1129
- :type sortBy: SortBy | None
1130
- :param limit: The maximum number of records to return when count_only is False. Defaults to 100.
1131
- :type limit: int
1132
- :param offset: The number of records to skip for paginated queries. Defaults to 0.
1133
- :type offset: int
1134
- :param indent: Initial indentation level for the generated SPARQL query. Defaults to 0.
1135
- :type indent: int
1136
- :param indent_inc: Incremental indentation used during SPARQL query generation. Defaults to 4.
1137
- :type indent_inc: int
1138
- :return: If count_only is True, an integer representing the count of matching entities. If count_only is
1139
- False, a dictionary with entity IRIs as keys and their respective property-to-value mappings
1140
- as values.
1141
- :rtype: int | dict[Iri, dict[str, Xsd]]
1142
-
1143
- The SPARQL generated is as follows
1144
-
1145
- ```sparql
1146
- SELECT DISTINCT ?s ?t ?p ?o ?creationDate
1147
- WHERE {
1148
- GRAPH test:data {
1149
- ?s oldap:creationDate ?creationDate .
1150
- ?s ?p ?o .
1151
- ?s rdf:type ?t .
1152
- ?s rdf:type test:Book .
1153
- ?s oldap:grantsPermission ?permset .
1154
- }
1155
- FILTER(isLiteral(?o) && (datatype(?o) = xsd:string || datatype(?o) = rdf:langString || lang(?o) != ""))
1156
- FILTER(CONTAINS(LCASE(STR(?o)), "gaga")) # case-insensitive substring match
1157
- GRAPH oldap:admin {
1158
- <https://orcid.org/0000-0003-1681-4036> oldap:hasPermissions ?permset .
1159
- ?permset oldap:givesPermission ?DataPermission .
1160
- ?DataPermission oldap:permissionValue ?permval .
1161
- }
1162
- FILTER(?permval >= "2"^^xsd:integer)
1163
- }
1164
- ORDER BY ASC(?creationDate)LIMIT 100 OFFSET 0
1165
- ```
1117
+ Searches and retrieves data from the database using a full-text search query. This method allows
1118
+ users to optionally filter and sort the results based on specific criteria. It supports returning
1119
+ either the count of matching results or the results themselves in a structured format.
1120
+
1121
+ :param con: The connection object used to interact with the database.
1122
+ This must implement the IConnection interface.
1123
+ :type con: IConnection
1124
+
1125
+ :param projectShortName: The short name of the project for which the data
1126
+ needs to be queried.
1127
+ :type projectShortName: Xsd_NCName | str
1128
+
1129
+ :param searchstr: The search string used for full-text search, with case-insensitive
1130
+ substring matching.
1131
+ :type searchstr: str
1132
+
1133
+ :param resClass: An optional parameter specifying the resource class of the
1134
+ objects to be retrieved. If provided, the query will filter results for the
1135
+ specified class.
1136
+ :type resClass: Xsd_QName | str | None
1137
+
1138
+ :param countOnly: A boolean flag to indicate whether to return only the count
1139
+ of matching results. If set to True, only the count is returned;
1140
+ otherwise, matching records are retrieved.
1141
+ :type countOnly: bool
1142
+
1143
+ :param sortBy: A list of sorting criteria. Each criterion specifies the property
1144
+ and direction (ascending or descending) to sort the results. If not provided,
1145
+ no sorting is applied. SortBy has the following attributes:
1146
+ - property (Xsd_QName): The property to sort by. The property must be one of
1147
+ Xsd_QName('oldap:creationDate'), Xsd_QName('oldap:lastModificationDate') or
1148
+ Xsd_QName('oldap:propval') to sort according the property where the match has been found..
1149
+ - direction (str): The sorting direction, either 'asc' for ascending or 'desc' for descending.
1150
+ :type sortBy: list[SortBy]
1151
+
1152
+ :param limit: The maximum number of results to retrieve. Defaults to 100 if not specified.
1153
+ :type limit: int
1154
+
1155
+ :param offset: The number of records to skip before starting to retrieve results.
1156
+ This is useful for paginated responses.
1157
+ :type offset: int
1158
+
1159
+ :param indent: The base indentation level used for formatting the generated SPARQL
1160
+ query string.
1161
+ :type indent: int
1162
+
1163
+ :param indent_inc: The incremental value to add to the base indent for nested query
1164
+ components.
1165
+ :type indent_inc: int
1166
+
1167
+ :return: If `countOnly` is True, an integer representing the count of matching results
1168
+ is returned. Otherwise, a dictionary is returned where the keys are IRIs of the
1169
+ matching resources, and the values are dictionaries containing their respective
1170
+ properties and values.
1171
+ :rtype: int | dict[Iri, dict[str, Xsd]]
1166
1172
  """
1167
1173
  if not isinstance(projectShortName, Xsd_NCName):
1168
1174
  graph = Xsd_NCName(projectShortName, validate=True)
@@ -1180,10 +1186,12 @@ class ResourceInstance:
1180
1186
  else:
1181
1187
  sparql += f'{blank:{indent * indent_inc}}SELECT DISTINCT ?s ?t ?p ?o'
1182
1188
  if sortBy:
1183
- if sortBy == SortBy.CREATED:
1184
- sparql += ' ?creationDate'
1185
- if sortBy == SortBy.LASTMOD:
1186
- sparql += '?lastModificationDate'
1189
+ for sortby in sortBy:
1190
+ if sortby.property == Xsd_QName('oldap:creationDate'):
1191
+ sparql += ' ?creationDate'
1192
+ elif sortby.property == Xsd_QName('oldap:lastModificationDate'):
1193
+ sparql += '?lastModificationDate'
1194
+
1187
1195
  sparql += f'\n{blank:{indent * indent_inc}}WHERE {{'
1188
1196
  sparql += f'\n{blank:{(indent + 1) * indent_inc}}GRAPH oldap:admin {{'
1189
1197
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}{con.userIri.toRdf} oldap:hasRole ?role .'
@@ -1191,11 +1199,12 @@ class ResourceInstance:
1191
1199
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}FILTER(?permval >= {DataPermission.DATA_VIEW.numeric.toRdf})'
1192
1200
  sparql += f'\n{blank:{(indent + 1) * indent_inc}}}}'
1193
1201
  sparql += f'\n{blank:{(indent + 1) * indent_inc}}GRAPH {graph}:data {{'
1194
- if sortBy:
1195
- if sortBy == SortBy.CREATED:
1196
- sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s oldap:creationDate ?creationDate .'
1197
- if sortBy == SortBy.LASTMOD:
1198
- sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s oldap:lastModificationDate ?lastModificationDate .'
1202
+ if not countOnly and sortBy:
1203
+ for sortby in sortBy:
1204
+ if sortby.property == Xsd_QName('oldap:creationDate'):
1205
+ sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s oldap:creationDate ?creationDate .'
1206
+ elif sortby.property == Xsd_QName('oldap:lastModificationDate'):
1207
+ sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s oldap:lastModificationDate ?lastModificationDate .'
1199
1208
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s ?p ?o .'
1200
1209
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s rdf:type ?t .'
1201
1210
  if resClass:
@@ -1203,17 +1212,27 @@ class ResourceInstance:
1203
1212
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s oldap:attachedToRole ?role .'
1204
1213
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}<< ?s oldap:attachedToRole ?role >> oldap:hasDataPermission ?DataPermission .'
1205
1214
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}FILTER(isLiteral(?o) && (datatype(?o) = xsd:string || datatype(?o) = rdf:langString || lang(?o) != ""))'
1206
- sparql += f'\n{blank:{(indent + 2) * indent_inc}}FILTER(CONTAINS(LCASE(STR(?o)), "{s}")) # case-insensitive substring match'
1215
+ sparql += f'\n{blank:{(indent + 2) * indent_inc}}FILTER(CONTAINS(LCASE(STR(?o)), "{searchstr}")) # case-insensitive substring match'
1207
1216
  sparql += f'\n{blank:{(indent + 1) * indent_inc}}}}'
1208
1217
  sparql += f'\n{blank:{indent * indent_inc}}}}'
1209
1218
 
1210
- if sortBy:
1211
- if sortBy == SortBy.CREATED:
1212
- sparql += f'\n{blank:{indent * indent_inc}}ORDER BY ASC(?creationDate)'
1213
- if sortBy == SortBy.LASTMOD:
1214
- sparql += f'\n{blank:{indent * indent_inc}}ORDER BY ASC(?lastModificationDate)'
1215
- if sortBy == SortBy.PROPVAL:
1216
- sparql += f'\n{blank:{indent * indent_inc}}ORDER BY ASC(LCASE(STR(?o)))'
1219
+ if not countOnly and sortBy:
1220
+ for sortby in sortBy:
1221
+ if sortby.property == Xsd_QName('oldap:creationDate'):
1222
+ if sortby.dir == SortDir.asc:
1223
+ sparql += f'\n{blank:{indent * indent_inc}}ORDER BY ASC(?creationDate)'
1224
+ else:
1225
+ sparql += f'\n{blank:{indent * indent_inc}}ORDER BY DESC(?creationDate)'
1226
+ elif sortby.property == Xsd_QName('oldap:lastModificationDate'):
1227
+ if sortby.dir == SortDir.asc:
1228
+ sparql += f'\n{blank:{indent * indent_inc}}ORDER BY ASC(?lastModificationDate)'
1229
+ else:
1230
+ sparql += f'\n{blank:{indent * indent_inc}}ORDER BY DESC(?lastModificationDate)'
1231
+ elif sortby.property == Xsd_QName('oldap:propval'):
1232
+ if sortby.dir == SortDir.asc:
1233
+ sparql += f'\n{blank:{indent * indent_inc}}ORDER BY ASC(?o)'
1234
+ else:
1235
+ sparql += f'\n{blank:{indent * indent_inc}}ORDER BY DESC(?o)'
1217
1236
 
1218
1237
  if not countOnly:
1219
1238
  sparql += f'\n{blank:{indent * indent_inc}}LIMIT {limit} OFFSET {offset}'
@@ -1235,10 +1254,11 @@ class ResourceInstance:
1235
1254
  Xsd_QName('owl:Class'): r['t']
1236
1255
  }
1237
1256
  if sortBy:
1238
- if sortBy == SortBy.CREATED:
1239
- tmp['oldap:creationDate'] = r['creationDate'],
1240
- if sortBy == SortBy.LASTMOD:
1241
- tmp['oldap:lastModificationDate'] = r['lastModificationDate']
1257
+ for sortby in sortBy:
1258
+ if sortby.property == Xsd_QName('oldap:creationDate'):
1259
+ tmp['oldap:creationDate'] = r['creationDate'],
1260
+ elif sortby.property == Xsd_QName('oldap:lastModificationDate'):
1261
+ tmp['oldap:lastModificationDate'] = r['lastModificationDate']
1242
1262
  result[r['s']] = tmp
1243
1263
  return result
1244
1264
 
@@ -1247,43 +1267,19 @@ class ResourceInstance:
1247
1267
  projectShortName: Xsd_NCName | str,
1248
1268
  resClass: Xsd_QName | str,
1249
1269
  includeProperties: list[Xsd_QName] | None = None,
1250
- count_only: bool = False,
1251
- sortBy: SortBy | None = None,
1270
+ countOnly: bool = False,
1271
+ sortBy: list[SortBy] = [],
1252
1272
  limit: int = 100,
1253
1273
  offset: int = 0,
1254
1274
  indent: int = 0, indent_inc: int = 4) -> dict[Iri, dict[str, Xsd]]:
1255
- # TODO: PROBLEM: does not work for properties which use MAX_COUNT > 1 !!!!!!!
1256
1275
  """
1257
1276
  Retrieves all resources matching the specified parameters from a data store using a SPARQL query.
1258
1277
  Depending on the `count_only` flag, it can return either a count of matching resources or detailed
1259
1278
  information about each resource.
1260
-
1261
- :param con: The connection object used to execute the SPARQL query.
1262
- :type con: IConnection
1263
- :param projectShortName: The short name of the project being queried.
1264
- :type projectShortName: Xsd_NCName | str
1265
- :param resClass: The resource class to filter the results by.
1266
- :type resClass: Xsd_QName | str
1267
- :param includeProperties: A list of resource properties to include in the query and results.
1268
- :type includeProperties: list[Xsd_QName] | None
1269
- :param count_only: If True, returns only the count of matching resources. Defaults to False.
1270
- :type count_only: bool
1271
- :param sortBy: The sorting criterion for the results. Defaults to None.
1272
- :type sortBy: SortBy | None
1273
- :param limit: The maximum number of results to retrieve. Defaults to 100.
1274
- :type limit: int
1275
- :param offset: The starting point for result retrieval in pagination. Defaults to 0.
1276
- :type offset: int
1277
- :param indent: The initial level of indentation for the SPARQL query strings. Defaults to 0.
1278
- :type indent: int
1279
- :param indent_inc: The incremental level of indentation for the SPARQL query strings. Defaults to 4.
1280
- :type indent_inc: int
1281
- :return: A dictionary where keys are resource IRIs and values are dictionaries containing resource
1282
- properties and their corresponding values. If `count_only` is True, returns the total count of
1283
- matching resources as an integer.
1284
- :rtype: dict[Iri, dict[str, Xsd]]
1285
- :raises OldapError: If there is an error during query execution in the connection object.
1286
1279
  """
1280
+ # --- ensure re is imported ---
1281
+ import re
1282
+
1287
1283
  if not isinstance(projectShortName, Xsd_NCName):
1288
1284
  graph = Xsd_NCName(projectShortName, validate=True)
1289
1285
  else:
@@ -1291,22 +1287,26 @@ class ResourceInstance:
1291
1287
  if not isinstance(resClass, Xsd_QName):
1292
1288
  resClass = Xsd_QName(resClass, validate=True)
1293
1289
 
1290
+ if sortBy:
1291
+ for s in sortBy:
1292
+ if not isinstance(s, SortBy):
1293
+ raise OldapErrorType(f'Expected SortBy, got {type(s)}')
1294
+ if not includeProperties or s.property not in includeProperties:
1295
+ if not includeProperties:
1296
+ includeProperties = []
1297
+ includeProperties.append(s.property)
1298
+
1294
1299
  blank = ''
1295
1300
  context = Context(name=con.context_name)
1296
1301
  sparql = context.sparql_context
1297
1302
 
1298
- if (count_only):
1303
+ if (countOnly):
1299
1304
  sparql += f'{blank:{indent * indent_inc}}SELECT (COUNT(DISTINCT ?s) as ?numResult)'
1300
1305
  else:
1301
1306
  sparql += f'{blank:{indent * indent_inc}}SELECT DISTINCT ?s'
1302
1307
  if includeProperties:
1303
1308
  for index, item in enumerate(includeProperties):
1304
1309
  sparql += f' ?o{index}'
1305
- if sortBy:
1306
- if sortBy == SortBy.CREATED:
1307
- sparql += ' ?creationDate'
1308
- if sortBy == SortBy.LASTMOD:
1309
- sparql += '?lastModificationDate'
1310
1310
  sparql += f'\n{blank:{indent * indent_inc}}WHERE {{'
1311
1311
  sparql += f'\n{blank:{(indent + 1) * indent_inc}}GRAPH oldap:admin {{'
1312
1312
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}{con.userIri.toRdf} oldap:hasRole ?role .'
@@ -1316,30 +1316,23 @@ class ResourceInstance:
1316
1316
  sparql += f'\n{blank:{(indent + 1) * indent_inc}}GRAPH {graph}:data {{'
1317
1317
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s oldap:attachedToRole ?role .'
1318
1318
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}<< ?s oldap:attachedToRole ?role >> oldap:hasDataPermission ?dataperm .'
1319
- if sortBy:
1320
- if sortBy == SortBy.CREATED:
1321
- sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s oldap:creationDate ?creationDate .'
1322
- if sortBy == SortBy.LASTMOD:
1323
- sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s oldap:lastModificationDate ?lastModificationDate .'
1324
1319
  if includeProperties:
1325
1320
  for index, prop in enumerate(includeProperties):
1326
- sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s {prop} ?o{index} .'
1321
+ sparql += f'\n{blank:{(indent + 2) * indent_inc}}OPTIONAL {{ ?s {prop} ?o{index} . }}'
1327
1322
  sparql += f'\n{blank:{(indent + 2) * indent_inc}}?s rdf:type {resClass} .'
1328
1323
  sparql += f'\n{blank:{(indent + 1) * indent_inc}}}}'
1329
1324
  sparql += f'\n{blank:{indent * indent_inc}}}}'
1330
1325
 
1331
- if sortBy:
1332
- if sortBy == SortBy.CREATED:
1333
- sparql += f'\n{blank:{indent * indent_inc}}ORDER BY ASC(?creationDate)'
1334
- if sortBy == SortBy.LASTMOD:
1335
- sparql += f'\n{blank:{indent * indent_inc}}ORDER BY ASC(?lastModificationDate)'
1336
- if sortBy == SortBy.PROPVAL:
1337
- sparql += f'\n{blank:{indent * indent_inc}}ORDER BY'
1338
- if includeProperties:
1339
- for index, item in enumerate(includeProperties):
1340
- sparql += f'\n{blank:{indent * indent_inc}} ?o{index}'
1326
+ if not countOnly and sortBy:
1327
+ sparql += f'\n{blank:{indent * indent_inc}}ORDER BY'
1328
+ for s in sortBy:
1329
+ if s.dir == SortDir.asc:
1330
+ sparql += f' ASC(?o{includeProperties.index(s.property)})'
1331
+ else:
1332
+ sparql += f' DESC(?o{includeProperties.index(s.property)})'
1333
+ sparql += '\n'
1341
1334
 
1342
- if not count_only:
1335
+ if not countOnly:
1343
1336
  sparql += f'\n{blank:{indent * indent_inc}}LIMIT {limit} OFFSET {offset}'
1344
1337
  sparql += '\n'
1345
1338
 
@@ -1349,22 +1342,33 @@ class ResourceInstance:
1349
1342
  print(sparql)
1350
1343
  raise
1351
1344
  res = QueryProcessor(context, jsonres)
1352
- if count_only:
1345
+ if countOnly:
1353
1346
  return res[0]['numResult']
1354
1347
  else:
1355
1348
  result = {}
1356
1349
  for r in res:
1357
- tmp = {}
1350
+ if result.get(r['s'], None) is None:
1351
+ result[r['s']] = {}
1358
1352
  if includeProperties:
1359
- for index, item in enumerate(includeProperties):
1360
- tmp[item] = r[f'o{index}']
1353
+ for index, property in enumerate(includeProperties):
1354
+ if result[r['s']].get(property, None) is None:
1355
+ result[r['s']][property] = []
1356
+ raw = r.get(f'o{index}')
1357
+ if raw is None:
1358
+ continue
1359
+ if raw not in result[r['s']][property]:
1360
+ result[r['s']][property].append(raw)
1361
+ if includeProperties:
1362
+ for k, v in result.items():
1363
+ for index, property in enumerate(includeProperties):
1364
+ is_langstring = False
1365
+ for val in v[property]:
1366
+ if isinstance(val, Xsd_string) and val.lang is not None:
1367
+ is_langstring = True
1368
+ break
1369
+ if is_langstring:
1370
+ v[property] = LangString(v[property])
1361
1371
 
1362
- if sortBy:
1363
- if sortBy == SortBy.CREATED:
1364
- tmp[Xsd_QName('oldap:creationDate')] = r['creationDate']
1365
- if sortBy == SortBy.LASTMOD:
1366
- tmp[Xsd_QName('oldap:lastModificationDate')] = r['lastModificationDate']
1367
- result[r['s']] = tmp
1368
1372
  return result
1369
1373
 
1370
1374
  @staticmethod
oldaplib/src/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.4.5"
1
+ __version__ = "0.4.6"
@@ -10,7 +10,7 @@ import jwt
10
10
  from oldaplib.src.cachesingleton import CacheSingletonRedis
11
11
  from oldaplib.src.datamodel import DataModel
12
12
  from oldaplib.src.enums.adminpermissions import AdminPermission
13
- from oldaplib.src.objectfactory import ResourceInstanceFactory, SortBy, ResourceInstance
13
+ from oldaplib.src.objectfactory import ResourceInstanceFactory, SortBy, ResourceInstance, SortDir
14
14
  from oldaplib.src.connection import Connection
15
15
  from oldaplib.src.enums.action import Action
16
16
  from oldaplib.src.enums.datapermissions import DataPermission
@@ -63,6 +63,7 @@ from oldaplib.src.xsd.xsd_unsignedbyte import Xsd_unsignedByte
63
63
  from oldaplib.src.xsd.xsd_unsignedint import Xsd_unsignedInt
64
64
  from oldaplib.src.xsd.xsd_unsignedlong import Xsd_unsignedLong
65
65
  from oldaplib.src.xsd.xsd_unsignedshort import Xsd_unsignedShort
66
+ from redis.commands.search.aggregation import SortDirection
66
67
 
67
68
 
68
69
  def find_project_root(current_path):
@@ -486,6 +487,7 @@ class TestObjectFactory(unittest.TestCase):
486
487
  SetterTester = factory.createObjectInstance('SetterTester')
487
488
  b = SetterTester(stringSetter="This is a test string",
488
489
  langStringSetter=["C'est un string de test@fr", "Dies ist eine Testzeichenkette@de"],
490
+ langStringSetter2=["gagagagag@de"],
489
491
  decimalSetter=Xsd_decimal(3.14),
490
492
  integerSetter={20200, 30300},
491
493
  attachedToRole={Xsd_QName('oldap:Unknown'): DataPermission.DATA_VIEW})
@@ -508,6 +510,7 @@ class TestObjectFactory(unittest.TestCase):
508
510
  SetterTester = factory.createObjectInstance('SetterTester')
509
511
  obj1 = SetterTester(stringSetter="This is a test string",
510
512
  langStringSetter=LangString("This is a test string@de"),
513
+ langStringSetter2=LangString("This is a test string2@de"),
511
514
  decimalSetter=Xsd_decimal(3.14),
512
515
  integerSetter={20200, 30300},
513
516
  grantsPermission={Iri('oldap:GenericView'), Iri('oldap:GenericUpdate')})
@@ -563,6 +566,7 @@ class TestObjectFactory(unittest.TestCase):
563
566
  SetterTester = factory.createObjectInstance('SetterTester')
564
567
  obj1 = SetterTester(stringSetter="This is a test string",
565
568
  langStringSetter=LangString("C'est un teste@fr", "Dies ist eine Test-Zeichenkette@de"),
569
+ langStringSetter2=LangString("C'est un teste2@fr", "Dies ist eine Test-Zeichenkette2@de"),
566
570
  decimalSetter=Xsd_decimal(3.14),
567
571
  integerSetter={-10, 20},
568
572
  booleanSetter=True,
@@ -591,6 +595,7 @@ class TestObjectFactory(unittest.TestCase):
591
595
  SetterTester = factory.createObjectInstance('SetterTester')
592
596
  obj1 = SetterTester(stringSetter="This is a test string",
593
597
  langStringSetter=LangString("C'est un teste@fr", "Dies ist eine Test-Zeichenkette@de"),
598
+ langStringSetter2=LangString("C'est un teste2@fr", "Dies ist eine Test-Zeichenkette2@de"),
594
599
  decimalSetter=Xsd_decimal(3.14),
595
600
  integerSetter={-10, 20},
596
601
  booleanSetter=True,
@@ -619,6 +624,7 @@ class TestObjectFactory(unittest.TestCase):
619
624
  SetterTester = factory.createObjectInstance('SetterTester')
620
625
  obj1 = SetterTester(stringSetter="This is a test string",
621
626
  langStringSetter=LangString("C'est un teste@fr", "Dies ist eine Test-Zeichenkette@de"),
627
+ langStringSetter2=LangString("C'est un teste2@fr", "Dies ist eine Test-Zeichenkette2@de"),
622
628
  decimalSetter=Xsd_decimal(3.14),
623
629
  booleanSetter=True,
624
630
  grantsPermission={Iri('oldap:GenericView'), Iri('oldap:GenericUpdate')})
@@ -629,11 +635,29 @@ class TestObjectFactory(unittest.TestCase):
629
635
  obj1 = SetterTester.read(con=self._connection, iri=obj1.iri)
630
636
  self.assertEqual(obj1.integerSetter, {Xsd_int(1)})
631
637
 
638
+ def test_value_modifier_D(self):
639
+ factory = ResourceInstanceFactory(con=self._connection, project='test')
640
+ SetterTester = factory.createObjectInstance('SetterTester')
641
+ obj1 = SetterTester(stringSetter="This is a test string",
642
+ langStringSetter=LangString("C'est un teste@fr"),
643
+ langStringSetter2=LangString("C'est un teste2@fr"),
644
+ decimalSetter=Xsd_decimal(3.14),
645
+ booleanSetter=True,
646
+ grantsPermission={Iri('oldap:GenericView'), Iri('oldap:GenericUpdate')})
647
+ obj1.create()
648
+ obj1 = SetterTester.read(con=self._connection, iri=obj1.iri)
649
+ obj1[Xsd_QName('test:langStringSetter')][Language.FR] = "Qu'est-ce que c'est?"
650
+ obj1.update()
651
+ obj1 = SetterTester.read(con=self._connection, iri=obj1.iri)
652
+ self.assertEqual(obj1.langStringSetter, LangString("Qu'est-ce que c'est?@fr"))
653
+
654
+
632
655
  def test_value_modifier_add_lang(self):
633
656
  factory = ResourceInstanceFactory(con=self._connection, project='test')
634
657
  SetterTester = factory.createObjectInstance('SetterTester')
635
658
  obj1 = SetterTester(stringSetter="This is a test string",
636
659
  langStringSetter=LangString("C'est un teste@fr"),
660
+ langStringSetter2=LangString("C'est un teste2@fr"),
637
661
  decimalSetter=Xsd_decimal(3.14),
638
662
  booleanSetter=True,
639
663
  grantsPermission={Iri('oldap:GenericView'), Iri('oldap:GenericUpdate')})
@@ -649,6 +673,7 @@ class TestObjectFactory(unittest.TestCase):
649
673
  SetterTester = factory.createObjectInstance('SetterTester')
650
674
  obj1 = SetterTester(stringSetter="This is a test string",
651
675
  langStringSetter=LangString("Waseliwas@de", "C'est un teste@fr"),
676
+ langStringSetter2=LangString("Waseliwas2@de", "C'est un teste2@fr"),
652
677
  decimalSetter=Xsd_decimal(3.14),
653
678
  booleanSetter=True,
654
679
  grantsPermission={Iri('oldap:GenericView'), Iri('oldap:GenericUpdate')})
@@ -664,6 +689,7 @@ class TestObjectFactory(unittest.TestCase):
664
689
  SetterTester = factory.createObjectInstance('SetterTester')
665
690
  obj1 = SetterTester(stringSetter="This is a test string",
666
691
  langStringSetter=LangString("Waseliwas@de", "C'est un teste@fr"),
692
+ langStringSetter2=LangString("Waseliwas2@de", "C'est un teste2@fr"),
667
693
  decimalSetter=Xsd_decimal(3.14),
668
694
  booleanSetter=True,
669
695
  grantsPermission={Iri('oldap:GenericView'), Iri('oldap:GenericUpdate')})
@@ -679,6 +705,7 @@ class TestObjectFactory(unittest.TestCase):
679
705
  SetterTester = factory.createObjectInstance('SetterTester')
680
706
  obj1 = SetterTester(stringSetter="This is a test string",
681
707
  langStringSetter=LangString("Waseliwas@de", "C'est un teste@fr"),
708
+ langStringSetter2=LangString("Waseliwas2@de", "C'est un teste2@fr"),
682
709
  decimalSetter=Xsd_decimal(3.14),
683
710
  booleanSetter=True,
684
711
  grantsPermission={Iri('oldap:GenericView'), Iri('oldap:GenericUpdate')})
@@ -697,6 +724,7 @@ class TestObjectFactory(unittest.TestCase):
697
724
  SetterTester = factory.createObjectInstance('SetterTester')
698
725
  obj1 = SetterTester(stringSetter="This is a test string",
699
726
  langStringSetter=LangString("C'est un teste@fr"),
727
+ langStringSetter2=LangString("C'est un teste2@fr"),
700
728
  decimalSetter=Xsd_decimal(3.14),
701
729
  booleanSetter=True,
702
730
  grantsPermission={Iri('oldap:GenericView'), Iri('oldap:GenericUpdate')})
@@ -712,6 +740,7 @@ class TestObjectFactory(unittest.TestCase):
712
740
  SetterTester = factory.createObjectInstance('SetterTester')
713
741
  obj1 = SetterTester(stringSetter="This is a test string",
714
742
  langStringSetter=LangString("C'est un teste@fr"),
743
+ langStringSetter2=LangString("C'est un teste2@fr"),
715
744
  decimalSetter=Xsd_decimal(3.14),
716
745
  booleanSetter=True,
717
746
  integerSetter={20200, 30300},
@@ -727,6 +756,7 @@ class TestObjectFactory(unittest.TestCase):
727
756
  SetterTester = factory.createObjectInstance('SetterTester')
728
757
  obj1 = SetterTester(stringSetter="This is a test string",
729
758
  langStringSetter=LangString("C'est un teste@fr"),
759
+ langStringSetter2=LangString("C'est un teste2@fr"),
730
760
  decimalSetter=Xsd_decimal(3.14),
731
761
  booleanSetter=True,
732
762
  integerSetter={20200, 30300},
@@ -761,6 +791,7 @@ class TestObjectFactory(unittest.TestCase):
761
791
  SetterTester = factory.createObjectInstance('SetterTester')
762
792
  obj1 = SetterTester(stringSetter="This is a test string",
763
793
  langStringSetter=LangString("C'est un teste@fr", "Dies ist eine Test-Zeichenkette@de"),
794
+ langStringSetter2=LangString("C'est un teste2@fr", "Dies ist eine Test-Zeichenkette2@de"),
764
795
  decimalSetter={Xsd_decimal(3.14159), Xsd_decimal(2.71828), Xsd_decimal(1.61803)},
765
796
  integerSetter={-10, 20},
766
797
  booleanSetter=True,
@@ -877,8 +908,8 @@ class TestObjectFactory(unittest.TestCase):
877
908
  res = ResourceInstance.search_fulltext(con=self._connection,
878
909
  projectShortName='test',
879
910
  resClass='test:Book',
880
- s='geschichte',
881
- sortBy=SortBy.CREATED)
911
+ searchstr='geschichte',
912
+ sortBy=[SortBy('oldap:creationDate', SortDir.desc)])
882
913
 
883
914
  self.assertEqual(len(res), 2)
884
915
  for x, y in res.items():
@@ -886,8 +917,8 @@ class TestObjectFactory(unittest.TestCase):
886
917
 
887
918
  res = ResourceInstance.search_fulltext(con=self._connection,
888
919
  projectShortName='test',
889
- s='spez',
890
- sortBy=SortBy.CREATED)
920
+ searchstr='spez',
921
+ sortBy=[SortBy('oldap:creationDate', SortDir.desc)])
891
922
 
892
923
  self.assertEqual(len(res), 5)
893
924
  for x, y in res.items():
@@ -898,7 +929,7 @@ class TestObjectFactory(unittest.TestCase):
898
929
  projectShortName='test',
899
930
  resClass='test:Page',
900
931
  includeProperties=[Xsd_QName('test:pageNum'), Xsd_QName('test:pageContent')],
901
- sortBy = SortBy.CREATED)
932
+ sortBy = [SortBy(Xsd_QName('oldap:creationDate'), SortDir.asc)])
902
933
  self.assertEqual(len(res), 8)
903
934
  for r in res:
904
935
  self.assertEqual(len(res[r]), 3)
@@ -909,6 +940,14 @@ class TestObjectFactory(unittest.TestCase):
909
940
  resClass='test:Page')
910
941
  self.assertEqual(len(res), 8)
911
942
 
943
+ def test_search_resource_D(self):
944
+ res = ResourceInstance.all_resources(con=self._connection,
945
+ projectShortName='test',
946
+ resClass='test:Book',
947
+ includeProperties=[Xsd_QName('test:title'), Xsd_QName('test:author')])
948
+ #self.assertEqual(len(res), 8)
949
+ pprint(res)
950
+
912
951
  #@unittest.skip('Work in progress')
913
952
  def test_read_media_object_by_id_A(self):
914
953
  res = ResourceInstance.get_media_object_by_id(con=self._connection, mediaObjectId='x_34db.tif')
@@ -1,3 +1,8 @@
1
+ @prefix test: <https://test4.example.com/> .
2
+ @prefix test: <https://test4.example.com/> .
3
+ @prefix test: <https://test4.example.com/> .
4
+ @prefix schema: <http://schema.org/> .
5
+ @prefix schema: <http://schema.org/> .
1
6
  @prefix http: <http://www.w3.org/2011/http#> .
2
7
  @prefix : <http://oldap.org/base#> .
3
8
  @prefix test: <http://oldap.org/test#> .
@@ -5,13 +10,33 @@
5
10
  @prefix shared: <http://oldap.org/shared#> .
6
11
 
7
12
  test:data {
13
+
14
+ test:DouglasAdams a test:Person ;
15
+ :createdBy <https://orcid.org/0000-0003-1681-4036> ;
16
+ :creationDate "2025-11-13T16:43:21.284536+01:00"^^xsd:dateTimeStamp;
17
+ :lastModifiedBy <https://orcid.org/0000-0003-1681-4036> ;
18
+ :lastModificationDate "2025-11-13T16:43:21.284536+01:00"^^xsd:dateTimeStamp ;
19
+ :attachedToRole :Unknown ;
20
+ schema:familyName "Adams" ;
21
+ schema:givenName "Douglas" .
22
+
23
+ test:ConanDoyle a test:Person ;
24
+ :createdBy <https://orcid.org/0000-0003-1681-4036> ;
25
+ :creationDate "2025-11-13T16:43:21.284536+01:00"^^xsd:dateTimeStamp;
26
+ :lastModifiedBy <https://orcid.org/0000-0003-1681-4036> ;
27
+ :lastModificationDate "2025-11-13T16:43:21.284536+01:00"^^xsd:dateTimeStamp ;
28
+ :attachedToRole :Unknown ;
29
+ schema:familyName "Doyle" ;
30
+ schema:givenName "Conan" .
31
+
8
32
  <urn:uuid:7a1de6d7-de75-4875-ab24-74819057703f> a test:Book ;
9
33
  :createdBy <https://orcid.org/0000-0003-1681-4036> ;
10
34
  :creationDate "2025-11-13T16:43:21.284536+01:00"^^xsd:dateTimeStamp;
11
35
  :lastModifiedBy <https://orcid.org/0000-0003-1681-4036> ;
12
36
  :lastModificationDate "2025-11-13T16:43:21.284536+01:00"^^xsd:dateTimeStamp ;
13
37
  :attachedToRole :Unknown ;
14
- test:title "Die Geschichte der Spez. tQh5OAgXOaK5"@de ;
38
+ test:title "Die Geschichte der Spez. tQh5OAgXOaK5"@de , "L'histoire de la Spez. tQh5OAgXOaK5"@fr ;
39
+ test:author test:DouglasAdams, test:ConanDoyle ;
15
40
  test:pubDate "2026-01-01"^^xsd:date .
16
41
 
17
42
  << <urn:uuid:7a1de6d7-de75-4875-ab24-74819057703f> :attachedToRole :Unknown>> :hasDataPermission :DATA_VIEW .
@@ -297,6 +297,17 @@ test:shacl {
297
297
  sh:order "2.0"^^xsd:decimal ;
298
298
  sh:minCount "1"^^xsd:integer ;
299
299
  ] ;
300
+ sh:property
301
+ [
302
+ sh:path test:langStringSetter2 ;
303
+ dcterms:creator <https://orcid.org/0000-0003-1681-4036> ;
304
+ dcterms:created "2024-05-16T18:38:25.551434"^^xsd:dateTime ;
305
+ dcterms:contributor <https://orcid.org/0000-0003-1681-4036> ;
306
+ dcterms:modified "2024-05-16T18:38:25.551434"^^xsd:dateTime ;
307
+ sh:datatype rdf:langString ;
308
+ sh:order "2.0"^^xsd:decimal ;
309
+ sh:minCount "1"^^xsd:integer ;
310
+ ] ;
300
311
  sh:property
301
312
  [
302
313
  sh:path test:booleanSetter ;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: oldaplib
3
- Version: 0.4.5
3
+ Version: 0.4.6
4
4
  Summary: Open Media Access Server Library (Linked Open Data middleware/RESTApi)
5
5
  License: GNU Affero General Public License version 3
6
6
  Author: Lukas Rosenthaler
@@ -28,7 +28,7 @@ oldaplib/src/enums/datapermissions.py,sha256=MiaVHXzNDKTGnZJ9pvs-IgQotyV4wA3X484
28
28
  oldaplib/src/enums/editor.py,sha256=sb7jMh7eC4pq3fEGK2ufZKwcUD84wnzGLXoRrhjp6Ro,2163
29
29
  oldaplib/src/enums/externalontologyattr.py,sha256=H7SrWrhe1Dkz_t1OFCWZVh3_14lJDltYGh3dOFr1Z6w,807
30
30
  oldaplib/src/enums/haspropertyattr.py,sha256=i_KiPY9cUi8QHdYHjwPLmEMPIiJDFV8jBdT-JVFiZxA,873
31
- oldaplib/src/enums/language.py,sha256=OfQsFpIBj8lGBbZEqVCR_1F-bimPM48vqBl4EKBgggY,4623
31
+ oldaplib/src/enums/language.py,sha256=X6x6amxmPA5pI8F_vaqh6AJ7YrZaWFS96xpw2KJ2DwQ,4790
32
32
  oldaplib/src/enums/oldaplistattr.py,sha256=xuOU3oP35-PFFmlI-jlN28yqdk5lp_OzScKCC1O4IDI,620
33
33
  oldaplib/src/enums/oldaplistnodeattr.py,sha256=qokSxE-0FLyWNipjjY3gZJC2bBEt1qS1Z2SFg-gb0kc,722
34
34
  oldaplib/src/enums/owlpropertytype.py,sha256=R7DaCV4vtkGeuDhslN3q7719J1sLKUL-x0o91Te7Qk8,989
@@ -62,8 +62,8 @@ oldaplib/src/helpers/singletonmeta.py,sha256=bz_c5LFcRxxYirL9EDaFrWlc5WhAzR2uz9k
62
62
  oldaplib/src/helpers/tools.py,sha256=sNbiOLucTGNFzZmiWwPLFOb80VTXQH0Zd9uCGubhzAk,12721
63
63
  oldaplib/src/iconnection.py,sha256=XlOc2Kh4tK_UOHydLQwlWjUFLUze-Aq_vEZpf9KS1-s,3677
64
64
  oldaplib/src/in_project.py,sha256=ZnfeOFwpdPh1oyC2mAGH8DnSD9afxYtvsh7_GrfGVgQ,10663
65
- oldaplib/src/model.py,sha256=wgvXaR2GVHk4hJxoL6rigFHwjPYEukBOjtf1Jmo-m9A,19326
66
- oldaplib/src/objectfactory.py,sha256=4pPzsbbjnmtAobMH4ZIazwFZVzCuOd8MZWCZ2lZgOz8,85862
65
+ oldaplib/src/model.py,sha256=YG_d4qyo7kadwns-51dXGWYCLWNr9PPuIJLYSF7KmQs,19493
66
+ oldaplib/src/objectfactory.py,sha256=yppOYyMNhrG6QeYkpkLTWhFGaeW5dXwCUUWD1Jvzc0k,85943
67
67
  oldaplib/src/oldaplist.py,sha256=s5afrHtUnvDfMUFoZTt-jMxlBlmK2c0tLeTMp0KiIfg,43077
68
68
  oldaplib/src/oldaplist_helpers.py,sha256=D_X7KdFjPNlX-OwR04D6onxhFucrGo8052WuJPRjLkA,14213
69
69
  oldaplib/src/oldaplistnode.py,sha256=NnC2juEGTtEkDO6OlB9PjSw_zTF-wSsRUgEk-6VV9DA,87344
@@ -74,7 +74,7 @@ oldaplib/src/resourceclass.py,sha256=zJNWNY1TfhGs-A2HNa1DO0KAajps_1jMQsoEkUsr7P0
74
74
  oldaplib/src/role.py,sha256=AWtZx80OVERT2xbKeuP8g32VSXkm4MVlzeUWd9nh6mQ,30741
75
75
  oldaplib/src/user.py,sha256=iTJzSvR0xfc3FFkoKG-q5LptkWB_PGpRGpG-L3271z8,55833
76
76
  oldaplib/src/userdataclass.py,sha256=4kWktau9XSv5alfEVuOvikfxnSSUSKT8cw77TWdMhQM,13921
77
- oldaplib/src/version.py,sha256=LHFUavV7Y99A-kKkHFv_mfCPFBihywzHsYRHNSa6xBs,21
77
+ oldaplib/src/version.py,sha256=kz_EtUK14aaAj9cTvW7Wp3hr3-OKQMeZoE6Yry0bGJo,21
78
78
  oldaplib/src/xsd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
79
  oldaplib/src/xsd/floatingpoint.py,sha256=rDReKqh0mXyc4F5wslgTUxbeGf3-PGERyughj5_62YI,8852
80
80
  oldaplib/src/xsd/iri.py,sha256=VrM1rgs-DKEuYLI8SUBp7QWMEZbxzxoUcvFKKfqY7mA,8454
@@ -130,7 +130,7 @@ oldaplib/test/test_hasproperty.py,sha256=_cc-wH_b4c_GIDOLQxirbAS7486KC19YSUxzykf
130
130
  oldaplib/test/test_in_project.py,sha256=OV5csuPwxcctmOM2HsB_ITmXXASRcH9-A2GlWW5foa4,7580
131
131
  oldaplib/test/test_langstring.py,sha256=37BeKiQzj63G-SyS_paK_SEG7ulRbGrE89Mz40UB_bE,15146
132
132
  oldaplib/test/test_language_in.py,sha256=ELqHO-YIsZSCPF3E3rWde4J7rERL7En7sV_pzQ00zgs,8826
133
- oldaplib/test/test_objectfactory.py,sha256=znSEy7VagIU6tcgXyw91aPMxjFNS8Nc7Ne3sJALhpno,55447
133
+ oldaplib/test/test_objectfactory.py,sha256=Bvka-IljFvvUnq79lMHnMv7BTUki3xB2d4jgwdbAgMA,58262
134
134
  oldaplib/test/test_observable_dict.py,sha256=GxD0sM0nsVfVRBu92SFGkJ6--YXq4ibBWI4IpjZZzDU,1396
135
135
  oldaplib/test/test_observable_set.py,sha256=JWZSoAsr8XIEBXPVgSVJjQQEEc8uSAme5IrFYLYVVXw,6313
136
136
  oldaplib/test/test_oldaplist.py,sha256=jMM3HiSFs7YcS2ltEvot6637EhK-fMV0W5DSUlFdTRI,20098
@@ -150,12 +150,12 @@ oldaplib/testdata/connection_test.trig,sha256=LFTGLEae7SaTU67rwvgvg_epi09O7oPZwf
150
150
  oldaplib/testdata/datamodel_test.trig,sha256=0n02awPthzi-Lx-_ABlrD9yZ3I1sWxp7eIbFwSxwKNA,802
151
151
  oldaplib/testdata/event_type.yaml,sha256=wpXiheSEKh4xOoUZvAxWytJQ-sNK6oUYdVpOmyW9wPc,3083
152
152
  oldaplib/testdata/hlist_schema.yaml,sha256=fgHiB-ZxOkE6OvkZKk9SL2kNn8Akj6dS6ySDFSpknTA,186
153
- oldaplib/testdata/instances_test.trig,sha256=suWL71fvNAnhpJfvAyq0VUvYQe2hNvDjf0rah2Ogb_M,9516
153
+ oldaplib/testdata/instances_test.trig,sha256=npuwyxLY2H2BlFa5o8nHcio1EsTbEQujSr2wux9T1VU,10636
154
154
  oldaplib/testdata/institution_or_building_type.yaml,sha256=SA2rsQwoAdyn6eSIJU1ilmdIQf-f1XNApwBow-JlJTo,2439
155
155
  oldaplib/testdata/language.yaml,sha256=YaQA77d7QyOydqNylR5RSb-0A6h9pLM4mgadJSrYC3A,451
156
156
  oldaplib/testdata/location_type.yaml,sha256=amlhYNDc9qLv_if6urtAtBTnEXrVrb6_aulE180GYkc,1323
157
157
  oldaplib/testdata/means_of_transportation.yaml,sha256=WOqtSHlw8gCK54d5hmibCWyL_H1DRtBBpUdFNwIUBJo,788
158
- oldaplib/testdata/objectfactory_test.trig,sha256=ZwO2dglOmkGLoTQFNkZ2tJJwKEWdIjiyuQlLTSVYxYA,80576
158
+ oldaplib/testdata/objectfactory_test.trig,sha256=1Gm-dYbo0FmIwhMtg70KP1Tt77gvQQ79Knv_eYRWxdo,81164
159
159
  oldaplib/testdata/playground_list.yaml,sha256=EypG4WQoq9emI10Hj-DrKjplgxr1MrQBPc0ppV_rHQQ,1620
160
160
  oldaplib/testdata/role.yaml,sha256=CLI9f2HD_ulYw67DqWntaMLWH0CGWz1cfNkvxcnK6XQ,691
161
161
  oldaplib/testdata/source_type-1.yaml,sha256=Khow4rD8oZgBAbUex4T-nKBTrx0bAseMhTShS7-MgGw,921
@@ -163,6 +163,6 @@ oldaplib/testdata/source_type.yaml,sha256=dSihKikw3O-IlGf6anj5KWMoBYLaweLVF1Zojm
163
163
  oldaplib/testdata/test_move_left_of_toL.yaml,sha256=2m1OSQrQFlsCQxeJrjzBAO74LMprNDo_HuyrYGsOeXI,787
164
164
  oldaplib/testdata/testlist.yaml,sha256=AT11nXEG81Sfyb-tr1gQV0H_dZBrOCcFuHf7YtL8P2g,1994
165
165
  oldaplib/testit.http,sha256=qW7mnr6aNLXFG6lQdLgyhXILOPN6qc5iFVZclLyVvkY,303
166
- oldaplib-0.4.5.dist-info/METADATA,sha256=VLeo79-yIMMJG2qmHv-s4uBvZrNntcNPYXp_RAkpLvQ,3035
167
- oldaplib-0.4.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
168
- oldaplib-0.4.5.dist-info/RECORD,,
166
+ oldaplib-0.4.6.dist-info/METADATA,sha256=hk5GKur9imdwD_w2yuHf1xf19qB_rTWx7rYdmkaKrpU,3035
167
+ oldaplib-0.4.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
168
+ oldaplib-0.4.6.dist-info/RECORD,,