dbox 0.4.4 → 0.5.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/README.md +1 -1
- data/Rakefile +2 -0
- data/TODO.txt +5 -2
- data/VERSION +1 -1
- data/dbox.gemspec +13 -3
- data/lib/dbox.rb +31 -11
- data/lib/dbox/api.rb +15 -5
- data/lib/dbox/database.rb +216 -0
- data/lib/dbox/db.rb +17 -3
- data/lib/dbox/parallel_tasks.rb +68 -0
- data/lib/dbox/syncer.rb +595 -0
- data/sample_polling_script.rb +45 -0
- data/spec/dbox_spec.rb +82 -30
- data/spec/spec_helper.rb +4 -7
- data/vendor/dropbox-client-ruby/README +2 -0
- data/vendor/dropbox-client-ruby/lib/dropbox.rb +36 -3
- metadata +42 -6
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "dbox"
|
5
|
+
|
6
|
+
ENV["DROPBOX_APP_KEY"] = "cmlrrjd3j0gbend"
|
7
|
+
ENV["DROPBOX_APP_SECRET"] = "uvuulp75xf9jffl"
|
8
|
+
ENV["DROPBOX_AUTH_KEY"] = "v4d7l1rez1czksn"
|
9
|
+
ENV["DROPBOX_AUTH_SECRET"] = "pqej9rmnj0i1gcxr4"
|
10
|
+
|
11
|
+
LOGFILE = "/home/myuser/dbox.log"
|
12
|
+
LOCAL_PATH = "/home/myuser/dropbox"
|
13
|
+
REMOTE_PATH = "/stuff/myfolder"
|
14
|
+
INTERVAL = 60 # time between syncs, in seconds
|
15
|
+
|
16
|
+
LOGGER = Logger.new(LOGFILE, 1, 1024000)
|
17
|
+
LOGGER.level = Logger::INFO
|
18
|
+
|
19
|
+
def main
|
20
|
+
while 1
|
21
|
+
begin
|
22
|
+
sync
|
23
|
+
rescue Interrupt => e
|
24
|
+
exit 0
|
25
|
+
rescue Exception => e
|
26
|
+
LOGGER.error e
|
27
|
+
end
|
28
|
+
sleep INTERVAL
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def sync
|
33
|
+
unless Dbox.exists?(LOCAL_PATH)
|
34
|
+
LOGGER.info "Cloning"
|
35
|
+
Dbox.clone(REMOTE_PATH, LOCAL_PATH)
|
36
|
+
LOGGER.info "Done"
|
37
|
+
else
|
38
|
+
LOGGER.info "Syncing"
|
39
|
+
Dbox.push(LOCAL_PATH)
|
40
|
+
Dbox.pull(LOCAL_PATH)
|
41
|
+
LOGGER.info "Done"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
main
|
data/spec/dbox_spec.rb
CHANGED
@@ -22,10 +22,15 @@ describe Dbox do
|
|
22
22
|
|
23
23
|
describe "#create" do
|
24
24
|
it "creates the local directory" do
|
25
|
-
Dbox.create(@remote, @local)
|
25
|
+
Dbox.create(@remote, @local).should eql(:created => [], :deleted => [], :updated => [""])
|
26
26
|
@local.should exist
|
27
27
|
end
|
28
28
|
|
29
|
+
it "creates the remote directory" do
|
30
|
+
Dbox.create(@remote, @local).should eql(:created => [], :deleted => [], :updated => [""])
|
31
|
+
ensure_remote_exists(@remote)
|
32
|
+
end
|
33
|
+
|
29
34
|
it "should fail if the remote already exists" do
|
30
35
|
Dbox.create(@remote, @local)
|
31
36
|
rm_rf @local
|
@@ -39,7 +44,7 @@ describe Dbox do
|
|
39
44
|
Dbox.create(@remote, @local)
|
40
45
|
rm_rf @local
|
41
46
|
@local.should_not exist
|
42
|
-
Dbox.clone(@remote, @local)
|
47
|
+
Dbox.clone(@remote, @local).should eql(:created => [], :deleted => [], :updated => [""])
|
43
48
|
@local.should exist
|
44
49
|
end
|
45
50
|
|
@@ -51,12 +56,13 @@ describe Dbox do
|
|
51
56
|
|
52
57
|
describe "#pull" do
|
53
58
|
it "should fail if the local dir is missing" do
|
54
|
-
expect { Dbox.pull(@local) }.to raise_error(Dbox::
|
59
|
+
expect { Dbox.pull(@local) }.to raise_error(Dbox::DatabaseError)
|
55
60
|
end
|
56
61
|
|
57
62
|
it "should fail if the remote dir is missing" do
|
58
63
|
Dbox.create(@remote, @local)
|
59
|
-
|
64
|
+
db = Dbox::Database.load(@local)
|
65
|
+
db.update_metadata(:remote_path => "/" + randname())
|
60
66
|
expect { Dbox.pull(@local) }.to raise_error(Dbox::RemoteMissing)
|
61
67
|
end
|
62
68
|
|
@@ -74,7 +80,7 @@ describe Dbox do
|
|
74
80
|
touch "#{@alternate}/hello.txt"
|
75
81
|
Dbox.push(@alternate).should eql(:created => ["hello.txt"], :deleted => [], :updated => [])
|
76
82
|
|
77
|
-
Dbox.pull(@local).should eql(:created => ["hello.txt"], :deleted => [], :updated => [])
|
83
|
+
Dbox.pull(@local).should eql(:created => ["hello.txt"], :deleted => [], :updated => [""])
|
78
84
|
"#{@local}/hello.txt".should exist
|
79
85
|
end
|
80
86
|
|
@@ -83,7 +89,7 @@ describe Dbox do
|
|
83
89
|
touch "#{@local}/hello.txt"
|
84
90
|
Dbox.push(@local).should eql(:created => ["hello.txt"], :deleted => [], :updated => [])
|
85
91
|
rm "#{@local}/hello.txt"
|
86
|
-
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [])
|
92
|
+
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [""])
|
87
93
|
"#{@local}/hello.txt".should_not exist
|
88
94
|
end
|
89
95
|
|
@@ -99,23 +105,28 @@ describe Dbox do
|
|
99
105
|
touch "#{@alternate}/bar.txt"
|
100
106
|
touch "#{@alternate}/baz.txt"
|
101
107
|
Dbox.push(@alternate).should eql(:created => ["bar.txt", "baz.txt", "foo.txt"], :deleted => [], :updated => [])
|
108
|
+
Dbox.pull(@alternate).should eql(:created => [], :deleted => [], :updated => [""])
|
109
|
+
Dbox.pull(@alternate).should eql(:created => [], :deleted => [], :updated => [])
|
102
110
|
|
103
|
-
Dbox.pull(@local).should eql(:created => ["bar.txt", "baz.txt", "foo.txt"], :deleted => [], :updated => [])
|
111
|
+
Dbox.pull(@local).should eql(:created => ["bar.txt", "baz.txt", "foo.txt"], :deleted => [], :updated => [""])
|
112
|
+
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [])
|
104
113
|
|
105
|
-
sleep 1
|
106
114
|
mkdir "#{@alternate}/subdir"
|
107
115
|
touch "#{@alternate}/subdir/one.txt"
|
108
116
|
rm "#{@alternate}/foo.txt"
|
109
117
|
File.open("#{@alternate}/baz.txt", "w") {|f| f << "baaz" }
|
110
118
|
Dbox.push(@alternate).should eql(:created => ["subdir", "subdir/one.txt"], :deleted => ["foo.txt"], :updated => ["baz.txt"])
|
119
|
+
Dbox.pull(@alternate).should eql(:created => [], :deleted => [], :updated => ["", "subdir"])
|
120
|
+
Dbox.pull(@alternate).should eql(:created => [], :deleted => [], :updated => [])
|
111
121
|
|
112
|
-
Dbox.pull(@local).should eql(:created => ["subdir", "subdir/one.txt"], :deleted => ["foo.txt"], :updated => ["baz.txt"])
|
122
|
+
Dbox.pull(@local).should eql(:created => ["subdir", "subdir/one.txt"], :deleted => ["foo.txt"], :updated => ["", "baz.txt"])
|
123
|
+
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [])
|
113
124
|
end
|
114
125
|
end
|
115
126
|
|
116
127
|
describe "#push" do
|
117
128
|
it "should fail if the local dir is missing" do
|
118
|
-
expect { Dbox.push(@local) }.to raise_error(Dbox::
|
129
|
+
expect { Dbox.push(@local) }.to raise_error(Dbox::DatabaseError)
|
119
130
|
end
|
120
131
|
|
121
132
|
it "should be able to push" do
|
@@ -123,50 +134,64 @@ describe Dbox do
|
|
123
134
|
Dbox.push(@local).should eql(:created => [], :deleted => [], :updated => [])
|
124
135
|
end
|
125
136
|
|
126
|
-
it "should be able to push new file" do
|
137
|
+
it "should be able to push a new file" do
|
127
138
|
Dbox.create(@remote, @local)
|
128
139
|
touch "#{@local}/foo.txt"
|
129
140
|
Dbox.push(@local).should eql(:created => ["foo.txt"], :deleted => [], :updated => [])
|
130
141
|
end
|
131
142
|
|
132
|
-
it "should
|
143
|
+
it "should be able to push a new dir" do
|
133
144
|
Dbox.create(@remote, @local)
|
134
|
-
|
135
|
-
@
|
136
|
-
@new_remote = File.join(REMOTE_TEST_PATH, @new_name)
|
137
|
-
modify_dbfile {|s| s.sub(/^remote_path: \/.*$/, "remote_path: #{@new_remote}") }
|
138
|
-
Dbox.push(@local).should eql(:created => ["foo.txt"], :deleted => [], :updated => [])
|
145
|
+
mkdir "#{@local}/subdir"
|
146
|
+
Dbox.push(@local).should eql(:created => ["subdir"], :deleted => [], :updated => [])
|
139
147
|
end
|
140
148
|
|
141
|
-
it "should be able to push
|
149
|
+
it "should be able to push a new dir with a file in it" do
|
142
150
|
Dbox.create(@remote, @local)
|
143
151
|
mkdir "#{@local}/subdir"
|
144
152
|
touch "#{@local}/subdir/foo.txt"
|
145
153
|
Dbox.push(@local).should eql(:created => ["subdir", "subdir/foo.txt"], :deleted => [], :updated => [])
|
146
154
|
end
|
147
155
|
|
156
|
+
it "should be able to push a new file in an existing dir" do
|
157
|
+
Dbox.create(@remote, @local)
|
158
|
+
mkdir "#{@local}/subdir"
|
159
|
+
Dbox.push(@local)
|
160
|
+
touch "#{@local}/subdir/foo.txt"
|
161
|
+
Dbox.push(@local).should eql(:created => ["subdir/foo.txt"], :deleted => [], :updated => [])
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should create the remote dir if it is missing" do
|
165
|
+
Dbox.create(@remote, @local)
|
166
|
+
touch "#{@local}/foo.txt"
|
167
|
+
@new_name = randname()
|
168
|
+
@new_remote = File.join(REMOTE_TEST_PATH, @new_name)
|
169
|
+
db = Dbox::Database.load(@local)
|
170
|
+
db.update_metadata(:remote_path => @new_remote)
|
171
|
+
Dbox.push(@local).should eql(:created => ["foo.txt"], :deleted => [], :updated => [])
|
172
|
+
end
|
173
|
+
|
148
174
|
it "should not re-download the file after creating" do
|
149
175
|
Dbox.create(@remote, @local)
|
150
176
|
touch "#{@local}/foo.txt"
|
151
177
|
Dbox.push(@local).should eql(:created => ["foo.txt"], :deleted => [], :updated => [])
|
152
|
-
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [])
|
178
|
+
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [""])
|
153
179
|
end
|
154
180
|
|
155
181
|
it "should not re-download the file after updating" do
|
156
182
|
Dbox.create(@remote, @local)
|
157
183
|
touch "#{@local}/foo.txt"
|
158
184
|
Dbox.push(@local).should eql(:created => ["foo.txt"], :deleted => [], :updated => [])
|
159
|
-
sleep 1
|
160
185
|
File.open("#{@local}/foo.txt", "w") {|f| f << "fooz" }
|
161
186
|
Dbox.push(@local).should eql(:created => [], :deleted => [], :updated => ["foo.txt"])
|
162
|
-
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [])
|
187
|
+
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [""])
|
163
188
|
end
|
164
189
|
|
165
190
|
it "should not re-download the dir after creating" do
|
166
191
|
Dbox.create(@remote, @local)
|
167
192
|
mkdir "#{@local}/subdir"
|
168
193
|
Dbox.push(@local).should eql(:created => ["subdir"], :deleted => [], :updated => [])
|
169
|
-
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [])
|
194
|
+
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [""])
|
170
195
|
end
|
171
196
|
|
172
197
|
it "should handle a complex set of changes" do
|
@@ -175,13 +200,12 @@ describe Dbox do
|
|
175
200
|
touch "#{@local}/bar.txt"
|
176
201
|
touch "#{@local}/baz.txt"
|
177
202
|
Dbox.push(@local).should eql(:created => ["bar.txt", "baz.txt", "foo.txt"], :deleted => [], :updated => [])
|
178
|
-
sleep 1
|
179
203
|
mkdir "#{@local}/subdir"
|
180
204
|
touch "#{@local}/subdir/one.txt"
|
181
205
|
rm "#{@local}/foo.txt"
|
182
206
|
touch "#{@local}/baz.txt"
|
183
207
|
Dbox.push(@local).should eql(:created => ["subdir", "subdir/one.txt"], :deleted => ["foo.txt"], :updated => ["baz.txt"])
|
184
|
-
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [])
|
208
|
+
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => ["", "subdir"])
|
185
209
|
end
|
186
210
|
|
187
211
|
it "should be able to handle crazy filenames" do
|
@@ -192,17 +216,17 @@ describe Dbox do
|
|
192
216
|
touch "#{@local}/#{crazy_name2}"
|
193
217
|
Dbox.push(@local).should eql(:created => [crazy_name1, crazy_name2], :deleted => [], :updated => [])
|
194
218
|
rm_rf @local
|
195
|
-
Dbox.clone(@remote, @local).should eql(:created => [crazy_name1, crazy_name2], :deleted => [], :updated => [])
|
219
|
+
Dbox.clone(@remote, @local).should eql(:created => [crazy_name1, crazy_name2], :deleted => [], :updated => [""])
|
196
220
|
end
|
197
221
|
|
198
|
-
it "should be able to handle directory names" do
|
222
|
+
it "should be able to handle crazy directory names" do
|
199
223
|
Dbox.create(@remote, @local)
|
200
224
|
crazy_name1 = "Day[J] #42"
|
201
225
|
mkdir File.join(@local, crazy_name1)
|
202
226
|
touch File.join(@local, crazy_name1, "foo.txt")
|
203
227
|
Dbox.push(@local).should eql(:created => [crazy_name1, File.join(crazy_name1, "foo.txt")], :deleted => [], :updated => [])
|
204
228
|
rm_rf @local
|
205
|
-
Dbox.clone(@remote, @local).should eql(:created => [crazy_name1, File.join(crazy_name1, "foo.txt")], :deleted => [], :updated => [])
|
229
|
+
Dbox.clone(@remote, @local).should eql(:created => [crazy_name1, File.join(crazy_name1, "foo.txt")], :deleted => [], :updated => [""])
|
206
230
|
end
|
207
231
|
end
|
208
232
|
|
@@ -214,7 +238,7 @@ describe Dbox do
|
|
214
238
|
end
|
215
239
|
|
216
240
|
it "should fail if the local dir is missing" do
|
217
|
-
expect { Dbox.move(@new_remote, @local) }.to raise_error(Dbox::
|
241
|
+
expect { Dbox.move(@new_remote, @local) }.to raise_error(Dbox::DatabaseError)
|
218
242
|
end
|
219
243
|
|
220
244
|
it "should be able to move" do
|
@@ -242,10 +266,38 @@ describe Dbox do
|
|
242
266
|
Dbox.exists?(@local).should be_true
|
243
267
|
end
|
244
268
|
|
245
|
-
it "should be false if the dir exists but is missing a .
|
269
|
+
it "should be false if the dir exists but is missing a .dbox.sqlite3 file" do
|
246
270
|
Dbox.create(@remote, @local)
|
247
|
-
rm "#{@local}/.
|
271
|
+
rm "#{@local}/.dbox.sqlite3"
|
248
272
|
Dbox.exists?(@local).should be_false
|
249
273
|
end
|
250
274
|
end
|
275
|
+
|
276
|
+
describe "misc" do
|
277
|
+
it "should be able to recreate a dir after deleting it" do
|
278
|
+
Dbox.create(@remote, @local)
|
279
|
+
|
280
|
+
@alternate = "#{ALTERNATE_LOCAL_TEST_PATH}/#{@name}"
|
281
|
+
Dbox.clone(@remote, @alternate)
|
282
|
+
|
283
|
+
Dbox.pull(@local).should eql(:created => [], :deleted => [], :updated => [])
|
284
|
+
|
285
|
+
mkdir "#{@local}/subdir"
|
286
|
+
touch "#{@local}/subdir/one.txt"
|
287
|
+
Dbox.push(@local).should eql(:created => ["subdir", "subdir/one.txt"], :deleted => [], :updated => [])
|
288
|
+
|
289
|
+
Dbox.pull(@alternate).should eql(:created => ["subdir", "subdir/one.txt"], :deleted => [], :updated => [""])
|
290
|
+
|
291
|
+
rm_rf "#{@alternate}/subdir"
|
292
|
+
Dbox.push(@alternate).should eql(:created => [], :deleted => ["subdir"], :updated => [])
|
293
|
+
|
294
|
+
Dbox.pull(@local).should eql(:created => [], :deleted => ["subdir"], :updated => [""])
|
295
|
+
|
296
|
+
mkdir "#{@local}/subdir"
|
297
|
+
touch "#{@local}/subdir/one.txt"
|
298
|
+
Dbox.push(@local).should eql(:created => ["subdir", "subdir/one.txt"], :deleted => [], :updated => [])
|
299
|
+
|
300
|
+
Dbox.pull(@alternate).should eql(:created => ["subdir", "subdir/one.txt"], :deleted => [], :updated => [""])
|
301
|
+
end
|
302
|
+
end
|
251
303
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -24,17 +24,14 @@ def randname
|
|
24
24
|
"test-#{u}"
|
25
25
|
end
|
26
26
|
|
27
|
-
def modify_dbfile
|
28
|
-
dbfile = File.join(@local, Dbox::DB::DB_FILE)
|
29
|
-
s = File.open(dbfile, "r").read
|
30
|
-
s = yield s
|
31
|
-
File.open(dbfile, "w") {|f| f << s }
|
32
|
-
end
|
33
|
-
|
34
27
|
def clear_test_log
|
35
28
|
File.open(LOGFILE, "w") {|f| f << "" }
|
36
29
|
end
|
37
30
|
|
31
|
+
def ensure_remote_exists(path)
|
32
|
+
expect { Dbox::Syncer.api.metadata(path) }.to_not raise_error
|
33
|
+
end
|
34
|
+
|
38
35
|
def log
|
39
36
|
LOGGER
|
40
37
|
end
|
@@ -85,6 +85,7 @@ class DropboxError < RuntimeError
|
|
85
85
|
end
|
86
86
|
|
87
87
|
class DropboxClient
|
88
|
+
attr_reader :token
|
88
89
|
|
89
90
|
def initialize(api_host, content_host, port, auth)
|
90
91
|
@api_host = api_host
|
@@ -94,6 +95,12 @@ class DropboxClient
|
|
94
95
|
@token = auth.get_access_token
|
95
96
|
end
|
96
97
|
|
98
|
+
def initialize_copy(other)
|
99
|
+
@token = other.token.clone()
|
100
|
+
@token.consumer = @token.consumer.clone()
|
101
|
+
@token.consumer.http = nil
|
102
|
+
end
|
103
|
+
|
97
104
|
def parse_response(response, callback=nil)
|
98
105
|
if response.kind_of?(Net::HTTPServerError)
|
99
106
|
raise DropboxError.new("Invalid response #{response}\n#{response.body}")
|
@@ -141,10 +148,36 @@ class DropboxClient
|
|
141
148
|
end
|
142
149
|
end
|
143
150
|
|
144
|
-
def get_file(root, from_path)
|
151
|
+
def get_file(root, from_path, destination_io=nil)
|
145
152
|
path = "/files/#{root}#{from_path}"
|
146
|
-
|
147
|
-
|
153
|
+
|
154
|
+
if destination_io
|
155
|
+
url = URI.parse(build_url(@content_host, @port, path))
|
156
|
+
|
157
|
+
# if a destination is given, stream the response into it
|
158
|
+
Net::HTTP.start(url.host, url.port) do |http|
|
159
|
+
# build the request
|
160
|
+
req = Net::HTTP::Get.new(url.path, {})
|
161
|
+
auth = @auth.clone(@content_host)
|
162
|
+
auth.sign(req)
|
163
|
+
|
164
|
+
# make the request
|
165
|
+
http.request(req) do |response|
|
166
|
+
if response.kind_of?(Net::HTTPServerError)
|
167
|
+
raise DropboxError.new("Invalid response #{response}\n#{response.body}")
|
168
|
+
elsif not response.kind_of?(Net::HTTPSuccess)
|
169
|
+
return response
|
170
|
+
else
|
171
|
+
# stream to given io
|
172
|
+
response.read_body {|segment| destination_io << segment }
|
173
|
+
return true
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
else
|
178
|
+
response = @token.get(build_url(@content_host, @port, path))
|
179
|
+
return parse_response(response, true)
|
180
|
+
end
|
148
181
|
end
|
149
182
|
|
150
183
|
def file_copy(root, from_path, to_path, callback=nil)
|
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: 11
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 5
|
9
|
+
- 0
|
10
|
+
version: 0.5.0
|
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: 2011-
|
18
|
+
date: 2011-09-19 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: multipart-post
|
@@ -65,6 +65,38 @@ dependencies:
|
|
65
65
|
version: 1.5.3
|
66
66
|
type: :runtime
|
67
67
|
version_requirements: *id003
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: sqlite3
|
70
|
+
prerelease: false
|
71
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
hash: 29
|
77
|
+
segments:
|
78
|
+
- 1
|
79
|
+
- 3
|
80
|
+
- 3
|
81
|
+
version: 1.3.3
|
82
|
+
type: :runtime
|
83
|
+
version_requirements: *id004
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: activesupport
|
86
|
+
prerelease: false
|
87
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
hash: 5
|
93
|
+
segments:
|
94
|
+
- 3
|
95
|
+
- 0
|
96
|
+
- 1
|
97
|
+
version: 3.0.1
|
98
|
+
type: :runtime
|
99
|
+
version_requirements: *id005
|
68
100
|
description: An easy-to-use Dropbox client with fine-grained control over syncs.
|
69
101
|
email: ken@kenpratt.net
|
70
102
|
executables:
|
@@ -85,8 +117,12 @@ files:
|
|
85
117
|
- dbox.gemspec
|
86
118
|
- lib/dbox.rb
|
87
119
|
- lib/dbox/api.rb
|
120
|
+
- lib/dbox/database.rb
|
88
121
|
- lib/dbox/db.rb
|
89
122
|
- lib/dbox/loggable.rb
|
123
|
+
- lib/dbox/parallel_tasks.rb
|
124
|
+
- lib/dbox/syncer.rb
|
125
|
+
- sample_polling_script.rb
|
90
126
|
- spec/dbox_spec.rb
|
91
127
|
- spec/spec_helper.rb
|
92
128
|
- vendor/dropbox-client-ruby/LICENSE
|
@@ -127,7 +163,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
127
163
|
requirements: []
|
128
164
|
|
129
165
|
rubyforge_project:
|
130
|
-
rubygems_version: 1.8.
|
166
|
+
rubygems_version: 1.8.5
|
131
167
|
signing_key:
|
132
168
|
specification_version: 3
|
133
169
|
summary: Dropbox made easy.
|