Home

Awesome

Sushy

A wiki/blogging engine with a static file back-end, full-text indexing and multiple markup support.

This was formerly the site engine for taoofmac.com circa 2015 until I decided to switch back to pure Python for maintainability.

Status

Many years later, I've decided to at least clean up the legacy codebase and bring it up to date. Once done, it should again be deployable to piku/Dokku-alt/Dokku/Heroku.

The goal is to make it run on the <strike>2023</strike> 1.0.0 version of Hylang, which was finally released in September 22<sup>nd</sup> 2024.

Roadmap

Stuff that will never happen:


Principles of Operation

Markup Support

Sushy supports plaintext, HTML and Textile for legacy reasons, and Markdown as its preferred format. <strike>ReStructured Text is also supported, but since I don't use it for anything (and find it rather a pain to read, let alone write), I can't make any guarantees as to its reliability. Work is ongoing for supporting Jupyter notebooks (which have no metadata/frontmatter conventions).</strike>

All markup formats MUST be preceded by "front matter" handled like RFC2822 headers (see the pages folder for examples and test cases). Sushy uses the file extension to determine a suitable renderer, but that can be overriden if you specify a Content-Type header (see config.hy for the mappings).

FAQ

Why?

I've been running a classical, object-oriented Python Wiki (called Yaki) for the better part of a decade. It works, but is comparatively big and has become unwieldy and cumbersome to tweak. So I decided to rewrite it. Again. And again.

And I eventually decided to make it smaller -- my intention is for the core to stop at around 1000 lines of code excluding templates, so this is also an exercise in building tight, readable (and functional) code.

Why Hy?

Because I've been doing a lot of Clojure lately for my other personal projects, and both the LISP syntax and functional programming style are quite natural to me.

I thought long and hard about doing this in Clojure instead (and in fact have been poking at an implementation for almost a year now), but the Java libraries for Markdown and Textile have a bunch of irritating little corner cases and I wanted to make sure all my content would render fine the first time, plus Python has an absolutely fantastic ecosystem that I am deeply into.

Then Hy came along, and I realized I could have my cake and eat it too.

Can this do static sites?

I've used a fair amount of static site generators, and they all come up short on a number of things (namely trivially easy updates that don't involve re-generating hundreds of tiny files and trashing the filesystem) -- which, incidentally, is one of the reasons why Sushy relies on a single SQLite file for temporary data.

But there's no reason why this can't be easily modified to pre-render and save the HTML content after indexing runs -- pull requests to do that are welcome.

Requirements

Thanks to Hy, this should run just as well under Python 2 and Python 3. My target environment is 2.7.8/PyPy, though, so your mileage may vary. Check the requirements.txt file - I've taken pains to make sure dependencies are there for a reason and not just because they're trendy.


Deployment

This repository should be deployable on piku (my featherweight version of Heroku), and also used to be deployable to Dokku -- this was removed in the 2023 refactoring since I don't use it anymore.

As is (for development) the content ships with the code repo. Changing things to work off a separate mount point (or a shared container volume) is trivial.

Configuration

In accordance with the 12 Factor approach, runtime configuration is taken from environment variables:

These are set in the Makefile (which I use for a variety of purposes).


Trying it out

Make sure you have libxml and libxslt headers, as well as the JPEG library - the following is for Ubuntu 14.04:

sudo apt-get install libxml2-dev libxslt1-dev libjpeg-dev
# install dependencies
make deps
# run the indexing daemon (updates upon file changes)
make index-watch &
# run the standalone server (or uwsgi)
make serve