Class: Eventful::API

Inherits:
Object
  • Object
show all
Defined in:
lib/eventful/api.rb

Overview

A class for working with the Eventful API.

Instance Method Summary collapse

Constructor Details

#initialize(app_key, options = {}) ⇒ API

Create an object for working with the Eventful API. Working with the API requires an application key, which can be obtained at api.eventful.com/keys/

Options may be:

:user

Authenticate as this user, required for some API methods. A password must also be specified.

:password

Password for user authentication.

If both user and password are specified, then digest authenticatino will be used. Otherise, basic authentication will be used. Please note that basic authentication sends passwords in the clear. For more information, please see api.eventful.com/docs/auth

Testing Against Another Server

For testing, you may use the following options for specifying a different API server:

:server

Hostname of the API server, default api.eventful.com

:root

Path to the root of all method calls, default /yaml/

:port

Server port, default 80

If the server is behind HTTP authentication, you can use:

:http_user

Username for HTTP authentication

:http_password

Password for HTTP authenciation

Please note that none of these five options are needed for using the Eventful API.

Example

eventful = Eventful::API.new 'app_key',
                             :user => 'username',
                             :password => 'password'


252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/eventful/api.rb', line 252

def initialize(app_key, options = {})
  # Grab our arguments

  @server = find_option [:server, :api_server], options, DEFAULT_SERVER
  @root = find_option [:root, :api_root], options, DEFAULT_ROOT
  @port = find_option [:port, :api_port], options, DEFAULT_PORT

  @http_user = find_option [:http_user, :auth_user], options
  @http_password = find_option [:http_password, :auth_password], options

  user = find_option [:user], options
  password = find_option [:password], options

  # User authentication
  if user and password
    # Get a nonce; we expect an error response here, so rescue the exception and continue
    begin
      response = call 'users/login',
                      :app_key => app_key
    rescue APIError => error
      raise unless error.response['nonce']
      nonce = error.response['nonce']
    end

    # Login with a hash of the nonce and our password
     = Digest::MD5.hexdigest "#{nonce}:#{Digest::MD5.hexdigest(password)}"
    response = call 'users/login',
                    :app_key => app_key,
                    :user => user,
                    :nonce => nonce,
                    :response => 

    # Store authentication information and use it for all future calls
    @authentication = { :app_key => app_key,
                        :user => user,
                        :user_key => response['user_key'] }
  else
    @authentication = { :app_key => app_key }
  end
end

Instance Method Details

#call(method, params = {}) ⇒ Object

Calls an API method with the given parameters, and returns the reply as a hash. Please see the Eventful API documentation (api.eventful.com/docs) for information about methods and their parameters.

Example

event = eventful.call 'events/get',
                      :id => 'E0-001-001042544-7'

Raises:



336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/eventful/api.rb', line 336

def call(method, params = {})
  # Use available auth tokens
  params.merge! @authentication if @authentication

  response = Net::HTTP.start(@server, @port) do |connection|
    if @http_user and @http_password then
      connection.post(
        "#{@root}#{method}",
        prepare_post(params),
        "Content-type" => "multipart/form-data; boundary=#{BOUNDARY} ",
        "Authorization" => Base64.encode64("#{@http_user}:#{@http_password}"))
    else
      connection.post(
        "#{@root}#{method}",
        prepare_post(params),
        "Content-type" => "multipart/form-data; boundary=#{BOUNDARY} ")
    end
  end

  # Raise an exception if we didn't get a 2xx response code
  response.value

  yaml = YAML::load response.body

  # Raise an error if we got an API error
  raise APIError.new(yaml['error']) if yaml['error']

  return yaml
end

#find_option(names, arguments, default = nil) ⇒ Object

Search through a method argument Hash for specified named parameters



296
297
298
299
300
301
302
# File 'lib/eventful/api.rb', line 296

def find_option(names, arguments, default = nil) #:nodoc:
  result = default
  names.each do |name|
    result = arguments[name] || arguments[name.to_s] || result
  end
  return result
end

#prepare_post(params) ⇒ Object

Prepares the body of the POST request



308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/eventful/api.rb', line 308

def prepare_post(params) #:nodoc:
  content = ""
  params.each do |key, value|
    content += BOUNDARY_MARKER + "\r\n"
    if key.to_s =~ /_file$/
      content += "Content-Disposition: file; name=\"#{CGI::escape(key.to_s)}\"; filename=\"#{value}\"\r\b"
      content += "Content-Type: #{MIME::Types.type_for(value.to_s)}\r\n"
      content += "Content-Transfer-Encoding: binary\r\n\r\n"
      content += open(value) { |f| f.read } + "\r\n"
    else
      content += "Content-Disposition: form-data; name=\"#{CGI::escape(key.to_s)}\";\r\n\r\n#{value}\r\n"
    end
  end
  content += BOUNDARY_END_MARKER
  return content
end