<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Jtv on Launchpad Blog</title>
    <link>https://blog.launchpad.net/authors/jtv/</link>
    <description>News and updates from the Launchpad team</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 19 Sep 2011 12:46:10 +0000</lastBuildDate>
    <atom:link href="https://blog.launchpad.net/feed/authors/jtv/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Translation imports: making approval conflicts visible</title>
      <link>https://blog.launchpad.net/translations/translation-imports-making-approval-conflicts-visible/</link>
      <pubDate>Mon, 19 Sep 2011 12:46:10 +0000</pubDate>
      <dc:creator>Jeroen Vermeulen</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=2858</guid>
      <description>&lt;p&gt;If you use Launchpad&amp;rsquo;s Translations feature, then as of today, you may notice a new kind of error for uploads in your translations import queue. Look for the &amp;ldquo;&lt;a href=&#34;https://blog.launchpad.net/images/posts/2011/09/Info-icon.png&#34;&gt;&lt;img src=&#34;https://blog.launchpad.net/images/posts/2011/09/Info-icon.png&#34; alt=&#34;info&#34;&gt;&lt;/a&gt;&amp;rdquo; icon next to your upload&amp;rsquo;s status, and click to unfold. The error message says &amp;ldquo;Can&amp;rsquo;t auto-approve upload: it&amp;rsquo;s not clear what template it belongs to.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.launchpad.net/images/posts/2011/09/Sample1.png&#34;&gt;&lt;img src=&#34;https://blog.launchpad.net/images/posts/2011/09/Sample1-300x214.png&#34; alt=&#34;Sample&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You may find this annoying, and as the person responsible, let me apologize. I hope when I&amp;rsquo;m done explaining, it won&amp;rsquo;t seem so bad.&lt;/p&gt;
