【问题标题】:How to compile *.po gettext translations in setup.py python script如何在 setup.py python 脚本中编译 *.po gettext 翻译
【发布时间】:2016-03-08 07:25:33
【问题描述】:

考虑一个支持多语言的 python 包(使用gettext)。执行setup.py时如何将*.po文件即时编译为*.mo文件?我真的不想分发预编译的*.mo 文件。

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from distutils.core import setup

setup(
    name='tractorbeam',
    version='0.1.0',
    url='http://starfleet.org/tractorbeam/',
    description='Pull beer out of the fridge while sitting on the couch.',

    author='James T. Kirk',
    author_email= 'jkirk@starfleet.org',

    packages=['tractorbeam'],
    package_data={
        'tractorbeam': [
            'locale/*.po',
            'locale/*.mo',  # How to compile on the fly?
        ]
    },

    install_requires=[
        'requests'
    ]
)

提前致谢!

【问题讨论】:

    标签: python gettext distutils setup.py po


    【解决方案1】:

    我可以分享我的*.mo文件编译过程:

    import glob
    import pathlib
    import subprocess
    (...)
    
    PO_FILES = 'translations/locale/*/LC_MESSAGES/app_name.po'
    
    def create_mo_files():
        mo_files = []
        prefix = 'app_name'
    
        for po_path in glob.glob(str(pathlib.Path(prefix) / PO_FILES)):
            mo = pathlib.Path(po_path.replace('.po', '.mo'))
    
            subprocess.run(['msgfmt', '-o', str(mo), po_path], check=True)
            mo_files.append(str(mo.relative_to(prefix)))
    
        return mo_files
    (...)
    
    setup(
        (...)
        package_data = {
            'app_name': [
                (...)
            ] + create_mo_files(),
        },
    )
    

    @edit 评论:

    例如pl翻译文件:

    app_name/translations/locale/pl/LC_MESSAGES/app_name.po
    

    函数create_mo_files()创建编译后的app_name.mo文件

    app_name/translations/locale/pl/LC_MESSAGES/app_name.mo
    

    然后在打包构建这个 app_name.mo 文件正在复制到

    package/translations/locale/pl/LC_MESSAGES/app_name.po
    

    【讨论】:

      【解决方案2】:

      我知道这个问题开始有点老了,但如果有人还在寻找答案:可以向setup.py 添加一个函数,该函数将编译po 文件并返回data_files list。我没有选择将它们包含在package_data 中,因为data_files 的描述看起来更合适:

      配置文件、消息目录、数据文件,任何不属于前面类别的东西。

      当然,您只能将此列表附加到您已经使用的列表中,但假设您只有这些 mo 文件要添加到 data_files 中,您可以编写:

      setup(
          .
          .
          .
          data_files=create_mo_files(),
          .
          .
          .
      )
      

      为了您的信息,这是我使用的函数create_mo_files()。我不假装这是最好的实现。我把它放在这里是因为它看起来很有用并且很容易适应。请注意,它比您需要的要复杂一些,因为它不假设每个目录只有一个 po 文件要编译,而是处理多个;另请注意,它假定所有 po 文件都位于locale/language/LC_MESSAGES/*.po 之类的位置,您必须对其进行更改以满足您的需要:

      def create_mo_files():
          data_files = []
          localedir = 'relative/path/to/locale'
          po_dirs = [localedir + '/' + l + '/LC_MESSAGES/'
                     for l in next(os.walk(localedir))[1]]
          for d in po_dirs:
              mo_files = []
              po_files = [f
                          for f in next(os.walk(d))[2]
                          if os.path.splitext(f)[1] == '.po']
              for po_file in po_files:
                  filename, extension = os.path.splitext(po_file)
                  mo_file = filename + '.mo'
                  msgfmt_cmd = 'msgfmt {} -o {}'.format(d + po_file, d + mo_file)
                  subprocess.call(msgfmt_cmd, shell=True)
                  mo_files.append(d + mo_file)
              data_files.append((d, mo_files))
          return data_files
      

      (您必须导入 ossubprocess 才能使用它)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-01
        • 2011-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-05
        • 1970-01-01
        • 2019-03-15
        相关资源
        最近更新 更多