eventfulapi 2.1.1 → 2.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/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
|