<s> '''<STR_LIT>''' <EOL> import base64 <EOL> import hashlib <EOL> import hmac <EOL> from urllib import urlencode <EOL> from urllib2 import urlopen <EOL> try : <EOL> import json <EOL> except ImportError : <EOL> try : <EOL> import simplejson as json <EOL> except ImportError : <EOL> import gluon . contrib . simplejson as json <EOL> from base import Geocoder , GeocoderResultError <EOL> from . . import util <EOL> class GoogleV3 ( Geocoder ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , domain = '<STR_LIT>' , protocol = '<STR_LIT:http>' , <EOL> client_id = None , secret_key = None ) : <EOL> '''<STR_LIT>''' <EOL> super ( GoogleV3 , self ) . __init__ ( ) <EOL> if protocol not in ( '<STR_LIT:http>' , '<STR_LIT>' ) : <EOL> raise ValueError , '<STR_LIT>' <EOL> if client_id and not secret_key : <EOL> raise ValueError , '<STR_LIT>' <EOL> if secret_key and not client_id : <EOL> raise ValueError , '<STR_LIT>' <EOL> self . domain = domain . strip ( '<STR_LIT:/>' ) <EOL> self . protocol = protocol <EOL> self . doc = { } <EOL> if client_id and secret_key : <EOL> self . client_id = client_id <EOL> self . secret_key = secret_key <EOL> self . premier = True <EOL> else : <EOL> self . premier = False <EOL> def get_signed_url ( self , params ) : <EOL> '''<STR_LIT>''' <EOL> params [ '<STR_LIT>' ] = self . client_id <EOL> url_params = { '<STR_LIT>' : self . protocol , '<STR_LIT>' : self . domain , <EOL> '<STR_LIT>' : urlencode ( params ) } <EOL> secret = base64 . urlsafe_b64decode ( self . secret_key ) <EOL> url_params [ '<STR_LIT>' ] = ( <EOL> '<STR_LIT>' % url_params ) <EOL> signature = hmac . new ( secret , url_params [ '<STR_LIT>' ] , hashlib . sha1 ) <EOL> url_params [ '<STR_LIT>' ] = base64 . urlsafe_b64encode ( signature . digest ( ) ) <EOL> return ( '<STR_LIT>' <EOL> '<STR_LIT>' % url_params ) <EOL> def get_url ( self , params ) : <EOL> '''<STR_LIT>''' <EOL> return '<STR_LIT>' % ( <EOL> { '<STR_LIT>' : self . domain , '<STR_LIT>' : urlencode ( params ) } ) <EOL> def geocode_url ( self , url , exactly_one = True ) : <EOL> '''<STR_LIT>''' <EOL> util . logger . debug ( "<STR_LIT>" % url ) <EOL> page = urlopen ( url ) <EOL> return self . parse_json ( page , exactly_one ) <EOL> def geocode ( self , string , bounds = None , region = None , <EOL> language = None , sensor = False , exactly_one = True ) : <EOL> '''<STR_LIT>''' <EOL> if isinstance ( string , unicode ) : <EOL> string = string . encode ( '<STR_LIT:utf-8>' ) <EOL> params = { <EOL> '<STR_LIT:address>' : self . format_string % string , <EOL> '<STR_LIT>' : str ( sensor ) . lower ( ) <EOL> } <EOL> if bounds : <EOL> params [ '<STR_LIT>' ] = bounds <EOL> if region : <EOL> params [ '<STR_LIT>' ] = region <EOL> if language : <EOL> params [ '<STR_LIT>' ] = language <EOL> if not self . premier : <EOL> url = self . get_url ( params ) <EOL> else : <EOL> url = self . get_signed_url ( params ) <EOL> return self . geocode_url ( url , exactly_one ) <EOL> def reverse ( self , point , language = None , sensor = False , exactly_one = False ) : <EOL> '''<STR_LIT>''' <EOL> params = { <EOL> '<STR_LIT>' : point , <EOL> '<STR_LIT>' : str ( sensor ) . lower ( ) <EOL> } <EOL> if language : <EOL> params [ '<STR_LIT>' ] = language <EOL> if not self . premier : <EOL> url = self . get_url ( params ) <EOL> else : <EOL> url = self . get_signed_url ( params ) <EOL> return self . geocode_url ( url , exactly_one ) <EOL> def parse_json ( self , page , exactly_one = True ) : <EOL> '''<STR_LIT>''' <EOL> if not isinstance ( page , basestring ) : <EOL> page = util . decode_page ( page ) <EOL> self . doc = json . loads ( page ) <EOL> places = self . doc . get ( '<STR_LIT>' , [ ] ) <EOL> if not places : <EOL> check_status ( self . doc . get ( '<STR_LIT:status>' ) ) <EOL> return None <EOL> elif exactly_one and len ( places ) != <NUM_LIT:1> : <EOL> raise ValueError ( <EOL> "<STR_LIT>" % len ( places ) ) <EOL> def parse_place ( place ) : <EOL> '''<STR_LIT>''' <EOL> location = place . get ( '<STR_LIT>' ) <EOL> latitude = place [ '<STR_LIT>' ] [ '<STR_LIT:location>' ] [ '<STR_LIT>' ] <EOL> longitude = place [ '<STR_LIT>' ] [ '<STR_LIT:location>' ] [ '<STR_LIT>' ] <EOL> return ( location , ( latitude , longitude ) ) <EOL> if exactly_one : <EOL> return parse_place ( places [ <NUM_LIT:0> ] ) <EOL> else : <EOL> return [ parse_place ( place ) for place in places ] <EOL> def check_status ( status ) : <EOL> '''<STR_LIT>''' <EOL> if status == '<STR_LIT>' : <EOL> raise GQueryError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> elif status == '<STR_LIT>' : <EOL> raise GTooManyQueriesError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> elif status == '<STR_LIT>' : <EOL> raise GQueryError ( <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> elif status == '<STR_LIT>' : <EOL> raise GQueryError ( '<STR_LIT>' ) <EOL> else : <EOL> raise GeocoderResultError ( '<STR_LIT>' ) <EOL> class GQueryError ( GeocoderResultError ) : <EOL> '''<STR_LIT>''' <EOL> pass <EOL> class GTooManyQueriesError ( GeocoderResultError ) : <EOL> '''<STR_LIT>''' <EOL> pass </s>
