iolanta 1.2.6__py3-none-any.whl → 1.2.8__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.
- iolanta/cli/main.py +37 -8
- iolanta/cyberspace/processor.py +16 -31
- iolanta/facets/page_title.py +1 -2
- iolanta/facets/textual_browser/app.py +25 -1
- iolanta/facets/textual_browser/location.py +3 -0
- iolanta/facets/textual_browser/page_switcher.py +153 -30
- iolanta/facets/textual_default/facets.py +2 -0
- iolanta/facets/textual_default/widgets.py +3 -5
- iolanta/facets/textual_provenance/facets.py +4 -3
- iolanta/iolanta.py +27 -55
- iolanta/parse_quads.py +15 -0
- {iolanta-1.2.6.dist-info → iolanta-1.2.8.dist-info}/METADATA +2 -1
- {iolanta-1.2.6.dist-info → iolanta-1.2.8.dist-info}/RECORD +15 -17
- iolanta/data/foaf-meta.yaml +0 -113
- iolanta/data/ontologies-meta.yaml +0 -57
- {iolanta-1.2.6.dist-info → iolanta-1.2.8.dist-info}/WHEEL +0 -0
- {iolanta-1.2.6.dist-info → iolanta-1.2.8.dist-info}/entry_points.txt +0 -0
iolanta/cli/main.py
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import locale
|
|
2
2
|
import logging
|
|
3
|
+
from pathlib import Path
|
|
3
4
|
from typing import Annotated
|
|
4
5
|
|
|
5
6
|
import loguru
|
|
6
7
|
import platformdirs
|
|
7
8
|
from documented import DocumentedError
|
|
8
|
-
from rdflib import Literal
|
|
9
|
+
from rdflib import Literal, URIRef
|
|
9
10
|
from rich.console import Console
|
|
10
11
|
from rich.markdown import Markdown
|
|
11
12
|
from typer import Argument, Exit, Option, Typer
|
|
13
|
+
from yarl import URL
|
|
12
14
|
|
|
13
15
|
from iolanta.cli.models import LogLevel
|
|
14
16
|
from iolanta.iolanta import Iolanta
|
|
17
|
+
from iolanta.models import NotLiteralNode
|
|
15
18
|
|
|
16
19
|
DEFAULT_LANGUAGE = locale.getlocale()[0].split('_')[0]
|
|
17
20
|
|
|
@@ -38,8 +41,24 @@ def construct_app() -> Typer:
|
|
|
38
41
|
app = construct_app()
|
|
39
42
|
|
|
40
43
|
|
|
44
|
+
def string_to_node(name: str) -> NotLiteralNode:
|
|
45
|
+
"""
|
|
46
|
+
Parse a string into a node identifier.
|
|
47
|
+
|
|
48
|
+
String might be:
|
|
49
|
+
* a URL,
|
|
50
|
+
* or a local disk path.
|
|
51
|
+
"""
|
|
52
|
+
url = URL(name)
|
|
53
|
+
if url.scheme:
|
|
54
|
+
return URIRef(name)
|
|
55
|
+
|
|
56
|
+
path = Path(name).absolute()
|
|
57
|
+
return URIRef(f'file://{path}')
|
|
58
|
+
|
|
59
|
+
|
|
41
60
|
@app.command(name='browse')
|
|
42
|
-
def render_command( # noqa: WPS231, WPS238
|
|
61
|
+
def render_command( # noqa: WPS231, WPS238, WPS210, C901
|
|
43
62
|
url: Annotated[str, Argument()],
|
|
44
63
|
as_datatype: Annotated[
|
|
45
64
|
str, Option(
|
|
@@ -74,17 +93,27 @@ def render_command( # noqa: WPS231, WPS238
|
|
|
74
93
|
enqueue=True,
|
|
75
94
|
)
|
|
76
95
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
)
|
|
96
|
+
node_url = URL(url)
|
|
97
|
+
if node_url.scheme:
|
|
98
|
+
node = URIRef(url)
|
|
81
99
|
|
|
82
|
-
|
|
100
|
+
iolanta: Iolanta = Iolanta(
|
|
101
|
+
language=Literal(language),
|
|
102
|
+
logger=logger,
|
|
103
|
+
)
|
|
104
|
+
else:
|
|
105
|
+
path = Path(url).absolute()
|
|
106
|
+
node = URIRef(f'file://{path}')
|
|
107
|
+
iolanta: Iolanta = Iolanta(
|
|
108
|
+
language=Literal(language),
|
|
109
|
+
logger=logger,
|
|
110
|
+
project_root=path,
|
|
111
|
+
)
|
|
83
112
|
|
|
84
113
|
try:
|
|
85
114
|
renderable, stack = iolanta.render(
|
|
86
115
|
node=node,
|
|
87
|
-
as_datatype=
|
|
116
|
+
as_datatype=URIRef(as_datatype),
|
|
88
117
|
)
|
|
89
118
|
|
|
90
119
|
except DocumentedError as documented_error:
|
iolanta/cyberspace/processor.py
CHANGED
|
@@ -131,6 +131,10 @@ def _extract_from_mapping( # noqa: WPS213
|
|
|
131
131
|
yield from extract_mentioned_urls(algebra['p2'])
|
|
132
132
|
yield from extract_mentioned_urls(algebra['expr'])
|
|
133
133
|
|
|
134
|
+
case 'Join':
|
|
135
|
+
yield from extract_mentioned_urls(algebra['p1'])
|
|
136
|
+
yield from extract_mentioned_urls(algebra['p2'])
|
|
137
|
+
|
|
134
138
|
case 'ConditionalOrExpression' | 'ConditionalAndExpression':
|
|
135
139
|
yield from extract_mentioned_urls(algebra['expr'])
|
|
136
140
|
yield from extract_mentioned_urls(algebra['other'])
|
|
@@ -149,10 +153,8 @@ def _extract_from_mapping( # noqa: WPS213
|
|
|
149
153
|
case unknown_name:
|
|
150
154
|
formatted_keys = ', '.join(algebra.keys())
|
|
151
155
|
loguru.logger.error(
|
|
152
|
-
'Unknown SPARQL expression
|
|
153
|
-
unknown_name,
|
|
154
|
-
formatted_keys,
|
|
155
|
-
algebra,
|
|
156
|
+
'Unknown SPARQL expression '
|
|
157
|
+
f'{unknown_name}({formatted_keys}): {algebra}',
|
|
156
158
|
)
|
|
157
159
|
return
|
|
158
160
|
|
|
@@ -422,7 +424,7 @@ class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
|
|
|
422
424
|
and isinstance(self.load(maybe_iri), Loaded)
|
|
423
425
|
):
|
|
424
426
|
is_anything_loaded = True # noqa: WPS220
|
|
425
|
-
self.logger.
|
|
427
|
+
self.logger.info( # noqa: WPS220
|
|
426
428
|
'Newly loaded: {uri}',
|
|
427
429
|
uri=maybe_iri,
|
|
428
430
|
)
|
|
@@ -463,6 +465,8 @@ class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
|
|
|
463
465
|
)
|
|
464
466
|
if existing_triple is not None:
|
|
465
467
|
return Skipped()
|
|
468
|
+
else:
|
|
469
|
+
self.logger.info(f'Existing triples not found for {source_uri}')
|
|
466
470
|
|
|
467
471
|
# FIXME This is definitely inefficient. However, python-yaml-ld caches
|
|
468
472
|
# the document, so the performance overhead is not super high.
|
|
@@ -563,10 +567,10 @@ class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
|
|
|
563
567
|
)
|
|
564
568
|
return Loaded()
|
|
565
569
|
except ParserNotFound as parser_not_found:
|
|
566
|
-
self.logger.info('
|
|
570
|
+
self.logger.info(f'{source} | {parser_not_found}')
|
|
567
571
|
return Loaded()
|
|
568
572
|
except YAMLLDError as yaml_ld_error:
|
|
569
|
-
self.logger.error('
|
|
573
|
+
self.logger.error(f'{source} | {yaml_ld_error}')
|
|
570
574
|
return Loaded()
|
|
571
575
|
|
|
572
576
|
try:
|
|
@@ -604,32 +608,13 @@ class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
|
|
|
604
608
|
self.graph.addN(quad_tuples)
|
|
605
609
|
self.graph.last_not_inferred_source = source
|
|
606
610
|
|
|
607
|
-
|
|
608
|
-
|
|
611
|
+
into_graphs = ', '.join({
|
|
612
|
+
quad.graph
|
|
609
613
|
for quad in quads
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
itertools.chain.from_iterable(
|
|
614
|
-
[
|
|
615
|
-
(
|
|
616
|
-
source_uri,
|
|
617
|
-
IOLANTA['has-sub-graph'],
|
|
618
|
-
created_graph,
|
|
619
|
-
source_uri,
|
|
620
|
-
),
|
|
621
|
-
(
|
|
622
|
-
created_graph,
|
|
623
|
-
RDF.type,
|
|
624
|
-
IOLANTA.Graph,
|
|
625
|
-
source_uri,
|
|
626
|
-
),
|
|
627
|
-
]
|
|
628
|
-
for created_graph in created_graphs
|
|
629
|
-
),
|
|
614
|
+
})
|
|
615
|
+
self.logger.info(
|
|
616
|
+
f'{source} | loaded successfully into graphs: {into_graphs}',
|
|
630
617
|
)
|
|
631
|
-
|
|
632
|
-
self.logger.info(f'{source} | loaded successfully.')
|
|
633
618
|
return Loaded()
|
|
634
619
|
|
|
635
620
|
def resolve_term(self, term: Node, bindings: dict[str, Node]):
|
iolanta/facets/page_title.py
CHANGED
|
@@ -22,8 +22,7 @@ class PageTitle(IolantaWidgetMixin, Static):
|
|
|
22
22
|
"""Initialize."""
|
|
23
23
|
self.iri = iri
|
|
24
24
|
self.extra = extra
|
|
25
|
-
|
|
26
|
-
super().__init__(qname)
|
|
25
|
+
super().__init__(iri)
|
|
27
26
|
|
|
28
27
|
def construct_title(self):
|
|
29
28
|
"""Render the title via Iolanta in a thread."""
|
|
@@ -4,6 +4,7 @@ from concurrent.futures import ThreadPoolExecutor
|
|
|
4
4
|
from rdflib.term import Node
|
|
5
5
|
from rich.console import RenderableType
|
|
6
6
|
from textual.app import App, ComposeResult
|
|
7
|
+
from textual.css.query import NoMatches
|
|
7
8
|
from textual.widgets import Footer, Header
|
|
8
9
|
|
|
9
10
|
from iolanta.facets.textual_browser.page_switcher import (
|
|
@@ -13,6 +14,8 @@ from iolanta.facets.textual_browser.page_switcher import (
|
|
|
13
14
|
)
|
|
14
15
|
from iolanta.iolanta import Iolanta
|
|
15
16
|
|
|
17
|
+
POPUP_TIMEOUT = 30 # seconds
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
class DevConsoleHandler(logging.Handler):
|
|
18
21
|
"""Pipe log output → dev console."""
|
|
@@ -28,6 +31,17 @@ class DevConsoleHandler(logging.Handler):
|
|
|
28
31
|
self.console.write(message)
|
|
29
32
|
|
|
30
33
|
|
|
34
|
+
def _log_message_to_dev_console(app: App):
|
|
35
|
+
"""Log a message to the dev console."""
|
|
36
|
+
def log_message_to_dev_console(message: str): # noqa: WPS430
|
|
37
|
+
try:
|
|
38
|
+
app.query_one(DevConsole).write(message)
|
|
39
|
+
except NoMatches:
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
return log_message_to_dev_console
|
|
43
|
+
|
|
44
|
+
|
|
31
45
|
class IolantaBrowser(App): # noqa: WPS214, WPS230
|
|
32
46
|
"""Browse Linked Data."""
|
|
33
47
|
|
|
@@ -69,11 +83,21 @@ class IolantaBrowser(App): # noqa: WPS214, WPS230
|
|
|
69
83
|
|
|
70
84
|
# Log to the dev console.
|
|
71
85
|
self.iolanta.logger.add(
|
|
72
|
-
|
|
86
|
+
_log_message_to_dev_console(self),
|
|
73
87
|
level='INFO',
|
|
74
88
|
format='{time} {level} {message}',
|
|
75
89
|
)
|
|
76
90
|
|
|
91
|
+
self.iolanta.logger.add(
|
|
92
|
+
lambda msg: self.notify(
|
|
93
|
+
msg,
|
|
94
|
+
severity='warning',
|
|
95
|
+
timeout=POPUP_TIMEOUT,
|
|
96
|
+
),
|
|
97
|
+
level='WARNING',
|
|
98
|
+
format='{message}',
|
|
99
|
+
)
|
|
100
|
+
|
|
77
101
|
def action_toggle_dark(self) -> None:
|
|
78
102
|
"""Toggle dark mode."""
|
|
79
103
|
self.dark = not self.dark
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import functools
|
|
2
|
+
import threading
|
|
2
3
|
import uuid
|
|
4
|
+
from dataclasses import dataclass
|
|
5
|
+
from typing import Any
|
|
3
6
|
|
|
7
|
+
import watchfiles
|
|
4
8
|
from rdflib import BNode, URIRef
|
|
5
9
|
from textual.widgets import ContentSwitcher, RichLog
|
|
6
10
|
from textual.worker import Worker, WorkerState
|
|
@@ -18,6 +22,21 @@ from iolanta.namespaces import DATATYPES
|
|
|
18
22
|
from iolanta.widgets.mixin import IolantaWidgetMixin
|
|
19
23
|
|
|
20
24
|
|
|
25
|
+
@dataclass
|
|
26
|
+
class RenderResult:
|
|
27
|
+
"""
|
|
28
|
+
We asked a thread to render something for us.
|
|
29
|
+
|
|
30
|
+
This is what did we get back.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
iri: NotLiteralNode
|
|
34
|
+
renderable: Any
|
|
35
|
+
flip_options: list[FlipOption]
|
|
36
|
+
facet_iri: URIRef
|
|
37
|
+
is_reload: bool
|
|
38
|
+
|
|
39
|
+
|
|
21
40
|
class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
|
|
22
41
|
"""
|
|
23
42
|
Container for open pages.
|
|
@@ -28,12 +47,15 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
|
|
|
28
47
|
BINDINGS = [ # noqa: WPS115
|
|
29
48
|
('alt+left', 'back', 'Back'),
|
|
30
49
|
('alt+right', 'forward', 'Fwd'),
|
|
50
|
+
('f5', 'reload', '🔄 Reload'),
|
|
51
|
+
('escape', 'abort', '🛑 Abort'),
|
|
31
52
|
('f12', 'console', 'Console'),
|
|
32
53
|
]
|
|
33
54
|
|
|
34
55
|
def __init__(self):
|
|
35
56
|
"""Set Home as first tab."""
|
|
36
57
|
super().__init__(id='page_switcher', initial='home')
|
|
58
|
+
self.stop_file_watcher_event = threading.Event()
|
|
37
59
|
|
|
38
60
|
def action_console(self):
|
|
39
61
|
"""Open dev console."""
|
|
@@ -53,22 +75,39 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
|
|
|
53
75
|
def on_mount(self):
|
|
54
76
|
"""Navigate to the initial page."""
|
|
55
77
|
self.action_goto(self.app.iri)
|
|
78
|
+
if self.iolanta.project_root:
|
|
79
|
+
self.run_worker(
|
|
80
|
+
self._watch_files,
|
|
81
|
+
thread=True,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def on_unmount(self) -> None:
|
|
85
|
+
"""Stop watching files."""
|
|
86
|
+
self.stop_file_watcher_event.set()
|
|
87
|
+
|
|
88
|
+
def _watch_files(self):
|
|
89
|
+
for _ in watchfiles.watch( # noqa: WPS352
|
|
90
|
+
self.iolanta.project_root,
|
|
91
|
+
stop_event=self.stop_file_watcher_event,
|
|
92
|
+
):
|
|
93
|
+
self.app.call_from_thread(self.action_reload)
|
|
56
94
|
|
|
57
95
|
def render_iri( # noqa: WPS210
|
|
58
|
-
self,
|
|
59
|
-
|
|
96
|
+
self,
|
|
97
|
+
destination: NotLiteralNode,
|
|
98
|
+
facet_iri: URIRef | None,
|
|
99
|
+
is_reload: bool,
|
|
100
|
+
) -> RenderResult:
|
|
60
101
|
"""Render an IRI in a thread."""
|
|
61
102
|
self.iri = destination
|
|
62
103
|
iolanta: Iolanta = self.iolanta
|
|
63
104
|
|
|
64
105
|
as_datatype = URIRef('https://iolanta.tech/cli/textual')
|
|
65
|
-
choices =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
).choices,
|
|
71
|
-
)
|
|
106
|
+
choices = FacetFinder(
|
|
107
|
+
iolanta=self.iolanta,
|
|
108
|
+
node=destination,
|
|
109
|
+
as_datatype=as_datatype,
|
|
110
|
+
).choices()
|
|
72
111
|
|
|
73
112
|
if not choices:
|
|
74
113
|
raise FacetNotFound(
|
|
@@ -106,11 +145,7 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
|
|
|
106
145
|
)
|
|
107
146
|
|
|
108
147
|
try:
|
|
109
|
-
|
|
110
|
-
destination,
|
|
111
|
-
self.app.call_from_thread(facet.show),
|
|
112
|
-
flip_options,
|
|
113
|
-
)
|
|
148
|
+
renderable = facet.show()
|
|
114
149
|
|
|
115
150
|
except Exception as err:
|
|
116
151
|
raise FacetError(
|
|
@@ -119,6 +154,14 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
|
|
|
119
154
|
error=err,
|
|
120
155
|
) from err
|
|
121
156
|
|
|
157
|
+
return RenderResult(
|
|
158
|
+
iri=destination,
|
|
159
|
+
renderable=renderable,
|
|
160
|
+
flip_options=flip_options,
|
|
161
|
+
facet_iri=facet_iri,
|
|
162
|
+
is_reload=is_reload,
|
|
163
|
+
)
|
|
164
|
+
|
|
122
165
|
def on_worker_state_changed( # noqa: WPS210
|
|
123
166
|
self,
|
|
124
167
|
event: Worker.StateChanged,
|
|
@@ -126,24 +169,98 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
|
|
|
126
169
|
"""Render a page as soon as it is ready."""
|
|
127
170
|
match event.state:
|
|
128
171
|
case WorkerState.SUCCESS:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
172
|
+
render_result: RenderResult = event.worker.result
|
|
173
|
+
|
|
174
|
+
if render_result.is_reload:
|
|
175
|
+
# We are reloading the current page.
|
|
176
|
+
current_page = self.query_one(f'#{self.current}', Page)
|
|
177
|
+
current_page.remove_children()
|
|
178
|
+
current_page.mount(render_result.renderable)
|
|
179
|
+
|
|
180
|
+
# FIXME: This does not actually change the flip options,
|
|
181
|
+
# but maybe that's okay
|
|
182
|
+
current_page.flip_options = render_result.flip_options
|
|
183
|
+
|
|
184
|
+
else:
|
|
185
|
+
# We are navigating to a new page.
|
|
186
|
+
page_uid = uuid.uuid4().hex
|
|
187
|
+
page_id = f'page_{page_uid}'
|
|
188
|
+
page = Page(
|
|
189
|
+
render_result.renderable,
|
|
190
|
+
iri=render_result.iri,
|
|
191
|
+
page_id=page_id,
|
|
192
|
+
flip_options=render_result.flip_options,
|
|
193
|
+
)
|
|
194
|
+
self.mount(page)
|
|
195
|
+
self.current = page_id
|
|
196
|
+
page.focus()
|
|
197
|
+
self.history.goto(
|
|
198
|
+
Location(
|
|
199
|
+
page_id,
|
|
200
|
+
url=render_result.iri,
|
|
201
|
+
facet_iri=render_result.facet_iri,
|
|
202
|
+
),
|
|
203
|
+
)
|
|
204
|
+
self.app.sub_title = render_result.iri
|
|
143
205
|
|
|
144
206
|
case WorkerState.ERROR:
|
|
145
207
|
raise ValueError(event)
|
|
146
208
|
|
|
209
|
+
@property
|
|
210
|
+
def is_loading(self) -> bool:
|
|
211
|
+
"""Determine if the app is presently loading something."""
|
|
212
|
+
for worker in self.workers:
|
|
213
|
+
if worker.name == 'render_iri':
|
|
214
|
+
return True
|
|
215
|
+
|
|
216
|
+
return False
|
|
217
|
+
|
|
218
|
+
def action_reload(self):
|
|
219
|
+
"""Reset Iolanta graph and re-render current view."""
|
|
220
|
+
self.iolanta.reset()
|
|
221
|
+
|
|
222
|
+
self.run_worker(
|
|
223
|
+
functools.partial(
|
|
224
|
+
self.render_iri,
|
|
225
|
+
destination=self.history.current.url,
|
|
226
|
+
facet_iri=self.history.current.facet_iri,
|
|
227
|
+
is_reload=True,
|
|
228
|
+
),
|
|
229
|
+
thread=True,
|
|
230
|
+
exclusive=True,
|
|
231
|
+
name='render_iri',
|
|
232
|
+
)
|
|
233
|
+
self.refresh_bindings()
|
|
234
|
+
|
|
235
|
+
def action_abort(self):
|
|
236
|
+
"""Abort loading."""
|
|
237
|
+
self.notify(
|
|
238
|
+
'Aborted.',
|
|
239
|
+
severity='warning',
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
for worker in self.workers:
|
|
243
|
+
if worker.name == 'render_iri':
|
|
244
|
+
worker.cancel()
|
|
245
|
+
break
|
|
246
|
+
|
|
247
|
+
self.refresh_bindings()
|
|
248
|
+
|
|
249
|
+
def check_action(
|
|
250
|
+
self,
|
|
251
|
+
action: str,
|
|
252
|
+
parameters: tuple[object, ...], # noqa: WPS110
|
|
253
|
+
) -> bool | None:
|
|
254
|
+
"""Check if action is available."""
|
|
255
|
+
is_loading = self.is_loading
|
|
256
|
+
match action:
|
|
257
|
+
case 'reload':
|
|
258
|
+
return not is_loading
|
|
259
|
+
case 'abort':
|
|
260
|
+
return is_loading
|
|
261
|
+
|
|
262
|
+
return True
|
|
263
|
+
|
|
147
264
|
def action_goto(
|
|
148
265
|
self,
|
|
149
266
|
destination: str,
|
|
@@ -158,19 +275,25 @@ class PageSwitcher(IolantaWidgetMixin, ContentSwitcher): # noqa: WPS214
|
|
|
158
275
|
self.run_worker(
|
|
159
276
|
functools.partial(
|
|
160
277
|
self.render_iri,
|
|
161
|
-
iri,
|
|
162
|
-
facet_iri and URIRef(facet_iri),
|
|
278
|
+
destination=iri,
|
|
279
|
+
facet_iri=facet_iri and URIRef(facet_iri),
|
|
280
|
+
is_reload=False,
|
|
163
281
|
),
|
|
164
282
|
thread=True,
|
|
283
|
+
exclusive=True,
|
|
284
|
+
name='render_iri',
|
|
165
285
|
)
|
|
286
|
+
self.refresh_bindings()
|
|
166
287
|
|
|
167
288
|
def action_back(self):
|
|
168
289
|
"""Go backward."""
|
|
169
290
|
self.current = self.history.back().page_id
|
|
291
|
+
self.focus()
|
|
170
292
|
|
|
171
293
|
def action_forward(self):
|
|
172
294
|
"""Go forward."""
|
|
173
295
|
self.current = self.history.forward().page_id
|
|
296
|
+
self.focus()
|
|
174
297
|
|
|
175
298
|
|
|
176
299
|
class ConsoleSwitcher(ContentSwitcher):
|
|
@@ -58,6 +58,7 @@ class TextualDefaultFacet(Facet[Widget]): # noqa: WPS214
|
|
|
58
58
|
for property_iri, property_values in self.grouped_properties.items():
|
|
59
59
|
property_name = PropertyName(
|
|
60
60
|
iri=property_iri,
|
|
61
|
+
qname=self.iolanta.node_as_qname(property_iri),
|
|
61
62
|
)
|
|
62
63
|
|
|
63
64
|
property_values = [
|
|
@@ -69,6 +70,7 @@ class TextualDefaultFacet(Facet[Widget]): # noqa: WPS214
|
|
|
69
70
|
property_value=property_value,
|
|
70
71
|
subject=self.iri,
|
|
71
72
|
property_iri=property_iri,
|
|
73
|
+
property_qname=self.iolanta.node_as_qname(property_iri),
|
|
72
74
|
)
|
|
73
75
|
for property_value in property_values
|
|
74
76
|
]
|
|
@@ -48,11 +48,11 @@ class PropertyName(Widget, can_focus=True, inherit_bindings=False):
|
|
|
48
48
|
def __init__(
|
|
49
49
|
self,
|
|
50
50
|
iri: NotLiteralNode,
|
|
51
|
+
qname: str,
|
|
51
52
|
):
|
|
52
53
|
"""Set the IRI."""
|
|
53
54
|
self.iri = iri
|
|
54
55
|
super().__init__()
|
|
55
|
-
qname = self.app.iolanta.node_as_qname(iri)
|
|
56
56
|
self.renderable = Text( # noqa: WPS601
|
|
57
57
|
f'⏳ {qname}',
|
|
58
58
|
style='#696969',
|
|
@@ -130,17 +130,15 @@ class PropertyValue(Widget, can_focus=True, inherit_bindings=False):
|
|
|
130
130
|
property_value: Node,
|
|
131
131
|
subject: NotLiteralNode,
|
|
132
132
|
property_iri: NotLiteralNode,
|
|
133
|
+
property_qname: str,
|
|
133
134
|
):
|
|
134
135
|
"""Initialize parameters for rendering, navigation, & provenance."""
|
|
135
136
|
self.property_value = property_value
|
|
136
137
|
self.subject = subject
|
|
137
138
|
self.property_iri = property_iri
|
|
138
139
|
super().__init__()
|
|
139
|
-
qname = self.app.iolanta.node_as_qname( # noqa: WPS601
|
|
140
|
-
property_value,
|
|
141
|
-
)
|
|
142
140
|
self.renderable = Text( # noqa: WPS601
|
|
143
|
-
f'⏳ {
|
|
141
|
+
f'⏳ {property_qname}',
|
|
144
142
|
style='#696969',
|
|
145
143
|
)
|
|
146
144
|
|
|
@@ -80,18 +80,19 @@ class ProvenanceView(Vertical):
|
|
|
80
80
|
"""Build page structure."""
|
|
81
81
|
yield Title('Provenan©e for a triple')
|
|
82
82
|
|
|
83
|
+
# TODO: Calculate QNames somehow.
|
|
83
84
|
yield PropertyRow(
|
|
84
|
-
PropertyName(RDF.subject),
|
|
85
|
+
PropertyName(RDF.subject, qname=str(RDF.subject)),
|
|
85
86
|
RDFTermView(self.triple.subject),
|
|
86
87
|
)
|
|
87
88
|
|
|
88
89
|
yield PropertyRow(
|
|
89
|
-
PropertyName(RDF.predicate),
|
|
90
|
+
PropertyName(RDF.predicate, qname=str(RDF.predicate)),
|
|
90
91
|
RDFTermView(self.triple.predicate),
|
|
91
92
|
)
|
|
92
93
|
|
|
93
94
|
yield PropertyRow(
|
|
94
|
-
PropertyName(RDF.object),
|
|
95
|
+
PropertyName(RDF.object, qname=str(RDF.object)),
|
|
95
96
|
RDFTermView(self.triple.object),
|
|
96
97
|
)
|
|
97
98
|
|
iolanta/iolanta.py
CHANGED
|
@@ -2,6 +2,7 @@ import functools
|
|
|
2
2
|
from dataclasses import dataclass, field, replace
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import ( # noqa: WPS235
|
|
5
|
+
Annotated,
|
|
5
6
|
Any,
|
|
6
7
|
Dict,
|
|
7
8
|
Iterable,
|
|
@@ -30,7 +31,6 @@ from iolanta.errors import UnresolvedIRI
|
|
|
30
31
|
from iolanta.facets.errors import FacetError
|
|
31
32
|
from iolanta.facets.facet import Facet
|
|
32
33
|
from iolanta.facets.locator import FacetFinder
|
|
33
|
-
from iolanta.loaders import Loader
|
|
34
34
|
from iolanta.loaders.base import SourceType
|
|
35
35
|
from iolanta.loaders.local_directory import merge_contexts
|
|
36
36
|
from iolanta.models import (
|
|
@@ -45,7 +45,6 @@ from iolanta.parse_quads import parse_quads
|
|
|
45
45
|
from iolanta.parsers.yaml import YAML
|
|
46
46
|
from iolanta.plugin import Plugin
|
|
47
47
|
from iolanta.resolvers.python_import import PythonImportResolver
|
|
48
|
-
from iolanta.shortcuts import construct_root_loader
|
|
49
48
|
from iolanta.stack import Stack
|
|
50
49
|
from ldflex import LDFlex
|
|
51
50
|
|
|
@@ -72,19 +71,24 @@ class LoggerProtocol(Protocol):
|
|
|
72
71
|
"""Log a WARNING message."""
|
|
73
72
|
|
|
74
73
|
|
|
74
|
+
def _create_default_graph():
|
|
75
|
+
return ConjunctiveGraph(identifier=namespaces.LOCAL.term('_inference'))
|
|
76
|
+
|
|
77
|
+
|
|
75
78
|
@dataclass
|
|
76
79
|
class Iolanta: # noqa: WPS214
|
|
77
80
|
"""Iolanta is a Semantic web browser."""
|
|
78
81
|
|
|
79
82
|
language: Literal = Literal('en')
|
|
80
83
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
project_root: Annotated[
|
|
85
|
+
Path | None,
|
|
86
|
+
(
|
|
87
|
+
'File or directory the contents of which '
|
|
88
|
+
'Iolanta will automatically load into the graph.'
|
|
86
89
|
),
|
|
87
|
-
|
|
90
|
+
] = None
|
|
91
|
+
graph: ConjunctiveGraph = field(default_factory=_create_default_graph)
|
|
88
92
|
force_plugins: List[Type[Plugin]] = field(default_factory=list)
|
|
89
93
|
|
|
90
94
|
facet_resolver: Mapping[URIRef, Type[Facet]] = field(
|
|
@@ -104,15 +108,6 @@ class Iolanta: # noqa: WPS214
|
|
|
104
108
|
init=False,
|
|
105
109
|
)
|
|
106
110
|
|
|
107
|
-
@functools.cached_property
|
|
108
|
-
def loader(self) -> Loader[SourceType]:
|
|
109
|
-
"""
|
|
110
|
-
Construct loader.
|
|
111
|
-
|
|
112
|
-
FIXME: Delete this.
|
|
113
|
-
"""
|
|
114
|
-
return construct_root_loader(logger=self.logger)
|
|
115
|
-
|
|
116
111
|
@property
|
|
117
112
|
def plugin_classes(self) -> List[Type[Plugin]]:
|
|
118
113
|
"""Installed Iolanta plugins."""
|
|
@@ -130,7 +125,7 @@ class Iolanta: # noqa: WPS214
|
|
|
130
125
|
for plugin_class in self.plugin_classes
|
|
131
126
|
]
|
|
132
127
|
|
|
133
|
-
@
|
|
128
|
+
@property
|
|
134
129
|
def ldflex(self) -> LDFlex:
|
|
135
130
|
"""
|
|
136
131
|
Create ldflex instance.
|
|
@@ -156,45 +151,45 @@ class Iolanta: # noqa: WPS214
|
|
|
156
151
|
)
|
|
157
152
|
}
|
|
158
153
|
|
|
159
|
-
def
|
|
154
|
+
def reset(self):
|
|
155
|
+
"""Reset Iolanta graph."""
|
|
156
|
+
self.graph = _create_default_graph() # noqa: WPS601
|
|
157
|
+
self.__post_init__()
|
|
158
|
+
|
|
159
|
+
def add( # noqa: C901, WPS231, WPS210, WPS213
|
|
160
160
|
self,
|
|
161
161
|
source: Path,
|
|
162
162
|
context: Optional[LDContext] = None,
|
|
163
163
|
graph_iri: Optional[URIRef] = None,
|
|
164
164
|
) -> 'Iolanta':
|
|
165
|
-
"""
|
|
166
|
-
Parse & load information from given URL into the graph.
|
|
167
|
-
|
|
168
|
-
FIXME:
|
|
169
|
-
* Maybe implement context.json/context.yaml files support.
|
|
170
|
-
"""
|
|
165
|
+
"""Parse & load information from given URL into the graph."""
|
|
171
166
|
self.logger.info(f'Adding to graph: {source}')
|
|
172
167
|
self.sources_added_not_yet_inferred.append(source)
|
|
173
168
|
|
|
174
169
|
if not isinstance(source, Path):
|
|
175
170
|
source = Path(source)
|
|
176
171
|
|
|
177
|
-
for source_file in source.rglob('*'):
|
|
172
|
+
for source_file in list(source.rglob('*')) or [source]:
|
|
178
173
|
if source_file.is_dir():
|
|
179
174
|
continue
|
|
180
175
|
|
|
181
176
|
try: # noqa: WPS225
|
|
182
177
|
ld_rdf = yaml_ld.to_rdf(source_file)
|
|
183
178
|
except ConnectionError as name_resolution_error:
|
|
184
|
-
self.logger.
|
|
179
|
+
self.logger.warning(
|
|
185
180
|
'%s | name resolution error: %s',
|
|
186
181
|
source_file,
|
|
187
182
|
str(name_resolution_error),
|
|
188
183
|
)
|
|
189
184
|
continue
|
|
190
185
|
except ParserNotFound as parser_not_found:
|
|
191
|
-
self.logger.
|
|
186
|
+
self.logger.error(f'{source} | {parser_not_found}')
|
|
192
187
|
continue
|
|
193
188
|
except YAMLLDError as yaml_ld_error:
|
|
194
|
-
self.logger.
|
|
189
|
+
self.logger.error(f'{source} | {yaml_ld_error}')
|
|
195
190
|
continue
|
|
196
191
|
except ValueError as value_error:
|
|
197
|
-
self.logger.
|
|
192
|
+
self.logger.error(f'{source} | {value_error}')
|
|
198
193
|
continue
|
|
199
194
|
|
|
200
195
|
self.logger.info(f'{source_file} is loaded.')
|
|
@@ -318,31 +313,8 @@ class Iolanta: # noqa: WPS214
|
|
|
318
313
|
"""
|
|
319
314
|
self.bind_namespaces()
|
|
320
315
|
self.add_files_from_plugins()
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
"""
|
|
324
|
-
Parse a string into a node identifier.
|
|
325
|
-
|
|
326
|
-
String might be:
|
|
327
|
-
* a full IRI,
|
|
328
|
-
* a qname,
|
|
329
|
-
* a qname with implied `local:` part,
|
|
330
|
-
* or a blank node identifier.
|
|
331
|
-
"""
|
|
332
|
-
if isinstance(name, Node):
|
|
333
|
-
return name
|
|
334
|
-
|
|
335
|
-
if ':' in name:
|
|
336
|
-
# This is either a full IRI, a qname, or a blank node identifier.
|
|
337
|
-
try:
|
|
338
|
-
# Trying to interpret this as QName.
|
|
339
|
-
return self.graph.namespace_manager.expand_curie(name)
|
|
340
|
-
except ValueError:
|
|
341
|
-
# If it is not a QName then it is an IRI, let's return it.
|
|
342
|
-
return URIRef(name)
|
|
343
|
-
|
|
344
|
-
# This string does not include an ":", so we imply `local:`.
|
|
345
|
-
return URIRef(f'local:{name}')
|
|
316
|
+
if self.project_root:
|
|
317
|
+
self.add(self.project_root)
|
|
346
318
|
|
|
347
319
|
def render(
|
|
348
320
|
self,
|
iolanta/parse_quads.py
CHANGED
|
@@ -7,6 +7,7 @@ from rdflib.term import Node
|
|
|
7
7
|
|
|
8
8
|
from iolanta.errors import UnresolvedIRI
|
|
9
9
|
from iolanta.models import Quad
|
|
10
|
+
from iolanta.namespaces import IOLANTA, RDF
|
|
10
11
|
from iolanta.parsers.errors import SpaceInProperty
|
|
11
12
|
|
|
12
13
|
|
|
@@ -66,6 +67,20 @@ def parse_quads(
|
|
|
66
67
|
else:
|
|
67
68
|
graph_name = URIRef(graph_name)
|
|
68
69
|
|
|
70
|
+
yield Quad(
|
|
71
|
+
graph,
|
|
72
|
+
IOLANTA['has-sub-graph'],
|
|
73
|
+
graph_name,
|
|
74
|
+
graph,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
yield Quad(
|
|
78
|
+
graph_name,
|
|
79
|
+
RDF.type,
|
|
80
|
+
IOLANTA.Graph,
|
|
81
|
+
IOLANTA.meta,
|
|
82
|
+
)
|
|
83
|
+
|
|
69
84
|
for quad in quads:
|
|
70
85
|
try:
|
|
71
86
|
yield Quad(
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: iolanta
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.8
|
|
4
4
|
Summary: Semantic Web browser
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Anatoly Scherbakov
|
|
@@ -32,6 +32,7 @@ Requires-Dist: requests (>=2.25.1)
|
|
|
32
32
|
Requires-Dist: rich (>=13.3.1)
|
|
33
33
|
Requires-Dist: textual (>=0.83.0)
|
|
34
34
|
Requires-Dist: typer (>=0.9.0)
|
|
35
|
+
Requires-Dist: watchfiles (>=1.0.4,<2.0.0)
|
|
35
36
|
Requires-Dist: yaml-ld (>=1.1.3)
|
|
36
37
|
Requires-Dist: yarl (>=1.9.4)
|
|
37
38
|
Description-Content-Type: text/markdown
|
|
@@ -6,7 +6,7 @@ iolanta/cli/formatters/choose.py,sha256=Ac4hNoptvnhuJB77K9KOn5oMF7j2RxmNuaLko28W
|
|
|
6
6
|
iolanta/cli/formatters/csv.py,sha256=OVucZxhcMjihUli0wkbSOKo500-i7DNV0Zdf6oIougU,753
|
|
7
7
|
iolanta/cli/formatters/json.py,sha256=jkNldFApSWw0kcMkeIPvI2Vt4JTE-Rvx5mWqKJb3Sj4,741
|
|
8
8
|
iolanta/cli/formatters/pretty.py,sha256=Ik75CR5GMBDJCvES9eF0bQPj64ZJD40iFDSSZH0s9aA,2920
|
|
9
|
-
iolanta/cli/main.py,sha256
|
|
9
|
+
iolanta/cli/main.py,sha256=-VS9B8kEBgJI6dl4W1cT4mZzWkANnMG1M6JnlXpdSKk,3126
|
|
10
10
|
iolanta/cli/models.py,sha256=cjbpowdzI4wAP0DUk3qoVHyimk6AZwlXi9CGmusZTuM,159
|
|
11
11
|
iolanta/cli/pretty_print.py,sha256=M6E3TmhzA6JY5GeUVmDZLmOh5u70-393PVit4voFKDI,977
|
|
12
12
|
iolanta/context.py,sha256=bZR-tbZIrDQ-Vby01PMDZ6ifxM-0YMK68RJvAsyqCTs,507
|
|
@@ -14,13 +14,11 @@ iolanta/conversions.py,sha256=hbLwRF1bAbOxy17eMWLHhYksbdCWN-v4-0y0wn3XSSg,1185
|
|
|
14
14
|
iolanta/cyberspace/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
iolanta/cyberspace/inference/wikibase-claim.sparql,sha256=JSawj3VTc9ZPoU9mvh1w1AMYb3cWyZ3x1rEYWUsKZ6A,209
|
|
16
16
|
iolanta/cyberspace/inference/wikibase-statement-property.sparql,sha256=SkSHZZlxWVDwBM3aLo0Q7hLuOj9BsIQnXtcuAuwaxqU,240
|
|
17
|
-
iolanta/cyberspace/processor.py,sha256=
|
|
17
|
+
iolanta/cyberspace/processor.py,sha256=G740tg93-vkSrOgPm8ll8dA18UwbZEgtlg0eXt49wes,20153
|
|
18
18
|
iolanta/data/cli.yaml,sha256=TsnldYXoY5GIzoNuPDvwBKGw8eAEForZW1FCKqKI0Kg,1029
|
|
19
19
|
iolanta/data/context.yaml,sha256=OULEeDkSqshabaXF_gMujgwFLDJvt9eQn_9FftUlSUw,1424
|
|
20
|
-
iolanta/data/foaf-meta.yaml,sha256=BhRTFY_uue5FsJEDJnSgnA8hCr927RHnET9ZrQnFpdU,2647
|
|
21
20
|
iolanta/data/html.yaml,sha256=hVFdLWLy8FMY8xpOrJMYc-tE3S0Nq83xuxVkjRW_7rI,517
|
|
22
21
|
iolanta/data/iolanta.yaml,sha256=xubIFBNU02lmFXhgOSuyQwUcZD3xCqVfeVAZMvOxKbI,1433
|
|
23
|
-
iolanta/data/ontologies-meta.yaml,sha256=nM6ROkZbk_CiMVOBcbUjXvA1noVsyIuhtXFgU4fQBbk,1374
|
|
24
22
|
iolanta/data/textual-browser.yaml,sha256=ViMQJLiqa3CHdXluv9Fk3bEtyYC2ezNoHO7kQEp_N7w,3799
|
|
25
23
|
iolanta/ensure_is_context.py,sha256=9aok8asyEx7KPesOR28VBDb3Ch9kfc3eoCpQSJwj07U,717
|
|
26
24
|
iolanta/entry_points.py,sha256=DZbf-udlEwELFGqeWENj0M2BOUPOWlmGJdqyaEtnot0,504
|
|
@@ -48,22 +46,22 @@ iolanta/facets/html/code_literal.py,sha256=qCddzBrg6Y5XMIKohFQ52Tf9GPOcU7bj83tfA
|
|
|
48
46
|
iolanta/facets/html/default.py,sha256=Dmf_kYiL2M954iigyYsiWrMstwZ1nvxKetuR6aW3xYY,647
|
|
49
47
|
iolanta/facets/icon.py,sha256=ddZcolx1Q5_wo3w0jqiCzcc5Lsru6-jA7s7oAd1T8Og,494
|
|
50
48
|
iolanta/facets/locator.py,sha256=tFwxGT4ujwEjwkgTevK6gwWfj3_1lU9Q305IU7a-I3Y,7697
|
|
51
|
-
iolanta/facets/page_title.py,sha256=
|
|
49
|
+
iolanta/facets/page_title.py,sha256=s70A9w39O7J9Di3ni2ufRGsNctAW-eTzPTuP_wzWAtI,1446
|
|
52
50
|
iolanta/facets/qname.py,sha256=ztyBbjjcW8dNZzuiNMqhcWfAUxk-gSjbseVGrQE7kVY,531
|
|
53
51
|
iolanta/facets/textual_browser/__init__.py,sha256=sKgDvXOwib9n9d63kdtKCEv26-FoL0VN6zxDmfcheZ8,104
|
|
54
|
-
iolanta/facets/textual_browser/app.py,sha256=
|
|
52
|
+
iolanta/facets/textual_browser/app.py,sha256=6-cmEkwRqj9UptVvXKVNIxT3PcDDOZP1OLpv8gPmB_Q,3202
|
|
55
53
|
iolanta/facets/textual_browser/facet.py,sha256=zFynpMWr0iYaem-imbft5-2tjbkrDQEndYfHDlqqHUQ,740
|
|
56
54
|
iolanta/facets/textual_browser/history.py,sha256=b3jTwVkVe0ZBcYkHGJ_zKIV4MSMScDdabmLQIjOZfes,1087
|
|
57
55
|
iolanta/facets/textual_browser/home.py,sha256=GfDD1G2HiwdLkPkNdcYRqVIxDl5tWH9fewh_FJb8G-I,384
|
|
58
|
-
iolanta/facets/textual_browser/location.py,sha256=
|
|
56
|
+
iolanta/facets/textual_browser/location.py,sha256=w0La8bVTpJiVo1_hFTDQeIUdDdqfhYnoihuZW-f130c,205
|
|
59
57
|
iolanta/facets/textual_browser/models.py,sha256=DqTBjhkkTt5mNwqr4DzNbPSqzV-QtNqfKj7wpn6T3ao,173
|
|
60
58
|
iolanta/facets/textual_browser/page.py,sha256=NkcQ5rSKZRbp63C8ozgsR_iVhcKHGv_SytUCQyGa7ss,786
|
|
61
|
-
iolanta/facets/textual_browser/page_switcher.py,sha256=
|
|
59
|
+
iolanta/facets/textual_browser/page_switcher.py,sha256=Rbfa7HjGMw-OFOUfq8J8A3pIlrY0iP3ZJQrWl_US5tQ,9693
|
|
62
60
|
iolanta/facets/textual_class/__init__.py,sha256=tiL0p-3JspGcBRj4qa3rmoBFAuadk71l2ja2lJN6CEs,75
|
|
63
61
|
iolanta/facets/textual_class/facets.py,sha256=W3-N7bekk-bKwrb2rTPwmySGF42-uV7aqLPAiHwFSU4,6496
|
|
64
62
|
iolanta/facets/textual_class/sparql/instances.sparql,sha256=tmG4tuYrROKo3A7idjOEblAeNPXiiExHxc6k3fhalSM,113
|
|
65
63
|
iolanta/facets/textual_default/__init__.py,sha256=snxA0FEY9qfAxNv3MlZLrJsXugD4dvs5hLStZWV7soM,158
|
|
66
|
-
iolanta/facets/textual_default/facets.py,sha256=
|
|
64
|
+
iolanta/facets/textual_default/facets.py,sha256=Pf5GttQ7EG0ZodjwwVXzYMffHus3MAZdJUIcbddcYtw,4738
|
|
67
65
|
iolanta/facets/textual_default/sparql/inverse-properties.sparql,sha256=daHNdhmh92Q77CSf7ULbhxg57CuYsRFfMnXQz4VYEug,64
|
|
68
66
|
iolanta/facets/textual_default/sparql/label.sparql,sha256=IWAkkgMKtIZ7Zpg8LUJ5fDZ9tiI8fiRYZo-zT61Fong,121
|
|
69
67
|
iolanta/facets/textual_default/sparql/nodes-for-property.sparql,sha256=J9vg0Pz2HXDlPCeZ6IS2C0wODrpYDuNeD6DYT6UdNsU,68
|
|
@@ -71,7 +69,7 @@ iolanta/facets/textual_default/sparql/properties.sparql,sha256=stDbvFP4g6YKYphpN
|
|
|
71
69
|
iolanta/facets/textual_default/tcss/default.tcss,sha256=v6k6LvZMndRW4t9Iq-7QF59U_LJTdohRsyavwTY5ruI,69
|
|
72
70
|
iolanta/facets/textual_default/templates/default.md,sha256=CuD5lISsE2eAVnm2z6kfNff-vEgrNG95Wi5LTgkieWY,21
|
|
73
71
|
iolanta/facets/textual_default/triple_uri_ref.py,sha256=XfuNPaAe-YxH8IyrdrHQ641aWh5zVMVs0L0WC3D6A4M,1279
|
|
74
|
-
iolanta/facets/textual_default/widgets.py,sha256=
|
|
72
|
+
iolanta/facets/textual_default/widgets.py,sha256=yOw3qJlwXYNqz3HuuRiVM0IZ-YSto_IeI2Hgv6n1BxU,9189
|
|
75
73
|
iolanta/facets/textual_graph/__init__.py,sha256=DWd2gljzL8SiyYKQdBH78HouF1EMqgCH-w0K5OEmL2I,59
|
|
76
74
|
iolanta/facets/textual_graph/facets.py,sha256=ZjWEEjzYGHRODvTUPiTFjKEjFQx59Bq-1v_RXU54M9k,876
|
|
77
75
|
iolanta/facets/textual_graph/sparql/triples.sparql,sha256=5rFVGcvZzEHZj2opQQp0YlxJLpEdl-r1RjkPwo8j7t0,145
|
|
@@ -89,7 +87,7 @@ iolanta/facets/textual_ontology/facets.py,sha256=60g8ANmePb9_i_-d4ui-FdtNwg9aktr
|
|
|
89
87
|
iolanta/facets/textual_ontology/sparql/terms.sparql,sha256=oVLxN452nqog_95qRaTWnvar6rxPNxPrRonSo7oFFTg,324
|
|
90
88
|
iolanta/facets/textual_ontology/sparql/visualization-vocab.sparql,sha256=UNbU2Qt5C1Vq-CvdVhok7wecnu6p_IDtw7A8n_g6lBs,66
|
|
91
89
|
iolanta/facets/textual_provenance/__init__.py,sha256=k5-_iK8Lrdwr5ZEJaDxq-UhGYe4G_adXVqGfOA5DAP8,114
|
|
92
|
-
iolanta/facets/textual_provenance/facets.py,sha256=
|
|
90
|
+
iolanta/facets/textual_provenance/facets.py,sha256=vv3UQsI2duB36DW5Zkw3sqgAXBPmK_xAo7cU0O7jF8g,3767
|
|
93
91
|
iolanta/facets/textual_provenance/sparql/graphs.sparql,sha256=B45uKFd-1vrBuMDSbTURjUUEjHt51vAbqdL4tUcgMvk,103
|
|
94
92
|
iolanta/facets/textual_provenance/sparql/triples.sparql,sha256=V-EdVuWbGHY3MspbJIMpwxPQautLDqJJV-AmihDjSHc,53
|
|
95
93
|
iolanta/facets/title/__init__.py,sha256=fxpkG-YvHDp6eiVL3o7BbwhPMZZe-1R2Qi6S36QCTf8,77
|
|
@@ -98,7 +96,7 @@ iolanta/facets/title/sparql/title.sparql,sha256=4rz47tjwX2OJavWMzftaYKil1-ZHB76Z
|
|
|
98
96
|
iolanta/facets/wikibase_statement_title/__init__.py,sha256=_yk1akxgSJOiUBJIc8QGrD2vovvmx_iw_vJDuv1rD7M,91
|
|
99
97
|
iolanta/facets/wikibase_statement_title/facets.py,sha256=mUH7twlAgoeX7DgLQuRBQv4ORT6GWbN-0eJ1aliSfiQ,724
|
|
100
98
|
iolanta/facets/wikibase_statement_title/sparql/statement-title.sparql,sha256=n07DQWxKqB5c3CA4kacq2HSN0R0dLgnMnLP1AxMo5YA,320
|
|
101
|
-
iolanta/iolanta.py,sha256=
|
|
99
|
+
iolanta/iolanta.py,sha256=kSMYvDmyjpSDgqLppeI835fHRl1YOVfuwiodIrVlUwo,12954
|
|
102
100
|
iolanta/loaders/__init__.py,sha256=QTiKCsQc1BTS-IlY2CQsN9iVpEIPqYFvI9ERMYVZCbU,99
|
|
103
101
|
iolanta/loaders/base.py,sha256=-DxYwqG1bfDXB2p_S-mKpkc_3Sh14OHhePbe65Iq3-s,3381
|
|
104
102
|
iolanta/loaders/data_type_choice.py,sha256=zRUXBIzjvuW28P_dhMDVevE9C8EFEIx2_X39WydWrtM,1982
|
|
@@ -111,7 +109,7 @@ iolanta/loaders/scheme_choice.py,sha256=GHA4JAD-Qq3uNdej4vs_bCrN1WMRshVRvOMxaYyP
|
|
|
111
109
|
iolanta/models.py,sha256=L0iFaga4-PCaWP18WmT03NLK_oT7q49V0WMTQskoffI,2824
|
|
112
110
|
iolanta/namespaces.py,sha256=fyWDCGPwU8Cs8d-Vmci4H0-fuIe7BMSevvEKFvG7Gf4,1153
|
|
113
111
|
iolanta/node_to_qname.py,sha256=a82_qpgT87cbekY_76tTkl4Z-6Rz6am4UGIQChUf9Y0,794
|
|
114
|
-
iolanta/parse_quads.py,sha256=
|
|
112
|
+
iolanta/parse_quads.py,sha256=yOI154hGRCNv4UjEuhicP0cQWNWid_52mE86VWYfH8w,2833
|
|
115
113
|
iolanta/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
116
114
|
iolanta/parsers/base.py,sha256=ZFjj0BLzW4985BdC6PwbngenhMuSYW5mNLpprZRWjhA,1048
|
|
117
115
|
iolanta/parsers/dict_parser.py,sha256=t_OK2meUh49DqSaOYkSgEwxMKUNNgjJY8rZAyL4NQKI,4546
|
|
@@ -130,7 +128,7 @@ iolanta/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
130
128
|
iolanta/widgets/mixin.py,sha256=nDRCOc-gizCf1a5DAcYs4hW8eZEd6pHBPFsfm0ncv7E,251
|
|
131
129
|
ldflex/__init__.py,sha256=8IELqR55CQXuI0BafjobXSK7_kOc-qKVTrEtEwXnZRA,33
|
|
132
130
|
ldflex/ldflex.py,sha256=omKmOo5PUyn8Evw4q_lqKCJOq6yqVOcLAYxnYkdwOUs,3332
|
|
133
|
-
iolanta-1.2.
|
|
134
|
-
iolanta-1.2.
|
|
135
|
-
iolanta-1.2.
|
|
136
|
-
iolanta-1.2.
|
|
131
|
+
iolanta-1.2.8.dist-info/METADATA,sha256=ZuobBaJiRgngoHBJuRTNrI8CZbn0KT_vPtHZP9QfkQ0,1361
|
|
132
|
+
iolanta-1.2.8.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
133
|
+
iolanta-1.2.8.dist-info/entry_points.txt,sha256=fIp9g4kzjSNcTsTSjUCk4BIG3laHd3b3hUZlkjgFAGU,179
|
|
134
|
+
iolanta-1.2.8.dist-info/RECORD,,
|
iolanta/data/foaf-meta.yaml
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
"@context":
|
|
2
|
-
"@import": https://json-ld.org/contexts/dollar-convenience.jsonld
|
|
3
|
-
vann: https://purl.org/vocab/vann/
|
|
4
|
-
foaf: https://xmlns.com/foaf/0.1/
|
|
5
|
-
owl: https://www.w3.org/2002/07/owl#
|
|
6
|
-
iolanta: https://iolanta.tech/
|
|
7
|
-
rdfs: "https://www.w3.org/2000/01/rdf-schema#"
|
|
8
|
-
rdf: https://www.w3.org/1999/02/22-rdf-syntax-ns#
|
|
9
|
-
|
|
10
|
-
$id: "foaf:"
|
|
11
|
-
$type: owl:Ontology
|
|
12
|
-
vann:termGroup:
|
|
13
|
-
- rdfs:label: Core Classes
|
|
14
|
-
$reverse:
|
|
15
|
-
rdf:type:
|
|
16
|
-
- foaf:Person
|
|
17
|
-
- foaf:Organization
|
|
18
|
-
- foaf:Group
|
|
19
|
-
- foaf:Agent
|
|
20
|
-
|
|
21
|
-
- rdfs:label: Docs & Images
|
|
22
|
-
$reverse:
|
|
23
|
-
rdf:type:
|
|
24
|
-
- foaf:Document
|
|
25
|
-
- foaf:Image
|
|
26
|
-
- foaf:img
|
|
27
|
-
- foaf:depiction
|
|
28
|
-
- foaf:page
|
|
29
|
-
- foaf:topic
|
|
30
|
-
- foaf:PersonalProfileDocument
|
|
31
|
-
- foaf:primaryTopic
|
|
32
|
-
- foaf:isPrimaryTopicOf
|
|
33
|
-
- foaf:sha1
|
|
34
|
-
|
|
35
|
-
- rdfs:label: Personal
|
|
36
|
-
$reverse:
|
|
37
|
-
rdf:type:
|
|
38
|
-
- foaf:name
|
|
39
|
-
- foaf:lastName
|
|
40
|
-
- foaf:title
|
|
41
|
-
- foaf:surname
|
|
42
|
-
- foaf:familyName
|
|
43
|
-
- foaf:givenName
|
|
44
|
-
- foaf:family_name
|
|
45
|
-
- foaf:firstName
|
|
46
|
-
- foaf:gender
|
|
47
|
-
- foaf:birthday
|
|
48
|
-
- foaf:age
|
|
49
|
-
- foaf:status
|
|
50
|
-
- foaf:myersBriggs
|
|
51
|
-
- foaf:dnaChecksum
|
|
52
|
-
- foaf:nick
|
|
53
|
-
- foaf:topic_interest
|
|
54
|
-
- foaf:publications
|
|
55
|
-
- foaf:workInfoHomepage
|
|
56
|
-
|
|
57
|
-
- rdfs:label: Online Presence
|
|
58
|
-
$reverse:
|
|
59
|
-
rdf:type:
|
|
60
|
-
- foaf:mbox
|
|
61
|
-
- foaf:phone
|
|
62
|
-
- foaf:OnlineAccount
|
|
63
|
-
- foaf:OnlineEcommerceAccount
|
|
64
|
-
- foaf:OnlineGamingAccount
|
|
65
|
-
- foaf:OnlineChatAccount
|
|
66
|
-
- foaf:account
|
|
67
|
-
- foaf:accountServiceHomepage
|
|
68
|
-
- foaf:accountName
|
|
69
|
-
- foaf:aimChatID
|
|
70
|
-
- foaf:jabberID
|
|
71
|
-
- foaf:skypeID
|
|
72
|
-
- foaf:msnChatID
|
|
73
|
-
- foaf:yahooChatID
|
|
74
|
-
- foaf:openid
|
|
75
|
-
- foaf:homepage
|
|
76
|
-
- foaf:weblog
|
|
77
|
-
- foaf:geekcode
|
|
78
|
-
- foaf:workplaceHomepage
|
|
79
|
-
- foaf:schoolHomepage
|
|
80
|
-
- foaf:icqChatID
|
|
81
|
-
- foaf:mbox_sha1sum
|
|
82
|
-
|
|
83
|
-
- rdfs:label: Social
|
|
84
|
-
$reverse:
|
|
85
|
-
rdf:type:
|
|
86
|
-
- foaf:knows
|
|
87
|
-
- foaf:friendOf
|
|
88
|
-
- foaf:member
|
|
89
|
-
- foaf:membershipClass
|
|
90
|
-
- foaf:depiction
|
|
91
|
-
- foaf:depicts
|
|
92
|
-
- foaf:thumbnail
|
|
93
|
-
- foaf:based_near
|
|
94
|
-
|
|
95
|
-
- rdfs:label: Activities & Projects
|
|
96
|
-
$reverse:
|
|
97
|
-
rdf:type:
|
|
98
|
-
- foaf:Project
|
|
99
|
-
- foaf:fundedBy
|
|
100
|
-
- foaf:interest
|
|
101
|
-
- foaf:currentProject
|
|
102
|
-
- foaf:pastProject
|
|
103
|
-
- foaf:logo
|
|
104
|
-
- foaf:maker
|
|
105
|
-
- foaf:made
|
|
106
|
-
- foaf:plan
|
|
107
|
-
- foaf:tipjar
|
|
108
|
-
|
|
109
|
-
- rdfs:label: Meta
|
|
110
|
-
$reverse:
|
|
111
|
-
rdf:type:
|
|
112
|
-
- foaf:LabelProperty
|
|
113
|
-
- foaf:focus
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"@context":
|
|
2
|
-
"@import": https://json-ld.org/contexts/dollar-convenience.jsonld
|
|
3
|
-
vann: https://purl.org/vocab/vann/
|
|
4
|
-
foaf: https://xmlns.com/foaf/0.1/
|
|
5
|
-
owl: https://www.w3.org/2002/07/owl#
|
|
6
|
-
iolanta: https://iolanta.tech/
|
|
7
|
-
rdfs: "https://www.w3.org/2000/01/rdf-schema#"
|
|
8
|
-
rdf: https://www.w3.org/1999/02/22-rdf-syntax-ns#
|
|
9
|
-
|
|
10
|
-
$included:
|
|
11
|
-
- $id: "owl:"
|
|
12
|
-
$type: owl:Ontology
|
|
13
|
-
|
|
14
|
-
- $id: "https://purl.org/dc/terms/"
|
|
15
|
-
$type: owl:Ontology
|
|
16
|
-
|
|
17
|
-
- $id: "rdf:"
|
|
18
|
-
vann:termGroup:
|
|
19
|
-
- rdfs:label: Properties
|
|
20
|
-
$reverse:
|
|
21
|
-
rdf:type:
|
|
22
|
-
- rdf:Property
|
|
23
|
-
- rdf:type
|
|
24
|
-
|
|
25
|
-
- rdfs:label: Triples
|
|
26
|
-
$reverse:
|
|
27
|
-
rdf:type:
|
|
28
|
-
- rdf:subject
|
|
29
|
-
- rdf:predicate
|
|
30
|
-
- rdf:object
|
|
31
|
-
- rdf:Statement
|
|
32
|
-
- rdfs:label: Containers
|
|
33
|
-
$reverse:
|
|
34
|
-
rdf:type:
|
|
35
|
-
- rdf:first
|
|
36
|
-
- rdf:rest
|
|
37
|
-
- rdf:List
|
|
38
|
-
- rdf:nil
|
|
39
|
-
- rdf:Bag
|
|
40
|
-
- rdf:Seq
|
|
41
|
-
- rdf:Alt
|
|
42
|
-
- rdfs:label: Language
|
|
43
|
-
$reverse:
|
|
44
|
-
rdf:type:
|
|
45
|
-
- rdf:langString
|
|
46
|
-
- rdf:language
|
|
47
|
-
|
|
48
|
-
- $id: rdfs:Datatype
|
|
49
|
-
- rdfs:label: Compound Literal
|
|
50
|
-
$reverse:
|
|
51
|
-
rdf:type:
|
|
52
|
-
- rdf:CompoundLiteral
|
|
53
|
-
- rdf:direction
|
|
54
|
-
- rdfs:label: Value
|
|
55
|
-
$reverse:
|
|
56
|
-
rdf:type:
|
|
57
|
-
- rdf:value
|
|
File without changes
|
|
File without changes
|