&lt;p&gt;To the right is an example of the error.  Click it to see more.&lt;/p&gt;
&lt;p&gt;Where does the error come from? Actually it&amp;rsquo;s a problem that&amp;rsquo;s always been there, but instead of telling you about it, we Launchpad developers tried to hide the complexity from you and take care of it all ourselves. And we weren&amp;rsquo;t keeping up. Some of your uploaded translations would just sit in the queue forever, with status Needs Review, for no clear reason. All that&amp;rsquo;s changing now is that Launchpad will tell you when this happens, so that you can deal with it without waiting for us.&lt;/p&gt;
&lt;h2 id=&#34;why-do-some-translations-sit-in-the-queue-forever&#34;&gt;Why do some translations sit in the queue forever?&lt;/h2&gt;
&lt;p&gt;Every translation you make in Launchpad has to go into a specific template and language. Usually it&amp;rsquo;s obvious where you want your translation to go: when you translate in Launchpad&amp;rsquo;s web UI, you&amp;rsquo;re already on the page for a specific template and language. If you have upload privileges for the project and language, you can follow the upload link from that same translation page and again it&amp;rsquo;s obvious which template you&amp;rsquo;re translating and to what language. If you always upload the same file with exactly the same name and path, new uploads of that file go to the same place as before. But what if you upload a new file from the release-series page, or the translation comes in from a Bazaar branch or an automated build?&lt;/p&gt;
&lt;p&gt;Then it&amp;rsquo;s up to a script we call the Translations Import Queue Gardener. The Gardener periodically scans all waiting uploads—the ones marked Needs Review—and tries more advanced ways of matching them up with known templates and languages. When it finds a match, it approves the upload&amp;rsquo;s import to the template and language it has found.&lt;/p&gt;
&lt;p&gt;One of the Gardener&amp;rsquo;s most important tools is a template&amp;rsquo;s &amp;lsquo;&amp;rsquo;translation domain.&amp;rsquo;&amp;rsquo; This is a simple name; no slashes or weird characters allowed. Launchpad figures out a template&amp;rsquo;s domain when you first import the template, based on its directory path. In principle a template&amp;rsquo;s domain should identify the template uniquely on the end-user&amp;rsquo;s system, but Launchpad isn&amp;rsquo;t as strict about it. It just assumes that the domain name is tied to the template file&amp;rsquo;s path within a project&amp;rsquo;s source tree. You probably shouldn&amp;rsquo;t, but you can give your project two templates with the same domain if you want.&lt;/p&gt;
&lt;p&gt;When you upload a translation, the Gardener tries to figure out its translation domain based on the file&amp;rsquo;s path, just like what happened when the template was created. The Gardener looks for a template with the right domain in the same release series. If it finds one, presto: it&amp;rsquo;s got the template that the upload is meant for. If not, then the Gardener tries a few other things and if nothing works, simply keeps the upload on the queue.&lt;/p&gt;
&lt;p&gt;So the entry doesn&amp;rsquo;t get imported, but usually the Gardener can&amp;rsquo;t give any single reason: all it knows is that it tried many ways of matching the file to a template and none of them worked. Maybe it&amp;rsquo;s an error; maybe it&amp;rsquo;s just a matter of waiting for the right template to be created.&lt;/p&gt;
&lt;h2 id=&#34;so-whats-changed&#34;&gt;So what&amp;rsquo;s changed?&lt;/h2&gt;
&lt;p&gt;The new error message is about &amp;ldquo;approval conflicts.&amp;rdquo;  You&amp;rsquo;ll see it when there is &amp;lsquo;&amp;lsquo;more than one&amp;rsquo;&amp;rsquo; matching template for your upload.  This can happen because your project&amp;rsquo;s directory structure is unusual and Launchpad can&amp;rsquo;t extract a meaningful domain from it.  Or a template&amp;rsquo;s domain may have been changed, or an old deactivated template is reactivated when a new one has already taken its place.&lt;/p&gt;
&lt;p&gt;Whatever the cause, the new error message tells you that this has happened, and what the matching templates are.  It&amp;rsquo;s up to you to decide what needs to be done about it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;update one of the templates&amp;rsquo; domains, or&lt;/li&gt;
&lt;li&gt;deactivate an obsolete template, or&lt;/li&gt;
&lt;li&gt;move a file, or&lt;/li&gt;
&lt;li&gt;re-upload your file to a specific template, or&lt;/li&gt;
&lt;li&gt;re-upload your file with a different name, or&lt;/li&gt;
&lt;li&gt;upload translations as a tarball so that Launchpad sees their full directory paths.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How much you can do, of course, depends on the permisisons you have.  Only the project&amp;rsquo;s owners (and Launchpad&amp;rsquo;s administrators) can deactivate templates or change their domains.  But you can always delete your own uploads if you want to upload your file differently: on the import-queue page, click on Needs Review and select Deleted instead.&lt;/p&gt;
&lt;h2 id=&#34;let-us-know&#34;&gt;Let us know&lt;/h2&gt;
&lt;p&gt;There&amp;rsquo;s still plenty more we&amp;rsquo;d like to do to make imports easier and more efficient, if we can find the time.  But I hope this small change will make your life a little easier.&lt;/p&gt;
&lt;p&gt;Is this error message working for you?  Is it helpful?  Are you seeing a lot of these errors, or none at all where you were expecting them?  Is the explanation unclear?  Do you see something happen for lots of people that we could fix in the same way?  Please get in touch:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Contact &lt;tt&gt;danilos&lt;/tt&gt; or &lt;tt&gt;jtv&lt;/tt&gt; on IRC, in &lt;tt&gt;#launchpad&lt;/tt&gt; on Freenode.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://bugs.launchpad.net/launchpad/&#34;&gt;Find or file a bug&lt;/a&gt; if it&amp;rsquo;s broken.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;tips&#34;&gt;Tips&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;If you want to become more familiar with the translations import queue, check out the &lt;a href=&#34;https://translations.qastaging.launchpad.net/+imports?field.filter_status=NEEDS_REVIEW&#34;&gt;global queue&lt;/a&gt; to see all uploads in Launchpad.  The version you see there is just a copy on a test server, so don&amp;rsquo;t be afraid to play with it.&lt;/li&gt;
&lt;li&gt;By the way, did you know about our test servers?  We test our changes on &lt;a href=&#34;https://staging.launchpad.net/&#34;&gt;staging&lt;/a&gt; and &lt;a href=&#34;https://qastaging.launchpad.net/&#34;&gt;qastaging&lt;/a&gt; servers before they go live.  You can try out most of Launchpad&amp;rsquo;s features there.  Look for the grey &amp;ldquo;demo&amp;rdquo; text in the background.  They get restored to a fresh copy of the real Launchpad once a week.&lt;/li&gt;
&lt;li&gt;Tired of creating translations tarballs and uploading them to your project?  Automate it all with &lt;a href=&#34;https://help.launchpad.net/Translations/YourProject/ImportingTranslations&#34;&gt;Bazaar integration&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You want Bazaar integration but your code is hosted outside Launchpad and/or in a different revision control system?  You can tell Launchpad to &lt;a href=&#34;https://help.launchpad.net/Code/MirroredBranches&#34;&gt;mirror a branch from elsewhere&lt;/a&gt;.  Then you can import translations from the mirrored copy.&lt;/li&gt;
&lt;li&gt;We like transparency!  If you&amp;rsquo;re interested in the engineering details of this change, &lt;a href=&#34;https://code.launchpad.net/~jtv/launchpad/bug-613823/+merge/75773&#34;&gt;it&amp;rsquo;s all online&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Trying Out Launchpad Translations</title>
      <link>https://blog.launchpad.net/general/trying-out-launchpad-translations/</link>
      <pubDate>Tue, 22 Dec 2009 13:31:15 +0000</pubDate>
      <dc:creator>Jeroen Vermeulen</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=1258</guid>
      <description>&lt;p&gt;You may already know this: if you want to try out Launchpad, there&amp;rsquo;s a &amp;ldquo;playground&amp;rdquo; version of the site at &lt;a href=&#34;https://staging.launchpad.net/&#34; title=&#34;Staging&#34;&gt;https://staging.launchpad.net/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This site gets refreshed daily (or almost daily) with the latest copy of the database that&amp;rsquo;s behind the real, production Launchpad site.  That makes it a good place to mess around: it&amp;rsquo;s pretty realistic but you won&amp;rsquo;t damage anything, and you won&amp;rsquo;t pollute Launchpad&amp;rsquo;s real database with fake information.  It also runs newer code than the production site, so the Launchpad developers themselves use it for testing their latest changes.&lt;/p&gt;
