2018-09-17 08:27:00 +08:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
#
|
|
|
|
# Copyright (c) 2013 the BabelFish authors. All rights reserved.
|
|
|
|
# Use of this source code is governed by the 3-clause BSD license
|
|
|
|
# that can be found in the LICENSE file.
|
|
|
|
#
|
2021-12-02 04:47:00 +08:00
|
|
|
from __future__ import unicode_literals
|
2018-09-17 08:27:00 +08:00
|
|
|
from collections import namedtuple
|
|
|
|
from functools import partial
|
|
|
|
from pkg_resources import resource_stream # @UnresolvedImport
|
|
|
|
from .converters import ConverterManager
|
|
|
|
from . import basestr
|
|
|
|
|
|
|
|
|
|
|
|
COUNTRIES = {}
|
|
|
|
COUNTRY_MATRIX = []
|
|
|
|
|
|
|
|
#: The namedtuple used in the :data:`COUNTRY_MATRIX`
|
|
|
|
IsoCountry = namedtuple('IsoCountry', ['name', 'alpha2'])
|
|
|
|
|
|
|
|
f = resource_stream('babelfish', 'data/iso-3166-1.txt')
|
|
|
|
f.readline()
|
|
|
|
for l in f:
|
|
|
|
iso_country = IsoCountry(*l.decode('utf-8').strip().split(';'))
|
|
|
|
COUNTRIES[iso_country.alpha2] = iso_country.name
|
|
|
|
COUNTRY_MATRIX.append(iso_country)
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
|
|
|
|
class CountryConverterManager(ConverterManager):
|
|
|
|
""":class:`~babelfish.converters.ConverterManager` for country converters"""
|
|
|
|
entry_point = 'babelfish.country_converters'
|
|
|
|
internal_converters = ['name = babelfish.converters.countryname:CountryNameConverter']
|
|
|
|
|
|
|
|
country_converters = CountryConverterManager()
|
|
|
|
|
|
|
|
|
|
|
|
class CountryMeta(type):
|
|
|
|
"""The :class:`Country` metaclass
|
|
|
|
|
|
|
|
Dynamically redirect :meth:`Country.frommycode` to :meth:`Country.fromcode` with the ``mycode`` `converter`
|
|
|
|
|
|
|
|
"""
|
|
|
|
def __getattr__(cls, name):
|
|
|
|
if name.startswith('from'):
|
|
|
|
return partial(cls.fromcode, converter=name[4:])
|
|
|
|
return type.__getattribute__(cls, name)
|
|
|
|
|
|
|
|
|
|
|
|
class Country(CountryMeta(str('CountryBase'), (object,), {})):
|
|
|
|
"""A country on Earth
|
|
|
|
|
|
|
|
A country is represented by a 2-letter code from the ISO-3166 standard
|
|
|
|
|
|
|
|
:param string country: 2-letter ISO-3166 country code
|
|
|
|
|
|
|
|
"""
|
|
|
|
def __init__(self, country):
|
|
|
|
if country not in COUNTRIES:
|
|
|
|
raise ValueError('%r is not a valid country' % country)
|
|
|
|
|
|
|
|
#: ISO-3166 2-letter country code
|
|
|
|
self.alpha2 = country
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def fromcode(cls, code, converter):
|
|
|
|
"""Create a :class:`Country` by its `code` using `converter` to
|
|
|
|
:meth:`~babelfish.converters.CountryReverseConverter.reverse` it
|
|
|
|
|
|
|
|
:param string code: the code to reverse
|
|
|
|
:param string converter: name of the :class:`~babelfish.converters.CountryReverseConverter` to use
|
|
|
|
:return: the corresponding :class:`Country` instance
|
|
|
|
:rtype: :class:`Country`
|
|
|
|
|
|
|
|
"""
|
|
|
|
return cls(country_converters[converter].reverse(code))
|
|
|
|
|
|
|
|
def __getstate__(self):
|
|
|
|
return self.alpha2
|
|
|
|
|
|
|
|
def __setstate__(self, state):
|
|
|
|
self.alpha2 = state
|
|
|
|
|
|
|
|
def __getattr__(self, name):
|
|
|
|
try:
|
|
|
|
return country_converters[name].convert(self.alpha2)
|
|
|
|
except KeyError:
|
|
|
|
raise AttributeError(name)
|
|
|
|
|
|
|
|
def __hash__(self):
|
|
|
|
return hash(self.alpha2)
|
|
|
|
|
|
|
|
def __eq__(self, other):
|
|
|
|
if isinstance(other, basestr):
|
|
|
|
return str(self) == other
|
|
|
|
if not isinstance(other, Country):
|
|
|
|
return False
|
|
|
|
return self.alpha2 == other.alpha2
|
|
|
|
|
|
|
|
def __ne__(self, other):
|
|
|
|
return not self == other
|
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return '<Country [%s]>' % self
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return self.alpha2
|