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.
Files changed (348) hide show
  1. dsp_tools/__init__.py +5 -0
  2. dsp_tools/cli/args.py +47 -0
  3. dsp_tools/cli/call_action.py +85 -0
  4. dsp_tools/cli/call_action_files_only.py +101 -0
  5. dsp_tools/cli/call_action_with_network.py +207 -0
  6. dsp_tools/cli/create_parsers.py +479 -0
  7. dsp_tools/cli/entry_point.py +322 -0
  8. dsp_tools/cli/utils.py +87 -0
  9. dsp_tools/clients/CLAUDE.md +420 -0
  10. dsp_tools/clients/authentication_client.py +14 -0
  11. dsp_tools/clients/authentication_client_live.py +66 -0
  12. dsp_tools/clients/connection.py +35 -0
  13. dsp_tools/clients/connection_live.py +233 -0
  14. dsp_tools/clients/fuseki_metrics.py +60 -0
  15. dsp_tools/clients/group_user_clients.py +35 -0
  16. dsp_tools/clients/group_user_clients_live.py +181 -0
  17. dsp_tools/clients/legal_info_client.py +23 -0
  18. dsp_tools/clients/legal_info_client_live.py +132 -0
  19. dsp_tools/clients/list_client.py +49 -0
  20. dsp_tools/clients/list_client_live.py +166 -0
  21. dsp_tools/clients/metadata_client.py +24 -0
  22. dsp_tools/clients/metadata_client_live.py +47 -0
  23. dsp_tools/clients/ontology_clients.py +49 -0
  24. dsp_tools/clients/ontology_create_client_live.py +166 -0
  25. dsp_tools/clients/ontology_get_client_live.py +80 -0
  26. dsp_tools/clients/permissions_client.py +68 -0
  27. dsp_tools/clients/project_client.py +16 -0
  28. dsp_tools/clients/project_client_live.py +66 -0
  29. dsp_tools/commands/create/communicate_problems.py +24 -0
  30. dsp_tools/commands/create/create.py +134 -0
  31. dsp_tools/commands/create/create_on_server/cardinalities.py +111 -0
  32. dsp_tools/commands/create/create_on_server/classes.py +99 -0
  33. dsp_tools/commands/create/create_on_server/complete_ontologies.py +116 -0
  34. dsp_tools/commands/create/create_on_server/default_permissions.py +134 -0
  35. dsp_tools/commands/create/create_on_server/group_users.py +165 -0
  36. dsp_tools/commands/create/create_on_server/lists.py +163 -0
  37. dsp_tools/commands/create/create_on_server/mappers.py +12 -0
  38. dsp_tools/commands/create/create_on_server/onto_utils.py +74 -0
  39. dsp_tools/commands/create/create_on_server/ontology.py +52 -0
  40. dsp_tools/commands/create/create_on_server/project.py +68 -0
  41. dsp_tools/commands/create/create_on_server/properties.py +119 -0
  42. dsp_tools/commands/create/exceptions.py +29 -0
  43. dsp_tools/commands/create/lists_only.py +66 -0
  44. dsp_tools/commands/create/models/create_problems.py +87 -0
  45. dsp_tools/commands/create/models/parsed_ontology.py +88 -0
  46. dsp_tools/commands/create/models/parsed_project.py +81 -0
  47. dsp_tools/commands/create/models/rdf_ontology.py +12 -0
  48. dsp_tools/commands/create/models/server_project_info.py +100 -0
  49. dsp_tools/commands/create/parsing/parse_lists.py +45 -0
  50. dsp_tools/commands/create/parsing/parse_ontology.py +243 -0
  51. dsp_tools/commands/create/parsing/parse_project.py +149 -0
  52. dsp_tools/commands/create/parsing/parsing_utils.py +40 -0
  53. dsp_tools/commands/create/project_validate.py +595 -0
  54. dsp_tools/commands/create/serialisation/ontology.py +119 -0
  55. dsp_tools/commands/create/serialisation/project.py +44 -0
  56. dsp_tools/commands/excel2json/CLAUDE.md +101 -0
  57. dsp_tools/commands/excel2json/json_header.py +321 -0
  58. dsp_tools/commands/excel2json/lists/__init__.py +0 -0
  59. dsp_tools/commands/excel2json/lists/compliance_checks.py +292 -0
  60. dsp_tools/commands/excel2json/lists/make_lists.py +247 -0
  61. dsp_tools/commands/excel2json/lists/models/__init__.py +0 -0
  62. dsp_tools/commands/excel2json/lists/models/deserialise.py +30 -0
  63. dsp_tools/commands/excel2json/lists/models/input_error.py +216 -0
  64. dsp_tools/commands/excel2json/lists/models/serialise.py +57 -0
  65. dsp_tools/commands/excel2json/lists/utils.py +81 -0
  66. dsp_tools/commands/excel2json/models/__init__.py +0 -0
  67. dsp_tools/commands/excel2json/models/input_error.py +416 -0
  68. dsp_tools/commands/excel2json/models/json_header.py +175 -0
  69. dsp_tools/commands/excel2json/models/list_node_name.py +16 -0
  70. dsp_tools/commands/excel2json/models/ontology.py +76 -0
  71. dsp_tools/commands/excel2json/old_lists.py +328 -0
  72. dsp_tools/commands/excel2json/project.py +280 -0
  73. dsp_tools/commands/excel2json/properties.py +370 -0
  74. dsp_tools/commands/excel2json/resources.py +336 -0
  75. dsp_tools/commands/excel2json/utils.py +352 -0
  76. dsp_tools/commands/excel2xml/__init__.py +7 -0
  77. dsp_tools/commands/excel2xml/excel2xml_cli.py +523 -0
  78. dsp_tools/commands/excel2xml/excel2xml_lib.py +1953 -0
  79. dsp_tools/commands/excel2xml/propertyelement.py +47 -0
  80. dsp_tools/commands/get/__init__.py +0 -0
  81. dsp_tools/commands/get/get.py +166 -0
  82. dsp_tools/commands/get/get_permissions.py +257 -0
  83. dsp_tools/commands/get/get_permissions_legacy.py +89 -0
  84. dsp_tools/commands/get/legacy_models/__init__.py +0 -0
  85. dsp_tools/commands/get/legacy_models/context.py +318 -0
  86. dsp_tools/commands/get/legacy_models/group.py +241 -0
  87. dsp_tools/commands/get/legacy_models/helpers.py +47 -0
  88. dsp_tools/commands/get/legacy_models/listnode.py +390 -0
  89. dsp_tools/commands/get/legacy_models/model.py +12 -0
  90. dsp_tools/commands/get/legacy_models/ontology.py +324 -0
  91. dsp_tools/commands/get/legacy_models/project.py +366 -0
  92. dsp_tools/commands/get/legacy_models/propertyclass.py +417 -0
  93. dsp_tools/commands/get/legacy_models/resourceclass.py +676 -0
  94. dsp_tools/commands/get/legacy_models/user.py +438 -0
  95. dsp_tools/commands/get/models/__init__.py +0 -0
  96. dsp_tools/commands/get/models/permissions_models.py +10 -0
  97. dsp_tools/commands/id2iri.py +258 -0
  98. dsp_tools/commands/ingest_xmlupload/__init__.py +0 -0
  99. dsp_tools/commands/ingest_xmlupload/bulk_ingest_client.py +178 -0
  100. dsp_tools/commands/ingest_xmlupload/create_resources/__init__.py +0 -0
  101. dsp_tools/commands/ingest_xmlupload/create_resources/apply_ingest_id.py +69 -0
  102. dsp_tools/commands/ingest_xmlupload/create_resources/upload_xml.py +166 -0
  103. dsp_tools/commands/ingest_xmlupload/create_resources/user_information.py +121 -0
  104. dsp_tools/commands/ingest_xmlupload/ingest_files/__init__.py +0 -0
  105. dsp_tools/commands/ingest_xmlupload/ingest_files/ingest_files.py +64 -0
  106. dsp_tools/commands/ingest_xmlupload/upload_files/__init__.py +0 -0
  107. dsp_tools/commands/ingest_xmlupload/upload_files/filechecker.py +20 -0
  108. dsp_tools/commands/ingest_xmlupload/upload_files/input_error.py +57 -0
  109. dsp_tools/commands/ingest_xmlupload/upload_files/upload_failures.py +66 -0
  110. dsp_tools/commands/ingest_xmlupload/upload_files/upload_files.py +67 -0
  111. dsp_tools/commands/resume_xmlupload/__init__.py +0 -0
  112. dsp_tools/commands/resume_xmlupload/resume_xmlupload.py +96 -0
  113. dsp_tools/commands/start_stack.py +428 -0
  114. dsp_tools/commands/update_legal/CLAUDE.md +344 -0
  115. dsp_tools/commands/update_legal/__init__.py +0 -0
  116. dsp_tools/commands/update_legal/core.py +182 -0
  117. dsp_tools/commands/update_legal/csv_operations.py +135 -0
  118. dsp_tools/commands/update_legal/models.py +87 -0
  119. dsp_tools/commands/update_legal/xml_operations.py +247 -0
  120. dsp_tools/commands/validate_data/CLAUDE.md +159 -0
  121. dsp_tools/commands/validate_data/__init__.py +0 -0
  122. dsp_tools/commands/validate_data/constants.py +59 -0
  123. dsp_tools/commands/validate_data/mappers.py +143 -0
  124. dsp_tools/commands/validate_data/models/__init__.py +0 -0
  125. dsp_tools/commands/validate_data/models/api_responses.py +45 -0
  126. dsp_tools/commands/validate_data/models/input_problems.py +119 -0
  127. dsp_tools/commands/validate_data/models/rdf_like_data.py +117 -0
  128. dsp_tools/commands/validate_data/models/validation.py +106 -0
  129. dsp_tools/commands/validate_data/prepare_data/__init__.py +0 -0
  130. dsp_tools/commands/validate_data/prepare_data/get_rdf_like_data.py +296 -0
  131. dsp_tools/commands/validate_data/prepare_data/make_data_graph.py +91 -0
  132. dsp_tools/commands/validate_data/prepare_data/prepare_data.py +184 -0
  133. dsp_tools/commands/validate_data/process_validation_report/__init__.py +0 -0
  134. dsp_tools/commands/validate_data/process_validation_report/get_user_validation_message.py +358 -0
  135. dsp_tools/commands/validate_data/process_validation_report/query_validation_result.py +507 -0
  136. dsp_tools/commands/validate_data/process_validation_report/reformat_validation_results.py +150 -0
  137. dsp_tools/commands/validate_data/shacl_cli_validator.py +70 -0
  138. dsp_tools/commands/validate_data/sparql/__init__.py +0 -0
  139. dsp_tools/commands/validate_data/sparql/cardinality_shacl.py +209 -0
  140. dsp_tools/commands/validate_data/sparql/construct_shacl.py +92 -0
  141. dsp_tools/commands/validate_data/sparql/legal_info_shacl.py +36 -0
  142. dsp_tools/commands/validate_data/sparql/value_shacl.py +357 -0
  143. dsp_tools/commands/validate_data/utils.py +59 -0
  144. dsp_tools/commands/validate_data/validate_data.py +283 -0
  145. dsp_tools/commands/validate_data/validation/__init__.py +0 -0
  146. dsp_tools/commands/validate_data/validation/check_duplicate_files.py +55 -0
  147. dsp_tools/commands/validate_data/validation/check_for_unknown_classes.py +67 -0
  148. dsp_tools/commands/validate_data/validation/get_validation_report.py +94 -0
  149. dsp_tools/commands/validate_data/validation/validate_ontology.py +107 -0
  150. dsp_tools/commands/xmlupload/CLAUDE.md +292 -0
  151. dsp_tools/commands/xmlupload/__init__.py +0 -0
  152. dsp_tools/commands/xmlupload/iri_resolver.py +21 -0
  153. dsp_tools/commands/xmlupload/make_rdf_graph/__init__.py +0 -0
  154. dsp_tools/commands/xmlupload/make_rdf_graph/constants.py +63 -0
  155. dsp_tools/commands/xmlupload/make_rdf_graph/jsonld_utils.py +44 -0
  156. dsp_tools/commands/xmlupload/make_rdf_graph/make_file_value.py +77 -0
  157. dsp_tools/commands/xmlupload/make_rdf_graph/make_resource_and_values.py +114 -0
  158. dsp_tools/commands/xmlupload/make_rdf_graph/make_values.py +262 -0
  159. dsp_tools/commands/xmlupload/models/__init__.py +0 -0
  160. dsp_tools/commands/xmlupload/models/bitstream_info.py +18 -0
  161. dsp_tools/commands/xmlupload/models/formatted_text_value.py +10 -0
  162. dsp_tools/commands/xmlupload/models/ingest.py +143 -0
  163. dsp_tools/commands/xmlupload/models/input_problems.py +58 -0
  164. dsp_tools/commands/xmlupload/models/lookup_models.py +21 -0
  165. dsp_tools/commands/xmlupload/models/permission.py +45 -0
  166. dsp_tools/commands/xmlupload/models/permissions_parsed.py +93 -0
  167. dsp_tools/commands/xmlupload/models/processed/__init__.py +0 -0
  168. dsp_tools/commands/xmlupload/models/processed/file_values.py +29 -0
  169. dsp_tools/commands/xmlupload/models/processed/res.py +27 -0
  170. dsp_tools/commands/xmlupload/models/processed/values.py +101 -0
  171. dsp_tools/commands/xmlupload/models/rdf_models.py +26 -0
  172. dsp_tools/commands/xmlupload/models/upload_clients.py +14 -0
  173. dsp_tools/commands/xmlupload/models/upload_state.py +20 -0
  174. dsp_tools/commands/xmlupload/prepare_xml_input/__init__.py +0 -0
  175. dsp_tools/commands/xmlupload/prepare_xml_input/ark2iri.py +55 -0
  176. dsp_tools/commands/xmlupload/prepare_xml_input/get_processed_resources.py +252 -0
  177. dsp_tools/commands/xmlupload/prepare_xml_input/iiif_uri_validator.py +50 -0
  178. dsp_tools/commands/xmlupload/prepare_xml_input/list_client.py +120 -0
  179. dsp_tools/commands/xmlupload/prepare_xml_input/prepare_xml_input.py +67 -0
  180. dsp_tools/commands/xmlupload/prepare_xml_input/read_validate_xml_file.py +58 -0
  181. dsp_tools/commands/xmlupload/prepare_xml_input/transform_input_values.py +118 -0
  182. dsp_tools/commands/xmlupload/resource_create_client.py +25 -0
  183. dsp_tools/commands/xmlupload/richtext_id2iri.py +37 -0
  184. dsp_tools/commands/xmlupload/stash/__init__.py +0 -0
  185. dsp_tools/commands/xmlupload/stash/analyse_circular_reference_graph.py +236 -0
  186. dsp_tools/commands/xmlupload/stash/create_info_for_graph.py +53 -0
  187. dsp_tools/commands/xmlupload/stash/graph_models.py +87 -0
  188. dsp_tools/commands/xmlupload/stash/stash_circular_references.py +68 -0
  189. dsp_tools/commands/xmlupload/stash/stash_models.py +109 -0
  190. dsp_tools/commands/xmlupload/stash/upload_stashed_resptr_props.py +106 -0
  191. dsp_tools/commands/xmlupload/stash/upload_stashed_xml_texts.py +196 -0
  192. dsp_tools/commands/xmlupload/upload_config.py +76 -0
  193. dsp_tools/commands/xmlupload/write_diagnostic_info.py +27 -0
  194. dsp_tools/commands/xmlupload/xmlupload.py +516 -0
  195. dsp_tools/config/__init__.py +0 -0
  196. dsp_tools/config/logger_config.py +69 -0
  197. dsp_tools/config/warnings_config.py +32 -0
  198. dsp_tools/error/__init__.py +0 -0
  199. dsp_tools/error/custom_warnings.py +39 -0
  200. dsp_tools/error/exceptions.py +204 -0
  201. dsp_tools/error/problems.py +10 -0
  202. dsp_tools/error/xmllib_errors.py +20 -0
  203. dsp_tools/error/xmllib_warnings.py +54 -0
  204. dsp_tools/error/xmllib_warnings_util.py +159 -0
  205. dsp_tools/error/xsd_validation_error_msg.py +19 -0
  206. dsp_tools/legacy_models/__init__.py +0 -0
  207. dsp_tools/legacy_models/datetimestamp.py +81 -0
  208. dsp_tools/legacy_models/langstring.py +253 -0
  209. dsp_tools/legacy_models/projectContext.py +49 -0
  210. dsp_tools/py.typed +0 -0
  211. dsp_tools/resources/schema/data.xsd +648 -0
  212. dsp_tools/resources/schema/lists-only.json +72 -0
  213. dsp_tools/resources/schema/project.json +1258 -0
  214. dsp_tools/resources/schema/properties-only.json +874 -0
  215. dsp_tools/resources/schema/resources-only.json +140 -0
  216. dsp_tools/resources/start-stack/docker-compose.override-host.j2 +11 -0
  217. dsp_tools/resources/start-stack/docker-compose.override.yml +11 -0
  218. dsp_tools/resources/start-stack/docker-compose.yml +88 -0
  219. dsp_tools/resources/start-stack/dsp-app-config.json +45 -0
  220. dsp_tools/resources/start-stack/dsp-app-config.override-host.j2 +26 -0
  221. dsp_tools/resources/validate_data/api-shapes-resource-cardinalities.ttl +191 -0
  222. dsp_tools/resources/validate_data/api-shapes.ttl +804 -0
  223. dsp_tools/resources/validate_data/shacl-cli-image.yml +4 -0
  224. dsp_tools/resources/validate_data/validate-ontology.ttl +99 -0
  225. dsp_tools/utils/__init__.py +0 -0
  226. dsp_tools/utils/ansi_colors.py +32 -0
  227. dsp_tools/utils/data_formats/__init__.py +0 -0
  228. dsp_tools/utils/data_formats/date_util.py +166 -0
  229. dsp_tools/utils/data_formats/iri_util.py +30 -0
  230. dsp_tools/utils/data_formats/shared.py +81 -0
  231. dsp_tools/utils/data_formats/uri_util.py +76 -0
  232. dsp_tools/utils/fuseki_bloating.py +63 -0
  233. dsp_tools/utils/json_parsing.py +22 -0
  234. dsp_tools/utils/rdf_constants.py +42 -0
  235. dsp_tools/utils/rdflib_utils.py +10 -0
  236. dsp_tools/utils/replace_id_with_iri.py +66 -0
  237. dsp_tools/utils/request_utils.py +238 -0
  238. dsp_tools/utils/xml_parsing/__init__.py +0 -0
  239. dsp_tools/utils/xml_parsing/get_lookups.py +32 -0
  240. dsp_tools/utils/xml_parsing/get_parsed_resources.py +325 -0
  241. dsp_tools/utils/xml_parsing/models/__init__.py +0 -0
  242. dsp_tools/utils/xml_parsing/models/parsed_resource.py +76 -0
  243. dsp_tools/utils/xml_parsing/parse_clean_validate_xml.py +137 -0
  244. dsp_tools/xmllib/CLAUDE.md +302 -0
  245. dsp_tools/xmllib/__init__.py +49 -0
  246. dsp_tools/xmllib/general_functions.py +877 -0
  247. dsp_tools/xmllib/internal/__init__.py +0 -0
  248. dsp_tools/xmllib/internal/checkers.py +162 -0
  249. dsp_tools/xmllib/internal/circumvent_circular_imports.py +36 -0
  250. dsp_tools/xmllib/internal/constants.py +46 -0
  251. dsp_tools/xmllib/internal/input_converters.py +155 -0
  252. dsp_tools/xmllib/internal/serialise_file_value.py +57 -0
  253. dsp_tools/xmllib/internal/serialise_resource.py +177 -0
  254. dsp_tools/xmllib/internal/serialise_values.py +152 -0
  255. dsp_tools/xmllib/internal/type_aliases.py +11 -0
  256. dsp_tools/xmllib/models/__init__.py +0 -0
  257. dsp_tools/xmllib/models/config_options.py +28 -0
  258. dsp_tools/xmllib/models/date_formats.py +48 -0
  259. dsp_tools/xmllib/models/dsp_base_resources.py +1542 -0
  260. dsp_tools/xmllib/models/internal/__init__.py +0 -0
  261. dsp_tools/xmllib/models/internal/file_values.py +172 -0
  262. dsp_tools/xmllib/models/internal/geometry.py +162 -0
  263. dsp_tools/xmllib/models/internal/migration_metadata.py +55 -0
  264. dsp_tools/xmllib/models/internal/serialise_permissions.py +66 -0
  265. dsp_tools/xmllib/models/internal/values.py +342 -0
  266. dsp_tools/xmllib/models/licenses/__init__.py +0 -0
  267. dsp_tools/xmllib/models/licenses/other.py +59 -0
  268. dsp_tools/xmllib/models/licenses/recommended.py +107 -0
  269. dsp_tools/xmllib/models/permissions.py +41 -0
  270. dsp_tools/xmllib/models/res.py +1782 -0
  271. dsp_tools/xmllib/models/root.py +348 -0
  272. dsp_tools/xmllib/value_checkers.py +434 -0
  273. dsp_tools/xmllib/value_converters.py +777 -0
  274. dsp_tools-18.3.0.post13.dist-info/METADATA +90 -0
  275. dsp_tools-18.3.0.post13.dist-info/RECORD +286 -0
  276. dsp_tools-18.3.0.post13.dist-info/WHEEL +4 -0
  277. dsp_tools-18.3.0.post13.dist-info/entry_points.txt +3 -0
  278. dsp_tools-0.9.13.dist-info/LICENSE +0 -674
  279. dsp_tools-0.9.13.dist-info/METADATA +0 -144
  280. dsp_tools-0.9.13.dist-info/RECORD +0 -71
  281. dsp_tools-0.9.13.dist-info/WHEEL +0 -5
  282. dsp_tools-0.9.13.dist-info/entry_points.txt +0 -3
  283. dsp_tools-0.9.13.dist-info/top_level.txt +0 -1
  284. dsplib/models/connection.py +0 -272
  285. dsplib/models/group.py +0 -296
  286. dsplib/models/helpers.py +0 -505
  287. dsplib/models/langstring.py +0 -277
  288. dsplib/models/listnode.py +0 -578
  289. dsplib/models/model.py +0 -20
  290. dsplib/models/ontology.py +0 -448
  291. dsplib/models/permission.py +0 -112
  292. dsplib/models/project.py +0 -547
  293. dsplib/models/propertyclass.py +0 -505
  294. dsplib/models/resource.py +0 -366
  295. dsplib/models/resourceclass.py +0 -810
  296. dsplib/models/sipi.py +0 -30
  297. dsplib/models/user.py +0 -731
  298. dsplib/models/value.py +0 -1000
  299. dsplib/utils/knora-data-schema.xsd +0 -454
  300. dsplib/utils/knora-schema-lists.json +0 -83
  301. dsplib/utils/knora-schema.json +0 -434
  302. dsplib/utils/onto_commons.py +0 -24
  303. dsplib/utils/onto_create_lists.py +0 -73
  304. dsplib/utils/onto_create_ontology.py +0 -442
  305. dsplib/utils/onto_get.py +0 -58
  306. dsplib/utils/onto_validate.py +0 -33
  307. dsplib/utils/xml_upload.py +0 -539
  308. dsplib/widgets/doublepassword.py +0 -80
  309. knora/MLS-import-libraries.py +0 -84
  310. knora/dsp_tools.py +0 -96
  311. knora/dsplib/models/connection.py +0 -272
  312. knora/dsplib/models/group.py +0 -296
  313. knora/dsplib/models/helpers.py +0 -506
  314. knora/dsplib/models/langstring.py +0 -277
  315. knora/dsplib/models/listnode.py +0 -578
  316. knora/dsplib/models/model.py +0 -20
  317. knora/dsplib/models/ontology.py +0 -448
  318. knora/dsplib/models/permission.py +0 -112
  319. knora/dsplib/models/project.py +0 -583
  320. knora/dsplib/models/propertyclass.py +0 -505
  321. knora/dsplib/models/resource.py +0 -416
  322. knora/dsplib/models/resourceclass.py +0 -811
  323. knora/dsplib/models/sipi.py +0 -35
  324. knora/dsplib/models/user.py +0 -731
  325. knora/dsplib/models/value.py +0 -1000
  326. knora/dsplib/utils/knora-data-schema.xsd +0 -464
  327. knora/dsplib/utils/knora-schema-lists.json +0 -83
  328. knora/dsplib/utils/knora-schema.json +0 -444
  329. knora/dsplib/utils/onto_commons.py +0 -24
  330. knora/dsplib/utils/onto_create_lists.py +0 -73
  331. knora/dsplib/utils/onto_create_ontology.py +0 -451
  332. knora/dsplib/utils/onto_get.py +0 -58
  333. knora/dsplib/utils/onto_validate.py +0 -33
  334. knora/dsplib/utils/xml_upload.py +0 -540
  335. knora/dsplib/widgets/doublepassword.py +0 -80
  336. knora/knora.py +0 -2108
  337. knora/test.py +0 -99
  338. knora/testit.py +0 -76
  339. knora/xml2knora.py +0 -633
  340. {dsplib → dsp_tools/cli}/__init__.py +0 -0
  341. {dsplib/models → dsp_tools/clients}/__init__.py +0 -0
  342. {dsplib/utils → dsp_tools/commands}/__init__.py +0 -0
  343. {dsplib/widgets → dsp_tools/commands/create}/__init__.py +0 -0
  344. {knora → dsp_tools/commands/create/create_on_server}/__init__.py +0 -0
  345. {knora/dsplib → dsp_tools/commands/create/models}/__init__.py +0 -0
  346. {knora/dsplib/models → dsp_tools/commands/create/parsing}/__init__.py +0 -0
  347. {knora/dsplib/utils → dsp_tools/commands/create/serialisation}/__init__.py +0 -0
  348. {knora/dsplib/widgets → dsp_tools/commands/excel2json}/__init__.py +0 -0
