gowalla 0.1.4 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/gowalla.rb +6 -1
- data/lib/gowalla/client.rb +153 -94
- data/test/gowalla_test.rb +168 -0
- data/test/helper.rb +0 -3
- metadata +52 -102
- data/.document +0 -5
- data/.gitignore +0 -21
- data/LICENSE +0 -20
- data/README.md +0 -59
- data/Rakefile +0 -58
- data/VERSION +0 -1
- data/changelog.md +0 -19
- data/gowalla.gemspec +0 -98
- data/test/fixtures/categories.json +0 -1826
- data/test/fixtures/category.json +0 -8
- data/test/fixtures/challenges.json +0 -191
- data/test/fixtures/checkin.json +0 -67
- data/test/fixtures/events.json +0 -185
- data/test/fixtures/find_spots.json +0 -620
- data/test/fixtures/find_trips.json +0 -695
- data/test/fixtures/friend_requests.json +0 -21
- data/test/fixtures/friends.json +0 -3
- data/test/fixtures/friends_recent.json +0 -243
- data/test/fixtures/item.json +0 -8
- data/test/fixtures/items.json +0 -100
- data/test/fixtures/me.json +0 -49
- data/test/fixtures/missing_items.json +0 -1
- data/test/fixtures/new_spot.json +0 -49
- data/test/fixtures/pins.json +0 -36
- data/test/fixtures/potential_twitter_friends.json +0 -2090
- data/test/fixtures/spot.json +0 -251
- data/test/fixtures/spots.json +0 -557
- data/test/fixtures/spots_by_category.json +0 -620
- data/test/fixtures/stamps.json +0 -284
- data/test/fixtures/top_spots.json +0 -64
- data/test/fixtures/trip.json +0 -22
- data/test/fixtures/trips.json +0 -881
- data/test/fixtures/user.json +0 -43
- data/test/fixtures/vaulted_items.json +0 -12
- data/test/fixtures/visited_spots.json +0 -1
- data/test/test_gowalla.rb +0 -305
data/lib/gowalla.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'hashie'
|
2
|
-
require '
|
2
|
+
require 'faraday'
|
3
|
+
require 'multi_json'
|
4
|
+
require 'oauth2'
|
3
5
|
|
4
6
|
directory = File.expand_path(File.dirname(__FILE__))
|
5
7
|
|
@@ -7,6 +9,8 @@ Hash.send :include, Hashie::HashExtensions
|
|
7
9
|
|
8
10
|
module Gowalla
|
9
11
|
|
12
|
+
VERSION = "0.2.0".freeze
|
13
|
+
|
10
14
|
# config/initializers/gowalla.rb (for instance)
|
11
15
|
#
|
12
16
|
# Gowalla.configure do |config|
|
@@ -27,6 +31,7 @@ module Gowalla
|
|
27
31
|
attr_accessor :api_key
|
28
32
|
attr_accessor :username
|
29
33
|
attr_accessor :password
|
34
|
+
attr_accessor :api_secret
|
30
35
|
end
|
31
36
|
|
32
37
|
end
|
data/lib/gowalla/client.rb
CHANGED
@@ -1,134 +1,181 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
1
3
|
module Gowalla
|
2
|
-
|
3
4
|
class Client
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
headers({'Accept' => 'application/json', "User-Agent" => 'Ruby gem'})
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
attr_reader :username, :api_key, :api_secret
|
8
8
|
|
9
|
-
|
9
|
+
def_delegators :oauth_client, :web_server, :authorize_url, :access_token_url
|
10
10
|
|
11
11
|
def initialize(options={})
|
12
|
-
api_key = options[:api_key] || Gowalla.api_key
|
12
|
+
@api_key = options[:api_key] || Gowalla.api_key
|
13
|
+
@api_secret = options[:api_secret] || Gowalla.api_secret
|
13
14
|
@username = options[:username] || Gowalla.username
|
15
|
+
@access_token = options[:access_token]
|
14
16
|
password = options[:password] || Gowalla.password
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
def friend_requests(user_id=self.username)
|
32
|
-
mashup(self.class.get("/users/#{user_id}/friend_requests")).friends_needing_approval
|
33
|
-
end
|
34
|
-
|
35
|
-
def friends(user_id=self.username)
|
36
|
-
mashup(self.class.get("/users/#{user_id}/friends")).friends
|
37
|
-
end
|
38
|
-
|
39
|
-
def items(user_id=self.username)
|
40
|
-
mashup(self.class.get("/users/#{user_id}/items")).items
|
41
|
-
end
|
42
|
-
|
43
|
-
def missing_items(user_id=self.username)
|
44
|
-
mashup(self.class.get("/users/#{user_id}/items/missing")).items
|
45
|
-
end
|
46
|
-
|
47
|
-
def vaulted_items(user_id=self.username)
|
48
|
-
mashup(self.class.get("/users/#{user_id}/items/vault")).items
|
49
|
-
end
|
50
|
-
|
17
|
+
connection.basic_auth(@username, password) unless @api_secret
|
18
|
+
end
|
19
|
+
|
20
|
+
# Retrieve information about a specific user
|
21
|
+
#
|
22
|
+
# @param [String] user_id (authenticated basic auth user) User ID (screen name)
|
23
|
+
# @return [Hashie::Mash] User info
|
24
|
+
def user(user_id=nil)
|
25
|
+
user_id ||= username
|
26
|
+
handle_response(connection.get("/users/#{user_id}"))
|
27
|
+
end
|
28
|
+
|
29
|
+
# Retrieve information about a specific item
|
30
|
+
#
|
31
|
+
# @param [Integer] id Item ID
|
32
|
+
# @return [Hashie::Mash] item info
|
51
33
|
def item(id)
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
34
|
+
handle_response(connection.get("/items/#{id}"))
|
35
|
+
end
|
36
|
+
|
37
|
+
# Retrieve a list of the stamps the user has collected
|
38
|
+
#
|
39
|
+
# @param [String] user_id (authenticated basic auth user) User ID (screen name)
|
40
|
+
# @param [Integer] limit (20) limit per page
|
41
|
+
# @return [Hashie::Mash] stamps info
|
59
42
|
def stamps(user_id=self.username, limit=20)
|
60
|
-
|
43
|
+
response = connection.get do |req|
|
44
|
+
req.url "/users/#{user_id}/stamps", :limit => limit
|
45
|
+
end
|
46
|
+
handle_response(response).stamps
|
61
47
|
end
|
62
|
-
|
48
|
+
|
49
|
+
# Retrieve a list of spots the user has visited most often
|
50
|
+
#
|
51
|
+
# @param [String] user_id (authenticated basic auth user) User ID (screen name)
|
52
|
+
# @return [Hashie::Mash] item info
|
63
53
|
def top_spots(user_id=self.username)
|
64
|
-
|
54
|
+
handle_response(connection.get("/users/#{user_id}/top_spots")).top_spots
|
65
55
|
end
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
56
|
+
|
57
|
+
# Retrieve information about a specific trip
|
58
|
+
#
|
59
|
+
# @param [Integer] trip_id Trip ID
|
60
|
+
# @return [Hashie::Mash] trip info
|
71
61
|
def trip(trip_id)
|
72
|
-
|
62
|
+
handle_response(connection.get("/trips/#{trip_id}"))
|
73
63
|
end
|
74
64
|
|
65
|
+
# Retrieve information about a specific spot
|
66
|
+
#
|
67
|
+
# @param [Integer] spot_id Spot ID
|
68
|
+
# @return [Hashie::Mash] Spot info
|
75
69
|
def spot(spot_id)
|
76
|
-
|
70
|
+
handle_response(connection.get("/spots/#{spot_id}"))
|
77
71
|
end
|
78
72
|
|
73
|
+
# Retrieve a list of check-ins at a particular spot. Shows only the activity that is visible to a given user.
|
74
|
+
#
|
75
|
+
# @param [Integer] spot_id Spot ID
|
76
|
+
# @return [Hashie::Mash] Spot info
|
79
77
|
def spot_events(spot_id)
|
80
|
-
|
78
|
+
handle_response(connection.get("/spots/#{spot_id}/events")).activity
|
81
79
|
end
|
82
80
|
|
81
|
+
# Retrieve a list of items available at a particular spot
|
82
|
+
#
|
83
|
+
# @param [Integer] spot_id Spot ID
|
84
|
+
# @return [Hashie::Mash] Spot info
|
83
85
|
def spot_items(spot_id)
|
84
|
-
|
86
|
+
handle_response(connection.get("/spots/#{spot_id}/items")).items
|
85
87
|
end
|
86
88
|
|
89
|
+
# Retrieve a list of spots within a specified distance of a location
|
90
|
+
#
|
91
|
+
# @option options [Float] :latitude Latitude of search location
|
92
|
+
# @option options [Float] :longitude Longitude of search location
|
93
|
+
# @option options [Integer] :radius Search radius (in meters)
|
94
|
+
# @return [Hashie::Mash] spots info
|
87
95
|
def list_spots(options={})
|
88
96
|
query = format_geo_options(options)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
list_spots(options.merge(:featured => 1))
|
94
|
-
end
|
95
|
-
|
96
|
-
def bookmarked_spots(options={})
|
97
|
-
list_spots(options.merge(:bookmarked => 1))
|
97
|
+
response = connection.get do |req|
|
98
|
+
req.url "/spots", query
|
99
|
+
end
|
100
|
+
handle_response(response).spots
|
98
101
|
end
|
99
102
|
|
103
|
+
# List of trips
|
104
|
+
#
|
105
|
+
# @return [<Hashie::Mash>] trip info
|
100
106
|
def trips(options={})
|
101
107
|
if user_id = options.delete(:user_id)
|
102
108
|
options[:user_url] = "/users/#{user_id}"
|
103
109
|
end
|
104
110
|
query = format_geo_options(options)
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
trips(options.merge(:context => 'featured'))
|
110
|
-
end
|
111
|
-
|
112
|
-
def friends_trips(options={})
|
113
|
-
trips(options.merge(:context => 'friends'))
|
111
|
+
response = connection.get do |req|
|
112
|
+
req.url "/trips", query
|
113
|
+
end
|
114
|
+
handle_response(response).trips
|
114
115
|
end
|
115
|
-
|
116
|
+
|
117
|
+
# Lists all spot categories
|
118
|
+
#
|
119
|
+
# @return [<Hashie::Mash>] category info
|
116
120
|
def categories
|
117
|
-
|
121
|
+
handle_response(connection.get("/categories")).spot_categories
|
118
122
|
end
|
119
123
|
|
124
|
+
# Retrieve information about a specific category
|
125
|
+
#
|
126
|
+
# @param [Integer] id Category ID
|
127
|
+
# @return [Hashie::Mash] category info
|
120
128
|
def category(id)
|
121
|
-
|
129
|
+
handle_response(connection.get("/categories/#{id}"))
|
122
130
|
end
|
123
131
|
|
124
|
-
|
125
|
-
|
132
|
+
# Check for missing access token
|
133
|
+
#
|
134
|
+
# @return [Boolean] whether or not to redirect to get an access token
|
135
|
+
def needs_access?
|
136
|
+
@api_secret and @access_token.to_s == ''
|
137
|
+
end
|
138
|
+
|
139
|
+
# Raw HTTP connection, either Faraday::Connection or OAuth2::AccessToken
|
140
|
+
#
|
141
|
+
# @return [OAuth2::Client]
|
142
|
+
def connection
|
126
143
|
|
127
|
-
|
144
|
+
if api_secret
|
145
|
+
@connection ||= OAuth2::AccessToken.new(oauth_client, @access_token)
|
146
|
+
else
|
147
|
+
headers = default_headers
|
148
|
+
headers['X-Gowalla-API-Key'] = api_key if api_key
|
149
|
+
@connection ||= Faraday::Connection.new \
|
150
|
+
:url => "http://api.gowalla.com",
|
151
|
+
:headers => headers
|
152
|
+
end
|
128
153
|
end
|
129
154
|
|
155
|
+
# Provides raw access to the OAuth2 Client
|
156
|
+
#
|
157
|
+
# @return [OAuth2::Client]
|
158
|
+
def oauth_client
|
159
|
+
if @oauth_client
|
160
|
+
@oauth_client
|
161
|
+
else
|
162
|
+
conn ||= Faraday::Connection.new \
|
163
|
+
:url => "https://api.gowalla.com",
|
164
|
+
:headers => default_headers
|
165
|
+
|
166
|
+
oauth= OAuth2::Client.new(api_key, api_secret, oauth_options = {
|
167
|
+
:site => 'https://api.gowalla.com',
|
168
|
+
:authorize_url => 'https://gowalla.com/api/oauth/new',
|
169
|
+
:access_token_url => 'https://gowalla.com/api/oauth/token'
|
170
|
+
})
|
171
|
+
oauth.connection = conn
|
172
|
+
oauth
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
130
176
|
private
|
131
177
|
|
178
|
+
# @private
|
132
179
|
def format_geo_options(options={})
|
133
180
|
options[:lat] = "+#{options[:lat]}" if options[:lat].to_i > 0
|
134
181
|
options[:lng] = "+#{options[:lng]}" if options[:lng].to_i > 0
|
@@ -137,21 +184,33 @@ module Gowalla
|
|
137
184
|
end
|
138
185
|
options
|
139
186
|
end
|
140
|
-
|
141
|
-
|
142
|
-
|
187
|
+
|
188
|
+
# @private
|
189
|
+
def default_headers
|
190
|
+
headers = {
|
191
|
+
:accept => 'application/json',
|
192
|
+
:user_agent => 'Ruby gem'
|
193
|
+
}
|
194
|
+
end
|
195
|
+
|
196
|
+
# @private
|
197
|
+
def handle_response(response)
|
198
|
+
case response.status
|
143
199
|
when 200
|
144
|
-
|
145
|
-
|
200
|
+
body = response.respond_to?(:body) ? response.body : response
|
201
|
+
data = MultiJson.decode(body)
|
202
|
+
if data.is_a?(Hash)
|
203
|
+
Hashie::Mash.new(data)
|
146
204
|
else
|
147
|
-
if
|
148
|
-
|
205
|
+
if data.first.is_a?(Hash)
|
206
|
+
data.map{|item| Hashie::Mash.new(item)}
|
149
207
|
else
|
150
|
-
|
208
|
+
data
|
151
209
|
end
|
152
210
|
end
|
153
211
|
end
|
154
212
|
end
|
213
|
+
|
155
214
|
|
156
215
|
end
|
157
216
|
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class GowallaTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "When using the Gowalla API" do
|
6
|
+
setup do
|
7
|
+
@client = Gowalla::Client.new(:username => 'pengwynn', :password => '0U812', :api_key => 'gowallawallabingbang')
|
8
|
+
end
|
9
|
+
|
10
|
+
context "and working with Spots" do
|
11
|
+
should "Retrieve a list of spots within a specified distance of a location" do
|
12
|
+
stub_get("http://pengwynn:0U812@api.gowalla.com/spots?lat=%2B33.237593417&lng=-96.960559033&radius=50", "spots.json")
|
13
|
+
spots = @client.list_spots(:lat => 33.237593417, :lng => -96.960559033, :radius => 50)
|
14
|
+
spots.first.name.should == 'Gnomb Bar'
|
15
|
+
spots.first.radius_meters.should == 50
|
16
|
+
end
|
17
|
+
|
18
|
+
should "Retrieve a list of spots within a specified bounds" do
|
19
|
+
stub_get("http://pengwynn:0U812@api.gowalla.com/spots?sw=%2839.25565142103586%2C%20-8.717308044433594%29&nw=%2839.31411296530539%2C%20-8.490715026855469%29", "spots.json")
|
20
|
+
spots = @client.list_spots(:sw => "(39.25565142103586, -8.717308044433594)", :nw => "(39.31411296530539, -8.490715026855469)")
|
21
|
+
spots.first.name.should == 'Gnomb Bar'
|
22
|
+
end
|
23
|
+
|
24
|
+
should "Retrieve information about a specific spot" do
|
25
|
+
stub_get('http://pengwynn:0U812@api.gowalla.com/spots/18568', 'spot.json')
|
26
|
+
spot = @client.spot(18568)
|
27
|
+
spot.name.should == "Wahoo's"
|
28
|
+
spot.twitter_username.should == 'Wahoos512'
|
29
|
+
spot.spot_categories.first.name.should == 'Mexican'
|
30
|
+
end
|
31
|
+
|
32
|
+
should "retrieve a list of check-ins at a particular spot. Shows only the activity that is visible to a given user" do
|
33
|
+
stub_get('http://pengwynn:0U812@api.gowalla.com/spots/452593/events', 'events.json')
|
34
|
+
events = @client.spot_events(452593)
|
35
|
+
events.first[:type].should == 'checkin'
|
36
|
+
events.first.user.last_name.should == 'Mack'
|
37
|
+
end
|
38
|
+
|
39
|
+
should "retrieve a list of items available at a particular spot" do
|
40
|
+
stub_get('http://pengwynn:0U812@api.gowalla.com/spots/18568/items', 'items.json')
|
41
|
+
items = @client.spot_items(18568)
|
42
|
+
items.first.issue_number.should == 27868
|
43
|
+
items.first.name.should == 'Bowl of Noodles'
|
44
|
+
end
|
45
|
+
|
46
|
+
should "lists all spot categories" do
|
47
|
+
stub_get("http://pengwynn:0U812@api.gowalla.com/categories", "categories.json")
|
48
|
+
categories = @client.categories
|
49
|
+
categories.size.should == 9
|
50
|
+
categories.first.name.should == 'Architecture & Buildings'
|
51
|
+
categories.first.description.should == 'Bridge, Corporate, Home, Church, etc.'
|
52
|
+
categories.first.spot_categories.size.should == 15
|
53
|
+
categories.first.spot_categories.first.name.should == 'Bridge'
|
54
|
+
end
|
55
|
+
|
56
|
+
should "retrieve information about a specific category" do
|
57
|
+
stub_get("http://pengwynn:0U812@api.gowalla.com/categories/1", "category.json")
|
58
|
+
category = @client.category(1)
|
59
|
+
category.name.should == 'Coffee Shop'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "and working with Users" do
|
64
|
+
|
65
|
+
should "retrieve information about a specific user" do
|
66
|
+
stub_get('http://pengwynn:0U812@api.gowalla.com/users/sco', 'user.json')
|
67
|
+
user = @client.user('sco')
|
68
|
+
user.bio.should == "CTO & co-founder of Gowalla. Ruby/Cocoa/JavaScript developer. Game designer. Author. Indoorsman."
|
69
|
+
user.stamps_count.should == 506
|
70
|
+
end
|
71
|
+
|
72
|
+
should "retrieve a list of the stamps the user has collected" do
|
73
|
+
stub_get('http://pengwynn:0U812@api.gowalla.com/users/1707/stamps?limit=20', 'stamps.json')
|
74
|
+
stamps = @client.stamps(1707)
|
75
|
+
stamps.size.should == 20
|
76
|
+
stamps.first.spot.name.should == "Muck-N-Dave's Texas BBQ"
|
77
|
+
stamps.first.spot.address.locality.should == 'Austin'
|
78
|
+
end
|
79
|
+
|
80
|
+
should "retrieve a list of spots the user has visited most often" do
|
81
|
+
stub_get('http://pengwynn:0U812@api.gowalla.com/users/1707/top_spots', 'top_spots.json')
|
82
|
+
top_spots = @client.top_spots(1707)
|
83
|
+
top_spots.size.should == 10
|
84
|
+
top_spots.first.name.should == 'Juan Pelota Cafe'
|
85
|
+
top_spots.first.user_checkins_count.should == 30
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
context "and working with Items" do
|
91
|
+
should "retrieve information about a specific item" do
|
92
|
+
stub_get('http://pengwynn:0U812@api.gowalla.com/items/607583', 'item.json')
|
93
|
+
item = @client.item(607583)
|
94
|
+
item.issue_number.should == 13998
|
95
|
+
item.name.should == 'Sweets'
|
96
|
+
item.determiner.should == 'some'
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "and working with Trips" do
|
101
|
+
should "retrieve a list of trips" do
|
102
|
+
stub_get('http://pengwynn:0U812@api.gowalla.com/trips', 'trips.json')
|
103
|
+
trips = @client.trips
|
104
|
+
trips.first.name.should == 'London Pub Crawl'
|
105
|
+
trips.first.spots.first.url.should == '/spots/164009'
|
106
|
+
end
|
107
|
+
|
108
|
+
should "retrieve information about a specific trip" do
|
109
|
+
stub_get('http://pengwynn:0U812@api.gowalla.com/trips/1', 'trip.json')
|
110
|
+
trip = @client.trip(1)
|
111
|
+
trip.creator.last_name.should == 'Gowalla'
|
112
|
+
trip.map_bounds.east.should == -63.457031
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when using basic auth" do
|
119
|
+
should "configure api_key, username, and password for easy access" do
|
120
|
+
|
121
|
+
Gowalla.configure do |config|
|
122
|
+
config.api_key = 'api_key'
|
123
|
+
config.api_secret = nil
|
124
|
+
config.username = 'username'
|
125
|
+
config.password = 'password'
|
126
|
+
end
|
127
|
+
|
128
|
+
@client = Gowalla::Client.new
|
129
|
+
|
130
|
+
stub_get('http://username:password@api.gowalla.com/trips', 'trips.json')
|
131
|
+
trips = @client.trips
|
132
|
+
|
133
|
+
@client.username.should == 'username'
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "when using OAuth2" do
|
138
|
+
|
139
|
+
setup do
|
140
|
+
Gowalla.configure do |config|
|
141
|
+
config.api_key = 'api_key'
|
142
|
+
config.api_secret = 'api_secret'
|
143
|
+
end
|
144
|
+
|
145
|
+
@client = Gowalla::Client.new
|
146
|
+
end
|
147
|
+
|
148
|
+
should "confiure api_key, api_secret" do
|
149
|
+
@client.api_secret.should == 'api_secret'
|
150
|
+
@client.oauth_client.id.should == 'api_key'
|
151
|
+
end
|
152
|
+
|
153
|
+
should "create an OAuth2 client" do
|
154
|
+
@client.oauth_client.class.to_s.should == "OAuth2::Client"
|
155
|
+
end
|
156
|
+
|
157
|
+
should "create an OAuth2 connection" do
|
158
|
+
@client.connection.class.to_s.should == "OAuth2::AccessToken"
|
159
|
+
end
|
160
|
+
|
161
|
+
should "indicate if it needs an access_token" do
|
162
|
+
@client.needs_access?.should == true
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
end
|