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.
@@ -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.