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