[util] Add central geolocation info library
This commit is contained in:
parent
0ef6a165e4
commit
74c25ba2ee
3 changed files with 112 additions and 1 deletions
|
@ -22,7 +22,6 @@
|
||||||
- allow handlers to specify whether to update or not (e.g. scroll)
|
- allow handlers to specify whether to update or not (e.g. scroll)
|
||||||
- API documentation
|
- API documentation
|
||||||
- github pages
|
- github pages
|
||||||
- central geolocation service? (currency, weather, rtt)
|
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
- themes: use colors to improve theme readability
|
- themes: use colors to improve theme readability
|
||||||
|
|
43
tests/util/test_location.py
Normal file
43
tests/util/test_location.py
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import unittest
|
||||||
|
import json
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
import util.location
|
||||||
|
|
||||||
|
class location(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
patcher = unittest.mock.patch('util.location.urllib.request')
|
||||||
|
self.addCleanup(patcher.stop)
|
||||||
|
self.request = patcher.start()
|
||||||
|
util.location.reset()
|
||||||
|
|
||||||
|
self.primary = {
|
||||||
|
'country': 'Middle Earth',
|
||||||
|
'longitude': '10.0',
|
||||||
|
'latitude': '20.5',
|
||||||
|
'ip': '127.0.0.1',
|
||||||
|
}
|
||||||
|
self.secondary = {
|
||||||
|
'country_name': 'Rivia',
|
||||||
|
'longitude': '-10.0',
|
||||||
|
'latitude': '-23',
|
||||||
|
'ip': '127.0.0.6',
|
||||||
|
}
|
||||||
|
|
||||||
|
def test_primary_provider(self):
|
||||||
|
self.request.urlopen.return_value.read.return_value = json.dumps(self.primary)
|
||||||
|
util.location.country()
|
||||||
|
self.assertEqual(self.primary['country'], util.location.country())
|
||||||
|
self.assertEqual((self.primary['latitude'], self.primary['longitude']), util.location.coordinates())
|
||||||
|
self.assertEqual(self.primary['ip'], util.location.public_ip())
|
||||||
|
|
||||||
|
def test_secondary_provider(self):
|
||||||
|
urlopen = unittest.mock.MagicMock()
|
||||||
|
urlopen.read.return_value = json.dumps(self.secondary)
|
||||||
|
self.request.urlopen.side_effect = [ RuntimeError(), urlopen ]
|
||||||
|
|
||||||
|
self.assertEqual(self.secondary['country_name'], util.location.country())
|
||||||
|
self.assertEqual((self.secondary['latitude'], self.secondary['longitude']), util.location.coordinates())
|
||||||
|
self.assertEqual(self.secondary['ip'], util.location.public_ip())
|
||||||
|
|
||||||
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
69
util/location.py
Normal file
69
util/location.py
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
__document = None
|
||||||
|
__data = {}
|
||||||
|
__next = 0
|
||||||
|
|
||||||
|
__sources = [
|
||||||
|
{
|
||||||
|
'url': 'http://free.ipwhois.io/json/',
|
||||||
|
'mapping': {
|
||||||
|
'latitude': 'latitude',
|
||||||
|
'longitude': 'longitude',
|
||||||
|
'country': 'country',
|
||||||
|
'ip': 'public_ip',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'url': 'http://ipapi.co/json',
|
||||||
|
'mapping': {
|
||||||
|
'latitude': 'latitude',
|
||||||
|
'longitude': 'longitude',
|
||||||
|
'country_name': 'country',
|
||||||
|
'ip': 'public_ip',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
def __expired():
|
||||||
|
global __next
|
||||||
|
return __next <= time.time()
|
||||||
|
|
||||||
|
def __load():
|
||||||
|
global __data
|
||||||
|
global __next
|
||||||
|
|
||||||
|
__data = {}
|
||||||
|
for src in __sources:
|
||||||
|
try:
|
||||||
|
tmp = json.loads(urllib.request.urlopen(src['url']).read())
|
||||||
|
for k, v in src['mapping'].items():
|
||||||
|
__data[v] = tmp.get(k, None)
|
||||||
|
__next = time.time() + 60*60*12 # update once every 12h
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
pass
|
||||||
|
__next = time.time() + 60*30 # error - try again every 30m
|
||||||
|
|
||||||
|
def __get(name, default=None):
|
||||||
|
global __data
|
||||||
|
if not __data or __expired():
|
||||||
|
__load()
|
||||||
|
return __data.get(name, default)
|
||||||
|
|
||||||
|
def reset():
|
||||||
|
global __next
|
||||||
|
__next = 0
|
||||||
|
|
||||||
|
def coordinates():
|
||||||
|
return __get('latitude'), __get('longitude')
|
||||||
|
|
||||||
|
def country():
|
||||||
|
return __get('country')
|
||||||
|
|
||||||
|
def public_ip():
|
||||||
|
return __get('public_ip')
|
||||||
|
|
||||||
|
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
Loading…
Reference in a new issue