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,370 @@
1
+ from __future__ import annotations
2
+
3
+ import importlib.resources
4
+ import json
5
+ import warnings
6
+ from typing import Any
7
+ from typing import Optional
8
+ from typing import cast
9
+
10
+ import jsonpath_ng.ext
11
+ import jsonschema
12
+ import numpy as np
13
+ import pandas as pd
14
+ import regex
15
+
16
+ from dsp_tools.commands.excel2json.models.input_error import ExcelFileProblem
17
+ from dsp_tools.commands.excel2json.models.input_error import InvalidExcelContentProblem
18
+ from dsp_tools.commands.excel2json.models.input_error import JsonValidationPropertyProblem
19
+ from dsp_tools.commands.excel2json.models.input_error import MissingValuesProblem
20
+ from dsp_tools.commands.excel2json.models.input_error import MoreThanOneSheetProblem
21
+ from dsp_tools.commands.excel2json.models.input_error import PositionInExcel
22
+ from dsp_tools.commands.excel2json.models.input_error import PropertyProblem
23
+ from dsp_tools.commands.excel2json.models.json_header import PermissionsOverrulesUnprefixed
24
+ from dsp_tools.commands.excel2json.models.ontology import GuiAttributes
25
+ from dsp_tools.commands.excel2json.models.ontology import OntoProperty
26
+ from dsp_tools.commands.excel2json.utils import add_optional_columns
27
+ from dsp_tools.commands.excel2json.utils import check_column_for_duplicate
28
+ from dsp_tools.commands.excel2json.utils import check_contains_required_columns
29
+ from dsp_tools.commands.excel2json.utils import check_permissions
30
+ from dsp_tools.commands.excel2json.utils import check_required_values
31
+ from dsp_tools.commands.excel2json.utils import col_must_or_not_empty_based_on_other_col
32
+ from dsp_tools.commands.excel2json.utils import find_one_full_cell_in_cols
33
+ from dsp_tools.commands.excel2json.utils import get_comments
34
+ from dsp_tools.commands.excel2json.utils import get_labels
35
+ from dsp_tools.commands.excel2json.utils import get_wrong_row_numbers
36
+ from dsp_tools.commands.excel2json.utils import read_and_clean_all_sheets
37
+ from dsp_tools.error.exceptions import InputError
38
+ from dsp_tools.error.exceptions import InvalidGuiAttributeError
39
+ from dsp_tools.error.problems import Problem
40
+
41
+ languages = ["en", "de", "fr", "it", "rm"]
42
+ language_label_col = ["label_en", "label_de", "label_fr", "label_it", "label_rm"]
43
+
44
+
45
+ def excel2properties(
46
+ excelfile: str,
47
+ path_to_output_file: Optional[str] = None,
48
+ ) -> tuple[list[dict[str, Any]], PermissionsOverrulesUnprefixed, bool]:
49
+ """
50
+ Converts properties described in an Excel file into a "properties" section which can be inserted into a JSON
51
+ project file.
52
+
53
+ Args:
54
+ excelfile: path to the Excel file containing the properties
55
+ path_to_output_file: if provided, the output is written into this JSON file
56
+
57
+ Raises:
58
+ InputError: if something went wrong
59
+
60
+ Returns:
61
+ - the "properties" section as a Python list
62
+ - the unprefixed "default_permissions_overrule"
63
+ - the success status (True if everything went well)
64
+ """
65
+
66
+ property_df = _read_check_property_df(excelfile)
67
+
68
+ property_df = _rename_deprecated_columnnames(df=property_df)
69
+
70
+ # Not all columns have to be filled, users may delete some for ease of use, but it would generate an error later
71
+ optional_col_set = {
72
+ "label_en",
73
+ "label_de",
74
+ "label_fr",
75
+ "label_it",
76
+ "label_rm",
77
+ "comment_en",
78
+ "comment_de",
79
+ "comment_fr",
80
+ "comment_it",
81
+ "comment_rm",
82
+ "subject",
83
+ "default_permissions_overrule",
84
+ }
85
+ property_df = add_optional_columns(property_df, optional_col_set)
86
+
87
+ _do_property_excel_compliance(df=property_df)
88
+
89
+ _check_for_deprecated_syntax(property_df)
90
+
91
+ # transform every row into a property
92
+ props: list[OntoProperty] = []
93
+ problems: list[Problem] = []
94
+ for index, row in property_df.iterrows():
95
+ result = _row2prop(
96
+ df_row=row,
97
+ row_num=int(str(index)) + 2, # index is a label/index/hashable, but we need an int
98
+ )
99
+ if isinstance(result, PropertyProblem):
100
+ problems.append(result)
101
+ else:
102
+ props.append(result)
103
+ if problems:
104
+ msg = ExcelFileProblem("properties.xlsx", problems).execute_error_protocol()
105
+ raise InputError(msg)
106
+
107
+ serialised_prop = [x.serialise() for x in props]
108
+ default_permissions_overrule = _extract_default_permissions_overrule(property_df)
109
+
110
+ # write final JSON file
111
+ _validate_properties_section_in_json(properties_list=serialised_prop)
112
+ if path_to_output_file:
113
+ with open(file=path_to_output_file, mode="w", encoding="utf-8") as file:
114
+ json.dump(serialised_prop, file, indent=4, ensure_ascii=False)
115
+ print(f"properties section was created successfully and written to file '{path_to_output_file}'")
116
+
117
+ return serialised_prop, default_permissions_overrule, True
118
+
119
+
120
+ def _check_for_deprecated_syntax(df: pd.DataFrame) -> None:
121
+ pass
122
+
123
+
124
+ def _read_check_property_df(excelfile: str) -> pd.DataFrame:
125
+ sheets_df_dict = read_and_clean_all_sheets(excelfile)
126
+ if len(sheets_df_dict) != 1:
127
+ msg = MoreThanOneSheetProblem("properties.xlsx", list(sheets_df_dict.keys())).execute_error_protocol()
128
+ raise InputError(msg)
129
+ return next(iter(sheets_df_dict.values()))
130
+
131
+
132
+ def _rename_deprecated_columnnames(df: pd.DataFrame) -> pd.DataFrame:
133
+ df = _rename_deprecated_lang_cols(df=df)
134
+ df = _rename_deprecated_hlist(df=df)
135
+ return df
136
+
137
+
138
+ def _rename_deprecated_lang_cols(df: pd.DataFrame) -> pd.DataFrame:
139
+ if set(language_label_col).issubset(set(df.columns)):
140
+ return df
141
+ if set(languages).issubset(set(df.columns)):
142
+ warnings.warn(
143
+ f"The file 'properties.xlsx' uses {languages} as column titles, which is deprecated. "
144
+ f"Please use {[f'label_{lang}' for lang in languages]}"
145
+ )
146
+ rename_dict = dict(zip(languages, language_label_col))
147
+ df = df.rename(columns=rename_dict)
148
+ return df
149
+
150
+
151
+ def _rename_deprecated_hlist(df: pd.DataFrame) -> pd.DataFrame:
152
+ # This function deals with Excel files that do conform to a previous format.
153
+ if "hlist" not in df.columns:
154
+ return df
155
+ warnings.warn(
156
+ "The file 'properties.xlsx' has a column 'hlist', which is deprecated. "
157
+ "Please use the column 'gui_attributes' for the attribute 'hlist'."
158
+ )
159
+ df["hlist"] = df["hlist"].apply(lambda x: f"hlist:{x}" if isinstance(x, str) else x)
160
+ # If gui_attributes already exists we have to merge the columns
161
+ if "gui_attributes" in df.columns:
162
+ # In case there is a hlist, it is the only valid value in gui_attributes and has precedence
163
+ df["hlist"] = df["hlist"].fillna(df["gui_attributes"])
164
+ df.pop("gui_attributes")
165
+ df = df.rename(columns={"hlist": "gui_attributes"})
166
+ return df
167
+
168
+
169
+ def _do_property_excel_compliance(df: pd.DataFrame) -> None:
170
+ required_columns = {
171
+ "name",
172
+ "super",
173
+ "object",
174
+ "gui_element",
175
+ "gui_attributes",
176
+ }
177
+ problems: list[Problem] = []
178
+ if req_prob := check_contains_required_columns(df=df, required_columns=required_columns):
179
+ problems.append(req_prob)
180
+ if col_prob := check_column_for_duplicate(df=df, to_check_column="name"):
181
+ problems.append(col_prob)
182
+ if missing_vals_check := _check_missing_values_in_row(df=df):
183
+ problems.append(missing_vals_check)
184
+ if permissions_prob := check_permissions(df=df, allowed_vals=["private"]):
185
+ problems.append(permissions_prob)
186
+ if any(problems):
187
+ excel_prob = ExcelFileProblem("properties.xlsx", problems)
188
+ msg = excel_prob.execute_error_protocol()
189
+ raise InputError(msg)
190
+
191
+
192
+ def _check_missing_values_in_row(df: pd.DataFrame) -> None | MissingValuesProblem:
193
+ required_values = ["name", "super", "object", "gui_element"]
194
+ missing_dict = check_required_values(df=df, required_values_columns=required_values)
195
+ missing_labels = find_one_full_cell_in_cols(df=df, required_columns=language_label_col)
196
+ if missing_labels is not None:
197
+ missing_dict.update({"label": missing_labels})
198
+ missing_gui_attributes = _check_compliance_gui_attributes(df=df)
199
+ if missing_gui_attributes is not None:
200
+ missing_dict.update(missing_gui_attributes)
201
+ if missing_dict:
202
+ missing_int_dict = get_wrong_row_numbers(wrong_row_dict=missing_dict, true_remains=True)
203
+ locs = []
204
+ for col, row_nums in missing_int_dict.items():
205
+ locs.extend([PositionInExcel(column=col, row=x) for x in row_nums])
206
+ return MissingValuesProblem(locs)
207
+ else:
208
+ return None
209
+
210
+
211
+ def _check_compliance_gui_attributes(df: pd.DataFrame) -> dict[str, pd.Series[bool]] | None:
212
+ mandatory_attributes = ["List"]
213
+ mandatory_check = col_must_or_not_empty_based_on_other_col(
214
+ df=df,
215
+ substring_list=mandatory_attributes,
216
+ substring_colname="gui_element",
217
+ check_empty_colname="gui_attributes",
218
+ must_have_value=True,
219
+ )
220
+ no_attributes = [
221
+ "Checkbox",
222
+ "Colorpicker",
223
+ "Date",
224
+ "Spinbox",
225
+ "Geonames",
226
+ "SimpleText",
227
+ "Textarea",
228
+ "Richtext",
229
+ "TimeStamp",
230
+ "Searchbox",
231
+ ]
232
+ no_attribute_check = col_must_or_not_empty_based_on_other_col(
233
+ df=df,
234
+ substring_list=no_attributes,
235
+ substring_colname="gui_element",
236
+ check_empty_colname="gui_attributes",
237
+ must_have_value=False,
238
+ )
239
+ final_series = _get_final_series(mandatory_check, no_attribute_check)
240
+ return {"gui_attributes": final_series} if final_series is not None else None
241
+
242
+
243
+ def _get_final_series(
244
+ mandatory_check: pd.Series[bool] | None, no_attribute_check: pd.Series[bool] | None
245
+ ) -> pd.Series[bool] | None:
246
+ final_series: pd.Series[bool] = pd.Series()
247
+ match mandatory_check, no_attribute_check:
248
+ case None, None:
249
+ return None
250
+ case pd.Series(), pd.Series():
251
+ final_series = pd.Series(np.logical_or(mandatory_check, no_attribute_check))
252
+ case pd.Series(), None:
253
+ final_series = mandatory_check
254
+ case None, pd.Series():
255
+ final_series = no_attribute_check
256
+ return final_series
257
+
258
+
259
+ def _row2prop(df_row: pd.Series[Any], row_num: int) -> OntoProperty | PropertyProblem:
260
+ subj = df_row["subject"] if not pd.isna(df_row["subject"]) else None
261
+ comment = get_comments(df_row=df_row)
262
+ gui_attrib = _get_gui_attribute(df_row=df_row, row_num=row_num)
263
+ if isinstance(gui_attrib, InvalidExcelContentProblem):
264
+ return PropertyProblem(df_row["name"], cast(list[Problem], [gui_attrib]))
265
+ prop = OntoProperty(
266
+ name=df_row["name"],
267
+ super=[s.strip() for s in df_row["super"].split(",")],
268
+ object=df_row["object"],
269
+ subject=subj,
270
+ labels=get_labels(df_row=df_row),
271
+ comments=comment,
272
+ gui_element=df_row["gui_element"],
273
+ gui_attributes=gui_attrib,
274
+ )
275
+ return prop
276
+
277
+
278
+ def _get_gui_attribute(
279
+ df_row: pd.Series[Any],
280
+ row_num: int,
281
+ ) -> GuiAttributes | InvalidExcelContentProblem | None:
282
+ if pd.isnull(df_row["gui_attributes"]):
283
+ return None
284
+ try:
285
+ return _unpack_gui_attributes(attribute_str=df_row["gui_attributes"])
286
+ except InvalidGuiAttributeError:
287
+ return InvalidExcelContentProblem(
288
+ expected_content="The only valid gui-attribute is 'hlist' for the gui-element 'List'.",
289
+ actual_content=df_row["gui_attributes"],
290
+ excel_position=PositionInExcel(column="gui_attributes", row=row_num),
291
+ )
292
+
293
+
294
+ def _unpack_gui_attributes(attribute_str: str) -> GuiAttributes:
295
+ attribute_str = attribute_str.strip()
296
+ if not attribute_str:
297
+ return GuiAttributes({})
298
+ attrib_key, attrib_val = _extract_information_from_single_gui_attribute(attribute_str)
299
+ if attrib_key != "hlist":
300
+ raise InvalidGuiAttributeError("The only valid gui-attribute is 'hlist' for the gui-element 'List'.")
301
+ return GuiAttributes({attrib_key: attrib_val})
302
+
303
+
304
+ def _extract_information_from_single_gui_attribute(attribute_str: str) -> tuple[str, str]:
305
+ attrib_format = r"(\S+)\s*:\s*(.+)"
306
+ if found := regex.search(attrib_format, attribute_str):
307
+ return found.group(1), found.group(2)
308
+ raise InvalidGuiAttributeError("Invalid gui attribute")
309
+
310
+
311
+ def _validate_properties_section_in_json(
312
+ properties_list: list[dict[str, Any]],
313
+ ) -> None:
314
+ with (
315
+ importlib.resources.files("dsp_tools")
316
+ .joinpath("resources/schema/properties-only.json")
317
+ .open(encoding="utf-8") as schema_file
318
+ ):
319
+ properties_schema = json.load(schema_file)
320
+ try:
321
+ jsonschema.validate(instance=properties_list, schema=properties_schema)
322
+ except jsonschema.ValidationError as err:
323
+ validation_problem = _find_validation_problem(properties_list=properties_list, validation_error=err)
324
+ msg = ExcelFileProblem("properties.xlsx", [validation_problem]).execute_error_protocol()
325
+ raise InputError(msg) from None
326
+
327
+
328
+ def _find_validation_problem(
329
+ properties_list: list[dict[str, Any]],
330
+ validation_error: jsonschema.ValidationError,
331
+ ) -> JsonValidationPropertyProblem:
332
+ if json_path_to_property := regex.search(r"^\$\[(\d+)\]", validation_error.json_path):
333
+ # fmt: off
334
+ wrong_property_name = (
335
+ jsonpath_ng.ext.parse(json_path_to_property.group(0))
336
+ .find(properties_list)[0]
337
+ .value["name"]
338
+ )
339
+ # fmt: on
340
+ excel_row = int(json_path_to_property.group(1)) + 2
341
+
342
+ column = None
343
+ val_msg = None
344
+ if affected_field := regex.search(
345
+ r"name|labels|comments|super|subject|object|gui_element|gui_attributes",
346
+ validation_error.json_path,
347
+ ):
348
+ column = affected_field.group(0)
349
+ val_msg = validation_error.message
350
+
351
+ return JsonValidationPropertyProblem(
352
+ problematic_property=wrong_property_name,
353
+ excel_position=PositionInExcel(column=column, row=excel_row),
354
+ original_msg=val_msg,
355
+ )
356
+ return JsonValidationPropertyProblem(
357
+ original_msg=validation_error.message,
358
+ message_path=validation_error.json_path,
359
+ )
360
+
361
+
362
+ def _extract_default_permissions_overrule(property_df: pd.DataFrame) -> PermissionsOverrulesUnprefixed:
363
+ result = PermissionsOverrulesUnprefixed(private=[], limited_view=[])
364
+ for _, row in property_df.iterrows():
365
+ perm = row.get("default_permissions_overrule")
366
+ if pd.isna(perm):
367
+ continue
368
+ if perm.strip().lower() == "private":
369
+ result.private.append(row["name"])
370
+ return result