&lt;p&gt;Until recently, you couldn&amp;rsquo;t really test Launchpad Translations on the staging site: you needed help from an admin to get your templates imported, and if you got that done before they were overwritten by the daily refresh, you couldn&amp;rsquo;t export your translations.  But today things are a lot better thanks to translation imports from, and exports to, bzr branches.&lt;/p&gt;
&lt;p&gt;You will need:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A Launchpad login.  You can only get this on the real Launchpad; but it will also be valid on staging.&lt;/li&gt;
&lt;li&gt;At least one gettext translation template (&amp;quot;.pot file&amp;quot;) with strings from your program.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The translation template should have a filename in all lower-case letters and end in &amp;ldquo;.pot&amp;rdquo; as a filename extension.  It should contain English &amp;ldquo;msgid&amp;rdquo; strings and empty &amp;ldquo;msgstr&amp;rdquo; strings as usual in the gettext format.  (The msgstr strings don&amp;rsquo;t actually need to be empty, but in a template their contents will be ignored.)&lt;/p&gt;
&lt;p&gt;You will be setting up:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A bzr &amp;ldquo;development branch&amp;rdquo; on staging.  This is how your templates get into the system.&lt;/li&gt;
&lt;li&gt;A bzr &amp;ldquo;translations branch&amp;rdquo; on staging. The system will write your translations into this branch.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s how you set up and test translations on the staging site.  With each of these steps, always make sure you&amp;rsquo;re working on staging, not on the production site!  The staging site has the word &amp;ldquo;demo&amp;rdquo; scrawled diagonally across the page background.  You may need to log in separately on this server; your account and password are the same as on the real Launchpad site.&lt;/p&gt;
&lt;h2 id=&#34;1-set-up-a-project&#34;&gt;1. Set up a project&lt;/h2&gt;
&lt;p&gt;You can do that on the &lt;a href=&#34;https://staging.launchpad.net/projects/+new&#34;&gt;project registration page&lt;/a&gt;.  Or if you already had your project registered on the production site, it will show up in staging as well.  In that case, just work with the project you have.&lt;/p&gt;
&lt;p&gt;On the project&amp;rsquo;s main page in staging, select &amp;ldquo;Change details.&amp;rdquo;  This takes you to the project&amp;rsquo;s setting page.  Enable translations: check the box labeled &amp;ldquo;Translations for this project are done in Launchpad&amp;rdquo; and submit using the Change button at the bottom.&lt;/p&gt;
&lt;p&gt;Your project should have a &amp;ldquo;trunk&amp;rdquo; release series.  This is where you will be doing most of your work.  Another release series will work just as well, but trunk is the default.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://help.launchpad.net/Translations/YourProject&#34; title=&#34;Detailed documentation&#34;&gt;&lt;em&gt;Detailed documentation&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;2-set-up-a-development-branch&#34;&gt;2. Set up a development branch&lt;/h2&gt;
&lt;p&gt;You may already have a development branch set up on the real Launchpad.  But staging is a separate environment that does not have copies of your production branches, so you&amp;rsquo;ll have to set up a branch on staging anyway.  Like everything else on staging, this branch will disappear when the staging site is refreshed.&lt;/p&gt;
&lt;p&gt;The first thing to do is to make sure your bzr program is logged into Launchpad:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr launchpad-login mylogin&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Where &lt;em&gt;mylogin&lt;/em&gt; stands for your Launchpad login name).  Next you&amp;rsquo;ll push a branch to the staging server.  How to do this depends on whether your project already has a bzr branch on Launchpad:&lt;/p&gt;
&lt;h3 id=&#34;a-you-have-a-bzr-branch-on-your-local-system&#34;&gt;a. You have a bzr branch on your local system&lt;/h3&gt;
&lt;p&gt;You&amp;rsquo;ll have to push a copy of the branch to the staging server.  Open a command-line shell and go into your branch.  Then, supplying your own Launchpad login and project name in the obvious places, push the branch:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr push &amp;ndash;use-existing-dir lp://staging/~mylogin/acme-zyzzyx/testbranch&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This may complain:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr: ERROR: Target directory lp://staging/~mylogin/acme-zyzzyx/testbranch&lt;br&gt;
already exists, but does not have a valid .bzr directory. Supply &amp;ndash;use-existing-dir&lt;br&gt;
to push there anyway.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If it does that, just run the command again and it should work.&lt;/p&gt;
&lt;h3 id=&#34;b-you-have-a-bzr-branch-on-launchpad&#34;&gt;b. You have a bzr branch on Launchpad&lt;/h3&gt;
&lt;p&gt;Go to the regular Launchpad page for the branch.  The page will show how to access the branch using the bzr command-line tool.  For example,&lt;/p&gt;
&lt;p&gt;Get this branch:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr branch lp:acme-zyzzyx&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(That is assuming that your branch is the main development branch for a project called &amp;ldquo;acme-zyzzyx.&amp;rdquo;  Yours probably has a different name; it could also be of another form such as &amp;ldquo;lp:~mylogin/acme-zyzzyx/trunk&amp;rdquo;).&lt;/p&gt;
&lt;p&gt;On your local system, go to some empty directory where you can create temporary data.  Execute the &amp;ldquo;bzr branch&amp;rdquo; command line there.  This creates a directory with your branch contents.  Go into that directory, and push the branch to staging.  You do this using the &amp;ldquo;bzr push&amp;rdquo; command:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr push &amp;ndash;use-existing-dir lp://staging/~mylogin/acme-zyzzyx/testbranch&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Of course you use your own login and project name instead of &amp;ldquo;mylogin&amp;rdquo; and &amp;ldquo;acme-zyzzyx&amp;rdquo;).  The &amp;ldquo;bzr push&amp;rdquo; command creates a real branch on staging.  It may complain:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr: ERROR: Target directory lp://staging/~mylogin/acme-zyzzyx/testbranch&lt;br&gt;
already exists, but does not have a valid .bzr directory. Supply &amp;ndash;use-existing-dir&lt;br&gt;
to push there anyway.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If it does that, just run the command again and it should work.&lt;/p&gt;
&lt;h3 id=&#34;c-you-dont-have-a-bzr-branch&#34;&gt;c. You don&amp;rsquo;t have a bzr branch&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s okay if your branch is actually in some other revision control system such as subversion or git.  Create a temporary copy of your source tree, so you can play without damaging anything.  From the command line, go into the copy and run:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr init&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now use &amp;ldquo;bzr add&amp;rdquo; to add all the files that you want to see appear in the staging branch.  For testing the only part that really matters is your translation templates:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr add po/messages.pot&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Your directory structure and filenames may be different of course, but the filename should end in .pot.  Commit your changes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr commit -m &amp;ldquo;Setting up test branch.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Congratulations—you have now set up a bzr branch for your project.  Push a copy to the staging server.  Supplying your own Launchpad login and project names in the obvious places, type:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr push &amp;ndash;use-existing-dir lp://staging/~mylogin/acme-zyzzyx/testbranch&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This may complain:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr: ERROR: Target directory lp://staging/~mylogin/acme-zyzzyx/testbranch&lt;br&gt;
already exists, but does not have a valid .bzr directory. Supply &amp;ndash;use-existing-dir&lt;br&gt;
to push there anyway.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If it does that, just run the command again and it should work.&lt;/p&gt;
&lt;p&gt;Make a note of that &amp;ldquo;bzr push&amp;rdquo; command line.  You can make changes to the template later, commit them, and push them to the same location.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://help.launchpad.net/Code/QuickStart&#34; title=&#34;Detailed documentation&#34;&gt;&lt;em&gt;Detailed documentation&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;3-set-up-a-translations-export-branch&#34;&gt;3. Set up a translations export branch&lt;/h2&gt;
&lt;p&gt;Besides import your template from a bzr branch, Launchpad can also export the template&amp;rsquo;s translations to a bzr branch.  The real Launchpad site does this once a day, but since staging doesn&amp;rsquo;t do any of the heavy lifting, and data on staging doesn&amp;rsquo;t have so long to live, it does this every hour.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with an empty branch for this that will contain just the translations.  There can be good reasons to do it differently in your real project, but exporting to an empty branch is always a good way to start.  That way you can make sure that the exports really do what you want them to before making Launchpad write to a real branch.&lt;/p&gt;
&lt;p&gt;In some temporary directory on your system, run this from the command line:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;mkdir translations-export-test&lt;br&gt;
cd translations-export-test&lt;br&gt;
bzr init&lt;br&gt;
bzr commit &amp;ndash;unchanged -m &amp;ldquo;Setting up translations branch.&amp;rdquo;&lt;br&gt;
bzr push lp://staging/~mylogin/acme-zyzzyx/translations-export-test&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(Here you probably see another complaint about &amp;ldquo;Target directory [&amp;hellip;] already exists, but does not have a valid .bzr directory.&amp;rdquo;  Just run that last command line again to get past it.)&lt;/p&gt;
&lt;p&gt;Make a note of the exact URL in that &amp;ldquo;bzr push&amp;rdquo; command.  You&amp;rsquo;ll be pulling the exported translations from there into your local branch.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://help.launchpad.net/Code/UploadingABranch&#34; title=&#34;Detailed documentation&#34;&gt;&lt;em&gt;Detailed documentation&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;4-configuring-imports-and-exports&#34;&gt;4. Configuring imports and exports&lt;/h2&gt;
&lt;p&gt;We now have two branches, one to import templates from and another to export translations to.  Next we configure imports from your development branch and exports to your translations branch.&lt;/p&gt;
&lt;p&gt;For the imports, tie your staging development branch to your project&amp;rsquo;s trunk release series.  Go to the project&amp;rsquo;s main page on the staging server, and from there, click on to the &amp;ldquo;trunk&amp;rdquo; release series.  The page you arrive at should have a section &amp;ldquo;Code for this series.&amp;rdquo;  In that section, you may see a link to your real branch on production.  The production branch won&amp;rsquo;t work on staging, so replace it with your development branch on staging.  Click on the little &amp;ldquo;edit&amp;rdquo; icon next to the branch URL to go to the settings form.  If no branch was tied to release series yet, click &amp;ldquo;link the branch to this series&amp;rdquo; instead.&lt;/p&gt;
&lt;p&gt;You can now ask the staging server to start importing and exporting.  Back on the &amp;ldquo;trunk&amp;rdquo; page, select the Translations tab at the top of the page.  Look for a link &amp;ldquo;Set up branch synchronization,&amp;rdquo; and follow it.&lt;/p&gt;
&lt;p&gt;This takes you to the page where translations synchronization with your branches is configured.  It should show your chosen development branch (the one on staging!) as the import branch.  Under &amp;ldquo;Import settings&amp;rdquo; select &amp;ldquo;Import template files&amp;rdquo; for now, and click &amp;ldquo;Save settings.&amp;rdquo;  From now on, every time you commit a change to your translation template and push it to your development branch on staging, the latest version of the template will be imported to the staging server automatically.  It usually happens within the hour.&lt;/p&gt;
&lt;p&gt;Important: on the real Launchpad site, the development branch can also be a mirrored version of a branch you keep elsewhere.  You can register an external branch (kept in CVS, Subversion, git, or bzr) and let Launchpad mirror it to a local branch.  That automates the full transport from committing your template changes to your own repository on another server, all the way to having the changes show up in Launchpad Translations.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://help.launchpad.net/Translations/YourProject/ImportingTemplates&#34; title=&#34;Detailed documentation&#34;&gt;&lt;em&gt;Detailed documentation&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll also want to set up translation exports on this page.  Under &amp;ldquo;Export translations to branch,&amp;rdquo; you&amp;rsquo;ll see a link &amp;ldquo;Choose a target branch.&amp;rdquo;  Selecting a branch will enable the exports immediately.  (If an export branch has already been set, you&amp;rsquo;ll see its URL with an &amp;ldquo;edit&amp;rdquo; icon next to it.  Clicking the icon will take you to the page where you set the branch.)  Use the link to set your translations export branch.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; the translations export branch must be one that you own, and it must have been pushed to the server—just registering a branch is not enough.  In the future it&amp;rsquo;ll also be possible to use a branch that is owned by a team that you are a member of.  That plan is tracked in Launchpad under &lt;a href=&#34;https://bugs.launchpad.net/rosetta/+bug/407260&#34; title=&#34;bug 407260&#34;&gt;bug 407260&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At this point you have a viable working setup.  As changes to your template (or even completely new templates) appear in your development branch, they are imported automatically.  Snapshots of your translations are periodically exported to your translations branch.  You may want to refine this further; I&amp;rsquo;ll go into that later.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://help.launchpad.net/Translations/YourProject/Exports&#34; title=&#34;Detailed documentation&#34;&gt;&lt;em&gt;Detailed documentation&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;5-check-up-on-the-imports&#34;&gt;5. Check up on the imports&lt;/h2&gt;
&lt;p&gt;Go to the translations import queue for your project.  You&amp;rsquo;ll see links to the queue from the Translations pages for your project and for the trunk series.  Within the hour you&amp;rsquo;ll see an entry for your template appear there.  Its initial status will be Approved, which means it&amp;rsquo;s sitting in the queue waiting to be processed.  Pending imports are processed several times an hour.  Once your template has had its turn, if you refresh the queue page, its status will show as Imported (or Failed if there were errors).&lt;/p&gt;
&lt;p&gt;Once your template has been imported, it will show up in the Translations page for your trunk series.  You will see red bars for each of the languages you have set up in your preferences, standing for untranslated messages.  The number of untranslated messages is indicated next to each.  Until your template is imported, the red bars will show but not the numbers.&lt;/p&gt;
&lt;h2 id=&#34;6-translate&#34;&gt;6. Translate!&lt;/h2&gt;
&lt;p&gt;Try clicking on one of the languages in the translations list with the red bars.  This will take you to the template&amp;rsquo;s translation page: the UI for entering translations.  Try translating one or more messages.  Remember to hit &amp;ldquo;Save &amp;amp; continue&amp;rdquo; at the bottom to submit your changes.&lt;/p&gt;
&lt;p&gt;Your changes are going to show up magically in your export branch.  Remember the location you pushed your translations branch to on staging?  Go back into your local copy of that branch and run, with that same URL:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr pull lp://staging/~mylogin/acme-zyzzyx/translations-export-test&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Most likely, nothing will happen and the command will just say &amp;ldquo;no revisions to pull.&amp;rdquo;  But keep trying!  Sometime within the next hour, your latest translations will be written into the branch.  When you set things up on production, you may want to set up an automated job (e.g. using &amp;ldquo;cron&amp;rdquo;) to pull snapshots of your latest translations to wherever you like to keep your translations.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://help.launchpad.net/Translations/StartingToTranslate&#34; title=&#34;Detailed documentation&#34;&gt;Detailed documentation&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;7-update-the-template&#34;&gt;7. Update the template&lt;/h2&gt;
&lt;p&gt;As your program changes, so will your template.  You&amp;rsquo;ll probably run the xgettext command to extract the latest message strings.  But today, since we&amp;rsquo;re only trying things out, you can edit the .pot file in a regular text editor.&lt;/p&gt;
&lt;p&gt;So edit the template in your staging development branch.  Add a new message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;msgid &amp;ldquo;Launchpad translations test message.&amp;rdquo;&lt;br&gt;
msgstr &amp;quot;&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now commit the change, and push it back onto staging using the same URL where you pushed your development branch before:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;bzr commit -m &amp;ldquo;Template update.&amp;rdquo;&lt;br&gt;
bzr push lp://staging/~mylogin/acme-zyzzyx/testbranch&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Your template&amp;rsquo;s entry on the import queue will go back to being Approved, and soon after that, will be imported again.  Now go back to the translation page.  The new message, &amp;ldquo;Launchpad translations test message&amp;rdquo; will appear in the same relative position where you inserted it into the template.&lt;/p&gt;
&lt;p&gt;This is how your project&amp;rsquo;s translations in Launchpad will keep up with development.  From time to time you&amp;rsquo;ll want to start work on a big new release while translators continue to work on the existing release.  That&amp;rsquo;s where you create a new release series.  Each series has its own branches and its own translations.  If the same English string occurs unchanged between two release series, the two will share their translations by default; but the old release series will be less of a &amp;ldquo;moving target&amp;rdquo; for the translators as the English strings probably won&amp;rsquo;t change so much between updates as you focus on the new release series.&lt;/p&gt;
&lt;h2 id=&#34;8-import-translations&#34;&gt;8. Import translations&lt;/h2&gt;
&lt;p&gt;Remember how we set up imports of templates only?  You can auto-import translations (&amp;quot;.po&amp;quot; files) as well.  Go back to the branch synchronization options (on the trunk page, under the Translations tab) and set the import option to &amp;ldquo;Import template and translation files.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Now, go back to your development branch.  Did you have any PO files in there?  If not, copy the one that was created in your translations export branch to the same directory where your template is.  Translate a previously untranslated message so that you can see the changes happening.  Add the file to the branch with &amp;ldquo;bzr add,&amp;rdquo; commit the change with &amp;ldquo;bzr commit,&amp;rdquo; and finally re-run the &amp;ldquo;bzr push&amp;rdquo; command.&lt;/p&gt;
&lt;p&gt;If you already had PO files in the branch, all you need to do is use the one-time import option on the branch synchronization page.  Each PO file should be in the same directory as its template, and be named after its language code with the &amp;ldquo;.po&amp;rdquo; extension: &lt;em&gt;de.po&lt;/em&gt; for German, &lt;em&gt;pt.po&lt;/em&gt; for Portuguese, &lt;em&gt;pt_BR.po&lt;/em&gt; for Brazilian Portuguese, &lt;em&gt;el.po&lt;/em&gt; for Greek, &lt;em&gt;zh_CN.po&lt;/em&gt; for Simplified Chinese and &lt;em&gt;zh_TW.po&lt;/em&gt; for Traditional Chinese, &lt;em&gt;es.po&lt;/em&gt; for Spanish, and so on.&lt;/p&gt;
&lt;p&gt;Now wait for up to one hour (but probably less) for your PO file to appear on the import queue for your project.  This time it will appear as &amp;ldquo;Needs review&amp;rdquo;; a script that runs about once or twice an hour will approve it automatically.  (If it doesn&amp;rsquo;t, check that you followed the naming rules).  It will be imported soon after that.&lt;/p&gt;
&lt;p&gt;If you go back to the translation pages, you&amp;rsquo;ll now see that the changes you pushed into the development branch have become visible in the translation UI.  In the translations overview for trunk you&amp;rsquo;ll see translated messages show up as green (translated) bars instead of red (untranslated).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; if you made a translations change in the branch for a message that you had already translated in the Launchpad UI, you may not see the change appear.  Translation changes made locally in Launchpad override translations that are imported from elsewhere; you&amp;rsquo;ll see such changes show up as light blue in the status bars.  This allows you to keep track of changes made in Launchpad, and if the project&amp;rsquo;s translations are centralized elsewhere, feed the changes back &amp;ldquo;upstream.&amp;rdquo;  You should try to keep the differences minimal by making sure that improvements are fed back to the origin, and that changes made in Launchpad are real improvements.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://help.launchpad.net/Translations/YourProject/ImportingTranslations&#34; title=&#34;Detailed documentation&#34;&gt;Detailed documentation&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;9-going-full-circle&#34;&gt;9. Going full-circle&lt;/h2&gt;
&lt;p&gt;By now you&amp;rsquo;re probably thinking that it&amp;rsquo;s not very useful to import translations from one branch and export them to another.  Things get much more interesting when you export the Launchpad translations back to the branch they came from!&lt;/p&gt;
&lt;p&gt;This is actually possible if your development branch is hosted on Launchpad.  There&amp;rsquo;s nothing stopping you from using the development branch as the translations export branch as well.  If you do that, you&amp;rsquo;ve got full two-way synchronization between your branch and the Launchpad user interface.  Your translators can work in the Launchpad UI, or they can edit PO files from the branch and push them right back using bzr.&lt;/p&gt;
&lt;p&gt;We normally recommend that you &lt;span style=&#34;text-decoration: underline&#34;&gt;import only your templates from a branch, and export your translations to a branch&lt;/span&gt; (which may be the same one).  But depending on how you choose to use Launchpad, two-way synchronization of translation files can be useful as well.  There are a few important things to keep in mind though.&lt;/p&gt;
&lt;p&gt;First, &lt;em&gt;the exported translations may not always be exactly what you expect.&lt;/em&gt; If you name your PO files after invalid language codes, like &amp;ldquo;de_DE.po&amp;rdquo; (should be &amp;ldquo;de.po&amp;rdquo;) or &amp;ldquo;zh.po&amp;rdquo; (should be either &amp;ldquo;zh_CN.po&amp;rdquo; or &amp;ldquo;zh_TW.po&amp;rdquo; depending on which language it really is), they will normally not be imported.  The same can happen if you include other things than the language code in the filenames, such as the template name.  But if these files ever do get imported, they&amp;rsquo;ll be exported with their normalized, proper names.  So it&amp;rsquo;s possible to end up with both a de.po and a de_DE.po in your branch.  Of these, only the correctly-named one will be updated and re-imported—de.po in this case—even though your translators may still try to work on the other one.&lt;/p&gt;
&lt;p&gt;Second, &lt;em&gt;the translations export will simply overwrite any files that were already there&lt;/em&gt;.  There is no intelligent merging, and &amp;ldquo;merge conflicts&amp;rdquo; are ignored.  If you set up translations export to your branch before the first import has happened, the export can overwrite translations that were in the branch.  Make sure this is really okay before enabling the exports!&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s also the risk of &amp;ldquo;crossing&amp;rdquo; translations: translator A makes a change in the UI, around the same time translator B pushes an updated PO file to the branch.  If there are pending changes in the branch when the export is scheduled to run, the export will not happen so as to avoid overwriting the changed files.  Of course this does mean that frequent changes to a large branch can stop the exports from happening.&lt;/p&gt;
&lt;p&gt;Third, an exported translation file will not be completely identical to the original, even if there were no changes in the Launchpad UI.  Messages can appear in a different order, and the file&amp;rsquo;s header is updated.  You may want to try merging Launchpad&amp;rsquo;s exported files into the original branch manually to get past the initial changes.&lt;/p&gt;
&lt;p&gt;So, before you set up two-way synchronization, &lt;strong&gt;always test the exports on an empty branch.&lt;/strong&gt; The staging server is the ideal environment for this.  Or if you do it on the real Launchpad site, remember to save space by deleting the experimental branch once you&amp;rsquo;re done with it.&lt;/p&gt;
&lt;h2 id=&#34;10--help--staging-refreshed-and-now-everythings-gone&#34;&gt;10.  Help!  Staging refreshed and now everything&amp;rsquo;s gone!&lt;/h2&gt;
&lt;p&gt;This happens once a day, or depending on the circumstances, once every few days.  If you still have your branches on your local system, and your project exists on the real Launchpad site, it&amp;rsquo;s not hard to set things up on staging again for another experiment.  Just re-run the &amp;ldquo;bzr push&amp;rdquo; command lines for the branches and set up the imports and exports again.&lt;/p&gt;
&lt;p&gt;Once you&amp;rsquo;re satisfied, we hope you&amp;rsquo;ll decide to set up translations permanently on the real Launchpad.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Exporting translations to a Bazaar branch</title>
      <link>https://blog.launchpad.net/general/exporting-translations-to-a-bazaar-branch/</link>
      <pubDate>Thu, 30 Jul 2009 10:06:35 +0000</pubDate>
      <dc:creator>Jeroen Vermeulen</dc:creator>
      <guid isPermaLink="false">https://blog.launchpad.net/?p=912</guid>
      <description>&lt;p&gt;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&amp;rsquo;s not very convenient if you&amp;rsquo;re trying to automate things.  It&amp;rsquo;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.&lt;/p&gt;
