iolanta 2.1.13__tar.gz → 2.1.14__tar.gz

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 (172) hide show
  1. {iolanta-2.1.13 → iolanta-2.1.14}/PKG-INFO +1 -1
  2. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_browser/page_switcher.py +37 -39
  3. iolanta-2.1.14/iolanta/facets/textual_class/sparql/instances.sparql +6 -0
  4. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_no_facet_found.py +40 -14
  5. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/iolanta.py +15 -5
  6. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/sparqlspace/processor.py +0 -9
  7. iolanta-2.1.14/iolanta/sparqlspace/redirects.py +58 -0
  8. {iolanta-2.1.13 → iolanta-2.1.14}/pyproject.toml +1 -1
  9. iolanta-2.1.13/iolanta/facets/textual_class/sparql/instances.sparql +0 -8
  10. iolanta-2.1.13/iolanta/sparqlspace/redirects.py +0 -79
  11. {iolanta-2.1.13 → iolanta-2.1.14}/README.md +0 -0
  12. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/__init__.py +0 -0
  13. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/base_plugin.py +0 -0
  14. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/cli/__init__.py +0 -0
  15. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/cli/formatters/__init__.py +0 -0
  16. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/cli/formatters/choose.py +0 -0
  17. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/cli/formatters/csv.py +0 -0
  18. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/cli/formatters/json.py +0 -0
  19. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/cli/formatters/pretty.py +0 -0
  20. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/cli/main.py +0 -0
  21. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/cli/models.py +0 -0
  22. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/cli/pretty_print.py +0 -0
  23. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/context.py +0 -0
  24. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/conversions.py +0 -0
  25. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/data/context.yaml +0 -0
  26. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/data/graph-triples.yamlld +0 -0
  27. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/data/iolanta.yaml +0 -0
  28. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/data/textual-browser.yaml +0 -0
  29. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/declension/__init__.py +0 -0
  30. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/declension/data/declension.yamlld +0 -0
  31. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/declension/facet.py +0 -0
  32. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/declension/sparql/declension.sparql +0 -0
  33. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/ensure_is_context.py +0 -0
  34. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/entry_points.py +0 -0
  35. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/errors.py +0 -0
  36. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/__init__.py +0 -0
  37. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/cli/__init__.py +0 -0
  38. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/cli/base.py +0 -0
  39. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/cli/default.py +0 -0
  40. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/cli/record.py +0 -0
  41. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/cli/sparql/link.sparql +0 -0
  42. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/cli/sparql/record.sparql +0 -0
  43. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/errors.py +0 -0
  44. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/facet.py +0 -0
  45. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/foaf_person_title/__init__.py +0 -0
  46. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/foaf_person_title/facet.py +0 -0
  47. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/foaf_person_title/sparql/names.sparql +0 -0
  48. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/generic/__init__.py +0 -0
  49. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/generic/bool_literal.py +0 -0
  50. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/generic/date_literal.py +0 -0
  51. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/generic/default.py +0 -0
  52. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/generic/sparql/default.sparql +0 -0
  53. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/html/__init__.py +0 -0
  54. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/html/base.py +0 -0
  55. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/html/code_literal.py +0 -0
  56. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/html/default.py +0 -0
  57. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/icon.py +0 -0
  58. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/locator/sparql/get-query-to-facet.sparql +0 -0
  59. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/locator.py +0 -0
  60. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mermaid_roadmap/__init__.py +0 -0
  61. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mermaid_roadmap/facet.py +0 -0
  62. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mermaid_roadmap/inference/blocks.sparql +0 -0
  63. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mermaid_roadmap/inference/has-task-default-type.sparql +0 -0
  64. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mermaid_roadmap/inference/task.sparql +0 -0
  65. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mermaid_roadmap/inference/unblocked.sparql +0 -0
  66. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mermaid_roadmap/mermaid_roadmap.yamlld +0 -0
  67. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mermaid_roadmap/sparql/edges.sparql +0 -0
  68. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mermaid_roadmap/sparql/nodes.sparql +0 -0
  69. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mkdocs_material_insiders_markdown/__init__.py +0 -0
  70. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mkdocs_material_insiders_markdown/data/mkdocs_material_insiders_markdown.yamlld +0 -0
  71. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mkdocs_material_insiders_markdown/facet.py +0 -0
  72. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/mkdocs_material_insiders_markdown/templates/datatype.jinja2.md +0 -0
  73. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/page_title.py +0 -0
  74. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/qname.py +0 -0
  75. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/__init__.py +0 -0
  76. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/ask_result_csv.py +0 -0
  77. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/ask_result_json.py +0 -0
  78. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/ask_result_table.py +0 -0
  79. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/construct_result_csv.py +0 -0
  80. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/construct_result_json.py +0 -0
  81. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/construct_result_table.py +0 -0
  82. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/data/query_result.yamlld +0 -0
  83. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/select_result_csv.py +0 -0
  84. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/select_result_json.py +0 -0
  85. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/query/select_result_table.py +0 -0
  86. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_browser/__init__.py +0 -0
  87. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_browser/app.py +0 -0
  88. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_browser/facet.py +0 -0
  89. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_browser/history.py +0 -0
  90. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_browser/home.py +0 -0
  91. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_browser/location.py +0 -0
  92. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_browser/models.py +0 -0
  93. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_browser/page.py +0 -0
  94. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_class/__init__.py +0 -0
  95. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_class/facets.py +0 -0
  96. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_class/textual-class.yamlld +0 -0
  97. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/__init__.py +0 -0
  98. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/facets.py +0 -0
  99. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/sparql/inverse-properties.sparql +0 -0
  100. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/sparql/label.sparql +0 -0
  101. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/sparql/nodes-for-property.sparql +0 -0
  102. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/sparql/properties.sparql +0 -0
  103. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/tcss/default.tcss +0 -0
  104. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/templates/default.md +0 -0
  105. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/textual-inverse-properties.yamlld +0 -0
  106. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/triple_uri_ref.py +0 -0
  107. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_default/widgets.py +0 -0
  108. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_graph/__init__.py +0 -0
  109. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_graph/facets.py +0 -0
  110. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_graph/sparql/triples.sparql +0 -0
  111. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_graph_triples.py +0 -0
  112. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_graphs/__init__.py +0 -0
  113. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_graphs/data/textual_graphs.yamlld +0 -0
  114. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_graphs/facets.py +0 -0
  115. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_graphs/sparql/graphs.sparql +0 -0
  116. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_link/__init__.py +0 -0
  117. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_link/facet.py +0 -0
  118. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_nanopublication/__init__.py +0 -0
  119. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_nanopublication/facet.py +0 -0
  120. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_nanopublication/models.py +0 -0
  121. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_nanopublication/nanopublication_widget.py +0 -0
  122. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_nanopublication/term_list_widget.py +0 -0
  123. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_nanopublication/term_widget.py +0 -0
  124. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_ontology/__init__.py +0 -0
  125. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_ontology/facets.py +0 -0
  126. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_ontology/sparql/terms.sparql +0 -0
  127. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_ontology/sparql/visualization-vocab.sparql +0 -0
  128. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_property_pairs_table.py +0 -0
  129. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_provenance/__init__.py +0 -0
  130. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_provenance/facets.py +0 -0
  131. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_provenance/sparql/graphs.sparql +0 -0
  132. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/textual_provenance/sparql/triples.sparql +0 -0
  133. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/title/__init__.py +0 -0
  134. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/title/facets.py +0 -0
  135. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/title/sparql/title.sparql +0 -0
  136. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/title/title.yamlld +0 -0
  137. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/wikibase_statement_title/__init__.py +0 -0
  138. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/wikibase_statement_title/facets.py +0 -0
  139. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/facets/wikibase_statement_title/sparql/statement-title.sparql +0 -0
  140. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/labeled_triple_set/__init__.py +0 -0
  141. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/labeled_triple_set/data/labeled_triple_set.yamlld +0 -0
  142. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/labeled_triple_set/labeled_triple_set.py +0 -0
  143. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/labeled_triple_set/sparql/triples.sparql +0 -0
  144. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/mcp/__init__.py +0 -0
  145. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/mcp/cli.py +0 -0
  146. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/mermaid/__init__.py +0 -0
  147. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/mermaid/facet.py +0 -0
  148. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/mermaid/mermaid.yamlld +0 -0
  149. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/mermaid/models.py +0 -0
  150. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/mermaid/sparql/ask-has-triples.sparql +0 -0
  151. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/mermaid/sparql/graph.sparql +0 -0
  152. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/mermaid/sparql/subgraphs.sparql +0 -0
  153. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/models.py +0 -0
  154. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/namespaces.py +0 -0
  155. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/node_to_qname.py +0 -0
  156. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/parse_quads.py +0 -0
  157. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/plugin.py +0 -0
  158. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/query_result.py +0 -0
  159. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/reformat_blank_nodes.py +0 -0
  160. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/resolvers/__init__.py +0 -0
  161. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/resolvers/base.py +0 -0
  162. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/resolvers/dispatch.py +0 -0
  163. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/resolvers/pypi.py +0 -0
  164. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/resolvers/python_import.py +0 -0
  165. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/sparqlspace/__init__.py +0 -0
  166. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/sparqlspace/cli.py +0 -0
  167. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/sparqlspace/inference/wikidata-prop-label.sparql +0 -0
  168. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/sparqlspace/inference/wikidata-statement-label.sparql +0 -0
  169. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/sparqlspace/sparqlspace.py +0 -0
  170. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/widgets/__init__.py +0 -0
  171. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/widgets/description.py +0 -0
  172. {iolanta-2.1.13 → iolanta-2.1.14}/iolanta/widgets/mixin.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iolanta
