iolanta 2.0.2__py3-none-any.whl → 2.0.6__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 +2 -2
- iolanta/data/context.yaml +15 -0
- iolanta/data/graph-triples.yamlld +6 -0
- iolanta/data/textual-browser.yaml +67 -52
- iolanta/facets/locator.py +34 -8
- iolanta/facets/textual_class/facets.py +35 -46
- iolanta/facets/textual_class/sparql/instances.sparql +1 -1
- iolanta/facets/textual_no_facet_found.py +68 -0
- iolanta/iolanta.py +3 -3
- iolanta/parse_quads.py +0 -7
- iolanta/sparqlspace/cli.py +64 -0
- iolanta/{cyberspace → sparqlspace}/processor.py +105 -69
- iolanta/sparqlspace/sparqlspace.py +32 -0
- iolanta/widgets/description.py +12 -0
- {iolanta-2.0.2.dist-info → iolanta-2.0.6.dist-info}/METADATA +2 -2
- {iolanta-2.0.2.dist-info → iolanta-2.0.6.dist-info}/RECORD +21 -16
- {iolanta-2.0.2.dist-info → iolanta-2.0.6.dist-info}/entry_points.txt +2 -1
- /iolanta/{cyberspace → sparqlspace}/__init__.py +0 -0
- /iolanta/{cyberspace → sparqlspace}/inference/wikibase-claim.sparql +0 -0
- /iolanta/{cyberspace → sparqlspace}/inference/wikibase-statement-property.sparql +0 -0
- {iolanta-2.0.2.dist-info → iolanta-2.0.6.dist-info}/WHEEL +0 -0
iolanta/cli/main.py
CHANGED
|
@@ -94,7 +94,7 @@ def render_command( # noqa: WPS231, WPS238, WPS210, C901
|
|
|
94
94
|
)
|
|
95
95
|
|
|
96
96
|
node_url = URL(url)
|
|
97
|
-
if node_url.scheme:
|
|
97
|
+
if node_url.scheme and node_url.scheme != 'file':
|
|
98
98
|
node = URIRef(url)
|
|
99
99
|
|
|
100
100
|
iolanta: Iolanta = Iolanta(
|
|
@@ -102,7 +102,7 @@ def render_command( # noqa: WPS231, WPS238, WPS210, C901
|
|
|
102
102
|
logger=logger,
|
|
103
103
|
)
|
|
104
104
|
else:
|
|
105
|
-
path = Path(
|
|
105
|
+
path = Path(node_url.path).absolute()
|
|
106
106
|
node = URIRef(f'file://{path}')
|
|
107
107
|
iolanta: Iolanta = Iolanta(
|
|
108
108
|
language=Literal(language),
|
iolanta/data/context.yaml
CHANGED
|
@@ -59,3 +59,18 @@
|
|
|
59
59
|
|
|
60
60
|
rdf:type:
|
|
61
61
|
"@type": "@id"
|
|
62
|
+
|
|
63
|
+
$: rdfs:label
|
|
64
|
+
→:
|
|
65
|
+
"@type": "@id"
|
|
66
|
+
"@id": iolanta:outputs
|
|
67
|
+
|
|
68
|
+
⊆:
|
|
69
|
+
"@type": "@id"
|
|
70
|
+
"@id": rdfs:subClassOf
|
|
71
|
+
|
|
72
|
+
⪯:
|
|
73
|
+
"@type": "@id"
|
|
74
|
+
"@id": iolanta:is-preferred-over
|
|
75
|
+
|
|
76
|
+
↦: iolanta:matches
|
|
@@ -13,57 +13,75 @@
|
|
|
13
13
|
iolanta:outputs:
|
|
14
14
|
"@type": "@id"
|
|
15
15
|
|
|
16
|
+
iolanta:when-no-facet-found:
|
|
17
|
+
"@type": "@id"
|
|
18
|
+
|
|
16
19
|
$: rdfs:label
|
|
20
|
+
→:
|
|
21
|
+
"@type": "@id"
|
|
22
|
+
"@id": iolanta:outputs
|
|
23
|
+
|
|
24
|
+
⊆:
|
|
25
|
+
"@type": "@id"
|
|
26
|
+
"@id": rdfs:subClassOf
|
|
27
|
+
|
|
28
|
+
⪯:
|
|
29
|
+
"@type": "@id"
|
|
30
|
+
"@id": iolanta:is-preferred-over
|
|
31
|
+
|
|
32
|
+
↦: iolanta:matches
|
|
17
33
|
|
|
18
34
|
"@included":
|
|
19
35
|
- $id: iolanta:icon
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
$id: xsd:string
|
|
36
|
+
$: Icon
|
|
37
|
+
⊆: xsd:string
|
|
23
38
|
|
|
24
39
|
- $id: dcterms:creator
|
|
25
40
|
iolanta:icon: ©️
|
|
26
41
|
|
|
27
42
|
- $id: https://iolanta.tech/datatypes/icon
|
|
28
|
-
|
|
43
|
+
$: Icon
|
|
29
44
|
iolanta:hasDefaultFacet:
|
|
30
45
|
$id: python://iolanta.facets.icon.IconFacet
|
|
31
|
-
iolanta
|
|
32
|
-
$id: https://iolanta.tech/datatypes/icon
|
|
46
|
+
→: https://iolanta.tech/datatypes/icon
|
|
33
47
|
|
|
34
48
|
- $id: np:Nanopublication
|
|
35
|
-
|
|
49
|
+
$: Nanopublication
|
|
36
50
|
iolanta:hasInstanceFacet:
|
|
37
51
|
$id: python://iolanta.facets.textual_nanopublication.NanopublicationFacet
|
|
38
|
-
|
|
39
|
-
iolanta
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
52
|
+
$: Nanopublication
|
|
53
|
+
→: https://iolanta.tech/cli/textual
|
|
54
|
+
⪯:
|
|
55
|
+
- python://iolanta.facets.textual_default.TextualDefaultFacet
|
|
56
|
+
- python://iolanta.facets.textual_graph.GraphFacet
|
|
43
57
|
|
|
44
58
|
- $id: https://iolanta.tech/cli/interactive
|
|
45
59
|
iolanta:hasDefaultFacet:
|
|
46
60
|
$id: python://iolanta.facets.textual_browser.TextualBrowserFacet
|
|
47
61
|
|
|
48
|
-
- $id:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
62
|
+
- $id: python://iolanta.facets.textual_default.TextualDefaultFacet
|
|
63
|
+
$: Properties
|
|
64
|
+
⪯: python://iolanta.facets.textual_default.InverseProperties
|
|
65
|
+
→: https://iolanta.tech/cli/textual
|
|
66
|
+
↦: |
|
|
67
|
+
ASK WHERE {
|
|
68
|
+
GRAPH ?graph { $this ?property ?value }
|
|
69
|
+
FILTER (?graph != <iolanta://_meta>)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
- $id: python://iolanta.facets.textual_default.InverseProperties
|
|
73
|
+
$: Inverse Properties
|
|
74
|
+
→: https://iolanta.tech/cli/textual
|
|
75
|
+
↦: |
|
|
76
|
+
ASK WHERE {
|
|
77
|
+
GRAPH ?graph { ?something ?property $this }
|
|
78
|
+
FILTER (?graph != <iolanta://_meta>)
|
|
79
|
+
}
|
|
61
80
|
|
|
62
81
|
- $id: "urn:"
|
|
63
82
|
iolanta:hasFacetByPrefix:
|
|
64
83
|
$id: python://iolanta.facets.textual_provenance.TextualProvenanceFacet
|
|
65
|
-
iolanta
|
|
66
|
-
$id: https://iolanta.tech/cli/textual
|
|
84
|
+
→: https://iolanta.tech/cli/textual
|
|
67
85
|
|
|
68
86
|
- $id: https://iolanta.tech/cli/link
|
|
69
87
|
iolanta:hasDefaultFacet:
|
|
@@ -72,47 +90,44 @@
|
|
|
72
90
|
- $id: https://wikiba.se/ontology#Statement
|
|
73
91
|
iolanta:hasInstanceFacet:
|
|
74
92
|
$id: python://iolanta.facets.wikibase_statement_title.WikibaseStatementTitle
|
|
75
|
-
|
|
76
|
-
iolanta
|
|
77
|
-
$id: https://iolanta.tech/datatypes/title
|
|
93
|
+
$: Title
|
|
94
|
+
→: https://iolanta.tech/datatypes/title
|
|
78
95
|
|
|
79
96
|
- $id: rdfs:Class
|
|
80
97
|
iolanta:hasInstanceFacet:
|
|
81
98
|
$id: python://iolanta.facets.textual_class.Class
|
|
82
|
-
|
|
83
|
-
iolanta
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
-
|
|
87
|
-
- $id: python://iolanta.facets.textual_default.InverseProperties
|
|
99
|
+
$: Instances
|
|
100
|
+
→: https://iolanta.tech/cli/textual
|
|
101
|
+
⪯:
|
|
102
|
+
- python://iolanta.facets.textual_browser.TextualBrowserFacet
|
|
103
|
+
- python://iolanta.facets.textual_default.InverseProperties
|
|
88
104
|
|
|
89
105
|
- $id: owl:Ontology
|
|
90
106
|
iolanta:hasInstanceFacet:
|
|
91
107
|
$id: python://iolanta.facets.textual_ontology.OntologyFacet
|
|
92
|
-
|
|
93
|
-
iolanta
|
|
94
|
-
|
|
95
|
-
iolanta:is-preferred-over:
|
|
96
|
-
- $id: python://iolanta.facets.textual_default.TextualDefaultFacet
|
|
97
|
-
|
|
98
|
-
- $id: iolanta:Graph
|
|
99
|
-
iolanta:hasInstanceFacet:
|
|
100
|
-
$id: python://iolanta.facets.textual_graph.GraphFacet
|
|
101
|
-
rdfs:label: Graph Triples
|
|
102
|
-
iolanta:outputs:
|
|
103
|
-
$id: https://iolanta.tech/cli/textual
|
|
108
|
+
$: Ontology
|
|
109
|
+
→: https://iolanta.tech/cli/textual
|
|
110
|
+
⪯: python://iolanta.facets.textual_default.TextualDefaultFacet
|
|
104
111
|
|
|
105
112
|
- $id: https://iolanta.tech/datatypes/textual-graph-triples
|
|
106
|
-
|
|
113
|
+
$: Graph Triples
|
|
107
114
|
iolanta:hasDefaultFacet:
|
|
108
115
|
$id: python://iolanta.facets.textual_graph_triples.GraphTriplesFacet
|
|
109
|
-
iolanta
|
|
110
|
-
$id: https://iolanta.tech/datatypes/textual-graph-triples
|
|
116
|
+
→: https://iolanta.tech/datatypes/textual-graph-triples
|
|
111
117
|
|
|
112
118
|
- $id: https://iolanta.tech/qname
|
|
113
119
|
iolanta:hasDefaultFacet:
|
|
114
120
|
$id: python://iolanta.facets.qname.QNameFacet
|
|
115
121
|
|
|
116
122
|
- $id: python://iolanta.facets.textual_property_pairs_table.TextualPropertyPairsTableFacet
|
|
117
|
-
iolanta:outputs: https://iolanta.tech/cli/textual
|
|
118
123
|
$: Subjects → Objects
|
|
124
|
+
→: https://iolanta.tech/cli/textual
|
|
125
|
+
↦: ASK WHERE { ?subject $this ?object }
|
|
126
|
+
|
|
127
|
+
- $id: python://iolanta.facets.textual_class.Class
|
|
128
|
+
↦:
|
|
129
|
+
- ASK WHERE { ?instance a $this }
|
|
130
|
+
- ASK WHERE { $this rdfs:subClassOf ?superclass }
|
|
131
|
+
|
|
132
|
+
- $id: https://iolanta.tech/cli/textual
|
|
133
|
+
iolanta:when-no-facet-found: python://iolanta.facets.textual_no_facet_found.TextualNoFacetFound
|
iolanta/facets/locator.py
CHANGED
|
@@ -18,6 +18,15 @@ class FoundRow(TypedDict):
|
|
|
18
18
|
output_datatype: NotLiteralNode
|
|
19
19
|
|
|
20
20
|
|
|
21
|
+
GET_QUERY_TO_FACET = """
|
|
22
|
+
SELECT ?facet ?match WHERE {
|
|
23
|
+
?facet
|
|
24
|
+
iolanta:matches ?match ;
|
|
25
|
+
iolanta:outputs $as_datatype .
|
|
26
|
+
}
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
|
|
21
30
|
def reorder_rows_by_facet_preferences( # noqa: WPS214, WPS210
|
|
22
31
|
rows: list[FoundRow],
|
|
23
32
|
ordering: set[tuple[URIRef, URIRef]],
|
|
@@ -108,16 +117,14 @@ class FacetFinder: # noqa: WPS214
|
|
|
108
117
|
if not isinstance(self.node, URIRef):
|
|
109
118
|
return
|
|
110
119
|
|
|
111
|
-
|
|
112
|
-
|
|
120
|
+
rows = self.iolanta.query(
|
|
121
|
+
GET_QUERY_TO_FACET,
|
|
122
|
+
as_datatype=self.as_datatype,
|
|
123
|
+
)
|
|
113
124
|
|
|
114
|
-
# TODO: Retrieve queries from the graph
|
|
115
|
-
# TODO: Verify datatype for which we are visualizing $this
|
|
116
125
|
query_to_facet = {
|
|
117
|
-
'
|
|
118
|
-
|
|
119
|
-
'.TextualPropertyPairsTableFacet',
|
|
120
|
-
),
|
|
126
|
+
row['match']: row['facet']
|
|
127
|
+
for row in rows
|
|
121
128
|
}
|
|
122
129
|
|
|
123
130
|
for query, facet in query_to_facet.items():
|
|
@@ -233,6 +240,22 @@ class FacetFinder: # noqa: WPS214
|
|
|
233
240
|
for row in rows
|
|
234
241
|
]
|
|
235
242
|
|
|
243
|
+
def by_facet_not_found(self) -> Iterable[FoundRow]:
|
|
244
|
+
"""What facet to show if no facets are found?"""
|
|
245
|
+
rows = self.iolanta.query( # noqa: WPS462
|
|
246
|
+
"""
|
|
247
|
+
SELECT ?facet ?output_datatype WHERE {
|
|
248
|
+
$output_datatype iolanta:when-no-facet-found ?facet .
|
|
249
|
+
}
|
|
250
|
+
""",
|
|
251
|
+
output_datatype=self.as_datatype,
|
|
252
|
+
)
|
|
253
|
+
|
|
254
|
+
return [
|
|
255
|
+
FoundRow(facet=row['facet'], output_datatype=row['output_datatype'])
|
|
256
|
+
for row in rows
|
|
257
|
+
]
|
|
258
|
+
|
|
236
259
|
def retrieve_facets_preference_ordering(self) -> set[tuple[URIRef, URIRef]]:
|
|
237
260
|
"""
|
|
238
261
|
Construct partial ordering on the set of facets.
|
|
@@ -256,6 +279,9 @@ class FacetFinder: # noqa: WPS214
|
|
|
256
279
|
"""Return all suitable facets."""
|
|
257
280
|
rows = list(self._found_facets())
|
|
258
281
|
|
|
282
|
+
if not rows:
|
|
283
|
+
rows = self.by_facet_not_found()
|
|
284
|
+
|
|
259
285
|
if len(rows) == 1:
|
|
260
286
|
# Nothing to order.
|
|
261
287
|
return rows
|
|
@@ -6,7 +6,7 @@ import funcy
|
|
|
6
6
|
from rich.console import RenderResult
|
|
7
7
|
from rich.text import Text
|
|
8
8
|
from textual.binding import Binding, BindingType
|
|
9
|
-
from textual.containers import Vertical
|
|
9
|
+
from textual.containers import Vertical # removed unused VerticalScroll (F401)
|
|
10
10
|
from textual.reactive import Reactive
|
|
11
11
|
from textual.widget import Widget
|
|
12
12
|
from textual.widgets import Label, ListItem, ListView
|
|
@@ -70,10 +70,8 @@ class InstancesList(ListView): # noqa: WPS214
|
|
|
70
70
|
|
|
71
71
|
DEFAULT_CSS = """
|
|
72
72
|
InstancesList {
|
|
73
|
-
height:
|
|
74
|
-
|
|
73
|
+
height: 1fr;
|
|
75
74
|
layout: vertical;
|
|
76
|
-
overflow-x: hidden;
|
|
77
75
|
overflow-y: auto;
|
|
78
76
|
}
|
|
79
77
|
"""
|
|
@@ -121,31 +119,6 @@ class InstancesList(ListView): # noqa: WPS214
|
|
|
121
119
|
parent_class=self.parent_class,
|
|
122
120
|
)
|
|
123
121
|
|
|
124
|
-
def on_list_view_highlighted(self):
|
|
125
|
-
"""
|
|
126
|
-
Find out whether the last item of the list is highlighted.
|
|
127
|
-
|
|
128
|
-
If yes then add more elements.
|
|
129
|
-
"""
|
|
130
|
-
if not self._nodes or (self.index >= len(self._nodes) - 1):
|
|
131
|
-
new_instance_items = list(self.stream_instance_items_chunk())
|
|
132
|
-
self.run_worker(
|
|
133
|
-
functools.partial(
|
|
134
|
-
self.render_newly_added_instances,
|
|
135
|
-
new_instance_items,
|
|
136
|
-
),
|
|
137
|
-
thread=True,
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
# #126 `extend()` here will lead to freeze in some situations
|
|
141
|
-
for new_item in new_instance_items:
|
|
142
|
-
self.append(new_item)
|
|
143
|
-
|
|
144
|
-
def on_list_item__child_clicked(self) -> None: # noqa: WPS116
|
|
145
|
-
"""Navigate on click."""
|
|
146
|
-
# FIXME if we call `action_goto()` here we'll navigate to the item that
|
|
147
|
-
# was selected _prior_ to this click.
|
|
148
|
-
|
|
149
122
|
def action_goto(self):
|
|
150
123
|
"""Navigate."""
|
|
151
124
|
self.app.action_goto(self.highlighted_child.node)
|
|
@@ -160,6 +133,32 @@ class InstancesList(ListView): # noqa: WPS214
|
|
|
160
133
|
),
|
|
161
134
|
)
|
|
162
135
|
|
|
136
|
+
def compose(self):
|
|
137
|
+
"""Fill in the instances."""
|
|
138
|
+
for instance in self.instances: # noqa: WPS526
|
|
139
|
+
yield InstanceItem(
|
|
140
|
+
node=instance,
|
|
141
|
+
parent_class=self.parent_class,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
def render_instances(self):
|
|
145
|
+
"""Render all instances."""
|
|
146
|
+
for instance_item in self.children:
|
|
147
|
+
self.app.call_from_thread(
|
|
148
|
+
instance_item.update,
|
|
149
|
+
self.app.iolanta.render(
|
|
150
|
+
instance_item.node,
|
|
151
|
+
as_datatype=DATATYPES.title,
|
|
152
|
+
),
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
def on_mount(self):
|
|
156
|
+
"""Render the first chunk of instances."""
|
|
157
|
+
self.run_worker(
|
|
158
|
+
self.render_instances,
|
|
159
|
+
thread=True,
|
|
160
|
+
)
|
|
161
|
+
|
|
163
162
|
|
|
164
163
|
class Bottom(Label):
|
|
165
164
|
"""Label below the instances list."""
|
|
@@ -198,29 +197,19 @@ class Class(Facet[Widget]):
|
|
|
198
197
|
We have to stop if a subsequent attempt returns no results. That's why
|
|
199
198
|
we can't use `funcy.distinct()` or something similar.
|
|
200
199
|
"""
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
),
|
|
208
|
-
).difference(known_instances)
|
|
209
|
-
|
|
210
|
-
if not instances:
|
|
211
|
-
return
|
|
212
|
-
|
|
213
|
-
yield from instances
|
|
214
|
-
|
|
215
|
-
known_instances.update(instances)
|
|
200
|
+
return set(
|
|
201
|
+
funcy.pluck(
|
|
202
|
+
'instance',
|
|
203
|
+
self.stored_query('instances.sparql', iri=self.iri),
|
|
204
|
+
),
|
|
205
|
+
)
|
|
216
206
|
|
|
217
207
|
def show(self) -> Widget:
|
|
218
208
|
"""Render the instances list."""
|
|
219
209
|
return InstancesBody(
|
|
220
210
|
PageTitle(self.iri),
|
|
221
211
|
InstancesList(
|
|
222
|
-
instances=self.stream_instances(),
|
|
212
|
+
instances=list(self.stream_instances()),
|
|
223
213
|
parent_class=self.iri,
|
|
224
214
|
),
|
|
225
|
-
Bottom('Select the last element to try loading more instances.'),
|
|
226
215
|
)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
from rich.markdown import Markdown
|
|
4
|
+
from textual.containers import Vertical
|
|
5
|
+
from yarl import URL
|
|
6
|
+
|
|
7
|
+
from iolanta import Facet
|
|
8
|
+
from iolanta.facets.page_title import PageTitle
|
|
9
|
+
from iolanta.widgets.description import Description
|
|
10
|
+
|
|
11
|
+
TEXT = """
|
|
12
|
+
**😕 Iolanta is unable to visualize this resource**
|
|
13
|
+
|
|
14
|
+
* The URI might be incorrect;
|
|
15
|
+
* Or, no edges might exist which involve it;
|
|
16
|
+
* Or maybe Iolanta does not know of such edges.
|
|
17
|
+
{content}
|
|
18
|
+
**What can you do?**
|
|
19
|
+
|
|
20
|
+
* If you feel this might indicate a bug 🐛, please do let us know at GitHub
|
|
21
|
+
issues: https://github.com/iolanta.tech/iolanta/issues
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
CONTENT_TEMPLATE = """
|
|
25
|
+
**File content**
|
|
26
|
+
|
|
27
|
+
```{type}
|
|
28
|
+
{content}
|
|
29
|
+
```
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class TextualNoFacetFound(Facet):
|
|
34
|
+
"""Facet to handle the case when no facet is found."""
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def raw_content(self):
|
|
38
|
+
"""Content of the file, if applicable."""
|
|
39
|
+
url = URL(self.uriref)
|
|
40
|
+
if url.scheme != 'file':
|
|
41
|
+
return None
|
|
42
|
+
|
|
43
|
+
path = Path(url.path)
|
|
44
|
+
if not path.is_relative_to(self.iolanta.project_root):
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
if not path.exists():
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
if path.is_dir():
|
|
51
|
+
return None
|
|
52
|
+
|
|
53
|
+
file_content = path.read_text()
|
|
54
|
+
return CONTENT_TEMPLATE.format(
|
|
55
|
+
content=file_content,
|
|
56
|
+
type={
|
|
57
|
+
'.yamlld': 'yaml',
|
|
58
|
+
}.get(path.suffix, ''),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
def show(self):
|
|
62
|
+
"""Compose the page."""
|
|
63
|
+
return Vertical(
|
|
64
|
+
PageTitle(self.this),
|
|
65
|
+
Description(
|
|
66
|
+
Markdown(TEXT.format(content=self.raw_content or '')),
|
|
67
|
+
),
|
|
68
|
+
)
|
iolanta/iolanta.py
CHANGED
|
@@ -28,7 +28,6 @@ from yaml_ld.errors import YAMLLDError
|
|
|
28
28
|
|
|
29
29
|
from iolanta import entry_points, namespaces
|
|
30
30
|
from iolanta.conversions import path_to_iri
|
|
31
|
-
from iolanta.cyberspace.processor import normalize_term
|
|
32
31
|
from iolanta.errors import UnresolvedIRI
|
|
33
32
|
from iolanta.facets.errors import FacetError
|
|
34
33
|
from iolanta.facets.facet import Facet
|
|
@@ -53,6 +52,7 @@ from iolanta.query_result import (
|
|
|
53
52
|
format_query_bindings,
|
|
54
53
|
)
|
|
55
54
|
from iolanta.resolvers.python_import import PythonImportResolver
|
|
55
|
+
from iolanta.sparqlspace.processor import normalize_term
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
class LoggerProtocol(Protocol):
|
|
@@ -161,7 +161,7 @@ class Iolanta: # noqa: WPS214
|
|
|
161
161
|
try:
|
|
162
162
|
sparql_result: SPARQLResult = self.graph.query(
|
|
163
163
|
query_text,
|
|
164
|
-
processor='
|
|
164
|
+
processor='sparqlspace',
|
|
165
165
|
initBindings=kwargs,
|
|
166
166
|
)
|
|
167
167
|
except ParseException as err:
|
|
@@ -259,7 +259,7 @@ class Iolanta: # noqa: WPS214
|
|
|
259
259
|
)
|
|
260
260
|
|
|
261
261
|
if not quads:
|
|
262
|
-
self.logger.
|
|
262
|
+
self.logger.info(f'{source_file} | No data found')
|
|
263
263
|
continue
|
|
264
264
|
|
|
265
265
|
quad_tuples = [
|
iolanta/parse_quads.py
CHANGED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
from enum import StrEnum
|
|
2
|
+
from typing import Annotated
|
|
3
|
+
|
|
4
|
+
import rich
|
|
5
|
+
from rdflib import Node
|
|
6
|
+
from rdflib.query import Result
|
|
7
|
+
from rich.table import Table
|
|
8
|
+
from typer import Option, Typer
|
|
9
|
+
|
|
10
|
+
from iolanta.sparqlspace.sparqlspace import SPARQLSpace
|
|
11
|
+
|
|
12
|
+
app = Typer()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class OutputFormat(StrEnum):
|
|
16
|
+
"""Output formats for the query command."""
|
|
17
|
+
|
|
18
|
+
CSV = 'csv' # noqa: WPS115
|
|
19
|
+
JSON = 'json' # noqa: WPS115
|
|
20
|
+
TABLE = 'table' # noqa: WPS115
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _format_node(node: Node):
|
|
24
|
+
return node
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _format_result(query_result: Result, output_format: OutputFormat):
|
|
28
|
+
match output_format:
|
|
29
|
+
case OutputFormat.CSV:
|
|
30
|
+
return query_result.serialize(format='csv').decode()
|
|
31
|
+
|
|
32
|
+
case OutputFormat.JSON:
|
|
33
|
+
return query_result.serialize(format='json').decode()
|
|
34
|
+
|
|
35
|
+
case OutputFormat.TABLE:
|
|
36
|
+
table = Table(*query_result.vars)
|
|
37
|
+
for row in query_result:
|
|
38
|
+
table.add_row(
|
|
39
|
+
*[
|
|
40
|
+
_format_node(node)
|
|
41
|
+
for node in row
|
|
42
|
+
],
|
|
43
|
+
)
|
|
44
|
+
return table
|
|
45
|
+
|
|
46
|
+
raise NotImplementedError(f'Output format {output_format} not implemented.')
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@app.command(name='query')
|
|
50
|
+
def query_command(
|
|
51
|
+
query: str,
|
|
52
|
+
output_format: Annotated[
|
|
53
|
+
OutputFormat,
|
|
54
|
+
Option(help='Output format.'),
|
|
55
|
+
] = OutputFormat.TABLE,
|
|
56
|
+
):
|
|
57
|
+
"""Execute a SPARQL query."""
|
|
58
|
+
query_result = SPARQLSpace().query(query)
|
|
59
|
+
rich.print(
|
|
60
|
+
_format_result(
|
|
61
|
+
query_result=query_result,
|
|
62
|
+
output_format=output_format,
|
|
63
|
+
),
|
|
64
|
+
)
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import dataclasses
|
|
2
2
|
import datetime
|
|
3
|
-
import itertools
|
|
4
3
|
import re
|
|
5
4
|
import time
|
|
6
5
|
from pathlib import Path
|
|
@@ -13,9 +12,11 @@ import funcy
|
|
|
13
12
|
import loguru
|
|
14
13
|
import platformdirs
|
|
15
14
|
import reasonable
|
|
15
|
+
import requests
|
|
16
16
|
import yaml_ld
|
|
17
17
|
from nanopub import NanopubClient
|
|
18
|
-
from rdflib import ConjunctiveGraph, Namespace, URIRef, Variable
|
|
18
|
+
from rdflib import ConjunctiveGraph, Dataset, Namespace, URIRef, Variable
|
|
19
|
+
from rdflib.namespace import RDF as original_RDF
|
|
19
20
|
from rdflib.plugins.sparql.algebra import translateQuery
|
|
20
21
|
from rdflib.plugins.sparql.evaluate import evalQuery
|
|
21
22
|
from rdflib.plugins.sparql.parser import parseQuery
|
|
@@ -23,6 +24,7 @@ from rdflib.plugins.sparql.parserutils import CompValue
|
|
|
23
24
|
from rdflib.plugins.sparql.sparql import Query
|
|
24
25
|
from rdflib.query import Processor
|
|
25
26
|
from rdflib.term import BNode, Literal, Node
|
|
27
|
+
from requests import HTTPError
|
|
26
28
|
from requests.exceptions import ConnectionError
|
|
27
29
|
from yaml_ld.document_loaders.content_types import ParserNotFound
|
|
28
30
|
from yaml_ld.errors import NotFound, YAMLLDError
|
|
@@ -97,13 +99,16 @@ def find_retractions_for(nanopublication: URIRef) -> set[URIRef]:
|
|
|
97
99
|
)
|
|
98
100
|
client.grlc_urls = [use_server]
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
'http://',
|
|
104
|
-
),
|
|
102
|
+
http_url = str(nanopublication).replace(
|
|
103
|
+
'https://',
|
|
104
|
+
'http://',
|
|
105
105
|
)
|
|
106
106
|
|
|
107
|
+
try:
|
|
108
|
+
retractions = client.find_retractions_of(http_url)
|
|
109
|
+
except HTTPError:
|
|
110
|
+
return set()
|
|
111
|
+
|
|
107
112
|
return {URIRef(retraction) for retraction in retractions}
|
|
108
113
|
|
|
109
114
|
|
|
@@ -293,6 +298,79 @@ def apply_redirect(source: URIRef) -> URIRef:
|
|
|
293
298
|
return source
|
|
294
299
|
|
|
295
300
|
|
|
301
|
+
def extract_triples(algebra: CompValue) -> Iterable[tuple[Node, Node, Node]]:
|
|
302
|
+
"""Extract triples from a SPARQL query algebra instance."""
|
|
303
|
+
if isinstance(algebra, CompValue):
|
|
304
|
+
for key, value in algebra.items(): # noqa: WPS110
|
|
305
|
+
if key == 'triples':
|
|
306
|
+
yield from value
|
|
307
|
+
|
|
308
|
+
else:
|
|
309
|
+
yield from extract_triples(value)
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
@dataclasses.dataclass(frozen=True)
|
|
313
|
+
class NanopubQueryPlugin:
|
|
314
|
+
"""Import additional information from Nanopublications Registry."""
|
|
315
|
+
|
|
316
|
+
graph: Dataset
|
|
317
|
+
|
|
318
|
+
def __call__(self, query: Query, bindings: dict[str, Any]):
|
|
319
|
+
"""Get stuff from Nanopub Registry, if it makes sense."""
|
|
320
|
+
class_uris = resolve_variables(
|
|
321
|
+
set(self._find_classes(query.algebra)),
|
|
322
|
+
bindings,
|
|
323
|
+
)
|
|
324
|
+
for class_uri in class_uris:
|
|
325
|
+
if self._is_from_nanopubs(class_uri):
|
|
326
|
+
self._load_instances(class_uri)
|
|
327
|
+
|
|
328
|
+
def _find_classes(self, algebra: CompValue) -> Iterable[URIRef]:
|
|
329
|
+
triples = extract_triples(algebra)
|
|
330
|
+
for _subject, potential_type, potential_class in triples:
|
|
331
|
+
if potential_type == original_RDF.type:
|
|
332
|
+
yield potential_class
|
|
333
|
+
|
|
334
|
+
@funcy.retry(errors=HTTPError, tries=3, timeout=3)
|
|
335
|
+
def _load_instances(self, class_uri: URIRef):
|
|
336
|
+
"""
|
|
337
|
+
Load instances from Nanopub Registry.
|
|
338
|
+
|
|
339
|
+
FIXME: Can we cache this?
|
|
340
|
+
"""
|
|
341
|
+
response = requests.post( # noqa: S113
|
|
342
|
+
'https://query.knowledgepixels.com/repo/full',
|
|
343
|
+
data={
|
|
344
|
+
'query': 'CONSTRUCT WHERE { ?instance a <%s> }' % class_uri,
|
|
345
|
+
},
|
|
346
|
+
headers={
|
|
347
|
+
'Accept': 'application/ld+json',
|
|
348
|
+
},
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
response.raise_for_status()
|
|
352
|
+
|
|
353
|
+
self.graph.get_context(BNode()).parse(
|
|
354
|
+
data=response.text,
|
|
355
|
+
format='json-ld',
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
def _is_from_nanopubs(self, class_uri: URIRef) -> bool:
|
|
359
|
+
if not isinstance(class_uri, URIRef):
|
|
360
|
+
raise ValueError(f'Not a URIRef: {class_uri}')
|
|
361
|
+
|
|
362
|
+
return self.graph.query( # noqa: WPS462
|
|
363
|
+
"""
|
|
364
|
+
ASK WHERE {
|
|
365
|
+
?_whatever <https://purl.org/nanopub/x/introduces> $class
|
|
366
|
+
}
|
|
367
|
+
""",
|
|
368
|
+
initBindings={
|
|
369
|
+
'class': class_uri,
|
|
370
|
+
},
|
|
371
|
+
).askAnswer
|
|
372
|
+
|
|
373
|
+
|
|
296
374
|
@dataclasses.dataclass(frozen=True)
|
|
297
375
|
class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
|
|
298
376
|
"""
|
|
@@ -401,25 +479,27 @@ class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
|
|
|
401
479
|
parse_tree = parseQuery(strOrQuery)
|
|
402
480
|
query = translateQuery(parse_tree, base, initNs)
|
|
403
481
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
482
|
+
self.load_retracting_nanopublications_by_query(
|
|
483
|
+
query=query,
|
|
484
|
+
bindings=initBindings,
|
|
485
|
+
base=base,
|
|
486
|
+
namespaces=initNs,
|
|
487
|
+
)
|
|
410
488
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
489
|
+
query, urls = extract_mentioned_urls_from_query(
|
|
490
|
+
query=query,
|
|
491
|
+
bindings=initBindings,
|
|
492
|
+
base=base,
|
|
493
|
+
namespaces=initNs,
|
|
494
|
+
)
|
|
417
495
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
496
|
+
for url in urls:
|
|
497
|
+
try:
|
|
498
|
+
self.load(url)
|
|
499
|
+
except Exception as err:
|
|
500
|
+
self.logger.error(f'Failed to load {url}: {err}', url, err)
|
|
501
|
+
|
|
502
|
+
NanopubQueryPlugin(graph=self.graph)(query, bindings=initBindings)
|
|
423
503
|
|
|
424
504
|
self.maybe_apply_inference()
|
|
425
505
|
|
|
@@ -542,12 +622,6 @@ class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
|
|
|
542
622
|
path=not_found.path,
|
|
543
623
|
)
|
|
544
624
|
|
|
545
|
-
self.graph.add((
|
|
546
|
-
source_uri,
|
|
547
|
-
RDF.type,
|
|
548
|
-
IOLANTA.Graph,
|
|
549
|
-
))
|
|
550
|
-
|
|
551
625
|
self.graph.add((
|
|
552
626
|
source_uri,
|
|
553
627
|
RDF.type,
|
|
@@ -555,38 +629,18 @@ class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
|
|
|
555
629
|
source_uri,
|
|
556
630
|
))
|
|
557
631
|
|
|
558
|
-
self.graph.add((
|
|
559
|
-
IOLANTA.Graph,
|
|
560
|
-
RDF.type,
|
|
561
|
-
RDFS.Class,
|
|
562
|
-
))
|
|
563
|
-
|
|
564
632
|
self._mark_as_loaded(source_uri)
|
|
565
633
|
|
|
566
634
|
return Loaded()
|
|
567
635
|
|
|
568
636
|
except Exception as err:
|
|
569
637
|
self.logger.info(f'{source} | Failed: {err}')
|
|
570
|
-
|
|
571
|
-
self.graph.add((
|
|
572
|
-
source_uri,
|
|
573
|
-
RDF.type,
|
|
574
|
-
IOLANTA.Graph,
|
|
575
|
-
))
|
|
576
|
-
|
|
577
638
|
self.graph.add((
|
|
578
639
|
URIRef(source),
|
|
579
640
|
RDF.type,
|
|
580
641
|
IOLANTA['failed'],
|
|
581
642
|
source_uri,
|
|
582
643
|
))
|
|
583
|
-
|
|
584
|
-
self.graph.add((
|
|
585
|
-
IOLANTA.Graph,
|
|
586
|
-
RDF.type,
|
|
587
|
-
RDFS.Class,
|
|
588
|
-
))
|
|
589
|
-
|
|
590
644
|
self._mark_as_loaded(source_uri)
|
|
591
645
|
|
|
592
646
|
return Loaded()
|
|
@@ -601,18 +655,6 @@ class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
|
|
|
601
655
|
))
|
|
602
656
|
source = _resolved_source
|
|
603
657
|
|
|
604
|
-
self.graph.add((
|
|
605
|
-
source_uri,
|
|
606
|
-
RDF.type,
|
|
607
|
-
IOLANTA.Graph,
|
|
608
|
-
))
|
|
609
|
-
|
|
610
|
-
self.graph.add((
|
|
611
|
-
IOLANTA.Graph,
|
|
612
|
-
RDF.type,
|
|
613
|
-
RDFS.Class,
|
|
614
|
-
))
|
|
615
|
-
|
|
616
658
|
self._mark_as_loaded(source_uri)
|
|
617
659
|
|
|
618
660
|
try: # noqa: WPS225
|
|
@@ -647,13 +689,7 @@ class GlobalSPARQLProcessor(Processor): # noqa: WPS338, WPS214
|
|
|
647
689
|
)
|
|
648
690
|
|
|
649
691
|
if not quads:
|
|
650
|
-
self.logger.
|
|
651
|
-
self.graph.addN([(
|
|
652
|
-
source_uri,
|
|
653
|
-
RDF.type,
|
|
654
|
-
IOLANTA.Graph,
|
|
655
|
-
source_uri,
|
|
656
|
-
)])
|
|
692
|
+
self.logger.info('{source} | No data found', source=source)
|
|
657
693
|
return Loaded()
|
|
658
694
|
|
|
659
695
|
quad_tuples = [
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Annotated
|
|
5
|
+
|
|
6
|
+
import rdflib
|
|
7
|
+
from rdflib.plugins.sparql.sparql import Query
|
|
8
|
+
from rdflib.query import Result
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class SPARQLSpace:
|
|
13
|
+
"""SPARQL interface to the Web of Data."""
|
|
14
|
+
|
|
15
|
+
graph: rdflib.Dataset = field(
|
|
16
|
+
default_factory=functools.partial(
|
|
17
|
+
rdflib.Dataset,
|
|
18
|
+
default_union=True,
|
|
19
|
+
),
|
|
20
|
+
)
|
|
21
|
+
path: Annotated[
|
|
22
|
+
Path | None,
|
|
23
|
+
'Local directory to load into the graph.',
|
|
24
|
+
] = None
|
|
25
|
+
|
|
26
|
+
def query(self, query: str | Query, **bindings) -> Result:
|
|
27
|
+
"""Execute a SPARQL query."""
|
|
28
|
+
return self.graph.query(
|
|
29
|
+
query_object=query,
|
|
30
|
+
processor='sparqlspace',
|
|
31
|
+
initBindings=bindings,
|
|
32
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: iolanta
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.6
|
|
4
4
|
Summary: Semantic Web browser
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Anatoly Scherbakov
|
|
@@ -32,7 +32,7 @@ Requires-Dist: rich (>=13.3.1)
|
|
|
32
32
|
Requires-Dist: textual (>=0.83.0)
|
|
33
33
|
Requires-Dist: typer (>=0.9.0)
|
|
34
34
|
Requires-Dist: watchfiles (>=1.0.4,<2.0.0)
|
|
35
|
-
Requires-Dist: yaml-ld (>=1.1.
|
|
35
|
+
Requires-Dist: yaml-ld (>=1.1.9)
|
|
36
36
|
Requires-Dist: yarl (>=1.9.4)
|
|
37
37
|
Description-Content-Type: text/markdown
|
|
38
38
|
|
|
@@ -6,20 +6,17 @@ iolanta/cli/formatters/choose.py,sha256=LWzsO_9IBSSgYNIyLlItkp8TNvpW3v6YCQ8-6kbI
|
|
|
6
6
|
iolanta/cli/formatters/csv.py,sha256=ceJ_DTz0beqeK-d6FPBQqqjXrziEfF0FRSLoGZCt_fs,760
|
|
7
7
|
iolanta/cli/formatters/json.py,sha256=Og5B9UrSM_0NWqW5Afpsy6WH8ZfYgPMVXYvT3i-43Jc,748
|
|
8
8
|
iolanta/cli/formatters/pretty.py,sha256=IypZRAr2vNqcXFY6NOIc75mpyfpFWh56aCBlOPDDieQ,2901
|
|
9
|
-
iolanta/cli/main.py,sha256=
|
|
9
|
+
iolanta/cli/main.py,sha256=W1SoQK9kncaSUsy4X5yMrzu8lQUlu-eE6YyIu4dNnec,3167
|
|
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
|
|
13
13
|
iolanta/conversions.py,sha256=hbLwRF1bAbOxy17eMWLHhYksbdCWN-v4-0y0wn3XSSg,1185
|
|
14
|
-
iolanta/cyberspace/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
iolanta/cyberspace/inference/wikibase-claim.sparql,sha256=JSawj3VTc9ZPoU9mvh1w1AMYb3cWyZ3x1rEYWUsKZ6A,209
|
|
16
|
-
iolanta/cyberspace/inference/wikibase-statement-property.sparql,sha256=SkSHZZlxWVDwBM3aLo0Q7hLuOj9BsIQnXtcuAuwaxqU,240
|
|
17
|
-
iolanta/cyberspace/processor.py,sha256=USGe54XuNMNYYl-Hed1bKxeqZLUhrb1jNRUDbWpay4A,21990
|
|
18
14
|
iolanta/data/cli.yaml,sha256=TsnldYXoY5GIzoNuPDvwBKGw8eAEForZW1FCKqKI0Kg,1029
|
|
19
|
-
iolanta/data/context.yaml,sha256=
|
|
15
|
+
iolanta/data/context.yaml,sha256=LUBasiBKgQeGAYjYV_T5XvgPlrdzACeKaZwY_rKzjtI,1636
|
|
16
|
+
iolanta/data/graph-triples.yamlld,sha256=oACKRwqWcMp6TBobXMG6gbbnaauyd6wlK-gH2vVkPps,241
|
|
20
17
|
iolanta/data/html.yaml,sha256=hVFdLWLy8FMY8xpOrJMYc-tE3S0Nq83xuxVkjRW_7rI,517
|
|
21
18
|
iolanta/data/iolanta.yaml,sha256=xubIFBNU02lmFXhgOSuyQwUcZD3xCqVfeVAZMvOxKbI,1433
|
|
22
|
-
iolanta/data/textual-browser.yaml,sha256=
|
|
19
|
+
iolanta/data/textual-browser.yaml,sha256=SajFDOdqISVLsBVneS3uh3s8vuYAUIuC0nWvVqIWMZ0,4141
|
|
23
20
|
iolanta/ensure_is_context.py,sha256=9aok8asyEx7KPesOR28VBDb3Ch9kfc3eoCpQSJwj07U,717
|
|
24
21
|
iolanta/entry_points.py,sha256=DZbf-udlEwELFGqeWENj0M2BOUPOWlmGJdqyaEtnot0,504
|
|
25
22
|
iolanta/errors.py,sha256=t_RltahnoEvcytVa1BOq2MADgHps3JNd_h5-SFu7_wM,1250
|
|
@@ -45,7 +42,7 @@ iolanta/facets/html/base.py,sha256=JcpK7YM_QQE9vwH5w5F_EgPkPv-XRzOrcZlVSy4LhIs,1
|
|
|
45
42
|
iolanta/facets/html/code_literal.py,sha256=qCddzBrg6Y5XMIKohFQ52Tf9GPOcU7bj83tfAU1FLLU,394
|
|
46
43
|
iolanta/facets/html/default.py,sha256=Dmf_kYiL2M954iigyYsiWrMstwZ1nvxKetuR6aW3xYY,647
|
|
47
44
|
iolanta/facets/icon.py,sha256=ddZcolx1Q5_wo3w0jqiCzcc5Lsru6-jA7s7oAd1T8Og,494
|
|
48
|
-
iolanta/facets/locator.py,sha256=
|
|
45
|
+
iolanta/facets/locator.py,sha256=b9TEK5_5SklTfEc6lUt7DJt1mKXsiL_urA2zxMk59EY,9152
|
|
49
46
|
iolanta/facets/page_title.py,sha256=TwgZK2g_e5UoWYjKNgDzzkmq1EI3cY58680iC8N9kZI,1407
|
|
50
47
|
iolanta/facets/qname.py,sha256=ztyBbjjcW8dNZzuiNMqhcWfAUxk-gSjbseVGrQE7kVY,531
|
|
51
48
|
iolanta/facets/textual_browser/__init__.py,sha256=sKgDvXOwib9n9d63kdtKCEv26-FoL0VN6zxDmfcheZ8,104
|
|
@@ -58,8 +55,8 @@ iolanta/facets/textual_browser/models.py,sha256=DqTBjhkkTt5mNwqr4DzNbPSqzV-QtNqf
|
|
|
58
55
|
iolanta/facets/textual_browser/page.py,sha256=NkcQ5rSKZRbp63C8ozgsR_iVhcKHGv_SytUCQyGa7ss,786
|
|
59
56
|
iolanta/facets/textual_browser/page_switcher.py,sha256=WOsFY9hSFEnuf3za1eCUhPaQ6uTaeBuMPIAHjHhnvDY,9950
|
|
60
57
|
iolanta/facets/textual_class/__init__.py,sha256=tiL0p-3JspGcBRj4qa3rmoBFAuadk71l2ja2lJN6CEs,75
|
|
61
|
-
iolanta/facets/textual_class/facets.py,sha256=
|
|
62
|
-
iolanta/facets/textual_class/sparql/instances.sparql,sha256=
|
|
58
|
+
iolanta/facets/textual_class/facets.py,sha256=tascZiue3tbYfpIsnP8yY2dgXQIQzoQ_HPzU7DbVbao,5999
|
|
59
|
+
iolanta/facets/textual_class/sparql/instances.sparql,sha256=EW4BmuNxiRDA8djuEtvZpLLJlNSIshvId4ExlaYPcZE,106
|
|
63
60
|
iolanta/facets/textual_default/__init__.py,sha256=snxA0FEY9qfAxNv3MlZLrJsXugD4dvs5hLStZWV7soM,158
|
|
64
61
|
iolanta/facets/textual_default/facets.py,sha256=Pf5GttQ7EG0ZodjwwVXzYMffHus3MAZdJUIcbddcYtw,4738
|
|
65
62
|
iolanta/facets/textual_default/sparql/inverse-properties.sparql,sha256=daHNdhmh92Q77CSf7ULbhxg57CuYsRFfMnXQz4VYEug,64
|
|
@@ -82,6 +79,7 @@ iolanta/facets/textual_nanopublication/models.py,sha256=MphggSvKmYac6v866GOKW5lc
|
|
|
82
79
|
iolanta/facets/textual_nanopublication/nanopublication_widget.py,sha256=sQPgEx25XJ15VqB5zjZuz2q2bf_B5GWXEp32FAufxQ4,2387
|
|
83
80
|
iolanta/facets/textual_nanopublication/term_list_widget.py,sha256=NZNATKjFmgI2sE5R0ebyQh5Qk2g-kf-MT4YZ-Vw78M4,992
|
|
84
81
|
iolanta/facets/textual_nanopublication/term_widget.py,sha256=uI5msCTSIYumAIS3I8nBfUz57_vRzvCKkouevrS3Qwk,3536
|
|
82
|
+
iolanta/facets/textual_no_facet_found.py,sha256=gYRSAYDX0t6EHln0S8msLZE27Svfef8iPVfZQ3Vf8Ns,1625
|
|
85
83
|
iolanta/facets/textual_ontology/__init__.py,sha256=3H6bfYaEbXFr90C6ZpGWC4O-24uaO18tnTXx7mckQSA,94
|
|
86
84
|
iolanta/facets/textual_ontology/facets.py,sha256=60g8ANmePb9_i_-d4ui-FdtNwg9aktrOKXHkTQtLp1w,3338
|
|
87
85
|
iolanta/facets/textual_ontology/sparql/terms.sparql,sha256=oVLxN452nqog_95qRaTWnvar6rxPNxPrRonSo7oFFTg,324
|
|
@@ -97,7 +95,7 @@ iolanta/facets/title/sparql/title.sparql,sha256=4rz47tjwX2OJavWMzftaYKil1-ZHB76Z
|
|
|
97
95
|
iolanta/facets/wikibase_statement_title/__init__.py,sha256=_yk1akxgSJOiUBJIc8QGrD2vovvmx_iw_vJDuv1rD7M,91
|
|
98
96
|
iolanta/facets/wikibase_statement_title/facets.py,sha256=mUH7twlAgoeX7DgLQuRBQv4ORT6GWbN-0eJ1aliSfiQ,724
|
|
99
97
|
iolanta/facets/wikibase_statement_title/sparql/statement-title.sparql,sha256=n07DQWxKqB5c3CA4kacq2HSN0R0dLgnMnLP1AxMo5YA,320
|
|
100
|
-
iolanta/iolanta.py,sha256=
|
|
98
|
+
iolanta/iolanta.py,sha256=wCt_7aUz9TOvZTJvpJQ-qVWkOpmM531uyxIk9l3n-lk,14229
|
|
101
99
|
iolanta/loaders/__init__.py,sha256=QTiKCsQc1BTS-IlY2CQsN9iVpEIPqYFvI9ERMYVZCbU,99
|
|
102
100
|
iolanta/loaders/base.py,sha256=-DxYwqG1bfDXB2p_S-mKpkc_3Sh14OHhePbe65Iq3-s,3381
|
|
103
101
|
iolanta/loaders/data_type_choice.py,sha256=zRUXBIzjvuW28P_dhMDVevE9C8EFEIx2_X39WydWrtM,1982
|
|
@@ -110,7 +108,7 @@ iolanta/loaders/scheme_choice.py,sha256=GHA4JAD-Qq3uNdej4vs_bCrN1WMRshVRvOMxaYyP
|
|
|
110
108
|
iolanta/models.py,sha256=L0iFaga4-PCaWP18WmT03NLK_oT7q49V0WMTQskoffI,2824
|
|
111
109
|
iolanta/namespaces.py,sha256=fyWDCGPwU8Cs8d-Vmci4H0-fuIe7BMSevvEKFvG7Gf4,1153
|
|
112
110
|
iolanta/node_to_qname.py,sha256=a82_qpgT87cbekY_76tTkl4Z-6Rz6am4UGIQChUf9Y0,794
|
|
113
|
-
iolanta/parse_quads.py,sha256=
|
|
111
|
+
iolanta/parse_quads.py,sha256=2UydATeDassOrpjWfjwWnMjnSS5RZw5KBFIeKHGJ36M,2660
|
|
114
112
|
iolanta/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
115
113
|
iolanta/parsers/base.py,sha256=ZFjj0BLzW4985BdC6PwbngenhMuSYW5mNLpprZRWjhA,1048
|
|
116
114
|
iolanta/parsers/dict_parser.py,sha256=t_OK2meUh49DqSaOYkSgEwxMKUNNgjJY8rZAyL4NQKI,4546
|
|
@@ -125,9 +123,16 @@ iolanta/resolvers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
|
125
123
|
iolanta/resolvers/base.py,sha256=cc9bcrVZ0wTwn85I-IYCwcIRU5Lwaph8D00C0dwSOm8,302
|
|
126
124
|
iolanta/resolvers/python_import.py,sha256=kDOhApBDFfxnrDgK9M7ztMkqXfcny81Zo86FgPFb-LI,1301
|
|
127
125
|
iolanta/shortcuts.py,sha256=j8b0E_yeoas8GumsPOfxO2v2jO0noqpmKJ6LFxFfsu4,1892
|
|
126
|
+
iolanta/sparqlspace/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
127
|
+
iolanta/sparqlspace/cli.py,sha256=pb6q03lzrU8OaZ4A3QAQEmaFYcQ_-sHUrPhRs6GE88w,1590
|
|
128
|
+
iolanta/sparqlspace/inference/wikibase-claim.sparql,sha256=JSawj3VTc9ZPoU9mvh1w1AMYb3cWyZ3x1rEYWUsKZ6A,209
|
|
129
|
+
iolanta/sparqlspace/inference/wikibase-statement-property.sparql,sha256=SkSHZZlxWVDwBM3aLo0Q7hLuOj9BsIQnXtcuAuwaxqU,240
|
|
130
|
+
iolanta/sparqlspace/processor.py,sha256=CXxdi7ORpddXxPh0UlnRG7oqNT9q-WdSPMxqB4CgOis,23570
|
|
131
|
+
iolanta/sparqlspace/sparqlspace.py,sha256=Y8_ZPXwuGEXbEes6XQjaQWA2Zv9y8SWxMPDFdqVBGFo,796
|
|
128
132
|
iolanta/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
133
|
+
iolanta/widgets/description.py,sha256=Qj5R2wgxJzlAHU0LHyKIoZSCkGk4VBuImWIyiUallhs,215
|
|
129
134
|
iolanta/widgets/mixin.py,sha256=nDRCOc-gizCf1a5DAcYs4hW8eZEd6pHBPFsfm0ncv7E,251
|
|
130
|
-
iolanta-2.0.
|
|
131
|
-
iolanta-2.0.
|
|
132
|
-
iolanta-2.0.
|
|
133
|
-
iolanta-2.0.
|
|
135
|
+
iolanta-2.0.6.dist-info/METADATA,sha256=zqVS0cP1WoIfWm-4NCgDrrryi5uxKwILIyquK8khpGA,2230
|
|
136
|
+
iolanta-2.0.6.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
137
|
+
iolanta-2.0.6.dist-info/entry_points.txt,sha256=z9RPLmGuz3tYGPV7Qf4nNjuSJYdTUS9enC4595poe-M,221
|
|
138
|
+
iolanta-2.0.6.dist-info/RECORD,,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
[console_scripts]
|
|
2
2
|
iolanta=iolanta.cli:app
|
|
3
|
+
sparqlspace=iolanta.sparqlspace.cli:app
|
|
3
4
|
|
|
4
5
|
[iolanta.plugins]
|
|
5
6
|
base=iolanta:IolantaBase
|
|
6
7
|
|
|
7
8
|
[rdf.plugins.queryprocessor]
|
|
8
|
-
|
|
9
|
+
sparqlspace=iolanta.sparqlspace.processor:GlobalSPARQLProcessor
|
|
9
10
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|