Author Archive

Exporting translations to a Bazaar branch

Thursday, July 30th, 2009

There used to be only one way of exporting translations from Launchpad—by requesting your files in the Launchpad UI and waiting for an email with the download URL.  It works, but it’s not very convenient if you’re trying to automate things.  It’s not that easy to make the request automatically, and then right in the middle of your script you also have to wait for the email, catch it, and parse it to get the file.

Now there’s another option: automatic exports to a Bazaar branch.  If you set up this option, Launchpad will regularly produce a snapshot of your translations and commit it to a Launchpad-hosted branch of your choice.  Now you can always find a reasonably fresh export of your translations in the same place, and download it automatically, without any asynchronous requests.

It also means that large numbers of developers or translators can get regular, fresh updates of the translation files.

How to use it

Let’s say you have a project called bzamqi. It’s set up for translation in Launchpad, and you want regular translation exports of the 1.0 release series.

The first thing you need is a branch.  It doesn’t have to be a branch for the bzamqi project, but you do have to be the owner.  (The branch can belong to a team, but then you do need to be a direct or indirect member of that team.)  The Launchpad help wiki describes various ways to create a branch:


Just remember that the branch must be Hosted, i.e. the master branch must be stored on Launchpad where we can commit to it.

Update: at the moment, team-owned branches don’t work. To work around this, make yourself the owner of the branch; set it as the translations branch; and then make the team the owner of the branch again.

Now, go to the page for bzamqi’s 1.0 release series.  You’ll be wanting the Translations tab.  Once there, pick the Settings option.

On the page that takes you to, near the bottom, there’s a section “Export translations to branch.”  You can set a branch there, and translations for the series will be exported to that branch.

If you want to disable the exports, go back (use the “pencil” icon next to the branch name to select a different branch) and select no branch at all.  Just clear the input field.  The settings page will go back to how it was before you selected a branch.

How it works

The main thing to grok is that this is not Launchpad “editing” text files for you.  The export brutally overwrites any previous versions of the files in your branch.  In the file that Launchpad writes, translations may have changed—but messages may also appear in a different order, or with different comments, and so on.

So do not expect files that you can merge back into the originals without any further work!  The Launchpad database and bzr have completely different views of this data.  There is a trick though; see the “Advanced” bit below.  Also, it will help to keep the messages in translation files in the same order in which they appear in the template.

Directory layout

In the branch, each translation file will have a normalized name (de.po for a German translation, zh_CN.po for Simplified Chinese, eo.po for Esperanto, and so on).  Each translation sits in the same directory where its template was on import.

If you have multiple templates, make sure that they have different directory paths, or the translation files for one will overwrite those for the other!  It was already recommended practice to give each template its own directory.

Templates are not exported.

Advanced: going two-way

It is possible to import translations from and export translations to the same branch.  If you push changes to a translation file into the branch, the export will not overwrite the changed file unless your updated file has already been copied onto the translations import queue.

Of course it’s still possible for the import to fail for whatever reason, and in that case your file will be overwritten.  This hopefully won’t hurt; the file that’s being exported is “better” in the sense that it shouldn’t cause any import errors.  But it may not always be what you want, so be careful if you do choose this setup.

(Your templates will not be touched, since the export doesn’t write them.)

Don’t use this “two-way” setup lightly, since it complicates things.  Complications are where accidents happen.  Either wait until there’s more practical experience with this, or make sure in some way that you won’t lose data if something goes horribly wrong.

A bit less adventurous but still useful is to have only your templates imported from a branch, and have your translations committed to the same branch.


How often do the exports happen?

For now, once a day.  We may tweak that later depending on how much this feature is used and how heavily it loads the servers.

If the export runs at a moment when you’ve pushed changes into the branch that Launchpad hasn’t processed yet, the export will not happen.  This is a deliberate protection against conflicting updates.  Unless you update your branch all the time or just at the wrong time of day, the next day’s export should catch up with the latest changes.

Why do I need to own the branch?

Otherwise you would be making Launchpad write data into someone else’s branch.  Not a nice thing to do to someone who isn’t expecting it!

If you want someone else to own the branch, you can change who owns it later, using the normal branch settings UI.  You only need to be the owner when you set it as the translations export branch.

What happens if I leave the project?

The exports keep happening to the same branch.  If that is not what you want, it’s up to the remaining project owners to choose a different branch or disable the exports.