[PATCH] Use langtable instead of our magic tables and hacks
Vratislav Podzimek
vpodzime at redhat.com
Tue Jun 11 14:57:23 UTC 2013
This great new package allows us to remove our magic tables and hacks dealing
with languages, locales and some more things.
Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
anaconda.spec.in | 3 +
pyanaconda/localization.py | 172 ++++++++++++++++++++++-----------------------
2 files changed, 86 insertions(+), 89 deletions(-)
diff --git a/anaconda.spec.in b/anaconda.spec.in
index f6a3f37..20a020a 100644
--- a/anaconda.spec.in
+++ b/anaconda.spec.in
@@ -38,6 +38,7 @@ Source0: %{name}-%{version}.tar.bz2
%define isomd5sum 1.0.10
%define fcoeutilsver 1.0.12-3.20100323git
%define iscsiver 6.2.0.870-3
+%define langtablever 0.0.5-1
BuildRequires: audit-libs-devel
BuildRequires: gettext >= %{gettextver}
@@ -88,6 +89,8 @@ Requires: python-urlgrabber >= %{pythonurlgrabberver}
Requires: system-logos
Requires: pykickstart >= %{pykickstartver}
Requires: python-babel
+Requires: langtable-data >= %{langtablever}
+Requires: langtable-python >= %{langtablever}
Requires: libuser-python
Requires: authconfig
Requires: firewalld >= %{firewalldver}
diff --git a/pyanaconda/localization.py b/pyanaconda/localization.py
index ae8d9e4..f9d0037 100644
--- a/pyanaconda/localization.py
+++ b/pyanaconda/localization.py
@@ -1,6 +1,6 @@
# Localization classes and functions
#
-# Copyright (C) 2012 Red Hat, Inc.
+# Copyright (C) 2012-2013 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions of
@@ -17,6 +17,7 @@
# Red Hat, Inc.
#
# Red Hat Author(s): Martin Gracik <mgracik at redhat.com>
+# Vratislav Podzimek <vpodzime at redhat.com>
#
from collections import defaultdict, deque
@@ -28,6 +29,7 @@ import logging
log = logging.getLogger("anaconda")
import babel
+import langtable
from pyanaconda.constants import DEFAULT_LANG
@@ -46,29 +48,73 @@ class LocalizationConfigError(Exception):
pass
+class InvalidLocaleSpec(LocalizationConfigError):
+ """Exception class for the errors related to invalid locale specs"""
+
+ pass
+
class LocaleInfo(object):
+ """
+ Class unifying the glibc-like and CLDR-like locales by providing a single
+ API based on properties.
+
+ """
- def __init__(self, localedata, encoding="", script=""):
+ def __init__(self, localespec):
"""
- :param encoding: encoding from the locale specification, e.g. UTF-8
- (localedata object has no attribute for that)
- :param script: script from the locale specification (e.g. latin)
- (changing localedata.script attribute results in
- problems)
+ Constructor for the LocaleInfo class.
+
+ :param localespec: locale string such as "sr_RS.UTF-8 at latin"
+ (glibc-like format) or "sr_Latn_RS" (CLDR-format)
+ :type localespec: str
"""
- self._localedata = localedata
- self._encoding = encoding or "UTF-8"
- self._script = script
+ # get the basic values
+ parsed_values = parse_langcode(localespec)
+ if parsed_values:
+ # successfully parsed -> a glibc-like locale, try to get some more
+ # information by querying langtable
+
+ # language must be specified
+ language = parsed_values["language"]
+ territory = parsed_values.get("territory", "")
+ script = parsed_values.get("modifier", "")
+
+ locales = langtable.list_locales(languageId=language,
+ territoryId=territory,
+ scriptId=script)
+ else:
+ # not in the glibc-like format, use langtable to get it
+ locales = langtable.list_locales(languageId=localespec)
+
+ if not locales:
+ msg = "'%s' is not a valid locale" % localespec
+ raise InvalidLocaleSpec(msg)
+
+ # locales are sorted from the most probable to the least probable
+ self._locale = locales[0]
+
+ parsed_values = parse_langcode(self._locale)
+
+ # language must be specified
+ self._language = parsed_values["language"]
+
+ # try to get the other values
+ self._territory = parsed_values.get("territory", "")
+ self._encoding = parsed_values.get("codeset", "")
+ self._script = parsed_values.get("modifier", "")
+
+ # TODO: never appeared so far, needs to be parsed and stored?
+ self._variant = None
@property
def language(self):
- return self._localedata.language
+ return self._language
@property
def territory(self):
- return self._localedata.territory
+ return self._territory
@property
def script(self):
@@ -76,23 +122,32 @@ class LocaleInfo(object):
@property
def variant(self):
- return self._localedata.variant
+ return self._variant
@property
def encoding(self):
return self._encoding
@property
+ def locale(self):
+ return self._locale
+
+ @property
def english_name(self):
- return self._localedata.english_name or u''
+ name = langtable.language_name(languageId=self.language,
+ territoryId=self.territory,
+ scriptId=self.script,
+ languageIdQuery="en")
+ # some languages don't start with a capital letter
+ return name.title()
@property
def display_name(self):
- # some languages don't have a display_name
- display_name = self._localedata.display_name or self.english_name
- # some start with lowercase
- display_name = display_name.title()
- return display_name
+ name = langtable.language_name(languageId=self.language,
+ territoryId=self.territory,
+ scriptId=self.script)
+ # some languages don't start with a capital letter
+ return name.title()
@property
def short_name(self):
@@ -120,29 +175,6 @@ class LocaleInfo(object):
def __eq__(self, other):
return repr(self) == repr(other)
-def mangleLocale(inLocale):
- mangleMap = {"af": "af_ZA", "am": "am_ET", "ar": "ar_SA", "as": "as_IN",
- "ast": "ast_ES", "be": "be_BY", "bg": "bg_BG", "bn": "bn_BD",
- "bs": "bs_BA", "ca": "ca_ES", "cs": "cs_CZ", "cy": "cy_GB",
- "da": "da_DK", "de": "de_DE", "el": "el_GR", "en": "en_US",
- "es": "es_ES", "et": "et_EE", "eu": "eu_ES", "fa": "fa_IR",
- "fi": "fi_FI", "fr": "fr_FR", "gl": "gl_ES", "gu": "gu_IN",
- "he": "he_IL", "hi": "hi_IN", "hr": "hr_HR", "hu": "hu_HU",
- "hy": "hy_AM", "id": "id_ID", "ilo": "ilo_PH", "is": "is_IS",
- "it": "it_IT", "ja": "ja_JP", "ka": "ka_GE", "kk": "kk_KZ",
- "kn": "kn_IN", "ko": "ko_KR", "lt": "lt_LT", "lv": "lv_LV",
- "mai": "mai_IN", "mk": "mk_MK", "ml": "ml_IN", "mr": "mr_IN",
- "ms": "ms_MY", "nb": "nb_NO", "nds": "nds_DE", "ne": "ne_NP",
- "nl": "nl_NL", "nn": "nn_NO", "nso": "nso_ZA", "or": "or_IN",
- "pa": "pa_IN", "pl": "pl_PL", "pt": "pt_PT", "ro": "ro_RO",
- "ru": "ru_RU", "si": "si_LK", "sk": "sk_SK", "sl": "sl_SI",
- "sq": "sq_AL", "sr": "sr_RS", "sr at latin": "sr_Latn_RS",
- "sv": "sv_SE", "ta": "ta_IN", "te": "te_IN", "tg": "tg_TJ",
- "th": "th_TH", "tr": "tr_TR", "uk": "uk_UA", "ur": "ur_PK",
- "vi": "vi_VN", "zu": "zu_ZA"}
-
- return mangleMap.get(inLocale, inLocale)
-
# XXX this should probably be somewhere else
def partition(seq, func=bool, func_range=(True, False)):
buffers = dict(((x, deque()) for x in func_range))
@@ -162,21 +194,17 @@ def get_all_locales():
localeset = set()
for localename in sorted(babel.localedata.list()):
try:
- localedata = babel.Locale.parse(localename)
- except babel.core.UnknownLocaleError:
+ locale = LocaleInfo(localename)
+ except InvalidLocaleSpec:
continue
- # BUG: babel.Locale.parse does not parse @script
- script = _get_locale_script(localename)
- encoding = _get_locale_encoding(localename)
-
- locale = LocaleInfo(localedata, encoding, script)
if repr(locale) not in localeset:
localeset.add(repr(locale))
yield locale
def get_available_translations(domain=None, localedir=None):
+ localeset = set()
domain = domain or gettext._current_domain
localedir = localedir or gettext._default_localedir
@@ -190,17 +218,13 @@ def get_available_translations(domain=None, localedir=None):
for langcode in languages:
try:
- localedata = babel.Locale.parse(mangleLocale(langcode))
- except babel.core.UnknownLocaleError:
+ locale = LocaleInfo(langcode)
+ except InvalidLocaleSpec:
continue
- encoding = _get_locale_encoding(langcode)
-
- # BUG: babel.Locale.parse does not parse @script
- script = _get_locale_script(langcode)
-
- localeinfo = LocaleInfo(localedata, encoding, script)
- yield localeinfo
+ if repr(locale) not in localeset:
+ localeset.add(repr(locale))
+ yield locale
def parse_langcode(langcode):
"""
@@ -264,30 +288,6 @@ def expand_langs(astring):
return list(langs)
-def _get_locale_encoding(locale):
- """
- If locale specification includes encoding (e.g. cs_CZ.UTF-8) returns
- the encoding. Otherwise returns "".
-
- """
-
- if "@" in locale:
- # remove @script suffix
- locale = locale.split("@", -1)[0]
-
- if "." in locale:
- return locale.split(".", -1)[1]
- else:
- return ""
-
-def _get_locale_script(locale):
- """Same as _get_locale_encoding but with the script."""
-
- if "@" in locale:
- return locale.split("@", -1)[1]
- else:
- return ""
-
def write_language_configuration(lang, root):
"""
Write language configuration to the $root/etc/locale.conf file.
@@ -300,13 +300,7 @@ def write_language_configuration(lang, root):
try:
fpath = os.path.normpath(root + LOCALE_CONF_FILE_PATH)
with open(fpath, "w") as fobj:
- # FIXME: Remove this annoying hack once python-babel includes the
- # right information.
- if lang.lang == "ia":
- fobj.write('LANG="ia_FR.UTF-8"\n')
- else:
- fobj.write('LANG="%s"\n' % lang.lang)
-
+ fobj.write('LANG="%s"\n' % lang.lang)
except IOError as ioerr:
msg = "Cannot write language configuration file: %s" % ioerr.strerror
raise LocalizationConfigError(msg)
--
1.7.11.7
More information about the anaconda-patches
mailing list