3
- Version: 2.1.13
3
+ Version: 2.1.14
4
4
  Summary: Semantic Web browser
5
5
  License: MIT
6
6
  Author: Anatoly Scherbakov
@@ -45,22 +45,22 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
45
45
  """
46
46
 
47
47
  BINDINGS = [ # noqa: WPS115
48
- ('alt+left', 'back', 'Back'),
49
- ('alt+right', 'forward', 'Fwd'),
50
- ('f5', 'reload', '🔄 Reload'),
51
- ('escape', 'abort', '🛑 Abort'),
52
- ('f12', 'console', 'Console'),
48
+ ("alt+left", "back", "Back"),
49
+ ("alt+right", "forward", "Fwd"),
50
+ ("f5", "reload", "🔄 Reload"),
51
+ ("escape", "abort", "🛑 Abort"),
52
+ ("f12", "console", "Console"),
53
53
  ]
54
54
 
55
55
  def __init__(self):
56
56
  """Set Home as first tab."""
57
- super().__init__(id='page_switcher', initial='home')
57
+ super().__init__(id="page_switcher", initial="home")
58
58
  self.stop_file_watcher_event = threading.Event()
59
59
 
60
60
  def action_console(self):
61
61
  """Open dev console."""
62
62
  console_switcher = self.app.query_one(ConsoleSwitcher)
63
- console_switcher.current = 'console'
63
+ console_switcher.current = "console"
64
64
  console_switcher.query_one(DevConsole).focus()
65
65
 
66
66
  @functools.cached_property
@@ -70,7 +70,7 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
70
70
 
71
71
  def compose(self):
72
72
  """Home is the first page to open."""
73
- yield Home(id='home')
73
+ yield Home(id="home")
74
74
 
75
75
  def on_mount(self):
76
76
  """Navigate to the initial page."""
@@ -86,13 +86,13 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
86
86
  self.stop_file_watcher_event.set()
87
87
 
88
88
  def _watch_files(self):
89
- for _ in watchfiles.watch( # noqa: WPS352
89
+ for _ in watchfiles.watch( # noqa: WPS352
90
90
  self.iolanta.project_root,
91
91
  stop_event=self.stop_file_watcher_event,
92
92
  ):
93
93
  self.app.call_from_thread(self.action_reload)
94
94
 
95
- def render_iri( # noqa: WPS210
95
+ def render_iri( # noqa: WPS210
96
96
  self,
97
97
  this: NotLiteralNode,
98
98
  facet_iri: URIRef | None,
@@ -102,7 +102,7 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
102
102
  self.this = this
103
103
  iolanta: Iolanta = self.iolanta
104
104
 
105
- as_datatype = URIRef('https://iolanta.tech/cli/textual')
105
+ as_datatype = URIRef("https://iolanta.tech/cli/textual")
106
106
  choices = FacetFinder(
107
107
  iolanta=self.iolanta,
108
108
  node=this,
@@ -117,12 +117,10 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
117
117
  )
118
118
 
119
119
  if facet_iri is None:
120
- facet_iri = choices[0]['facet']
120
+ facet_iri = choices[0]["facet"]
121
121
 
122
122
  other_facets = [
123
- choice['facet']
124
- for choice in choices
125
- if choice['facet'] != facet_iri
123
+ choice["facet"] for choice in choices if choice["facet"] != facet_iri
126
124
  ]
127
125
  flip_options = [
128
126
  FlipOption(
@@ -141,7 +139,7 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
141
139
  facet = facet_class(
142
140
  this=self.this,
143
141
  iolanta=iolanta,
144
- as_datatype=URIRef('https://iolanta.tech/cli/textual'),
142
+ as_datatype=URIRef("https://iolanta.tech/cli/textual"),
145
143
  )
146
144
 
147
145
  try:
@@ -162,7 +160,7 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
162
160
  is_reload=is_reload,
163
161
  )
164
162
 
165
- def on_worker_state_changed( # noqa: WPS210
163
+ def on_worker_state_changed( # noqa: WPS210
166
164
  self,
167
165
  event: Worker.StateChanged,
168
166
  ):
@@ -173,7 +171,7 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
173
171
 
174
172
  if render_result.is_reload:
175
173
  # We are reloading the current page.
176
- current_page = self.query_one(f'#{self.current}', Page)
174
+ current_page = self.query_one(f"#{self.current}", Page)
177
175
  current_page.remove_children()
178
176
  current_page.mount(render_result.renderable)
179
177
 
@@ -184,7 +182,7 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
184
182
  else:
185
183
  # We are navigating to a new page.
186
184
  page_uid = uuid.uuid4().hex
187
- page_id = f'page_{page_uid}'
185
+ page_id = f"page_{page_uid}"
188
186
  page = Page(
189
187
  render_result.renderable,
190
188
  iri=render_result.iri,
@@ -210,7 +208,7 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
210
208
  def is_loading(self) -> bool:
211
209
  """Determine if the app is presently loading something."""
212
210
  for worker in self.workers:
213
- if worker.name == 'render_iri':
211
+ if worker.name == "render_iri":
214
212
  return True
215
213
 
216
214
  return False
@@ -219,31 +217,31 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
219
217
  """Reset Iolanta graph and re-render current view."""
220
218
  if self.history.current is None:
221
219
  return
222
-
220
+
223
221
  self.iolanta.reset()
224
222
 
225
223
  self.run_worker(
226
224
  functools.partial(
227
225
  self.render_iri,
228
226
  this=self.history.current.url,
229
- facet_iri=self.history.current.facet_iri,
227
+ facet_iri=None, # Re-resolve facet after reload so parse errors use TextualNoFacetFound
230
228
  is_reload=True,
231
229
  ),
232
230
  thread=True,
233
231
  exclusive=True,
234
- name='render_iri',
232
+ name="render_iri",
235
233
  )
236
234
  self.refresh_bindings()
237
235
 
238
236
  def action_abort(self):
239
237
  """Abort loading."""
240
238
  self.notify(
241
- 'Aborted.',
242
- severity='warning',
239
+ "Aborted.",
240
+ severity="warning",
243
241
  )
244
242
 
245
243
  for worker in self.workers:
246
- if worker.name == 'render_iri':
244
+ if worker.name == "render_iri":
247
245
  worker.cancel()
248
246
  break
249
247
 
@@ -252,18 +250,18 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
252
250
  def check_action(
253
251
  self,
254
252
  action: str,
255
- parameters: tuple[object, ...], # noqa: WPS110
253
+ parameters: tuple[object, ...], # noqa: WPS110
256
254
  ) -> bool | None:
257
255
  """Check if action is available."""
258
256
  is_loading = self.is_loading
259
257
  match action:
260
- case 'reload':
258
+ case "reload":
261
259
  return not is_loading
262
- case 'abort':
260
+ case "abort":
263
261
  return is_loading
264
- case 'back':
262
+ case "back":
265
263
  return bool(self.history.past)
266
- case 'forward':
264
+ case "forward":
267
265
  return bool(self.history.future)
268
266
 
269
267
  return True
@@ -280,12 +278,12 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
280
278
  # Direct calls (like line 77) pass Node objects directly.
281
279
  if isinstance(this, str):
282
280
  # Check if string represents a blank node (starts with "_:")
283
- if this.startswith('_:'):
281
+ if this.startswith("_:"):
284
282
  # Create a BNode with the full string (including the "_:")
285
283
  this = BNode(this)
286
284
  else:
287
285
  this = URIRef(this)
288
-
286
+
289
287
  self.run_worker(
290
288
  functools.partial(
291
289
  self.render_iri,
@@ -295,7 +293,7 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
295
293
  ),
296
294
  thread=True,
297
295
  exclusive=True,
298
- name='render_iri',
296
+ name="render_iri",
299
297
  )
300
298
  self.refresh_bindings()
301
299
 
@@ -319,8 +317,8 @@ class ConsoleSwitcher(ContentSwitcher):
319
317
  def __init__(self):
320
318
  """Specify initial params."""
321
319
  super().__init__(
322
- id='console_switcher',
323
- initial='page_switcher',
320
+ id="console_switcher",
321
+ initial="page_switcher",
324
322
  )
325
323
 
326
324
  def compose(self):
@@ -333,17 +331,17 @@ class DevConsole(RichLog):
333
331
  """Development console."""
334
332
 
335
333
  BINDINGS = [
336
- ('f12,escape', 'close', 'Close Console'),
334
+ ("f12,escape", "close", "Close Console"),
337
335
  ]
338
336
 
339
337
  def __init__(self):
340
338
  """Set default props for console."""
341
- super().__init__(highlight=False, markup=False, id='console')
339
+ super().__init__(highlight=False, markup=False, id="console")
342
340
 
343
341
  def action_close(self):
344
342
  """Close the dev console."""
345
343
  console_switcher = self.app.query_one(ConsoleSwitcher)
346
- console_switcher.current = 'page_switcher'
344
+ console_switcher.current = "page_switcher"
347
345
 
348
346
  page_switcher = console_switcher.query_one(PageSwitcher)
349
347
  page_switcher.visible_content.focus()
@@ -0,0 +1,6 @@
1
+ SELECT ?instance WHERE {
2
+ ?instance a $this .
3
+
4
+ # Overcome what RDFLib does
5
+ FILTER(!isLiteral(?instance)) .
6
+ } ORDER BY ?instance
@@ -24,6 +24,14 @@ TEXT = """
24
24
  issues: https://github.com/iolanta.tech/iolanta/issues
