eventfulapi 2.1

Sign up to get free protection for your applications and to get access to all the features.
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: