dbox 0.4.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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::MissingDatabase)
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
- modify_dbfile {|s| s.sub(/^remote_path: \/.*$/, "remote_path: /#{randname()}") }
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::MissingDatabase)
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 create the remote dir if it is missing" do
143
+ it "should be able to push a new dir" do
133
144
  Dbox.create(@remote, @local)
134
- touch "#{@local}/foo.txt"
135
- @new_name = randname()
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 nested content" do
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::MissingDatabase)
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 .dropbox.db file" do
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}/.dropbox.db"
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
@@ -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
@@ -1,3 +1,5 @@
1
+ Forked from Ruby client at https://www.dropbox.com/developers/releases
2
+
1
3
  Getting started with the Dropbox ruby library:
2
4
  1. Make sure you have rake and rubygems installed on your system.
3
5
  1b. Some of the gems below may need to be compiled locally, so make sure you
@@ -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
- response = @token.get(build_url(@content_host, @port, path))
147
- return parse_response(response, callback=true)
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: 7
4
+ hash: 11
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 4
9
- - 4
10
- version: 0.4.4
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-06-28 00:00:00 Z
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.1
166
+ rubygems_version: 1.8.5
131
167
  signing_key:
132
168
  specification_version: 3
133
169
  summary: Dropbox made easy.