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