dropbox-api-alt 0.4.7
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.
- checksums.yaml +7 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/CHANGELOG +8 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.markdown +369 -0
- data/Rakefile +4 -0
- data/dropbox-api-alt.gemspec +34 -0
- data/lib/dropbox-api-alt.rb +1 -0
- data/lib/dropbox-api.rb +22 -0
- data/lib/dropbox-api/client.rb +72 -0
- data/lib/dropbox-api/client/files.rb +77 -0
- data/lib/dropbox-api/client/raw.rb +51 -0
- data/lib/dropbox-api/connection.rb +34 -0
- data/lib/dropbox-api/connection/requests.rb +87 -0
- data/lib/dropbox-api/objects/delta.rb +11 -0
- data/lib/dropbox-api/objects/dir.rb +29 -0
- data/lib/dropbox-api/objects/file.rb +39 -0
- data/lib/dropbox-api/objects/fileops.rb +33 -0
- data/lib/dropbox-api/objects/object.rb +39 -0
- data/lib/dropbox-api/tasks.rb +48 -0
- data/lib/dropbox-api/util/config.rb +27 -0
- data/lib/dropbox-api/util/error.rb +20 -0
- data/lib/dropbox-api/util/oauth.rb +29 -0
- data/lib/dropbox-api/util/util.rb +27 -0
- data/lib/dropbox-api/version.rb +5 -0
- data/spec/connection.sample.yml +5 -0
- data/spec/fixtures/dropbox.jpg +0 -0
- data/spec/lib/dropbox-api/client_spec.rb +259 -0
- data/spec/lib/dropbox-api/connection_spec.rb +137 -0
- data/spec/lib/dropbox-api/dir_spec.rb +59 -0
- data/spec/lib/dropbox-api/file_spec.rb +126 -0
- data/spec/lib/dropbox-api/oauth_spec.rb +17 -0
- data/spec/lib/dropbox-api/thumbnail_spec.rb +29 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/config.rb +15 -0
- data/spec/support/jpeg.rb +39 -0
- metadata +193 -0
@@ -0,0 +1 @@
|
|
1
|
+
require 'dropbox-api'
|
data/lib/dropbox-api.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "oauth"
|
2
|
+
require "multi_json"
|
3
|
+
require "hashie"
|
4
|
+
|
5
|
+
module Dropbox
|
6
|
+
module API
|
7
|
+
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
require "dropbox-api/version"
|
12
|
+
require "dropbox-api/util/config"
|
13
|
+
require "dropbox-api/util/oauth"
|
14
|
+
require "dropbox-api/util/error"
|
15
|
+
require "dropbox-api/util/util"
|
16
|
+
require "dropbox-api/objects/object"
|
17
|
+
require "dropbox-api/objects/fileops"
|
18
|
+
require "dropbox-api/objects/file"
|
19
|
+
require "dropbox-api/objects/dir"
|
20
|
+
require "dropbox-api/objects/delta"
|
21
|
+
require "dropbox-api/connection"
|
22
|
+
require "dropbox-api/client"
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require "dropbox-api/client/raw"
|
2
|
+
require "dropbox-api/client/files"
|
3
|
+
|
4
|
+
module Dropbox
|
5
|
+
module API
|
6
|
+
|
7
|
+
class Client
|
8
|
+
|
9
|
+
attr_accessor :raw, :connection
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@connection = Dropbox::API::Connection.new(:token => options.delete(:token),
|
13
|
+
:secret => options.delete(:secret))
|
14
|
+
@raw = Dropbox::API::Raw.new :connection => @connection
|
15
|
+
@options = options
|
16
|
+
end
|
17
|
+
|
18
|
+
include Dropbox::API::Client::Files
|
19
|
+
|
20
|
+
def find(filename)
|
21
|
+
data = self.raw.metadata(:path => filename, :list => false)
|
22
|
+
Dropbox::API::Object.convert(data, self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def ls(path = '')
|
26
|
+
Dropbox::API::Dir.init({'path' => path}, self).ls
|
27
|
+
end
|
28
|
+
|
29
|
+
def account
|
30
|
+
Dropbox::API::Object.init(self.raw.account, self)
|
31
|
+
end
|
32
|
+
|
33
|
+
def mkdir(path)
|
34
|
+
# Remove the characters not allowed by Dropbox
|
35
|
+
path = path.gsub(/[\\\:\?\*\<\>\"\|]+/, '')
|
36
|
+
response = raw.create_folder :path => path
|
37
|
+
Dropbox::API::Dir.init(response, self)
|
38
|
+
end
|
39
|
+
|
40
|
+
def destroy(path, options = {})
|
41
|
+
response = raw.delete({ :path => path }.merge(options))
|
42
|
+
Dropbox::API::Object.convert(response, self)
|
43
|
+
end
|
44
|
+
|
45
|
+
def search(term, options = {})
|
46
|
+
options[:path] ||= ''
|
47
|
+
results = raw.search({ :query => term }.merge(options))
|
48
|
+
Dropbox::API::Object.convert(results, self)
|
49
|
+
end
|
50
|
+
|
51
|
+
def delta(cursor=nil, options={})
|
52
|
+
entries = []
|
53
|
+
has_more = true
|
54
|
+
params = cursor ? options.merge(:cursor => cursor) : options
|
55
|
+
while has_more
|
56
|
+
response = raw.delta(params)
|
57
|
+
params[:cursor] = response['cursor']
|
58
|
+
has_more = response['has_more']
|
59
|
+
entries.push *response['entries']
|
60
|
+
end
|
61
|
+
|
62
|
+
files = entries.map do |entry|
|
63
|
+
entry.last || {:is_deleted => true, :path => entry.first}
|
64
|
+
end
|
65
|
+
|
66
|
+
Delta.new(params[:cursor], Dropbox::API::Object.convert(files, self))
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Dropbox
|
2
|
+
module API
|
3
|
+
|
4
|
+
class Client
|
5
|
+
|
6
|
+
module Files
|
7
|
+
|
8
|
+
def download(path, options = {})
|
9
|
+
root = options.delete(:root) || Dropbox::API::Config.mode
|
10
|
+
path = Dropbox::API::Util.escape(path)
|
11
|
+
url = ['', "files", root, path].compact.join('/')
|
12
|
+
connection.get_raw(:content, url)
|
13
|
+
end
|
14
|
+
|
15
|
+
def upload(path, data, options = {})
|
16
|
+
root = options.delete(:root) || Dropbox::API::Config.mode
|
17
|
+
query = Dropbox::API::Util.query(options)
|
18
|
+
path = Dropbox::API::Util.escape(path)
|
19
|
+
url = ['', "files_put", root, path].compact.join('/')
|
20
|
+
response = connection.put(:content, "#{url}?#{query}", data, {
|
21
|
+
'Content-Type' => "application/octet-stream",
|
22
|
+
"Content-Length" => data.length.to_s
|
23
|
+
})
|
24
|
+
Dropbox::API::File.init(response, self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def chunked_upload(path, file, options = {})
|
28
|
+
root = options.delete(:root) || Dropbox::API::Config.mode
|
29
|
+
path = Dropbox::API::Util.escape(path)
|
30
|
+
upload_url = '/chunked_upload'
|
31
|
+
commit_url = ['', "commit_chunked_upload", root, path].compact.join('/')
|
32
|
+
|
33
|
+
total_file_size = ::File.size(file)
|
34
|
+
chunk_size = options[:chunk_size] || 4*1024*1024 # default 4 MB chunk size
|
35
|
+
offset = options[:offset] || 0
|
36
|
+
upload_id = options[:upload_id]
|
37
|
+
|
38
|
+
while offset < total_file_size
|
39
|
+
data = file.read(chunk_size)
|
40
|
+
|
41
|
+
query = Dropbox::API::Util.query(options.merge(:offset => offset))
|
42
|
+
response = connection.put(:content, "#{upload_url}?#{query}", data, {
|
43
|
+
'Content-Type' => "application/octet-stream",
|
44
|
+
"Content-Length" => data.length.to_s
|
45
|
+
})
|
46
|
+
|
47
|
+
upload = Dropbox::API::Object.init(response, self)
|
48
|
+
options[:upload_id] ||= upload[:upload_id]
|
49
|
+
offset += upload[:offset].to_i - offset if upload[:offset] && upload[:offset].to_i > offset
|
50
|
+
yield offset, upload if block_given?
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
query = Dropbox::API::Util.query({:upload_id => options[:upload_id]})
|
55
|
+
|
56
|
+
response = connection.post(:content, "#{commit_url}?#{query}", "", {
|
57
|
+
'Content-Type' => "application/octet-stream",
|
58
|
+
"Content-Length" => "0"
|
59
|
+
})
|
60
|
+
|
61
|
+
Dropbox::API::File.init(response, self)
|
62
|
+
end
|
63
|
+
|
64
|
+
def copy_from_copy_ref(copy_ref, to, options = {})
|
65
|
+
raw.copy({
|
66
|
+
:from_copy_ref => copy_ref,
|
67
|
+
:to_path => to
|
68
|
+
}.merge(options))
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Dropbox
|
2
|
+
module API
|
3
|
+
|
4
|
+
class Raw
|
5
|
+
|
6
|
+
attr_accessor :connection
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
@connection = options[:connection]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.add_method(method, action, options = {})
|
13
|
+
# Add the default root bit, but allow it to be disabled by a config option
|
14
|
+
root = options[:root] == false ? '' : "options[:root] ||= Dropbox::API::Config.mode"
|
15
|
+
self.class_eval <<-STR
|
16
|
+
def #{options[:as] || action}(options = {})
|
17
|
+
#{root}
|
18
|
+
request(:#{options[:endpoint] || 'main'}, :#{method}, "#{action}", options)
|
19
|
+
end
|
20
|
+
STR
|
21
|
+
end
|
22
|
+
|
23
|
+
def request(endpoint, method, action, data = {})
|
24
|
+
action.sub! ':root', data.delete(:root) if action.match ':root'
|
25
|
+
action.sub! ':path', Dropbox::API::Util.escape(data.delete(:path)) if action.match ':path'
|
26
|
+
action = Dropbox::API::Util.remove_double_slashes(action)
|
27
|
+
connection.send(method, endpoint, action, data)
|
28
|
+
end
|
29
|
+
|
30
|
+
add_method :get, "/account/info", :as => 'account', :root => false
|
31
|
+
|
32
|
+
add_method :get, "/metadata/:root/:path", :as => 'metadata'
|
33
|
+
add_method :post, "/delta", :as => 'delta', :root => false
|
34
|
+
add_method :get, "/revisions/:root/:path", :as => 'revisions'
|
35
|
+
add_method :post, "/restore/:root/:path", :as => 'restore'
|
36
|
+
add_method :get, "/search/:root/:path", :as => 'search'
|
37
|
+
add_method :post, "/shares/:root/:path", :as => 'shares'
|
38
|
+
add_method :post, "/media/:root/:path", :as => 'media'
|
39
|
+
|
40
|
+
add_method :get_raw, "/thumbnails/:root/:path", :as => 'thumbnails', :endpoint => :content
|
41
|
+
|
42
|
+
add_method :post, "/fileops/copy", :as => "copy"
|
43
|
+
add_method :get, "/copy_ref/:root/:path", :as => 'copy_ref'
|
44
|
+
add_method :post, "/fileops/create_folder", :as => "create_folder"
|
45
|
+
add_method :post, "/fileops/delete", :as => "delete"
|
46
|
+
add_method :post, "/fileops/move", :as => "move"
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "dropbox-api/connection/requests"
|
2
|
+
|
3
|
+
module Dropbox
|
4
|
+
module API
|
5
|
+
|
6
|
+
class Connection
|
7
|
+
|
8
|
+
include Dropbox::API::Connection::Requests
|
9
|
+
|
10
|
+
attr_accessor :consumers
|
11
|
+
attr_accessor :tokens
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
@options = options
|
15
|
+
@consumers = {}
|
16
|
+
@tokens = {}
|
17
|
+
Dropbox::API::Config.endpoints.each do |endpoint, url|
|
18
|
+
@consumers[endpoint] = Dropbox::API::OAuth.consumer(endpoint)
|
19
|
+
@tokens[endpoint] = Dropbox::API::OAuth.access_token(@consumers[endpoint], options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def consumer(endpoint = :main)
|
24
|
+
@consumers[endpoint]
|
25
|
+
end
|
26
|
+
|
27
|
+
def token(endpoint = :main)
|
28
|
+
@tokens[endpoint]
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Dropbox
|
2
|
+
module API
|
3
|
+
|
4
|
+
class Connection
|
5
|
+
|
6
|
+
module Requests
|
7
|
+
|
8
|
+
def request(options = {})
|
9
|
+
response = yield
|
10
|
+
raise Dropbox::API::Error::ConnectionFailed if !response
|
11
|
+
status = response.code.to_i
|
12
|
+
case status
|
13
|
+
when 400
|
14
|
+
parsed = MultiJson.decode(response.body)
|
15
|
+
raise Dropbox::API::Error::BadInput.new("400 - Bad input parameter - #{parsed['error']}")
|
16
|
+
when 401
|
17
|
+
raise Dropbox::API::Error::Unauthorized.new("401 - Bad or expired token")
|
18
|
+
when 403
|
19
|
+
parsed = MultiJson.decode(response.body)
|
20
|
+
raise Dropbox::API::Error::Forbidden.new('403 - Bad OAuth request')
|
21
|
+
when 404
|
22
|
+
raise Dropbox::API::Error::NotFound.new("404 - Not found")
|
23
|
+
when 405
|
24
|
+
parsed = MultiJson.decode(response.body)
|
25
|
+
raise Dropbox::API::Error::WrongMethod.new("405 - Request method not expected - #{parsed['error']}")
|
26
|
+
when 406
|
27
|
+
parsed = MultiJson.decode(response.body)
|
28
|
+
raise Dropbox::API::Error.new("#{status} - #{parsed['error']}")
|
29
|
+
when 429
|
30
|
+
raise Dropbox::API::Error::RateLimit.new('429 - Rate Limiting in affect')
|
31
|
+
when 300..399
|
32
|
+
raise Dropbox::API::Error::Redirect.new("#{status} - Redirect Error")
|
33
|
+
when 503
|
34
|
+
handle_503 response
|
35
|
+
when 507
|
36
|
+
raise Dropbox::API::Error::StorageQuota.new("507 - Dropbox storage quota exceeded.")
|
37
|
+
when 500..502, 504..506, 508..599
|
38
|
+
parsed = MultiJson.decode(response.body)
|
39
|
+
raise Dropbox::API::Error.new("#{status} - Server error. Check http://status.dropbox.com/")
|
40
|
+
else
|
41
|
+
options[:raw] ? response.body : MultiJson.decode(response.body)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def handle_503(response)
|
46
|
+
if response.is_a? Net::HTTPServiceUnavailable
|
47
|
+
raise Dropbox::API::Error.new("503 - #{response.message}")
|
48
|
+
else
|
49
|
+
parsed = MultiJson.decode(response.body)
|
50
|
+
header_parse = MultiJson.decode(response.headers)
|
51
|
+
error_message = "#{parsed["error"]}. Retry after: #{header_parse['Retry-After']}"
|
52
|
+
raise Dropbox::API::Error.new("503 - #{error_message}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_raw(endpoint, path, data = {}, headers = {})
|
57
|
+
query = Dropbox::API::Util.query(data)
|
58
|
+
request(:raw => true) do
|
59
|
+
token(endpoint).get "#{Dropbox::API::Config.prefix}#{path}?#{URI.parse(URI.encode(query))}", headers
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def get(endpoint, path, data = {}, headers = {})
|
64
|
+
query = Dropbox::API::Util.query(data)
|
65
|
+
request do
|
66
|
+
token(endpoint).get "#{Dropbox::API::Config.prefix}#{path}?#{URI.parse(URI.encode(query))}", headers
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def post(endpoint, path, data = {}, headers = {})
|
71
|
+
request do
|
72
|
+
token(endpoint).post "#{Dropbox::API::Config.prefix}#{path}", data, headers
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def put(endpoint, path, data = {}, headers = {})
|
77
|
+
request do
|
78
|
+
token(endpoint).put "#{Dropbox::API::Config.prefix}#{path}", data, headers
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Dropbox
|
2
|
+
module API
|
3
|
+
|
4
|
+
class Dir < Dropbox::API::Object
|
5
|
+
|
6
|
+
include Dropbox::API::Fileops
|
7
|
+
|
8
|
+
def ls(path_to_list = '')
|
9
|
+
data = client.raw.metadata :path => path + path_to_list
|
10
|
+
if data['is_dir']
|
11
|
+
Dropbox::API::Object.convert(data.delete('contents') || [], client)
|
12
|
+
else
|
13
|
+
[Dropbox::API::Object.convert(data, client)]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def direct_url(options = {})
|
18
|
+
response = client.raw.shares({ :path => self.path, :short_url => false }.merge(options))
|
19
|
+
Dropbox::API::Object.init(response, client)
|
20
|
+
end
|
21
|
+
|
22
|
+
def hash
|
23
|
+
self[:hash]
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Dropbox
|
2
|
+
module API
|
3
|
+
|
4
|
+
class File < Dropbox::API::Object
|
5
|
+
|
6
|
+
include Dropbox::API::Fileops
|
7
|
+
|
8
|
+
def revisions(options = {})
|
9
|
+
response = client.raw.revisions({ :path => self.path }.merge(options))
|
10
|
+
Dropbox::API::Object.convert(response, client)
|
11
|
+
end
|
12
|
+
|
13
|
+
def restore(rev, options = {})
|
14
|
+
response = client.raw.restore({ :rev => rev, :path => self.path }.merge(options))
|
15
|
+
self.update response
|
16
|
+
end
|
17
|
+
|
18
|
+
def thumbnail(options = {})
|
19
|
+
client.raw.thumbnails({ :path => self.path }.merge(options))
|
20
|
+
end
|
21
|
+
|
22
|
+
def copy_ref(options = {})
|
23
|
+
response = client.raw.copy_ref({ :path => self.path }.merge(options))
|
24
|
+
Dropbox::API::Object.init(response, client)
|
25
|
+
end
|
26
|
+
|
27
|
+
def download
|
28
|
+
client.download(self.path)
|
29
|
+
end
|
30
|
+
|
31
|
+
def direct_url(options = {})
|
32
|
+
response = client.raw.media({ :path => self.path }.merge(options))
|
33
|
+
Dropbox::API::Object.init(response, client)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Dropbox
|
2
|
+
module API
|
3
|
+
|
4
|
+
module Fileops
|
5
|
+
|
6
|
+
def copy(to, options = {})
|
7
|
+
response = client.raw.copy({ :from_path => self.path, :to_path => to }.merge(options))
|
8
|
+
self.update response
|
9
|
+
end
|
10
|
+
|
11
|
+
def move(to, options = {})
|
12
|
+
response = client.raw.move({ :from_path => self.path, :to_path => to }.merge(options))
|
13
|
+
self.update response
|
14
|
+
end
|
15
|
+
|
16
|
+
def destroy(options = {})
|
17
|
+
response = client.raw.delete({ :path => self.path }.merge(options))
|
18
|
+
self.update response
|
19
|
+
end
|
20
|
+
|
21
|
+
def path
|
22
|
+
self['path'].sub(/^\//, '')
|
23
|
+
end
|
24
|
+
|
25
|
+
def share_url(options = {})
|
26
|
+
response = client.raw.shares({ :path => self.path }.merge(options))
|
27
|
+
Dropbox::API::Object.init(response, client)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|