bumblebee-status/bumblebee_status/util/location.py
tobi-wan-kenobi 350648b0cd [util/location] reverse location providers
seems that ipapi gives better results wrt. location
2020-06-27 15:05:57 +02:00

103 lines
2.1 KiB
Python

"""Retrieves location information from an external
service and caches it for 12h (retries are done every
30m in case of problems)
Right now, it uses (in order of preference):
- http://free.ipwhois.io/
- http://ipapi.co/
"""
import json
import time
import urllib.request
__document = None
__data = {}
__next = 0
__sources = [
{
"url": "http://ipapi.co/json",
"mapping": {
"latitude": "latitude",
"longitude": "longitude",
"country_name": "country",
"ip": "public_ip",
},
},
{
"url": "http://free.ipwhois.io/json/",
"mapping": {
"latitude": "latitude",
"longitude": "longitude",
"country": "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():
"""Resets the location library, ensuring that a new query will be started
"""
global __next
__next = 0
def coordinates():
"""Returns a latitude, longitude pair
:return: current latitude and longitude
:rtype: pair of strings
"""
return __get("latitude"), __get("longitude")
def country():
"""Returns the current country name
:return: country name
:rtype: string
"""
return __get("country")
def public_ip():
"""Returns the current public IP
:return: public IP
:rtype: string
"""
return __get("public_ip")
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4