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