Projects
This page lists my software projects and other smaller pieces of code which I've created at one point or another that might be of use to someone. Please send any questions or feedback to hello@menno.io.
IMAPClient
I am the author and maintainer of IMAPClient, an easy-to-use, idomatic and complete IMAP client library for Python. It's on GitHub at https://github.com/mjs/imapclient
sdshout
sdshout is a service for Linux systems that creates desktop notifications when background services fail. It's great for finding out that your backups, system updates or other critical functions aren't working. It's on GitHub at https://github.com/mjs/sdshout.
PyBot Arena
A coding game where participants implement algorithms in Python to control autonomous tanks which are pitted against each other. I created it as a coding challenge for Python NZ Christchurch meetup using the Hunter2 game from PaulleDemon as starting point.
It can be found on GitHub: https://github.com/mjs/pybot-arena
Logseq DONE Time Plugin
A simple plugin for Logseq which adds a timestamp property to completed tasks. This is handy for generating reports along the lines of "what did I do yesterday?" or "what did I do last week?" using Logseq's advanced query functionality.
The plugin code can be found on GitHub and the plugin can be installed via marketplace inside Logseq itself.
There's a blog article introducing the plugin elsewhere here.
Faux Maps
A web based random map generator using WebAssembly and Rust.
Emacs Config
Most serious users of Emacs end up with a non-trivial configuration. This configuration is actually a software project and should be treated as such. This means that a good Emacs config uses modularisation, clean code, comments and source control.
My Emacs configuration is my attempt at doing these things well. It uses the wonderful straight.el and use-package for package management and configuration. I've even written an article about use-package.
elemental
elemental is an Emacs extension that provides elisp functions for "intelligently jumping between and transposing list/tuple/dictionary/function-parameter elements". It's hosted on GitHub: https://github.com/mjs/elemental
I don't actually use this any more because I use Evil and discovered that evil-args and evil-exchange can do what elemental can do and more. It's still a decent example of how to deal with some arcane corners of elisp developement (syntax tables) and writing unit tests in elisp.
Raspberry Pi VU Meter
My wife and I once worked on a Raspberry Pi based media server with a built-in analog VU meter. There's some articles about this project on the blog whic includes descriptions of the software and electronics we created.
- Somewhat overengineered blinking LEDs
- Monitoring Audio Levels with PulseAudio
- Driving a VU meter using a digital-to-analog converter
See https://gitlab.com/menn0/raspberry-pi-vu-meter to skip the articles and get straight to the code.
mongrel
This is a fairly rough extension to Thunderbird that provides Mutt-like key bindings and functionality.
I used to use it every day but not for some time now (I wonder how many Thunderbird users there are these days?). It could do with some cleaning up, documentation etc. If you're interested in using it yourself, please email hello@menno.io.
mongrel is hosted on GitLab: https://gitlab.com/menn0/mongrel
Various PyBlosxom Plugins
A long time ago this site used to be powered by PyBlosxom. I ended up creating a few plugins for it which are recorded here for posterity.
rst_break
This plugin allows the rst (reStructured Text) and readmore plugins to work together. It defines a reST "break" directive which will trigger the readmore plugin's breakpoint functionality. See the documentation at the top of the file for more information.
On GitLab: https://gitlab.com/menn0/pyblosxom-plugins/-/tree/master/rst_break
draftsdir
This simple plugin allows you to define a directory under your datadir that contains draft blog entries. Draft entries will not be displayed on the blog by default. To display drafts add a 'drafts' query parameter to the end of the page URL (for example http://my.site.com/blog/?drafts or http://my.site.com/blog/?other=arg&drafts)
Installation and configuration information is at the top of draftsdir.py.
On GitLab: https://gitlab.com/menn0/pyblosxom-plugins/-/tree/master/draftsdir
spamquestion
spamquestion is a simple PyBlosxom plugin that helps to prevent comment spam.
A randomly selected question is shown on the comment form for a blog entry. The user must answer the question correctly in order to submit a comment. The approach works because each blog will use it's own set of unique questions that are easy for a human to deal with but are virtually impossible for a computer to answer unaided. This prevents makes automated spambots ineffective.
Unlike CAPTCHA based anti-spam systems, this approach does not disadvantage visually impaired users and works even in text only browsers.
On GitLab: https://gitlab.com/menn0/pyblosxom-plugins/-/tree/master/spamquestion
ssh-agent-applet
ssh-agent-applet is a Gnome applet that allows you to conveniently keep your ssh key(s) on external media. This means that if your computer is cracked or stolen, the attacker will not have a copy of private ssh key(s).
Using ssh-agent-applet, your keys are loaded into ssh-agent as soon as you insert your "key drive" into a USB port. The drive is automatically unmounted once the key loaded so you can remove it from the USB port immediately.
For developers, ssh-agent-applet is an example of how to write Gnome applets in Python and how to interface with HAL from Python using DBUS.
ssh-agent-applet is hosted on GitLab: https://gitlab.com/menn0/ssh-agent-applet