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: