rscribd 1.1.0 → 1.2.0
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.
- data/.gitignore +1 -0
- data/History.txt +10 -0
- data/{README.txt → README} +21 -20
- data/Rakefile +19 -0
- data/VERSION +1 -1
- data/lib/rscribd.rb +12 -33
- data/lib/{scribdapi.rb → scribd/api.rb} +48 -35
- data/lib/scribd/category.rb +112 -0
- data/lib/scribd/collection.rb +96 -0
- data/lib/{scribddoc.rb → scribd/document.rb} +179 -101
- data/lib/{scribderrors.rb → scribd/errors.rb} +4 -5
- data/lib/{scribdresource.rb → scribd/resource.rb} +65 -42
- data/lib/scribd/security.rb +102 -0
- data/lib/scribd/user.rb +193 -0
- data/lib/support/extensions.rb +26 -0
- data/lib/{scribdmultiparthack.rb → support/multipart_hack.rb} +3 -1
- data/rscribd.gemspec +86 -0
- data/spec/category_spec.rb +177 -0
- data/spec/collection_spec.rb +127 -0
- data/spec/document_spec.rb +106 -42
- data/spec/security_spec.rb +118 -0
- data/spec/user_spec.rb +88 -0
- metadata +35 -12
- data/lib/scribduser.rb +0 -145
data/.gitignore
CHANGED
data/History.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
=== 1.2.0 / 2010-5-13
|
2
|
+
|
3
|
+
* Added support for collections.
|
4
|
+
* Added support for iPaper Secure.
|
5
|
+
* Added support for categories.
|
6
|
+
* Added support for the docs.uploadThumb API method.
|
7
|
+
* Added support for the user.autoSignInUrl API method.
|
8
|
+
* Simplified the finder methods for Users and Documents.
|
9
|
+
* Switched from RDoc to YARD for gem documentation.
|
10
|
+
|
1
11
|
=== 1.1.0 / 2010-3-16
|
2
12
|
|
3
13
|
* Switched from Hoe to Jeweler.
|
data/{README.txt → README}
RENAMED
@@ -1,22 +1,22 @@
|
|
1
|
-
|
1
|
+
h1. rscribd
|
2
2
|
|
3
|
-
* 1.
|
3
|
+
* 1.2.0 (May 13, 2010)
|
4
4
|
|
5
|
-
|
5
|
+
h2. DESCRIPTION:
|
6
6
|
|
7
7
|
This gem provides a simple and powerful library for the Scribd API, allowing you
|
8
8
|
to write Ruby applications or Ruby on Rails websites that upload, convert,
|
9
9
|
display, search, and control documents in many formats. For more information on
|
10
|
-
the Scribd platform, visit
|
10
|
+
the Scribd platform, visit the Developer web page on Scribd.
|
11
11
|
|
12
|
-
|
12
|
+
h2. FEATURES:
|
13
13
|
|
14
14
|
* Upload your documents to Scribd's servers and access them using the gem
|
15
15
|
* Upload local files or from remote web sites
|
16
16
|
* Search, tag, and organize documents
|
17
17
|
* Associate documents with your users' accounts
|
18
18
|
|
19
|
-
|
19
|
+
h2. SYNOPSIS:
|
20
20
|
|
21
21
|
This API allows you to use Scribd's Flash viewer on your website. You'll be able
|
22
22
|
to take advantage of Scribd's scalable document conversion system to convert
|
@@ -24,41 +24,42 @@ your documents into platform-independent formats. You can leverage Scribd's
|
|
24
24
|
storage system to store your documents in accessible manner. Scribd's ad system
|
25
25
|
will help you monetize your documents easily.
|
26
26
|
|
27
|
-
First, you'll need to get a Scribd API account. Visit
|
28
|
-
|
27
|
+
First, you'll need to get a Scribd API account. Visit Scribd to apply for a
|
28
|
+
developer account.
|
29
29
|
|
30
30
|
On the Platform site you will be given an API key and secret. The API object
|
31
31
|
will need these to authenticate you:
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
<pre><code>
|
34
|
+
require 'rscribd'
|
35
|
+
Scribd::API.instance.key = 'your API key'
|
36
|
+
Scribd::API.instance.secret = 'your API secret'
|
37
|
+
</code></pre>
|
36
38
|
|
37
39
|
Next, log into the Scribd website:
|
38
40
|
|
39
|
-
|
41
|
+
<pre><code>Scribd::User.login 'username', 'password'</code></pre>
|
40
42
|
|
41
43
|
You are now ready to use Scribd to manage your documents. For instance, to
|
42
44
|
upload a document:
|
43
45
|
|
44
|
-
|
46
|
+
<pre><code>doc = Scribd::Document.upload(:file => 'your-file.pdf')</code></pre>
|
45
47
|
|
46
48
|
For more information, please see the documentation for the Scribd::API,
|
47
49
|
Scribd::User, and Scribd::Document classes. (You can also check out the docs for
|
48
50
|
the other classes for a more in-depth look at this gem's features).
|
49
51
|
|
50
|
-
|
52
|
+
h2. REQUIREMENTS:
|
51
53
|
|
52
54
|
* A Scribd API account
|
53
|
-
*
|
55
|
+
* Ruby 1.8 or newer, with RubyGems 1.3 or newer.
|
54
56
|
|
55
|
-
|
57
|
+
h2. INSTALL:
|
56
58
|
|
57
|
-
* The client library is a RubyGem called *rscribd*. To install, type
|
59
|
+
* The client library is a RubyGem called *rscribd*. To install, type
|
60
|
+
@sudo gem install rscribd@.
|
58
61
|
|
59
|
-
|
60
|
-
|
61
|
-
== LICENSE:
|
62
|
+
h2. LICENSE:
|
62
63
|
|
63
64
|
(The MIT License)
|
64
65
|
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'spec/rake/spectask'
|
3
|
+
require 'yard'
|
3
4
|
|
4
5
|
begin
|
5
6
|
require 'jeweler'
|
@@ -10,17 +11,35 @@ begin
|
|
10
11
|
gemspec.email = "api@scribd.com"
|
11
12
|
gemspec.homepage = "http://www.scribd.com/developers"
|
12
13
|
gemspec.authors = [ "Tim Morgan", "Jared Friedman", "Mike Watts" ]
|
14
|
+
gemspec.rubyforge_project = "rscribd"
|
13
15
|
|
14
16
|
gemspec.add_dependency 'mime-types'
|
15
17
|
gemspec.add_development_dependency "rspec"
|
18
|
+
gemspec.add_development_dependency "yard"
|
19
|
+
end
|
20
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
21
|
+
rubyforge.doc_task = "rdoc"
|
16
22
|
end
|
17
23
|
Jeweler::GemcutterTasks.new
|
18
24
|
rescue LoadError
|
19
25
|
puts "Jeweler not available. Install it with: gem install jeweler"
|
20
26
|
end
|
21
27
|
|
28
|
+
task :default => :spec
|
29
|
+
|
22
30
|
desc "Verify gem specs"
|
23
31
|
Spec::Rake::SpecTask.new do |t|
|
24
32
|
t.spec_files = FileList['spec/*.rb']
|
25
33
|
t.spec_opts = [ '-cfs' ]
|
26
34
|
end
|
35
|
+
|
36
|
+
desc 'Generate YARD documentation.'
|
37
|
+
YARD::Rake::YardocTask.new(:doc) do |rdoc|
|
38
|
+
rdoc.options << '-o' << 'doc'
|
39
|
+
rdoc.options << "--title" << "RScribd Documentation".inspect
|
40
|
+
rdoc.options << '--charset' << 'utf-8'
|
41
|
+
rdoc.options << '-r' << 'README'
|
42
|
+
rdoc.options << '--protected' << '--no-private'
|
43
|
+
rdoc.options << '--markup' << 'textile'
|
44
|
+
rdoc.files << "lib/**/*.rb"
|
45
|
+
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.2.0
|
data/lib/rscribd.rb
CHANGED
@@ -1,38 +1,17 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
module
|
4
|
-
end
|
5
|
-
|
6
|
-
class Symbol
|
7
|
-
def to_proc
|
8
|
-
Proc.new { |*args| args.shift.__send__(self, *args) }
|
9
|
-
end unless method_defined?(:to_proc)
|
10
|
-
end
|
11
|
-
|
12
|
-
class Hash #:nodoc:
|
13
|
-
# Taken from Rails, with appreciation to DHH
|
14
|
-
def stringify_keys
|
15
|
-
inject({}) do |options, (key, value)|
|
16
|
-
options[key.to_s] = value
|
17
|
-
options
|
18
|
-
end
|
19
|
-
end unless method_defined?(:stringify_keys)
|
20
|
-
end
|
3
|
+
# Container module for all classes in the RScribd gem.
|
21
4
|
|
22
|
-
|
23
|
-
def to_hsh
|
24
|
-
h = Hash.new
|
25
|
-
each { |k, v| h[k] = v }
|
26
|
-
h
|
27
|
-
end
|
5
|
+
module Scribd
|
28
6
|
end
|
29
7
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
require '
|
34
|
-
require '
|
35
|
-
require '
|
36
|
-
require '
|
37
|
-
require '
|
38
|
-
require '
|
8
|
+
require 'support/extensions'
|
9
|
+
require 'support/multipart_hack'
|
10
|
+
require 'scribd/errors'
|
11
|
+
require 'scribd/api'
|
12
|
+
require 'scribd/resource'
|
13
|
+
require 'scribd/category'
|
14
|
+
require 'scribd/collection'
|
15
|
+
require 'scribd/document'
|
16
|
+
require 'scribd/user'
|
17
|
+
require 'scribd/security'
|
@@ -6,74 +6,87 @@ module Scribd
|
|
6
6
|
|
7
7
|
# This class acts as the top-level interface between Scribd and your
|
8
8
|
# application. Before you can begin using the Scribd API, you must specify for
|
9
|
-
# this object your API key and API secret. They are available on your
|
10
|
-
#
|
9
|
+
# this object your API key and API secret. They are available on your account
|
10
|
+
# settings page.
|
11
11
|
#
|
12
12
|
# This class is a singleton. Its only instance is accessed using the
|
13
|
-
#
|
13
|
+
# @instance@ class method.
|
14
14
|
#
|
15
15
|
# To begin, first specify your API key and secret:
|
16
16
|
#
|
17
|
-
#
|
18
|
-
#
|
17
|
+
# <pre><code>
|
18
|
+
# Scribd::API.instance.key = 'your API key here'
|
19
|
+
# Scribd::API.instance.secret = 'your API secret here'
|
20
|
+
# </code></pre>
|
19
21
|
#
|
20
|
-
# (If you set the
|
22
|
+
# (If you set the @SCRIBD_API_KEY@ and @SCRIBD_API_SECRET@ Ruby environment
|
21
23
|
# variables before loading the gem, these values will be set automatically for
|
22
24
|
# you.)
|
23
25
|
#
|
24
26
|
# Next, you should log in to Scribd, or create a new account through the gem.
|
25
27
|
#
|
26
|
-
#
|
28
|
+
# <pre><code>user = Scribd::User.login 'login', 'password'</code></pre>
|
27
29
|
#
|
28
|
-
# You are now free to use the Scribd::User or Scribd::Document classes to
|
29
|
-
# with Scribd documents or your user account.
|
30
|
+
# You are now free to use the {Scribd::User} or {Scribd::Document} classes to
|
31
|
+
# work with Scribd documents or your user account.
|
30
32
|
#
|
31
|
-
# If you need the
|
32
|
-
#
|
33
|
+
# If you need the {User} instance for the currently logged in user at a later
|
34
|
+
# point in time, you can retrieve it using the @user@ attribute:
|
33
35
|
#
|
34
|
-
#
|
36
|
+
# <pre><code>user = Scribd::API.instance.user</code></pre>
|
35
37
|
#
|
36
38
|
# In addition, you can save and restore sessions by simply storing this user
|
37
39
|
# instance and assigning it to the API at a later time. For example, to
|
38
40
|
# restore the session retrieved in the previous example:
|
39
41
|
#
|
40
|
-
#
|
42
|
+
# <pre><code>Scribd::API.instance.user = user</code></pre>
|
41
43
|
#
|
42
44
|
# In addition to working with Scribd users, you can also work with your own
|
43
45
|
# website's user accounts. To do this, set the Scribd API user to a string
|
44
46
|
# containing a unique identifier for that user (perhaps a login name or a user
|
45
47
|
# ID):
|
46
48
|
#
|
47
|
-
#
|
49
|
+
# <pre><code>Scribd::API.instance.user = my_user_object.mangled_user_id</code></pre>
|
48
50
|
#
|
49
|
-
# A "phantom" Scribd user will be set up with that ID, so
|
50
|
-
#
|
51
|
+
# A "phantom" Scribd user will be set up with that ID, so any documents you
|
52
|
+
# upload will be associated with that account.
|
51
53
|
#
|
52
54
|
# For more hints on what you can do with the Scribd API, please see the
|
53
|
-
#
|
55
|
+
# {Document} class.
|
54
56
|
|
55
57
|
class API
|
56
58
|
include Singleton
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
59
|
+
|
60
|
+
# @private
|
61
|
+
HOST = 'api.scribd.com'
|
62
|
+
# @private
|
63
|
+
PORT = 80
|
64
|
+
# @private
|
65
|
+
REQUEST_PATH = '/api'
|
66
|
+
# @private
|
67
|
+
TRIES = 3
|
68
|
+
|
69
|
+
# @return [String] The API key you were given when you created a Platform account.
|
70
|
+
attr_accessor :key
|
71
|
+
# @return [String] The API secret used to validate your key (also provided with your account).
|
72
|
+
attr_accessor :secret
|
73
|
+
# @return [Scribd::User] The currently logged in user.
|
74
|
+
attr_accessor :user
|
75
|
+
# @return [true, false] If true, requests are processed asynchronously. If false, requests are blocking.
|
76
|
+
attr_accessor :asynchronous
|
77
|
+
# @return [true, false] If true, extended debugging information is printed
|
78
|
+
attr_accessor :debug
|
79
|
+
|
80
|
+
# @private
|
81
|
+
def initialize
|
70
82
|
@asychronous = false
|
71
83
|
@key = ENV['SCRIBD_API_KEY']
|
72
84
|
@secret = ENV['SCRIBD_API_SECRET']
|
73
85
|
@user = User.new
|
74
86
|
end
|
75
|
-
|
76
|
-
|
87
|
+
|
88
|
+
# @private
|
89
|
+
def send_request(method, fields={})
|
77
90
|
raise NotReadyError unless @key and @secret
|
78
91
|
# See if method is given
|
79
92
|
raise ArgumentError, "Method should be given" if method.nil? || method.empty?
|
@@ -161,7 +174,7 @@ module Scribd
|
|
161
174
|
# TODO: It would probably be better if we wrapped the fault
|
162
175
|
# in something more meaningful. At the very least, a broad
|
163
176
|
# division of errors, such as retryable and fatal.
|
164
|
-
def error(el)
|
177
|
+
def error(el)
|
165
178
|
att = el.attributes
|
166
179
|
fe = XMLRPC::FaultException.new(att['code'].to_i, att['msg'])
|
167
180
|
$stderr.puts "ERR: #{fe.faultString} (#{fe.faultCode})"
|
@@ -177,7 +190,7 @@ module Scribd
|
|
177
190
|
# Raises:
|
178
191
|
# ArgumentError if the value is nil, or empty.
|
179
192
|
#
|
180
|
-
def check_not_empty(name, value)
|
193
|
+
def check_not_empty(name, value)
|
181
194
|
check_given(name, value)
|
182
195
|
raise ArgumentError, "#{name} must not be empty" if value.to_s.empty?
|
183
196
|
end
|
@@ -191,7 +204,7 @@ module Scribd
|
|
191
204
|
# Raises:
|
192
205
|
# ArgumentError if the value is nil.
|
193
206
|
#
|
194
|
-
def check_given(name, value)
|
207
|
+
def check_given(name, value)
|
195
208
|
raise ArgumentError, "#{name} must be given" if value.nil?
|
196
209
|
end
|
197
210
|
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module Scribd
|
2
|
+
|
3
|
+
# A category on Scribd. Categories group together {Document Documents} about
|
4
|
+
# similar topics. Categories are represented as a two-way tree, with each
|
5
|
+
# category having both a {#parent} and an array of {#children}.
|
6
|
+
#
|
7
|
+
# You can choose to load categories with or without their children using the
|
8
|
+
# {.all} method. If you load categories with their children, each parent will
|
9
|
+
# have its {#children} attribute set. Otherwise, calling {#children} on a
|
10
|
+
# category will induce another network call.
|
11
|
+
|
12
|
+
class Category < Resource
|
13
|
+
# @return [Scribd::Category] The parent of this category.
|
14
|
+
# @return [nil] If this is a top-level category.
|
15
|
+
attr_reader :parent
|
16
|
+
|
17
|
+
# @private
|
18
|
+
def initialize(options)
|
19
|
+
super
|
20
|
+
@children_preloaded = false
|
21
|
+
if options[:xml] then
|
22
|
+
children_xml = options[:xml].get_elements('subcategories').first
|
23
|
+
if children_xml and not children_xml.children.empty?
|
24
|
+
@children = Array.new
|
25
|
+
children_xml.get_elements('subcategory').each do |child_xml|
|
26
|
+
children << Category.new(:xml => child_xml, :parent => self)
|
27
|
+
end
|
28
|
+
@children_preloaded = true
|
29
|
+
end
|
30
|
+
options[:xml].delete(children_xml) if children_xml
|
31
|
+
|
32
|
+
load_attributes(options[:xml])
|
33
|
+
@parent = options[:parent]
|
34
|
+
@saved = true
|
35
|
+
@created = true
|
36
|
+
else
|
37
|
+
raise "Categories cannot be created, only retrieved."
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# @return [true, false] True if this @Category@ has its children preloaded.
|
42
|
+
# @see #children
|
43
|
+
|
44
|
+
def children_preloaded?
|
45
|
+
@children_preloaded
|
46
|
+
end
|
47
|
+
|
48
|
+
# Returns an array of top-level categories. These categories will have their
|
49
|
+
# {#children} attributes set if @include_children@ is @true@.
|
50
|
+
#
|
51
|
+
# @param [true, false] include_children If @true@, child categories will be
|
52
|
+
# loaded for each top-level category. If @false@, only top-level categories
|
53
|
+
# will be loaded.
|
54
|
+
# @return [Array<Scribd::Category>] All top-level categories. If
|
55
|
+
# @include_children@ is @true@, each of these categories will have its
|
56
|
+
# @children@ attribute pre-loaded.
|
57
|
+
|
58
|
+
def self.all(include_children=false)
|
59
|
+
response = include_children ? API.instance.send_request('docs.getCategories', :with_subcategories => true) : API.instance.send_request('docs.getCategories')
|
60
|
+
categories = Array.new
|
61
|
+
response.get_elements('/rsp/result_set/result').each do |res|
|
62
|
+
categories << Category.new(:xml => res)
|
63
|
+
end
|
64
|
+
return categories
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns a list of the categories whose parent is this category.
|
68
|
+
#
|
69
|
+
# *If the receiver has preloaded its children* (in other words, it came from
|
70
|
+
# a call to {.all .all(true)}), this method makes no network call.
|
71
|
+
#
|
72
|
+
# *If the receiver has not preloaded its children* (in other words, it came
|
73
|
+
# from a call to {.all .all(false)}), _each_ invocation of this method will
|
74
|
+
# make a new network call.
|
75
|
+
#
|
76
|
+
# @return [Array<Scribd::Category>] The child categories of this category.
|
77
|
+
|
78
|
+
def children
|
79
|
+
return @children if @children
|
80
|
+
response = API.instance.send_request('docs.getCategories', :category_id => self.id)
|
81
|
+
children = Array.new
|
82
|
+
response.get_elements('/rsp/result_set/result').each do |res|
|
83
|
+
children << Category.new(:xml => res)
|
84
|
+
end
|
85
|
+
return children
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns documents found by the Scribd browser with given options, all
|
89
|
+
# categorized under this category. The browser provides documents suitable
|
90
|
+
# for a browse page.
|
91
|
+
#
|
92
|
+
# This method is called with a hash of options. For a list of supported
|
93
|
+
# options, please see the online API documentation.
|
94
|
+
#
|
95
|
+
# Documents returned from this method will have their @owner@ attributes set
|
96
|
+
# to @nil@ (i.e., they are read-only).
|
97
|
+
#
|
98
|
+
# @param [Hash] options Options to pass to the API find method.
|
99
|
+
# @return [Array<Scribd::Document>] An array of documents found.
|
100
|
+
# @example
|
101
|
+
# category.browse(:sort => 'views', :category_id => 1, :limit => 10)
|
102
|
+
|
103
|
+
def browse(options={})
|
104
|
+
response = API.instance.send_request('docs.browse', options.merge(:category_id => self.id))
|
105
|
+
documents = []
|
106
|
+
response.elements['/rsp/result_set'].elements.each do |doc|
|
107
|
+
documents << Document.new(:xml => doc)
|
108
|
+
end
|
109
|
+
return documents
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|