browser: rename screen and handle quick commands

This commit is contained in:
dece 2021-02-16 21:22:49 +01:00
parent 15f56289b9
commit 85570de5a8
2 changed files with 46 additions and 15 deletions

View file

@ -1,7 +1,7 @@
import argparse import argparse
from bebop.browser import Browser
from bebop.tofu import load_cert_stash from bebop.tofu import load_cert_stash
from bebop.screen import Screen
def main(): def main():
@ -17,7 +17,7 @@ def main():
start_url = None start_url = None
cert_stash = load_cert_stash("/tmp/stash") cert_stash = load_cert_stash("/tmp/stash")
Screen(cert_stash).run(start_url=start_url) Browser(cert_stash).run(start_url=start_url)
main() main()

View file

@ -12,7 +12,8 @@ from bebop.page import Page
from bebop.protocol import Request, Response from bebop.protocol import Request, Response
class Screen: class Browser:
"""Manage the events, inputs and rendering."""
def __init__(self, cert_stash): def __init__(self, cert_stash):
self.stash = cert_stash self.stash = cert_stash
@ -64,15 +65,14 @@ class Screen:
running = True running = True
while running: while running:
if pending_url: if pending_url:
self.open_gemini_url(pending_url) self.open_url(pending_url)
pending_url = None pending_url = None
char = self.screen.getch() char = self.screen.getch()
if char == ord("q"): if char == ord("q"):
running = False running = False
elif char == ord(":"): elif char == ord(":"):
command = self.take_user_input() self.quick_command("")
self.set_status(f"Command: {command}")
elif char == ord("s"): elif char == ord("s"):
self.set_status(f"h {self.h} w {self.w}") self.set_status(f"h {self.h} w {self.w}")
elif char == ord("h"): elif char == ord("h"):
@ -87,6 +87,8 @@ class Screen:
self.scroll_page_vertically(self.page_pad_size[0]) self.scroll_page_vertically(self.page_pad_size[0])
elif char == ord("b"): elif char == ord("b"):
self.scroll_page_vertically(-self.page_pad_size[0]) self.scroll_page_vertically(-self.page_pad_size[0])
elif char == ord("o"):
self.quick_command("open")
elif char == ord("H"): elif char == ord("H"):
self.go_back() self.go_back()
elif curses.ascii.isdigit(char): elif curses.ascii.isdigit(char):
@ -113,11 +115,13 @@ class Screen:
return 1, self.w return 1, self.w
def refresh_windows(self): def refresh_windows(self):
"""Refresh all windows and clear command line."""
self.refresh_page() self.refresh_page()
self.refresh_status_line() self.refresh_status_line()
self.command_line.clear() self.command_line.clear()
def refresh_page(self): def refresh_page(self):
"""Refresh the current page pad; it does not reload the page."""
self.page.refresh_content(*self.page_pad_size) self.page.refresh_content(*self.page_pad_size)
def refresh_status_line(self): def refresh_status_line(self):
@ -138,19 +142,28 @@ class Screen:
self.status_data = text, ColorPair.ERROR self.status_data = text, ColorPair.ERROR
self.refresh_status_line() self.refresh_status_line()
def open_url(self, url, redirections=0): def open_url(self, url, redirections=0, assume_absolute=False):
"""Try to open an URL. """Try to open an URL.
If the URL is not strictly absolute, it will be opened relatively to the This function assumes that the URL can be from an user and thus tries a
current URL, unless there is no current URL yet. few things to make it work.
If there is no current URL (e.g. we just started) or `assume_absolute`
is True, assume it is an absolute URL. In other cases, parse it normally
and later check if it has to be used relatively to the current URL.
Arguments:
- url: an URL string, may not be completely compliant.
- redirections: number of redirections we did yet for the same request.
- assume_absolute: assume we intended to use an absolute URL if True.
""" """
if redirections > 5: if redirections > 5:
self.set_status_error(f"Too many redirections ({url}).") self.set_status_error(f"Too many redirections ({url}).")
return return
if self.current_url: if assume_absolute or not self.current_url:
parts = parse_url(url)
else:
parts = parse_url(url, absolute=True) parts = parse_url(url, absolute=True)
else:
parts = parse_url(url)
if parts.scheme == "gemini": if parts.scheme == "gemini":
# If there is no netloc, this is a relative URL. # If there is no netloc, this is a relative URL.
if not parts.netloc: if not parts.netloc:
@ -217,9 +230,13 @@ class Screen:
else: else:
self.refresh_page() self.refresh_page()
def take_user_input(self, type_char: str =":"): def take_user_input(self, type_char: str =":", prefix: str =""):
"""Focus command line to let the user type something""" """Focus command line to let the user type something."""
return self.command_line.focus(type_char, self.validate_common_char) return self.command_line.focus(
type_char,
validator=self.validate_common_char,
prefix=prefix,
)
def validate_common_char(self, ch: int): def validate_common_char(self, ch: int):
"""Generic input validator, handles a few more cases than default. """Generic input validator, handles a few more cases than default.
@ -245,6 +262,20 @@ class Screen:
self.screen.nodelay(False) self.screen.nodelay(False)
return ch return ch
def quick_command(self, command):
"""Shortcut method to take user input with a prefixed command string."""
prefix = f"{command} " if command else ""
user_input = self.take_user_input(prefix=prefix)
if not user_input:
return
self.process_command(user_input)
def process_command(self, command_text: str):
words = command_text.split()
command = words[0]
if command == "open":
self.open_url(words[1], assume_absolute=True)
def handle_digit_input(self, init_char: int): def handle_digit_input(self, init_char: int):
"""Handle a initial digit input by the user. """Handle a initial digit input by the user.