apostrophe/build/lib/uberwriter_lib/pylocales/locales.py

138 lines
4.8 KiB
Python

# -*- coding:utf-8 -*-
#
# Copyright (C) 2012, Maximilian Köhl <linuxmaxi@googlemail.com>
# Copyright (C) 2012, Carlos Jenkins <carlos@jenkins.co.cr>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Query the ISO 639/3166 database about a country or a language. The locales
database contains ISO 639 languages definitions and ISO 3166 countries
definitions. This package provides translation for countries and languages names
if iso-codes package is installed (Ubuntu/Debian).
@see utils/locales/build.py to know the database tables and structure.
"""
import gettext
import logging
import os
import sqlite3
# Public Objects
__all__ = ['Country', 'Language', 'LanguageNotFound',
'CountryNotFound', 'code_to_name']
# Translation
_translator_language = gettext.translation('iso_639', fallback=True).gettext
_translator_country = gettext.translation('iso_3166', fallback=True).gettext
# Decides where the database is located. If an application provides an
# os.path.get_module_path monkey patch to determine the path where the module
# is located it uses this. If not it searches in the directory of this source
# code file.
__path__ = None
if hasattr(os.path, 'get_module_path'):
__path__ = os.path.get_module_path(__file__)
if not os.path.isfile(os.path.join(__path__, 'locales.db')):
__path__ = None
if __path__ is None:
__path__ = os.path.abspath(os.path.realpath(os.path.dirname(__file__)))
# Loading the Database
_database = sqlite3.connect(os.path.join(__path__, 'locales.db'))
logger = logging.getLogger(__name__)
# Exceptions
class LanguageNotFound(Exception):
"""
The specified language wasn't found in the database.
"""
class CountryNotFound(Exception):
"""
The specified country wasn't found in the database.
"""
class Country(object):
def __init__(self, rowid):
country = _database.execute('SELECT * FROM countries WHERE rowid == ?', (rowid,)).fetchone()
self.name = country[0]
self.official_name = country[1]
self.alpha_2 = country[2]
self.alpha_3 = country[3]
self.numeric = country[4]
self.translation = _translator_country(self.name)
@classmethod
def get_country(cls, code, codec):
country = _database.execute('SELECT rowid FROM countries WHERE %s == ?' % (codec), (code,)).fetchone()
if country:
return cls(country[0])
raise CountryNotFound('code: %s, codec: %s' % (code, codec))
@classmethod
def by_alpha_2(cls, code):
return Country.get_country(code, 'alpha_2')
@classmethod
def by_alpha_3(cls, code):
return Country.get_country(code, 'alpha_3')
@classmethod
def by_numeric(cls, code):
return Country.get_country(code, 'numeric')
class Language(object):
def __init__(self, rowid):
language = _database.execute('SELECT * FROM languages WHERE rowid == ?', (rowid,)).fetchone()
self.name = language[0]
self.iso_639_2B = language[1]
self.iso_639_2T = language[2]
self.iso_639_1 = language[3]
self.translation = _translator_language(self.name)
@classmethod
def get_language(cls, code, codec):
language = _database.execute('SELECT rowid FROM languages WHERE %s == ?' % (codec), (code,)).fetchone()
if language:
return cls(language[0])
raise LanguageNotFound('code: %s, codec: %s' % (code, codec))
@classmethod
def by_iso_639_2B(cls, code):
return Language.get_language(code, 'iso_639_2B')
@classmethod
def by_iso_639_2T(cls, code):
return Language.get_language(code, 'iso_639_2T')
@classmethod
def by_iso_639_1(cls, code):
return Language.get_language(code, 'iso_639_1')
def code_to_name(code, separator='_'):
"""
Get the natural name of a language based on it's code.
"""
logger.debug('requesting name for code "{}"'.format(code))
code = code.split(separator)
if len(code) > 1:
lang = Language.by_iso_639_1(code[0]).translation
country = Country.by_alpha_2(code[1]).translation
return '{lang} ({country})'.format(lang=lang, country=country)
else:
return Language.by_iso_639_1(code[0]).translation