116 lines
2.9 KiB
Python
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
|