eventfulapi 2.1
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 +10 -0
- data/lib/eventful/api.rb +271 -0
- metadata +56 -0
data/README
ADDED
@@ -0,0 +1,10 @@
|
|
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. All rights reserved. This module is distributed
|
9
|
+
under the same terms as Ruby itself (see
|
10
|
+
http://www.ruby-lang.org/en/LICENSE.txt)
|
data/lib/eventful/api.rb
ADDED
@@ -0,0 +1,271 @@
|
|
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 an error fetching the event: #{e}"
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
#
|
37
|
+
# = API Key
|
38
|
+
#
|
39
|
+
# Use of the Eventful API requires an application key (see http://api.eventful.com/keys for more information).
|
40
|
+
#
|
41
|
+
# = Change Notes
|
42
|
+
#
|
43
|
+
# == Eventful API
|
44
|
+
#
|
45
|
+
# === Version 2.1
|
46
|
+
#
|
47
|
+
# - As EVDB Inc. has been renamed Eventful Inc., the EVDB module has been
|
48
|
+
# renamed Eventful, and the gem is now named eventfulapi. Support for the
|
49
|
+
# evdbapi gem is being discontinued; please use the eventfulapi gem from now on.
|
50
|
+
# - Much better at throwing an error when a network or server problem happens,
|
51
|
+
# rather than failing silently and mysteriously
|
52
|
+
# - Documentation improvements
|
53
|
+
#
|
54
|
+
# == EVDB API
|
55
|
+
#
|
56
|
+
# === Version 2.0.1
|
57
|
+
#
|
58
|
+
# - Fixed a minor documentation error
|
59
|
+
#
|
60
|
+
# === Version 2.0
|
61
|
+
#
|
62
|
+
# Version 2.0 of this library includes some significant changes which may not
|
63
|
+
# be backwards compatible. Specifically:
|
64
|
+
#
|
65
|
+
# - Anonymous logins are now allowed
|
66
|
+
# - Fixes a potential image uploading API error
|
67
|
+
#
|
68
|
+
# Most importantly, the library now uses YAML as its data exchange format instead of
|
69
|
+
# XML, and the objects returned from a call can be used like hashes instead of
|
70
|
+
# REXML objects.
|
71
|
+
#
|
72
|
+
# = Information
|
73
|
+
#
|
74
|
+
# Status:: Stable
|
75
|
+
# Version:: 2.1
|
76
|
+
# Date:: 2007-03-24
|
77
|
+
# Current Author:: Paul Knight (mailto:pknight@eventful.com)
|
78
|
+
# Previous Authors:: Joe Auricchio
|
79
|
+
# Copyright:: Copyright (C) 2005-2007 Eventful Inc.
|
80
|
+
# License:: This code is distributed under the same terms as Ruby itself (see http://www.ruby-lang.org/en/LICENSE.txt)
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
|
86
|
+
# mime/types is available as a gem, but that's out of our way if it happens to
|
87
|
+
# be in our load path somewhere
|
88
|
+
begin
|
89
|
+
require 'mime/types'
|
90
|
+
rescue LoadError
|
91
|
+
require 'rubygems'
|
92
|
+
require 'mime/types'
|
93
|
+
end
|
94
|
+
|
95
|
+
# The rest of these are part of the standard distribution
|
96
|
+
require 'yaml'
|
97
|
+
require 'cgi'
|
98
|
+
require 'net/http'
|
99
|
+
require 'base64'
|
100
|
+
require 'digest/md5'
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
|
106
|
+
module Eventful
|
107
|
+
|
108
|
+
|
109
|
+
|
110
|
+
# Version descriptor of this library
|
111
|
+
VERSION = '2.1'
|
112
|
+
|
113
|
+
# Default API server to connect to
|
114
|
+
DEFAULT_API_SERVER = 'api.eventful.com' #:nodoc:
|
115
|
+
# Default server port
|
116
|
+
DEFAULT_API_PORT = 80 #:nodoc:
|
117
|
+
# Default server path
|
118
|
+
DEFAULT_API_ROOT = '/yaml/' #:nodoc:
|
119
|
+
|
120
|
+
# Our POST data boundary
|
121
|
+
BOUNDARY = '1E666D29B5E749F6A145BE8A576049E6' #:nodoc:
|
122
|
+
BOUNDARY_MARKER = "--#{BOUNDARY}" #:nodoc:
|
123
|
+
BOUNDARY_END_MARKER = "--#{BOUNDARY}--" #:nodoc:
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
# Parent Error used for all Eventful exceptions
|
128
|
+
class Error < StandardError ; end
|
129
|
+
|
130
|
+
# An error that may also include the YAML response from the server
|
131
|
+
class APIError < Error
|
132
|
+
attr_reader :response
|
133
|
+
|
134
|
+
# Creates a new exception.
|
135
|
+
def initialize(response)
|
136
|
+
super
|
137
|
+
@response = response
|
138
|
+
end
|
139
|
+
|
140
|
+
# The error string returned by the API call.
|
141
|
+
def to_s
|
142
|
+
"#{@response['string']}: #{@response['description']}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
# A class for working with the Eventful API.
|
149
|
+
class API
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
# Create an object for working with the Eventful API. Working with the API
|
154
|
+
# requires an application key, which can be obtained at http://api.eventful.com/keys/
|
155
|
+
#
|
156
|
+
# Options may be:
|
157
|
+
#
|
158
|
+
# <tt>'user'</tt>:: Authenticate as this user, required for some API methods. A password must also be specified.
|
159
|
+
# <tt>'password'</tt>:: Password for user authentication.
|
160
|
+
# <tt>'api_server'</tt>, <tt>'api_root'</tt>, <tt>'api_port'</tt>:: For specifying a different API server.
|
161
|
+
#
|
162
|
+
# Example:
|
163
|
+
#
|
164
|
+
# eventful = Eventful::API.new 'app_key',
|
165
|
+
# 'user' => 'username',
|
166
|
+
# 'password' => 'password'
|
167
|
+
#
|
168
|
+
def initialize(app_key, options = {})
|
169
|
+
@api_server = options['api_server'] || DEFAULT_API_SERVER
|
170
|
+
@api_root = options['api_root'] || DEFAULT_API_ROOT
|
171
|
+
@api_port = options['api_port'] || DEFAULT_API_PORT
|
172
|
+
|
173
|
+
@auth_user = options['auth_user']
|
174
|
+
@auth_password = options['auth_password']
|
175
|
+
|
176
|
+
@authentication = nil
|
177
|
+
|
178
|
+
# User authentication
|
179
|
+
if (options['user'] && options['password'])
|
180
|
+
# Get a nonce; we expect an error response here, so rescue the exception and continue
|
181
|
+
begin
|
182
|
+
response = call 'users/login',
|
183
|
+
'app_key' => app_key
|
184
|
+
rescue APIError => err
|
185
|
+
raise if !err.response['nonce']
|
186
|
+
nonce = err.response['nonce']
|
187
|
+
end
|
188
|
+
|
189
|
+
# Login with a hash of the nonce and our password
|
190
|
+
login_hash = Digest::MD5.hexdigest("#{nonce}:#{Digest::MD5.hexdigest(options['password'])}")
|
191
|
+
response = call 'users/login',
|
192
|
+
'app_key' => app_key,
|
193
|
+
'user' => options['user'],
|
194
|
+
'nonce' => nonce,
|
195
|
+
'response' => login_hash
|
196
|
+
|
197
|
+
# Store authentication information and use it for all future calls
|
198
|
+
@authentication = { 'app_key' => app_key,
|
199
|
+
'user' => options['user'],
|
200
|
+
'user_key' => response['user_key'] }
|
201
|
+
else
|
202
|
+
@authentication = { 'app_key' => app_key }
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
|
207
|
+
|
208
|
+
# Prepares the body of the POST request
|
209
|
+
def prepare_post(params) #:nodoc:
|
210
|
+
content = ""
|
211
|
+
params.each do |key, value|
|
212
|
+
content += BOUNDARY_MARKER + "\r\n"
|
213
|
+
if key.to_s =~ /_file$/
|
214
|
+
content += "Content-Disposition: file; name=\"#{CGI::escape(key.to_s)}\"; filename=\"#{value}\"\r\b"
|
215
|
+
content += "Content-Type: #{MIME::Types.type_for(value.to_s)}\r\n"
|
216
|
+
content += "Content-Transfer-Encoding: binary\r\n\r\n"
|
217
|
+
content += open(value) { |f| f.read } + "\r\n"
|
218
|
+
else
|
219
|
+
content += "Content-Disposition: form-data; name=\"#{CGI::escape(key.to_s)}\";\r\n\r\n#{value}\r\n"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
content += BOUNDARY_END_MARKER
|
223
|
+
return content
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
|
228
|
+
# Calls an API method with the given parameters, and returns the reply as
|
229
|
+
# a hash. Please see the Eventful API documentation (http://api.eventful.com/docs)
|
230
|
+
# for information about methods and their parameters.
|
231
|
+
#
|
232
|
+
# Example:
|
233
|
+
#
|
234
|
+
# event = eventful.call 'events/get',
|
235
|
+
# 'id' => 'E0-001-001042544-7'
|
236
|
+
#
|
237
|
+
def call(method, params = {})
|
238
|
+
# Use available auth tokens
|
239
|
+
params.merge! @authentication if @authentication
|
240
|
+
|
241
|
+
response = Net::HTTP.start(@api_server, @api_port) do |connection|
|
242
|
+
if @auth_user && @auth_password then
|
243
|
+
connection.post(
|
244
|
+
"#{@api_root}#{method}",
|
245
|
+
prepare_post(params),
|
246
|
+
"Content-type" => "multipart/form-data; boundary=#{BOUNDARY} ",
|
247
|
+
"Authorization" => Base64.encode64("#{@auth_user}:#{@auth_password}"))
|
248
|
+
else
|
249
|
+
connection.post(
|
250
|
+
"#{@api_root}#{method}",
|
251
|
+
prepare_post(params),
|
252
|
+
"Content-type" => "multipart/form-data; boundary=#{BOUNDARY} ")
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
# Raise an exception if we didn't get a 2xx response code
|
257
|
+
response.value
|
258
|
+
|
259
|
+
yaml = YAML::load response.body
|
260
|
+
|
261
|
+
# Raise an error if we got an API error
|
262
|
+
raise APIError.new(yaml['error']) if yaml['error']
|
263
|
+
|
264
|
+
return yaml
|
265
|
+
end
|
266
|
+
|
267
|
+
|
268
|
+
|
269
|
+
end # class API
|
270
|
+
end # module Eventful
|
271
|
+
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: eventfulapi
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "2.1"
|
7
|
+
date: 2007-03-26 00:00:00 -07:00
|
8
|
+
summary: Interface to the Eventful API. http://eventful.com
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: pknight@eventful.com
|
12
|
+
homepage: http://api.evdb.com
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: eventful/api
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Paul Knight, originally with Joe Auricchio
|
31
|
+
files:
|
32
|
+
- lib/eventful
|
33
|
+
- lib/eventful/api.rb
|
34
|
+
- README
|
35
|
+
test_files: []
|
36
|
+
|
37
|
+
rdoc_options:
|
38
|
+
- -inline-code
|
39
|
+
extra_rdoc_files:
|
40
|
+
- README
|
41
|
+
executables: []
|
42
|
+
|
43
|
+
extensions: []
|
44
|
+
|
45
|
+
requirements: []
|
46
|
+
|
47
|
+
dependencies:
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: mime-types
|
50
|
+
version_requirement:
|
51
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 0.0.0
|
56
|
+
version:
|