dropbox-api-petems 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,10 +1,4 @@
1
- source "http://rubygems.org"
1
+ source "https://rubygems.org"
2
2
 
3
3
  # Specify your gem's dependencies in dropbox-api.gemspec
4
- gemspec
5
-
6
- gem "rspec"
7
- gem "rake"
8
- gem 'simplecov'
9
- gem "ruby-debug19"
10
- gem "yajl-ruby"
4
+ gemspec
data/README.markdown CHANGED
@@ -198,6 +198,27 @@ Stores a file with a provided body under a provided name and returns a Dropbox::
198
198
  client.upload 'file.txt', 'file body' # => #<Dropbox::API::File>
199
199
  ```
200
200
 
201
+ ### Dropbox::API::Client#chunked_upload
202
+
203
+ Stores a file using the chunked upload endpoint. This method issues multiple requests, and optionally takes a block, passing in the current upload byte offset and a unique ID usable for resuming uploads. Use this for uploading large files.
204
+
205
+ For more info, see [https://www.dropbox.com/developers/reference/api#chunked-upload](https://www.dropbox.com/developers/reference/api#chunked-upload)
206
+
207
+ Standard use:
208
+
209
+ ```ruby
210
+ client.chunked_upload 'file.txt', 'file or IO object' # => #<Dropbox::API::File>
211
+ ```
212
+
213
+ Using a block to show upload progress and save the upload id:
214
+
215
+ ```ruby
216
+ client.chunked_upload 'file.txt', 'file or IO object' do |offset, resp|
217
+ @upload_id = resp[:upload_id]
218
+ puts "Uploaded #{offset} bytes"
219
+ end
220
+ ```
221
+
201
222
  ### Dropbox::API::Client#download
202
223
 
203
224
  Downloads a file with a provided name and returns it's content
data/dropbox-api.gemspec CHANGED
@@ -9,13 +9,19 @@ Gem::Specification.new do |s|
9
9
  s.email = ["p.morsou@gmail.com"]
10
10
  s.homepage = "http://github.com/petems/dropbox-api-petems"
11
11
  s.summary = "A Ruby client for the DropBox REST API (Originally by marcinbunsch, forked by petems)"
12
- s.description = "To deliver a more Rubyesque experience when using the DropBox API."
12
+ s.description = "To deliver a more Rubyesque experience when using the DropBox API (forked by petems)."
13
13
 
14
14
  s.rubyforge_project = "dropbox-api"
15
15
 
16
- s.add_dependency 'multi_json'
17
- s.add_dependency 'oauth'
18
- s.add_dependency 'hashie'
16
+ s.add_dependency 'multi_json', '1.7.9'
17
+ s.add_dependency 'oauth', '0.4.7'
18
+ s.add_dependency 'hashie', '2.0.5'
19
+
20
+ s.add_development_dependency 'rspec','2.14.1'
21
+ s.add_development_dependency 'rake', '10.1.0'
22
+ s.add_development_dependency 'simplecov', '0.7.1'
23
+ s.add_development_dependency 'ruby-debug19', '0.11.6'
24
+ s.add_development_dependency 'yajl-ruby', '1.1.0'
19
25
 
20
26
  s.files = `git ls-files`.split("\n")
21
27
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -24,6 +24,42 @@ module Dropbox
24
24
  Dropbox::API::File.init(response, self)
25
25
  end
26
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
+ query = Dropbox::API::Util.query({:upload_id => options[:upload_id]})
54
+
55
+ response = connection.post(:content, "#{commit_url}?#{query}", "", {
56
+ 'Content-Type' => "application/octet-stream",
57
+ "Content-Length" => "0"
58
+ })
59
+
60
+ Dropbox::API::File.init(response, self)
61
+ end
62
+
27
63
  def copy_from_copy_ref(copy_ref, to, options = {})
28
64
  raw.copy({
29
65
  :from_copy_ref => copy_ref,
@@ -32,10 +32,12 @@ module Dropbox
32
32
  raise Dropbox::API::Error::Redirect.new("#{status} - Redirect Error")
33
33
  when 503
34
34
  parsed = MultiJson.decode(response.body)
35
- raise Dropbox::API::Error.new("503 - Possible Rate Limiting: #{parsed["error"]}")
35
+ header_parse = MultiJson.decode(response.headers)
36
+ error_message = "#{parsed["error"]}. Retry after: #{header_parse['Retry-After']}"
37
+ raise Dropbox::API::Error.new("503 - #{error_message}")
36
38
  when 507
37
39
  raise Dropbox::API::Error::StorageQuota.new("507 - Dropbox storage quota exceeded.")
38
- when 500..599
40
+ when 500..502, 504..506, 508..599
39
41
  parsed = MultiJson.decode(response.body)
40
42
  raise Dropbox::API::Error.new("#{status} - Server error. Check http://status.dropbox.com/")
41
43
  else
@@ -1,5 +1,5 @@
1
1
  module Dropbox
2
2
  module API
3
- VERSION = "0.4.1"
3
+ VERSION = "0.4.2"
4
4
  end
5
5
  end
@@ -1,5 +1,6 @@
1
1
  # encoding: utf-8
2
2
  require "spec_helper"
3
+ require "tempfile"
3
4
 
4
5
  describe Dropbox::API::Client do
5
6
 
@@ -114,6 +115,43 @@ describe Dropbox::API::Client do
114
115
  end
115
116
  end
116
117
 
118
+ describe "#chunked_upload" do
119
+
120
+ before do
121
+ @filename = "/tmp/dropbox-api-largefile-test"
122
+ @size = 5*1024*1024 # 5MB, to test the 4MB chunk size
123
+ @file = File.open(@filename, "w") {|f| f.write "a"*@size}
124
+ end
125
+
126
+ it "puts a 5MB file in dropbox" do
127
+ filename = "#{Dropbox::Spec.test_dir}/test-5MB-#{Dropbox::Spec.namespace}.txt"
128
+ response = @client.chunked_upload filename, File.open(@filename)
129
+ response.path.should == filename
130
+ response.bytes.should == @size
131
+ end
132
+
133
+ it "yields current offset and upload id" do
134
+ filename = "#{Dropbox::Spec.test_dir}/test-yield-#{Dropbox::Spec.namespace}.txt"
135
+ log_offset = ""
136
+ log_upload = ""
137
+ response = @client.chunked_upload filename, File.open(@filename) do |offset, upload|
138
+ offset.should be > 0
139
+ log_offset += "#{offset.to_s},"
140
+ log_upload += upload.inspect
141
+ upload[:upload_id].length.should eq(22)
142
+ end
143
+ response.path.should == filename
144
+ response.bytes.should == @size
145
+ log_offset.should match(/[\d]{7},[\d]{7},/)
146
+ log_upload.should include("Dropbox::API::Object","upload_id=")
147
+ end
148
+
149
+ after do
150
+ FileUtils.rm @filename
151
+ end
152
+
153
+ end
154
+
117
155
  describe "#search" do
118
156
 
119
157
  let(:term) { "searchable-test-#{Dropbox::Spec.namespace}" }
@@ -143,10 +181,10 @@ describe Dropbox::API::Client do
143
181
  it "copies a file from a copy_ref" do
144
182
  filename = "test/searchable-test-#{Dropbox::Spec.namespace}.txt"
145
183
  @client.upload filename, "Some file"
146
- response = @client.search "searchable-test-#{Dropbox::Spec.namespace}", :path => 'test'
184
+ response = @client.search "searchable-test-#{Dropbox::Spec.namespace}", :path => 'test'
147
185
  ref = response.first.copy_ref['copy_ref']
148
186
  @client.copy_from_copy_ref ref, "#{filename}.copied"
149
- response = @client.search "searchable-test-#{Dropbox::Spec.namespace}.txt.copied", :path => 'test'
187
+ response = @client.search "searchable-test-#{Dropbox::Spec.namespace}.txt.copied", :path => 'test'
150
188
  response.size.should == 1
151
189
  response.first.class.should == Dropbox::API::File
152
190
  end
@@ -79,10 +79,10 @@ describe Dropbox::API::Connection do
79
79
  end
80
80
 
81
81
  it "raises a Dropbox::API::Error when the response is a 503" do
82
- response = double :code => 503, :body => '{ "error": "rate limited" }'
82
+ response = double :code => 503, :body => '{ "error": "rate limited" }', :headers => '{ "Retry-After": "50" }'
83
83
  lambda do
84
84
  @connection.request { response }
85
- end.should raise_error(Dropbox::API::Error, '503 - Possible Rate Limiting: rate limited')
85
+ end.should raise_error(Dropbox::API::Error, '503 - rate limited. Retry after: 50')
86
86
  end
87
87
 
88
88
  it "raises a Dropbox::API::Error::StorageQuota when the response is a 507" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dropbox-api-petems
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -16,50 +16,131 @@ dependencies:
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ! '>='
19
+ - - '='
20
20
  - !ruby/object:Gem::Version
21
- version: '0'
21
+ version: 1.7.9
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ! '>='
27
+ - - '='
28
28
  - !ruby/object:Gem::Version
29
- version: '0'
29
+ version: 1.7.9
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: oauth
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
- - - ! '>='
35
+ - - '='
36
36
  - !ruby/object:Gem::Version
37
- version: '0'
37
+ version: 0.4.7
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ! '>='
43
+ - - '='
44
44
  - !ruby/object:Gem::Version
45
- version: '0'
45
+ version: 0.4.7
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: hashie
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
- - - ! '>='
51
+ - - '='
52
52
  - !ruby/object:Gem::Version
53
- version: '0'
53
+ version: 2.0.5
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
- - - ! '>='
59
+ - - '='
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
62
- description: To deliver a more Rubyesque experience when using the DropBox API.
61
+ version: 2.0.5
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 2.14.1
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - '='
76
+ - !ruby/object:Gem::Version
77
+ version: 2.14.1
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - '='
84
+ - !ruby/object:Gem::Version
85
+ version: 10.1.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - '='
92
+ - !ruby/object:Gem::Version
93
+ version: 10.1.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: simplecov
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - '='
100
+ - !ruby/object:Gem::Version
101
+ version: 0.7.1
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - '='
108
+ - !ruby/object:Gem::Version
109
+ version: 0.7.1
110
+ - !ruby/object:Gem::Dependency
111
+ name: ruby-debug19
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - '='
116
+ - !ruby/object:Gem::Version
117
+ version: 0.11.6
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - '='
124
+ - !ruby/object:Gem::Version
125
+ version: 0.11.6
126
+ - !ruby/object:Gem::Dependency
127
+ name: yajl-ruby
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - '='
132
+ - !ruby/object:Gem::Version
133
+ version: 1.1.0
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - '='
140
+ - !ruby/object:Gem::Version
141
+ version: 1.1.0
142
+ description: To deliver a more Rubyesque experience when using the DropBox API (forked
143
+ by petems).
63
144
  email:
64
145
  - p.morsou@gmail.com
65
146
  executables: []