Class: Dbox::DB::DropboxDir
Instance Attribute Summary collapse
Attributes inherited from DropboxBlob
#modified_at, #path, #revision
Instance Method Summary
collapse
Methods inherited from DropboxBlob
#api, #create, #delete, #force_metadata_update_from_server, #local_path, #modified?, #parse_time, #remote_path, #saving_parent_timestamp, #smart_new, #time_to_s, #update, #update_file_timestamp, #update_modification_info
Methods included from Loggable
included, #log
Constructor Details
#initialize(db, res) ⇒ DropboxDir
Returns a new instance of DropboxDir.
290
291
292
293
294
|
# File 'lib/dbox/db.rb', line 290
def initialize(db, res)
@contents_hash = nil
@contents = {}
super(db, res)
end
|
Instance Attribute Details
#contents ⇒ Object
Returns the value of attribute contents.
288
289
290
|
# File 'lib/dbox/db.rb', line 288
def contents
@contents
end
|
#contents_hash ⇒ Object
Returns the value of attribute contents_hash.
288
289
290
|
# File 'lib/dbox/db.rb', line 288
def contents_hash
@contents_hash
end
|
Instance Method Details
#calculate_changes(res) ⇒ Object
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
|
# File 'lib/dbox/db.rb', line 334
def calculate_changes(res)
raise(ArgumentError, "Not a directory: #{res.inspect}") unless res["is_dir"]
if @contents_hash && res["hash"] && @contents_hash == res["hash"]
[]
elsif res["contents"]
out = []
got_paths = []
remove_dotfiles(res["contents"]).each do |c|
p = @db.remote_to_relative_path(c["path"])
c["rel_path"] = p
got_paths << p
if @contents.has_key?(p)
if @contents[p].modified?(c)
out << [:update, c]
end
else
out << [:create, c]
end
end
out += (@contents.keys.sort - got_paths.sort).map {|p| [:delete, { "rel_path" => p }] }
out
else
raise(RuntimeError, "Trying to calculate dir changes without any contents")
end
end
|
#create_local ⇒ Object
430
431
432
433
434
435
436
|
# File 'lib/dbox/db.rb', line 430
def create_local
log.info "Creating #{local_path}"
saving_parent_timestamp do
FileUtils.mkdir_p(local_path)
update_file_timestamp
end
end
|
#create_remote ⇒ Object
449
450
451
452
|
# File 'lib/dbox/db.rb', line 449
def create_remote
api.create_dir(remote_path)
force_metadata_update_from_server
end
|
#delete_local ⇒ Object
438
439
440
441
442
443
|
# File 'lib/dbox/db.rb', line 438
def delete_local
log.info "Deleting #{local_path}"
saving_parent_timestamp do
FileUtils.rm_r(local_path)
end
end
|
#delete_remote ⇒ Object
454
455
456
|
# File 'lib/dbox/db.rb', line 454
def delete_remote
api.delete_dir(remote_path)
end
|
#dir? ⇒ Boolean
426
427
428
|
# File 'lib/dbox/db.rb', line 426
def dir?
true
end
|
#execute_changes(changes, direction) ⇒ Object
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
|
# File 'lib/dbox/db.rb', line 366
def execute_changes(changes, direction)
log.debug "executing changes: #{changes.inspect}"
changelist = { :created => [], :deleted => [], :updated => [] }
changes.each do |op, c|
case op
when :create
e = smart_new(c)
e.create(direction)
@contents[e.path] = e
changelist[:created] << e.path
when :update
e = @contents[c["rel_path"]]
e.update_modification_info(c) if direction == :down
e.update(direction)
changelist[:updated] << e.path
when :delete
e = @contents[c["rel_path"]]
e.delete(direction)
@contents.delete(e.path)
changelist[:deleted] << e.path
else
raise(RuntimeError, "Unknown operation type: #{op}")
end
@db.save
end
changelist.keys.each {|k| changelist[k].sort! }
changelist
end
|
#gather_local_info(rel, list_contents = true) ⇒ Object
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
|
# File 'lib/dbox/db.rb', line 399
def gather_local_info(rel, list_contents=true)
full = @db.relative_to_local_path(rel)
remote = @db.relative_to_remote_path(rel)
attrs = {
"path" => remote,
"is_dir" => File.directory?(full),
"modified" => File.mtime(full),
"revision" => @contents[rel] ? @contents[rel].revision : nil
}
if attrs["is_dir"] && list_contents
contents = Dir.entries(full).reject {|s| s == "." || s == ".." }
attrs["contents"] = contents.map do |s|
p = File.join(full, s)
r = @db.local_to_relative_path(p)
gather_local_info(r, false)
end
end
attrs
end
|
#merge_changelists(old, new) ⇒ Object
395
396
397
|
# File 'lib/dbox/db.rb', line 395
def merge_changelists(old, new)
old.merge(new) {|k, v1, v2| (v1 + v2).sort }
end
|
#print ⇒ Object
466
467
468
469
470
471
472
473
|
# File 'lib/dbox/db.rb', line 466
def print
puts
puts "#{path} (v#{@revision}, #{@modified_at})"
contents.each do |path, c|
puts " #{c.path} (v#{c.revision}, #{c.modified_at})"
end
puts
end
|
#pull ⇒ Object
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
|
# File 'lib/dbox/db.rb', line 296
def pull
res = api.metadata(remote_path)
changes = calculate_changes(res)
changelist = execute_changes(changes, :down)
changelist = subdirs.inject(changelist) {|c, d| merge_changelists(c, d.pull) }
update_modification_info(res)
@db.save
changelist
end
|
#push ⇒ Object
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
|
# File 'lib/dbox/db.rb', line 315
def push
res = gather_local_info(@path)
changes = calculate_changes(res)
changelist = execute_changes(changes, :up)
changelist = subdirs.inject(changelist) {|c, d| merge_changelists(c, d.push) }
update_modification_info(res)
@db.save
changelist
end
|
#remove_dotfiles(contents) ⇒ Object
422
423
424
|
# File 'lib/dbox/db.rb', line 422
def remove_dotfiles(contents)
contents.reject {|c| File.basename(c["path"]).start_with?(".") }
end
|
#subdirs ⇒ Object
462
463
464
|
# File 'lib/dbox/db.rb', line 462
def subdirs
@contents.values.select {|c| c.dir? }
end
|
#update_local ⇒ Object
445
446
447
|
# File 'lib/dbox/db.rb', line 445
def update_local
update_file_timestamp
end
|
#update_remote ⇒ Object
458
459
460
|
# File 'lib/dbox/db.rb', line 458
def update_remote
end
|