Editing Internationalize a Python application

Warning: You are not logged in. Your IP address will be recorded in this page's edit history.
The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 69: Line 69:
If you don't know the locale of a language, can check [http://www.roseindia.net/tutorials/I18N/locales-list.shtml www.roseindia.net/tutorials/I18N/locales-list.shtml] or [http://people.w3.org/rishida/utils/subtags/ people.w3.org/rishida/utils/subtags].
If you don't know the locale of a language, can check [http://www.roseindia.net/tutorials/I18N/locales-list.shtml www.roseindia.net/tutorials/I18N/locales-list.shtml] or [http://people.w3.org/rishida/utils/subtags/ people.w3.org/rishida/utils/subtags].
 +
 +
== Include translations in your installation ==
 +
Here again are several ways of doing it. I suggest to do it the automatic way as it is way easier if you have scratchbox.
 +
=== Automatic way ===
 +
If you already have the .tar.gz file, then you already have the structure with the files. Just unpack the .tar.gz file into a folder. If you have to pack it for the first time, MohammadAG has a good page about how to generate the needed files: [[User:Mohammad7410/Packaging]]
 +
 +
Now you will have to add some basic lines to the debian/rules file.Under the line with "install: build" should be many lines with "<code>mkdir</code>" and "<code>cp -a</code>". After the last one of them, add those two lines:
 +
 +
  #compile language files with msgfmt
 +
  msgfmt src/opt/PROJECTNAME/i18n/de.po --output-file debian/PROJECTNAME/opt/PROJECTNAME/i18n/de/LC_MESSAGES/PROJECTNAME.mo
 +
This will tell the autobuilder to generate the .mo files. You will need a line like that for every language!
 +
Don't forget to adapt the file paths. In the example the .mo files are in the sub folder i18n/de/LC_MESSAGES/
 +
 +
=== Python way ===
 +
This part is more tricky, because it depends on your build system. I'll explain how it goes with the common python 'distutils' (what makes the usual ''<code>python setup.py install</code>'' command work). In distutils all the magic happens in the ''<code>setup.py</code>'' file.
 +
 +
First of all, if in the previous steps you have added the <code>i18n.py</code> file to your source tree, don't forget to include it in your <code>data_files</code> list!
 +
 +
Then, copy to the root folder of your project the file [https://garage.maemo.org/plugins/ggit/browse.php/?p=mussorgsky;a=blob;f=msgfmt.py;hb=HEAD msgfmt.py]. It is a program that translates the .po files into the binary .mo files that the application needs.
 +
 +
In your <code>setup.py</code> file you need to add all this code. It "overloads" the default 'build' and 'install' instructions to include the translations in the process. Now in 'build' time it will generate the .mo files (using the <code>msgfmt.py</code> we added just now), and in 'install' time it will include the '<code>.mo</code>' files in the <code>data_files</code> list. The code is copied from this a [https://garage.maemo.org/plugins/ggit/browse.php/?p=mussorgsky;a=blob;f=setup.py;hb=HEAD setup.py] file.
 +
 +
<source lang="python">
 +
from distutils.core import setup
 +
from distutils import cmd
 +
from distutils.command.install_data import install_data as _install_data
 +
from distutils.command.build import build as _build
 +
 +
import msgfmt
 +
import os
 +
</source>
 +
This command compiles every <code>.po</code> file under the <code>po/</code> folder into a <code>.mo</code> (the <code>.mo</code> files will be under <code>build/locale/</code>)
 +
<source lang="python">
 +
class build_trans(cmd.Command):
 +
    description = 'Compile .po files into .mo files'
 +
    def initialize_options(self):
 +
        pass
 +
 +
    def finalize_options(self):
 +
        pass
 +
 +
    def run(self):
 +
        po_dir = os.path.join(os.path.dirname(os.curdir), 'po')
 +
        for path, names, filenames in os.walk(po_dir):
 +
            for f in filenames:
 +
                if f.endswith('.po'):
 +
                    lang = f[:-3]
 +
                    src = os.path.join(path, f)
 +
                    dest_path = os.path.join('build', 'locale', lang, 'LC_MESSAGES')
 +
                    dest = os.path.join(dest_path, 'mussorgsky.mo')
 +
                    if not os.path.exists(dest_path):
 +
                        os.makedirs(dest_path)
 +
                    if not os.path.exists(dest):
 +
                        print 'Compiling %s' % src
 +
                        msgfmt.make(src, dest)
 +
                    else:
 +
                        src_mtime = os.stat(src)[8]
 +
                        dest_mtime = os.stat(dest)[8]
 +
                        if src_mtime > dest_mtime:
 +
                            print 'Compiling %s' % src
 +
                            msgfmt.make(src, dest)
 +
</source>
 +
Now we append the previous command to the 'build' command.
 +
<source lang="python">
 +
class build(_build):
 +
    sub_commands = _build.sub_commands + [('build_trans', None)]
 +
    def run(self):
 +
        _build.run(self)
 +
</source>
 +
Installation time: put every <code>.mo</code> file under <code>build/locale</code> in the <code>data_files</code> list (the list of things to be installed) and call the default 'install' operation
 +
<source lang="python">
 +
class install_data(_install_data):
 +
 +
    def run(self):
 +
        for lang in os.listdir('build/locale/'):
 +
            lang_dir = os.path.join('share', 'locale', lang, 'LC_MESSAGES')
 +
            lang_file = os.path.join('build', 'locale', lang, 'LC_MESSAGES', 'mussorgsky.mo')
 +
            self.data_files.append( (lang_dir, [lang_file]) )
 +
        _install_data.run(self)
 +
</source>
 +
Finally, add the new commands in distutils...
 +
<source lang="python">
 +
cmdclass = {
 +
    'build': build,
 +
    'build_trans': build_trans,
 +
    'install_data': install_data,
 +
}
 +
</source>
 +
And don't forget to add this in your setup function, in the <code>setup.py</code>
 +
<source lang="python">
 +
setup(name        = 'your project',
 +
      ...
 +
    license      = 'GPL v2 or later',
 +
    data_files  = DATA,
 +
    scripts      = SCRIPTS,
 +
    cmdclass    = cmdclass  <----- DON'T FORGET THIS
 +
    )
 +
</source>
 +
Ok, now everything should be ready. If you run
 +
 +
python2.5 setup.py build
 +
 +
the terminal will print things like
 +
 +
compiling es.po
 +
compiling de.po
 +
...
 +
 +
Usually <code>dpkg-buildpackage</code> uses <code>python2.5 setup.py build</code> and <code>install</code>, so everything should work out-of-the-box with your previous package configuration.
 +
 +
Feel free to complete/correct this wiki page with your own experience.
 +
 +
[[Category:Internationalization]]
 +
[[Category:Development]]
 +
[[Category:HowTo]]
 +
[[Category:Python]]

Learn more about Contributing to the wiki.


Please note that all contributions to maemo.org wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see maemo.org wiki:Copyrights for details). Do not submit copyrighted work without permission!


Cancel | Editing help (opens in new window)