@@ -1,811 +0,0 @@
1
- import json
2
- import re
3
- from pystrict import strict
4
- from typing import List, Set, Dict, Tuple, Optional, Any, Union
5
- from enum import Enum
6
- from urllib.parse import quote_plus
7
-
8
- from pprint import pprint
9
-
10
- from .helpers import Actions, BaseError, Context, Cardinality, LastModificationDate
11
- from .connection import Connection
12
- from .model import Model
13
- from .langstring import Languages, LangString
14
-
15
- class SetEncoder(json.JSONEncoder):
16
- def default(self, obj):
17
- if isinstance(obj, set):
18
- return list(obj)
19
- return json.JSONEncoder.default(self, obj)
20
-
21
- """
22
- This model implements the handling of resource classes. It contains two classes that work closely together:
23
- * "HasProperty" deals with the association of Property-instances with the Resource-instances. This association
24
- is done using the "cardinality"-clause
25
- * "ResourceClass" is the main class representing a knora resource class.
26
- """
27
- @strict
28
- class HasProperty(Model):
29
- class Ptype(Enum):
30
- system = 1
31
- knora = 2
32
- other = 3
33
-
34
- _context: Context
35
- _ontology_id: str
36
- _property_id: str
37
- _resclass_id: str
38
- _cardinality: Cardinality
39
- _gui_order: int
40
- _is_inherited: bool
41
- _ptype: Ptype
42
-
43
- def __init__(self,
44
- con: Connection,
45
- context: Context,
46
- ontology_id: Optional[str] = None,
47
- property_id: Optional[str] = None,
48
- resclass_id: Optional[str] = None,
49
- cardinality: Optional[Cardinality] = None,
50
- gui_order: Optional[int] = None,
51
- is_inherited: Optional[bool] = None,
52
- ptype: Optional[Ptype] = None):
53
- super().__init__(con)
54
- if not isinstance(context, Context):
55
- raise BaseError('"context"-parameter must be an instance of Context')
56
- self._context = context
57
- if ontology_id is not None:
58
- self._ontology_id = context.iri_from_prefix(ontology_id)
59
- else:
60
- self._ontology_id = None
61
- self._property_id = property_id
62
- self._resclass_id = resclass_id
63
- self._cardinality = cardinality
64
- self._gui_order = gui_order
65
- self._is_inherited = is_inherited
66
- self._ptype = ptype
67
- self._changed = set()
68
-
69
- #
70
- # Here follows a list of getters/setters
71
- #
72
- @property
73
- def ontology_id(self) -> Optional[str]:
74
- return self._ontology_id
75
-
76
- @ontology_id.setter
77
- def ontology_id(self, value: Optional[str]) -> None:
78
- self._ontology_id = value
79
-
80
- @property
81
- def property_id(self) -> Optional[str]:
82
- return self._property_id
83
-
84
- @property_id.setter
85
- def property_id(self, value: str) -> None:
86
- raise BaseError('property_id "{}" cannot be modified!'.format(self._property_id))
87
-
88
- @property
89
- def resclass_id(self) -> Optional[str]:
90
- return self._resclass_id
91
-
92
- @resclass_id.setter
93
- def resclass_id(self, value: Optional[str]) -> None:
94
- self._resclass_id = value
95
-
96
- @property
97
- def cardinality(self) -> Optional[Cardinality]:
98
- return self._cardinality
99
-
100
- @cardinality.setter
101
- def cardinality(self, value: Optional[Cardinality]) -> None:
102
- self._cardinality = value
103
- self._changed.add('cardinality')
104
-
105
- @property
106
- def gui_order(self) -> Optional[int]:
107
- return self._gui_order
108
-
109
- @gui_order.setter
110
- def gui_order(self, value: int) -> None:
111
- self._gui_order = value
112
- self._changed.add('gui_order')
113
-
114
- @property
115
- def ptype(self) -> Ptype:
116
- return self._ptype
117
-
118
- @classmethod
119
- def fromJsonObj(cls, con: Connection, context: Context, jsonld_obj: Any) -> Tuple[str, 'HasProperty']:
120
- if not isinstance(con, Connection):
121
- raise BaseError('"con"-parameter must be an instance of Connection')
122
- if not isinstance(context, Context):
123
- raise BaseError('"context"-parameter must be an instance of Context')
124
-
125
- rdf = context.prefix_from_iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
126
- rdfs = context.prefix_from_iri("http://www.w3.org/2000/01/rdf-schema#")
127
- owl = context.prefix_from_iri("http://www.w3.org/2002/07/owl#")
128
- xsd = context.prefix_from_iri("http://www.w3.org/2001/XMLSchema#")
129
- knora_api = context.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
130
- salsah_gui = context.prefix_from_iri("http://api.knora.org/ontology/salsah-gui/v2#")
131
-
132
- if jsonld_obj.get('@type') is None or jsonld_obj.get('@type') != owl + ":Restriction":
133
- raise BaseError('Expected restriction type')
134
-
135
- #
136
- # let's get the inherited field...
137
- #
138
- tmp = jsonld_obj.get(knora_api + ':isInherited')
139
- is_inherited = tmp if tmp is not None else False
140
-
141
- #
142
- # let's get the cardinality
143
- #
144
- cardinality: Cardinality
145
- if jsonld_obj.get(owl + ':cardinality') is not None:
146
- cardinality = Cardinality.C_1
147
- elif jsonld_obj.get(owl + ':maxCardinality') is not None:
148
- cardinality = Cardinality.C_0_1
149
- elif jsonld_obj.get(owl + ':minCardinality') is not None:
150
- if jsonld_obj.get(owl + ':minCardinality') == 0:
151
- cardinality = Cardinality.C_0_n
152
- elif jsonld_obj.get(owl + ':minCardinality') == 1:
153
- cardinality = Cardinality.C_1_n
154
- else:
155
- raise BaseError('Problem with cardinality')
156
- else:
157
- raise BaseError('Problem with cardinality')
158
-
159
- #
160
- # Now let's get the property IRI
161
- #
162
- property_id: str
163
- ptype: HasProperty.Ptype
164
- ontology_id: Optional[str] = None
165
- if jsonld_obj.get(owl + ':onProperty') is None:
166
- raise BaseError('No property IRI given')
167
- p = jsonld_obj[owl + ':onProperty'].get('@id')
168
- if p is None:
169
- raise BaseError('No property IRI given')
170
- pp = p.split(':')
171
- if pp[0] == rdf or pp[0] == rdfs or pp[0] == owl:
172
- ptype = HasProperty.Ptype.system
173
- elif pp[0] == knora_api:
174
- ptype = HasProperty.Ptype.knora
175
- else:
176
- ptype = HasProperty.Ptype.other
177
- ontology_id = context.iri_from_prefix(pp[0])
178
- property_id = p
179
-
180
- gui_order: int = None
181
- if jsonld_obj.get(salsah_gui + ':guiOrder') is not None:
182
- gui_order = jsonld_obj[salsah_gui + ':guiOrder']
183
- return property_id, cls(con=con,
184
- context=context,
185
- ontology_id=ontology_id,
186
- property_id=property_id,
187
- cardinality=cardinality,
188
- gui_order=gui_order,
189
- is_inherited=is_inherited,
190
- ptype=ptype)
191
-
192
- def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions) -> Any:
193
- if self._cardinality is None:
194
- raise BaseError("There must be a cardinality given!")
195
- tmp = {}
196
- switcher = {
197
- Cardinality.C_1: ("owl:cardinality", 1),
198
- Cardinality.C_0_1: ("owl:maxCardinality", 1),
199
- Cardinality.C_0_n: ("owl:minCardinality", 0),
200
- Cardinality.C_1_n: ("owl:minCardinality", 1)
201
- }
202
- occurrence = switcher.get(self._cardinality)
203
- if action == Actions.Create:
204
- tmp = {
205
- "@id": self._ontology_id,
206
- "@type": "owl:Ontology",
207
- "knora-api:lastModificationDate": lastModificationDate.toJsonObj(),
208
- "@graph": [{
209
- "@id": self._resclass_id,
210
- "@type": "owl:Class",
211
- "rdfs:subClassOf": {
212
- "@type": "owl:Restriction",
213
- occurrence[0]: occurrence[1],
214
- "owl:onProperty": {
215
- "@id": self._property_id
216
- }
217
- }
218
- }],
219
- "@context": self._context.toJsonObj()
220
- }
221
- if self._gui_order is not None:
222
- tmp["@graph"][0]["rdfs:subClassOf"]["salsah-gui:guiOrder"] = self._gui_order
223
- elif action == Actions.Update:
224
- tmp = {
225
- "@id": self._ontology_id,
226
- "@type": "owl:Ontology",
227
- "knora-api:lastModificationDate": lastModificationDate.toJsonObj(),
228
- "@graph": [{
229
- "@id": self._resclass_id,
230
- "@type": "owl:Class",
231
- "rdfs:subClassOf": {
232
- "@type": "owl:Restriction",
233
- occurrence[0]: occurrence[1],
234
- "owl:onProperty": {
235
- "@id": self._property_id
236
- }
237
- }
238
- }],
239
- "@context": self._context.toJsonObj()
240
- }
241
- if self._gui_order is not None and 'gui_order' in self._changed:
242
- tmp["@graph"][0]["rdfs:subClassOf"]["salsah-gui:guiOrder"] = self._gui_order
243
- return tmp
244
-
245
- def create(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']:
246
- if self._ontology_id is None:
247
- raise BaseError("Ontology id required")
248
- if self._property_id is None:
249
- raise BaseError("Property id required")
250
- if self._cardinality is None:
251
- raise BaseError("Cardinality id required")
252
-
253
- jsonobj = self.toJsonObj(last_modification_date, Actions.Create)
254
- jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=2)
255
- result = self._con.post('/v2/ontologies/cardinalities', jsondata)
256
- last_modification_date = LastModificationDate(result['knora-api:lastModificationDate'])
257
- return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph'])
258
-
259
- def update(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']:
260
- if self._ontology_id is None:
261
- raise BaseError("Ontology id required")
262
- if self._property_id is None:
263
- raise BaseError("Property id required")
264
- if self._cardinality is None:
265
- raise BaseError("Cardinality id required")
266
- jsonobj = self.toJsonObj(last_modification_date, Actions.Update)
267
- jsondata = json.dumps(jsonobj, indent=3, cls=SetEncoder)
268
- result = self._con.put('/v2/ontologies/cardinalities', jsondata)
269
- last_modification_date = LastModificationDate(result['knora-api:lastModificationDate'])
270
- # TODO: self._changed = str()
271
- return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph'])
272
-
273
- def delete(self, last_modification_date: LastModificationDate) -> LastModificationDate:
274
- raise BaseError("Cannot remove a single property from a class!")
275
- # ToDo: Check with Ben if we could add this feature...
276
-
277
- def createDefinitionFileObj(self, context: Context, shortname: str):
278
- cardinality = {}
279
- if self._ptype == HasProperty.Ptype.other:
280
- cardinality["propname"] = context.reduce_iri(self._property_id, shortname)
281
- cardinality["cardinality"] = self._cardinality.value
282
- if self._gui_order is not None:
283
- cardinality["gui_order"] = self._gui_order
284
- return cardinality
285
-
286
- def print(self, offset: int = 0):
287
- blank = ' '
288
- if self._ptype == HasProperty.Ptype.system:
289
- print(f'{blank:>{offset}}Has Property (system)')
290
- elif self._ptype == HasProperty.Ptype.knora:
291
- print(f'{blank:>{offset}}Has Property (knora)')
292
- else:
293
- print(f'{blank:>{offset}}Has Property (project)')
294
- print(f'{blank:>{offset + 2}}Property: {self._property_id}')
295
- print(f'{blank:>{offset + 2}}Cardinality: {self._cardinality.value}')
296
- if self._ptype == HasProperty.Ptype.other:
297
- print(f'{blank:>{offset + 2}}Ontology_id: {self._ontology_id}')
298
- print(f'{blank:>{offset + 2}}Resclass: {self._resclass_id}')
299
-
300
-
301
- @strict
302
- class ResourceClass(Model):
303
- """
304
- This class represents a knora resource class
305
-
306
- Attributes
307
- ----------
308
-
309
- con : Connection
310
- A Connection instance to a Knora server
311
-
312
- id : str
313
- IRI of the ResourceClass [readonly, cannot be modified after creation of instance]
314
-
315
- name: str
316
- The name of the resource class, e.g. "Book", "Person", "Portait". Usually these names start
317
- with a capital letter
318
-
319
- ontology_id: str
320
- The IRI/Id of the ontology this resource class belongs to
321
-
322
- superlcasses: str, List[str]
323
- This is a list of superclasses for this resource class. Usually a project specific class must at least
324
- be a subclass of "Resource", but can be subclassed of any other valid resource class. In addition, external
325
- ontologies may be referenced:
326
- e.g.:
327
- ```
328
- "super": "Resource"
329
-
330
- "super": ":MySpecialTYpe"
331
-
332
- "super": [":MySpecialType", "dcterms:BibliographicResource"]
333
- ```
334
-
335
- label: language dependent string, that is a dict like {"en": "Biblography", "de": "Literaturverzeichnis"}
336
- A label (human readable name) for the resource
337
-
338
- comment: language dependent string, that is a dict like {"en": "a comment", "de": "Ein Kommentar"}
339
- A commentary to further explain what this resource class is used for
340
-
341
- permission: str
342
- The default permissions to be used if an instance of this resource class is being created
343
-
344
- has_properties: Dict[str, HasProperty]
345
- Holds a dict with the property names as keys and a HasProperty instance. HasProperty holds
346
- the information, how this resource class uses this property (basically the cardinality)
347
-
348
- changed: bool
349
- is set to True, if one of the fields has been chaned by the user (internal use only!)
350
-
351
-
352
- Methods
353
- -------
354
-
355
- addLabel: Add a new label to the resource
356
- addLabel(self, lang: Union[Languages, str], value: str) -> None
357
-
358
- getProperty: Get information about a property defined for this resource class
359
- getPropertery(prop_id: str) -> HasProperty
360
- returns a HasProperty-instance
361
-
362
- addProperty: Add a new property to the resource class
363
- addProperty(property_id: str, cardinality: Cardinality, last_modification_date: LastModificationDate)
364
- -> Optional[LastModificationDate]
365
-
366
- updateProperty: Updates the cardinality parameters of the given property with the resource class
367
- updateProperty(self, property_id: str, cardinality: Cardinality, last_modification_date: LastModificationDate)
368
- -> Optional[LastModificationDate]
369
- Please note that the cardinality usually can only be changed to be *less* restrictive!
370
-
371
- create: Create a new resource class on the connected server
372
-
373
- update: Update the information of a resource class on the connected server
374
-
375
- delete: Mark a resource class as deleted (on the connected server)
376
-
377
- createDefinitionFileObj: Create an object suitable for jsonification that conforms the the knora-py ontology tools
378
-
379
- print: Print the content of this class to the console
380
-
381
- """
382
- _context: Context
383
- _id: str
384
- _name: str
385
- _ontology_id: str
386
- _superclasses: List[str]
387
- _label: LangString
388
- _comment: LangString
389
- _permissions: str
390
- _has_properties: Dict[str, HasProperty]
391
-
392
- def __init__(self,
393
- con: Connection,
394
- context: Context,
395
- id: Optional[str] = None,
396
- name: Optional[str] = None,
397
- ontology_id: Optional[str] = None,
398
- superclasses: Optional[List[Union['ResourceClass', str]]] = None,
399
- label: Optional[Union[LangString, str]] = None,
400
- comment: Optional[Union[LangString, str]] = None,
401
- permissions: Optional[str] = None,
402
- has_properties: Optional[Dict[str, HasProperty]] = None):
403
- """
404
- Create an instance of ResourceClass
405
-
406
- :param con:
407
- :param context:
408
- :param id:
409
- :param name:
410
- :param ontology_id:
411
- :param superclasses:
412
- :param label:
413
- :param comment:
414
- :param permissions:
415
- :param has_properties:
416
- """
417
- super().__init__(con)
418
- if not isinstance(con, Connection):
419
- raise BaseError('"con"-parameter must be an instance of Connection')
420
- if not isinstance(context, Context):
421
- raise BaseError('"context"-parameter must be an instance of Context')
422
- self._context = context
423
- self._id = id
424
- self._name = name
425
- if ontology_id is not None:
426
- self._ontology_id = context.iri_from_prefix(ontology_id)
427
- if isinstance(superclasses, ResourceClass):
428
- self._superclasses = list(map(lambda a: a.id, superclasses))
429
- else:
430
- self._superclasses = superclasses
431
- #
432
- # process label
433
- #
434
- if label is not None:
435
- if isinstance(label, str):
436
- self._label = LangString(label)
437
- elif isinstance(label, LangString):
438
- self._label = label
439
- else:
440
- raise BaseError('Invalid LangString for label!')
441
- else:
442
- self._label = None
443
- #
444
- # process comment
445
- #
446
- if comment is not None:
447
- if isinstance(comment, str):
448
- self._comment = LangString(comment)
449
- elif isinstance(comment, LangString):
450
- self._comment = comment
451
- else:
452
- raise BaseError('Invalid LangString for comment!')
453
- else:
454
- self._comment = None
455
- self._permissions = permissions
456
- self._has_properties = has_properties
457
- self._changed = set()
458
-
459
- #
460
- # Here follows a list of getters/setters
461
- #
462
- @property
463
- def name(self) -> Optional[str]:
464
- return self._name
465
-
466
- @name.setter
467
- def name(self, value: str) -> None:
468
- raise BaseError('"name" cannot be modified!')
469
-
470
- @property
471
- def id(self) -> Optional[str]:
472
- return self._id
473
-
474
- @id.setter
475
- def id(self, value: str) -> None:
476
- raise BaseError('"id" cannot be modified!')
477
-
478
- @property
479
- def ontology_id(self) -> Optional[str]:
480
- return self._ontology_id
481
-
482
- @ontology_id.setter
483
- def ontology_id(self, value: str) -> None:
484
- raise BaseError('"ontology_id" cannot be modified!')
485
-
486
- @property
487
- def superclasses(self) -> Optional[List[str]]:
488
- return self._superclasses
489
-
490
- @superclasses.setter
491
- def superclasses(self, value: List[str]) -> None:
492
- raise BaseError('"superclasses" cannot be modified!')
493
-
494
- @property
495
- def label(self) -> Optional[LangString]:
496
- return self._label
497
-
498
- @label.setter
499
- def label(self, value: Optional[Union[LangString, str]]) -> None:
500
- if value is None:
501
- self._label.empty() # clear all labels
502
- else:
503
- if isinstance(value, LangString):
504
- self._label = value
505
- elif isinstance(value, str):
506
- self._label = LangString(value)
507
- else:
508
- raise BaseError('Not a valid LangString')
509
- self._changed.add('label')
510
-
511
-
512
- def addLabel(self, lang: Union[Languages, str], value: str) -> None:
513
- self._label[lang] = value
514
- self._changed.add('label')
515
-
516
- def rmLabel(self, lang: Union[Languages, str]) -> None:
517
- del self._label[lang]
518
- self._changed.add('label')
519
-
520
- @property
521
- def comment(self) -> Optional[LangString]:
522
- return self._comment
523
-
524
- @comment.setter
525
- def comment(self, value: Optional[LangString]) -> None:
526
- if value is None:
527
- self._comment.empty() # clear all comments!
528
- else:
529
- if isinstance(value, LangString):
530
- self._comment = value
531
- elif isinstance(value, str):
532
- self._comment = LangString(value)
533
- else:
534
- raise BaseError('Not a valid LangString')
535
- self._changed.add('comment')
536
-
537
- def addComment(self, lang: Union[Languages, str], value: str) -> None:
538
- self._comment[lang] = value
539
- self._changed.add('comment')
540
-
541
- def rmComment(self, lang: Union[Languages, str]) -> None:
542
- del self._comment[lang]
543
- self._changed.add('comment')
544
-
545
- @property
546
- def permissions(self) -> Optional[str]:
547
- return self._permissions
548
-
549
- @permissions.setter
550
- def permissions(self, value: str) -> None:
551
- raise BaseError('"permissions" cannot be modified!')
552
-
553
- @property
554
- def has_properties(self) -> Dict[str, HasProperty]:
555
- return self._has_properties
556
-
557
- @has_properties.setter
558
- def has_properties(self, value: str) -> None:
559
- raise BaseError('"has_property" cannot be modified!')
560
-
561
- def getProperty(self, property_id) -> Optional[HasProperty]:
562
- if self._has_properties is None:
563
- return None
564
- else:
565
- return self._has_properties.get(self._context.get_prefixed_iri(property_id))
566
-
567
- def addProperty(self,
568
- last_modification_date: LastModificationDate,
569
- property_id: str,
570
- cardinality: Cardinality,
571
- gui_order: Optional[int] = None,
572
- ) -> Optional[LastModificationDate]:
573
- if self._has_properties.get(property_id) is None:
574
- latest_modification_date, resclass = HasProperty(con=self._con,
575
- context=self._context,
576
- ontology_id=self._ontology_id,
577
- property_id=property_id,
578
- resclass_id=self.id,
579
- cardinality=cardinality,
580
- gui_order=gui_order).create(last_modification_date)
581
- hp = resclass.getProperty(property_id)
582
- hp._ontology_id = self._context.iri_from_prefix(self._ontology_id)
583
- hp._resclass_id = self._id
584
- self._has_properties[hp.property_id] = hp
585
- return latest_modification_date
586
- else:
587
- raise BaseError("Property already has cardinality in this class! " + property_id)
588
-
589
- def updateProperty(self,
590
- last_modification_date: LastModificationDate,
591
- property_id: str,
592
- cardinality: Optional[Cardinality],
593
- gui_order: Optional[int] = None,
594
- ) -> Optional[LastModificationDate]:
595
- property_id = self._context.get_prefixed_iri(property_id)
596
- if self._has_properties.get(property_id) is not None:
597
- has_properties = self._has_properties[property_id]
598
- #onto_id = has_properties.ontology_id # save for later user
599
- #rescl_id = has_properties.resclass_id # save for later user
600
- has_properties.ontology_id = self._ontology_id
601
- has_properties.resclass_id = self._id
602
- if cardinality:
603
- has_properties.cardinality = cardinality
604
- if gui_order:
605
- has_properties.gui_order = gui_order
606
- latest_modification_date, resclass = has_properties.update(last_modification_date)
607
- hp = resclass.getProperty(property_id)
608
- hp.ontology_id = self._ontology_id # self.__context.iri_from_prefix(onto_id) # restore value
609
- hp.resclass_id = self._id # rescl_id # restore value
610
- self._has_properties[hp.property_id] = hp
611
- return latest_modification_date
612
- else:
613
- return last_modification_date
614
-
615
- @classmethod
616
- def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> Any:
617
- if isinstance(json_obj, list):
618
- json_obj = json_obj[0] # TODO: Is it possible to have more than one element in the list??
619
- if not isinstance(con, Connection):
620
- raise BaseError('"con"-parameter must be an instance of Connection')
621
- if not isinstance(context, Context):
622
- raise BaseError('"context"-parameter must be an instance of Context')
623
- rdf = context.prefix_from_iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
624
- rdfs = context.prefix_from_iri("http://www.w3.org/2000/01/rdf-schema#")
625
- owl = context.prefix_from_iri("http://www.w3.org/2002/07/owl#")
626
- xsd = context.prefix_from_iri("http://www.w3.org/2001/XMLSchema#")
627
- knora_api = context.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
628
- salsah_gui = context.prefix_from_iri("http://api.knora.org/ontology/salsah-gui/v2#")
629
-
630
- if not (json_obj.get(knora_api + ':isResourceClass') or json_obj.get(knora_api + ':isStandoffClass')):
631
- raise BaseError("This is not a resource!")
632
-
633
- if json_obj.get('@id') is None:
634
- raise BaseError('Resource class has no "@id"!')
635
- tmp_id = json_obj.get('@id').split(':')
636
- id = context.iri_from_prefix(tmp_id[0]) + '#' + tmp_id[1]
637
- ontology_id = tmp_id[0]
638
- name = tmp_id[1]
639
- superclasses_obj = json_obj.get(rdfs + ':subClassOf')
640
- if superclasses_obj is not None:
641
- supercls: List[Any] = list(filter(lambda a: a.get('@id') is not None, superclasses_obj))
642
- superclasses: List[str] = list(map(lambda a: a['@id'], supercls))
643
- has_props: List[Any] = list(filter(lambda a: a.get('@type') == (owl + ':Restriction'), superclasses_obj))
644
- has_properties: Dict[HasProperty] = dict(map(lambda a: HasProperty.fromJsonObj(con, context, a), has_props))
645
- else:
646
- superclasses = None
647
- has_properties = None
648
-
649
- label = LangString.fromJsonLdObj(json_obj.get(rdfs + ':label'))
650
- comment = LangString.fromJsonLdObj(json_obj.get(rdfs + ':comment'))
651
- return cls(con=con,
652
- context=context,
653
- name=name,
654
- id=id,
655
- ontology_id=ontology_id,
656
- superclasses=superclasses,
657
- label=label,
658
- comment=comment,
659
- has_properties=has_properties)
660
-
661
- def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions, what: Optional[str] = None) -> Any:
662
-
663
- def resolve_resref(resref: str):
664
- tmp = resref.split(':')
665
- if len(tmp) > 1:
666
- if tmp[0]:
667
- self._context.add_context(tmp[0])
668
- return {"@id": resref} # fully qualified name in the form "prefix:name"
669
- else:
670
- return {"@id": self._context.prefix_from_iri(self._ontology_id) + ':' + tmp[1]} # ":name" in current ontology
671
- else:
672
- return {"@id": "knora-api:" + resref} # no ":", must be from knora-api!
673
-
674
- tmp = {}
675
- exp = re.compile('^http.*') # It is already a fully IRI
676
- if exp.match(self._ontology_id):
677
- resid = self._context.prefix_from_iri(self._ontology_id) + ":" + self._name
678
- ontid = self._ontology_id
679
- else:
680
- resid = self._ontology_id + ":" + self._name
681
- ontid = self._context.iri_from_prefix(self._ontology_id)
682
- if action == Actions.Create:
683
- if self._name is None:
684
- raise BaseError("There must be a valid resource class name!")
685
- if self._ontology_id is None:
686
- raise BaseError("There must be a valid ontology_id given!")
687
- if self._superclasses is None:
688
- superclasses = [{"@id": "knora-api:Resource"}]
689
- else:
690
- superclasses = list(map(resolve_resref, self._superclasses))
691
- if self._comment is None or self._comment.isEmpty():
692
- self._comment = LangString("no comment available")
693
- if self._label is None or self._label.isEmpty():
694
- self._label = LangString("no label available")
695
- tmp = {
696
- "@id": ontid, # self._ontology_id,
697
- "@type": "owl:Ontology",
698
- "knora-api:lastModificationDate": lastModificationDate.toJsonObj(),
699
- "@graph": [{
700
- "@id": resid,
701
- "@type": "owl:Class",
702
- "rdfs:label": self._label.toJsonLdObj(),
703
- "rdfs:comment": self._comment.toJsonLdObj(),
704
- "rdfs:subClassOf": superclasses
705
- }],
706
- "@context": self._context.toJsonObj(),
707
- }
708
- elif action == Actions.Update:
709
- tmp = {
710
- "@id": ontid, # self._ontology_id,
711
- "@type": "owl:Ontology",
712
- "knora-api:lastModificationDate": lastModificationDate.toJsonObj(),
713
- "@graph": [{
714
- "@id": resid,
715
- "@type": "owl:Class",
716
- }],
717
- "@context": self._context.toJsonObj(),
718
- }
719
- if what == 'label':
720
- if not self._label.isEmpty() and 'label' in self._changed:
721
- tmp['@graph'][0]['rdfs:label'] = self._label.toJsonLdObj()
722
- if what == 'comment':
723
- if not self._comment.isEmpty() and 'comment' in self._changed:
724
- tmp['@graph'][0]['rdfs:comment'] = self._comment.toJsonLdObj()
725
- return tmp
726
-
727
- def create(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']:
728
- jsonobj = self.toJsonObj(last_modification_date, Actions.Create)
729
- jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4)
730
- result = self._con.post('/v2/ontologies/classes', jsondata)
731
- last_modification_date = LastModificationDate(result['knora-api:lastModificationDate'])
732
- return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph'])
733
-
734
- def update(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']:
735
- #
736
- # Note: Knora is able to change only one thing per call, either label or comment!
737
- #
738
- result = None
739
- something_changed = False
740
- if 'label' in self._changed:
741
- jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'label')
742
- jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4)
743
- result = self._con.put('v2/ontologies/classes', jsondata)
744
- last_modification_date = LastModificationDate(result['knora-api:lastModificationDate'])
745
- something_changed = True
746
- if 'comment' in self._changed:
747
- jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'comment')
748
- jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4)
749
- result = self._con.put('v2/ontologies/classes', jsondata)
750
- last_modification_date = LastModificationDate(result['knora-api:lastModificationDate'])
751
- something_changed = True
752
- if something_changed:
753
- return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph'])
754
- else:
755
- return last_modification_date, self
756
-
757
- def delete(self, last_modification_date: LastModificationDate) -> LastModificationDate:
758
- result = self._con.delete('v2/ontologies/classes/' + quote_plus(self._id) + '?lastModificationDate=' + str(last_modification_date))
759
- return LastModificationDate(result['knora-api:lastModificationDate'])
760
-
761
- def createDefinitionFileObj(self, context: Context, shortname: str, skiplist: List[str]):
762
- resource = {
763
- "name": self._name,
764
- "labels": self._label.createDefinitionFileObj(),
765
- }
766
- if self._comment:
767
- resource["comments"] = self._comment.createDefinitionFileObj()
768
- if self._superclasses:
769
- if len(self._superclasses) > 1:
770
- superclasses = []
771
- for sc in self._superclasses:
772
- superclasses.append(context.reduce_iri(sc, shortname))
773
- else:
774
- superclasses = context.reduce_iri(self._superclasses[0], shortname)
775
- resource["super"] = superclasses
776
- if self._has_properties:
777
- cardinalities = []
778
- for pid, hp in self._has_properties.items():
779
- if hp.property_id in skiplist:
780
- continue
781
- if hp.ptype == HasProperty.Ptype.other:
782
- cardinalities.append(hp.createDefinitionFileObj(context, shortname))
783
- resource["cardinalities"] = cardinalities
784
-
785
- return resource
786
-
787
- def print(self, offset: int = 0):
788
- blank = ' '
789
- print(f'{blank:>{offset}}Resource Class Info')
790
- print(f'{blank:>{offset+2}}Name: {self._name}')
791
- print(f'{blank:>{offset+2}}Ontology prefix: {self._ontology_id}')
792
- print(f'{blank:>{offset+2}}Superclasses:')
793
- if self._superclasses is not None:
794
- for sc in self._superclasses:
795
- print(f'{blank:>{offset + 4}}{sc}')
796
- if self._label is not None:
797
- print(f'{blank:>{offset + 2}}Labels:')
798
- self._label.print(offset + 4)
799
- if self._comment is not None:
800
- print(f'{blank:>{offset + 2}}Comments:')
801
- self._comment.print(offset + 4)
802
- if self._has_properties is not None:
803
- print(f'{blank:>{offset + 2}}Has properties:')
804
- if self._has_properties is not None:
805
- for pid, hp in self._has_properties.items():
806
- hp.print(offset + 4)
807
-
808
-
809
-
810
-
811
-