You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@community.apache.org by ni...@apache.org on 2014/01/20 23:34:37 UTC
svn commit: r1559846 - in /comdev/nearby_people: lib/geoname.py
local_settings.py.example nearby/views.py
Author: nick
Date: Mon Jan 20 22:34:37 2014
New Revision: 1559846
URL: http://svn.apache.org/r1559846
Log:
The GeoNames WS server seems to have finally gone, switch to their new API server instead (needs a username and a different library)
Modified:
comdev/nearby_people/lib/geoname.py
comdev/nearby_people/local_settings.py.example
comdev/nearby_people/nearby/views.py
Modified: comdev/nearby_people/lib/geoname.py
URL: http://svn.apache.org/viewvc/comdev/nearby_people/lib/geoname.py?rev=1559846&r1=1559845&r2=1559846&view=diff
==============================================================================
--- comdev/nearby_people/lib/geoname.py (original)
+++ comdev/nearby_people/lib/geoname.py Mon Jan 20 22:34:37 2014
@@ -1,357 +1,103 @@
-# -*- coding: utf-8 -*-
+# New GeoNames library from Greg Robbins
+# See https://github.com/gregrobbins/geonames-python
-"""Python wrapper for geoname web APIs
+import sys
+import urllib
+import urllib2
+import simplejson as json
+DOMAIN = 'http://api.geonames.org/'
+USERNAME = '' #enter your geonames username here
+
+def fetchJson(method, params):
+ uri = DOMAIN + '%s?%s&username=%s' % (method, urllib.urlencode(params), USERNAME)
+ print uri
+ resource = urllib2.urlopen(uri).readlines()
+ js = json.loads(resource[0])
+ return js
+
+def get(geonameId, **kwargs):
+ method = 'getJSON'
+ valid_kwargs = ('lang',)
+ params = {'geonameId': geonameId}
+ for key in kwargs:
+ if key in valid_kwargs:
+ params[key] = kwargs[key]
+ return fetchJson(method, params)
+
+def children(geonameId, **kwargs):
+ method = 'childrenJSON'
+ valid_kwargs = ('maxRows', 'lang',)
+ params = {'geonameId': geonameId}
+ for key in kwargs:
+ if key in valid_kwargs:
+ params[key] = kwargs[key]
+ results = fetchJson(method, params)
-created 19/03/2006 By Nicolas Laurance
-
-This module allows you to access geoname's web APIs,
-and get the results programmatically.
-Described here:
- http://www.geonames.org/export/
-
-It is based on the Mark Pilgrim's technorati API :
- http://www.sifry.com/alerts/archives/000288.html
-
-def postalCodeSearch(postalcode, placename='', country=COUNTRY, maxRows='10', http_proxy=None):
-def postalCodeLookupJSON(postalcode, placename='', country=COUNTRY, maxRows='10',gcallback='', http_proxy=None):
-def findNearbyPostalCodes(postalcode, placename='', country=COUNTRY, radius='5', maxRows='10',lat=None,lng=None, http_proxy=None):
-def postalCodeCountryInfo(http_proxy=None):
-def search(placename='', country=COUNTRY, maxRows='10', style='SHORT',lang=LANG, fclass=None, http_proxy=None):
-def findNearbyPlaceName(lat,lng, http_proxy=None):
-
-Sample usage:
->>> import geoname
->>> result=geoname.postalCodeSearch('35580','guichen','fr','10')
->>> result.totalResultsCount
-1
->>> result.code[0].lat
-47.966666699999998
->>> result.code[0].lng
--1.8
-
->>> result=geoname.postalCodeLookupJSON('35580','guichen','fr','10')
->>> result['postalcodes']
-[{'postalcode': '35580', 'placeName': 'Guichen', 'countryCode': 'FR'}]
-
->>> result=geoname.findNearbyPostalCodes('35000','rennes','FR',10,10)
->>> for b in result.code:
-... print '%s : %s' %(b.name,b.postalcode)
-...
-Rennes : 35700
-Rennes : 35200
-Rennes : 35000
-St Jacques De La Lande : 35136
-Noyal Sur Seiche : 35230
-Pont Pean : 35131
-Chartres De Bretagne : 35131
-Chantepie : 35135
-Chatillon Sur Seiche : 35230
-St Gregoire : 35760
-
->>> result=geoname.findNearbyPostalCodes('','','FR',10,10,47.97,-1.8)
->>> for b in result.code:
-... print '%s : %s' %(b.name,b.postalcode)
-...
-Guichen : 35580
-Pont Rean : 35580
-Pont Rean : 35170
-Goven : 35580
-Lassy : 35580
-Bourg Des Comptes : 35890
-Guignen : 35580
-St Senoux : 35580
-Bruz : 35170
-Chavagne : 35310
-
-
->>> result=geoname.search('guichen','fr',5,'SHORT','fr')
->>> result.totalResultsCount
-3
->>> for b in result.geoname:
-... print '%s' %(b.name)
-...
-Guichen
-Guiche
-La Guiche
-
-
->>> result=geoname.findNearbyPlaceName(47.97,-1.8)
->>> for b in result.geoname:
-... print '%s' % b.name
-...
-Guichen
-
-"""
-
-__author__ = "Nicolas Laurance (nlaurance@zindep.com)"
-__version__ = "0.1"
-__cvsversion__ = "$Revision: 1.0 $"[11:-2]
-__date__ = "$Date: 2003/06/19 22:40:53 $"[7:-2]
-__copyright__ = "Copyright (c) 2006 Nicolas Laurance"
-__license__ = "Python"
-
-from xml.dom import minidom
-import os, sys, urllib, re
-try:
- import timeoutsocket # http://www.timo-tasi.org/python/timeoutsocket.py
- timeoutsocket.setDefaultSocketTimeout(120)
-except ImportError:
- pass
-
-HTTP_PROXY = None
-DEBUG = 0
-COUNTRY = 'FR'
-LANG ='fr'
-
-
-# don't touch the rest of these constants
-class GeonameError(Exception): pass
-
-## administrative functions
-def version():
- print """PyGeoname %(__version__)s
-%(__copyright__)s
-released %(__date__)s
-""" % globals()
-
-def setProxy(http_proxy):
- """set HTTP proxy"""
- global HTTP_PROXY
- HTTP_PROXY = http_proxy
-
-def getProxy(http_proxy = None):
- """get HTTP proxy"""
- return http_proxy or HTTP_PROXY
-
-def getProxies(http_proxy = None):
- http_proxy = getProxy(http_proxy)
- if http_proxy:
- proxies = {"http": http_proxy}
+ if('geonames' in results):
+ return results['geonames']
else:
- proxies = None
- return proxies
+ return None
-def _contentsOf(dirname, filename):
- filename = os.path.join(dirname, filename)
- if not os.path.exists(filename): return None
- fsock = open(filename)
- contents = fsock.read()
- fsock.close()
- return contents
-
-def _getScriptDir():
- if __name__ == '__main__':
- return os.path.abspath(os.path.dirname(sys.argv[0]))
+def search(**kwargs):
+ method = 'searchJSON'
+ valid_kwargs = ('q', 'name', 'name_equals', 'name_startsWith', 'maxRows', 'startRow', 'country', 'countryBias', 'continentCode', 'adminCode1', 'adminCode2', 'adminCode3', 'featureClass', 'featureCode', 'lang', 'type', 'style', 'isNameRequired', 'tag', 'operator', 'charset',)
+ params = []
+ for key in kwargs:
+ if key in valid_kwargs:
+ # One or many values?
+ value = kwargs[key]
+ if isinstance(value, basestring) or isinstance(value, int):
+ params.append((key,value))
+ else:
+ for v in value:
+ params.append((key,v))
+ results = fetchJson(method, params)
+
+ if('geonames' in results):
+ return results['geonames']
+ elif('status' in results and 'message' in results['status']):
+ raise IOError(results['status']['message'])
else:
- return os.path.abspath(os.path.dirname(sys.modules[__name__].__file__))
+ return None
-class Bag: pass
+def postalCodeSearch(**kwargs):
+ method = 'postalCodeSearchJSON'
+ valid_kwargs = ('postalcode', 'postalcode_startsWith', 'placename', 'placename_startsWith', 'maxRows', 'country', 'countryBias', 'style', 'operator', 'isReduced', 'charset',)
+ params = {}
+ for key in kwargs:
+ if key in valid_kwargs:
+ params[key] = kwargs[key]
+ results = fetchJson(method, params)
-_intFields = ('totalResultsCount')
-_dateFields = ()
-_listFields = ('code','geoname','country',)
-_floatFields = ('lat','lng','distance')
-
-def unmarshal(element):
- #import pdb;pdb.set_trace()
- rc = Bag()
- childElements = [e for e in element.childNodes if isinstance(e, minidom.Element)]
- if childElements:
- for child in childElements:
- key = child.tagName
- if hasattr(rc, key):
- if key in _listFields:
- setattr(rc, key, getattr(rc, key) + [unmarshal(child)])
- elif isinstance(child, minidom.Element) and (child.tagName in ( )):
- rc = unmarshal(child)
- elif key in _listFields:
- setattr(rc, key, [unmarshal(child)])
- else:
- setattr(rc, key, unmarshal(child))
+ if('postalCodes' in results):
+ return results['postalCodes']
else:
- rc = "".join([e.data for e in element.childNodes if isinstance(e, minidom.Text)])
- if str(element.tagName) in _intFields:
- rc = int(rc)
- if DEBUG: print '%s : %s' % (element.tagName,rc)
- elif str(element.tagName) in _floatFields:
- rc = float(rc)
- if DEBUG: print '%s : %s' % (element.tagName,rc)
- elif str(element.tagName) in _dateFields:
- year, month, day, hour, minute, second = re.search(r'(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})', rc).groups()
- rc = (int(year), int(month), int(day), int(hour), int(minute), int(second), 0, 0, 0)
- if DEBUG: print '%s : %s' % (element.tagName,rc)
- return rc
-
-def _do(url, http_proxy):
- proxies = getProxies(http_proxy)
- u = urllib.FancyURLopener(proxies)
- usock = u.open(url)
- rawdata = usock.read()
- if DEBUG: print rawdata
- xmldoc = minidom.parseString(rawdata)
- usock.close()
- data = unmarshal(xmldoc)
-# if hasattr(data, 'ErrorMsg'):
- if 0:
- raise TechnoratiError, data
- else:
- return data
+ return None
-## main functions
+def findNearbyPostalCodes(**kwargs):
+ method = 'findNearbyPostalCodesJSON'
+ valid_kwargs = ('postalcode', 'placename', 'maxRows', 'country', 'localCountry', 'lat', 'lng', 'radius', 'style',)
+ params = {}
+ for key in kwargs:
+ if key in valid_kwargs:
+ params[key] = kwargs[key]
+ results = fetchJson(method, params)
-def _buildfindNearbyPostalCodes(postalcode, placename, country, radius, maxRows ):
- placename=urllib.quote(placename)
- searchUrl = "http://ws.geonames.org/findNearbyPostalCodes?postalcode=%(postalcode)s&placename=%(placename)s&country=%(country)s&radius=%(radius)s&maxRows=%(maxRows)s" % vars()
- return searchUrl
-
-
-def _buildpostalCodeLookupJSON(postalcode,placename,country,maxRows,gcallback):
- placename=urllib.quote(placename)
- searchUrl = "http://ws.geonames.org/postalCodeLookupJSON?postalcode=%(postalcode)s&placename=%(placename)s&country=%(country)s&maxRows=%(maxRows)s&callback=%(gcallback)s" % vars()
- return searchUrl
-
-def _buildfindNearbyPostalCodesLL(lat,lng,radius,maxRows):
- searchUrl = "http://ws.geonames.org/findNearbyPostalCodes?lat=%(lat)s&lng=%(lng)s&radius=%(radius)s&maxRows=%(maxRows)s" % vars()
- return searchUrl
-
-def _buildfindNearbyPlaceName(lat,lng):
- searchUrl = "http://ws.geonames.org/findNearbyPlaceName?lat=%(lat)s&lng=%(lng)s" % vars()
- return searchUrl
-
-def _buildpostalCodeSearch(postalcode, placename, country, maxRows ):
- placename=urllib.quote(placename)
- searchUrl = "http://ws.geonames.org/postalCodeSearch?postalcode=%(postalcode)s&placename=%(placename)s&country=%(country)s&maxRows=%(maxRows)s" % vars()
- return searchUrl
-
-def _buildsearch(placename, country, maxRows,style,lang, fclass):
- placename=urllib.quote(placename)
- if fclass:
- urlfclass=''
- for fc in fclass:
- urlfclass+="&fclass="
- urlfclass+=urllib.quote(fc)
- searchUrl = "http://ws.geonames.org/search?q=%(placename)s&country=%(country)s&maxRows=%(maxRows)s&lang=%(lang)s&style=%(style)s%(urlfclass)s" % vars()
- return searchUrl
-
-def postalCodeSearch(postalcode, placename='', country=COUNTRY, maxRows='10', http_proxy=None):
- """
- http://ws.geonames.org/postalCodeSearch?postalcode=35580&maxRows=10&country=fr
- Url : ws.geonames.org/postalCodeSearch?
- Parameters : postalcode ,placename,maxRows,country
- <geonames>
- <totalResultsCount>7</totalResultsCount>
- -
- <code>
- <postalcode>35580</postalcode>
- <name>St Senoux</name>
- <countryCode>FR</countryCode>
- <lat>47.9</lat>
- <lng>-1.7833333</lng>
- </code>
- """
- url = _buildpostalCodeSearch(postalcode,placename,country,maxRows)
- if DEBUG: print url
- return _do(url,http_proxy).geonames
-
-def postalCodeLookupJSON(postalcode, placename='', country=COUNTRY, maxRows='10',gcallback='', http_proxy=None):
- """
- Webservice Type : REST /JSON
- Url : ws.geonames.org/postalCodeLookupJSON?
- Parameters : postalcode,country ,maxRows (default = 20),callback
- Result : returns a list of places for the given postalcode in JSON format
- """
- url = _buildpostalCodeLookupJSON(postalcode,placename,country,maxRows,gcallback)
-# print url
- proxies = getProxies(http_proxy)
- u = urllib.FancyURLopener(proxies)
- usock = u.open(url)
- rawdata = usock.read()
- if DEBUG: print rawdata
- usock.close()
- return eval(rawdata[:-3])
-
-def findNearbyPostalCodes(postalcode, placename='', country=COUNTRY, radius='5', maxRows='10',lat=None,lng=None, http_proxy=None):
- """
- Find nearby postal codes / reverse geocoding
- This service comes in two flavors. You can either pass the lat/long or a postalcode/placename.
-
- Webservice Type : REST
- Url : ws.geonames.org/findNearbyPostalCodes?
- Parameters :
- lat,lng, radius (in km), maxRows (default = 5),country (default = all countries)
- or
- postalcode,country, radius (in Km), maxRows (default = 5)
- Result : returns a list of postalcodes and places for the lat/lng query as xml document
- Example:
- http://ws.geonames.org/findNearbyPostalCodes?postalcode=35580&placename=guichen&country=FR&radius=5
- <geonames>
- -
- <code>
- <postalcode>35580</postalcode>
- <name>Guichen</name>
- <countryCode>FR</countryCode>
- <lat>47.9666667</lat>
- <lng>-1.8</lng>
- <distance>0.0</distance>
- </code>
- """
- if lat and lng :
- url = _buildfindNearbyPostalCodesLL(lat,lng,radius,maxRows)
+ if('postalCodes' in results):
+ return results['postalCodes']
else:
- url = _buildfindNearbyPostalCodes(postalcode,placename,country,radius,maxRows)
- if DEBUG: print url
-# import pdb;pdb.set_trace()
- return _do(url,http_proxy).geonames
-
-
-def postalCodeCountryInfo(http_proxy=None):
- """
- http://ws.geonames.org/postalCodeCountryInfo?
- <country>
- <countryCode>FR</countryCode>
- <countryName>France</countryName>
- <numPostalCodes>39163</numPostalCodes>
- <minPostalCode>01000</minPostalCode>
- <maxPostalCode>98000</maxPostalCode>
- </country>
-
- """
- return _do("http://ws.geonames.org/postalCodeCountryInfo?",http_proxy).geonames.country
-
-def search(placename='', country=COUNTRY, maxRows='10', style='SHORT',lang=LANG, fclass=None, http_proxy=None):
- """
- Url : ws.geonames.org/search?
- Parameters : q : place name (urlencoded utf8)
- maxRows : maximal number of rows returned (default = 100)
- country : iso country code, two characters (default = all countries)
- fclass : featureclass(es) (default= all feature classes); this parameter may occur more then once, example: fclass=P&fclass=A
- style : SHORT,MEDIUM,LONG (default = MEDIUM), verbosity of returned xml document
- lang : ISO 2-letter language code. (default = en), countryName will be returned in the specified language.
-
- http://ws.geonames.org/search?q=guichen&maxRows=10&style=SHORT&lang=fr&country=fr
- <geonames>
- <totalResultsCount>3</totalResultsCount>
- -
- <geoname>
- <name>Laillé</name>
- <lat>47.9833333</lat>
- <lng>-1.7166667</lng>
- </geoname>
- """
- url = _buildsearch(placename, country, maxRows,style,lang, fclass)
- if DEBUG: print url
- return _do(url,http_proxy).geonames
-
-def findNearbyPlaceName(lat,lng, http_proxy=None):
- """
- Webservice Type : REST
- Url : ws.geonames.org/findNearbyPlaceName?
- Parameters : lat,lng
- Result : returns the closest populated place for the lat/lng query as xml document
- Example:
- http://ws.geonames.org/findNearbyPlaceName?lat=47.3&lng=9
- """
- url = _buildfindNearbyPlaceName(lat,lng)
- if DEBUG: print url
- return _do(url,http_proxy).geonames
+ return None
+
+def hierarchy(geonameId, **kwargs):
+ method = 'hierarchyJSON'
+ valid_kwargs = ('lang')
+ params = {'geonameId': geonameId}
+ for key in kwargs:
+ if key in valid_kwargs:
+ params[key] = kwargs[key]
+ results = fetchJson(method, params)
+ if('geonames' in results):
+ return results['geonames']
+ else:
+ return None
Modified: comdev/nearby_people/local_settings.py.example
URL: http://svn.apache.org/viewvc/comdev/nearby_people/local_settings.py.example?rev=1559846&r1=1559845&r2=1559846&view=diff
==============================================================================
--- comdev/nearby_people/local_settings.py.example (original)
+++ comdev/nearby_people/local_settings.py.example Mon Jan 20 22:34:37 2014
@@ -17,6 +17,10 @@ PEOPLE_FOAF_PATH = os.path.join(BASE_PAT
GMAPS_KEY = "ABQIAAAAteF8gqn96L8K4RRZYtk7ZRQv7OBTi813IEDuwD3BusDViujKIBTUfK-gV5SL7dqLeRkgc0jLmyXgkg" # localhost
#GMAPS_KEY = "ABQIAAAAKzqK7s3QLJgbVNLowesmvBRZUAEs3HYX8hgK-I5Eho3zsmHV-RQBJhSLW6bIoahGVe1Ap9pWhcewGw" # apache.org
+# GeoNames settings
+# Note - you need your own username, register at http://www.geonames.org/login
+#GEONAMES_USERNAME = "ExampleUsername"
+
# Are we in testing or production?
DEBUG = True
TEMPLATE_DEBUG = DEBUG
Modified: comdev/nearby_people/nearby/views.py
URL: http://svn.apache.org/viewvc/comdev/nearby_people/nearby/views.py?rev=1559846&r1=1559845&r2=1559846&view=diff
==============================================================================
--- comdev/nearby_people/nearby/views.py (original)
+++ comdev/nearby_people/nearby/views.py Mon Jan 20 22:34:37 2014
@@ -16,13 +16,14 @@
# ====================================================================
from django.http import HttpResponseRedirect
-from settings import COMDEV_DOAP, SPEAKERS_DOAP, GMAPS_KEY
+from settings import COMDEV_DOAP, SPEAKERS_DOAP, GMAPS_KEY, GEONAMES_USERNAME
from nearby_people.nearby.foaf import *
from nearby_people.nearby.forms import *
from nearby_people.nearby.shortcuts import *
import geoname
+geoname.USERNAME = GEONAMES_USERNAME
#geoname.DEBUG=1
try:
@@ -49,21 +50,19 @@ def pick_place(request):
if request.POST:
form = PlaceForm(request.POST)
if form.is_valid():
- result = geoname.search(
- placename=form.data["place_name"],
- fclass=["P","T"],
- country='',
+ results = geoname.search(
+ name=form.data["place_name"],
+ featureClass=["P","T"],
lang="EN",
maxRows=10,
)
- if hasattr(result, "geoname"):
- for res in result.geoname:
- places.append({
- 'name':res.name,
- 'latitude':res.lat,
- 'longitude':res.lng,
- 'country':res.countryCode
- })
+ for res in results:
+ places.append({
+ 'name': res['name'],
+ 'latitude': res['lat'],
+ 'longitude': res['lng'],
+ 'country': res['countryCode']
+ })
else:
message = "We can't work out the location you mean, sorry. Please double check your spelling, or try searching for a nearby place which is larger."
else: