iolanta 2.1.13__tar.gz → 2.1.15__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.
- {iolanta-2.1.13 → iolanta-2.1.15}/PKG-INFO +2 -1
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_browser/page_switcher.py +37 -39
- iolanta-2.1.15/iolanta/facets/textual_class/sparql/instances.sparql +6 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_no_facet_found.py +40 -14
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/iolanta.py +15 -5
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/sparqlspace/processor.py +0 -9
- iolanta-2.1.15/iolanta/sparqlspace/redirects.py +58 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/pyproject.toml +2 -1
- iolanta-2.1.13/iolanta/facets/textual_class/sparql/instances.sparql +0 -8
- iolanta-2.1.13/iolanta/sparqlspace/redirects.py +0 -79
- {iolanta-2.1.13 → iolanta-2.1.15}/README.md +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/base_plugin.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/cli/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/cli/formatters/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/cli/formatters/choose.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/cli/formatters/csv.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/cli/formatters/json.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/cli/formatters/pretty.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/cli/main.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/cli/models.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/cli/pretty_print.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/context.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/conversions.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/data/context.yaml +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/data/graph-triples.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/data/iolanta.yaml +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/data/textual-browser.yaml +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/declension/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/declension/data/declension.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/declension/facet.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/declension/sparql/declension.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/ensure_is_context.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/entry_points.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/errors.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/cli/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/cli/base.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/cli/default.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/cli/record.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/cli/sparql/link.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/cli/sparql/record.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/errors.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/facet.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/foaf_person_title/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/foaf_person_title/facet.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/foaf_person_title/sparql/names.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/generic/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/generic/bool_literal.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/generic/date_literal.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/generic/default.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/generic/sparql/default.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/html/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/html/base.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/html/code_literal.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/html/default.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/icon.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/locator/sparql/get-query-to-facet.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/locator.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mermaid_roadmap/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mermaid_roadmap/facet.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mermaid_roadmap/inference/blocks.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mermaid_roadmap/inference/has-task-default-type.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mermaid_roadmap/inference/task.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mermaid_roadmap/inference/unblocked.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mermaid_roadmap/mermaid_roadmap.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mermaid_roadmap/sparql/edges.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mermaid_roadmap/sparql/nodes.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mkdocs_material_insiders_markdown/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mkdocs_material_insiders_markdown/data/mkdocs_material_insiders_markdown.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mkdocs_material_insiders_markdown/facet.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/mkdocs_material_insiders_markdown/templates/datatype.jinja2.md +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/page_title.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/qname.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/ask_result_csv.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/ask_result_json.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/ask_result_table.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/construct_result_csv.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/construct_result_json.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/construct_result_table.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/data/query_result.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/select_result_csv.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/select_result_json.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/query/select_result_table.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_browser/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_browser/app.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_browser/facet.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_browser/history.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_browser/home.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_browser/location.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_browser/models.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_browser/page.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_class/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_class/facets.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_class/textual-class.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/facets.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/sparql/inverse-properties.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/sparql/label.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/sparql/nodes-for-property.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/sparql/properties.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/tcss/default.tcss +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/templates/default.md +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/textual-inverse-properties.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/triple_uri_ref.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_default/widgets.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_graph/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_graph/facets.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_graph/sparql/triples.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_graph_triples.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_graphs/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_graphs/data/textual_graphs.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_graphs/facets.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_graphs/sparql/graphs.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_link/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_link/facet.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_nanopublication/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_nanopublication/facet.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_nanopublication/models.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_nanopublication/nanopublication_widget.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_nanopublication/term_list_widget.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_nanopublication/term_widget.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_ontology/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_ontology/facets.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_ontology/sparql/terms.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_ontology/sparql/visualization-vocab.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_property_pairs_table.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_provenance/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_provenance/facets.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_provenance/sparql/graphs.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/textual_provenance/sparql/triples.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/title/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/title/facets.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/title/sparql/title.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/title/title.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/wikibase_statement_title/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/wikibase_statement_title/facets.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/facets/wikibase_statement_title/sparql/statement-title.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/labeled_triple_set/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/labeled_triple_set/data/labeled_triple_set.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/labeled_triple_set/labeled_triple_set.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/labeled_triple_set/sparql/triples.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/mcp/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/mcp/cli.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/mermaid/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/mermaid/facet.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/mermaid/mermaid.yamlld +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/mermaid/models.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/mermaid/sparql/ask-has-triples.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/mermaid/sparql/graph.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/mermaid/sparql/subgraphs.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/models.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/namespaces.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/node_to_qname.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/parse_quads.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/plugin.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/query_result.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/reformat_blank_nodes.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/resolvers/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/resolvers/base.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/resolvers/dispatch.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/resolvers/pypi.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/resolvers/python_import.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/sparqlspace/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/sparqlspace/cli.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/sparqlspace/inference/wikidata-prop-label.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/sparqlspace/inference/wikidata-statement-label.sparql +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/sparqlspace/sparqlspace.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/widgets/__init__.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/widgets/description.py +0 -0
- {iolanta-2.1.13 → iolanta-2.1.15}/iolanta/widgets/mixin.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iolanta
|
|
3
|
-
Version: 2.1.
|
|
3
|
+
Version: 2.1.15
|
|
4
4
|
Summary: Semantic Web browser
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Anatoly Scherbakov
|
|
@@ -20,6 +20,7 @@ Requires-Dist: documented (>=0.1.1)
|
|
|
20
20
|
Requires-Dist: dominate (>=2.6.0)
|
|
21
21
|
Requires-Dist: fastmcp (>=2.12.4,<3.0.0)
|
|
22
22
|
Requires-Dist: funcy (>=2.0)
|
|
23
|
+
Requires-Dist: jinja2 (>=3.1.0)
|
|
23
24
|
Requires-Dist: loguru (>=0.7.3)
|
|
24
25
|
Requires-Dist: more-itertools (>=9.0.0)
|
|
25
26
|
Requires-Dist: nanopub (>=2.1.0,<3.0.0)
|
|
@@ -45,22 +45,22 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
|
|
|
45
45
|
"""
|
|
46
46
|
|
|
47
47
|
BINDINGS = [ # noqa: WPS115
|
|
48
|
-
(
|
|
49
|
-
(
|
|
50
|
-
(
|
|
51
|
-
(
|
|
52
|
-
(
|
|
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=
|
|
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 =
|
|
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=
|
|
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(
|
|
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(
|
|
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(
|
|
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][
|
|
120
|
+
facet_iri = choices[0]["facet"]
|
|
121
121
|
|
|
122
122
|
other_facets = [
|
|
123
|
-
choice[
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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 ==
|
|
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=
|
|
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=
|
|
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
|
-
|
|
242
|
-
severity=
|
|
239
|
+
"Aborted.",
|
|
240
|
+
severity="warning",
|
|
243
241
|
)
|
|
244
242
|
|
|
245
243
|
for worker in self.workers:
|
|
246
|
-
if worker.name ==
|
|
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, ...],
|
|
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
|
|
258
|
+
case "reload":
|
|
261
259
|
return not is_loading
|
|
262
|
-
case
|
|
260
|
+
case "abort":
|
|
263
261
|
return is_loading
|
|
264
|
-
case
|
|
262
|
+
case "back":
|
|
265
263
|
return bool(self.history.past)
|
|
266
|
-
case
|
|
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=
|
|
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=
|
|
323
|
-
initial=
|
|
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
|
-
(
|
|
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=
|
|
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 =
|
|
344
|
+
console_switcher.current = "page_switcher"
|
|
347
345
|
|
|
348
346
|
page_switcher = console_switcher.query_one(PageSwitcher)
|
|
349
347
|
page_switcher.visible_content.focus()
|
|
@@ -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 !=
|
|
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
|
-
|
|
72
|
+
content = CONTENT_TEMPLATE.format(
|
|
64
73
|
content=file_content,
|
|
65
74
|
type={
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
102
|
+
"SELECT ?subgraph WHERE { $this iolanta:has-sub-graph ?subgraph }",
|
|
76
103
|
this=self.this,
|
|
77
104
|
)
|
|
78
|
-
subgraphs = funcy.lpluck(
|
|
105
|
+
subgraphs = funcy.lpluck("subgraph", rows)
|
|
79
106
|
if subgraphs:
|
|
80
107
|
return SUBGRAPHS_TEMPLATE.format(
|
|
81
|
-
formatted_subgraphs=
|
|
82
|
-
f
|
|
83
|
-
|
|
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
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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.
|
|
3
|
+
version = "2.1.15"
|
|
4
4
|
description = "Semantic Web browser"
|
|
5
5
|
authors = ["Anatoly Scherbakov <altaisoft@gmail.com>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -8,6 +8,7 @@ readme = "README.md"
|
|
|
8
8
|
|
|
9
9
|
[tool.poetry.dependencies]
|
|
10
10
|
python = ">=3.12,<4.0"
|
|
11
|
+
jinja2 = ">=3.1.0"
|
|
11
12
|
rdflib = "<8.0"
|
|
12
13
|
python-frontmatter = ">=0.5.0"
|
|
13
14
|
requests = ">=2.25.1"
|
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|