25
25
  """
26
26
 
27
+ PARSE_ERROR_TEMPLATE = """
28
+ **Parse error**
29
+
30
+ ```
31
+ {message}
32
+ ```
33
+ """
34
+
27
35
  CONTENT_TEMPLATE = """
28
36
  **File content**
29
37
 
@@ -46,7 +54,7 @@ class TextualNoFacetFound(Facet):
46
54
  def raw_content(self):
47
55
  """Content of the file, if applicable."""
48
56
  url = URL(self.this)
49
- if url.scheme != 'file':
57
+ if url.scheme != "file":
50
58
  return None
51
59
 
52
60
  path = Path(url.path)
@@ -59,32 +67,50 @@ class TextualNoFacetFound(Facet):
59
67
  if path.is_dir():
60
68
  return None
61
69
 
70
+ parse_error_msg = self._parse_error_message()
62
71
  file_content = path.read_text()
63
- return CONTENT_TEMPLATE.format(
72
+ content = CONTENT_TEMPLATE.format(
64
73
  content=file_content,
65
74
  type={
66
- '.yamlld': 'yaml',
67
- '.jsonld': 'json',
68
- }.get(path.suffix, ''),
75
+ ".yamlld": "yaml",
76
+ ".jsonld": "json",
77
+ ".ttl": "turtle",
78
+ }.get(path.suffix, ""),
69
79
  )
