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,810 +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
- self._property_id = property_id
60
- self._resclass_id = resclass_id
61
- self._cardinality = cardinality
62
- self._gui_order = gui_order
63
- self._is_inherited = is_inherited
64
- self._ptype = ptype
65
- self._changed = set()
66
-
67
- #
68
- # Here follows a list of getters/setters
69
- #
70
- @property
71
- def ontology_id(self) -> Optional[str]:
72
- return self._ontology_id
73
-
74
- @ontology_id.setter
75
- def ontology_id(self, value: Optional[str]) -> None:
76
- self._ontology_id = value
77
-
78
- @property
79
- def property_id(self) -> Optional[str]:
80
- return self._property_id
81
-
82
- @property_id.setter
83
- def property_id(self, value: str) -> None:
84
- raise BaseError('"property_id" cannot be modified!')
85
-
86
- @property
87
- def resclass_id(self) -> Optional[str]:
88
- return self._resclass_id
89
-
90
- @resclass_id.setter
91
- def resclass_id(self, value: Optional[str]) -> None:
92
- self._resclass_id = value
93
-
94
- @property
95
- def cardinality(self) -> Optional[Cardinality]:
96
- return self._cardinality
97
-
98
- @cardinality.setter
99
- def cardinality(self, value: Optional[Cardinality]) -> None:
100
- self._cardinality = value
101
- self._changed.add('cardinality')
102
-
103
- @property
104
- def gui_order(self) -> Optional[int]:
105
- return self._gui_order
106
-
107
- @gui_order.setter
108
- def gui_order(self, value: int) -> None:
109
- self._gui_order = value
110
- self._changed.add('gui_order')
111
-
112
- @property
113
- def ptype(self) -> Ptype:
114
- return self._ptype
115
-
116
- @classmethod
117
- def fromJsonObj(cls, con: Connection, context: Context, jsonld_obj: Any) -> Tuple[str, 'HasProperty']:
118
- if not isinstance(con, Connection):
119
- raise BaseError('"con"-parameter must be an instance of Connection')
120
- if not isinstance(context, Context):
121
- raise BaseError('"context"-parameter must be an instance of Context')
122
-
123
- rdf = context.prefix_from_iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
124
- rdfs = context.prefix_from_iri("http://www.w3.org/2000/01/rdf-schema#")
125
- owl = context.prefix_from_iri("http://www.w3.org/2002/07/owl#")
126
- xsd = context.prefix_from_iri("http://www.w3.org/2001/XMLSchema#")
127
- knora_api = context.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
128
- salsah_gui = context.prefix_from_iri("http://api.knora.org/ontology/salsah-gui/v2#")
129
-
130
- if jsonld_obj.get('@type') is None or jsonld_obj.get('@type') != owl + ":Restriction":
131
- raise BaseError('Expected restriction type')
132
-
133
- #
134
- # let's get the inherited field...
135
- #
136
- tmp = jsonld_obj.get(knora_api + ':isInherited')
137
- is_inherited = tmp if tmp is not None else False
138
-
139
- #
140
- # let's get the cardinality
141
- #
142
- cardinality: Cardinality
143
- if jsonld_obj.get(owl + ':cardinality') is not None:
144
- cardinality = Cardinality.C_1
145
- elif jsonld_obj.get(owl + ':maxCardinality') is not None:
146
- cardinality = Cardinality.C_0_1
147
- elif jsonld_obj.get(owl + ':minCardinality') is not None:
148
- if jsonld_obj.get(owl + ':minCardinality') == 0:
149
- cardinality = Cardinality.C_0_n
150
- elif jsonld_obj.get(owl + ':minCardinality') == 1:
151
- cardinality = Cardinality.C_1_n
152
- else:
153
- raise BaseError('Problem with cardinality')
154
- else:
155
- raise BaseError('Problem with cardinality')
156
-
157
- #
158
- # Now let's get the property IRI
159
- #
160
- property_id: str
161
- ptype: HasProperty.Ptype
162
- ontology_id: Optional[str] = None
163
- if jsonld_obj.get(owl + ':onProperty') is None:
164
- raise BaseError('No property IRI given')
165
- p = jsonld_obj[owl + ':onProperty'].get('@id')
166
- if p is None:
167
- raise BaseError('No property IRI given')
168
- pp = p.split(':')
169
- if pp[0] == rdf or pp[0] == rdfs or pp[0] == owl:
170
- ptype = HasProperty.Ptype.system
171
- elif pp[0] == knora_api:
172
- ptype = HasProperty.Ptype.knora
173
- else:
174
- ptype = HasProperty.Ptype.other
175
- ontology_id = context.iri_from_prefix(pp[0])
176
- property_id = p
177
-
178
- gui_order: int = None
179
- if jsonld_obj.get(salsah_gui + ':guiOrder') is not None:
180
- gui_order = jsonld_obj[salsah_gui + ':guiOrder']
181
- return property_id, cls(con=con,
182
- context=context,
183
- ontology_id=ontology_id,
184
- property_id=property_id,
185
- cardinality=cardinality,
186
- gui_order=gui_order,
187
- is_inherited=is_inherited,
188
- ptype=ptype)
189
-
190
- def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions) -> Any:
191
- if self._cardinality is None:
192
- raise BaseError("There must be a cardinality given!")
193
- tmp = {}
194
- switcher = {
195
- Cardinality.C_1: ("owl:cardinality", 1),
196
- Cardinality.C_0_1: ("owl:maxCardinality", 1),
197
- Cardinality.C_0_n: ("owl:minCardinality", 0),
198
- Cardinality.C_1_n: ("owl:minCardinality", 1)
199
- }
200
- occurrence = switcher.get(self._cardinality)
201
- if action == Actions.Create:
202
- tmp = {
203
- "@id": self._ontology_id,
204
- "@type": "owl:Ontology",
205
- "knora-api:lastModificationDate": lastModificationDate.toJsonObj(),
206
- "@graph": [{
207
- "@id": self._resclass_id,
208
- "@type": "owl:Class",
209
- "rdfs:subClassOf": {
210
- "@type": "owl:Restriction",
211
- occurrence[0]: occurrence[1],
212
- "owl:onProperty": {
213
- "@id": self._property_id
214
- }
215
- }
216
- }],
217
- "@context": self._context.toJsonObj()
218
- }
219
- if self._gui_order is not None:
220
- tmp["@graph"][0]["rdfs:subClassOf"]["salsah-gui:guiOrder"] = self._gui_order
221
- elif action == Actions.Update:
222
- tmp = {
223
- "@id": self._ontology_id,
224
- "@type": "owl:Ontology",
225
- "knora-api:lastModificationDate": lastModificationDate.toJsonObj(),
226
- "@graph": [{
227
- "@id": self._resclass_id,
228
- "@type": "owl:Class",
229
- "rdfs:subClassOf": {
230
- "@type": "owl:Restriction",
231
- occurrence[0]: occurrence[1],
232
- "owl:onProperty": {
233
- "@id": self._property_id
234
- }
235
- }
236
- }],
237
- "@context": self._context.toJsonObj()
238
- }
239
- if self._gui_order is not None and 'gui_order' in self._changed:
240
- tmp["@graph"][0]["rdfs:subClassOf"]["salsah-gui:guiOrder"] = self._gui_order
241
- return tmp
242
-
243
- def create(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']:
244
- if self._ontology_id is None:
245
- raise BaseError("Ontology id required")
246
- if self._property_id is None:
247
- raise BaseError("Property id required")
248
- if self._cardinality is None:
249
- raise BaseError("Cardinality id required")
250
-
251
- jsonobj = self.toJsonObj(last_modification_date, Actions.Create)
252
- jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=2)
253
- result = self._con.post('/v2/ontologies/cardinalities', jsondata)
254
- last_modification_date = LastModificationDate(result['knora-api:lastModificationDate'])
255
- return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph'])
256
-
257
- def update(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']:
258
- if self._ontology_id is None:
259
- raise BaseError("Ontology id required")
260
- if self._property_id is None:
261
- raise BaseError("Property id required")
262
- if self._cardinality is None:
263
- raise BaseError("Cardinality id required")
264
- jsonobj = self.toJsonObj(last_modification_date, Actions.Update)
265
- jsondata = json.dumps(jsonobj, indent=3, cls=SetEncoder)
266
- result = self._con.put('/v2/ontologies/cardinalities', jsondata)
267
- last_modification_date = LastModificationDate(result['knora-api:lastModificationDate'])
268
- # TODO: self._changed = str()
269
- return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph'])
270
-
271
- def delete(self, last_modification_date: LastModificationDate) -> LastModificationDate:
272
- raise BaseError("Cannot remove a single property from a class!")
273
- # ToDo: Check with Ben if we could add this feature...
274
-
275
- def createDefinitionFileObj(self, context: Context, shortname: str):
276
- cardinality = {}
277
- if self._ptype == HasProperty.Ptype.other:
278
- cardinality["propname"] = context.reduce_iri(self._property_id, shortname)
279
- cardinality["cardinality"] = self._cardinality.value
280
- if self._gui_order is not None:
281
- cardinality["gui_order"] = self._gui_order
282
- return cardinality
283
-
284
- def print(self, offset: int = 0):
285
- blank = ' '
286
- if self._ptype == HasProperty.Ptype.system:
287
- print(f'{blank:>{offset}}Has Property (system)')
288
- elif self._ptype == HasProperty.Ptype.knora:
289
- print(f'{blank:>{offset}}Has Property (knora)')
290
- else:
291
- print(f'{blank:>{offset}}Has Property (project)')
292
- print(f'{blank:>{offset + 2}}Property: {self._property_id}')
293
- print(f'{blank:>{offset + 2}}Cardinality: {self._cardinality.value}')
294
- if self._ptype == HasProperty.Ptype.other:
295
- print(f'{blank:>{offset + 2}}Ontology_id: {self._ontology_id}')
296
- print(f'{blank:>{offset + 2}}Resclass: {self._resclass_id}')
297
-
298
-
299
- @strict
300
- class ResourceClass(Model):
301
- """
302
- This class represents a knora resource class
303
-
304
- Attributes
305
- ----------
306
-
307
- con : Connection
308
- A Connection instance to a Knora server
309
-
310
- id : str
311
- IRI of the ResourceClass [readonly, cannot be modified after creation of instance]
312
-
313
- name: str
314
- The name of the resource class, e.g. "Book", "Person", "Portait". Usually these names start
315
- with a capital letter
316
-
317
- ontology_id: str
318
- The IRI/Id of the ontology this resource class belongs to
319
-
320
- superlcasses: str, List[str]
321
- This is a list of superclasses for this resource class. Usually a project specific class must at least
322
- be a subclass of "Resource", but can be subclassed of any other valid resource class. In addition, external
323
- ontologies may be referenced:
324
- e.g.:
325
- ```
326
- "super": "Resource"
327
-
328
- "super": ":MySpecialTYpe"
329
-
330
- "super": [":MySpecialType", "dcterms:BibliographicResource"]
331
- ```
332
-
333
- label: language dependent string, that is a dict like {"en": "Biblography", "de": "Literaturverzeichnis"}
334
- A label (human readable name) for the resource
335
-
336
- comment: language dependent string, that is a dict like {"en": "a comment", "de": "Ein Kommentar"}
337
- A commentary to further explain what this resource class is used for
338
-
339
- permission: str
340
- The default permissions to be used if an instance of this resource class is being created
341
-
342
- has_properties: Dict[str, HasProperty]
343
- Holds a dict with the property names as keys and a HasProperty instance. HasProperty holds
344
- the information, how this resource class uses this property (basically the cardinality)
345
-
346
- changed: bool
347
- is set to True, if one of the fields has been chaned by the user (internal use only!)
348
-
349
-
350
- Methods
351
- -------
352
-
353
- addLabel: Add a new label to the resource
354
- addLabel(self, lang: Union[Languages, str], value: str) -> None
355
-
356
- getProperty: Get information about a property defined for this resource class
357
- getPropertery(prop_id: str) -> HasProperty
358
- returns a HasProperty-instance
359
-
360
- addProperty: Add a new property to the resource class
361
- addProperty(property_id: str, cardinality: Cardinality, last_modification_date: LastModificationDate)
362
- -> Optional[LastModificationDate]
363
-
364
- updateProperty: Updates the cardinality parameters of the given property with the resource class
365
- updateProperty(self, property_id: str, cardinality: Cardinality, last_modification_date: LastModificationDate)
366
- -> Optional[LastModificationDate]
367
- Please note that the cardinality usually can only be changed to be *less* restrictive!
368
-
369
- create: Create a new resource class on the connected server
370
-
371
- update: Update the information of a resource class on the connected server
372
-
373
- delete: Mark a resource class as deleted (on the connected server)
374
-
375
- createDefinitionFileObj: Create an object suitable for jsonification that conforms the the knora-py ontology tools
376
-
377
- print: Print the content of this class to the console
378
-
379
- """
380
- _context: Context
381
- _id: str
382
- _name: str
383
- _ontology_id: str
384
- _superclasses: List[str]
385
- _label: LangString
386
- _comment: LangString
387
- _permissions: str
388
- _has_properties: Dict[str, HasProperty]
389
-
390
- def __init__(self,
391
- con: Connection,
392
- context: Context,
393
- id: Optional[str] = None,
394
- name: Optional[str] = None,
395
- ontology_id: Optional[str] = None,
396
- superclasses: Optional[List[Union['ResourceClass', str]]] = None,
397
- label: Optional[Union[LangString, str]] = None,
398
- comment: Optional[Union[LangString, str]] = None,
399
- permissions: Optional[str] = None,
400
- has_properties: Optional[Dict[str, HasProperty]] = None):
401
- """
402
- Create an instance of ResourceClass
403
-
404
- :param con:
405
- :param context:
406
- :param id:
407
- :param name:
408
- :param ontology_id:
409
- :param superclasses:
410
- :param label:
411
- :param comment:
412
- :param permissions:
413
- :param has_properties:
414
- """
415
- super().__init__(con)
416
- if not isinstance(con, Connection):
417
- raise BaseError('"con"-parameter must be an instance of Connection')
418
- if not isinstance(context, Context):
419
- raise BaseError('"context"-parameter must be an instance of Context')
420
- self._context = context
421
- self._id = id
422
- self._name = name
423
- if ontology_id is not None:
424
- self._ontology_id = context.iri_from_prefix(ontology_id)
425
- if isinstance(superclasses, ResourceClass):
426
- self._superclasses = list(map(lambda a: a.id, superclasses))
427
- else:
428
- self._superclasses = superclasses
429
- #
430
- # process label
431
- #
432
- if label is not None:
433
- if isinstance(label, str):
434
- self._label = LangString(label)
435
- elif isinstance(label, LangString):
436
- self._label = label
437
- else:
438
- raise BaseError('Invalid LangString for label!')
439
- else:
440
- self._label = None
441
- #
442
- # process comment
443
- #
444
- if comment is not None:
445
- if isinstance(comment, str):
446
- self._comment = LangString(comment)
447
- elif isinstance(comment, LangString):
448
- self._comment = comment
449
- else:
450
- raise BaseError('Invalid LangString for comment!')
451
- else:
452
- self._comment = None
453
- self._permissions = permissions
454
- self._has_properties = has_properties
455
- self._changed = set()
456
-
457
- #
458
- # Here follows a list of getters/setters
459
- #
460
- @property
461
- def name(self) -> Optional[str]:
462
- return self._name
463
-
464
- @name.setter
465
- def name(self, value: str) -> None:
466
- raise BaseError('"name" cannot be modified!')
467
-
468
- @property
469
- def id(self) -> Optional[str]:
470
- return self._id
471
-
472
- @id.setter
473
- def id(self, value: str) -> None:
474
- raise BaseError('"id" cannot be modified!')
475
-
476
- @property
477
- def ontology_id(self) -> Optional[str]:
478
- return self._ontology_id
479
-
480
- @ontology_id.setter
481
- def ontology_id(self, value: str) -> None:
482
- raise BaseError('"ontology_id" cannot be modified!')
483
-
484
- @property
485
- def superclasses(self) -> Optional[List[str]]:
486
- return self._superclasses
487
-
488
- @superclasses.setter
489
- def superclasses(self, value: List[str]) -> None:
490
- raise BaseError('"superclasses" cannot be modified!')
491
-
492
- @property
493
- def label(self) -> Optional[LangString]:
494
- return self._label
495
-
496
- @label.setter
497
- def label(self, value: Optional[Union[LangString, str]]) -> None:
498
- if value is None:
499
- self._label.empty() # clear all labels
500
- else:
501
- if isinstance(value, LangString):
502
- self._label = value
503
- elif isinstance(value, str):
504
- self._label = LangString(value)
505
- else:
506
- raise BaseError('Not a valid LangString')
507
- self._changed.add('label')
508
-
509
-
510
- def addLabel(self, lang: Union[Languages, str], value: str) -> None:
511
- self._label[lang] = value
512
- self._changed.add('label')
513
-
514
- def rmLabel(self, lang: Union[Languages, str]) -> None:
515
- del self._label[lang]
516
- self._changed.add('label')
517
-
518
- @property
519
- def comment(self) -> Optional[LangString]:
520
- return self._comment
521
-
522
- @comment.setter
523
- def comment(self, value: Optional[LangString]) -> None:
524
- if value is None:
525
- self._comment.empty() # clear all comments!
526
- else:
527
- if isinstance(value, LangString):
528
- self._comment = value
529
- elif isinstance(value, str):
530
- self._comment = LangString(value)
531
- else:
532
- raise BaseError('Not a valid LangString')
533
- self._changed.add('comment')
534
-
535
- def addComment(self, lang: Union[Languages, str], value: str) -> None:
536
- self._comment[lang] = value
537
- self._changed.add('comment')
538
-
539
- def rmComment(self, lang: Union[Languages, str]) -> None:
540
- del self._comment[lang]
541
- self._changed.add('comment')
542
-
543
- @property
544
- def permissions(self) -> Optional[str]:
545
- return self._permissions
546
-
547
- @permissions.setter
548
- def permissions(self, value: str) -> None:
549
- raise BaseError('"permissions" cannot be modified!')
550
-
551
- @property
552
- def has_properties(self) -> Dict[str, HasProperty]:
553
- return self._has_properties
554
-
555
- @has_properties.setter
556
- def has_properties(self, value: str) -> None:
557
- raise BaseError('"has_property" cannot be modified!')
558
-
559
- def getProperty(self, property_id) -> Optional[HasProperty]:
560
- if self._has_properties is None:
561
- return None
562
- else:
563
- return self._has_properties.get(self._context.get_prefixed_iri(property_id))
564
-
565
- def addProperty(self,
566
- last_modification_date: LastModificationDate,
567
- property_id: str,
568
- cardinality: Cardinality,
569
- gui_order: Optional[int] = None,
570
- ) -> Optional[LastModificationDate]:
571
- if self._has_properties.get(property_id) is None:
572
- latest_modification_date, resclass = HasProperty(con=self._con,
573
- context=self._context,
574
- ontology_id=self._ontology_id,
575
- property_id=property_id,
576
- resclass_id=self.id,
577
- cardinality=cardinality,
578
- gui_order=gui_order).create(last_modification_date)
579
- hp = resclass.getProperty(property_id)
580
- hp.ontology_id = self._context.iri_from_prefix(self._ontology_id)
581
- hp.resclass_id = self._id
582
- self._has_properties[hp.property_id] = hp
583
- return latest_modification_date
584
- else:
585
- raise BaseError("Property already has cardinality in this class!")
586
-
587
- def updateProperty(self,
588
- last_modification_date: LastModificationDate,
589
- property_id: str,
590
- cardinality: Optional[Cardinality],
591
- gui_order: Optional[int] = None,
592
- ) -> Optional[LastModificationDate]:
593
- property_id = self._context.get_prefixed_iri(property_id)
594
- if self._has_properties.get(property_id) is not None:
595
- has_properties = self._has_properties[property_id]
596
- #onto_id = has_properties.ontology_id # save for later user
597
- #rescl_id = has_properties.resclass_id # save for later user
598
- has_properties.ontology_id = self._ontology_id
599
- has_properties.resclass_id = self._id
600
- if cardinality:
601
- has_properties.cardinality = cardinality
602
- if gui_order:
603
- has_properties.gui_order = gui_order
604
- latest_modification_date, resclass = has_properties.update(last_modification_date)
605
- hp = resclass.getProperty(property_id)
606
- hp.ontology_id = self._ontology_id # self.__context.iri_from_prefix(onto_id) # restore value
607
- hp.resclass_id = self._id # rescl_id # restore value
608
- self._has_properties[hp.property_id] = hp
609
- return latest_modification_date
610
- else:
611
- return last_modification_date
612
-
613
- @classmethod
614
- def fromJsonObj(cls, con: Connection, context: Context, json_obj: Any) -> Any:
615
- if isinstance(json_obj, list):
616
- json_obj = json_obj[0] # TODO: Is it possible to have more than one element in the list??
617
- if not isinstance(con, Connection):
618
- raise BaseError('"con"-parameter must be an instance of Connection')
619
- if not isinstance(context, Context):
620
- raise BaseError('"context"-parameter must be an instance of Context')
621
- rdf = context.prefix_from_iri("http://www.w3.org/1999/02/22-rdf-syntax-ns#")
622
- rdfs = context.prefix_from_iri("http://www.w3.org/2000/01/rdf-schema#")
623
- owl = context.prefix_from_iri("http://www.w3.org/2002/07/owl#")
624
- xsd = context.prefix_from_iri("http://www.w3.org/2001/XMLSchema#")
625
- knora_api = context.prefix_from_iri("http://api.knora.org/ontology/knora-api/v2#")
626
- salsah_gui = context.prefix_from_iri("http://api.knora.org/ontology/salsah-gui/v2#")
627
-
628
- if not (json_obj.get(knora_api + ':isResourceClass') or json_obj.get(knora_api + ':isStandoffClass')):
629
- raise BaseError("This is not a resource!")
630
-
631
- if json_obj.get('@id') is None:
632
- raise BaseError('Resource class has no "@id"!')
633
- tmp_id = json_obj.get('@id').split(':')
634
- id = context.iri_from_prefix(tmp_id[0]) + '#' + tmp_id[1]
635
- ontology_id = tmp_id[0]
636
- name = tmp_id[1]
637
- superclasses_obj = json_obj.get(rdfs + ':subClassOf')
638
- if superclasses_obj is not None:
639
- supercls: List[Any] = list(filter(lambda a: a.get('@id') is not None, superclasses_obj))
640
- superclasses: List[str] = list(map(lambda a: a['@id'], supercls))
641
- has_props: List[Any] = list(filter(lambda a: a.get('@type') == (owl + ':Restriction'), superclasses_obj))
642
- has_properties: Dict[HasProperty] = dict(map(lambda a: HasProperty.fromJsonObj(con, context, a), has_props))
643
- else:
644
- superclasses = None
645
- has_properties = None
646
-
647
- label = LangString.fromJsonLdObj(json_obj.get(rdfs + ':label'))
648
- comment = LangString.fromJsonLdObj(json_obj.get(rdfs + ':comment'))
649
- return cls(con=con,
650
- context=context,
651
- name=name,
652
- id=id,
653
- ontology_id=ontology_id,
654
- superclasses=superclasses,
655
- label=label,
656
- comment=comment,
657
- has_properties=has_properties)
658
-
659
- def toJsonObj(self, lastModificationDate: LastModificationDate, action: Actions, what: Optional[str] = None) -> Any:
660
-
661
- def resolve_resref(resref: str):
662
- tmp = resref.split(':')
663
- if len(tmp) > 1:
664
- if tmp[0]:
665
- self._context.add_context(tmp[0])
666
- return {"@id": resref} # fully qualified name in the form "prefix:name"
667
- else:
668
- return {"@id": self._context.prefix_from_iri(self._ontology_id) + ':' + tmp[1]} # ":name" in current ontology
669
- else:
670
- return {"@id": "knora-api:" + resref} # no ":", must be from knora-api!
671
-
672
- tmp = {}
673
- exp = re.compile('^http.*') # It is already a fully IRI
674
- if exp.match(self._ontology_id):
675
- resid = self._context.prefix_from_iri(self._ontology_id) + ":" + self._name
676
- ontid = self._ontology_id
677
- else:
678
- resid = self._ontology_id + ":" + self._name
679
- ontid = self._context.iri_from_prefix(self._ontology_id)
680
- if action == Actions.Create:
681
- if self._name is None:
682
- raise BaseError("There must be a valid resource class name!")
683
- if self._ontology_id is None:
684
- raise BaseError("There must be a valid ontology_id given!")
685
- if self._superclasses is None:
686
- superclasses = [{"@id": "knora-api:Resource"}]
687
- else:
688
- superclasses = list(map(resolve_resref, self._superclasses))
689
- if self._comment is None or self._comment.isEmpty():
690
- self._comment = LangString("no comment available")
691
- if self._label is None or self._label.isEmpty():
692
- self._label = LangString("no label available")
693
- tmp = {
694
- "@id": ontid, # self._ontology_id,
695
- "@type": "owl:Ontology",
696
- "knora-api:lastModificationDate": lastModificationDate.toJsonObj(),
697
- "@graph": [{
698
- "@id": resid,
699
- "@type": "owl:Class",
700
- "rdfs:label": self._label.toJsonLdObj(),
701
- "rdfs:comment": self._comment.toJsonLdObj(),
702
- "rdfs:subClassOf": superclasses
703
- }],
704
- "@context": self._context.toJsonObj(),
705
- }
706
- elif action == Actions.Update:
707
- tmp = {
708
- "@id": ontid, # self._ontology_id,
709
- "@type": "owl:Ontology",
710
- "knora-api:lastModificationDate": lastModificationDate.toJsonObj(),
711
- "@graph": [{
712
- "@id": resid,
713
- "@type": "owl:Class",
714
- }],
715
- "@context": self._context.toJsonObj(),
716
- }
717
- if what == 'label':
718
- if not self._label.isEmpty() and 'label' in self._changed:
719
- tmp['@graph'][0]['rdfs:label'] = self._label.toJsonLdObj()
720
- if what == 'comment':
721
- if not self._comment.isEmpty() and 'comment' in self._changed:
722
- tmp['@graph'][0]['rdfs:comment'] = self._comment.toJsonLdObj()
723
- return tmp
724
-
725
- def create(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']:
726
- jsonobj = self.toJsonObj(last_modification_date, Actions.Create)
727
- jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4)
728
- print(jsondata)
729
- result = self._con.post('/v2/ontologies/classes', jsondata)
730
- last_modification_date = LastModificationDate(result['knora-api:lastModificationDate'])
731
- return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph'])
732
-
733
- def update(self, last_modification_date: LastModificationDate) -> Tuple[LastModificationDate, 'ResourceClass']:
734
- #
735
- # Note: Knora is able to change only one thing per call, either label or comment!
736
- #
737
- result = None
738
- something_changed = False
739
- if 'label' in self._changed:
740
- jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'label')
741
- jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4)
742
- result = self._con.put('v2/ontologies/classes', jsondata)
743
- last_modification_date = LastModificationDate(result['knora-api:lastModificationDate'])
744
- something_changed = True
745
- if 'comment' in self._changed:
746
- jsonobj = self.toJsonObj(last_modification_date, Actions.Update, 'comment')
747
- jsondata = json.dumps(jsonobj, cls=SetEncoder, indent=4)
748
- result = self._con.put('v2/ontologies/classes', jsondata)
749
- last_modification_date = LastModificationDate(result['knora-api:lastModificationDate'])
750
- something_changed = True
751
- if something_changed:
752
- return last_modification_date, ResourceClass.fromJsonObj(self._con, self._context, result['@graph'])
753
- else:
754
- return last_modification_date, self
755
-
756
- def delete(self, last_modification_date: LastModificationDate) -> LastModificationDate:
757
- result = self._con.delete('v2/ontologies/classes/' + quote_plus(self._id) + '?lastModificationDate=' + str(last_modification_date))
758
- return LastModificationDate(result['knora-api:lastModificationDate'])
759
-
760
- def createDefinitionFileObj(self, context: Context, shortname: str, skiplist: List[str]):
761
- resource = {
762
- "name": self._name,
763
- "labels": self._label.createDefinitionFileObj(),
764
- }
765
- if self._comment:
766
- resource["comments"] = self._comment.createDefinitionFileObj()
767
- if self._superclasses:
768
- if len(self._superclasses) > 1:
769
- superclasses = []
770
- for sc in self._superclasses:
771
- superclasses.append(context.reduce_iri(sc, shortname))
772
- else:
773
- superclasses = context.reduce_iri(self._superclasses[0], shortname)
774
- resource["super"] = superclasses
775
- if self._has_properties:
776
- cardinalities = []
777
- for pid, hp in self._has_properties.items():
778
- if hp.property_id in skiplist:
779
- continue
780
- if hp.ptype == HasProperty.Ptype.other:
781
- cardinalities.append(hp.createDefinitionFileObj(context, shortname))
782
- resource["cardinalities"] = cardinalities
783
-
784
- return resource
785
-
786
- def print(self, offset: int = 0):
787
- blank = ' '
788
- print(f'{blank:>{offset}}Resource Class Info')
789
- print(f'{blank:>{offset+2}}Name: {self._name}')
790
- print(f'{blank:>{offset+2}}Ontology prefix: {self._ontology_id}')
791
- print(f'{blank:>{offset+2}}Superclasses:')
792
- if self._superclasses is not None:
793
- for sc in self._superclasses:
794
- print(f'{blank:>{offset + 4}}{sc}')
795
- if self._label is not None:
796
- print(f'{blank:>{offset + 2}}Labels:')
797
- self._label.print(offset + 4)
798
- if self._comment is not None:
799
- print(f'{blank:>{offset + 2}}Comments:')
800
- self._comment.print(offset + 4)
801
- if self._has_properties is not None:
802
- print(f'{blank:>{offset + 2}}Has properties:')
803
- if self._has_properties is not None:
804
- for pid, hp in self._has_properties.items():
805
- hp.print(offset + 4)
806
-
807
-
808
-
809
-
810
-