GetTogether/events/ipstack.py

116 lines
2.9 KiB
Python

from collections import OrderedDict
import requests
from django.conf import settings
from geocoder.base import OneResult, MultipleResultsQuery
IPSTACK_URL = 'http://api.ipstack.com/{0}?access_key={1}&format=json&legacy=1'
RESULT_CACHE = OrderedDict()
CACHE_SIZE = getattr(settings, 'IPSTACK_CACHE_SIZE', 1000)
class IPStackResult(OneResult):
@property
def lat(self):
return self.raw.get('latitude')
@property
def lng(self):
return self.raw.get('longitude')
@property
def latlng(self):
if self.ok:
return [self.lat, self.lng]
return None
@property
def address(self):
if self.city:
return u'{0}, {1} {2}'.format(self.city, self.state, self.country)
elif self.state:
return u'{0}, {1}'.format(self.state, self.country)
elif self.country:
return u'{0}'.format(self.country)
return u''
@property
def postal(self):
zip_code = self.raw.get('zip_code')
postal_code = self.raw.get('postal_code')
if zip_code:
return zip_code
if postal_code:
return postal_code
@property
def city(self):
return self.raw.get('city')
@property
def state(self):
return self.raw.get('region')
@property
def region_code(self):
return self.raw.get('region_code')
@property
def country(self):
return self.raw.get('country_name')
@property
def country_code3(self):
return self.raw.get('country_code3')
@property
def continent(self):
return self.raw.get('continent')
@property
def timezone(self):
return self.raw.get('timezone')
@property
def area_code(self):
return self.raw.get('area_code')
@property
def dma_code(self):
return self.raw.get('dma_code')
@property
def offset(self):
return self.raw.get('offset')
@property
def organization(self):
return self.raw.get('organization')
@property
def ip(self):
return self.raw.get('ip')
@property
def time_zone(self):
return self.raw.get('time_zone')
def get_ipstack_geocoder(ip):
if ip in RESULT_CACHE:
return RESULT_CACHE[ip]
ipstack_key = getattr(settings, 'IPSTACK_ACCESS_KEY', None)
if ipstack_key is None:
print("You must define IPSTACK_ACCESS_KEY in your setting to use ipstack.com geocoding")
return IPStackResult({})
call_url = IPSTACK_URL.format(ip, ipstack_key)
session = requests.Session()
response = session.get(call_url)
if response.status_code != 200:
raise Exception("Call to ipstack.com returned status code {0}".format(response.status_code))
result = IPStackResult(response.json())
RESULT_CACHE[ip] = result
if len(RESULT_CACHE) > CACHE_SIZE:
RESULT_CACHE.popitem(last=False) # Discard the oldest entry
return result