dbox 0.6.7 → 0.6.8
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/History.txt +5 -0
- data/VERSION +1 -1
- data/dbox.gemspec +2 -2
- data/lib/dbox/api.rb +27 -13
- data/lib/dbox/db.rb +1 -3
- data/lib/dbox/syncer.rb +5 -7
- data/spec/dbox_spec.rb +8 -1
- metadata +4 -4
data/History.txt
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
== 0.6.8 / 2012-04-02
|
2
|
+
* Minor Enhancements
|
3
|
+
* Added retries after receiving HTTPServiceUnavailable from Dropbox API.
|
4
|
+
* Turned number of threads down to 3 (more than that triggers Dropbox rate limiting after a while).
|
5
|
+
|
1
6
|
== 0.6.7 / 2012-03-29
|
2
7
|
* Minor Enhancements
|
3
8
|
* Added timeout to SQLite operations to help with threads competing for db operations.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.8
|
data/dbox.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "dbox"
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ken Pratt"]
|
12
|
-
s.date = "2012-03
|
12
|
+
s.date = "2012-04-03"
|
13
13
|
s.description = "An easy-to-use Dropbox client with fine-grained control over syncs."
|
14
14
|
s.email = "ken@kenpratt.net"
|
15
15
|
s.executables = ["dbox"]
|
data/lib/dbox/api.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
module Dbox
|
2
|
+
NUM_TRIES = 3
|
3
|
+
TIME_BETWEEN_TRIES = 3 # in seconds
|
4
|
+
|
2
5
|
class ConfigurationError < RuntimeError; end
|
3
6
|
class ServerError < RuntimeError; end
|
4
7
|
class RemoteMissing < RuntimeError; end
|
@@ -62,16 +65,24 @@ module Dbox
|
|
62
65
|
@client = DropboxClient.new(@session, 'dropbox')
|
63
66
|
end
|
64
67
|
|
65
|
-
def run(path)
|
68
|
+
def run(path, tries = NUM_TRIES, &proc)
|
66
69
|
begin
|
67
|
-
res =
|
70
|
+
res = proc.call
|
68
71
|
handle_response(path, res) { raise RuntimeError, "Unexpected result: #{res.inspect}" }
|
69
72
|
rescue DropboxNotModified => e
|
70
73
|
:not_modified
|
71
74
|
rescue DropboxAuthError => e
|
72
75
|
raise e
|
73
76
|
rescue DropboxError => e
|
74
|
-
|
77
|
+
if e.http_response.kind_of?(Net::HTTPServiceUnavailable) && tries > 0
|
78
|
+
log.info "Encountered 503 on #{path} (likely rate limiting). Sleeping #{TIME_BETWEEN_TRIES}s and trying again."
|
79
|
+
# TODO check for "Retry-After" header and use that for sleep instead of TIME_BETWEEN_TRIES
|
80
|
+
log.debug "Headers: #{e.http_response.to_hash.inspect}"
|
81
|
+
sleep TIME_BETWEEN_TRIES
|
82
|
+
run(path, tries - 1, &proc)
|
83
|
+
else
|
84
|
+
handle_response(path, e.http_response) { raise ServerError, "Server error -- might be a hiccup, please try your request again (#{e.message})" }
|
85
|
+
end
|
75
86
|
end
|
76
87
|
end
|
77
88
|
|
@@ -95,8 +106,8 @@ module Dbox
|
|
95
106
|
end
|
96
107
|
|
97
108
|
def metadata(path = "/", hash = nil, list=true)
|
98
|
-
log.debug "Fetching metadata for #{path}"
|
99
109
|
run(path) do
|
110
|
+
log.debug "Fetching metadata for #{path}"
|
100
111
|
res = @client.metadata(path, 10000, list, hash)
|
101
112
|
log.debug res.inspect
|
102
113
|
res
|
@@ -104,8 +115,8 @@ module Dbox
|
|
104
115
|
end
|
105
116
|
|
106
117
|
def create_dir(path)
|
107
|
-
log.info "Creating #{path}"
|
108
118
|
run(path) do
|
119
|
+
log.info "Creating #{path}"
|
109
120
|
begin
|
110
121
|
@client.file_create_folder(path)
|
111
122
|
rescue DropboxError => e
|
@@ -119,17 +130,19 @@ module Dbox
|
|
119
130
|
end
|
120
131
|
|
121
132
|
def delete_dir(path)
|
122
|
-
log.info "Deleting #{path}"
|
123
133
|
run(path) do
|
134
|
+
log.info "Deleting #{path}"
|
124
135
|
@client.file_delete(path)
|
125
136
|
end
|
126
137
|
end
|
127
138
|
|
128
139
|
def get_file(path, file_obj, stream=false)
|
129
|
-
log.info "Downloading #{path}"
|
130
140
|
unless stream
|
131
141
|
# just download directly using the get_file API
|
132
|
-
res = run(path)
|
142
|
+
res = run(path) do
|
143
|
+
log.info "Downloading #{path}"
|
144
|
+
@client.get_file(path)
|
145
|
+
end
|
133
146
|
if res.kind_of?(String)
|
134
147
|
file_obj << res
|
135
148
|
true
|
@@ -142,6 +155,7 @@ module Dbox
|
|
142
155
|
res = run(path) { @client.media(path) }
|
143
156
|
url = res[:url] if res && res.kind_of?(Hash)
|
144
157
|
if url
|
158
|
+
log.info "Downloading #{path}"
|
145
159
|
streaming_download(url, file_obj)
|
146
160
|
else
|
147
161
|
get_file(path, file_obj, false)
|
@@ -149,23 +163,23 @@ module Dbox
|
|
149
163
|
end
|
150
164
|
end
|
151
165
|
|
152
|
-
def put_file(path,
|
153
|
-
log.info "Uploading #{path}"
|
166
|
+
def put_file(path, local_path, previous_revision=nil)
|
154
167
|
run(path) do
|
155
|
-
|
168
|
+
log.info "Uploading #{path}"
|
169
|
+
File.open(local_path, "r") {|f| @client.put_file(path, f, false, previous_revision) }
|
156
170
|
end
|
157
171
|
end
|
158
172
|
|
159
173
|
def delete_file(path)
|
160
|
-
log.info "Deleting #{path}"
|
161
174
|
run(path) do
|
175
|
+
log.info "Deleting #{path}"
|
162
176
|
@client.file_delete(path)
|
163
177
|
end
|
164
178
|
end
|
165
179
|
|
166
180
|
def move(old_path, new_path)
|
167
|
-
log.info "Moving #{old_path} to #{new_path}"
|
168
181
|
run(old_path) do
|
182
|
+
log.info "Moving #{old_path} to #{new_path}"
|
169
183
|
begin
|
170
184
|
@client.file_move(old_path, new_path)
|
171
185
|
rescue DropboxError => e
|
data/lib/dbox/db.rb
CHANGED
data/lib/dbox/syncer.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Dbox
|
2
2
|
class Syncer
|
3
|
-
MAX_PARALLEL_DBOX_OPS =
|
3
|
+
MAX_PARALLEL_DBOX_OPS = 3
|
4
4
|
MIN_BYTES_TO_STREAM_DOWNLOAD = 1024 * 100 # 100kB
|
5
5
|
|
6
6
|
include Loggable
|
@@ -620,12 +620,10 @@ module Dbox
|
|
620
620
|
def upload_file(file)
|
621
621
|
local_path = relative_to_local_path(file[:path])
|
622
622
|
remote_path = relative_to_remote_path(file[:path])
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
process_basic_remote_props(res)
|
628
|
-
end
|
623
|
+
db_entry = database.find_by_path(file[:path])
|
624
|
+
last_revision = db_entry ? db_entry[:revision] : nil
|
625
|
+
res = api.put_file(remote_path, local_path, last_revision)
|
626
|
+
process_basic_remote_props(res)
|
629
627
|
end
|
630
628
|
|
631
629
|
def force_metadata_update_from_server(entry)
|
data/spec/dbox_spec.rb
CHANGED
@@ -377,7 +377,14 @@ describe Dbox do
|
|
377
377
|
Dbox.push(@local).should eql(:created => [], :deleted => [], :updated => ["hello.txt"], :failed => [])
|
378
378
|
|
379
379
|
make_file "#{@alternate}/hello.txt"
|
380
|
-
Dbox.push(@alternate)
|
380
|
+
res = Dbox.push(@alternate)
|
381
|
+
res[:created].should eql([])
|
382
|
+
res[:updated].should eql([])
|
383
|
+
res[:deleted].should eql([])
|
384
|
+
res[:failed].should eql([])
|
385
|
+
res[:conflicts].size.should eql(1)
|
386
|
+
res[:conflicts][0][:original].should eql("hello.txt")
|
387
|
+
res[:conflicts][0][:renamed].should match(/hello \(.* conflicted copy\).txt/)
|
381
388
|
end
|
382
389
|
end
|
383
390
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 8
|
10
|
+
version: 0.6.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Ken Pratt
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-03
|
18
|
+
date: 2012-04-03 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: multipart-post
|