Wednesday, June 24, 2015

GSoC 2015 Report #2 - Internationalization support for GnomeKeysign

Because the replacement of the GPG wrapper is taking longer than I have expected, I have done something that will surely make GnomeKeysign one step closer to become GNOME ready - I have added support for Internationalization and Localization.

I had no knowledge about this so I started reading this tutorial which is more customized for C projects that use autotools.
GnomeKeysign is a Python pure project and it uses distutils/setuptools for building and installing.

I will explain step by step how to add support for translations in a Python application but first I will talk a little about building & packaging in Python.

"Real artists ship. Or so says Steve Jobs." (taken from

It seemed reasonable that Python should have a packaging framework , hence distutils.
Distutils is many things: a build tool (for you), an installation tool (for your users), a package metadata format (for search engines), and more. It integrates with the Python Package Index  (“PyPI”), a central repository for open source Python libraries.

A good project layout could be the following

| -- package
|    | --
|    | --
|    `-- subpackage
|         | --
|         | --
| -- runner
| --
| -- [setup.cfg]
| --

If you want to know more about what every file does then check the Python Packaging User Guide .
Already having a good project structure , I could easily add support for internationalization (i18n).

To  add i18n support we need to accomplish these tasks:
  1. Configure the function that translates the strings
  2. Mark the strings in the code with that function
  3. Generate a template for the translators (the .pot file)
  4. Add translations
  5. Include the translations in the installation

Configure the '_()' macro

The Python gettext module allows you to mark strings in source code, extract those strings for translation, and use the translated strings in your application. It is a common practice to define macros which are shorter wrappers, like the '_()'  macro that replaces a gettext() call

import gettext
t = gettext.translation("gnome-keysign", PATH_TO_MO_FILES)
_ = t.ugettext

Mark strings for i18n

Search the source code files for strings that are visible in the GUI (window title, labels, button labels, messages, and so on) and wrap them inside '_()' function

print _("Getting ready for i18n.")

Generate template for translators

Using a command line tool, you generate a ".pot" file from the source code. This file contains all strings that need translation in the project. We only need to generate it  once or after the strings change in the code. The file is generated inside /po folder and the command used is
xgettext --language=Python --keyword=_ --output=po/gnome-keysign.pot `find . -name "*.py"`

Add translations

Then, from the ".pot" file , using another command line tool we will generate the ".po" files for each language. These are the files that translators need to complete. Inside the po/ folder we use this command
msginit --input=PROJECTNAME.pot --locale=LOCALE

But once the program is running, it doesn't use .po files directly, but a binary (compiled) version of them: the .mo files. These .mo files must be re-created on build time (when creating the package) and installed in the right location in the system.

Include translations into the project installation

The file is where various aspects of the project are configured. Alongside with the general setup arguments there is a `cmdclass` argument where we put the code to perform custom actions such as code generation, running tests, building translation files, etc.

I implemented a custom command derived from distutils.cmd.Command which will generate the '.mo' files in build time and in install time will include the '.mo' files into the data_files list. In this way we include the translations by overloading the default 'build' and 'install' instructions.

Now I can translate GnomeKeysign and run it in my language :-).

That's all for now, I will be posting again after I'm done with the GPG replacement part.


Saturday, June 20, 2015

Google Summer of Code 2015 - GnomeKeysign

Hi there,

This is the first post about my project with GNOME for GSoC 2015. I have just finished my exams and now I will be more active.

Last summer I have started from an idea: make OpenPGP keys exchange & sign easier through an app.  This is how GnomeKeysign [0] appeared.

It allows people to connect over a local network , choose from one of their personal keys to be signed by others, transfer the public key from one peer to other , sign it and send it as an email attachment back to its owner.

The app has also a minimalistic GUI and it supports web cam integration to allow for scanning a QR-encoded fingerprint of the key.

Now my job is to make this app ready for integration with GNOME. For this I am following the next points, but not necessarily in this order:

  • Remove dependencies - at the moment we use a custom build gpg wrapper to call out GnuPG and a qrencode library that is a wrapper of a C library.  We want to replace those with libraries written entirely in python (pygpgme, PyQRCode) to make distribution easier.
  • Add internationalization support - even though this isn't isn't as urgent as other points, it will offer me a good perspective on project development & deploying for GNOME.
  • Give GnomeKeysign better looks - the current GUI is designed by me (with suggests from my mentor). It requires a more professional GUI and adhere to Gnome design patterns.
  • Establish a secure channel - at this moment we only authenticate the data received, so the application only process data after it is authenticated. A secure channel would help deter attacks such as keyserver-in-the-middle.
  • Build a test harness - these tests will cover GnuPG communication, key signing, GUI testing.

This was just an introduction post. I have done some work [1] on the gpg wrapper replacement and I will blog about it soon.

See you soon,