07
Jan 10

Spanish and Galician dictionaries for Vim 7

If you write long, literary text (like end-user documentation) in Spanish and/or Galician, and Vim 7 is your editor of choice, you may want to download the spell checker dictionaries for those languages. To use them, drop the files under ~/.vim/spell. (By the way, you may need to create the directory if needed).

To use the dictionaries, just type in the needed Ex command, e.g. for Galician that would be:

  :set spell spelllang=gl

If you use modelines in your text files, you may want to add those settings there as well. That makes an easy way to choose a different language for each file. Also, do not forget to take a look at the spell checker documentation to learn more about it (tip: some keybindings are really useful).

Note that you will only be able of editing UTF-8 texts. I have not crafted ISO-8859-1 versions of the dictionary tables because no single person should be using an encoding different from UTF-8 nowadays (for a number of good reasons). If someone has a strong need for ISO-encoded tables, please let me know.

Last but not least, let me stress that the dictionaries were converted from the ones used by OpenOffice.org plus some small patches I took from the Vim SVN repository. Big thanks go to the all the people working in both projects. I am not an expert with legal stuff, but as the source files are under the LGPL I think it is safe to assume that the Spanish and Galician dictionaries generated from them are LGPL’d, too.

Remember: it is always good to deliver well-written documents. Happy 2010 ;-)


12
Dec 09

Python recipe: Functional config file parsing

Update: Added a note regarding how to do simple error handling.

Sometimes one has to parse programmatically some file containing key=value pairs. In the world of systems administration this means configuration files most of the time. Also, one thing I like is functional programming, but in the real world one ends up making almost all of the code in imperative style. Python allows some functional constructs, and sometimes I like to use them to make code most concise, because it express better what the code is trying to do or just because I wanted to melt my mind doing some functional tricks.

First, let me introduce the code:

from itertools import imap, ifilter
 
config_items = lambda iterable: \
    imap(lambda (k, v): (k.strip(), v.strip()),
        imap(lambda s: s.split("=", 1),
            ifilter(lambda s: s and not s.startswith("#"),
                imap(lambda s: s.strip(), iterable))))

Neat, huh? As promised in the title, this is functional. And yes, I am aware of ConfigParser, but I do not need its full power, and also I have found some problems with files containing Unicode strings.

I think this is one of the most beautiful snippets of code I have ever written in Python: it makes just one thing well, and it is terse and concise. Moreover, it is quite easy to explain.

How does it work

I have just written that it is easy to explain how this works. Okay, I will dissect this beast one line at a time, starting at the innermost. But first, a quick introduction to imap() and ifilter:

  • imap(): Works like map(), which returns a list whose contents are the results of applying a function (first argument) to each of the elements of another list (the second argument). The difference is that imap() uses generators instead.
  • ifilter(): This one works like filter() and will also return a list, whose contents are the items of another list (second argument) for which the result of calling the given function (first argument) is True. This one also works with generators.

Now, let us start with the first one:

imap(lambda s: s.strip(), iterable)

This picks each line, and removes whitespace sitting at the left and and the right of the string.

ifilter(lambda s: s and not s.startswith("#"),

We want to keep interesting lines: empty lines and comment-lines starting with a hash mark (#) must be thrashed away. We check for lines which both are not empty and that do not start with a hash-mark.

imap(lambda s: s.split("=", 1),

That one picks each string and splits it at the first = character, thus separating the key from the value. This is what converts each string into a (key, value) tuple.

imap(lambda (k, v): (k.strip(), v.strip()),

This is the last remaining detail: Removes extra leading and trailing whitespace from the keys and values of the generated tuples. This is needed for removing the spaces around the = character.

How to use it

Fire in the interpreter, type in (or copy-and-paste) the above code and guess by yourself:

>>> text = """a = 1
... b = this is b"""
>>> tuple(config_items(text.splitlines()))
(('a', '1'), ('b', 'this is b'))
>>> dict(config_items(text.splitlines()))
{'a': '1', 'b': 'this is b'}
>>>

So you pass it a list an iterable which yields lines, and it will return another iterable, which yields (key, value) tuples. Thanks to how dict() is defined, we can directly pass the result to it and get a dictionary.

But it would be useful as well to use it on files, so here we go:

>>> file("test.conf", "w").write(text)
>>> dict(config_items(file("test.conf").readlines()))
{'a': '1', 'b': 'this is B'}
>>>

For your convenience, you may want to define a helper function if it makes you feel more comfortable:

>>> def config_file_items(path):
...    with file(path, "rU") as f:
...        return config_items(f.readlines())
...
>>> dict(config_file_items("test.conf"))
{'a': '1', 'b': 'this is B'}
>>>

Extra niceties

I have already mentioned that this code uses generators in its entirety. What is passed from one function to another in the chain of imap() and ifilter() calls are always generators. This means that if config_items() is used to read a big file (e.g. some hundreds of megabytes) only one line is in memory at a given time. This is why I did not use map() and filter() but their “incremental” counterparts from the itertools module. So the bottom line is that this may not be the most efficient implementation out there, but it is good and is capable of working over arbitrarily long sequences of data while the function remains small and understandable.

Error Handling

Whenever the input is not well formed, then this function will raise ValueError when a = character is not found in some line. This means that you can do something like this:

import sys
try:
    items = dict(config_items(sys.stdin.readlines()))
except ValueError:
    raise SystemExit("Malformed 'key=value' input in standard input")

Of course more elaborate error checking could be done i.e. to be able of showing to the user the exact offending line number, but the goal is to keep things as simple as possible. Also the syntax of those simple configuration files is so simple that it should be fairy simple for the user to spot typos.

Final words and advice

My advice is that if you have the possibility, make your Python code in such a way that it uses generators, unless you are sure that it will always handle reasonably small amounts of data.

I hope that things are explained well enough, and (who knows!) maybe this can help someone to better understand why generators are a good idea. I will also be happy if you came here looking for some code to parse simple configuration files and this did the trick for you :D


04
Nov 09

Branching, merging, rebasing…

Giggle Graph

The image at the left is exactly what Giggle shows in this very precise moment for one of my coding projects. I think this is the most complex commit graph I have seen during my occassional coding tasks… This is how Git is supposed to be used: a branch per feature, and small atomic commits. Definitely I like this way of working :D

(This post is no more a small coding break… just to leave some neurons rest before reclaiming them back :D )


02
Nov 09

Running older (pre-etch) Debian releases

This post is quick public information service for everyone using, or having to deal with old Debian releases. This includes all releases prior to Etch: Woody, Sarge, Potato…

You have probably noticed that you cannot longer use APT to install packages in your system.
The package repositories have been moved over to archive.debian.org, so you will need to change your /etc/apt/sources.list accordingly. For Sarge, you would use:

deb http://archive.debian.org/debian sarge main contrib non-free
deb http://archive.debian.org/debian-security sarge/updates main contrib non-free

You may even use archived repository of backports.org of Sarge, adding a line like this:

deb http://archive.debian.org/backports.org sarge-backports main contrib non-free

This way one can inject some fresh air into an existing Debian setup if making a full system upgrading is not an option for you.

Have a lot of fun…


19
Oct 09

Factor out your Apache-fu with mod_macro

For nearly all HTTP-serving related work, our software of choice is the Apache web server. Lately, we have been moving some old setups which were still running Apache 1.3 to the latest version in the 2.x series. This may be a lot of work when the number of virtual hosts you are serving is far from low, or if you have some lengthy, repetitive configuration blocks which must be modified everytime you want introduce some change. One may be tempted to auto-generate configuration snippets from something else using some quick Bash/Perl/Python/Whatever script, but there is a more elegant solution: meet mod_macro.

As the name suggests, it is an Apache 2.x module which allows for defining snippets with customizable optional parameters. Take this real-world example from /etc/apache2/mods-available/macro.conf:

<Macro AuthLDAPSetup $group>
  AuthType basic
  AuthBasicProvider ldap
  AuthLDAPUrl ldap://ldap.local/dc=igalia,dc=com?uid
  AuthLDAPGroupAttribute uniqueMember
  AuthLDAPGroupAttributeIsDN On
  Require ldap-group cn=$group,ou=Group,dc=yoursite,dc=com
</Macro>

This is a common setup in most of our services, so now everytime one wants to add autentication against the LDAP server, it is only a matter of adding an Use clause in the proper place:

<VirtualHost *:443>
  # Virtual host configuration cruft skipped from example!
  <Location />
    Use AuthLDAPSetup wwwusers
  </Location>
</VirtualHost>

Ta-da! This is 5 lines shorter, and less error-prone. Also, if some day some extra configuration is needed to authenticate using LDAP, it is enough to change the macro definition, and changes will be automatically propagated to all places where it is used.

Wrapping up, you may consider installing mod_macro in your Apache installs for the following reasons:

  • Greatly simplifies repeated code snippets in configuration files.
  • It is integrated with the web server: no external tools are needed.
  • Is especially useful to make changes to big sites in a single shot.
  • Does not add overhead to request processing, only to initial configuration file parsing at server startup.
  • It is simple enough to learn and use in a couple of minutes.

:-)


25
Sep 09

Two months after…

Two months have passed after my last post, and things here have been quieter than usual in this blog, but the world kept moving in the meanwhile so there are some things to tell, and some other that have already been told. Probably the most exciting thing for me and my work mates was the announcement of the shiny Nokia N900. I have resisted the temptation then, because a lot of things have already been said about it. We systems administrators are usually in the shadows, but even so it is a delight working as backing support for people who does big things.

There were a couple of releases this week what are a great example of why Igalia reached its eighth year, and we are still rockin’ in the free world:

  • Hildon 2.2.0, the user interface toolkit used in Maemo. No words are needed to explain how awesome is this!
  • Also, some of my work mates are fine-tuning MAFW after bringing it to life in order to provide multimedia coolness to Maemo, and (who knows!) maybe the desktop as well. Of course all built on top of the lovely GStreamer libraries.
  • GNOME 2.28, which includes the hard work from a lot of work in form all around the world, and a revamped Epiphany web browser which uses WebKitGTK+ as the rendering engine. This means that some of my colleguaes have been killing kitties and their hard work will be deployed in every GNOME install!
  • Frogr 0.1, a tool which carries out out the simple (but important) task of uploading pictures to Flickr, and it is doing a fine task for me right now.
  • In the operating systems ground, Haiku R1 Alpha 1 has been released. This may sound like “some other hobbyist operating system”, but it is a lot more than that: it is a new life for the mighty BeOS R5, which  took eight years to to bring from the dead. I have played a bit with the live CD: the experience is great, although somw rough edges still exist, but I would say that Haiku contains lots of superb work and I am eager to install it in some real hardware.

But more changes apart from software releases happened: in a more personal note, I am now using Fedora 11 in a daily basis at my laptop. Initially I wanted to try out Foresight, because the Conary package manager looks like an interesting piece of software, but unfortunately the installer does not have support for LUKS-encrypted volumes in the installer, and I did not want to bootstrap it manually. Interestingly enough, Fedora does have such support using the same Anaconda installer. I did not like Fedora back in version 6, but I must admit that the community did an impressive improvement (at least comparing version 6 to version 11!) and I am very happy with my current setup. I am even considering Fedora 11 for installing it on my brand new PlayStation 3: I bought one of the old “fat” models, because the new “slim” ones do not officially support installing third-party operating systems.

Finally, a quick note to finish this “I am alive” post: I am glad that we have decided to push Linux-vServer in our servers, because we are getting some interesting benefits thanks to it, being the main one the ability to easily clone a running machine and use the clone for testing purposes before applying changes in the production environment. Also, we are now able of easily provide sandboxed environments in which users have almost-full administrative privileges without having to worry about other services being affected in case something goes wrong. And we are getting those niceties with a minimal overhead (~1.5%) in terms of kernel CPU usage. As we are moving services which were previously run on physical machines into virtual machines, we are saving power and contributing to the environment while providing a better service and support to our staff :-D


02
Aug 09

More DebConf9 adventures

Now it looks like it is time to complete my previous post about DebConf9, after a tiresome journey back from Cáceres to Coruña the 30th, an Igalia assembly the 31st (the first one ever for me :-D ), and sleeping for more than 14 hours today.

Fortunately I did not need to travel alone, as Diego came with me to visit Coruña and the journey was more enjoyable than the other way around. To make the most out of the occasion, we followed an alternative route via  Ciudad Rodrigo (where we had lunch and bought some red wine, olive oil, and Iberian “embutido”: chorizo, salchichón and cured loin), then Porto (where we saw the bridges by Gustave Eiffel and his disciples), Valença do Minho (where we bought some goods which are sold in Portugal: salted butter, cheese, coffee, guava jelly…) and finally we made a longer stop at Santiago de Compostela in order to see the cathedral and the old town area while eating a sandwich. It took some time to complete the trip, but was far funnier that going alone to Cáceres.

But going back on to DebConf9, here is the rest of my batch of lectures and events, including summaries of them:

  • Free travel instead of free beer: Very nice presentation of photographs from all past DebConf and FLOSS related events, by Andreas Tille who has attended loads of them! This was a quite relaxing event, and the people there made the thing more enjoyable by telling the others about anecdotes and funny things about the places and the things which happened all along the world in past conferences.
  • Stable/Volatile/Backports ecosystem: This was a nice chat trying to define how the different Debian repositories should interact between each other. I think that the nicer part was including the not-so-official backports.org repositories, but nothing has been said about including debian-multimedia. It is a good thing to be coherent with the DFSG and being picky with which packages are actually in the main repository, but in my opinion something should be done to support the packages the users want in some way, including debian-multimedia as well.
  • Qemu for Debian developers: Not something which could be considered astonishing, but I have learned a couple of nice Qemu tricks with this. This was an interesting introduction for people wanting to make packages for architectures different than the one they are running.
  • Drowning in bugs: This was an extremely interesting chat about how it would be possible to actually get people to do bug triaging in Debian. Some solutions were outlined, like having some kind of teams for people to belong to, so they get at least some social recognition (e.g. “look, I am part of the Debian Foo-Bar Bugsquad” and the like), adding a score meter to the BTS like in the Gnome Bugzilla and so on. I think that something which should is being cooked right now will help a lot with this.
  • Libvirt, hypervisor independent virtual machine management: I heard before about libvirt, but have always thought that it looked like an unneccessary layer of indirection about THE virtualization technology you want to use. The facts are that it does not have Linux-vServer support (well, it might) and that one gets an interesting feature: remote management of virtual machines. Does that feature that pose much differences from using SSH to open a remote session? Probably if you use Qemu and/or Xen, but I do not see the point of having the additional hassle of another software layer.
  • Debian Redesign: Agnieszka aka “pixelgirl” proposed a new design for some stuff related to Debian, logo, colours, fonts and website. Some minor work for boot splash screens and is also there in the pack. It was funny to see how people asked questions about the openness of the license of the new font used for the logo, when the old one has a commercial one… I hope that she does not get annoyed too much by the rest of the community, because I also think there is a real and urgent need to give some love to how things look in Debian. And having people which has the neccessary knowledge to properly design nice things is great, so the community should support her.
  • State of the Bug Tracking System: Don Armstrong was making some improvements and cleanups to the old debbugs big code clean-up, and presented to the public one new feature which allows to mirror the state of the BTS and run a local copy. This made all the audience clap hands like crazy, as this allows for speedier operations, especially for searching and filtering in reports.
  • Introducing DebConf10: New York will held the next DebConf, which will be also the 10th anniversary of the event. The main venue will be at the Columbia University which looks great for such a thing. The main issue could be problems for people living in certain countries to get a visa so they can travel there the next year, so the organizers will be even providing legal advice and support. I just hope that this will not make the next edition be a “DebConf light” and that people from all around the world is represented the next year.
  • Debian on Network Attached Storage (NAS) devices: First of all, as most igalians have a NSLU2, I would want to say that Martin has already found the perfect and improved replacement for them: the Marvell SheevaPlug. It is great to see how well GNU/Linux is spreading over to all kinds of devices and architectures. And it is even nicer to see how the developers have designed a way for seamlessly installing Debian in this kind of devices in such a way that an average user could do it without requiring ninja skills.

That’s a good selection of the lectures and events I attended to. Of course there were some more interesting things, like the conference dinner, the massive group photo, giving a talk (slides here), the odyssey all along Cáceres to find a proper Irish tavern… The pint of Guinness with Gunnar, Gustavo and Diego was one of the best moments of the conference ;-)

Quick summary: going to DebConf9 was a rewarding experience, even when I ended up extremely tired after it. Let’s try to attend some more conferences anytime soon…


27
Jul 09

First day at the DebConf9

I arrived yesterday at the main venue after a the long trip by car: ~700km in a car without air conditioning. I was very tired so I headed up for my room (which is in an ancient building at the old town area of Cáceres), had a shower and decided to take a nap… with so much success that I slept for two hours and a miracle made me wake up just in time for the Cheese & wine party. It was great to taste an uncountable amount of kinds of cheese, wine and liquors from places all around the world. Among a lot of tasty stuff, it was really enlightening to try out some real japanese sake and the best peanuts I ever tried.

After a quick breakfast today in the morning, my personal schedule included attending the following:

  • Using FOSSology for license analysis in Debian: a tool which determines which license a package has by examining its sources and looking for license disclaimers and similar texts contained in source code was presented. This way even cases where each source file may have a different license can be easily identified. For packagers this makes easier to check whether a software component complies with the packaging policy.
  • Not your grandpa’s debhelper: This one really catched my attention, as I do some packaging from time to time it is very interesting to know about new incarnations of tools which suppose an aid to this task. The new dh thing is able of greatly simplifying build rules. I wanna try it!
  • Debian System Administraors BoF: I thought that it could be interesting to know how systems used for running the Debian infrastructure are configured. Three of the members of the team asked lots of questions from the audience, most of them being about e-mail services and whether it would be possible to improve spam handling.
  • Scratchbox2 for cross-compiling Debian: It was a shame that there was no projector nor something similar for Riku to give an introduction to Scratchbox 2, which looks like a good step forward. For example now it is possible to use it without root privileges at all.
  • Point releases – How to update stable more efficiently: I have missed some bits of this lecture because I was sitting near the end of the room, but if I understood correctly there is a plan for rolling updates sooner into the Debian stable package set by using a repository in the fashion of the Ubuntu “proposed-updates” one, so users can get theirs hands on sooner on the packages in order to provide the needed feedback for stabilization.

After having a light dinner I went along with Diego for a walk along the old town area, to see how does it look at night. The perfect accompaniment was a glass of beer and a magnificent ice cream. And that is enough for today… :-D


24
Jul 09

See you at DebConf9

DebConf9 LogoI will pick up my car and embark myself into a 8-hour trip to reach Cáceres tomorrow in the evening, after 699 km of road trip. The goal: attending (and enjoying!) the ninth edition of the Debian Conference, which has already started. As I do not know exactly the arrival time, I will skip the dinner tomorrow, but I will do my best to be at the Cheese & wine party and bringing some “tetilla” (small breast) cheese from Galicia, which has a funny shape as you can imagine:

I am looking forward to be there tomorrow, as this will be my first time at a big community event and it really looks like this kind of things are really interesting and a great opportunity to get in touch with latest developments, learning lots of new stuff, and meeting people from all around the world… The latter is a must for me, as I will not know anyone there because there will be no more Igalians attending the conference. So if you will be there from 25th to 30th feel free to approach me and have some chat :-D

Last, but not least, shell scripters (and anyone interested) may want to know that have a slot in the unofficial track for a  lecture on Shaft, a tool which we have been using lately to do declarative unit testing of shell scripts. I am just now polishing the slides, preparing a couple of examples and preparing the code for release.

See you there!


16
Jul 09

My own Gtk+ theme

I have never been completely happy with how the widgets of Gtk+ applications looked like. Undoubtedly the “Clearlooks” theme was an impressive improvement, but it has some glitches with some applications (for example Claws-Mail has to be tamed to look good with some themes) and I always had the curiosity of knowing how a theme is made. So I picked up the Chrome theme which uses the Murrine engine, and modified it to have warm gray colors, and the Gnome panel with the same shades as the rest of the widgets. After some tweaking I came up with this:

It makes a smooth, clean environment without too much distractions, apart from the blue shades of the selected items, so it is a good option for everyday use. Especially if you spend loads of hours in front of a computer. It matches nicely with the “Clearlooks” theme included in the latest versions of the OpenBox window manager (which I use).

I think this is nice enough to share, so you may want to get the theme conveniently packaged as a tarball.