80
+ if parse_error_msg:
81
+ content = PARSE_ERROR_TEMPLATE.format(message=parse_error_msg) + content
82
+ return content
83
+
84
+ def _parse_error_message(self) -> str | None:
85
+ """Return parse error message for this node if it failed to load."""
86
+ rows = self.query(
87
+ """
88
+ SELECT ?msg WHERE {
89
+ GRAPH <iolanta://_meta> { $this iolanta:parse-error ?msg }
90
+ }
91
+ """,
92
+ this=self.this,
93
+ )
94
+ if row := funcy.first(rows):
95
+ return str(row["msg"])
96
+ return None
70
97
 
71
98
  @property
72
99
  def subgraphs_description(self) -> str:
73
100
  """Return a formatted description of subgraphs, if any exist."""
74
101
  rows = self.query(
75
- 'SELECT ?subgraph WHERE { $this iolanta:has-sub-graph ?subgraph }',
102
+ "SELECT ?subgraph WHERE { $this iolanta:has-sub-graph ?subgraph }",
76
103
  this=self.this,
77
104
  )
78
- subgraphs = funcy.lpluck('subgraph', rows)
105
+ subgraphs = funcy.lpluck("subgraph", rows)
79
106
  if subgraphs:
80
107
  return SUBGRAPHS_TEMPLATE.format(
81
- formatted_subgraphs='\n'.join([
82
- f'- {subgraph}'
83
- for subgraph in subgraphs
84
- ]),
108
+ formatted_subgraphs="\n".join(
109
+ [f"- {subgraph}" for subgraph in subgraphs]
110
+ ),
85
111
  )
