Added input field data handling

This commit is contained in:
Mark Qvist 2023-02-14 19:46:21 +01:00
parent 1378a3f6dd
commit d30f405fd5
3 changed files with 119 additions and 53 deletions

View File

@ -97,7 +97,7 @@ class Node:
for directory in directories: for directory in directories:
self.scan_files(base_path+"/"+directory) 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) RNS.log("Page request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_VERBOSE)
try: try:
self.app.peer_settings["served_page_requests"] += 1 self.app.peer_settings["served_page_requests"] += 1
@ -152,7 +152,18 @@ class Node:
if request_allowed: if request_allowed:
RNS.log("Serving page: "+file_path, RNS.LOG_VERBOSE) RNS.log("Serving page: "+file_path, RNS.LOG_VERBOSE)
if os.access(file_path, os.X_OK): 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 return generated.stdout
else: else:
fh = open(file_path, "rb") fh = open(file_path, "rb")

View File

@ -81,6 +81,7 @@ class Browser:
self.aspects = aspects self.aspects = aspects
self.destination_hash = destination_hash self.destination_hash = destination_hash
self.path = path self.path = path
self.field_data = None
self.timeout = Browser.DEFAULT_TIMEOUT self.timeout = Browser.DEFAULT_TIMEOUT
self.last_keypress = None self.last_keypress = None
@ -161,7 +162,31 @@ class Browser:
else: else:
return destination_type 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("@") components = link_target.split("@")
destination_type = None destination_type = None
@ -177,7 +202,7 @@ class Browser:
RNS.log("Browser handling link to: "+str(link_target), RNS.LOG_DEBUG) RNS.log("Browser handling link to: "+str(link_target), RNS.LOG_DEBUG)
self.browser_footer = urwid.Text("Opening link to: "+str(link_target)) self.browser_footer = urwid.Text("Opening link to: "+str(link_target))
try: try:
self.retrieve_url(link_target) self.retrieve_url(link_target, field_data)
except Exception as e: except Exception as e:
self.browser_footer = urwid.Text("Could not open link: "+str(e)) self.browser_footer = urwid.Text("Could not open link: "+str(e))
self.frame.contents["footer"] = (self.browser_footer, self.frame.options()) self.frame.contents["footer"] = (self.browser_footer, self.frame.options())
@ -365,7 +390,7 @@ class Browser:
self.update_display() 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_destination_hash = self.destination_hash
self.previous_path = self.path self.previous_path = self.path
@ -418,6 +443,7 @@ class Browser:
else: else:
self.set_destination_hash(destination_hash) self.set_destination_hash(destination_hash)
self.set_path(path) self.set_path(path)
self.set_field_data(field_data)
self.load_page() self.load_page()
def set_destination_hash(self, destination_hash): def set_destination_hash(self, destination_hash):
@ -431,6 +457,8 @@ class Browser:
def set_path(self, path): def set_path(self, path):
self.path = path self.path = path
def set_field_data(self, field_data):
self.field_data = field_data
def set_timeout(self, timeout): def set_timeout(self, timeout):
self.timeout = timeout self.timeout = timeout
@ -637,7 +665,11 @@ class Browser:
def load_page(self): 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: if cached:
self.status = Browser.DONE self.status = Browser.DONE
self.page_data = cached self.page_data = cached
@ -671,7 +703,11 @@ class Browser:
page_data = b"The requested local page did not exist in the file system" page_data = b"The requested local page did not exist in the file system"
if os.path.isfile(page_path): if os.path.isfile(page_path):
if os.access(page_path, os.X_OK): 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 page_data = generated.stdout
else: else:
file = open(page_path, "rb") file = open(page_path, "rb")
@ -758,7 +794,7 @@ class Browser:
self.update_display() self.update_display()
receipt = self.link.request( receipt = self.link.request(
self.path, self.path,
data = None, data = self.field_data,
response_callback = self.response_received, response_callback = self.response_received,
failed_callback = self.request_failed, failed_callback = self.request_failed,
progress_callback = self.response_progressed progress_callback = self.response_progressed

View File

@ -462,49 +462,52 @@ def make_output(state, line, url_delegate):
state["align"] = state["default_align"] state["align"] = state["default_align"]
elif c == "<": elif c == "<":
field_name = None try:
field_name_end = line[i:].find("`") field_name = None
if field_name_end == -1: field_name_end = line[i:].find("`")
pass if field_name_end == -1:
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:
pass pass
else: else:
field_data = lr[1:endpos].replace(rsg, "\\>") field_name = line[i+1:i+field_name_end]
skip = len(field_data)+field_name_skip+2 field_name_skip = len(field_name)
field_data = field_data.replace("\\>", ">") field_masked = False
output.append({ field_width = 24
"type":"field",
"name": field_name, if "|" in field_name:
"width": field_width, f_components = field_name.split("|")
"masked": field_masked, field_flags = f_components[0]
"data": field_data, field_name = f_components[1]
"style": make_style(state) 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 == "[": elif c == "[":
endpos = line[i:].find("]") endpos = line[i:].find("]")
@ -517,13 +520,20 @@ def make_output(state, line, url_delegate):
link_components = link_data.split("`") link_components = link_data.split("`")
if len(link_components) == 1: if len(link_components) == 1:
link_label = "" link_label = ""
link_fields = ""
link_url = link_data link_url = link_data
elif len(link_components) == 2: elif len(link_components) == 2:
link_label = link_components[0] link_label = link_components[0]
link_url = link_components[1] 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: else:
link_url = "" link_url = ""
link_label = "" link_label = ""
link_fields = ""
if len(link_url) != 0: if len(link_url) != 0:
if link_label == "": if link_label == "":
@ -551,6 +561,14 @@ def make_output(state, line, url_delegate):
if url_delegate != None: if url_delegate != None:
linkspec = LinkSpec(link_url, orig_spec) 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)) output.append((linkspec, link_label))
else: else:
output.append(make_part(state, link_label)) output.append(make_part(state, link_label))
@ -593,6 +611,7 @@ def make_output(state, line, url_delegate):
class LinkSpec(urwid.AttrSpec): class LinkSpec(urwid.AttrSpec):
def __init__(self, link_target, orig_spec): def __init__(self, link_target, orig_spec):
self.link_target = link_target self.link_target = link_target
self.link_fields = None
urwid.AttrSpec.__init__(self, orig_spec.foreground, orig_spec.background) urwid.AttrSpec.__init__(self, orig_spec.foreground, orig_spec.background)
@ -611,9 +630,9 @@ class LinkableText(urwid.Text):
if self.delegate != None: if self.delegate != None:
self.delegate.last_keypress = 0 self.delegate.last_keypress = 0
def handle_link(self, link_target): def handle_link(self, link_target, link_fields):
if self.delegate != None: 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): def find_next_part_pos(self, pos, part_positions):
for position in part_positions: for position in part_positions:
@ -671,7 +690,7 @@ class LinkableText(urwid.Text):
item = self.find_item_at_pos(self._cursor_position) item = self.find_item_at_pos(self._cursor_position)
if item != None: if item != None:
if isinstance(item, LinkSpec): if isinstance(item, LinkSpec):
self.handle_link(item.link_target) self.handle_link(item.link_target, item.link_fields)
elif key == "up": elif key == "up":
self._cursor_position = 0 self._cursor_position = 0
@ -761,7 +780,7 @@ class LinkableText(urwid.Text):
if item != None: if item != None:
if isinstance(item, LinkSpec): if isinstance(item, LinkSpec):
self.handle_link(item.link_target) self.handle_link(item.link_target, item.link_fields)
self._invalidate() self._invalidate()
self._emit("change") self._emit("change")