Class: Dbox::Syncer::Operation

Inherits:
Object
  • Object
show all
Includes:
Loggable, Utils
Defined in:
lib/dbox/syncer.rb

Direct Known Subclasses

Pull, Push

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Utils

#calculate_hash, #case_insensitive_difference, #case_insensitive_equal, #case_insensitive_join, #case_insensitive_resolve, #find_nonconflicting_path, #local_to_relative_path, #parse_time, #relative_to_local_path, #relative_to_remote_path, #remote_to_relative_path, #time_to_s, #times_equal?

Methods included from Loggable

included, #log

Constructor Details

#initialize(database, api) ⇒ Operation

Returns a new instance of Operation.



44
45
46
47
# File 'lib/dbox/syncer.rb', line 44

def initialize(database, api)
  @database = database
  @api = api
end

Instance Attribute Details

#databaseObject (readonly)

Returns the value of attribute database.



42
43
44
# File 'lib/dbox/syncer.rb', line 42

def database
  @database
end

Instance Method Details

#apiObject



49
50
51
# File 'lib/dbox/syncer.rb', line 49

def api
  @api
end

#current_dir_entries_as_hash(dir) ⇒ Object



69
70
71
72
73
74
75
76
77
# File 'lib/dbox/syncer.rb', line 69

def current_dir_entries_as_hash(dir)
  if dir[:id]
    out = InsensitiveHash.new
    database.contents(dir[:id]).each {|e| out[e[:path]] = e }
    out
  else
    {}
  end
end

#gather_remote_info(entry) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/dbox/syncer.rb', line 104

def gather_remote_info(entry)
  res = api.(entry[:remote_path], entry[:remote_hash])
  case res
  when Hash
    out = process_basic_remote_props(res)
    out[:id] = entry[:id] if entry[:id]
    if res[:contents]
      out[:contents] = remove_dotfiles(res[:contents]).map do |c|
        o = process_basic_remote_props(c)
        o[:parent_id] = entry[:id] if entry[:id]
        o[:parent_path] = entry[:path]
        o
      end
    end
    out
  when :not_modified
    :not_modified
  else
    raise(RuntimeError, "Invalid result from server: #{res.inspect}")
  end
end

#generate_tmpfilename(path) ⇒ Object



139
140
141
142
143
144
145
146
# File 'lib/dbox/syncer.rb', line 139

def generate_tmpfilename(path)
  out = File.join(local_path, ".#{path.gsub(/\W/, '-')}.part")
  if File.exists?(out)
    generate_tmpfilename("path#{rand(1000)}")
  else
    out
  end
end

#local_pathObject



57
58
59
# File 'lib/dbox/syncer.rb', line 57

def local_path
  [:local_path]
end

#lookup_id_by_path(path) ⇒ Object



79
80
81
82
# File 'lib/dbox/syncer.rb', line 79

def lookup_id_by_path(path)
  @_ids ||= {}
  @_ids[path] ||= database.find_by_path(path)[:id]
end

#metadataObject



53
54
55
# File 'lib/dbox/syncer.rb', line 53

def 
  @_metadata ||= database.
end

#process_basic_remote_props(res) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/dbox/syncer.rb', line 126

def process_basic_remote_props(res)
  out = {}
  out[:path]        = remote_to_relative_path(res[:path])
  out[:local_path]  = relative_to_local_path(out[:path])
  out[:remote_path] = relative_to_remote_path(out[:path])
  out[:modified]    = parse_time(res[:modified])
  out[:is_dir]      = res[:is_dir]
  out[:remote_hash] = res[:hash] if res[:hash]
  out[:revision]    = res[:rev] if res[:rev]
  out[:size]        = res[:bytes] if res[:bytes]
  out
end

#remote_pathObject



61
62
63
# File 'lib/dbox/syncer.rb', line 61

def remote_path
  [:remote_path]
end

#remove_dotfiles(contents) ⇒ Object



65
66
67
# File 'lib/dbox/syncer.rb', line 65

def remove_dotfiles(contents)
  contents.reject {|c| File.basename(c[:path]).start_with?(".") }
end

#remove_tmpfilesObject



148
149
150
# File 'lib/dbox/syncer.rb', line 148

def remove_tmpfiles
  Dir["#{local_path}/.*.part"].each {|f| FileUtils.rm(f) }
end

#saving_parent_timestamp(entry, &proc) ⇒ Object



91
92
93
94
# File 'lib/dbox/syncer.rb', line 91

def saving_parent_timestamp(entry, &proc)
  parent = File.dirname(entry[:local_path])
  saving_timestamp(parent, &proc)
end

#saving_timestamp(path) ⇒ Object



84
85
86
87
88
89
# File 'lib/dbox/syncer.rb', line 84

def saving_timestamp(path)
  mtime = File.mtime(path)
  res = yield
  File.utime(Time.now, mtime, path)
  res
end

#sort_changelist(changelist) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/dbox/syncer.rb', line 152

def sort_changelist(changelist)
  changelist.keys.each do |k|
    case k
    when :conflicts
      changelist[k].sort! {|c1, c2| c1[:original] <=> c2[:original] }
    when :failed
      changelist[k].sort! {|c1, c2| c1[:path] <=> c2[:path] }
    else
      changelist[k].sort!
    end
  end
  changelist
end

#update_file_timestamp(entry) ⇒ Object



96
97
98
99
100
101
102
# File 'lib/dbox/syncer.rb', line 96

def update_file_timestamp(entry)
  begin
    File.utime(Time.now, entry[:modified], entry[:local_path])
  rescue Errno::ENOENT
    nil
  end
end