foursquare-oauth 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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
+