Commit 0078e49b authored by xa's avatar xa

cleanup

parent cfea515c
......@@ -19,12 +19,7 @@ It will respond with::
Content-Type: application/json; charset=utf-8
{
"lat": 48.8534,
"lng": 2.3488,
"city": "Paris",
"country": "Frankreich",
"iso_code": "FR",
"accuracy": 100,
"number": "+33123456789",
"timezone": "Europe/Paris"
}
......@@ -32,7 +27,7 @@ It will respond with::
Query parameters:
* `number`: a number to check. mandatory
* `code`: a code to check, like FR, US, GB. optional
* `code`: territory code to check against, like FR. optional
Returned fields:
......@@ -52,7 +47,7 @@ Returned status codes:
It exposes also some codes::
GET /country?lang=en
GET /territories?lang=en
Host: localhost:80
It will respond with::
......@@ -62,8 +57,8 @@ It will respond with::
Content-Type: application/json; charset=utf-8
[
{"name": "Afghanistan", "dial": "93", "code": "AF"},
{"name": "Albania", "dial": "355", "code": "AL"},
{"name": "Afghanistan", "idd": "93", "code": "AF"},
{"name": "Albania", "idd": "355", "code": "AL"},
...
]
......@@ -72,3 +67,10 @@ Query parameters:
* `lang`: a language for translating country and city.
Supported languages are: `de`, `en`, `es`, `fr`, `ja`, `pt-BR`, `ru`, and `zh-CN`.
Returned fields:
* `name`: territory name. mandatory
* `idd`: international dialer code. mandatory
* `code`: ISO code used for check. mandatory
class PossibleError(Exception):
pass
class ValidError(Exception):
pass
class ParseError(Exception):
pass
from collections import namedtuple
from functools import lru_cache
import phonenumbers
from phonenumbers import NumberParseException
from phonenumbers.timezone import time_zones_for_number
from . import errors
import csv
Country = namedtuple('Country', 'name dial code')
Territory = namedtuple('Territory', 'name idd code')
Record = namedtuple('Record', 'number timezone')
......@@ -23,20 +24,20 @@ class Lookup:
self.path = path
@lru_cache(maxsize=256)
def countries(self, language=None):
def territories(self, language=None):
language = language or 'en'
with open(self.path, encoding="utf-8") as csvfile:
for row in csv.DictReader(csvfile, delimiter=',', quotechar='"'):
name = row['name'] or row['official_name_en']
dial = row['Dial']
idd = row['Dial']
code = row['ISO3166-1-Alpha-2']
if not name:
continue
if not dial:
if not idd:
continue
if not code:
continue
yield Country(name, dial, code)
yield Territory(name, idd, code)
@lru_cache(maxsize=256)
def __call__(self, *, number, code=None):
......@@ -46,18 +47,18 @@ class Lookup:
raise errors.PossibleError('%s is not a possible number' % number)
if not phonenumbers.is_valid_number(parsed):
raise errors.ValidError('%s not valid number' % number)
except phonenumbers.NumberParseException as error:
except NumberParseException as error:
if error.error_type == NumberParseException.INVALID_COUNTRY_CODE:
raise ParseError('country code is invalid or missing') from error
raise errors.ParseError('country code is invalid or missing') from error
elif error.error_type == NumberParseException.NOT_A_NUMBER:
raise ParseError('%s is not a valid number' % number) from error
raise errors.ParseError('%s is not a valid number' % number) from error
elif error.error_type == NumberParseException.TOO_SHORT_AFTER_IDD:
raise ParseError('%s is too short idd' % number) from error
raise errors.ParseError('%s is too short after idd' % number) from error
elif error.error_type == NumberParseException.TOO_SHORT_NSN:
raise ParseError('%s is too short nsn' % number) from error
raise errors.ParseError('%s is too short nsn' % number) from error
elif error.error_type == NumberParseException.TOO_LONG:
raise ParseError('%s is too long' % number) from error
raise ParseError(error._msg) from error
raise errors.ParseError('%s is too long' % number) from error
raise errors.ParseError(error._msg) from error
except Exception as error:
raise
formatted = phonenumbers.format_number(parsed, phonenumbers.PhoneNumberFormat.E164)
......
import pathlib
from .views import countries, validate
from .views import territories, validate
PROJECT_ROOT = pathlib.Path(__file__).parent
def setup_routes(app):
app.router.add_get('/', validate)
app.router.add_get('/countries', countries)
app.router.add_get('/territories', territories)
from aiohttp import web
async def countries(request):
async def territories(request):
lang = request.query.get('lang', None)
result = []
for name, dial, code in request.app['lookup'].countries(language=lang):
for name, idd, code in request.app['lookup'].territories(language=lang):
result.append({
'name': name,
'dial': dial,
'idd': idd,
'code': code
})
return web.json_response(result, headers={
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment