From 790e815e043994282669b1229b180dfeb1a68a41 Mon Sep 17 00:00:00 2001 From: Flancian <0@flancia.org> Date: Sat, 23 Jan 2021 22:30:44 +0100 Subject: [PATCH] Initial implementation of go/node0/node1 --- app/agora.py | 44 ++++++++++++++++++++++++++++++++++++++------ app/db.py | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/app/agora.py b/app/agora.py index a5dc5a4..76c7b71 100644 --- a/app/agora.py +++ b/app/agora.py @@ -84,18 +84,50 @@ def go(node): @bp.route('/push//') def push(node, other): - #import pprint - #response = [] - #response.append("node: {}".format(node)) - #response.append("other: {}".format(other)) n = G.node(node) o = G.node(other) pushing = n.pushing(o) - #response.append(pushing) - #return Response(pprint.pformat(response)) return Response(pushing) +# [default action](https://anagora.org/node/default-action) +@bp.route('/go//') +def default_action(node0, node1): + """Redirects to the URL in the given node in a block that starts with [[]], if there is one.""" + # TODO(flancian): all node-scoped stuff should move to actually use node objects. + # TODO(flancian): make [[go]] call this? + try: + n0 = db.nodes_by_wikilink(node0) + except KeyError: + return redirect("https://anagora.org/node/%s" % node0) + try: + n1 = db.nodes_by_wikilink(node1) + except KeyError: + return redirect("https://anagora.org/node/%s" % node1) + + if len(n0) == 0 and len(n1) == 0: + # No nodes with this name. + # Redirect to composite node, which might exist and provides search. + return redirect(f'https://anagora.org/node/{node0}-{node1}') + + if len(n0) != 0: + links = n0[0].filter(node1) + elif len(n1) != 0: + links += n1[0].filter(node0) + + if len(links) == 0: + # No matching links found. + # Redirect to composite node, which might exist and provides search. + # TODO(flancian): flash an explanation :) + return redirect(f'https://anagora.org/node/{node0}-{node1}') + + if len(links) > 1: + # TODO(flancian): to be implemented. + # Likely default to one of the links, show all of them but redirect to default within n seconds. + current_app.logger.warning('Code to manage nodes with more than one go link is not Not implemented.') + + return redirect(links[0]) + @bp.route('/jump') def jump(): """Redirects to a context; in "jump" mode, a node *always* exists (nodes map one to one to all possible queries).""" diff --git a/app/db.py b/app/db.py index 3add96b..ef6eac2 100644 --- a/app/db.py +++ b/app/db.py @@ -162,6 +162,13 @@ class Node: links.extend(subnode.go()) return links + def filter(self, other): + # There's surely a much better way to do this. Alas :) + links = [] + for subnode in self.subnodes: + links.extend(subnode.filter(other)) + return links + # The following section is particularly confusing. # Some functions return wikilinks, some return full blown nodes. # We probably want to converge on the latter. @@ -352,6 +359,26 @@ class Subnode: sanitized_golinks.append('https://' + golink) return sanitized_golinks + def filter(self, other): + """ + other is a string. + returns a set of links contained in this subnode + in blocks of the form: + - [[other]] protocol://example.org/url + + protocol defaults to https. + might pick up magic like resolving social network issues later :) + """ + links = subnode_to_actions(self, other, blocks_only=True) + sanitized_links = [] + for link in links: + if '://' in link: + sanitized_links.append(link) + else: + # hack hack. + sanitized_links.append('https://' + link) + return sanitized_links + def pull_nodes(self): """ returns a set of nodes pulled (anagora.org/node/pull) in this subnode @@ -401,11 +428,14 @@ class VirtualSubnode(Subnode): self.node = self.wikilink -def subnode_to_actions(subnode, action): +def subnode_to_actions(subnode, action, blocks_only=False): # hack hack. if subnode.mediatype != 'text/plain': return [] - action_regex ='\[\[' + action + '\]\] (.*?)$' + if blocks_only: + action_regex ='- \[\[' + action + '\]\] (.*?)$' + else: + action_regex ='\[\[' + action + '\]\] (.*?)$' content = subnode.content actions = [] for line in content.splitlines():