86
112
 
87
- return ''
113
+ return ""
88
114
 
89
115
  def show(self):
90
116
  """Compose the page."""
@@ -93,8 +119,8 @@ class TextualNoFacetFound(Facet):
93
119
  Description(
94
120
  Markdown(
95
121
  TEXT.format(
96
- content=self.raw_content or '',
97
- subgraphs=self.subgraphs_description or '',
122
+ content=self.raw_content or "",
123
+ subgraphs=self.subgraphs_description or "",
98
124
  reference_type=type(self.this).__name__,
99
125
  ),
100
126
  ),
@@ -17,6 +17,7 @@ import yaml_ld
17
17
  from pyparsing import ParseException
18
18
  from rdflib import ConjunctiveGraph, Graph, Literal, URIRef
19
19
  from rdflib.namespace import NamespaceManager
20
+ from rdflib.plugins.parsers.notation3 import BadSyntax
20
21
  from rdflib.plugins.sparql.processor import SPARQLResult
21
22
  from rdflib.term import Node
22
23
  from yaml_ld.document_loaders.content_types import ParserNotFound
@@ -256,10 +257,20 @@ class Iolanta: # noqa: WPS214, WPS338
256
257
  except ParserNotFound as parser_not_found:
257
258
  self.logger.error(f"{source} | {parser_not_found}")
258
259
  continue
259
- except YAMLLDError as yaml_ld_error:
260
- # .add() only processes local files, so errors should be raised
261
- self.logger.error(f"{source_file} | {yaml_ld_error}")
262
- raise
260
+ except (YAMLLDError, BadSyntax) as parse_error:
261
+ self.logger.warning("%s | parse error: %s", source_file, parse_error)
262
+ file_iri = path_to_iri(source_file)
263
+ self.graph.addN(
264
+ [
265
+ (
266
+ file_iri,
267
+ namespaces.IOLANTA["parse-error"],
268
+ Literal(str(parse_error)),
269
+ namespaces.META,
270
+ ),
271
+ ]
272
+ )
273
+ continue
263
274
  except ValueError as value_error:
264
275
  self.logger.error(f"{source} | {value_error}")
265
276
  continue
@@ -362,7 +373,6 @@ class Iolanta: # noqa: WPS214, WPS338
362
373
  ) -> Any:
