diff --git a/BOARD.txt b/BOARD.txt index 35caaa6..ae2a5a0 100644 --- a/BOARD.txt +++ b/BOARD.txt @@ -1,7 +1,5 @@ TODO ----------------------------------------- -provide a plugin interface for schemes -finger +-------------------------------------------------------------------------------- @@ -60,3 +58,5 @@ preferences per site basic mouse support basic local browsing search in page +plugin interface for schemes +finger plugin diff --git a/plugins/finger/README.md b/plugins/finger/README.md new file mode 100644 index 0000000..43581be --- /dev/null +++ b/plugins/finger/README.md @@ -0,0 +1,12 @@ +Finger plugin for Bebop +======================= + +This is a minimal Finger protocol plugin for [Bebop][bebop], refer to its docs +for details. + +[bebop]: https://git.dece.space/Dece/Bebop + +Requires: + +* Bebop >= 0.2.0 +* A `finger` command on your system diff --git a/plugins/finger/bebop_finger/__init__.py b/plugins/finger/bebop_finger/__init__.py new file mode 100644 index 0000000..c42b63f --- /dev/null +++ b/plugins/finger/bebop_finger/__init__.py @@ -0,0 +1 @@ +from .plugin import plugin diff --git a/plugins/finger/bebop_finger/plugin.py b/plugins/finger/bebop_finger/plugin.py new file mode 100644 index 0000000..abdd239 --- /dev/null +++ b/plugins/finger/bebop_finger/plugin.py @@ -0,0 +1,53 @@ +import subprocess +from typing import Optional + +from bebop.browser.browser import Browser +from bebop.navigation import parse_url +from bebop.page import Page +from bebop.plugins import SchemePlugin + + +class FingerPlugin(SchemePlugin): + + def __init__(self) -> None: + super().__init__("finger") + + def open_url(self, browser: Browser, url: str) -> Optional[str]: + parts = parse_url(url, default_scheme="finger") + host = parts["netloc"] + user = parts["path"][1:] # Strip leading '/' from path. + if not host: + browser.set_status_error(f"Could not parse {url}.") + return None + + raw_output = self.request(browser, host, user) + if raw_output is None: + return None + + try: + output = raw_output.decode(errors="replace") + except ValueError: + browser.set_status_error("Failed to decode finger output.") + return None + + browser.load_page(Page.from_text(output)) + browser.current_url = url + return url + + def request(self, browser: Browser, host: str, user: str): + target = f"{user}@{host}" + browser.set_status(f"Requesting {target}…") + command = ["finger", target] + try: + output = subprocess.check_output(command, stderr=subprocess.PIPE) + except FileNotFoundError: + browser.set_status_error("Finger program not found.") + except subprocess.CalledProcessError as exc: + finger_error = exc.stderr.decode(errors="replace").replace("\n", "") + error = f"Finger failed with code {exc.returncode}: {finger_error}" + browser.set_status_error(error) + else: + return output + + +plugin = FingerPlugin() diff --git a/plugins/finger/setup.cfg b/plugins/finger/setup.cfg new file mode 100644 index 0000000..1973f87 --- /dev/null +++ b/plugins/finger/setup.cfg @@ -0,0 +1,18 @@ +[metadata] +name = bebop-browser-finger +version = 0.1.0 +description = Finger plugin for the Bebop terminal browser +long_description = file: README.md +license = GPLv3 +author = dece +author-email = shgck@pistache.land +home-page = https://git.dece.space/Dece/Bebop +classifiers = + Environment :: Console + Programming Language :: Python :: 3 + Programming Language :: Python :: 3.7 + +[options] +packages = bebop_finger +python_requires = >= 3.7 +setup_requires = setuptools >= 38.3.0