1# Copyright 2010 Google Inc. All Rights Reserved.
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#      http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Class used for determining GeoIP location."""
16
17import re
18import tempfile
19
20# external dependencies (from nb_third_party)
21import httplib2
22import simplejson
23
24import util
25
26
27def GetFromGoogleLocAPI():
28  """Use the Google Loc JSON API from Google Gears.
29
30  Returns:
31    A dictionary containing geolocation information
32
33  NOTE: This is in violation of the Gears Terms of Service. See:
34  http://code.google.com/p/gears/wiki/GeolocationAPI
35  """
36  h = httplib2.Http(tempfile.gettempdir(), timeout=10)
37  url = 'http://www.google.com/loc/json'
38  post_data = {'request_address': 'true', 'version': '1.1.0', 'source': 'namebench'}
39  unused_resp, content = h.request(url, 'POST', simplejson.dumps(post_data))
40  try:
41    data = simplejson.loads(content)['location']
42    return {
43        'region_name': data['address'].get('region'),
44        'country_name': data['address'].get('country'),
45        'country_code': data['address'].get('country_code'),
46        'city': data['address'].get('city'),
47        'latitude': data['latitude'],
48        'longitude': data['longitude'],
49        'source': 'gloc'
50    }
51  except:
52    print '* Failed to use GoogleLocAPI: %s (content: %s)' % (util.GetLastExceptionString(), content)
53    return {}
54
55
56def GetFromMaxmindJSAPI():
57  h = httplib2.Http(tempfile.gettempdir(), timeout=10)
58  unused_resp, content = h.request('http://j.maxmind.com/app/geoip.js', 'GET')
59  keep = ['region_name', 'country_name', 'city', 'latitude', 'longitude', 'country_code']
60  results = dict([x for x in re.findall("geoip_(.*?)\(.*?\'(.*?)\'", content) if x[0] in keep])
61  results.update({'source': 'mmind'})
62  if results:
63    return results
64  else:
65    return {}
66
67
68def GetGeoData():
69  """Get geodata from any means necessary. Sanitize as necessary."""
70  try:
71    json_data = GetFromGoogleLocAPI()
72    if not json_data:
73      json_data = GetFromMaxmindJSAPI()
74
75    # Make our data less accurate. We don't need any more than that.
76    json_data['latitude'] = '%.3f' % float(json_data['latitude'])
77    json_data['longitude'] = '%.3f' % float(json_data['longitude'])
78    return json_data
79  except:
80    print 'Failed to get Geodata: %s' % util.GetLastExceptionString()
81    return {}
82