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.
- data/README +9 -0
- data/lib/eventful/api.rb +369 -0
- 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)
|
data/lib/eventful/api.rb
ADDED
@@ -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
|
+
|