Lars Wirzenius: Random hacks, 2007


Thursday, October 11, 2007

Random hacks: Unperish 2.0

I've just released a new, completely re-written version of Unperish, my program to automate the mechanical steps of releasing a free software project.

It is now completely based on plugins, so it should be easy to adapt to other people's needs than mine. For example, although it currently only supports Bazaar as a version control system, it should be quite easy to write a plugin for any other one. After that is done, the rest of the existing plugins will still work, and can take care of things like building a Debian package with pbuilder, checking it with lintian, linda, and piuparts, and putting the results in an apt repository.

Git, for example, should be especially easy. I haven't written a git plugin yet myself, since I don't use git. The README has instructions for writing plugins, and if anything is unclear, please ask me.

I'd be more than happy to include any such plugins, or changes to plugins, that other people want to make.

Monday, May 28, 2007

Random hacks: Static website, with translations, using IkiWiki

One of my current projects involves setting up a website that is translated to at least two languages. For various reasons I wanted to use IkiWiki as the backend, even though the site is static, and does not need the wiki functionality. IkiWiki is, in principle, a wiki engine, but with a difference: it is run off-line, and creates a set of static HTML pages, rather than running every time a page is accessed. This makes it suitable for static websites.

For the translation, I wanted to have the following setup: Each page is available in each language, so the pages are named foo.xx.html, with xx being the ISO language code. This also allows HTTP content negotiation to work, if the client asks for the page without the .html suffix.

IkiWiki itself does not currently have support for translations. Doing translations by manually editing each page in each language is tiresome and error prone. I wanted to use the gettext approach, where the translations are maintained using .po files. The po4a tool makes this possible: it supports many file formats.

English is declared as the original language for this project: all other languages are generated via po4a from the English ones. The page content gets put into foo.xx.mdwn. po4a generates all other language files than English, and these are then fed as input to IkiWiki, which generates the HTML.

In summary and horrible ad hoc pseudo-notation:

  • po4a: foo.en.mdwn -> foo.pot
  • cp: foo.pot -> foo.xx.po
  • $EDITOR: update translation in foo.xx.po
  • po4a: foo.en.mdwn + foo.xx.po -> foo.xx.mdwn
  • IkiWiki: foo.*.mdwn -> foo.*.html

This works pretty well, but only for the part of the page that gets put into the content section in the IkiWiki page template (<TMPL_VAR CONTENT>). The page design we have calls for a couple of elements with translatable content outside the content: a logo and a menu/navigation bar. To deal with these, I made a little IkiWiki plugin.

The plugin sets a couple of Perl HTML::Template variables, LANG and BASENAME, based on the input file name. If the input name is foo.en.mdwn, the variable get set to en and foo, respectively. The IkiWiki page template then uses the variables to load the right logo for the language of the page being generated.

The navigation bar needs further work. Unfortunately, the po4a tools have trouble with the IkiWiki page templates, and can't extract just the menu entries. I ended up doing the navigation bar translation directly in the page template, since it is only a few words anyway.

<li><a href="index.<TMPL_VAR LANG>.html">

The "this page in other languages" part of the navigation part looks like this:

<li><a href="<TMPL_VAR BASENAME>.fi.html">suomeksi</a></li>

I made the plugin (my first Perl ever!) available in case anyone else finds it useful.

Note that the plugin isn't of much help if you want to maintain a translated wiki, since this all need some Makefile magic to make things smooth. I'm not sure the Makefile is at all optimal, though.

We haven't yet gone public with the website, so this setup of mine may well get improvements still.

Wednesday, April 18, 2007

Random hacks: Notetak 0.14

I've rewritten Notetak, my search centric note taking application for GNOME. The goal of the rewrite was to make the code clearer, and to get test coverage to 100% on the statement level. Both goals achieved.

Functionally, the new version should be identical to the old one, but I'm sure I missed something. Now that the code is clean again, I expect to start adding new things every now and then.

Thursday, April 05, 2007

Random hacks: Lap tray

For a few years now, I've used a lap tray under my laptop when sitting in an armchair or sofa at home. It is basically a tray with a pillow below. It's been very nice: not only does it protect me from burns, it's just plain more comfortable than balancing the thing on my thighs and knees.

Unfortunately, it's been slowly disintegrating for the past couple of years. I decided to hire my cousin Johan Wirzenius the carpenter to make me a new one. Since I was ordering a custom one, I got to specify three new fancy features: the pillow is detachable (via velcro), and the tray is foldable, resulting in a more transportable whole. Also, the edges of the tray have grooves to hold cables in place, and the surface has grooves to allow better ventilation.

