foursquare-oauth 0.2.2

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/History ADDED
@@ -0,0 +1,16 @@
1
+ == 0.2.2 March 5, 2010
2
+ * oauth support
3
+ * method_missing api mapping
4
+ == 0.2.0 February 7th, 2010
5
+ * updated methods to reflect updates to Foursquare API
6
+ * added validations
7
+ * deprecated cities, check_city, switch_city, and friend_checkins calls in line with updates to the Foursquare API
8
+ * updated readme to reflect code changes
9
+
10
+ == 0.1.0 November 8th, 2009
11
+ * added website
12
+ * added defaults for optional method variables
13
+ * fleshed out readme
14
+
15
+ == 0.0.1 - October 31, 2009
16
+ * initial release
data/README.rdoc ADDED
@@ -0,0 +1,114 @@
1
+ == foursquare
2
+
3
+ A simple Ruby Gem wrapper for the Foursquare API. With OAuth authentication.
4
+
5
+ == install
6
+
7
+ gem install foursquare
8
+
9
+ == example
10
+
11
+ require 'rubygems'
12
+ require 'foursquare'
13
+
14
+ oauth_key 'your_key'
15
+ oauth_secret = 'your_secret'
16
+
17
+ oauth = Foursquare::OAuth.new(oauth_key, oauth_secret)
18
+
19
+ request_token = oauth.request_token.token
20
+ request_secret = oauth.request_token.secret
21
+
22
+ # redirecting user to foursquare to authorize
23
+ oauth.request_token.authorize_url
24
+
25
+ # foursquare redirects back to your callback url, passing the verifier in the url params
26
+
27
+ access_token, access_secret = oauth.authorize_from_request(request_token, request_secret, verifier)
28
+
29
+ # save the user's access token and secret
30
+
31
+
32
+ oauth = Foursquare::OAuth.new(oauth_key, oauth_secret)
33
+ oauth.authorize_from_access(access_token, access_secret)
34
+ foursquare = Foursquare::Base.new(oauth)
35
+
36
+ foursquare.test
37
+
38
+ foursquare.venues :geolat => geolat, :geolong => geolong, :limit => 10, :q => 'pizza'
39
+ foursquare.tips :geolat => geolat, :geolong => geolong, :limit => 10
40
+ foursquare.checkins :geolat => geolat, :geolong => geolong
41
+
42
+ checkin = {
43
+ :vid => vid,
44
+ :shout => "this is what i'm up to",
45
+ :venue => "Cohabitat",
46
+ :private => 0,
47
+ :twitter => 0,
48
+ :geolat => geolat,
49
+ :geolong => geolong
50
+ }
51
+
52
+ # these all do the same thing
53
+ # the response is a hashie object built from the checkin json. so you can do new_checkin.shout
54
+ new_checkin = foursquare.checkin(checkin)
55
+ new_checkin.class
56
+ => Hashie::Mash
57
+ new_checkin
58
+ => {...checkin hashie...}
59
+ new_checkin = foursquare.send('checkin=', checkin)
60
+ new_checkin.class
61
+ => Hash
62
+ new_checkin
63
+ => {'checkin' => {...}}
64
+ new_checkin = foursquare.api(:checkin=, checkin)
65
+ new_checkin.class
66
+ => Hashie::Mash
67
+ new_checkin
68
+ => {:checkin => {...}}
69
+
70
+ foursquare.history :limit => 10
71
+ foursquare.api(:history, :limit => 10).checkins
72
+ foursquare.user :uid => user_id :badges => 0
73
+ foursquare.user # currently authenticated user
74
+ foursquare.friends :uid => 99999
75
+ foursquare.venue :vid => venue_id
76
+ foursquare.addvenue :name => name, :address => address, :city => city, ...
77
+ foursquare.venue_proposeedit :venue_id => venue_id, :name => name, :address => address, :city => ...
78
+ foursquare.venue_flagclosed :vid => venue_id
79
+ foursquare.addtip :vid => 12345, :tip => 'here is a tip'
80
+ foursquare.tip_marktodo :tid => tip_id
81
+ foursquare.tip_markdone :tid => tip_id
82
+ foursquare.friend_requests
83
+ foursquare.friend_approve :uid => friend_id
84
+ foursquare.friend_deny :uid => friend_id
85
+ foursquare.friend_sendrequest :uid => friend_id
86
+ foursquare.findfriends_byname :q => search_string
87
+ foursquare.findfriends_byphone :q => '555 123'
88
+ foursquare.findfriends_bytwitter :q => twitter_name
89
+ foursquare.settings_setping :uid => user_id, :self => global_ping_status
90
+
91
+ == license
92
+
93
+ (the MIT license)
94
+
95
+ Copyright (c) 2009 Workperch Inc
96
+
97
+ Permission is hereby granted, free of charge, to any person obtaining
98
+ a copy of this software and associated documentation files (the
99
+ "Software"), to deal in the Software without restriction, including
100
+ without limitation the rights to use, copy, modify, merge, publish,
101
+ distribute, sublicense, and/or sell copies of the Software, and to
102
+ permit persons to whom the Software is furnished to do so, subject to
103
+ the following conditions:
104
+
105
+ The above copyright notice and this permission notice shall be
106
+ included in all copies or substantial portions of the Software.
107
+
108
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
109
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
110
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
111
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
112
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
113
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
114
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,52 @@
1
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
2
+ require 'rake/gempackagetask'
3
+ require 'rubygems/specification'
4
+ require 'date'
5
+ require 'spec/rake/spectask'
6
+
7
+ spec = Gem::Specification.new do |s|
8
+ s.name = "foursquare-oauth"
9
+ s.version = '0.2.2'
10
+ s.authors = ['Jeremy Welch', 'Thomas Hanley', 'Elise Wood']
11
+ s.email = "hello@jeremyrwelch.com"
12
+ s.homepage = "http://github.com/glytch/Foursquare"
13
+ s.description = s.summary = "A simple Ruby wrapper for the Foursquare API"
14
+ s.post_install_message = "NOTE: This version of the Foursquare Gem has significant changes to the way methods are called. Please review the examples in the README"
15
+
16
+ s.platform = Gem::Platform::RUBY
17
+ s.has_rdoc = true
18
+ s.extra_rdoc_files = ["README.rdoc", "History"]
19
+
20
+ s.require_path = 'lib'
21
+ s.autorequire = 'foursquare'
22
+ s.files = %w(README.rdoc Rakefile History) + Dir.glob("{lib,spec,script,examples}/**/*")
23
+
24
+ s.add_dependency('httparty', '0.4.3')
25
+ s.add_dependency('oauth', '0.3.6')
26
+ s.add_dependency('hashie', '0.1.5')
27
+ end
28
+
29
+ task :default => :spec
30
+
31
+ desc "Run specs"
32
+ Spec::Rake::SpecTask.new do |t|
33
+ t.spec_files = FileList['spec/**/*_spec.rb']
34
+ t.spec_opts = %w(-fs --color)
35
+ end
36
+
37
+
38
+ Rake::GemPackageTask.new(spec) do |pkg|
39
+ pkg.gem_spec = spec
40
+ end
41
+
42
+ desc "install the gem locally"
43
+ task :install => [:package] do
44
+ sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
45
+ end
46
+
47
+ desc "create a gemspec file"
48
+ task :make_spec do
49
+ File.open("foursquare.gemspec", "w") do |file|
50
+ file.puts spec.to_ruby
51
+ end
52
+ end
data/lib/foursquare.rb ADDED
@@ -0,0 +1,226 @@
1
+ require 'rubygems'
2
+ require 'httparty'
3
+ require 'hashie'
4
+ require 'oauth'
5
+
6
+ Hash.send :include, Hashie::HashExtensions
7
+
8
+
9
+
10
+ module Foursquare
11
+ class OAuth
12
+ def initialize(ctoken, csecret, options={})
13
+ @consumer_token, @consumer_secret = ctoken, csecret
14
+ end
15
+
16
+ def consumer
17
+ return @consumer if @consumer
18
+ @consumer = ::OAuth::Consumer.new(@consumer_token, @consumer_secret, {
19
+ :site => "http://foursquare.com",
20
+ :scheme => :header,
21
+ :http_method => :post,
22
+ :request_token_path => "/oauth/request_token",
23
+ :access_token_path => "/oauth/access_token",
24
+ :authorize_path => "/oauth/authorize",
25
+ :proxy => (ENV['HTTP_PROXY'] || ENV['http_proxy'])
26
+ })
27
+ end
28
+
29
+ def set_callback_url(url)
30
+ clear_request_token
31
+ request_token(:oauth_callback => url)
32
+ end
33
+
34
+ def request_token(options={})
35
+ @request_token ||= consumer.get_request_token(options)
36
+ end
37
+
38
+ def authorize_from_request(request_token, request_secret, verifier)
39
+ request_token = ::OAuth::RequestToken.new(consumer, request_token, request_secret)
40
+ access_token = request_token.get_access_token(:oauth_verifier => verifier)
41
+ @atoken, @asecret = access_token.token, access_token.secret
42
+ end
43
+
44
+ def access_token
45
+ @access_token ||= ::OAuth::AccessToken.new(consumer, @atoken, @asecret)
46
+ end
47
+
48
+ def authorize_from_access(atoken, asecret)
49
+ @atoken, @asecret = atoken, asecret
50
+ end
51
+
52
+ private
53
+
54
+ def clear_request_token
55
+ @request_token = nil
56
+ end
57
+ end
58
+
59
+ class Base
60
+ BASE_URL = 'http://api.foursquare.com/v1'
61
+ FORMAT = 'json'
62
+
63
+ attr_accessor :oauth
64
+
65
+ def initialize(oauth)
66
+ @oauth = oauth
67
+ end
68
+
69
+ #
70
+ # Foursquare API: http://groups.google.com/group/foursquare-api/web/api-documentation
71
+ #
72
+ # .test # api test method
73
+ # => {'response': 'ok'}
74
+ # .checkin = {:shout => 'At home. Writing code'} # post new check in
75
+ # => {...checkin hash...}
76
+ # .history # authenticated user's checkin history
77
+ # => [{...checkin hashie...}, {...another checkin hashie...}]
78
+ # .send('venue.flagclosed=', {:vid => 12345}) # flag venue 12345 as closed
79
+ # => {'response': 'ok'}
80
+ # .venue_flagclosed = {:vid => 12345}
81
+ # => {'response': 'ok'}
82
+ #
83
+ # Assignment methods(POSTs) always return a hash. Annoyingly Ruby always returns what's on
84
+ # the right side of the assignment operator. So there are some wrapper methods below
85
+ # for POSTs that make sure it gets turned into a hashie
86
+ #
87
+ def method_missing(method_symbol, params = {})
88
+ method_name = method_symbol.to_s.split(/\.|_/).join('/')
89
+
90
+ if (method_name[-1,1]) == '='
91
+ method = method_name[0..-2]
92
+ result = post(api_url(method), params)
93
+ params.replace(result[method] || result)
94
+ else
95
+ result = get(api_url(method_name, params))
96
+ result[method_name] || result
97
+ end
98
+ end
99
+
100
+ def api(method_symbol, params = {})
101
+ Hashie::Mash.new(method_missing(method_symbol, params))
102
+ end
103
+
104
+ def api_url(method_name, options = nil)
105
+ params = options.is_a?(Hash) ? to_query_params(options) : options
106
+ params = nil if params and params.blank?
107
+ url = BASE_URL + '/' + method_name.split('.').join('/')
108
+ url += ".#{FORMAT}"
109
+ url += "?#{params}" if params
110
+ url
111
+ end
112
+
113
+ def parse_response(response)
114
+ raise_errors(response)
115
+ Crack::JSON.parse(response.body)
116
+ end
117
+
118
+ def to_query_params(options)
119
+ options.collect { |key, value| "#{key}=#{value}" }.join('&')
120
+ end
121
+
122
+ def get(url)
123
+ parse_response(@oauth.access_token.get(url))
124
+ end
125
+
126
+ def post(url, body)
127
+ parse_response(@oauth.access_token.post(url, body))
128
+ end
129
+
130
+ # API method wrappers
131
+
132
+ def checkin(params = {})
133
+ api(:checkin=, params).checkin
134
+ end
135
+
136
+ def history(params = {})
137
+ api(:history, params).checkins
138
+ end
139
+
140
+ def addvenue(params = {})
141
+ api(:addvenue=, params).venue
142
+ end
143
+
144
+ def venue_proposeedit(params = {})
145
+ api(:venue_proposeedit=, params)
146
+ end
147
+
148
+ def venue_flagclosed(params = {})
149
+ api(:venue_flagclosed=, params)
150
+ end
151
+
152
+ def addtip(params = {})
153
+ api(:addtip=, params).tip
154
+ end
155
+
156
+ def tip_marktodo(params = {})
157
+ api(:tip_marktodo=, params).tip
158
+ end
159
+
160
+ def tip_markdone(params = {})
161
+ api(:tip_markdone=, params).tip
162
+ end
163
+
164
+ def friend_requests
165
+ api(:friend_requests).requests
166
+ end
167
+
168
+ def friend_approve(params = {})
169
+ api(:friend_approve=, params).user
170
+ end
171
+
172
+ def friend_deny(params = {})
173
+ api(:friend_deny=, params).user
174
+ end
175
+
176
+ def friend_sendrequest(params = {})
177
+ api(:friend_sendrequest=, params).user
178
+ end
179
+
180
+ def findfriends_byname(params = {})
181
+ api(:findfriends_byname, params).users
182
+ end
183
+
184
+ def findfriends_byphone(params = {})
185
+ api(:findfriends_byphone, params).users
186
+ end
187
+
188
+ def findfriends_bytwitter(params = {})
189
+ api(:findfriends_bytwitter, params).users
190
+ end
191
+
192
+ def settings_setpings(params = {})
193
+ api(:settings_setpings=, params).settings
194
+ end
195
+
196
+ private
197
+
198
+
199
+ def raise_errors(response)
200
+ message = "(#{response.code}): #{response.message} - #{response.inspect} - #{response.body}"
201
+
202
+ case response.code.to_i
203
+ when 400
204
+ raise BadRequest, message
205
+ when 401
206
+ raise Unauthorized, message
207
+ when 403
208
+ raise General, message
209
+ when 404
210
+ raise NotFound, message
211
+ when 500
212
+ raise InternalError, "Foursquare had an internal error. Please let them know in the group.\n#{message}"
213
+ when 502..503
214
+ raise Unavailable, message
215
+ end
216
+ end
217
+ end
218
+
219
+
220
+ class BadRequest < StandardError; end
221
+ class Unauthorized < StandardError; end
222
+ class General < StandardError; end
223
+ class Unavailable < StandardError; end
224
+ class InternalError < StandardError; end
225
+ class NotFound < StandardError; end
226
+ end
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:newgem_simple, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:newgem_simple, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "foursquare" do
4
+ it "should do nothing" do
5
+ true.should == true
6
+ end
7
+ end
@@ -0,0 +1,2 @@
1
+ $TESTING=true
2
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: foursquare-oauth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Jeremy Welch
8
+ - Thomas Hanley
9
+ - Elise Wood
10
+ autorequire: foursquare
11
+ bindir: bin
12
+ cert_chain: []
13
+
14
+ date: 2010-03-08 00:00:00 -06:00
15
+ default_executable:
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: httparty
19
+ type: :runtime
20
+ version_requirement:
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "="
24
+ - !ruby/object:Gem::Version
25
+ version: 0.4.3
26
+ version:
27
+ - !ruby/object:Gem::Dependency
28
+ name: oauth
29
+ type: :runtime
30
+ version_requirement:
31
+ version_requirements: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "="
34
+ - !ruby/object:Gem::Version
35
+ version: 0.3.6
36
+ version:
37
+ - !ruby/object:Gem::Dependency
38
+ name: hashie
39
+ type: :runtime
40
+ version_requirement:
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - "="
44
+ - !ruby/object:Gem::Version
45
+ version: 0.1.5
46
+ version:
47
+ description: A simple Ruby wrapper for the Foursquare API
48
+ email: hello@jeremyrwelch.com
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ extra_rdoc_files:
54
+ - README.rdoc
55
+ - History
56
+ files:
57
+ - README.rdoc
58
+ - Rakefile
59
+ - History
60
+ - lib/foursquare.rb
61
+ - spec/foursquare_spec.rb
62
+ - spec/spec_helper.rb
63
+ - script/destroy
64
+ - script/generate
65
+ has_rdoc: true
66
+ homepage: http://github.com/glytch/Foursquare
67
+ licenses: []
68
+
69
+ post_install_message: "NOTE: This version of the Foursquare Gem has significant changes to the way methods are called. Please review the examples in the README"
70
+ rdoc_options: []
71
+
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ version:
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: "0"
85
+ version:
86
+ requirements: []
87
+
88
+ rubyforge_project:
89
+ rubygems_version: 1.3.5
90
+ signing_key:
91
+ specification_version: 3
92
+ summary: A simple Ruby wrapper for the Foursquare API
93
+ test_files: []
94
+