From 2a3e3cd5e06d23420db1be27f52de7583a3e73e5 Mon Sep 17 00:00:00 2001 From: Ross Fenning Date: Mon, 17 Oct 2022 22:17:35 +0100 Subject: [PATCH] Add dangling changes --- hyperspace/__init__.py | 14 +++++++- hyperspace/affordances.py | 72 +++++++++++++++++++++++++++++++++++---- hyperspace/rdf.py | 2 +- 3 files changed, 80 insertions(+), 8 deletions(-) diff --git a/hyperspace/__init__.py b/hyperspace/__init__.py index e62a604..8c27c39 100644 --- a/hyperspace/__init__.py +++ b/hyperspace/__init__.py @@ -37,7 +37,6 @@ def response_to_page(response): def jump(url, client=None): - print('Jumping: ' + url) response = get_client(client).get(url) return response_to_page(response) @@ -57,3 +56,16 @@ def mime_to_page(mime, **kwargs): 'text/turtle': TurtlePage, }[mime] + +def git(command, *args, **params): + return { + 'commit': git_commit, + 'checkout': git_checkout, + }[command](*args, **params) + + +def update(uri, _store): + print('Updating: ' + uri) + response = get_client().put(uri, _store.serialize(format='turtle'), headers={'Content-Type': 'text/turtle'}) + print(response.text) + return response_to_page(response) diff --git a/hyperspace/affordances.py b/hyperspace/affordances.py index 134dccf..b336e72 100644 --- a/hyperspace/affordances.py +++ b/hyperspace/affordances.py @@ -2,10 +2,11 @@ from urllib import parse as urlparse except ImportError: import urlparse -from uritemplate import expand +from uritemplate import expand, variables import hyperspace -from rdflib import Graph -from laconia import ThingFactory +from rdflib import Graph, URIRef, RDF, OWL +from laconia import ThingFactory, Thing +import yarl class FilterableList(list): @@ -13,18 +14,31 @@ def __init__(self, base_url=None): self.base_url = base_url def __getitem__(self, item_name): + if isinstance(item_name, int): + return list.__getitem__(self, item_name) if self.base_url: item_name = urlparse.urljoin(self.base_url, item_name) matches = [item for item in self if item.name == item_name] if matches: - return matches + if len(matches) == 1: + return matches[0] + else: + return matches else: other_names = ','.join({item.name for item in self}) raise KeyError( 'No item with name "{name}". Available: {other_names} (Using base URL: {base})'.format( name=item_name, other_names=other_names, base=self.base_url)) + def __add__(self, other): + new = FilterableList(base_url=self.base_url) + for item in self: + new.append(item) + for item in other: + new.append(item) + return new + def keys(self): return set(sorted(item.name for item in self)) @@ -58,6 +72,9 @@ def submit(self): """Very naive URL creation.""" return hyperspace.jump(self.uri) + def __call__(self, **params): + return self.build(params).submit() + def __unicode__(self): return self.__str__() @@ -65,6 +82,9 @@ def __str__(self): return u'[{name}]({href})'.format( name=self.name, href=self.uri_template) + def keys(self): + return variables(self.uri_template) + class Template(object): def __init__(self, name, href, params, content_type): @@ -91,6 +111,20 @@ def __str__(self): name=self.name, href=self.href, params=flat_params) +class Entity(Thing): + def update(self): + return hyperspace.update(self._id, self._store) + + def follow(self): + print('Following: ' + str(self._id)) + return hyperspace.jump(str(self._id)) + + +class EntityFactory(ThingFactory): + def __call__(self, ident=None, **props): + return Entity(self.store, self.schema_store, self.alias_map, ident, props) + + class Page(object): def __init__(self, response): self.response = response @@ -116,8 +150,34 @@ def extract_templates(self): def entity(self, uri): self.data.bind('schema', 'http://schema.org/', override=True) - Thing = ThingFactory(self.data) - return Thing(uri) + return EntityFactory(self.data)(uri) + + @property + def entities(self): + thing = URIRef(urlparse.urljoin(self.response.url, '/vocab#Thing')) + return [EntityFactory(self.data)(uri) + for uri in self.data.subjects(predicate=RDF.type, object=thing)] + + def __getattr__(self, item): + try: + item_url = str(yarl.URL(self.url).with_fragment(item)) + return self.queries[item_url] + except KeyError: + print(self.data.serialize(format='turtle').decode('utf-8')) + raise + + def __getitem__(self, item): + if type(item) == int: + try: + return self.entities[item] + except IndexError: + print('Cannot find entity in: ' + self.data.serialize(format='turtle').decode('utf-8')) + raise + else: + if item in self.data.subjects(): + return self.entity(item) + else: + return self.templates[item] def __str__(self): return u'Page:\n\tData:\n{data}\n\tLinks:\n\t\t{links}\n\tQueries:\n\t\t{queries}\n\tTemplates:\n\t\t{templates}'.format( diff --git a/hyperspace/rdf.py b/hyperspace/rdf.py index 7a300e0..e5d0b65 100644 --- a/hyperspace/rdf.py +++ b/hyperspace/rdf.py @@ -31,7 +31,7 @@ def extract_queries(self): PREFIX rdf: PREFIX schema: PREFIX hydra: - SELECT ?rel ?template + SELECT DISTINCT ?rel ?template WHERE { ?url ?rel ?action . ?action rdf:type hydra:IriTemplate .