320827d577
OK - so I have to admit I *hate* the fact that PIP seems to require a subdirectory named like the library. But since the PIP package is something really nifty to have (thanks to @tony again!!!), I updated the codebase to hopefully conform with what PIP expects. Testruns so far look promising...
103 lines
2.1 KiB
Python
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://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():
|
|
"""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
|