def Install(language=None,pathRead=None,pathWrite=None):
    """Install translation for language.  If language is not specified,
       installs a translation for the default language."""
    if not language:
        language = locale.getlocale()[0].split('_',1)[0]
    pathRead = pathRead if pathRead else GPath('l10n')
    pathWrite = pathWrite if pathWrite else pathRead
    if language.lower() == 'german':
        language = 'de'
    txt = pathRead.join(language+'.txt')
    po = pathWrite.join(language+'.po')
    mo = pathWrite.join(language+'.mo')
    #--Test for no translation for the language
    if not txt.exists and not mo.exists:
        if language.lower() != 'english':
            print('No translation file for language:', language)
        trans = gettext.NullTranslations()
    else:
        try:
            # See if translation needs to be recompiled
            txtMtime = txt.mtime
            if not mo.exists or txtMtime != mo.mtime:
                txt.copyTo(po)
                args= ['m',po.s,'-o',mo.s]
                if hasattr(sys,'frozen'):
                    # Same thing as for 'Dump' for frozen
                    # apps.
                    import msgfmt
                    old_argv = sys.argv[:]
                    sys.argv = args
                    msgfmt.main()
                    sys.argv = old_argv
                else:
                    m = GPath(sys.prefix).join('Tools','i18n','msgfmt.py')
                    args[0] = m.s
                    subprocess.call(args,shell=True)
                po.remove()
                mo.mtime = txtMtime
            # Create GNU translations
            with mo.open('rb') as ins:
                trans = gettext.GNUTranslations(ins)
        except:
            print('Error loading translation file for', language)
            traceback.print_exc()
            trans = gettext.NullTranslations()
    # Install
    trans.install()
Exemple #2
0
def setup_locale(cli_lang, _wx):
    """Sets up wx and Wrye Bash locales, ensuring they match or falling back
    to English if that is impossible. Also considers cli_lang as an override,
    installs the gettext translation and remembers the locale we end up with
    as bass.active_locale.

    bolt.deprint must be set up and ready to use (i.e. hooked up to the
    BashBugDump if debug mode is enabled) and the working directory must be
    correct (otherwise detection of translation files will not work and this
    method will always set locale to English).

    :param cli_lang: The language the user specified on the command line, or
        None.
    :param _wx: The wx instance to use.
    :return: The wx.Locale object we ended up using."""
    # We need a throwaway wx.App so that the calls below work
    _temp_app = _wx.App(False)
    # Set the wx language - otherwise we will crash when loading any images
    if cli_lang and _wx.Locale.FindLanguageInfo(cli_lang):
        # The user specified a language that wx recognizes and WB supports
        target_language = _wx.Locale.FindLanguageInfo(cli_lang).Language
    else:
        # Fall back on the default language
        target_language = _wx.LANGUAGE_DEFAULT
    # We now have a language that wx supports, but we don't know if WB supports
    # it - so check that next
    target_locale = _wx.Locale(target_language)
    target_name = target_locale.GetSysName().split(u'_', 1)[0]
    # Ugly hack, carried forward from bolt.initTranslator
    if target_name.lower() == u'german':
        target_name = u'de'
    # English is the default, so it doesn't have a translation file
    # For all other languages, check if we have a translation
    trans_path = os.path.join(os.getcwdu(), u'bash', u'l10n')
    if target_name.lower() != u'english' and not os.path.exists(
            os.path.join(trans_path, target_name + u'.txt')):
        # WB does not support the default language, use English instead
        target_locale = _wx.Locale(_wx.LANGUAGE_ENGLISH)
        bolt.deprint(u"No translation file for language '%s', falling back to "
                     u"English" % target_name)
        target_name = target_locale.GetSysName().split(u'_', 1)[0]
    bolt.deprint(u"Set wx locale to '%s' (%s)" %
                 (target_name, target_locale.GetCanonicalName()))
    # Next, set the Wrye Bash locale based on the one we grabbed from wx
    txt, po, mo = (os.path.join(trans_path, target_name + ext)
                   for ext in (u'.txt', u'.po', u'.mo'))
    if not os.path.exists(txt) and not os.path.exists(mo):
        # We're using English or don't have a translation file - either way,
        # prepare the English translation
        trans = gettext.NullTranslations()
        bolt.deprint(u"Set Wrye Bash locale to 'English'")
    else:
        try:
            # We have a translation file, check if it has to be compiled
            if not os.path.exists(mo) or (os.path.getmtime(txt) >
                                          os.path.getmtime(mo)):
                # Try compiling - have to do it differently if we're a
                # standalone build
                shutil.copy(txt, po)
                args = [u'm', u'-o', mo, po]
                if bass.is_standalone:
                    # Delayed import, since it's only present on standalone
                    import msgfmt
                    old_argv = sys.argv[:]
                    sys.argv = args
                    msgfmt.main()
                    sys.argv = old_argv
                else:
                    # msgfmt is only in Tools, so call it explicitly
                    m = os.path.join(sys.prefix, u'Tools', u'i18n',
                                     u'msgfmt.py')
                    subprocess.call([sys.executable, m, u'-o', mo, po],
                                    shell=True)
                # Clean up the temp file we created for compilation
                os.remove(po)
            # We've succesfully compiled the translation, read it into memory
            with open(mo, u'rb') as trans_file:
                trans = gettext.GNUTranslations(trans_file)
            bolt.deprint(u"Set Wrye Bash locale to '%s'" % target_name)
        except (UnicodeError, OSError):
            bolt.deprint(u'Error loading translation file:')
            traceback.print_exc()
            trans = gettext.NullTranslations()
    # Everything has gone smoothly, install the translation and remember what
    # we ended up with as the final locale
    # PY3: drop the unicode=True, gone in py3 (this is always unicode now)
    trans.install(unicode=True)
    bass.active_locale = target_name
    del _temp_app
    return target_locale
