graticule 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +11 -0
- data/Manifest.txt +26 -11
- data/README.txt +1 -1
- data/bin/geocode +1 -1
- data/lib/graticule.rb +10 -8
- data/lib/graticule/cli.rb +1 -0
- data/lib/graticule/geocoder.rb +1 -12
- data/lib/graticule/geocoder/bogus.rb +15 -0
- data/lib/graticule/geocoder/geocoder_ca.rb +52 -0
- data/lib/graticule/geocoder/geocoder_us.rb +47 -0
- data/lib/graticule/geocoder/google.rb +106 -0
- data/lib/graticule/geocoder/host_ip.rb +50 -0
- data/lib/graticule/geocoder/local_search_maps.rb +45 -0
- data/lib/graticule/geocoder/meta_carta.rb +38 -0
- data/lib/graticule/geocoder/postcode_anywhere.rb +63 -0
- data/lib/graticule/geocoder/rest.rb +110 -0
- data/lib/graticule/geocoder/yahoo.rb +96 -0
- data/lib/graticule/location.rb +19 -7
- data/lib/graticule/version.rb +2 -2
- data/test/fixtures/responses/host_ip/private.txt +4 -0
- data/test/fixtures/responses/host_ip/success.txt +4 -0
- data/test/fixtures/responses/host_ip/unknown.txt +4 -0
- data/test/fixtures/responses/local_search_maps/success.txt +1 -0
- data/test/fixtures/responses/postcode_anywhere/badkey.xml +9 -0
- data/test/fixtures/responses/postcode_anywhere/canada.xml +16 -0
- data/test/fixtures/responses/postcode_anywhere/empty.xml +16 -0
- data/test/fixtures/responses/postcode_anywhere/success.xml +16 -0
- data/test/fixtures/responses/postcode_anywhere/uk.xml +18 -0
- data/test/test_helper.rb +4 -2
- data/test/unit/graticule/geocoder/geocoder_us_test.rb +43 -0
- data/test/unit/graticule/geocoder/google_test.rb +66 -0
- data/test/unit/graticule/geocoder/host_ip_test.rb +39 -0
- data/test/unit/graticule/geocoder/local_search_maps_test.rb +30 -0
- data/test/unit/graticule/geocoder/meta_carta_test.rb +44 -0
- data/test/unit/graticule/geocoder/postcode_anywhere_test.rb +50 -0
- data/test/unit/graticule/geocoder/yahoo_test.rb +48 -0
- data/test/unit/graticule/geocoder_test.rb +5 -9
- data/test/unit/graticule/location_test.rb +22 -7
- metadata +37 -18
- data/lib/graticule/geocoders/bogus.rb +0 -11
- data/lib/graticule/geocoders/geocoder_us.rb +0 -45
- data/lib/graticule/geocoders/google.rb +0 -99
- data/lib/graticule/geocoders/meta_carta.rb +0 -102
- data/lib/graticule/geocoders/rest.rb +0 -98
- data/lib/graticule/geocoders/yahoo.rb +0 -101
- data/test/unit/graticule/geocoders/geocoder_us_test.rb +0 -42
- data/test/unit/graticule/geocoders/geocoders.rb +0 -56
- data/test/unit/graticule/geocoders/google_test.rb +0 -22
- data/test/unit/graticule/geocoders/meta_carta_test.rb +0 -70
- data/test/unit/graticule/geocoders/yahoo_test.rb +0 -49
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.9.2
|
3
3
|
specification_version: 1
|
4
4
|
name: graticule
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2007-03-17 00:00:00 -04:00
|
8
8
|
summary: API for using all the popular geocoding services.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -25,6 +25,7 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
25
25
|
platform: ruby
|
26
26
|
signing_key:
|
27
27
|
cert_chain:
|
28
|
+
post_install_message:
|
28
29
|
authors:
|
29
30
|
- Brandon Keepers
|
30
31
|
files:
|
@@ -42,12 +43,16 @@ files:
|
|
42
43
|
- lib/graticule/distance/spherical.rb
|
43
44
|
- lib/graticule/distance/vincenty.rb
|
44
45
|
- lib/graticule/geocoder.rb
|
45
|
-
- lib/graticule/
|
46
|
-
- lib/graticule/
|
47
|
-
- lib/graticule/
|
48
|
-
- lib/graticule/
|
49
|
-
- lib/graticule/
|
50
|
-
- lib/graticule/
|
46
|
+
- lib/graticule/geocoder/bogus.rb
|
47
|
+
- lib/graticule/geocoder/geocoder_ca.rb
|
48
|
+
- lib/graticule/geocoder/geocoder_us.rb
|
49
|
+
- lib/graticule/geocoder/google.rb
|
50
|
+
- lib/graticule/geocoder/host_ip.rb
|
51
|
+
- lib/graticule/geocoder/local_search_maps.rb
|
52
|
+
- lib/graticule/geocoder/meta_carta.rb
|
53
|
+
- lib/graticule/geocoder/postcode_anywhere.rb
|
54
|
+
- lib/graticule/geocoder/rest.rb
|
55
|
+
- lib/graticule/geocoder/yahoo.rb
|
51
56
|
- lib/graticule/location.rb
|
52
57
|
- lib/graticule/version.rb
|
53
58
|
- test/fixtures/responses/geocoder_us/success.xml
|
@@ -59,29 +64,43 @@ files:
|
|
59
64
|
- test/fixtures/responses/google/success.xml
|
60
65
|
- test/fixtures/responses/google/unavailable.xml
|
61
66
|
- test/fixtures/responses/google/unknown_address.xml
|
67
|
+
- test/fixtures/responses/host_ip/private.txt
|
68
|
+
- test/fixtures/responses/host_ip/success.txt
|
69
|
+
- test/fixtures/responses/host_ip/unknown.txt
|
70
|
+
- test/fixtures/responses/local_search_maps/success.txt
|
62
71
|
- test/fixtures/responses/meta_carta/bad_address.xml
|
63
72
|
- test/fixtures/responses/meta_carta/multiple.xml
|
64
73
|
- test/fixtures/responses/meta_carta/success.xml
|
74
|
+
- test/fixtures/responses/postcode_anywhere/badkey.xml
|
75
|
+
- test/fixtures/responses/postcode_anywhere/canada.xml
|
76
|
+
- test/fixtures/responses/postcode_anywhere/empty.xml
|
77
|
+
- test/fixtures/responses/postcode_anywhere/success.xml
|
78
|
+
- test/fixtures/responses/postcode_anywhere/uk.xml
|
65
79
|
- test/fixtures/responses/yahoo/success.xml
|
66
80
|
- test/fixtures/responses/yahoo/unknown_address.xml
|
67
81
|
- test/mocks/uri.rb
|
68
82
|
- test/test_helper.rb
|
69
83
|
- test/unit/graticule/distance_test.rb
|
84
|
+
- test/unit/graticule/geocoder/geocoder_us_test.rb
|
85
|
+
- test/unit/graticule/geocoder/google_test.rb
|
86
|
+
- test/unit/graticule/geocoder/host_ip_test.rb
|
87
|
+
- test/unit/graticule/geocoder/local_search_maps_test.rb
|
88
|
+
- test/unit/graticule/geocoder/meta_carta_test.rb
|
89
|
+
- test/unit/graticule/geocoder/postcode_anywhere_test.rb
|
90
|
+
- test/unit/graticule/geocoder/yahoo_test.rb
|
70
91
|
- test/unit/graticule/geocoder_test.rb
|
71
|
-
- test/unit/graticule/geocoders/geocoder_us_test.rb
|
72
|
-
- test/unit/graticule/geocoders/geocoders.rb
|
73
|
-
- test/unit/graticule/geocoders/google_test.rb
|
74
|
-
- test/unit/graticule/geocoders/meta_carta_test.rb
|
75
|
-
- test/unit/graticule/geocoders/yahoo_test.rb
|
76
92
|
- test/unit/graticule/location_test.rb
|
77
93
|
test_files:
|
78
94
|
- test/unit/graticule/distance_test.rb
|
79
95
|
- test/unit/graticule/geocoder_test.rb
|
80
96
|
- test/unit/graticule/location_test.rb
|
81
|
-
- test/unit/graticule/
|
82
|
-
- test/unit/graticule/
|
83
|
-
- test/unit/graticule/
|
84
|
-
- test/unit/graticule/
|
97
|
+
- test/unit/graticule/geocoder/geocoder_us_test.rb
|
98
|
+
- test/unit/graticule/geocoder/google_test.rb
|
99
|
+
- test/unit/graticule/geocoder/host_ip_test.rb
|
100
|
+
- test/unit/graticule/geocoder/local_search_maps_test.rb
|
101
|
+
- test/unit/graticule/geocoder/meta_carta_test.rb
|
102
|
+
- test/unit/graticule/geocoder/postcode_anywhere_test.rb
|
103
|
+
- test/unit/graticule/geocoder/yahoo_test.rb
|
85
104
|
rdoc_options: []
|
86
105
|
|
87
106
|
extra_rdoc_files: []
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Graticule #:nodoc:
|
2
|
-
|
3
|
-
# A library for lookup up coordinates with geocoder.us' API.
|
4
|
-
#
|
5
|
-
# http://geocoder.us/help/
|
6
|
-
class GeocoderUsGeocoder < RestGeocoder
|
7
|
-
|
8
|
-
# Creates a new GeocoderUs object optionally using +username+ and
|
9
|
-
# +password+.
|
10
|
-
#
|
11
|
-
# You can sign up for a geocoder.us account here:
|
12
|
-
#
|
13
|
-
# http://geocoder.us/user/signup
|
14
|
-
def initialize(user = nil, password = nil)
|
15
|
-
if user and password then
|
16
|
-
@url = URI.parse 'http://geocoder.us/member/service/rest/geocode'
|
17
|
-
@url.user = user
|
18
|
-
@url.password = password
|
19
|
-
else
|
20
|
-
@url = URI.parse 'http://rpc.geocoder.us/service/rest/geocode'
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Locates +address+ and returns the address' latitude and longitude or
|
25
|
-
# raises an AddressError.
|
26
|
-
def locate(address)
|
27
|
-
get :address => address
|
28
|
-
end
|
29
|
-
|
30
|
-
def parse_response(xml) #:nodoc:
|
31
|
-
location = Location.new
|
32
|
-
location.street = xml.elements['rdf:RDF/geo:Point/dc:description'].text
|
33
|
-
|
34
|
-
location.latitude = xml.elements['rdf:RDF/geo:Point/geo:lat'].text.to_f
|
35
|
-
location.longitude = xml.elements['rdf:RDF/geo:Point/geo:long'].text.to_f
|
36
|
-
|
37
|
-
return location
|
38
|
-
end
|
39
|
-
|
40
|
-
def check_error(xml) #:nodoc:
|
41
|
-
raise AddressError, xml.text if xml.text == 'couldn\'t find this address! sorry'
|
42
|
-
end
|
43
|
-
|
44
|
-
end
|
45
|
-
end
|
@@ -1,99 +0,0 @@
|
|
1
|
-
|
2
|
-
module Graticule
|
3
|
-
|
4
|
-
# First you need a Google Maps API key. You can register for one here:
|
5
|
-
# http://www.google.com/apis/maps/signup.html
|
6
|
-
#
|
7
|
-
# Then you create a GoogleGeocode object and start locating addresses:
|
8
|
-
#
|
9
|
-
# require 'rubygems'
|
10
|
-
# require 'graticule'
|
11
|
-
#
|
12
|
-
# gg = Graticule.service(:google).new(:key => MAPS_API_KEY)
|
13
|
-
# location = gg.locate '1600 Amphitheater Pkwy, Mountain View, CA'
|
14
|
-
# p location.coordinates
|
15
|
-
#
|
16
|
-
class GoogleGeocoder < RestGeocoder
|
17
|
-
# http://www.google.com/apis/maps/documentation/#Geocoding_HTTP_Request
|
18
|
-
|
19
|
-
# http://www.google.com/apis/maps/documentation/reference.html#GGeoAddressAccuracy
|
20
|
-
PRECISION = {
|
21
|
-
0 => :unknown, # Unknown location. (Since 2.59)
|
22
|
-
1 => :country, # Country level accuracy. (Since 2.59)
|
23
|
-
2 => :state, # Region (state, province, prefecture, etc.) level accuracy. (Since 2.59)
|
24
|
-
3 => :state, # Sub-region (county, municipality, etc.) level accuracy. (Since 2.59)
|
25
|
-
4 => :city, # Town (city, village) level accuracy. (Since 2.59)
|
26
|
-
5 => :zip, # Post code (zip code) level accuracy. (Since 2.59)
|
27
|
-
6 => :street, # Street level accuracy. (Since 2.59)
|
28
|
-
7 => :street, # Intersection level accuracy. (Since 2.59)
|
29
|
-
8 => :address # Address level accuracy. (Since 2.59)
|
30
|
-
}
|
31
|
-
|
32
|
-
# Creates a new GoogleGeocode that will use Google Maps API key +key+. You
|
33
|
-
# can sign up for an API key here:
|
34
|
-
#
|
35
|
-
# http://www.google.com/apis/maps/signup.html
|
36
|
-
def initialize(key)
|
37
|
-
@key = key
|
38
|
-
@url = URI.parse 'http://maps.google.com/maps/geo'
|
39
|
-
end
|
40
|
-
|
41
|
-
# Locates +address+ returning a Location
|
42
|
-
def locate(address)
|
43
|
-
get :q => address
|
44
|
-
end
|
45
|
-
|
46
|
-
# Extracts a Location from +xml+.
|
47
|
-
def parse_response(xml) #:nodoc:
|
48
|
-
address = REXML::XPath.first(xml, '//xal:AddressDetails', 'xal' => "urn:oasis:names:tc:ciq:xsdschema:xAL:2.0")
|
49
|
-
|
50
|
-
longitude, latitude, = xml.elements['/kml/Response/Placemark/Point/coordinates'].text.split(',').map { |v| v.to_f }
|
51
|
-
|
52
|
-
Location.new \
|
53
|
-
:street => address.elements['Country/AdministrativeArea/SubAdministrativeArea/Locality/Thoroughfare/ThoroughfareName/text()'].value,
|
54
|
-
:city => address.elements['Country/AdministrativeArea/SubAdministrativeArea/Locality/LocalityName/text()'].value,
|
55
|
-
:state => address.elements['Country/AdministrativeArea/AdministrativeAreaName/text()'].value,
|
56
|
-
:zip => address.elements['Country/AdministrativeArea/SubAdministrativeArea/Locality/PostalCode/PostalCodeNumber/text()'].value,
|
57
|
-
:country => address.elements['Country/CountryNameCode/text()'].value,
|
58
|
-
:latitude => latitude,
|
59
|
-
:longitude => longitude,
|
60
|
-
:precision => PRECISION[address.attribute('Accuracy').value.to_i] || :unknown
|
61
|
-
end
|
62
|
-
|
63
|
-
# Extracts and raises an error from +xml+, if any.
|
64
|
-
def check_error(xml) #:nodoc:
|
65
|
-
status ||= xml.elements['/kml/Response/Status/code'].text.to_i
|
66
|
-
case status
|
67
|
-
when 200 then # ignore, ok
|
68
|
-
when 500 then
|
69
|
-
raise Error, 'server error'
|
70
|
-
when 601 then
|
71
|
-
raise AddressError, 'missing address'
|
72
|
-
when 602 then
|
73
|
-
raise AddressError, 'unknown address'
|
74
|
-
when 603 then
|
75
|
-
raise AddressError, 'unavailable address'
|
76
|
-
when 610 then
|
77
|
-
raise CredentialsError, 'invalid key'
|
78
|
-
when 620 then
|
79
|
-
raise CredentialsError, 'too many queries'
|
80
|
-
else
|
81
|
-
raise Error, "unknown error #{status}"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
# Creates a URL from the Hash +params+. Automatically adds the key and
|
86
|
-
# sets the output type to 'xml'.
|
87
|
-
def make_url(params) #:nodoc:
|
88
|
-
params[:key] = @key
|
89
|
-
params[:output] = 'xml'
|
90
|
-
|
91
|
-
super params
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
def text(element)
|
96
|
-
element.text if element
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
@@ -1,102 +0,0 @@
|
|
1
|
-
|
2
|
-
module Graticule
|
3
|
-
|
4
|
-
# Library for looking up coordinates with MetaCarta's GeoParser API.
|
5
|
-
#
|
6
|
-
# http://labs.metacarta.com/GeoParser/documentation.html
|
7
|
-
class MetaCartaGeocoder < RestGeocoder
|
8
|
-
Location = Struct.new :name, :type, :population, :hierarchy,
|
9
|
-
:latitude, :longitude, :confidence, :viewbox
|
10
|
-
|
11
|
-
def initialize # :nodoc:
|
12
|
-
@url = URI.parse 'http://labs.metacarta.com/GeoParser/'
|
13
|
-
end
|
14
|
-
|
15
|
-
# Locates +place+ and returns a Location object.
|
16
|
-
def locate(place)
|
17
|
-
locations, = get :q => place
|
18
|
-
return locations.first
|
19
|
-
end
|
20
|
-
|
21
|
-
# Retrieve all locations matching +place+.
|
22
|
-
#
|
23
|
-
# Returns an Array of Location objects and a pair of coordinates that will
|
24
|
-
# surround them.
|
25
|
-
def locations(place)
|
26
|
-
get :loc => place
|
27
|
-
end
|
28
|
-
|
29
|
-
def check_error(xml) # :nodoc:
|
30
|
-
raise AddressError, 'bad location' unless xml.elements['Locations/Location']
|
31
|
-
end
|
32
|
-
|
33
|
-
def make_url(params) # :nodoc:
|
34
|
-
params[:output] = 'locations'
|
35
|
-
|
36
|
-
super params
|
37
|
-
end
|
38
|
-
|
39
|
-
def parse_response(xml) # :nodoc:
|
40
|
-
locations = []
|
41
|
-
|
42
|
-
xml.elements['/Locations'].each do |l|
|
43
|
-
next if REXML::Text === l or l.name == 'ViewBox'
|
44
|
-
location = Location.new
|
45
|
-
|
46
|
-
location.viewbox = viewbox_coords l.elements['ViewBox/gml:Box/gml:coordinates']
|
47
|
-
|
48
|
-
location.name = l.attributes['Name']
|
49
|
-
location.type = l.attributes['Type']
|
50
|
-
population = l.attributes['Population'].to_i
|
51
|
-
location.population = population > 0 ? population : nil
|
52
|
-
location.hierarchy = l.attributes['Hierarchy']
|
53
|
-
|
54
|
-
coords = l.elements['Centroid/gml:Point/gml:coordinates'].text.split ','
|
55
|
-
location.latitude = coords.first.to_f
|
56
|
-
location.longitude = coords.last.to_f
|
57
|
-
|
58
|
-
confidence = l.elements['Confidence']
|
59
|
-
location.confidence = confidence.text.to_f if confidence
|
60
|
-
|
61
|
-
locations << location
|
62
|
-
end
|
63
|
-
|
64
|
-
query_viewbox = xml.elements['/Locations/ViewBox/gml:Box/gml:coordinates']
|
65
|
-
|
66
|
-
return locations, viewbox_coords(query_viewbox)
|
67
|
-
end
|
68
|
-
|
69
|
-
# Turns a element containing a pair of coordinates into a pair of coordinate
|
70
|
-
# Arrays.
|
71
|
-
def viewbox_coords(viewbox) # :nodoc:
|
72
|
-
return viewbox.text.split(' ').map do |coords|
|
73
|
-
coords.split(',').map { |c| c.to_f }
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
78
|
-
|
79
|
-
# A Location contains the following fields:
|
80
|
-
#
|
81
|
-
# +name+:: The name of this location
|
82
|
-
# +type+:: The type of this location (no clue what it means)
|
83
|
-
# +population+:: The number of people who live here or nil
|
84
|
-
# +hierarchy+:: The places above this place
|
85
|
-
# +latitude+:: Latitude of the location
|
86
|
-
# +longitude+:: Longitude of the location
|
87
|
-
# +confidence+:: Accuracy confidence (if any)
|
88
|
-
# +viewbox+:: Pair of coordinates forming a box around this place
|
89
|
-
#
|
90
|
-
# viewbox runs from lower left to upper right.
|
91
|
-
class MetaCartaGeocoder::Location
|
92
|
-
|
93
|
-
##
|
94
|
-
# The latitude and longitude for this location.
|
95
|
-
|
96
|
-
def coordinates
|
97
|
-
[latitude, longitude]
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
101
|
-
|
102
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
require 'open-uri'
|
2
|
-
require 'rexml/document'
|
3
|
-
|
4
|
-
module Graticule #:nodoc:
|
5
|
-
|
6
|
-
# Abstract class for implementing REST APIs.
|
7
|
-
#
|
8
|
-
# === Example
|
9
|
-
#
|
10
|
-
# The following methods must be implemented in sublcasses:
|
11
|
-
#
|
12
|
-
# +initialize+:: Sets @url to the service enpoint.
|
13
|
-
# +check_error+:: Checks for errors in the server response.
|
14
|
-
# +parse_response+:: Extracts information from the server response.
|
15
|
-
#
|
16
|
-
# If you have extra URL paramaters (application id, output type) or need to
|
17
|
-
# perform URL customization, override +make_url+.
|
18
|
-
#
|
19
|
-
# class FakeService < RCRest
|
20
|
-
#
|
21
|
-
# class Error < RCRest::Error; end
|
22
|
-
#
|
23
|
-
# def initialize(appid)
|
24
|
-
# @appid = appid
|
25
|
-
# @url = URI.parse 'http://example.com/test'
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
# def check_error(xml)
|
29
|
-
# raise Error, xml.elements['error'].text if xml.elements['error']
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# def make_url(params)
|
33
|
-
# params[:appid] = @appid
|
34
|
-
# super params
|
35
|
-
# end
|
36
|
-
#
|
37
|
-
# def parse_response(xml)
|
38
|
-
# return xml
|
39
|
-
# end
|
40
|
-
#
|
41
|
-
# def test(query)
|
42
|
-
# get :q => query
|
43
|
-
# end
|
44
|
-
#
|
45
|
-
# end
|
46
|
-
class RestGeocoder < Geocoder
|
47
|
-
|
48
|
-
# Web services initializer.
|
49
|
-
#
|
50
|
-
# Concrete web services implementations must set the +url+ instance
|
51
|
-
# variable which must be a URI.
|
52
|
-
def initialize
|
53
|
-
raise NotImplementedError
|
54
|
-
end
|
55
|
-
|
56
|
-
# Must extract and raise an error from +xml+, an REXML::Document, if any.
|
57
|
-
# Must returns if no error could be found.
|
58
|
-
def check_error(xml)
|
59
|
-
raise NotImplementedError
|
60
|
-
end
|
61
|
-
|
62
|
-
# Performs a GET request with +params+. Calls the parse_response method on
|
63
|
-
# the concrete class with an REXML::Document instance and returns its
|
64
|
-
# result.
|
65
|
-
def get(params = {})
|
66
|
-
url = make_url params
|
67
|
-
|
68
|
-
url.open do |response|
|
69
|
-
res = REXML::Document.new response.read
|
70
|
-
check_error(res)
|
71
|
-
return parse_response(res)
|
72
|
-
end
|
73
|
-
rescue OpenURI::HTTPError => e
|
74
|
-
response = REXML::Document.new e.io.read
|
75
|
-
check_error response
|
76
|
-
raise
|
77
|
-
end
|
78
|
-
|
79
|
-
# Creates a URI from the Hash +params+. Override this then call super if
|
80
|
-
# you need to add extra params like an application id or output type.
|
81
|
-
def make_url(params)
|
82
|
-
escaped_params = params.sort_by { |k,v| k.to_s }.map do |k,v|
|
83
|
-
"#{URI.escape k.to_s}=#{URI.escape v.to_s}"
|
84
|
-
end
|
85
|
-
|
86
|
-
url = @url.dup
|
87
|
-
url.query = escaped_params.join '&'
|
88
|
-
return url
|
89
|
-
end
|
90
|
-
|
91
|
-
# Must parse results from +xml+, an REXML::Document, into something sensible
|
92
|
-
# for the API.
|
93
|
-
def parse_response(xml)
|
94
|
-
raise NotImplementedError
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
98
|
-
end
|