&lt;p&gt;Now there&amp;rsquo;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.&lt;/p&gt;
&lt;p&gt;It also means that large numbers of developers or translators can get regular, fresh updates of the translation files.&lt;/p&gt;
&lt;h2 id=&#34;how-to-use-it&#34;&gt;How to use it&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s say you have a project called &lt;em&gt;bzamqi.&lt;/em&gt; It&amp;rsquo;s set up for translation in Launchpad, and you want regular translation exports of the 1.0 release series.&lt;/p&gt;
&lt;p&gt;The first thing you need is a branch.  It doesn&amp;rsquo;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:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://help.launchpad.net/Code/UploadingABranch&lt;/li&gt;
&lt;li&gt;https://help.launchpad.net/Code/TeamBranches&lt;/li&gt;
&lt;li&gt;https://help.launchpad.net/Code/PersonalBranches&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Just remember that the branch must be Hosted, i.e. the master branch must be stored on Launchpad where we can commit to it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update: at the moment, &lt;a href=&#34;https://bugs.launchpad.net/rosetta/+bug/407260&#34;&gt;team-owned branches don&amp;rsquo;t work&lt;/a&gt;.&lt;/strong&gt;  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.&lt;/p&gt;
&lt;p&gt;Now, go to the page for bzamqi&amp;rsquo;s 1.0 release series.  You&amp;rsquo;ll be wanting the Translations tab.  Once there, pick the &lt;em&gt;Settings&lt;/em&gt; option.&lt;/p&gt;
&lt;p&gt;On the page that takes you to, near the bottom, there&amp;rsquo;s a section &amp;ldquo;Export translations to branch.&amp;rdquo;  You can set a branch there, and translations for the series will be exported to that branch.&lt;/p&gt;
&lt;p&gt;If you want to disable the exports, go back (use the &amp;ldquo;pencil&amp;rdquo; 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.&lt;/p&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;/h2&gt;
&lt;p&gt;The main thing to grok is that this is not Launchpad &amp;ldquo;editing&amp;rdquo; text files for you.  The export &lt;strong&gt;brutally overwrites&lt;/strong&gt; 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.&lt;/p&gt;
&lt;p&gt;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 &amp;ldquo;Advanced&amp;rdquo; bit below.  Also, it will help to keep the messages in translation files in the same order in which they appear in the template.&lt;/p&gt;
&lt;h3 id=&#34;directory-layout&#34;&gt;Directory layout&lt;/h3&gt;
&lt;p&gt;In the branch, each translation file will have a normalized name (&lt;tt&gt;de.po&lt;/tt&gt; for a German translation, &lt;tt&gt;zh_CN.po&lt;/tt&gt; for Simplified Chinese, &lt;tt&gt;eo.po&lt;/tt&gt; for Esperanto, and so on).  Each translation sits in the same directory where its template was on import.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Templates are not exported.&lt;/p&gt;
&lt;h2 id=&#34;advanced-going-two-way&#34;&gt;Advanced: going two-way&lt;/h2&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;Of course it&amp;rsquo;s still possible for the import to fail for whatever reason, and in that case your file will be overwritten.  This hopefully won&amp;rsquo;t hurt; the file that&amp;rsquo;s being exported is &amp;ldquo;better&amp;rdquo; in the sense that it shouldn&amp;rsquo;t cause any import errors.  But it may not always be what you want, so be careful if you do choose this setup.&lt;/p&gt;
&lt;p&gt;(Your templates will not be touched, since the export doesn&amp;rsquo;t write them.)&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t use this &amp;ldquo;two-way&amp;rdquo; setup lightly, since it complicates things.  Complications are where accidents happen.  Either wait until there&amp;rsquo;s more practical experience with this, or make sure in some way that you won&amp;rsquo;t lose data if something goes horribly wrong.&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h2 id=&#34;questions&#34;&gt;Questions&lt;/h2&gt;
&lt;h3 id=&#34;how-often-do-the-exports-happen&#34;&gt;How often do the exports happen?&lt;/h3&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;If the export runs at a moment when you&amp;rsquo;ve pushed changes into the branch that Launchpad hasn&amp;rsquo;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&amp;rsquo;s export should catch up with the latest changes.&lt;/p&gt;
&lt;h3 id=&#34;why-do-i-need-to-own-the-branch&#34;&gt;Why do I need to own the branch?&lt;/h3&gt;
&lt;p&gt;Otherwise you would be making Launchpad write data into someone else&amp;rsquo;s branch.  Not a nice thing to do to someone who isn&amp;rsquo;t expecting it!&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;h3 id=&#34;what-happens-if-i-leave-the-project&#34;&gt;What happens if I leave the project?&lt;/h3&gt;
&lt;p&gt;The exports keep happening to the same branch.  If that is not what you want, it&amp;rsquo;s up to the remaining project owners to choose a different branch or disable the exports.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
