Skip to content

Commit

Permalink
Merge bc776b3 into 449a137
Browse files Browse the repository at this point in the history
  • Loading branch information
Bibhas committed Apr 9, 2019
2 parents 449a137 + bc776b3 commit 0c52997
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 0 deletions.
30 changes: 30 additions & 0 deletions baseframe/__init__.py
Expand Up @@ -3,12 +3,14 @@
from __future__ import absolute_import

import json
import gettext

from pytz import timezone, UTC
from pytz.tzinfo import BaseTzInfo
from speaklater import is_lazy_string
import six
from furl import furl
import pycountry

from flask import Blueprint, request, current_app
from flask.json import JSONEncoder as JSONEncoderBase
Expand Down Expand Up @@ -321,6 +323,34 @@ def get_timezone():
return current_app.config.get('tz') or UTC


def localized_country_list():
"""
Returns a localized list of country names and their ISO3166-1 alpha-2 code inside a request context.
The locale depends on the `Accept-Language` header of the request for now.
The best matched locale is picked in `get_locale()` function and then used
to localize the country names.
The list is ordered by the localized country name and not the alpha-2 code.
The list is also memoized with the locale code as the key for a day.
"""
return _localized_country_list_inner(get_locale())


@cache.memoize(timeout=86400)
def _localized_country_list_inner(locale):
if locale == 'en':
countries = [(country.name, country.alpha_2) for country in pycountry.countries]
else:
pycountry_locale = gettext.translation('iso3166-1', pycountry.LOCALES_DIR, languages=[locale])
if six.PY2:
countries = [(pycountry_locale.gettext(country.name).decode('utf-8'), country.alpha_2) for country in pycountry.countries]
else:
countries = [(pycountry_locale.gettext(country.name), country.alpha_2) for country in pycountry.countries]
countries.sort()
return [(code, name) for (name, code) in countries]


def localize_timezone(datetime, tz=None):
if not datetime.tzinfo:
datetime = UTC.localize(datetime)
Expand Down
1 change: 1 addition & 0 deletions setup.py
Expand Up @@ -34,6 +34,7 @@
'lxml',
'mxsniff',
'furl',
'pycountry',
# For link validation with SNI SSL support
'requests',
'pyOpenSSL',
Expand Down
68 changes: 68 additions & 0 deletions tests/test_utils.py
@@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-

from baseframe import _localized_country_list_inner, localized_country_list
from .fixtures import app1 as app, TestCaseBaseframe


@app.route('/localetest')
def locale_testview():
country_list = localized_country_list()
return dict(country_list)['DE']


class TestUtils(TestCaseBaseframe):
def test_localized_country_list(self):
countries = _localized_country_list_inner('en')
assert dict(countries)['DE'] == u"Germany"
countries = _localized_country_list_inner('de')
assert dict(countries)['DE'] == u"Deutschland"
countries = _localized_country_list_inner('es')
assert dict(countries)['DE'] == u"Alemania"
countries = _localized_country_list_inner('hi')
assert dict(countries)['DE'] == u"जर्मनी"

def test_localized_country_inrequest(self):
with app.test_client() as c:
rv = c.get('/localetest', headers={'Accept-Language': 'en;q=0.8, *;q=0.5'})
assert rv.data.decode('utf-8') == u"Germany"

with app.test_client() as c:
rv = c.get('/localetest', headers={'Accept-Language': 'de;q=0.9, en;q=0.8, *;q=0.5'})
assert rv.data.decode('utf-8') == u"Deutschland"

with app.test_client() as c:
rv = c.get('/localetest', headers={'Accept-Language': 'es;q=0.9, en;q=0.8, *;q=0.5'})
assert rv.data.decode('utf-8') == u"Alemania"

with app.test_client() as c:
rv = c.get('/localetest', headers={'Accept-Language': 'hi;q=0.9, en;q=0.8, *;q=0.5'})
assert rv.data.decode('utf-8') == u"जर्मनी"

def test_localized_country_order(self):
"""
Ordering is done by name. So even though index(DE) < index(DZ),
the order will vary because of their localized names.
"""
countries = _localized_country_list_inner('en')
assert dict(countries)['DE'] == u"Germany"
assert dict(countries)['DZ'] == u"Algeria"
# index(DE) < index(DZ), but index(Germany) > index(Algeria)
assert countries.index((u'DE', u'Germany')) > countries.index((u'DZ', u'Algeria'))

countries = _localized_country_list_inner('de')
assert dict(countries)['DE'] == u"Deutschland"
assert dict(countries)['DZ'] == u"Algerien"
# index(DE) < index(DZ), but index(Deutschland) > index(Algerien)
assert countries.index((u'DE', u'Deutschland')) > countries.index((u'DZ', u'Algerien'))

countries = _localized_country_list_inner('es')
assert dict(countries)['DE'] == u"Alemania"
assert dict(countries)['DZ'] == u"Algeria"
# index(DE) < index(DZ), and index(Alemania) < index(Algeria)
assert countries.index((u'DE', u'Alemania')) < countries.index((u'DZ', u'Algeria'))

countries = _localized_country_list_inner('hi')
assert dict(countries)['DE'] == u"जर्मनी"
assert dict(countries)['DZ'] == u"अल्जीरिया"
# index(DE) < index(DZ), but index(जर्मनी) > index(अल्जीरिया)
assert countries.index((u'DE', u'जर्मनी')) > countries.index((u'DZ', u'अल्जीरिया'))

0 comments on commit 0c52997

Please sign in to comment.