gowalla 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|