Vincent Jousse: 1 refactor: simplify set_prompt and add tests 4 files changed, 116 insertions(+), 54 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~lioploum/offpunk-devel/patches/56064/mbox | git am -3Learn more about email & git
I was going through the code and I found some nits in the prompt code (using `.get` with a default value on dicts) and decided to take the occasion to setup some tests. I've updated the README accordingly (tests need `pytest` and `pytest-mock` to be installed). The `README.md` has been reformated using a markdown linter, I hope you don't mind. --- README.md | 92 +++++++++++++++++++++----------------- offpunk.py | 26 +++++------ requirements-dev.txt | 2 + tests/geminiclient_test.py | 50 +++++++++++++++++++++ 4 files changed, 116 insertions(+), 54 deletions(-) create mode 100644 requirements-dev.txt create mode 100644 tests/geminiclient_test.py diff --git a/README.md b/README.md index f0a93a7..b8577de 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Offpunk is a set of python files. Installation is optional, you can simply git c You use the `go` command to visit a URL, e.g. `go gemini.circumlunar.space`. (gemini:// is assumed if no protocol is specified. Supported protocols are gemini, gopher, finger, http, https, mailto, spartan and file. Default protocol is configurable). -Links in pages are assigned numerical indices. Just type an index to follow that link. If page is too long to fit on your screen, the content is displayed in the less pager. Type `q` to quit and go back to Offpunk prompt. Type `view` or `v` to display it again. (`view full` or `v full` allows to see the full html page instead of the article view. `v feed` try to display the linked RSS feed and `v feeds` displays a list of available feeds. This only applies to html pages. `v source` allows you to see the source code of a page and `v normal` to go back to normal view) +Links in pages are assigned numerical indices. Just type an index to follow that link. If page is too long to fit on your screen, the content is displayed in the less pager. Type `q` to quit and go back to Offpunk prompt. Type `view` or `v` to display it again. (`view full` or `v full` allows to see the full html page instead of the article view. `v feed` try to display the linked RSS feed and `v feeds` displays a list of available feeds. This only applies to html pages. `v source` allows you to see the source code of a page and `v normal` to go back to normal view) Use `add` to add a page to your bookmarks and `bookmarks` or `bm` to show your bookmarks (you can create multiple bookmarks lists, edit and remove them. See the `list` manual with `help list`). @@ -50,7 +50,7 @@ To have offpunk fetch the URL at next sync and close immediately, run: ## More -Important news and releases will be announced on the offpunk-devel mailing list +Important news and releases will be announced on the offpunk-devel mailing list => https://lists.sr.ht/~lioploum/offpunk-devel Questions can be asked on the users mailing list: @@ -59,70 +59,75 @@ Questions can be asked on the users mailing list: ## Dependencies Offpunk has few "strict dependencies", i.e. it should run and work without anything -else beyond the Python standard library and the "less" pager. However, it will "opportunistically +else beyond the Python standard library and the "less" pager. However, it will "opportunistically import" a few other libraries if they are available to offer an improved -experience or some other features such as HTTP/HTML or image support. +experience or some other features such as HTTP/HTML or image support. To avoid using unstable or too recent libraries, the rule of thumb is that a library should be packaged in Debian/Ubuntu. Keep in mind that Offpunk is mainly tested will all libraries installed. If you encounter a crash without one optional dependencies, please report it. Patches and contributions to remove dependencies or support alternatives are highly appreciated. -* [List of existing Offpunk packages (Repology)](https://repology.org/project/offpunk/versions) -* PIP: [requirements file to install dependencies with pip](requirements.txt) -* Ubuntu/Debian: [command to install dependencies on Ubuntu/Debian without pip](ubuntu_dependencies.txt) -* Please contribute packages for other systems, there’s a [mailing-list dedicated to packaging](https://lists.sr.ht/~lioploum/offpunk-packagers). +- [List of existing Offpunk packages (Repology)](https://repology.org/project/offpunk/versions) +- PIP: [requirements file to install dependencies with pip](requirements.txt) +- Ubuntu/Debian: [command to install dependencies on Ubuntu/Debian without pip](ubuntu_dependencies.txt) +- Please contribute packages for other systems, there’s a [mailing-list dedicated to packaging](https://lists.sr.ht/~lioploum/offpunk-packagers). Run command `version` in offpunk to see if you are missing some dependencies. Mandatory or highly recommended (packagers should probably make those mandatory): -* [less](http://www.greenwoodsoftware.com/less/): mandatory but is probably already on your system -* [file](https://www.darwinsys.com/file/) is used to get the MIME type of cached objects. Should already be on your system. -* [xdg-utils](https://www.freedesktop.org/wiki/Software/xdg-utils/) provides xdg-open which is highly recommended to open files without a renderer or a handler. It is also used for mailto: command. -* The [cryptography library](https://pypi.org/project/cryptography/) will provide a better and slightly more secure experience when using the default TOFU certificate validation mode and is recommended (apt-get install python3-cryptography). + +- [less](http://www.greenwoodsoftware.com/less/): mandatory but is probably already on your system +- [file](https://www.darwinsys.com/file/) is used to get the MIME type of cached objects. Should already be on your system. +- [xdg-utils](https://www.freedesktop.org/wiki/Software/xdg-utils/) provides xdg-open which is highly recommended to open files without a renderer or a handler. It is also used for mailto: command. +- The [cryptography library](https://pypi.org/project/cryptography/) will provide a better and slightly more secure experience when using the default TOFU certificate validation mode and is recommended (apt-get install python3-cryptography). Dependencies to enable web browsing (packagers may put those in an offpunk-web meta-package but it is recommended to have it for a better offpunk experience) -* [Python-requests](http://python-requests.org) is needed to handle http/https requests natively (apt-get install python3-requests). Without it, http links will be opened in an external browser -* [BeautifulSoup4](https://www.crummy.com/software/BeautifulSoup) and [Readability](https://github.com/buriy/python-readability) are both needed to render HTML. Without them, HTML will not be rendered or be sent to an external parser like Lynx. (apt-get install python3-bs4 python3-readability or pip3 install readability-lxml) -* [Python-feedparser](https://github.com/kurtmckee/feedparser) will allow parsing of RSS/Atom feeds and thus subscriptions to them. (apt-get install python3-feedparser) -* [Chafa](https://hpjansson.org/chafa/) allows to display pictures in your console. Install it and browse to an HTML page with picture to see the magic. + +- [Python-requests](http://python-requests.org) is needed to handle http/https requests natively (apt-get install python3-requests). Without it, http links will be opened in an external browser +- [BeautifulSoup4](https://www.crummy.com/software/BeautifulSoup) and [Readability](https://github.com/buriy/python-readability) are both needed to render HTML. Without them, HTML will not be rendered or be sent to an external parser like Lynx. (apt-get install python3-bs4 python3-readability or pip3 install readability-lxml) +- [Python-feedparser](https://github.com/kurtmckee/feedparser) will allow parsing of RSS/Atom feeds and thus subscriptions to them. (apt-get install python3-feedparser) +- [Chafa](https://hpjansson.org/chafa/) allows to display pictures in your console. Install it and browse to an HTML page with picture to see the magic. Gopher dependencies: -* [Python-chardet](https://github.com/chardet/chardet) is used to detect the character encoding on Gopher (and may be used more in the future) + +- [Python-chardet](https://github.com/chardet/chardet) is used to detect the character encoding on Gopher (and may be used more in the future) Older dependencies which are only needed on older systems (where chafa < 1.10) -* [Timg](https://github.com/hzeller/timg) is a slower alternative to chafa for inline images. Might be deprecated in the future. -* [Python-pil](http://python-pillow.github.io/) is required to only display the first frame of animated gif with chafa if chafa version is lower than 1.10. Might be deprecated in the future. + +- [Timg](https://github.com/hzeller/timg) is a slower alternative to chafa for inline images. Might be deprecated in the future. +- [Python-pil](http://python-pillow.github.io/) is required to only display the first frame of animated gif with chafa if chafa version is lower than 1.10. Might be deprecated in the future. Nice to have (packagers should may make those optional): -* [Xsel](http://www.vergenet.net/~conrad/software/xsel/) allows to `go` to the URL copied in the clipboard without having to paste it (both X and traditional clipboards are supported). Also needed to use the `copy` command. (apt-get install xsel). Xclip can be used too. -* [Wl-clipboard](https://github.com/bugaevc/wl-clipboard) allows the same feature than xsel but under Wayland -* [Python-setproctitle](https://github.com/dvarrazzo/py-setproctitle) will change the process name from "python" to "offpunk". Useful to kill it without killing every python service. + +- [Xsel](http://www.vergenet.net/~conrad/software/xsel/) allows to `go` to the URL copied in the clipboard without having to paste it (both X and traditional clipboards are supported). Also needed to use the `copy` command. (apt-get install xsel). Xclip can be used too. +- [Wl-clipboard](https://github.com/bugaevc/wl-clipboard) allows the same feature than xsel but under Wayland +- [Python-setproctitle](https://github.com/dvarrazzo/py-setproctitle) will change the process name from "python" to "offpunk". Useful to kill it without killing every python service. ## Features -* Browse https/gemini/gopher without leaving your keyboard and without distractions -* Customize your experience with the `theme` command. -* Built-in documentation: type `help` to get the list of command or a specific help about a command. -* Offline mode to browse cached content without a connection. Requested elements are automatically fetched during the next synchronization and are added to your tour. -* HTML pages are prettified to focus on content. Read without being disturbed or see the full page with `view full`. -* RSS/Atom feeds are automatically discovered by `subscribe` and rendered as gemlogs. They can be explored with `view feed` and `view feeds`. -* Support "subscriptions" to a page. New content seen in subscribed pages are automatically added to your next tour. -* Complex bookmarks management through multiple lists, built-in edition, subscribing/freezing lists and archiving content. -* Advanced navigation tools like `tour` and `mark` (as per VF-1). Unlike AV-98, tour is saved on disk accross sessions. -* Ability to specify external handler programs for different MIME types (use `handler`) -* Enhanced privacy with `redirect` which allows to block a http domain or to redirect all request to a privacy friendly frontent (such as nitter for twitter). -* Non-interactive cache-building with configurable depth through the --sync command. The cache can easily be used by other software. -* `netcache`, a standalone CLI tool to retrieve the cached version of a network ressource. -* `ansicat`, a standalone CLI tool to render HTML/Gemtext/image in a terminal. -* `opnk`, a standalone CLI tool to open any kind of ressources (local or network) and display it in your terminal or, if not possible, fallback to `xdg-open`. +- Browse https/gemini/gopher without leaving your keyboard and without distractions +- Customize your experience with the `theme` command. +- Built-in documentation: type `help` to get the list of command or a specific help about a command. +- Offline mode to browse cached content without a connection. Requested elements are automatically fetched during the next synchronization and are added to your tour. +- HTML pages are prettified to focus on content. Read without being disturbed or see the full page with `view full`. +- RSS/Atom feeds are automatically discovered by `subscribe` and rendered as gemlogs. They can be explored with `view feed` and `view feeds`. +- Support "subscriptions" to a page. New content seen in subscribed pages are automatically added to your next tour. +- Complex bookmarks management through multiple lists, built-in edition, subscribing/freezing lists and archiving content. +- Advanced navigation tools like `tour` and `mark` (as per VF-1). Unlike AV-98, tour is saved on disk accross sessions. +- Ability to specify external handler programs for different MIME types (use `handler`) +- Enhanced privacy with `redirect` which allows to block a http domain or to redirect all request to a privacy friendly frontent (such as nitter for twitter). +- Non-interactive cache-building with configurable depth through the --sync command. The cache can easily be used by other software. +- `netcache`, a standalone CLI tool to retrieve the cached version of a network ressource. +- `ansicat`, a standalone CLI tool to render HTML/Gemtext/image in a terminal. +- `opnk`, a standalone CLI tool to open any kind of ressources (local or network) and display it in your terminal or, if not possible, fallback to `xdg-open`. ## RC files You can use an RC file to automatically run any sequence of valid Offpunk -commands upon start up. This can be used to make settings controlled with the -`set`, `handler` or `themes` commands persistent. You can also put a `go` command in +commands upon start up. This can be used to make settings controlled with the +`set`, `handler` or `themes` commands persistent. You can also put a `go` command in your RC file to visit a "homepage" automatically on startup, or to pre-prepare a `tour` of your favourite Gemini sites or `offline` to go offline by default. -The RC file should be called `offpunkrc` and goes in $XDG_CONFIG_DIR/offpunk (or .config/offpunk or .offpunk if xdg not available). In that file, simply write one command per line, just like you would type them in offpunk. +The RC file should be called `offpunkrc` and goes in $XDG_CONFIG_DIR/offpunk (or .config/offpunk or .offpunk if xdg not available). In that file, simply write one command per line, just like you would type them in offpunk. ## Cache design @@ -132,3 +137,10 @@ The cache can be accessed/built with the `netcache` tool. See `netcache -h` for There’s no feature to automatically trim the cache. But any part of the cache can safely be removed manually as there are no databases or complex synchronisation. +## Tests + +Be sure to install the dev requirements (`pytest` and `pytest-mock`) with: + + pip install -r requirements-dev.txt + +And then run the test suite using `pytest`. diff --git a/offpunk.py b/offpunk.py index 9636bb7..28afa02 100755 --- a/offpunk.py +++ b/offpunk.py @@ -188,25 +188,23 @@ class GeminiClient(cmd.Cmd): def set_prompt(self, prompt): key = "prompt_%s" % prompt.lower() - if key in self.theme: - colors = self.theme[key] - else: - # default color is green - colors = ["green"] + + # default color is green + colors = self.theme.get(key, ["green"]) + open_color = "" close_color = "" - for c in colors: - if c in offthemes.colors: - ansi = offthemes.colors[c] - else: - ansi = ["32", "39"] + for color in colors: + # default to green 32 if color name `green` is not found + ansi = offthemes.colors.get(color, ["32", "39"]) + open_color += "%s;" % ansi[0] close_color += "%s;" % ansi[1] + # removing the last ";" - if open_color.endswith(";"): - open_color = open_color[:-1] - if close_color.endswith(";"): - close_color = close_color[:-1] + open_color = open_color.rstrip(";") + close_color = close_color.rstrip(";") + self.prompt = ( "\001\x1b[%sm\002" % open_color + prompt diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..1213649 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,2 @@ +pytest +pytest-mock diff --git a/tests/geminiclient_test.py b/tests/geminiclient_test.py new file mode 100644 index 0000000..d3c0f2a --- /dev/null +++ b/tests/geminiclient_test.py @@ -0,0 +1,50 @@ +from offpunk import GeminiClient +import offthemes + + +def test_set_prompt(): + gc = GeminiClient() + + prompt_value = "ON" + prompt = gc.set_prompt(prompt_value) + + # Default prompt should be green 32 and go back to default 39 + assert prompt == format_prompt("32", "39", prompt_value) + + +# Prompt should still be green if nothing is set +def test_set_prompt_without_themes(mocker): + mocker.patch("offthemes.offpunk1", {}) + mocker.patch("offthemes.colors", {}) + gc = GeminiClient() + + prompt_value = "ON" + prompt = gc.set_prompt(prompt_value) + + # Default prompt should be green 32 and go back to default 39 + assert prompt == format_prompt("32", "39", prompt_value) + + +# Prompt should still be green if nothing is set +def test_set_prompt_without_themes(mocker): + new_theme = offthemes.default.copy() + new_theme["prompt_on"] = ["blue"] + + mocker.patch("offthemes.default", new_theme) + + gc = GeminiClient() + + prompt_value = "ON" + prompt = gc.set_prompt(prompt_value) + + # Default prompt should be green 32 and go back to default 39 + assert prompt == format_prompt("34", "39", prompt_value) + + +def format_prompt(open_color: str, close_color: str, prompt_value: str) -> str: + return ( + "\001\x1b[%sm\002" % open_color + + prompt_value + + "\001\x1b[%sm\002" % close_color + + "> " + ) -- 2.47.0
Thanks for the patch, I’ve merged it. For those, like me, not wanting to use pip, you can simply "apt install python3-pytest-mock". Tests are runs with the simple "pytest". That’s really useful. Le 24 nov 22 05:58, Vincent Jousse a écrit :