tonycoco-eventfulapi 2.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.
Files changed (3) hide show
  1. data/README +9 -0
  2. data/lib/eventful/api.rb +369 -0
  3. metadata +74 -0
data/README ADDED
@@ -0,0 +1,9 @@
1
+ A library for working with the Eventful API. Simple programmatic access to
2
+ Eventful's database of events, venues, performers and speakers, groups,
3
+ calendars, and users.
4
+
5
+ See http://api.eventful.com/ for general information about the API, and
6
+ http://api.eventful.com/docs/libs/ruby/doc for documentation about the Ruby library.
7
+
8
+ Copyright 2005-2007 EVDB, Inc. This module is distributed under the same terms
9
+ as Ruby itself (see http://www.ruby-lang.org/en/LICENSE.txt)
@@ -0,0 +1,369 @@
1
+ # A library for working with the Eventful API. Simple programmatic access to
2
+ # Eventful's database of events, venues, performers and speakers, groups,
3
+ # calendars, and users.
4
+ #
5
+ # See http://api.eventful.com for more information about the Eventful API and
6
+ # the available API methods.
7
+ #
8
+ # == Example Usage
9
+ #
10
+ # require 'rubygems'
11
+ # require 'eventful/api'
12
+ #
13
+ # begin
14
+ #
15
+ # # Start an API session with a username and password
16
+ # eventful = Eventful::API.new 'application_key',
17
+ # :user => 'username',
18
+ # :password => 'password'
19
+ #
20
+ # # Lookup an event by its unique id
21
+ # event = eventful.call 'events/get',
22
+ # :id => 'E0-001-001042544-7'
23
+ #
24
+ # puts "Event Title: #{event['title']}"
25
+ #
26
+ # # Get information about that event's venue
27
+ # venue = eventful.call 'venues/get',
28
+ # :id => event['venue_id']
29
+ #
30
+ # puts "Venue: #{venue['name']}"
31
+ #
32
+ # rescue Eventful::APIError => e
33
+ # puts "There was a problem with the API call: #{e}"
34
+ # end
35
+ #
36
+ #
37
+ # == Another Example
38
+ #
39
+ # require 'rubygems'
40
+ # require 'eventful/api'
41
+ #
42
+ # # First, create our Eventful::API object
43
+ # eventful = Eventful::API.new 'application_key'
44
+ #
45
+ # loop do
46
+ # # Ask the user what and where to search
47
+ # puts "Search where? (Ex: San Diego)"
48
+ # print "? "
49
+ # location = gets.chomp
50
+ # puts "Search for what (Ex: music)"
51
+ # print "? "
52
+ # query = gets.chomp
53
+ #
54
+ # # This is the cool part!
55
+ # results = eventful.call 'events/search',
56
+ # :keywords => query,
57
+ # :location => location,
58
+ # :page_size => 5
59
+ #
60
+ # # If we couldn't find anything, ask the user again
61
+ # if results['events'].nil? then
62
+ # puts
63
+ # puts "Hmm. I couldn't find anything. Sorry."
64
+ # puts
65
+ # next
66
+ # end
67
+ #
68
+ # # Output the results
69
+ # results['events']['event'].each do |event|
70
+ # puts
71
+ # puts "http://eventful.com/events/" + event['id']
72
+ # puts event['title']
73
+ # puts " at " + event['venue_name']
74
+ # puts " on " + Time.parse(event['start_time']).strftime("%a, %b %d, %I:%M %p") if event['start_time']
75
+ # end
76
+ # puts
77
+ # end
78
+ #
79
+ #
80
+ # == API Key
81
+ #
82
+ # Use of the Eventful API requires an application key
83
+ # (see http://api.eventful.com/keys for more information).
84
+ #
85
+ # == Change Notes
86
+ #
87
+ # === Eventful API
88
+ # ==== Version 2.2.1
89
+ #
90
+ # - Updated Paul Knight's contact email in the docs
91
+ # (please reach him at pknight@eventful.com)
92
+ #
93
+ # ==== Version 2.2.0
94
+ #
95
+ # - The authentication bug has been fixed, so I'm rolling back the workaround.
96
+ # - Documented the parameters for specifying alternative API servers when calling
97
+ # Eventful.new
98
+ # - The names of these keys have been changed to be a bit friendlier. The old
99
+ # keys will still work fine.
100
+ # - Hash keys to methods can now be Symbols, in addition to strings
101
+ # - A fun new example, just because
102
+ #
103
+ # ==== Version 2.1.1
104
+ #
105
+ # - Includes a workaround fix for an authentication bug. This fix may be rolled
106
+ # back should the workaround become unecessary in the future.
107
+ #
108
+ # ==== Version 2.1
109
+ #
110
+ # - As EVDB Inc. has been renamed Eventful Inc., the EVDB module has been
111
+ # renamed Eventful, and the gem is now named eventfulapi. Support for the
112
+ # evdbapi gem is being discontinued; please use the eventfulapi gem from now on.
113
+ # - Much better at throwing an error when a network or server problem happens,
114
+ # rather than failing silently and mysteriously
115
+ # - Documentation improvements
116
+ #
117
+ # === EVDB API
118
+ #
119
+ # ==== Version 2.0.1
120
+ #
121
+ # - Fixed a minor documentation error
122
+ #
123
+ # ==== Version 2.0
124
+ #
125
+ # Version 2.0 of this library includes some significant changes which may not
126
+ # be backwards compatible. Specifically:
127
+ #
128
+ # - Anonymous logins are now allowed
129
+ # - Fixes a potential image uploading API error
130
+ #
131
+ # Most importantly, the library now uses YAML as its data exchange format instead of
132
+ # XML, and the objects returned from a call can be used like hashes instead of
133
+ # REXML objects.
134
+ #
135
+ # == Information
136
+ #
137
+ # Status:: Stable
138
+ # Version:: 2.2.1
139
+ # Date:: 2007-03-24
140
+ # Current Author:: Paul Knight (mailto:pknight@eventful.com)
141
+ # Previous Authors:: Joe Auricchio
142
+ # Copyright:: Copyright (C) 2005-2007 Eventful Inc.
143
+ # License:: This code is distributed under the same terms as Ruby
144
+ # itself (see http://www.ruby-lang.org/en/LICENSE.txt)
145
+
146
+
147
+
148
+
149
+
150
+ # mime/types is available as a gem, but that's out of our way if it happens to
151
+ # be in our load path somewhere
152
+ begin
153
+ require 'mime/types'
154
+ rescue LoadError
155
+ require 'rubygems'
156
+ require 'mime/types'
157
+ end
158
+
159
+ # The rest of these are part of the standard distribution
160
+ require 'yaml'
161
+ require 'cgi'
162
+ require 'net/http'
163
+ require 'base64'
164
+ require 'digest/md5'
165
+
166
+
167
+
168
+
169
+
170
+ module Eventful
171
+
172
+
173
+
174
+ # Version descriptor of this library
175
+ VERSION = '2.2.1'
176
+
177
+ # Default API server to connect to
178
+ DEFAULT_SERVER = 'api.eventful.com' #:nodoc:
179
+ # Default server port
180
+ DEFAULT_PORT = 80 #:nodoc:
181
+ # Default server path
182
+ DEFAULT_ROOT = '/yaml/' #:nodoc:
183
+
184
+ # Our POST data boundary
185
+ BOUNDARY = '1E666D29B5E749F6A145BE8A576049E6' #:nodoc:
186
+ BOUNDARY_MARKER = "--#{BOUNDARY}" #:nodoc:
187
+ BOUNDARY_END_MARKER = "--#{BOUNDARY}--" #:nodoc:
188
+
189
+
190
+
191
+ # Parent Error used for all Eventful exceptions
192
+ class Error < StandardError ; end
193
+
194
+ # An error that may also include the YAML response from the server
195
+ class APIError < Error
196
+ attr_reader :response
197
+
198
+ # Creates a new exception.
199
+ def initialize(response)
200
+ super
201
+ @response = response
202
+ end
203
+
204
+ # The error string returned by the API call.
205
+ def to_s
206
+ "#{@response['string']}: #{@response['description']}"
207
+ end
208
+ end
209
+
210
+
211
+
212
+ # A class for working with the Eventful API.
213
+ class API
214
+
215
+
216
+
217
+ # Create an object for working with the Eventful API. Working with the API
218
+ # requires an application key, which can be obtained at http://api.eventful.com/keys/
219
+ #
220
+ # Options may be:
221
+ #
222
+ # <tt>:user</tt>:: Authenticate as this user, required for some API methods. A password must also be specified.
223
+ # <tt>:password</tt>:: Password for user authentication.
224
+ #
225
+ # If both <tt>user</tt> and <tt>password</tt> are specified, then digest
226
+ # authenticatino will be used. Otherise, basic authentication will be used.
227
+ # Please note that basic authentication sends passwords in the clear.
228
+ # For more information, please see http://api.eventful.com/docs/auth
229
+ #
230
+ # ==== Testing Against Another Server
231
+ #
232
+ # For testing, you may use the following options for specifying a
233
+ # different API server:
234
+ #
235
+ # <tt>:server</tt>:: Hostname of the API server, default <tt>api.eventful.com</tt>
236
+ # <tt>:root</tt>:: Path to the root of all method calls, default <tt>/yaml/</tt>
237
+ # <tt>:port</tt>:: Server port, default <tt>80</tt>
238
+ #
239
+ # If the server is behind HTTP authentication, you can use:
240
+ #
241
+ # <tt>:http_user</tt>:: Username for HTTP authentication
242
+ # <tt>:http_password</tt>:: Password for HTTP authenciation
243
+ #
244
+ # Please note that none of these five options are needed for using the Eventful API.
245
+ #
246
+ # ==== Example
247
+ #
248
+ # eventful = Eventful::API.new 'app_key',
249
+ # :user => 'username',
250
+ # :password => 'password'
251
+ #
252
+ def initialize(app_key, options = {})
253
+ # Grab our arguments
254
+
255
+ @server = find_option [:server, :api_server], options, DEFAULT_SERVER
256
+ @root = find_option [:root, :api_root], options, DEFAULT_ROOT
257
+ @port = find_option [:port, :api_port], options, DEFAULT_PORT
258
+
259
+ @http_user = find_option [:http_user, :auth_user], options
260
+ @http_password = find_option [:http_password, :auth_password], options
261
+
262
+ user = find_option [:user], options
263
+ password = find_option [:password], options
264
+
265
+ # User authentication
266
+ if user and password
267
+ # Get a nonce; we expect an error response here, so rescue the exception and continue
268
+ begin
269
+ response = call 'users/login',
270
+ :app_key => app_key
271
+ rescue APIError => error
272
+ raise unless error.response['nonce']
273
+ nonce = error.response['nonce']
274
+ end
275
+
276
+ # Login with a hash of the nonce and our password
277
+ login_hash = Digest::MD5.hexdigest "#{nonce}:#{Digest::MD5.hexdigest(password)}"
278
+ response = call 'users/login',
279
+ :app_key => app_key,
280
+ :user => user,
281
+ :nonce => nonce,
282
+ :response => login_hash
283
+
284
+ # Store authentication information and use it for all future calls
285
+ @authentication = { :app_key => app_key,
286
+ :user => user,
287
+ :user_key => response['user_key'] }
288
+ else
289
+ @authentication = { :app_key => app_key }
290
+ end
291
+ end
292
+
293
+
294
+
295
+ # Search through a method argument Hash for specified named parameters
296
+ def find_option(names, arguments, default = nil) #:nodoc:
297
+ result = default
298
+ names.each do |name|
299
+ result = arguments[name] || arguments[name.to_s] || result
300
+ end
301
+ return result
302
+ end
303
+
304
+
305
+
306
+
307
+ # Prepares the body of the POST request
308
+ def prepare_post(params) #:nodoc:
309
+ content = ""
310
+ params.each do |key, value|
311
+ content += BOUNDARY_MARKER + "\r\n"
312
+ if key.to_s =~ /_file$/
313
+ content += "Content-Disposition: file; name=\"#{CGI::escape(key.to_s)}\"; filename=\"#{value}\"\r\b"
314
+ content += "Content-Type: #{MIME::Types.type_for(value.to_s)}\r\n"
315
+ content += "Content-Transfer-Encoding: binary\r\n\r\n"
316
+ content += open(value) { |f| f.read } + "\r\n"
317
+ else
318
+ content += "Content-Disposition: form-data; name=\"#{CGI::escape(key.to_s)}\";\r\n\r\n#{value}\r\n"
319
+ end
320
+ end
321
+ content += BOUNDARY_END_MARKER
322
+ return content
323
+ end
324
+
325
+
326
+
327
+ # Calls an API method with the given parameters, and returns the reply as
328
+ # a hash. Please see the Eventful API documentation (http://api.eventful.com/docs)
329
+ # for information about methods and their parameters.
330
+ #
331
+ # ==== Example
332
+ #
333
+ # event = eventful.call 'events/get',
334
+ # :id => 'E0-001-001042544-7'
335
+ #
336
+ def call(method, params = {})
337
+ # Use available auth tokens
338
+ params.merge! @authentication if @authentication
339
+
340
+ response = Net::HTTP.start(@server, @port) do |connection|
341
+ if @http_user and @http_password then
342
+ connection.post(
343
+ "#{@root}#{method}",
344
+ prepare_post(params),
345
+ "Content-type" => "multipart/form-data; boundary=#{BOUNDARY} ",
346
+ "Authorization" => Base64.encode64("#{@http_user}:#{@http_password}"))
347
+ else
348
+ connection.post(
349
+ "#{@root}#{method}",
350
+ prepare_post(params),
351
+ "Content-type" => "multipart/form-data; boundary=#{BOUNDARY} ")
352
+ end
353
+ end
354
+
355
+ # Raise an exception if we didn't get a 2xx response code
356
+ response.value
357
+
358
+ yaml = YAML::load response.body
359
+
360
+ # Raise an error if we got an API error
361
+ raise APIError.new(yaml['error']) if yaml['error']
362
+
363
+ return yaml
364
+ end
365
+
366
+
367
+
368
+ end # class API
369
+ end # module Eventful
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tonycoco-eventfulapi
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.2.2
5
+ platform: ruby
6
+ authors:
7
+ - Eventful
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-04-01 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: mime-types
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "1.15"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: diff-lcs
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.2
34
+ version:
35
+ description: Eventful API
36
+ email: support@eventful.com
37
+ executables: []
38
+
39
+ extensions: []
40
+
41
+ extra_rdoc_files: []
42
+
43
+ files:
44
+ - README
45
+ - lib/eventful
46
+ - lib/eventful/api.rb
47
+ has_rdoc: true
48
+ homepage: http://api.eventful.com
49
+ post_install_message:
50
+ rdoc_options: []
51
+
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project: evdbapi
69
+ rubygems_version: 1.2.0
70
+ signing_key:
71
+ specification_version: 2
72
+ summary: Eventful API
73
+ test_files: []
74
+