I am creating a python GTK3 program. I'll like to add translation support. I know how to create a .pot and .po file. However in order to make the application available in multiple languages, I need to generate .mo files. I read here that the way to generate .mo files is using the msgfmt.make command.

My question is whether I (the developer) should generate the .mo files manually in my computer and then instruct the .deb installer to move the files into the usr/share/locale/en_GB/ folder when it is being installed? Or should the .deb installer generate these .mo files while the user installs my program on his system?

In way this could be summarized as "are the .mo files machine dependant?"

2 Answers
2

Binary MO files need to be generated at build time. This means that your build system needs to have a build target to read the textual PO files used as the source and convert them to the binary MO files that will be installed in the user's system. As you correctly point out, the msgfmt command (part of the gettext tools) will ultimately create them.

So to answer the last part of the question, yes, MO files are machine-dependant.

Creating MO files the hard way

Now onto how to create them, in the standard gettext layout you'll generally have all PO files in the same directory, one per language and named after each language's ISO-639 2-letter or 3-letter code:

po/
po/ca.po
po/de.po
...

If you want to build them manually, you'll have to walk through each file in that dir and invoke msgfmt manually, e.g.

$ msgfmt -c po/ca.po -o build/locale/LC_MESSAGES/ca/myapp.mo

But you don't want to be doing this when there is already an established way and automated tools created especially for the operation of building MO files.

Furthermore, these tools take care of other associated tasks, such as extracting translations from the code and putting them all together in a POT file to give to translators to do their work.

Creating MO files the clever way

If you are using Python, I very much recommeng using the python-distutils-extra package (install p-d-e), which automates and hides away the complexity by just having to specify the following in the setup.py file you'll use to build, install and distribute your app. Same example as @dobey was already pointing out on his answer:

If you want to test translations before shipping them, you can use the handy build_i18n command from python-distutils-extra:

$ python setup.py build_i18n

This will build all the PO files in your /po folder and will put them under build (it will create it if it doesn't exist) in the same layout gettext expects when they are installed in a system.

You can then test your application with translations either by:
* Copying the contents of /build to /usr/share/locale, or
* Pointing your app to the build directory using the gettext.bindtextdomain() function:

Being even cleverer

Stand on the shoulder of giants. Simply create a test application with Quickly and copy how translations are set up in setup.py, which basically boils down to using the DistutilsExtra module in auto mode, as outlined above.

You can use the test app to play with generating translations too and learn how the generation works.

Packaging

The tarball you put together as part of a release should not include the .mo files. That is, you don't have to build them manually. That needs to happen when either someone builds the tarball contents to install manually or when e.g. a Debian binary package is being created.

Looking at your source tree, I would suggest again to use a build system such as python-distutils-extra, which will also help with the packaging. Roughly, you'll need to:

Create a setup.py file with contents similar to those suggested above

Create the packaging control files under debian/. Using p-d-e your debian/rules file can become very simple and consist of only a few lines.

Actually, you might just want to use Quickly to create the harness for the build and packaging system for your app and then replace Quickly's generated source code for the test application with your application's code.

Thank you very much for your detailed answer. I actually did try using quickly when I first started this project, however quickly creates lots of files like builders.py, etc etc...that I do not understand the working. This is why I created everything from scratch by myself without any help from quickly..So I will try to use python-distutils-extra somehow in my project..
–
nik90May 30 '12 at 15:05

You're welcome :) Regarding files that Quickly create, most of them constitute only the harness of the application. For most Quickly apps, you can ignore what's under the myapp_lib folder and concentrate on just the MyAppWindow.py file. If you find that's still too complex, there is yet another alternative: create the basic structure of an app with Quickly, remove all source code files, remove the part above the comment line from the generated setup.py file and just drop your source code inside the myapp folder (assuming your project is called myapp). It's not supported, but doable.
–
David PlanellaMay 30 '12 at 16:07

You can pass the same arguments to setup() as you normally do for your package. DistUtilsExtra.auto can automatically handle many system integration pieces such as translations, including translating static text files such as .desktop files.

I do not use setuptools/distribute/distutils for my project. My project has basically .py, .pyc and .ui files. I then use debian packaging to ensure that files are installed in the correct directory..and my desktop file basically executes the main .py file.
–
nik90May 30 '12 at 13:53

You should switch to using setup.py for it then. Using a proper build system takes care of a lot of work that otherwise has to be done manually, and makes supporting many system configurations much easier, and automatic.
–
dobeyMay 30 '12 at 15:37

yeah I realise that now..I will ask another question soon about disutils. I get the concept of using setup.py..but I am missing the bigger picture. I mean why use setup.py when I have already packaged it in .deb format? But do not answer this question since I will create a new askubuntu question for this :)
–
nik90May 30 '12 at 15:39