363
374
  """Find an Iolanta facet for a node and render it."""
364
375
  node = normalize_term(node)
365
-
366
376
  if not as_datatype:
367
377
  raise ValueError(
368
378
  f"Please provide the datatype to render {node} as.",
@@ -557,15 +557,6 @@ class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
557
557
  path=not_found.path,
558
558
  )
559
559
 
560
- self.graph.add(
561
- (
562
- source_uri,
563
- RDF.type,
564
- IOLANTA["not-found"],
565
- source_uri,
566
- )
567
- )
568
-
569
560
  self._mark_as_loaded(source_uri)
570
561
 
571
562
  return Loaded()
@@ -0,0 +1,58 @@
1
+ import re
2
+ from types import MappingProxyType
3
+
4
+ from rdflib import URIRef
5
+
6
+ # All entries are (pattern, replacement) strings; pattern may be regex with $ for exact match.
7
+ REDIRECTS = MappingProxyType(
8
+ {
9
+ # FIXME This is presently hardcoded; we need to
10
+ # - either find a way to resolve these URLs automatically,
11
+ # - or create a repository of those redirects online.
12
+ r"http://purl\.org/vocab/vann/$": "https://vocab.org/vann/vann-vocab-20100607.rdf",
13
+ r"https://purl\.org/dc/elements/1\.1/$": "https://purl.org/dc/terms/",
14
+ r"http://www\.w3\.org/1999/02/22-rdf-syntax-ns#$": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
15
+ r"http://www\.w3\.org/2000/01/rdf-schema#$": "http://www.w3.org/2000/01/rdf-schema#",
16
+ r"http://www\.w3\.org/2002/07/owl#$": "http://www.w3.org/2002/07/owl#",
17
+ # Add # fragment to OWL and RDFS when URI has no fragment (pattern $ = no fragment)
18
+ # (fixes bug reported at https://stackoverflow.com/q/78934864/1245471)
19
+ r"http://www\.w3\.org/2002/07/owl$": "http://www.w3.org/2002/07/owl#",
20
+ r"http://www\.w3\.org/2000/01/rdf-schema$": "http://www.w3.org/2000/01/rdf-schema#",
21
+ # Redirect FOAF namespace to GitHub mirror
22
+ r"https?://xmlns\.com/foaf/0\.1/.+": "https://raw.githubusercontent.com/foaf/foaf/refs/heads/master/xmlns.com/htdocs/foaf/0.1/index.rdf",
23
+ r"https://www\.nanopub\.org/nschema$": "https://www.nanopub.net/nschema#",
24
+ r"https://nanopub\.org/nschema$": "https://nanopub.net/nschema#",
25
+ # Convert lexvo.org/id URLs to lexvo.org/data URLs
26
+ r"http://lexvo\.org/id/(.+)": r"http://lexvo.org/data/\1",
27
+ r"https://lexvo\.org/id/(.+)": r"http://lexvo.org/data/\1",
28
+ r"https://www\.lexinfo\.net/(.+)": r"http://www.lexinfo.net/\1",
29
+ # Convert Wikidata https:// to http:// (Wikidata JSON-LD uses http:// URIs)
30
+ r"https://www\.wikidata\.org/entity/(.+)": r"http://www.wikidata.org/entity/\1",
31
+ }
32
+ )
33
+
34
+
35
+ def apply_redirect(source: URIRef) -> URIRef: # noqa: WPS210
36
+ """
37
+ Rewrite the URL using regex patterns and group substitutions.
38
+
39
+ For each pattern in REDIRECTS:
40
+ - If the pattern matches the source URI
41
+ - Replace the source with the destination, substituting any regex groups
42
+ """
43
+ source_str = str(source)
44
+
45
+ for pattern, destination in REDIRECTS.items():
46
+ pattern_str = str(pattern)
47
+ destination_str = str(destination)
48
+
49
+ if re.match(pattern_str, source_str):
50
+ # Replace any group references in the destination (e.g. \1)
51
+ redirected_uri = re.sub(
52
+ pattern_str,
53
+ destination_str,
54
+ source_str,
55
+ )
56
+ return URIRef(redirected_uri)
57
+
58
+ return source
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "iolanta"
3
- version = "2.1.13"
3
+ version = "2.1.14"
4
4
  description = "Semantic Web browser"
