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.
Files changed (3) hide show
  1. data/README +10 -0
  2. data/lib/eventful/api.rb +271 -0
  3. 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)
@@ -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: