diff --git a/nomadnet/Node.py b/nomadnet/Node.py index 018d43b..13e1f41 100644 --- a/nomadnet/Node.py +++ b/nomadnet/Node.py @@ -97,7 +97,7 @@ class Node: for directory in directories: self.scan_files(base_path+"/"+directory) - def serve_page(self, path, data, request_id, remote_identity, requested_at): + def serve_page(self, path, data, request_id, link_id, remote_identity, requested_at): RNS.log("Page request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_VERBOSE) try: self.app.peer_settings["served_page_requests"] += 1 @@ -152,7 +152,18 @@ class Node: if request_allowed: RNS.log("Serving page: "+file_path, RNS.LOG_VERBOSE) if os.access(file_path, os.X_OK): - generated = subprocess.run([file_path], stdout=subprocess.PIPE) + env_map = {} + if link_id != None: + env_map["link_id"] = RNS.hexrep(link_id, delimit=False) + if remote_identity != None: + env_map["remote_identity"] = RNS.hexrep(remote_identity.hash, delimit=False) + + if data != None and isinstance(data, dict): + for e in data: + if isinstance(e, str) and e.startswith("field_"): + env_map[e] = data[e] + + generated = subprocess.run([file_path], stdout=subprocess.PIPE, env=env_map) return generated.stdout else: fh = open(file_path, "rb") diff --git a/nomadnet/ui/textui/Browser.py b/nomadnet/ui/textui/Browser.py index 8b75fbd..6c3aa51 100644 --- a/nomadnet/ui/textui/Browser.py +++ b/nomadnet/ui/textui/Browser.py @@ -81,6 +81,7 @@ class Browser: self.aspects = aspects self.destination_hash = destination_hash self.path = path + self.field_data = None self.timeout = Browser.DEFAULT_TIMEOUT self.last_keypress = None @@ -161,7 +162,31 @@ class Browser: else: return destination_type - def handle_link(self, link_target): + def handle_link(self, link_target, link_fields = None): + field_data = None + if link_fields != None: + field_data = {} + def recurse_down(w): + target = None + if isinstance(w, list): + for t in w: + recurse_down(t) + elif isinstance(w, tuple): + for t in w: + recurse_down(t) + elif hasattr(w, "contents"): + recurse_down(w.contents) + elif hasattr(w, "original_widget"): + recurse_down(w.original_widget) + elif hasattr(w, "_original_widget"): + recurse_down(w._original_widget) + else: + if hasattr(w, "field_name") and (link_fields == "all" or w.field_name in link_fields): + field_data["field_"+w.field_name] = w.get_edit_text() + + recurse_down(self.attr_maps) + RNS.log("Found field data: "+str(field_data)) + components = link_target.split("@") destination_type = None @@ -177,7 +202,7 @@ class Browser: RNS.log("Browser handling link to: "+str(link_target), RNS.LOG_DEBUG) self.browser_footer = urwid.Text("Opening link to: "+str(link_target)) try: - self.retrieve_url(link_target) + self.retrieve_url(link_target, field_data) except Exception as e: self.browser_footer = urwid.Text("Could not open link: "+str(e)) self.frame.contents["footer"] = (self.browser_footer, self.frame.options()) @@ -365,7 +390,7 @@ class Browser: self.update_display() - def retrieve_url(self, url): + def retrieve_url(self, url, field_data = None): self.previous_destination_hash = self.destination_hash self.previous_path = self.path @@ -418,6 +443,7 @@ class Browser: else: self.set_destination_hash(destination_hash) self.set_path(path) + self.set_field_data(field_data) self.load_page() def set_destination_hash(self, destination_hash): @@ -431,6 +457,8 @@ class Browser: def set_path(self, path): self.path = path + def set_field_data(self, field_data): + self.field_data = field_data def set_timeout(self, timeout): self.timeout = timeout @@ -637,7 +665,11 @@ class Browser: def load_page(self): - cached = self.get_cached(self.current_url()) + if self.field_data == None: + cached = self.get_cached(self.current_url()) + else: + cached = None + if cached: self.status = Browser.DONE self.page_data = cached @@ -671,7 +703,11 @@ class Browser: page_data = b"The requested local page did not exist in the file system" if os.path.isfile(page_path): if os.access(page_path, os.X_OK): - generated = subprocess.run([page_path], stdout=subprocess.PIPE) + if self.field_data != None: + env_map = self.field_data + else: + env_map = None + generated = subprocess.run([page_path], stdout=subprocess.PIPE, env=env_map) page_data = generated.stdout else: file = open(page_path, "rb") @@ -758,7 +794,7 @@ class Browser: self.update_display() receipt = self.link.request( self.path, - data = None, + data = self.field_data, response_callback = self.response_received, failed_callback = self.request_failed, progress_callback = self.response_progressed diff --git a/nomadnet/ui/textui/MicronParser.py b/nomadnet/ui/textui/MicronParser.py index fc1a6ec..917808c 100644 --- a/nomadnet/ui/textui/MicronParser.py +++ b/nomadnet/ui/textui/MicronParser.py @@ -462,49 +462,52 @@ def make_output(state, line, url_delegate): state["align"] = state["default_align"] elif c == "<": - field_name = None - field_name_end = line[i:].find("`") - if field_name_end == -1: - pass - else: - field_name = line[i+1:i+field_name_end] - field_name_skip = len(field_name) - field_masked = False - field_width = 24 - - if "|" in field_name: - f_components = field_name.split("|") - field_flags = f_components[0] - field_name = f_components[1] - if "!" in field_flags: - field_flags = field_flags.replace("!", "") - field_masked = True - if len(field_flags) > 0: - field_width = min(int(field_flags), 256) - - def sr(): - return "@{"+str(random.randint(1000,9999))+"}" - rsg = sr() - while rsg in line[i+field_name_end:]: - rsg = sr() - lr = line[i+field_name_end:].replace("\\>", rsg) - endpos = lr.find(">") - - if endpos == -1: + try: + field_name = None + field_name_end = line[i:].find("`") + if field_name_end == -1: pass - else: - field_data = lr[1:endpos].replace(rsg, "\\>") - skip = len(field_data)+field_name_skip+2 - field_data = field_data.replace("\\>", ">") - output.append({ - "type":"field", - "name": field_name, - "width": field_width, - "masked": field_masked, - "data": field_data, - "style": make_style(state) - }) + field_name = line[i+1:i+field_name_end] + field_name_skip = len(field_name) + field_masked = False + field_width = 24 + + if "|" in field_name: + f_components = field_name.split("|") + field_flags = f_components[0] + field_name = f_components[1] + if "!" in field_flags: + field_flags = field_flags.replace("!", "") + field_masked = True + if len(field_flags) > 0: + field_width = min(int(field_flags), 256) + + def sr(): + return "@{"+str(random.randint(1000,9999))+"}" + rsg = sr() + while rsg in line[i+field_name_end:]: + rsg = sr() + lr = line[i+field_name_end:].replace("\\>", rsg) + endpos = lr.find(">") + + if endpos == -1: + pass + + else: + field_data = lr[1:endpos].replace(rsg, "\\>") + skip = len(field_data)+field_name_skip+2 + field_data = field_data.replace("\\>", ">") + output.append({ + "type":"field", + "name": field_name, + "width": field_width, + "masked": field_masked, + "data": field_data, + "style": make_style(state) + }) + except Exception as e: + pass elif c == "[": endpos = line[i:].find("]") @@ -517,13 +520,20 @@ def make_output(state, line, url_delegate): link_components = link_data.split("`") if len(link_components) == 1: link_label = "" + link_fields = "" link_url = link_data elif len(link_components) == 2: link_label = link_components[0] link_url = link_components[1] + link_fields = "" + elif len(link_components) == 3: + link_label = link_components[0] + link_url = link_components[1] + link_fields = link_components[2] else: link_url = "" link_label = "" + link_fields = "" if len(link_url) != 0: if link_label == "": @@ -551,6 +561,14 @@ def make_output(state, line, url_delegate): if url_delegate != None: linkspec = LinkSpec(link_url, orig_spec) + if link_fields != "": + if link_fields == "*": + linkspec.link_fields = "all" + else: + lf = link_fields.split("|") + if len(lf) > 0: + linkspec.link_fields = lf + output.append((linkspec, link_label)) else: output.append(make_part(state, link_label)) @@ -593,6 +611,7 @@ def make_output(state, line, url_delegate): class LinkSpec(urwid.AttrSpec): def __init__(self, link_target, orig_spec): self.link_target = link_target + self.link_fields = None urwid.AttrSpec.__init__(self, orig_spec.foreground, orig_spec.background) @@ -611,9 +630,9 @@ class LinkableText(urwid.Text): if self.delegate != None: self.delegate.last_keypress = 0 - def handle_link(self, link_target): + def handle_link(self, link_target, link_fields): if self.delegate != None: - self.delegate.handle_link(link_target) + self.delegate.handle_link(link_target, link_fields) def find_next_part_pos(self, pos, part_positions): for position in part_positions: @@ -671,7 +690,7 @@ class LinkableText(urwid.Text): item = self.find_item_at_pos(self._cursor_position) if item != None: if isinstance(item, LinkSpec): - self.handle_link(item.link_target) + self.handle_link(item.link_target, item.link_fields) elif key == "up": self._cursor_position = 0 @@ -761,7 +780,7 @@ class LinkableText(urwid.Text): if item != None: if isinstance(item, LinkSpec): - self.handle_link(item.link_target) + self.handle_link(item.link_target, item.link_fields) self._invalidate() self._emit("change")