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
@@ -0,0 +1,416 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+
6
+ from dsp_tools.error.problems import Problem
7
+
8
+ separator = "\n "
9
+ list_separator = "\n - "
10
+ medium_separator = "\n----------------------------\n"
11
+
12
+ grand_separator = "\n\n---------------------------------------\n\n"
13
+
14
+
15
+ @dataclass(frozen=True)
16
+ class PositionInExcel:
17
+ """This class contains the information about the position of a value in the excel."""
18
+
19
+ sheet: str | None = None
20
+ column: str | None = None
21
+ row: int | None = None
22
+ excel_filename: str | None = None
23
+
24
+ def __str__(self) -> str:
25
+ msg = []
26
+ if self.excel_filename:
27
+ msg.append(f"Excel '{self.excel_filename}'")
28
+ if self.sheet:
29
+ msg.append(f"Sheet '{self.sheet}'")
30
+ if self.column:
31
+ msg.append(f"Column '{self.column}'")
32
+ if self.row:
33
+ msg.append(f"Row {self.row}")
34
+ return " | ".join(msg)
35
+
36
+ def execute_error_protocol(self) -> str:
37
+ """
38
+ This function initiates all the steps for successful problem communication with the user.
39
+
40
+ Returns:
41
+ message for the error
42
+ """
43
+ return str(self)
44
+
45
+
46
+ @dataclass(frozen=True)
47
+ class ExcelFileProblem:
48
+ """This class contains information about problems with an excel file."""
49
+
50
+ filename: str
51
+ problems: list[Problem]
52
+
53
+ def execute_error_protocol(self) -> str:
54
+ """
55
+ This function initiates all the steps for successful problem communication with the user.
56
+
57
+ Returns:
58
+ message for the error
59
+ """
60
+ msg = f"The Excel file '{self.filename}' contains the following problems:\n\n"
61
+ msg += medium_separator.join([x.execute_error_protocol() for x in self.problems])
62
+ return msg
63
+
64
+
65
+ @dataclass(frozen=True)
66
+ class ExcelSheetProblem:
67
+ """This class contains information about problems in one excel sheet."""
68
+
69
+ sheet_name: str
70
+ problems: list[Problem]
71
+
72
+ def execute_error_protocol(self) -> str:
73
+ """
74
+ This function initiates all the steps for successful problem communication with the user.
75
+
76
+ Returns:
77
+ message for the error
78
+ """
79
+
80
+ problem_strings = [x.execute_error_protocol() for x in self.problems]
81
+ return f"The sheet '{self.sheet_name}' has the following problems:\n\n{'\n\n'.join(problem_strings)}"
82
+
83
+
84
+ @dataclass(frozen=True)
85
+ class EmptySheetsProblem:
86
+ """This class contains information if sheets that must contain information are empty."""
87
+
88
+ sheet_names: list[str]
89
+
90
+ def execute_error_protocol(self) -> str:
91
+ """
92
+ This function initiates all the steps for successful problem communication with the user.
93
+
94
+ Returns:
95
+ message for the error
96
+ """
97
+ return (
98
+ f"The following sheet(s) are mandatory and may not be empty:{list_separator}"
99
+ f"{list_separator.join(sorted(self.sheet_names))}"
100
+ )
101
+
102
+
103
+ @dataclass(frozen=True)
104
+ class MissingValuesProblem:
105
+ """This class contains information if a value is missing in a location"""
106
+
107
+ locations: list[PositionInExcel]
108
+
109
+ def execute_error_protocol(self) -> str:
110
+ """
111
+ This function initiates all the steps for successful problem communication with the user.
112
+
113
+ Returns:
114
+ message for the error
115
+ """
116
+ locs = [str(x) for x in self.locations]
117
+ return f"At the following locations, mandatory values are missing:{list_separator}{list_separator.join(locs)}"
118
+
119
+
120
+ @dataclass(frozen=True)
121
+ class RequiredColumnMissingProblem:
122
+ """This class contains information if a required column is missing."""
123
+
124
+ columns: list[str]
125
+
126
+ def execute_error_protocol(self) -> str:
127
+ """
128
+ This function initiates all the steps for successful problem communication with the user.
129
+
130
+ Returns:
131
+ message for the error
132
+ """
133
+ return f"The following required column(s) are missing:{list_separator}{list_separator.join(self.columns)}"
134
+
135
+
136
+ @dataclass(frozen=True)
137
+ class DuplicatesInColumnProblem:
138
+ """This class contains information if a required column is missing."""
139
+
140
+ column: str
141
+ duplicate_values: list[str]
142
+
143
+ def execute_error_protocol(self) -> str:
144
+ """
145
+ This function initiates all the steps for successful problem communication with the user.
146
+
147
+ Returns:
148
+ message for the error
149
+ """
150
+ return (
151
+ f"No duplicates are allowed in the column '{self.column}'\n"
152
+ f"The following values appear several times:{list_separator}"
153
+ f"{list_separator.join(self.duplicate_values)}"
154
+ )
155
+
156
+
157
+ @dataclass(frozen=True)
158
+ class InvalidExcelContentProblem:
159
+ """This class contains information if a required column is missing."""
160
+
161
+ expected_content: str
162
+ actual_content: str
163
+ excel_position: PositionInExcel
164
+
165
+ def execute_error_protocol(self) -> str:
166
+ """
167
+ This function initiates all the steps for successful problem communication with the user.
168
+
169
+ Returns:
170
+ message for the error
171
+ """
172
+ return (
173
+ f"There is invalid content in the excel.\n"
174
+ f"Located at: {self.excel_position}\n"
175
+ f"Expected Content: {self.expected_content}\n"
176
+ f"Actual Content: {self.actual_content}"
177
+ )
178
+
179
+
180
+ @dataclass(frozen=True)
181
+ class InvalidSheetNameProblem:
182
+ """This class contains information if the excel sheet names are not strings."""
183
+
184
+ excelfile: str
185
+ excel_sheet_names: list[Any]
186
+
187
+ def execute_error_protocol(self) -> str:
188
+ """
189
+ This function initiates all the steps for successful problem communication with the user.
190
+
191
+ Returns:
192
+ message for the error
193
+ """
194
+ sheet_types = [f"Name: {x} | Type {type(x)}" for x in self.excel_sheet_names if not isinstance(x, str)]
195
+ return (
196
+ f"The names sheets in the excel '{self.excelfile}' are not all valid.\n"
197
+ f"They must be of type string. The following names are problematic:\n"
198
+ f"{list_separator}{list_separator.join(sheet_types)}\n"
199
+ f"Please rename them."
200
+ )
201
+
202
+
203
+ @dataclass(frozen=True)
204
+ class DuplicateSheetProblem:
205
+ duplicate_sheets: list[str]
206
+
207
+ def execute_error_protocol(self) -> str:
208
+ """
209
+ This function initiates all the steps for successful problem communication with the user.
210
+
211
+ Returns:
212
+ message for the error
213
+ """
214
+ return (
215
+ f"The sheet names inside the same Excel file must be unique. "
216
+ f"Using capitalisation or spaces to differentiate sheets is not valid.\n"
217
+ f"For example 'sheet' and 'SHEET ' are considered identical.\n"
218
+ f"Under this condition, the following sheet names appear multiple times:"
219
+ f"{list_separator}{list_separator.join(sorted(self.duplicate_sheets))}"
220
+ )
221
+
222
+
223
+ @dataclass(frozen=True)
224
+ class MoreThanOneSheetProblem:
225
+ """This class contains information if the excel containing the property values has more than one sheet."""
226
+
227
+ excelname: str
228
+ sheet_names: list[str]
229
+
230
+ def execute_error_protocol(self) -> str:
231
+ msg = [
232
+ f"\nIn the '{self.excelname}' file only one sheet is allowed.",
233
+ f"The excel used contains the following sheets:{list_separator}{list_separator.join(self.sheet_names)}",
234
+ "Please delete all but one sheet.",
235
+ ]
236
+ return separator.join(msg)
237
+
238
+
239
+ @dataclass(frozen=True)
240
+ class MandatorySheetsMissingProblem:
241
+ """This class contains information if the excel is missing a mandatory sheet."""
242
+
243
+ mandatory_sheet: list[str]
244
+ existing_sheets: list[str]
245
+
246
+ def execute_error_protocol(self) -> str:
247
+ return (
248
+ f"The following mandatory sheet(s) are missing in this Excel:{list_separator}"
249
+ f"{list_separator.join(sorted(self.mandatory_sheet))}"
250
+ f"The following sheets are in the file:{list_separator}"
251
+ f"{list_separator.join(sorted(self.existing_sheets))}"
252
+ )
253
+
254
+
255
+ @dataclass(frozen=True)
256
+ class ResourceSheetNotListedProblem:
257
+ """This class contains information if some resource sheets are missing in the 'classes' sheet."""
258
+
259
+ missing_names: set[str]
260
+
261
+ def execute_error_protocol(self) -> str:
262
+ """
263
+ This function initiates all the steps for successful problem communication with the user.
264
+
265
+ Returns:
266
+ message for the error
267
+ """
268
+ return (
269
+ f"All the sheets in the Excel must be listed in the 'name' column of the 'classes' sheet.\n"
270
+ f"The following sheet(s) are not listed in the column:{list_separator}"
271
+ f"{list_separator.join(self.missing_names)}"
272
+ )
273
+
274
+
275
+ @dataclass(frozen=True)
276
+ class MoreThanOneRowProblem:
277
+ """This class contains information if a sheet has more than one row."""
278
+
279
+ num_rows: int
280
+
281
+ def execute_error_protocol(self) -> str:
282
+ """
283
+ This function initiates all the steps for successful problem communication with the user.
284
+
285
+ Returns:
286
+ message for the error
287
+ """
288
+ return f"This sheet may only have one row. The provided sheet has {self.num_rows} rows."
289
+
290
+
291
+ @dataclass(frozen=True)
292
+ class AtLeastOneValueRequiredProblem:
293
+ """This class contains information if at least one entry in a group of columns must be filled."""
294
+
295
+ columns: list[str]
296
+ row_num: int
297
+
298
+ def execute_error_protocol(self) -> str:
299
+ """
300
+ This function initiates all the steps for successful problem communication with the user.
301
+
302
+ Returns:
303
+ message for the error
304
+ """
305
+ return (
306
+ f"At least one value is required in the columns: {', '.join(sorted(self.columns))}\n"
307
+ f"Row {self.row_num} does not contain any values in those columns."
308
+ )
309
+
310
+
311
+ @dataclass(frozen=True)
312
+ class JsonValidationPropertyProblem:
313
+ """This class contains information about a JSON property section that fails its validation against the schema."""
314
+
315
+ problematic_property: str | None = None
316
+ original_msg: str | None = None
317
+ message_path: str | None = None
318
+ excel_position: PositionInExcel | None = None
319
+
320
+ def execute_error_protocol(self) -> str:
321
+ """
322
+ This function initiates all the steps for successful problem communication with the user.
323
+
324
+ Returns:
325
+ message for the error
326
+ """
327
+ msg = [
328
+ f"{separator}Section of the problem: 'Properties'",
329
+ ]
330
+ if self.problematic_property:
331
+ msg.append(f"Problematic property: '{self.problematic_property}'")
332
+ if self.excel_position:
333
+ msg.append(f"Located at: {self.excel_position}")
334
+ if self.original_msg:
335
+ msg.append(f"Original Error Message: {self.original_msg}")
336
+ if self.message_path:
337
+ msg.append(f"The error occurred at {self.message_path}")
338
+ return separator.join(msg)
339
+
340
+
341
+ @dataclass(frozen=True)
342
+ class JsonValidationResourceProblem:
343
+ """This class contains information about a JSON resource section that fails its validation against the schema."""
344
+
345
+ problematic_resource: str | None = None
346
+ excel_position: PositionInExcel | None = None
347
+ original_msg: str | None = None
348
+ message_path: str | None = None
349
+
350
+ def execute_error_protocol(self) -> str:
351
+ """
352
+ This function initiates all the steps for successful problem communication with the user.
353
+
354
+ Returns:
355
+ message for the error
356
+ """
357
+ msg = [
358
+ f"{separator}Section of the problem: 'Resources'",
359
+ ]
360
+ if self.problematic_resource:
361
+ msg.append(f"Problematic Resource '{self.problematic_resource}'")
362
+ if self.excel_position:
363
+ msg.append(f"Located at: {self.excel_position}")
364
+ if self.original_msg:
365
+ msg.append(f"Original Error Message: {self.original_msg}")
366
+ if self.message_path:
367
+ msg.append(f"The error occurred at {self.message_path}")
368
+ return separator.join(msg)
369
+
370
+
371
+ @dataclass(frozen=True)
372
+ class PropertyProblem:
373
+ """This class contains information if a property has invalid content."""
374
+
375
+ prop_name: str
376
+ problems: list[Problem]
377
+
378
+ def execute_error_protocol(self) -> str:
379
+ """
380
+ This function initiates all the steps for successful problem communication with the user.
381
+
382
+ Returns:
383
+ message for the error
384
+ """
385
+ all_problems = [x.execute_error_protocol() for x in self.problems]
386
+ return f"The property '{self.prop_name}' has the following problem(s):\n{medium_separator.join(all_problems)}"
387
+
388
+
389
+ @dataclass(frozen=True)
390
+ class InvalidPermissionsOverrule:
391
+ entity_name: str
392
+ actual_val: str
393
+ allowed_vals: list[str]
394
+
395
+
396
+ @dataclass(frozen=True)
397
+ class InvalidPermissionsOverruleProblem:
398
+ """This class contains information if a "default_permissions_overrule" is invalid."""
399
+
400
+ wrong_vals: list[InvalidPermissionsOverrule]
401
+
402
+ def execute_error_protocol(self) -> str:
403
+ """
404
+ This function initiates all the steps for successful problem communication with the user.
405
+
406
+ Returns:
407
+ message for the error
408
+ """
409
+ report_lines = [
410
+ f"Entity: '{x.entity_name}'. Actual value: '{x.actual_val}'. Allowed values: {', '.join(x.allowed_vals)}."
411
+ for x in self.wrong_vals
412
+ ]
413
+ return (
414
+ f"The following entities have an invalid 'default_permissions_overrule': "
415
+ f"{list_separator}{list_separator.join(report_lines)}"
416
+ )
@@ -0,0 +1,175 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+ from typing import Protocol
6
+
7
+ SCHEMA = "https://raw.githubusercontent.com/dasch-swiss/dsp-tools/main/src/dsp_tools/resources/schema/project.json"
8
+
9
+
10
+ @dataclass
11
+ class JsonHeader(Protocol):
12
+ def to_dict(self) -> dict[str, Any]:
13
+ raise NotImplementedError
14
+
15
+
16
+ @dataclass
17
+ class EmptyJsonHeader(JsonHeader):
18
+ def to_dict(self) -> dict[str, Any]:
19
+ return {
20
+ "prefixes": {"": ""},
21
+ "$schema": SCHEMA,
22
+ "project": {
23
+ "shortcode": "",
24
+ "shortname": "",
25
+ "longname": "",
26
+ "descriptions": {"en": ""},
27
+ "keywords": [""],
28
+ "enabled_licenses": [""],
29
+ },
30
+ }
31
+
32
+
33
+ @dataclass
34
+ class FilledJsonHeader(JsonHeader):
35
+ project: Project
36
+ prefixes: Prefixes | None
37
+
38
+ def to_dict(self) -> dict[str, Any]:
39
+ header_dict: dict[str, Any] = {}
40
+ if self.prefixes:
41
+ header_dict["prefixes"] = self.prefixes.to_dict()
42
+ header_dict.update({"$schema": SCHEMA, "project": self.project.to_dict()})
43
+ return header_dict
44
+
45
+
46
+ @dataclass
47
+ class Prefixes:
48
+ prefixes: dict[str, str]
49
+
50
+ def to_dict(self) -> dict[str, Any]:
51
+ return self.prefixes
52
+
53
+
54
+ @dataclass
55
+ class Project:
56
+ shortcode: str
57
+ shortname: str
58
+ longname: str
59
+ descriptions: Descriptions
60
+ keywords: Keywords
61
+ licenses: Licenses
62
+ users: Users | None
63
+ default_permissions: str
64
+
65
+ def to_dict(self) -> dict[str, Any]:
66
+ proj_dict: dict[str, Any] = {
67
+ "shortcode": self.shortcode,
68
+ "shortname": self.shortname,
69
+ "longname": self.longname,
70
+ "descriptions": self.descriptions.to_dict(),
71
+ "keywords": self.keywords.to_dict(),
72
+ "enabled_licenses": self.licenses.to_dict(),
73
+ "default_permissions": self.default_permissions,
74
+ }
75
+ if self.users:
76
+ proj_dict["users"] = self.users.to_dict()
77
+ return proj_dict
78
+
79
+
80
+ @dataclass
81
+ class Descriptions:
82
+ descriptions: dict[str, str]
83
+
84
+ def __post_init__(self) -> None:
85
+ for k, v in self.descriptions.items():
86
+ self.descriptions[k] = v.replace("\n", "<br/>")
87
+
88
+ def to_dict(self) -> dict[str, str]:
89
+ return self.descriptions
90
+
91
+
92
+ @dataclass
93
+ class Keywords:
94
+ keywords: list[str]
95
+
96
+ def to_dict(self) -> list[str]:
97
+ return sorted(self.keywords)
98
+
99
+
100
+ @dataclass
101
+ class Licenses:
102
+ licenses: list[str]
103
+
104
+ def to_dict(self) -> list[str]:
105
+ return sorted(self.licenses)
106
+
107
+
108
+ @dataclass
109
+ class Users:
110
+ users: list[User]
111
+
112
+ def to_dict(self) -> list[dict[str, Any]]:
113
+ return [x.to_dict() for x in self.users]
114
+
115
+
116
+ @dataclass
117
+ class User:
118
+ username: str
119
+ email: str
120
+ givenName: str
121
+ familyName: str
122
+ password: str | None
123
+ lang: str
124
+ isProjectAdmin: bool
125
+
126
+ def to_dict(self) -> dict[str, Any]:
127
+ usr_dict: dict[str, Any] = {
128
+ "username": self.username,
129
+ "email": self.email,
130
+ "givenName": self.givenName,
131
+ "familyName": self.familyName,
132
+ "password": self.password,
133
+ "lang": self.lang,
134
+ "status": True,
135
+ }
136
+ if self.isProjectAdmin:
137
+ usr_dict["projects"] = [":admin", ":member"]
138
+ else:
139
+ usr_dict["projects"] = [":member"]
140
+ return usr_dict
141
+
142
+
143
+ @dataclass
144
+ class PermissionsOverrulesUnprefixed:
145
+ """
146
+ Data gathered from the column 'default_permissions_overrule' from 1 resources.xlsx / 1 properties.xlsx,
147
+ not yet enriched with ontology prefixes
148
+ """
149
+
150
+ private: list[str]
151
+ limited_view: list[str]
152
+
153
+
154
+ @dataclass
155
+ class PermissionsOverrulesPrefixed:
156
+ """
157
+ Object to gather 'default_permissions_overrule' infos from several resources.xlsx/properties.xlsx,
158
+ with ontology prefixes.
159
+ """
160
+
161
+ private: list[str]
162
+ limited_view: list[str]
163
+
164
+ def add_overrules(self, new_overrules: PermissionsOverrulesUnprefixed, onto_prefix: str) -> None:
165
+ self.private.extend([f"{onto_prefix}:{p}" for p in new_overrules.private])
166
+ self.limited_view.extend([f"{onto_prefix}:{p}" for p in new_overrules.limited_view])
167
+
168
+ def non_empty(self) -> bool:
169
+ return bool(self.private or self.limited_view)
170
+
171
+ def serialize(self) -> dict[str, list[str]]:
172
+ return {
173
+ "private": self.private,
174
+ "limited_view": self.limited_view,
175
+ }
@@ -0,0 +1,16 @@
1
+ from dataclasses import dataclass
2
+ from dataclasses import field
3
+
4
+
5
+ @dataclass
6
+ class ListNodeNames:
7
+ """
8
+ Contains the information to construct a list
9
+
10
+ Args:
11
+ lists_with_previous_cell_values: used to ensure that there are no duplicate node names
12
+ previous_node_names: used to ensure that there are no duplicate node names
13
+ """
14
+
15
+ lists_with_previous_cell_values: list[list[str]] = field(default_factory=list)
16
+ previous_node_names: list[str] = field(default_factory=list)
@@ -0,0 +1,76 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+ from typing import Any
5
+
6
+
7
+ @dataclass
8
+ class OntoResource:
9
+ name: str
10
+ super: list[str]
11
+ labels: LanguageDict
12
+ comments: LanguageDict | None
13
+ cardinalities: list[ResourceCardinality] | None
14
+
15
+ def serialise(self) -> dict[str, Any]:
16
+ res: dict[str, Any] = {
17
+ "name": self.name,
18
+ "super": self.super,
19
+ "labels": self.labels.serialise(),
20
+ }
21
+ if self.comments:
22
+ res["comments"] = self.comments.serialise()
23
+ if self.cardinalities:
24
+ res["cardinalities"] = [x.serialise() for x in self.cardinalities]
25
+ return res
26
+
27
+
28
+ @dataclass
29
+ class ResourceCardinality:
30
+ propname: str
31
+ cardinality: str
32
+ gui_order: int
33
+
34
+ def serialise(self) -> dict[str, str | int]:
35
+ return {"propname": self.propname, "cardinality": self.cardinality, "gui_order": self.gui_order}
36
+
37
+
38
+ @dataclass
39
+ class OntoProperty:
40
+ name: str
41
+ super: list[str]
42
+ object: str
43
+ subject: str | None
44
+ labels: LanguageDict
45
+ comments: LanguageDict | None
46
+ gui_element: str
47
+ gui_attributes: GuiAttributes | None
48
+
49
+ def serialise(self) -> dict[str, Any]:
50
+ prop_dict: dict[str, Any] = {"name": self.name, "super": self.super, "object": self.object}
51
+ if self.subject:
52
+ prop_dict["subject"] = self.subject
53
+ prop_dict["labels"] = self.labels.serialise()
54
+ if self.comments:
55
+ prop_dict["comments"] = self.comments.serialise()
56
+ prop_dict["gui_element"] = self.gui_element
57
+ if self.gui_attributes:
58
+ prop_dict["gui_attributes"] = self.gui_attributes.serialise()
59
+ return prop_dict
60
+
61
+
62
+ @dataclass
63
+ class LanguageDict:
64
+ lang_dict: dict[str, str]
65
+
66
+ def serialise(self) -> dict[str, str]:
67
+ sorted_dict = {k: self.lang_dict[k] for k in sorted(self.lang_dict.keys())}
68
+ return sorted_dict
69
+
70
+
71
+ @dataclass
72
+ class GuiAttributes:
73
+ gui_attributes: dict[str, str]
74
+
75
+ def serialise(self) -> dict[str, str]:
76
+ return self.gui_attributes