rscribd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,381 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'md5'
4
+ require 'rexml/document'
5
+ require 'net/http'
6
+ require 'parsedate'
7
+
8
+ # Main Scribd API class
9
+ class Scribd
10
+ # Default API key
11
+ API_KEY = ''
12
+
13
+ # Default API signature
14
+ API_SIG = ''
15
+
16
+ # Default API endpoint
17
+ ENDPOINT = 'http://tikhon.com/api'
18
+
19
+ # Number of tries to call a method
20
+ TRIES = 3
21
+
22
+ attr_reader :api_key, :host, :port, :path
23
+ attr_accessor :async, :debug
24
+
25
+ # Outputs whatever is given into the $stderr if debugging is enabled.
26
+ #
27
+ # Parameters:
28
+ # args - content to output
29
+ def debug(*args) $stderr.puts(sprintf(*args)) if @debug end
30
+
31
+ # Initializes API
32
+ #
33
+ # Parameters:
34
+ # api_key - API key to use
35
+ # api_sig - API signature to use
36
+ # endpoint - API endpoint,
37
+ def initialize(api_key = API_KEY, api_sig = API_SIG, endpoint = ENDPOINT)
38
+ @async = false
39
+
40
+ @api_key = api_key
41
+ @api_sig = api_sig
42
+ @endpoint = endpoint
43
+
44
+ proto, @host, @port, @path, user, pass = parse_url(@endpoint)
45
+ raise ProtoUnknownError.new("Unhandled protocol '#{proto}'") if proto.downcase != 'http'
46
+ end
47
+
48
+ # Returns Docs API interface.
49
+ def docs() @docs ||= Docs.new(self) end
50
+
51
+ # Returns Search API interface.
52
+ def search() @search || Search.new(self) end
53
+
54
+ # Sends the HTTP form to the server API with the given fields.
55
+ #
56
+ # Parameters:
57
+ # method - method name.
58
+ # fields - the Hash of field names to field values. If a field requires
59
+ # its mime-type set, you specify its value in array where the
60
+ # first element is value, the second is mime-type, and the third
61
+ # is file name, like this:
62
+ # Simple value: :user => 'john', :pass => 'nhoj'
63
+ # Typed value : :user => 'john', :file => [data, type, name]
64
+ # or : ... :file => { :data => data, :mimetype => type, :filename => 'test.txt' }
65
+ #
66
+ # Returns:
67
+ # REXML::Document with the response of the server.
68
+ #
69
+ # Raises:
70
+ # Scribd::ResponseError upon getting the 'fail' code from the server API.
71
+ # Timeout::Error if unable to connect to the server.
72
+ #
73
+ def send_form(method, fields)
74
+ # See if method is given
75
+ raise ArgumentError, "Method should be given" if method.nil? || method.empty?
76
+
77
+ # Complete fields with the method name
78
+ fields = {} if fields.nil?
79
+ fields['method'] = method
80
+
81
+ # Create a multi-part form from given fields
82
+ form = Scribd::MultiPartForm.new
83
+ form.parts = prepare_parts(fields)
84
+
85
+ debug(form.to_s)
86
+
87
+ # Configure proper boundary in the headers
88
+ headers = { "Content-Type" => "multipart/form-data; boundary=" + form.boundary }
89
+
90
+ # Create the connection
91
+ http = Net::HTTP.new(host, port)
92
+ # TODO configure timeouts through the properties
93
+ # http.read_timeout = 900 # 15 minutes max upload time
94
+
95
+ tries = TRIES
96
+ begin
97
+ tries -= 1
98
+ res = http.post(path, form.to_s, headers)
99
+ rescue Timeout::Error => err
100
+ $stderr.puts "Timed out, will retry #{tries} more."
101
+ retry if tries > 0
102
+ raise err
103
+ end
104
+
105
+ debug(res.body)
106
+
107
+ # Convert response into XML
108
+ xml = REXML::Document.new(res.body)
109
+
110
+ # See if there was an error and raise an exception
111
+ if xml.elements['/rsp'].attributes['stat'] == 'fail'
112
+ # Load default code and error
113
+ code, message = -1, "Unidentified error:\n#{res.body}"
114
+
115
+ # Get actual error code and message
116
+ err = xml.elements['/rsp/error']
117
+ code, message = err.attributes['code'], err.attributes['message'] if err
118
+
119
+ # Add more data
120
+ message = "Method: #{method} Response: code=#{code} message=#{message}"
121
+
122
+ raise Scribd::ResponseError.new(code), message
123
+ end
124
+
125
+ return xml
126
+ end
127
+
128
+ private
129
+
130
+ # Sign the arguments hash with our very own signature.
131
+ #
132
+ # Parameters:
133
+ # args - method arguments to be sent to the server API
134
+ #
135
+ # Returns:
136
+ # signature
137
+ #
138
+ def sign(args)
139
+ return MD5.md5(@api_sig + args.sort.flatten.join).to_s
140
+ end
141
+
142
+ # Parses given URL into pieces
143
+ #
144
+ # Parameters:
145
+ # url - URL to parse
146
+ #
147
+ # Returns:
148
+ # array of protocol, host, port, path, user, and password
149
+ #
150
+ def parse_url(url)
151
+ url =~ /([^:]+):\/\/([^\/]*)(.*)/
152
+ proto = $1.to_s
153
+ hostplus = $2.to_s
154
+ path = $3.to_s
155
+
156
+ hostplus =~ /(?:(.*)@)?(.*)/
157
+ userpass = $1
158
+ hostport = $2
159
+ user, pass = userpass.to_s.split(':', 2)
160
+ host, port = hostport.to_s.split(':', 2)
161
+ port = port ? port.to_i : 80
162
+
163
+ return proto, host, port, path, user, pass
164
+ end
165
+
166
+ # Prepares a list of parts for a multi-part form.
167
+ # The signature is added to the end of the list as a part.
168
+ # Fields with mime-type set are ignored during the signature calculation.
169
+ #
170
+ # Parameters:
171
+ # fields - the Hash of field names to field values. If a field requires
172
+ # its mime-type set, you specify its value in array where the
173
+ # first element is value, the second is mime-type, and the third
174
+ # is file name, like this:
175
+ # Simple value: :user => 'john', :pass => 'nhoj'
176
+ # Typed value : :user => 'john', :file => [data, type, name]
177
+ # or : ... :file => { :data => data, :mimetype => type, :filename => 'test.txt' }
178
+ #
179
+ # Returns:
180
+ # array of Scribd::FormPart objects
181
+ #
182
+ def prepare_parts(fields)
183
+ # Parameter check
184
+ raise "Fields must be a Hash" unless fields.nil? || fields.class == Hash
185
+
186
+ # Build the list of form parts and the list of non-typed
187
+ # arguments in parallel. The list of arguments will be used
188
+ # for the signature calculation.
189
+ parts = []
190
+ args = {}
191
+ fields.each do |k, v|
192
+ if v.class == Array
193
+ data, mimetype, filename = v
194
+ elsif v.class == Hash
195
+ data, mimetype, filename = v[:data], v[:mimetype], v[:filename]
196
+ else
197
+ data = v.to_s
198
+ end
199
+
200
+ parts << Scribd::FormPart.new(k.to_s, data, mimetype, filename)
201
+
202
+ # We don't place fields with mime-type set into the array
203
+ # as they usually are files and other binary data we don't
204
+ # want to hash.
205
+ args[k.to_s] = v.to_s if mimetype.nil?
206
+ end
207
+ parts << Scribd::FormPart.new('api_key', api_key)
208
+
209
+ # Add the key and calculate the signature
210
+ args['api_key'] = api_key
211
+ parts << Scribd::FormPart.new('api_sig', sign(args))
212
+
213
+ return parts
214
+ end
215
+ end
216
+
217
+ # Base class for API groups
218
+ class Scribd::APIBase
219
+ attr_reader :scribd
220
+
221
+ # Initializes API group
222
+ def initialize(scribd) @scribd = scribd end
223
+
224
+ protected
225
+
226
+ # FIXME: Since we don't need XMLRPC, the exception could be different
227
+ # TODO: It would probably be better if we wrapped the fault
228
+ # in something more meaningful. At the very least, a broad
229
+ # division of errors, such as retryable and fatal.
230
+ def error(el)
231
+ att = el.attributes
232
+ fe = XMLRPC::FaultException.new(att['code'].to_i, att['msg'])
233
+ $stderr.puts "ERR: #{fe.faultString} (#{fe.faultCode})"
234
+ raise fe
235
+ end
236
+
237
+ # Checks if a string parameter is given and not empty.
238
+ #
239
+ # Parameters:
240
+ # name - parameter name for an error message.
241
+ # value - value.
242
+ #
243
+ # Raises:
244
+ # ArgumentError if the value is nil, or empty.
245
+ #
246
+ def check_not_empty(name, value)
247
+ check_given(name, value)
248
+ raise ArgumentError, "#{name} must not be empty" if value.to_s.empty?
249
+ end
250
+
251
+ # Checks an integer parameter for being given, being a number,
252
+ # and being within the range.
253
+ #
254
+ # Parameters:
255
+ # name - parameter name for an error message.
256
+ # value - value.
257
+ # min - range minimum.
258
+ # max - range maximum.
259
+ #
260
+ # Raises:
261
+ # ArgumentError if the value is nil, not Fixnum, or outside the [min, max] range.
262
+ #
263
+ def check_in_range(name, value, min, max)
264
+ check_given(name, value)
265
+ raise ArgumentError, "#{name} is not a number" if value.class != Fixnum
266
+ raise ArgumentError, "#{name} is out of range [#{min}, #{max}]" if value < min || value > max
267
+ end
268
+
269
+ # Checks the value for being given, and being mentioned in the list.
270
+ #
271
+ # Parameters:
272
+ # name - parameter name for an error message.
273
+ # value - value.
274
+ # allowed - list of allowed values.
275
+ #
276
+ # Raises:
277
+ # ArgumentError if the value is nil, or not among the allowed values.
278
+ #
279
+ def check_allowed(name, value, allowed)
280
+ check_given(name, value)
281
+ raise ArgumentError, "#{name} is out of range #{allowed.inspect}" unless allowed.include?(value.to_sym)
282
+ end
283
+
284
+ # Checks if the value is given.
285
+ #
286
+ # Parameters:
287
+ # name - parameter name for an error message.
288
+ # value - value.
289
+ #
290
+ # Raises:
291
+ # ArgumentError if the value is nil.
292
+ #
293
+ def check_given(name, value)
294
+ raise ArgumentError, "#{name} must be given" if value.nil?
295
+ end
296
+ end
297
+
298
+ # Form part class represents a single block of attributes, or
299
+ # file or other part of the form.
300
+ class Scribd::FormPart
301
+ attr_reader :data, :mime_type, :attributes
302
+
303
+ # Initializes the part.
304
+ #
305
+ # Parameters:
306
+ # name - name
307
+ # data - data
308
+ # mime_type - optional type of the form part
309
+ # filename - optional name of the file (use with mime-type)
310
+ #
311
+ def initialize(name, data, mime_type = nil, filename = nil)
312
+ @attributes = {}
313
+ @attributes['name'] = name
314
+ @attributes['filename'] = filename unless filename.nil?
315
+ @data = data
316
+ @mime_type = mime_type
317
+ end
318
+
319
+ # Returns string representation.
320
+ def to_s
321
+ mime_present = @mime_type.nil? || @mime_type.empty?
322
+
323
+ # Disposition
324
+ fld_disposition = "Content-Disposition: form-data"
325
+ attributes.each { |k, v| fld_disposition += "; #{k}=\"#{v}\"" }
326
+
327
+ # Fields
328
+ fields = [ fld_disposition ]
329
+ unless mime_present
330
+ fields << "Content-Type: #{@mime_type}"
331
+ fields << "Content-Transfer-Encoding: binary"
332
+ end
333
+
334
+ # Add empty line and data block
335
+ fields << ''
336
+ fields << data
337
+
338
+ return fields.join("\r\n")
339
+ end
340
+ end
341
+
342
+ # Multi-part form object.
343
+ class Scribd::MultiPartForm
344
+ attr_accessor :boundary, :parts
345
+
346
+ # Creates the form object.
347
+ #
348
+ # Parameters:
349
+ # boundary - optional boundary to use for parts separation
350
+ #
351
+ def initialize(boundary = nil)
352
+ @boundary = boundary || "----------------------------Ruby#{rand(1000000000000)}"
353
+ @parts = []
354
+ end
355
+
356
+ # Returns string representation.
357
+ def to_s
358
+ "--#@boundary\r\n" +
359
+ parts.map { |p| p.to_s }.join("\r\n--#@boundary\r\n") +
360
+ "\r\n--#@boundary--\r\n"
361
+ end
362
+ end
363
+
364
+ # Response error that indicates there was a problem during
365
+ # processing your request to the server, which resulted in
366
+ # the response with the 'fail' code.
367
+ #
368
+ # You can find the code and the message inside.
369
+ #
370
+ class Scribd::ResponseError < RuntimeError
371
+ attr_reader :code
372
+
373
+ # Initializes the error.
374
+ #
375
+ # Parameters:
376
+ # code - error code.
377
+ #
378
+ def initialize(code)
379
+ @code = code
380
+ end
381
+ end
@@ -0,0 +1,246 @@
1
+ require 'rubygems'
2
+ require 'scribd/base'
3
+ require 'mime/types'
4
+
5
+ # Interface to the Docs server API
6
+ class Scribd::Docs < Scribd::APIBase
7
+
8
+ DISPLAY_FORMAT = [:html, :flash]
9
+ PARENTAL_ADVISORY = [:safe, :adult]
10
+ BOOLEAN = [:true, :false]
11
+ ACCESS = [:public, :private]
12
+ COMMENTING = [:none, :allow]
13
+
14
+ # Settings with their allowed values
15
+ SETTINGS = {
16
+ :display_format => DISPLAY_FORMAT,
17
+ :parental_advisory => PARENTAL_ADVISORY,
18
+ :access => ACCESS,
19
+ :commenting => COMMENTING,
20
+ :allow_word_download => BOOLEAN,
21
+ :allow_text_download => BOOLEAN,
22
+ :allow_pdf_download => BOOLEAN
23
+ }
24
+
25
+ # Uploads a file specified by its name (path) and returns the
26
+ # pair of document ID and GUID as an array. In addition to the
27
+ # file name, you need to specify document and access types.
28
+ #
29
+ # Parameters:
30
+ # filename - name of the file to upload.
31
+ # doc_type - optional type of the document:
32
+ # "pdf", "doc", "txt", "ppt", "pps", "xls", "ps", "htm",
33
+ # "html", "rtf", "odt", "odp", "ods", "odg", "odf", "sxw",
34
+ # "sxc", "sxi", "sxd", "jpg", "jpeg", "gif", "png"
35
+ # public - optional flag showing if the document is public (default)
36
+ # or private.
37
+ #
38
+ # Returns:
39
+ # array with two elements: doc_id and doc_guid
40
+ #
41
+ # Raises:
42
+ # ArgumentError if file name isn't given.
43
+ # Scribd::ResponseError upon getting the 'fail' code from the server API.
44
+ # Timeout::Error if unable to connect to the server.
45
+ #
46
+ def upload(filename, doc_type = nil, public = nil)
47
+ # See if URL is given
48
+ check_not_empty('filename', filename)
49
+
50
+ # Get file type and load its data
51
+ mimetype = MIME::Types.of(filename)
52
+ mimetype = 'application/octet-stream' if mimetype.nil? || mimetype.empty?
53
+ data = File.open(filename, 'rb').read
54
+
55
+ # Make a request form
56
+ fields = {}
57
+ fields[:file] = { :data => data, :mimetype => mimetype,
58
+ :filename => File.basename(filename) }
59
+
60
+ return upload_impl('docs.upload', fields, doc_type, public)
61
+ end
62
+
63
+ # Uploads a file specified by an URL and returns the
64
+ # pair of document ID and GUID as an array. In addition to the
65
+ # file name, you need to specify document and access types.
66
+ #
67
+ # Parameters:
68
+ # url - URL of the file to upload.
69
+ # doc_type - optional type of the document:
70
+ # "pdf", "doc", "txt", "ppt", "pps", "xls", "ps", "htm",
71
+ # "html", "rtf", "odt", "odp", "ods", "odg", "odf", "sxw",
72
+ # "sxc", "sxi", "sxd", "jpg", "jpeg", "gif", "png"
73
+ # public - optional flag showing if the document is public (default)
74
+ # or private.
75
+ #
76
+ # Returns:
77
+ # array with two elements: doc_id and doc_guid
78
+ #
79
+ # Raises:
80
+ # ArgumentError if URL isn't given.
81
+ # Scribd::ResponseError upon getting the 'fail' code from the server API.
82
+ # Timeout::Error if unable to connect to the server.
83
+ #
84
+ def upload_from_url(url, doc_type = nil, public = nil)
85
+ # See if URL is given
86
+ check_not_empty('url', url)
87
+
88
+ # Make a request form
89
+ fields = {}
90
+ fields[:url] = url
91
+
92
+ return upload_impl('docs.uploadFromUrl', fields, doc_type, public)
93
+ end
94
+
95
+ # Deletes a document from the repository by its ID.
96
+ #
97
+ # Parameters:
98
+ # doc_id - document ID.
99
+ #
100
+ # Returns:
101
+ # id of the deleted document.
102
+ #
103
+ # Raises:
104
+ # ArgumentError if document ID isn't given.
105
+ # Scribd::ResponseError upon getting the 'fail' code from the server API.
106
+ # Timeout::Error if unable to connect to the server.
107
+ #
108
+ def delete(doc_id)
109
+ # See if document ID is given
110
+ raise ArgumentError, "Document ID must be given" if doc_id.nil?
111
+
112
+ # Send form and return the result
113
+ res = @scribd.send_form('docs.delete', :doc_id => doc_id)
114
+ return res.elements['/rsp/doc_id'].text
115
+ end
116
+
117
+ # Returns the status of the document conversion.
118
+ #
119
+ # Parameters:
120
+ # doc_id - document ID.
121
+ #
122
+ # Returns:
123
+ # status string: "CONVERSION_ERROR", "CONVERTING", "ENCRYPTED_ERROR",
124
+ # "FAILED_TO_CONVERT", "IN_QUEUE", "PUBLISHED", "UPLOADED".
125
+ #
126
+ # Raises:
127
+ # ArgumentError if document ID isn't given.
128
+ # Scribd::ResponseError upon getting the 'fail' code from the server API.
129
+ # Timeout::Error if unable to connect to the server.
130
+ #
131
+ def get_conversion_status(doc_id)
132
+ # See if document ID is given
133
+ check_given('doc_id', doc_id)
134
+
135
+ # Send form and return the result
136
+ res = @scribd.send_form('docs.getConversionStatus', :doc_id => doc_id)
137
+ return res.elements['/rsp/conversion_status'].text
138
+ end
139
+
140
+ # Changes the settings of the document specified by its ID. The settings
141
+ # is a Hash with any number of settings key-pairs from the list below. If
142
+ # no settings are given, the method call isn't relayed to the server for
143
+ # the performance reasons.
144
+ #
145
+ # Settings keys and values you can update with this method:
146
+ # title - document title.
147
+ # description - document description.
148
+ # display_format - "html" (for plain text, HTML and images),
149
+ # "flash" (for everything else).
150
+ # access - "public" or "private"
151
+ # language - "ar", "bg", "da", "de", "en", "es", "fr", "he",
152
+ # "hu", "it", "ja", "ko", "nl", "no", "pt", "ro",
153
+ # "ru", "unknown" (default), "zh"
154
+ # license - "by", "by-nc" (Creative Commons), "by-nc-nd",
155
+ # "by-nc-sa", "by-nd", "by-sa",
156
+ # "c" (traditional copyright),
157
+ # "pd" (public domain)
158
+ # allow_word_download - "true" or "false". Allow others to download a
159
+ # MS Word version of this document. Default: "true".
160
+ # allow_text_download - "true" or "false". Allow others to download a
161
+ # plain text version of this document. Default: "true".
162
+ # allow_pdf_download - "true" or "false". Allow others to download a
163
+ # PDF version of this document. Default: "true".
164
+ # commenting - "none" or "allow". Allow others to comment. Default: "allow".
165
+ # paretal_advisory - "safe" or "adult". Default: "safe".
166
+ # tags - comma-separated list of tags. Tags cannot contain whitespace.
167
+ #
168
+ # Parameters:
169
+ # doc_id - document ID.
170
+ # settings - hash with any combination of above settings.
171
+ #
172
+ # Returns:
173
+ # id of the updated document.
174
+ #
175
+ # Raises:
176
+ # ArgumentError if document ID isn't given.
177
+ # Scribd::ResponseError upon getting the 'fail' code from the server API.
178
+ # Timeout::Error if unable to connect to the server.
179
+ #
180
+ def change_settings(doc_id, settings = nil)
181
+ # See if document ID is given
182
+ check_given('doc_id', doc_id)
183
+ check_settings(settings)
184
+
185
+ # If settings aren't given, return. Otherwise see if they are given in a Hash
186
+ return doc_id if settings.nil? || (settings.class == Hash && settings.empty?)
187
+ raise ArgumentError, "Settings must be given in a Hash" if settings.class != Hash
188
+
189
+ # Copy the settings as we'll be adding more keys to it
190
+ fields = settings.dup
191
+ fields[:doc_id] = doc_id
192
+
193
+ # Send the form and return the result
194
+ res = @scribd.send_form('docs.changeSettings', fields)
195
+ return res.elements['/rsp/doc_id'].text
196
+ end
197
+
198
+ private
199
+
200
+ # Checks if known settings are inside their allowed lists.
201
+ #
202
+ # Parameters:
203
+ # settings - Hash of settings to check, as given to #change_settings.
204
+ #
205
+ # Raises:
206
+ # ArgumentError if some setting is not given a value, or
207
+ # falls out of allowed set.
208
+ #
209
+ def check_settings(settings)
210
+ settings.each do |name, value|
211
+ allowed = SETTINGS[name.to_sym]
212
+
213
+ # If it's the setting we check, do it
214
+ unless allowed.nil?
215
+ check_given(name, value)
216
+ check_allowed(name, value, allowed)
217
+ end
218
+ end
219
+ end
220
+
221
+ # Uploads the file.
222
+ #
223
+ # Parameters:
224
+ # method - method name.
225
+ # fields - method arguments.
226
+ # doc_type - document type (see concrete methods for description).
227
+ # public - public / private boolean flag.
228
+ #
229
+ # Returns:
230
+ # array with two elements: doc_id and doc_guid
231
+ #
232
+ def upload_impl(method, fields, doc_type, public)
233
+ fields = {} if fields.nil?
234
+ fields[:doc_type] = doc_type unless doc_type.nil?
235
+ fields[:access] = (public ? 'public' : 'private') unless public.nil?
236
+
237
+ # Send it and wait for the result
238
+ res = @scribd.send_form(method, fields)
239
+
240
+ # Extract our response
241
+ doc_id = res.elements['/rsp/doc_id'].text
242
+ doc_guid = res.elements['/rsp/doc_guid'].text
243
+
244
+ return doc_id, doc_guid
245
+ end
246
+ end
@@ -0,0 +1,85 @@
1
+ require 'scribd/base'
2
+
3
+ # Interface to the Search server API
4
+ class Scribd::Search < Scribd::APIBase
5
+
6
+ SORT_BY = [:popularity, :relevance, :scribds, :time, :views]
7
+ SCOPE = [:all, :api]
8
+ PARENTAL_ADVISORY = [:safe, :adult]
9
+
10
+ # Looks for documents matching a given query. Additional optional
11
+ # parameters can be used to control the output.
12
+ #
13
+ # Parameters:
14
+ # query - query to pass to the server.
15
+ # num_results - desired maximum number of records to return [1-1000].
16
+ # num_start - first record in the result set to start from [1-1000].
17
+ # sort_by - order of sorting, default :relevance. See SORT_BY
18
+ # constant for the list of allowed values.
19
+ # scope - scope of search:
20
+ # :all - all of Scribd
21
+ # :api - only user documents
22
+ # parental_advisory - filter for adult content:
23
+ # :safe - no adult content
24
+ # :adult - everything
25
+ #
26
+ # Returns:
27
+ # list of Scribd::Document objects.
28
+ #
29
+ # Raises:
30
+ # ArgumentError if query is not given, or
31
+ # num_results is out of range, or
32
+ # num_start is out of range, or
33
+ # sort_by is not one of allowed, or
34
+ # scope is not one of allowed, or
35
+ # parental_advisory is not one of allowed.
36
+ # Scribd::ResponseError upon getting the 'fail' code from the server API.
37
+ # Timeout::Error if unable to connect to the server.
38
+ #
39
+ def docs(query, num_results = 10, num_start = 1, sort_by = :relevance,
40
+ scope = :all, parental_advisory = :safe)
41
+
42
+ # Verify the parameters
43
+ check_not_empty('query', query)
44
+ check_in_range('num_results', num_results, 1, 1000)
45
+ check_in_range('num_start', num_start, 1, 1000)
46
+ check_allowed('sort_by', sort_by, SORT_BY)
47
+ check_allowed('scope', scope, SCOPE)
48
+ check_allowed('parental_advisory', parental_advisory, PARENTAL_ADVISORY)
49
+
50
+ # Send the form
51
+ res = @scribd.send_form('search.docs', fields)
52
+
53
+ # Get documents
54
+ documents = []
55
+ res.elements['/response/result_set/result'].each do |doc|
56
+ documents << Scribd::Document.new(
57
+ doc.elements['title'],
58
+ doc.elements['description'],
59
+ doc.elements['scribd_url'],
60
+ doc.elements['doc_id'])
61
+ end
62
+
63
+ return documents
64
+ end
65
+ end
66
+
67
+ # Document returned from the search
68
+ class Scribd::Document
69
+ attr_reader :title, :description, :scribd_url, :doc_id
70
+
71
+ # Initializes a document.
72
+ #
73
+ # Parameters:
74
+ # title - document title.
75
+ # description - description.
76
+ # scribd_url - Scribd URL.
77
+ # doc_id - document ID.
78
+ #
79
+ def initialize(title, description, scribd_url, doc_id)
80
+ @title = title
81
+ @description = description
82
+ @scribd_url = scribd_url
83
+ @doc_id = doc_id
84
+ end
85
+ end
data/lib/scribd.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'scribd/base'
2
+ require 'scribd/docs'
3
+ require 'scribd/search'
@@ -0,0 +1,25 @@
1
+ # Example 1 - Uploading a test text file and removing it afterwards.
2
+ require 'scribd'
3
+
4
+ # Create a scribd object
5
+ scribd = Scribd.new('123456')
6
+
7
+ # Enable debugging if you need
8
+ # scribd.debug = true
9
+
10
+ # Get a docs API
11
+ docs = scribd.docs
12
+
13
+ begin
14
+ # Upload the document from a file
15
+ print "Uploading a document ... "
16
+ doc_id, doc_guid = docs.upload('../test/test.txt')
17
+ puts "Done doc_id=#{doc_id}, doc_guid=#{doc_guid}"
18
+
19
+ # Delete the uploaded document
20
+ print "Deleting a document ... "
21
+ doc_id = docs.delete(doc_id)
22
+ puts "Done doc_id=#{doc_id}"
23
+ rescue Scribd::ResponseError => e
24
+ puts "failed code=#{e.code} error='#{e.message}'"
25
+ end
@@ -0,0 +1,27 @@
1
+ # Example 2 - Uploading a test image file and removing it afterwards.
2
+ #
3
+ # Note: a different mime-type will be used.
4
+ require 'scribd'
5
+
6
+ # Create a scribd object
7
+ scribd = Scribd.new('123456')
8
+
9
+ # Enable debugging if you need
10
+ # scribd.debug = true
11
+
12
+ # Get a docs API
13
+ docs = scribd.docs
14
+
15
+ begin
16
+ # Upload the document from a file
17
+ print "Uploading a document ... "
18
+ doc_id, doc_guid = docs.upload('../test/test.gif', 'gif')
19
+ puts "Done doc_id=#{doc_id}, doc_guid=#{doc_guid}"
20
+
21
+ # Delete the uploaded document
22
+ print "Deleting a document ... "
23
+ doc_id = docs.delete(doc_id)
24
+ puts "Done doc_id=#{doc_id}"
25
+ rescue Scribd::ResponseError => e
26
+ puts "failed code=#{e.code} error='#{e.message}'"
27
+ end
@@ -0,0 +1,25 @@
1
+ # Example 2 - Uploading file from a URL and removing it afterwards.
2
+ require 'scribd'
3
+
4
+ # Create a scribd object
5
+ scribd = Scribd.new('123456')
6
+
7
+ # Enable debugging if you need
8
+ # scribd.debug = true
9
+
10
+ # Get a docs API
11
+ docs = scribd.docs
12
+
13
+ begin
14
+ # Upload the document from a file
15
+ print "Uploading a document ... "
16
+ doc_id, doc_guid = docs.upload_from_url('http://www.accesstoinsight.org/lib/authors/walshe/wheel261.pdf', 'pdf')
17
+ puts "Done doc_id=#{doc_id}, doc_guid=#{doc_guid}"
18
+
19
+ # Delete the uploaded document
20
+ print "Deleting a document ... "
21
+ doc_id = docs.delete(doc_id)
22
+ puts "Done doc_id=#{doc_id}"
23
+ rescue Scribd::ResponseError => e
24
+ puts "failed code=#{e.code} error='#{e.message}'"
25
+ end
@@ -0,0 +1,48 @@
1
+ # Example 4 - Uploading a test text file and changing its settings followed
2
+ # by cleanup.
3
+ require 'scribd'
4
+
5
+ # Create a scribd object
6
+ scribd = Scribd.new('123456')
7
+
8
+ # Enable debugging if you need
9
+ # scribd.debug = true
10
+
11
+ # Get a docs API
12
+ docs = scribd.docs
13
+
14
+ begin
15
+ # Upload the document from a file
16
+ print "Uploading a document ... "
17
+ doc_id, doc_guid = docs.upload('../test/test.txt')
18
+ puts "Done doc_id=#{doc_id}, doc_guid=#{doc_guid}"
19
+
20
+ begin
21
+ # Change settings of the document
22
+ print "Changing settings ... "
23
+ ndoc_id = docs.change_settings(doc_id, {
24
+ :title => 'New title',
25
+ :description => 'New description',
26
+ :display_format => 'html',
27
+ :access => 'private',
28
+ :language => 'en',
29
+ :license => 'c',
30
+ :allow_word_download => 'false',
31
+ :allow_text_download => 'true',
32
+ :allow_pdf_download => 'false',
33
+ :commenting => 'allow',
34
+ :parental_advisory => 'safe',
35
+ :tags => 'test,text'
36
+ })
37
+ puts "Done doc_id=#{ndoc_id}"
38
+ rescue Scribd::ResponseError => e
39
+ puts "failed code=#{e.code} error='#{e.message}'"
40
+ ensure
41
+ # Delete the uploaded document
42
+ print "Deleting a document ... "
43
+ doc_id = docs.delete(doc_id)
44
+ puts "Done doc_id=#{doc_id}"
45
+ end
46
+ rescue Scribd::ResponseError => e
47
+ puts "failed code=#{e.code} error='#{e.message}'"
48
+ end
@@ -0,0 +1,34 @@
1
+ # Example 5 - Uploading a test text file and checking its conversion status
2
+ # followed by cleanup.
3
+ require 'scribd'
4
+
5
+ # Create a scribd object
6
+ scribd = Scribd.new('123456')
7
+
8
+ # Enable debugging if you need
9
+ # scribd.debug = true
10
+
11
+ # Get a docs API
12
+ docs = scribd.docs
13
+
14
+ begin
15
+ # Upload the document from a file
16
+ print "Uploading a document ... "
17
+ doc_id, doc_guid = docs.upload('../test/test.txt')
18
+ puts "Done doc_id=#{doc_id}, doc_guid=#{doc_guid}"
19
+
20
+ begin
21
+ # Check the conversion status
22
+ print "Getting a conversion status ... "
23
+ puts docs.get_conversion_status(doc_id)
24
+ rescue Scribd::ResponseError => e
25
+ puts "failed code=#{e.code} error='#{e.message}'"
26
+ ensure
27
+ # Delete the uploaded document
28
+ print "Deleting a document ... "
29
+ doc_id = docs.delete(doc_id)
30
+ puts "Done doc_id=#{doc_id}"
31
+ end
32
+ rescue Scribd::ResponseError => e
33
+ puts "failed code=#{e.code} error='#{e.message}'"
34
+ end
data/sample/test.gif ADDED
Binary file
data/sample/test.txt ADDED
@@ -0,0 +1 @@
1
+ Test text file.
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: rscribd
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-11-18 00:00:00 +02:00
8
+ summary: Ruby interface to the Flickr API
9
+ require_paths:
10
+ - lib
11
+ email: matt.jaynes@gmail.com
12
+ homepage: http://rubyforge.org/projects/rscribd/
13
+ rubyforge_project: rscribd
14
+ description: rscribd is a Ruby implementation of the Scribd API. It includes a faithful reproduction of the published API as well as method encapsulation to provide more useful object mappings. rscribd features result caching to improve performance.
15
+ autorequire: rake
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
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
+
31
+ files:
32
+ - lib/scribd/search.rb
33
+ - lib/scribd/base.rb
34
+ - lib/scribd/docs.rb
35
+ - lib/scribd.rb
36
+ - sample/04-docs_changeSettings.rb
37
+ - sample/05-docs_getConversionStatus.rb
38
+ - sample/test.gif
39
+ - sample/03-docs_uploadFromUrl.rb
40
+ - sample/test.txt
41
+ - sample/01-docs_upload-text.rb
42
+ - sample/02-docs_upload-binary.rb
43
+ test_files: []
44
+
45
+ rdoc_options: []
46
+
47
+ extra_rdoc_files: []
48
+
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ requirements: []
54
+
55
+ dependencies:
56
+ - !ruby/object:Gem::Dependency
57
+ name: mime-types
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Version::Requirement
60
+ requirements:
61
+ - - ">"
62
+ - !ruby/object:Gem::Version
63
+ version: 0.0.0
64
+ version: