1# vim:fileencoding=utf-8
2"""pycountry"""
3
4import os.path
5
6import pycountry.db
7
8try:
9    from pkg_resources import resource_filename
10except ImportError:
11    def resource_filename(package_or_requirement, resource_name):
12        return os.path.join(os.path.dirname(__file__), resource_name)
13
14
15LOCALES_DIR = resource_filename('pycountry', 'locales')
16DATABASE_DIR = resource_filename('pycountry', 'databases')
17
18
19class ExistingCountries(pycountry.db.Database):
20    """Provides access to an ISO 3166 database (Countries)."""
21
22    data_class_name = 'Country'
23    root_key = '3166-1'
24
25
26class HistoricCountries(pycountry.db.Database):
27    """Provides access to an ISO 3166-3 database
28    (Countries that have been removed from the standard)."""
29
30    data_class_name = 'Country'
31    root_key = '3166-3'
32
33
34class Scripts(pycountry.db.Database):
35    """Provides access to an ISO 15924 database (Scripts)."""
36
37    data_class_name = 'Script'
38    root_key = '15924'
39
40
41class Currencies(pycountry.db.Database):
42    """Provides access to an ISO 4217 database (Currencies)."""
43
44    data_class_name = 'Currency'
45    root_key = '4217'
46
47
48class Languages(pycountry.db.Database):
49    """Provides access to an ISO 639-1/2T/3 database (Languages)."""
50
51    no_index = ['status', 'scope', 'type', 'inverted_name', 'common_name']
52    data_class_name = 'Language'
53    root_key = '639-3'
54
55
56class Subdivision(pycountry.db.Data):
57
58    def __init__(self, **kw):
59        if 'parent' in kw:
60            kw['parent_code'] = kw['parent']
61        else:
62            kw['parent_code'] = None
63        super(Subdivision, self).__init__(**kw)
64        self.country_code = self.code.split('-')[0]
65        if self.parent_code is not None:
66            self.parent_code = '%s-%s' % (self.country_code, self.parent_code)
67
68    @property
69    def country(self):
70        return countries.get(alpha_2=self.country_code)
71
72    @property
73    def parent(self):
74        if not self.parent_code:
75            return None
76        return subdivisions.get(code=self.parent_code)
77
78
79class Subdivisions(pycountry.db.Database):
80
81    # Note: subdivisions can be hierarchical to other subdivisions. The
82    # parent_code attribute is related to other subdivisons, *not*
83    # the country!
84
85    data_class_base = Subdivision
86    data_class_name = 'Subdivision'
87    no_index = ['name', 'parent_code', 'parent', 'type']
88    root_key = '3166-2'
89
90    def _load(self, *args, **kw):
91        super(Subdivisions, self)._load(*args, **kw)
92
93        # Add index for the country code.
94        self.indices['country_code'] = {}
95        for subdivision in self:
96            divs = self.indices['country_code'].setdefault(
97                subdivision.country_code, set())
98            divs.add(subdivision)
99
100    def get(self, **kw):
101        try:
102            return super(Subdivisions, self).get(**kw)
103        except KeyError:
104            # This propagates a KeyError if the country does not exist and
105            # returns an empty list if it exists but it does not have (or we do
106            # not know about)  any sub-divisions.
107            if 'country_code' in kw:
108                countries.get(alpha_2=kw['country_code'])
109                return []
110            raise
111
112
113countries = ExistingCountries(os.path.join(DATABASE_DIR, 'iso3166-1.json'))
114historic_countries = HistoricCountries(
115    os.path.join(DATABASE_DIR, 'iso3166-3.json'))
116scripts = Scripts(os.path.join(DATABASE_DIR, 'iso15924.json'))
117currencies = Currencies(os.path.join(DATABASE_DIR, 'iso4217.json'))
118languages = Languages(os.path.join(DATABASE_DIR, 'iso639-3.json'))
119subdivisions = Subdivisions(os.path.join(DATABASE_DIR, 'iso3166-2.json'))
120