browser: rename screen and handle quick commands
This commit is contained in:
parent
15f56289b9
commit
85570de5a8
|
@ -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()
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Reference in a new issue