5
5
  authors = ["Anatoly Scherbakov <altaisoft@gmail.com>"]
6
6
  license = "MIT"
@@ -1,8 +0,0 @@
1
- # Remember we are HTTPS-izing all URIs in Iolanta graph
2
- PREFIX rdf: <https://www.w3.org/1999/02/22-rdf-syntax-ns#>
3
-
4
- SELECT ?instance WHERE {
5
- ?instance rdf:type $this .
6
-
7
- FILTER(!isLiteral(?instance)) .
8
- } ORDER BY ?instance
@@ -1,79 +0,0 @@
1
- import re
2
- from types import MappingProxyType
3
-
4
- from rdflib import URIRef
5
-
6
- from iolanta.namespaces import (
7
- DC,
8
- DCTERMS,
9
- FOAF,
10
- OWL,
11
- PROV,
12
- RDF,
13
- RDFS,
14
- VANN,
15
- )
16
-
17
- REDIRECTS = MappingProxyType({
18
- # FIXME This is presently hardcoded; we need to
19
- # - either find a way to resolve these URLs automatically,
20
- # - or create a repository of those redirects online.
21
- 'http://purl.org/vocab/vann/': URIRef(
22
- 'https://vocab.org/vann/vann-vocab-20100607.rdf',
23
- ),
24
- URIRef(str(DC)): URIRef(str(DCTERMS)),
25
- URIRef(str(RDF)): URIRef(str(RDF)),
26
- URIRef(str(RDFS)): URIRef(str(RDFS)),
27
- URIRef(str(OWL)): URIRef(str(OWL)),
28
-
29
- # Add # fragment to OWL and RDFS namespace URIs
30
- # (fixes bug reported at https://stackoverflow.com/q/78934864/1245471)
31
- URIRef('http://www.w3.org/2002/07/owl'): URIRef('http://www.w3.org/2002/07/owl#'),
32
- URIRef('http://www.w3.org/2000/01/rdf-schema'): URIRef('http://www.w3.org/2000/01/rdf-schema#'),
33
-
34
- # Redirect FOAF namespace to GitHub mirror
35
- URIRef('https?://xmlns.com/foaf/0.1/.+'): URIRef(
36
- 'https://raw.githubusercontent.com/foaf/foaf/refs/heads/master/xmlns.com/htdocs/foaf/0.1/index.rdf',
37
- ),
38
- URIRef('https://www.nanopub.org/nschema'): URIRef(
39
- 'https://www.nanopub.net/nschema#',
40
- ),
41
- URIRef('https://nanopub.org/nschema'): URIRef(
42
- 'https://nanopub.net/nschema#',
43
- ),
44
-
45
- # Convert lexvo.org/id URLs to lexvo.org/data URLs
46
- r'http://lexvo\.org/id/(.+)': r'http://lexvo.org/data/\1',
47
- r'https://lexvo\.org/id/(.+)': r'http://lexvo.org/data/\1',
48
- r'https://www\.lexinfo\.net/(.+)': r'http://www.lexinfo.net/\1',
49
- # Convert Wikidata https:// to http:// (Wikidata JSON-LD uses http:// URIs)
50
- r'https://www\.wikidata\.org/entity/(.+)': r'http://www.wikidata.org/entity/\1',
51
- })
52
-
53
-
54
- def apply_redirect(source: URIRef) -> URIRef: # noqa: WPS210
55
- """
56
- Rewrite the URL using regex patterns and group substitutions.
57
-
58
- For each pattern in REDIRECTS:
59
- - If the pattern matches the source URI
60
- - Replace the source with the destination, substituting any regex groups
61
- """
62
- source_str = str(source)
63
-
64
- for pattern, destination in REDIRECTS.items():
65
- pattern_str = str(pattern)
66
- destination_str = str(destination)
67
-
68
- match = re.match(pattern_str, source_str)
69
- if match:
70
- # Replace any group references in the destination
71
- # (like \1, \2, etc.)
72
- redirected_uri = re.sub(
73
- pattern_str,
74
- destination_str,
75
- source_str,
76
- )
77
- return URIRef(redirected_uri)
78
-
79
- return source
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes