common/i18n.py
changeset 4021 280c910c8710
parent 4018 d4d4e7112ccf
child 4022 934e758a73ef
equal deleted inserted replaced
4018:d4d4e7112ccf 4021:280c910c8710
     1 """Some i18n/gettext utilities.
       
     2 
       
     3 :organization: Logilab
       
     4 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
       
     5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
       
     6 :license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
       
     7 """
       
     8 __docformat__ = "restructuredtext en"
       
     9 
       
    10 import re
       
    11 import os
       
    12 import sys
       
    13 from os.path import join, basename, splitext, exists
       
    14 from glob import glob
       
    15 
       
    16 from cubicweb.toolsutils import create_dir
       
    17 
       
    18 def extract_from_tal(files, output_file):
       
    19     """extract i18n strings from tal and write them into the given output file
       
    20     using standard python gettext marker (_)
       
    21     """
       
    22     output = open(output_file, 'w')
       
    23     for filepath in files:
       
    24         for match in re.finditer('i18n:(content|replace)="([^"]+)"', open(filepath).read()):
       
    25             print >> output, '_("%s")' % match.group(2)
       
    26     output.close()
       
    27 
       
    28 
       
    29 def add_msg(w, msgid, msgctx=None):
       
    30     """write an empty pot msgid definition"""
       
    31     if isinstance(msgid, unicode):
       
    32         msgid = msgid.encode('utf-8')
       
    33     if msgctx:
       
    34         if isinstance(msgctx, unicode):
       
    35             msgctx = msgctx.encode('utf-8')
       
    36         w('msgctxt "%s"\n' % msgctx)
       
    37     msgid = msgid.replace('"', r'\"').splitlines()
       
    38     if len(msgid) > 1:
       
    39         w('msgid ""\n')
       
    40         for line in msgid:
       
    41             w('"%s"' % line.replace('"', r'\"'))
       
    42     else:
       
    43         w('msgid "%s"\n' % msgid[0])
       
    44     w('msgstr ""\n\n')
       
    45 
       
    46 
       
    47 def execute(cmd):
       
    48     """display the command, execute it and raise an Exception if returned
       
    49     status != 0
       
    50     """
       
    51     from subprocess import call
       
    52     print cmd.replace(os.getcwd() + os.sep, '')
       
    53     status = call(cmd, shell=True)
       
    54     if status != 0:
       
    55         raise Exception('status = %s' % status)
       
    56 
       
    57 
       
    58 def available_catalogs(i18ndir=None):
       
    59     if i18ndir is None:
       
    60         wildcard = '*.po'
       
    61     else:
       
    62         wildcard = join(i18ndir, '*.po')
       
    63     for popath in glob(wildcard):
       
    64         lang = splitext(basename(popath))[0]
       
    65         yield lang, popath
       
    66 
       
    67 
       
    68 def compile_i18n_catalogs(sourcedirs, destdir, langs):
       
    69     """generate .mo files for a set of languages into the `destdir` i18n directory
       
    70     """
       
    71     from logilab.common.fileutils import ensure_fs_mode
       
    72     print '-> compiling %s catalogs...' % destdir
       
    73     errors = []
       
    74     for lang in langs:
       
    75         langdir = join(destdir, lang, 'LC_MESSAGES')
       
    76         if not exists(langdir):
       
    77             create_dir(langdir)
       
    78         pofiles = [join(path, '%s.po' % lang) for path in sourcedirs]
       
    79         pofiles = [pof for pof in pofiles if exists(pof)]
       
    80         mergedpo = join(destdir, '%s_merged.po' % lang)
       
    81         try:
       
    82             # merge instance/cubes messages catalogs with the stdlib's one
       
    83             execute('msgcat --use-first --sort-output --strict -o "%s" %s'
       
    84                     % (mergedpo, ' '.join('"%s"' % f for f in pofiles)))
       
    85             # make sure the .mo file is writeable and compiles with *msgfmt*
       
    86             applmo = join(destdir, lang, 'LC_MESSAGES', 'cubicweb.mo')
       
    87             try:
       
    88                 ensure_fs_mode(applmo)
       
    89             except OSError:
       
    90                 pass # suppose not exists
       
    91             execute('msgfmt "%s" -o "%s"' % (mergedpo, applmo))
       
    92         except Exception, ex:
       
    93             errors.append('while handling language %s: %s' % (lang, ex))
       
    94         try:
       
    95             # clean everything
       
    96             os.unlink(mergedpo)
       
    97         except Exception:
       
    98             continue
       
    99     return errors