Class: Scribd::API

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/scribdapi.rb

Overview

This class acts as the top-level interface between Scribd and your application. Before you can begin using the Scribd API, you must specify for this object your API key and API secret. They are available on your Platform home page.

This class is a singleton. Its only instance is accessed using the instance class method.

To begin, first specify your API key and secret:

Scribd::API.instance.key = 'your API key here'
Scribd::API.instance.secret = 'your API secret here'

(If you set the SCRIBD_API_KEY and SCRIBD_API_SECRET Ruby environment variables before loading the gem, these values will be set automatically for you.)

Next, you should log in to Scribd, or create a new account through the gem.

user = Scribd::User. 'login', 'password'

You are now free to use the Scribd::User or Scribd::Document classes to work with Scribd documents or your user account.

If you need the Scribd::User instance for the currently logged in user at a later point in time, you can retrieve it using the user attribute:

user = Scribd::API.instance.user

In addition, you can save and restore sessions by simply storing this user instance and assigning it to the API at a later time. For example, to restore the session retrieved in the previous example:

Scribd::API.instance.user = user

In addition to working with Scribd users, you can also work with your own website’s user accounts. To do this, set the Scribd API user to a string containing a unique identifier for that user (perhaps a login name or a user ID):

Scribd::API.instance.user = my_user_object.mangled_user_id

A “phantom” Scribd user will be set up with that ID, so you any documents you upload will be associated with that account.

For more hints on what you can do with the Scribd API, please see the Scribd::Document class.

Constant Summary collapse

HOST =

:nodoc:

'api.scribd.com'
PORT =

:nodoc:

80
REQUEST_PATH =

:nodoc:

'/api'
TRIES =

:nodoc:

3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAPI

:nodoc:



69
70
71
72
73
74
# File 'lib/scribdapi.rb', line 69

def initialize #:nodoc:
  @asychronous = false
  @key = ENV['SCRIBD_API_KEY']
  @secret = ENV['SCRIBD_API_SECRET']
  @user = User.new
end

Instance Attribute Details

#asynchronousObject

If true, requests are processed asynchronously. If false, requests are blocking.



66
67
68
# File 'lib/scribdapi.rb', line 66

def asynchronous
  @asynchronous
end

#debug=(value) ⇒ Object

If true, extended debugging information is printed



67
68
69
# File 'lib/scribdapi.rb', line 67

def debug=(value)
  @debug = value
end

#keyObject

The API key you were given when you created a Platform account.



63
64
65
# File 'lib/scribdapi.rb', line 63

def key
  @key
end

#secretObject

The API secret used to validate your key (also provided with your account).



64
65
66
# File 'lib/scribdapi.rb', line 64

def secret
  @secret
end

#userObject

The currently logged in user.



65
66
67
# File 'lib/scribdapi.rb', line 65

def user
  @user
end

Instance Method Details

#send_request(method, fields = {}) ⇒ Object

:nodoc:

Raises:



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/scribdapi.rb', line 76

def send_request(method, fields={}) #:nodoc:
  raise NotReadyError unless @key and @secret
  # See if method is given
  raise ArgumentError, "Method should be given" if method.nil? || method.empty?
  
  debug("** Remote method call: #{method}; fields: #{fields.inspect}")
  
  # replace pesky hashes to prevent accidents
  fields = fields.stringify_keys

  # Complete fields with the method name
  fields['method'] = method
  fields['api_key'] = @key
  
  if fields['session_key'].nil? and fields['my_user_id'].nil? then
    if @user.kind_of? Scribd::User then
      fields['session_key'] = @user.session_key
    elsif @user.kind_of? String then
      fields['my_user_id'] = @user
    end
  end
  
  fields.reject! { |k, v| v.nil? }

  # Don't include file in parameters to calculate signature
  sign_fields = fields.dup
  sign_fields.delete 'file'

  fields['api_sig'] = sign(sign_fields)
  debug("** POST parameters: #{fields.inspect}")

  # Create the connection
  http = Net::HTTP.new(HOST, PORT)
  # TODO configure timeouts through the properties

  # API methods can be SLOW.  Make sure this is set to something big to prevent spurious timeouts
  http.read_timeout = 15*60

  request = Net::HTTP::Post.new(REQUEST_PATH)
  request.multipart_params = fields

  tries = TRIES
  begin
    tries -= 1
    res = http.request(request)
  rescue Exception
    $stderr.puts "Request encountered error, will retry #{tries} more."
    if tries > 0
      # Retrying several times with sleeps is recommended.
      # This will prevent temporary downtimes at Scribd from breaking API applications
      sleep(20)
      retry
    end
    raise $!
  end
  
  debug "** Response:"
  debug(res.body)
  debug "** End response"

  # Convert response into XML
  xml = REXML::Document.new(res.body)
  raise MalformedResponseError, "The response received from the remote host could not be interpreted" unless xml.elements['/rsp']

  # See if there was an error and raise an exception
  if xml.elements['/rsp'].attributes['stat'] == 'fail'
    # Load default code and error
    code, message = -1, "Unidentified error:\n#{res.body}"

    # Get actual error code and message
    err = xml.elements['/rsp/error']
    code, message = err.attributes['code'], err.attributes['message'] if err

    # Add more data
    message = "Method: #{method} Response: code=#{code} message=#{message}"

    raise ResponseError.new(code), message
  end

  return xml
end