Exemple #3
0
import os, glob
import msgfmt

import sys

script_dir = os.path.dirname(os.path.abspath(__file__))
locale_path = os.path.abspath(os.path.join(script_dir, '..', 'locale'))

for name in glob.iglob(locale_path + '/**'):
    if not os.path.isfile(name):
        path = os.path.join(locale_path, name, 'LC_MESSAGES', 'lang')
        sys.argv[1:] = [path + '.po']
        msgfmt.reset()
        msgfmt.main()
Exemple #4
0
def setup_locale(cli_lang):
    """Sets up wx and Wrye Bash locales, ensuring they match or falling back
    to English if that is impossible. Also considers cli_lang as an override,
    installs the gettext translation and remembers the locale we end up with
    as bass.active_locale.

    bolt.deprint must be set up and ready to use (i.e. hooked up to the
    BashBugDump if debug mode is enabled) and the working directory must be
    correct (otherwise detection of translation files will not work and this
    method will always set locale to English).

    :param cli_lang: The language the user specified on the command line, or
        None.
    :return: The wx.Locale object we ended up using."""
    # We need a throwaway wx.App so that the calls below work
    import wx as _wx
    _temp_app = _wx.App(False)
    # Set the wx language - otherwise we will crash when loading any images
    cli_target = cli_lang and _wx.Locale.FindLanguageInfo(cli_lang)
    if cli_target:
        # The user specified a language that wx recognizes
        target_language = cli_target.Language
    else:
        # Fall back on the default language
        target_language = _wx.LANGUAGE_DEFAULT
    # We now have a language that wx supports, but we don't know if WB supports
    # it - so check that next
    target_locale = _wx.Locale(target_language)
    target_name = target_locale.GetCanonicalName()
    trans_path = os.path.join(os.getcwdu(), u'bash', u'l10n')
    if not os.path.exists(trans_path):
        # HACK: the CI has to run tests from the top dir, which causes us to
        # have a non-Mopy working dir here. Real fix is ditching the fake
        # startup and adding a real headless mode to WB (see #568 and #554)
        trans_path = os.path.join(os.getcwdu(), u'Mopy', u'bash', u'l10n')
    supported_l10ns = [
        l[:-3] for l in os.listdir(trans_path) if l[-3:] == u'.po'
    ]
    if target_name not in supported_l10ns:
        # We don't support this exact language. Check if we support any similar
        # languages (i.e. same prefix)
        wanted_prefix = target_name.split(u'_', 1)[0]
        for l in supported_l10ns:
            if l.split(u'_', 1)[0] == wanted_prefix:
                bolt.deprint(u"No translation file for language '%s', "
                             u"using similar language with translation file "
                             u"'%s' instead" % (target_name, l))
                target_name = l
                # Try switching wx to this locale as well
                lang_info = _wx.Locale.FindLanguageInfo(target_name)
                if lang_info:
                    target_locale = _wx.Locale(lang_info.Language)
                else:
                    # Didn't work, try the prefix to get a similar language
                    lang_info = _wx.Locale.FindLanguageInfo(wanted_prefix)
                    if lang_info:
                        target_locale = _wx.Locale(lang_info.Language)
                        bolt.deprint(
                            u"wxPython does not support language "
                            u"'%s', using supported language '%s' "
                            u"instead" %
                            (target_name, target_locale.GetCanonicalName()))
                    else:
                        # If even that didn't work, all we can do is complain
                        # about it and fall back to English
                        bolt.deprint(u"wxPython does not support the language "
                                     u"family '%s', will fall back to "
                                     u"English" % wanted_prefix)
                break
    po, mo = (os.path.join(trans_path, target_name + ext)
              for ext in (u'.po', u'.mo'))
    # English is the default, so it doesn't have a translation file
    # For all other languages, check if we have a translation
    if not target_name.startswith(u'en_') and not os.path.isfile(po):
        # WB does not support the default language, use English instead
        target_locale = _wx.Locale(_wx.LANGUAGE_ENGLISH)
        fallback_name = target_locale.GetCanonicalName()
        bolt.deprint(u"No translation file for language '%s', falling back to "
                     u"'%s'" % (target_name, fallback_name))
        target_name = fallback_name
    bolt.deprint(u"Set wxPython language to '%s'" %
                 target_locale.GetCanonicalName())
    bolt.deprint(u"Set Wrye Bash language to '%s'" % target_name)
    # Next, set the Wrye Bash locale based on the one we grabbed from wx
    if not os.path.isfile(po) and not os.path.isfile(mo):
        # We're using English or don't have a translation file - either way,
        # prepare the English translation
        trans = gettext.NullTranslations()
    else:
        try:
            # We have a translation file, check if it has to be compiled
            if not os.path.isfile(mo) or (os.path.getmtime(po) >
                                          os.path.getmtime(mo)):
                # Try compiling - have to do it differently if we're a
                # standalone build
                args = [u'm', u'-o', mo, po]
                if bass.is_standalone:
                    # Delayed import, since it's only present on standalone
                    import msgfmt
                    old_argv = sys.argv[:]
                    sys.argv = args
                    msgfmt.main()
                    sys.argv = old_argv
                else:
                    # msgfmt is only in Tools, so call it explicitly
                    from .env import python_tools_dir
                    m = os.path.join(python_tools_dir(), u'i18n', u'msgfmt.py')
                    subprocess.call([sys.executable, m, u'-o', mo, po])
            # We've successfully compiled the translation, read it into memory
            with open(mo, u'rb') as trans_file:
                trans = gettext.GNUTranslations(trans_file)
        except (UnicodeError, OSError):
            bolt.deprint(u'Error loading translation file:')
            traceback.print_exc()
            trans = gettext.NullTranslations()
    # Everything has gone smoothly, install the translation and remember what
    # we ended up with as the final locale
    # PY3: drop the unicode=True, gone in py3 (this is always unicode now)
    trans.install(unicode=True)
    bass.active_locale = target_name
    del _temp_app
    return target_locale