Below are four pictures of the tray, courtesy of my cousin.

lap tray lap tray lap tray lap tray

Four pictures of the new tray. The person is my cousin's assistant.

Friday, March 23, 2007

Random hacks: Finnish .ics files

I abandoned paper calendars in 1997. For a few years I used various Palm devices, then Evolution. For the most part, this has worked fine. One of the drawbacks is that I have not had any info in my calendar about official holidays in Finland. That would be useful so that I would know when other people are going to be responding to e-mail slowly, and get annoyed if I call them on business.

Evolution can deal with several calendars at the same time, and can import calendar files in various formats. A couple of years ago I found an iCal file with Finnish holidays, and imported that to Evolution, but it's out of date by now. This week I decided to look for a new one, but before I did, Droidy, the fastest interface to search engines, found one for me. Unfortunately, it was severly lacking, and did not even include Midsummer Eve, the biggest summer festivity in Finland.

I then decided to make my own. I skimmed the web pages of The Almanac Office at University of Helsinki. They used to have the monopoly on making calendars in Finland (and what a silly anachronism that was), and they still have the copyright on name days, but that stuff doesn't interest me. The list of holidays is uncopyrightable, and that's the info I extracted from their pages.

I also looked at the list of times when food stores are allowed to be open. That's actually more important to me than holidays.

I ended up making two .ics files: aukiolot2007.ics for opening hours, and suomi2007.ics for the holidays. They're probably riddled with errors: if you find any, e-mail me and I'll fix and update. I hope they're of some use for someone.

(I realize that someone is going to tell me about a complete and officially supported .ics file with all the above data as a response to this log entry. Good.)

Saturday, January 13, 2007

Random hacks: Unperish

I've been thinking lately about how to improve my process for making a release of one of the projects I work on. Actually, calling it a process is to glorify it. Each of my projects basically does things differently, but they do share some common steps:

That's a lot of tedious manual steps. I would like to automate everything so that I only need a single command, possibly excluding the upload to Debian. I have the beginnings of script that does most of this, but it is not very flexible. Actually, that's not true: I have several scripts that overlap, and together they most of the above. It's a bother to have to remember which script does what, and is suitable for which project. They're all horrible to improve upon.

I use Bazaar (bzr) for version control in all of my own projects. A couple of days ago, I looked at the builddeb plugin for bzr, which creates a Debian package (source and binary) from within a bzr branch. It doesn't do more than that, however, and I'd like to do much more.

While thinking about this some more, I realized that something tied to bzr isn't very appropriate. While I currently favor bzr, I'd really like to not tie my development processes too closely to it. If nothing else, one of the projects I'm involved in is piuparts, which is currently maintained in Subversion, and I'd like to use my automation for that as well.

Further, sometimes I package other people's software for Debian. While most of the work is similar to when I package my own software, there are some subtle differences, and again, it'd be nice to use the same automation for this as well.

And, finally, sometimes I work on fixing bugs in other people's Debian packages, and most of the automation is relevant to that work as well.

I've decided that a single, atomic command is not acceptable. What I need is a suite of commands for each of the small tasks, plus one or more scripts to combine them together. The flexibility of combining small commands should make it easy to adapt things for different workflows and scenarios.

After some hacking, I came up with Unperish. It's currently in its early stages, but I intend to keep using it and improving it, until it takes all the pain away from making a release. At least for me, but hopefully it will be of some use for other people.

Wednesday, January 10, 2007

Random hacks: Notetak, revisited

My Notetak application is slowly maturing. Some day in the relatively near future I expect it to get so mature that I need to start refactoring the code so that it isn't utter crap.

So far I've developed Notetak by doing random quick hacks, as they have occurred to me, without caring much about maintainability, unit tests, or such. This is fine for the crude prototype phase Notetak is currently going through, but it's getting to the point where making changes meets with internal resistance, since I first need to figure out a way to avoid breaking unrelated things.

Now that I have some idea of how the application should behave, refactoring it to be nicely coded is easier. Heck, it's still only 374 lines of Python, plus a .glade file, so rewriting it from scratch should only be an evening's work.

Anyway, I'm pretty happy with it now. It fits fairly well into my simple GTD workflow, it's pretty quick to work with, and generally doesn't get in my way. I miss undo/redo, and the UI is ugly, and there's no pretty icon, but the core functionality is there, and is satisfactory.

(374 lines of Python to build a useful GNOME application is pretty good, I think. The combination of GTK+, PyGTK, Python, Glade-2, and libglade, is a very powerful combination indeed.)