Class: Mclone::Task

Inherits:
Object
  • Object
show all
Defined in:
lib/mclone.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

CRYPTER_MODES =
%i[encrypt decrypt].freeze
MODES =
%i[update synchronize copy move].freeze
@@crypter_tokens =
{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(session, mode, source_id, source_root, destination_id, destination_root, include: nil, exclude: nil, crypter_mode: nil, crypter_token: nil, crypter_password: nil) ⇒ Task

Returns a new instance of Task.



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/mclone.rb', line 202

def initialize(session, mode, source_id, source_root, destination_id, destination_root, include: nil, exclude: nil, crypter_mode: nil, crypter_token: nil, crypter_password: nil)
  @touch = false # Indicates that the time stamp should be updated whenever state of self is altered
  @session = session
  @id = SecureRandom.hex(4)
  @source_id = source_id
  @destination_id = destination_id
  @source_root = source_root
  @destination_root = destination_root
  self.mode = mode
  self.include = include
  self.exclude = exclude
  set_crypter_mode crypter_mode
  unless crypter_mode.nil?
    raise(Task::Error, %(either Rclone crypt token or plain text password is expected, not both)) if !crypter_token.nil? && !crypter_password.nil?
    @assigned_token = register_crypter_token crypter_token
    @assigned_password = crypter_password
  end
ensure
  @touch = true
  touch!
end

Instance Attribute Details

#crypter_modeObject (readonly)

Returns the value of attribute crypter_mode.



184
185
186
# File 'lib/mclone.rb', line 184

def crypter_mode
  @crypter_mode
end

#destination_idObject (readonly)

Returns the value of attribute destination_id.



169
170
171
# File 'lib/mclone.rb', line 169

def destination_id
  @destination_id
end

#destination_rootObject (readonly)

Returns the value of attribute destination_root.



172
173
174
# File 'lib/mclone.rb', line 172

def destination_root
  @destination_root
end

#excludeObject

Returns the value of attribute exclude.



181
182
183
# File 'lib/mclone.rb', line 181

def exclude
  @exclude
end

#idObject (readonly)

Returns the value of attribute id.



166
167
168
# File 'lib/mclone.rb', line 166

def id
  @id
end

#includeObject

Returns the value of attribute include.



181
182
183
# File 'lib/mclone.rb', line 181

def include
  @include
end

#modeObject

Returns the value of attribute mode.



178
179
180
# File 'lib/mclone.rb', line 178

def mode
  @mode
end

#mtimeObject (readonly)

Returns the value of attribute mtime.



175
176
177
# File 'lib/mclone.rb', line 175

def mtime
  @mtime
end

#source_idObject (readonly)

Returns the value of attribute source_id.



169
170
171
# File 'lib/mclone.rb', line 169

def source_id
  @source_id
end

#source_rootObject (readonly)

Returns the value of attribute source_root.



172
173
174
# File 'lib/mclone.rb', line 172

def source_root
  @source_root
end

Class Method Details

.restore(session, hash) ⇒ Object



285
286
287
288
289
# File 'lib/mclone.rb', line 285

def self.restore(session, hash)
  obj = allocate
  obj.send(:from_h, session, hash)
  obj
end

Instance Method Details

#crypter_tokenObject

Lazily determine the crypt token from either assigned values or the token repository



240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/mclone.rb', line 240

def crypter_token
  # Locally assigned token takes precedence over the repository's
  unless @assigned_token.nil?
    @@crypter_tokens[id] = @assigned_token unless @@crypter_tokens[id].nil? # Assign repository entry with this local token if not yet assigned
    @assigned_token
  else
    if @@crypter_tokens[id].nil?
      # If token is neither locally assigned nor in repository, try to construct it from the user-supplied password
      # If a user-supplied password is omitted, create a new randomly generated password
      args = [Mclone.rclone, 'obscure', @assigned_password.nil? ? SecureRandom.alphanumeric(16) : @assigned_password]
      $stdout << args.collect(&:escape).join(' ') << "\n" if @session.verbose?
      stdout, status = Open3.capture2(*args)
      raise(Task::Error, %(Rclone execution failure)) unless status.success?
      @@crypter_tokens[id] = stdout.strip
    else
      @@crypter_tokens[id]
    end
  end
end

#eql?(other) ⇒ Boolean Also known as: ==

Returns:

  • (Boolean)


190
191
192
193
194
195
196
197
# File 'lib/mclone.rb', line 190

def eql?(other)
  equal?(other) || (
    source_id == other.source_id &&
    destination_id == other.destination_id &&
    source_root == other.source_root &&
    destination_root == other.destination_root
  )
end

#hashObject



186
187
188
# File 'lib/mclone.rb', line 186

def hash
  @hash ||= source_id.hash ^ destination_id.hash ^ source_root.hash ^ destination_root.hash
end

#to_h(volume) ⇒ Object



311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/mclone.rb', line 311

def to_h(volume)
  hash = {
    task: id,
    mode: mode,
    mtime: mtime,
    source: { volume: source_id },
    destination: { volume: destination_id }
  }
  hash[:source][:root] = source_root unless source_root.nil? || source_root.empty?
  hash[:destination][:root] = destination_root unless destination_root.nil? || destination_root.empty?
  hash[:include] = include unless include.nil?
  hash[:exclude] = exclude unless exclude.nil?
  unless crypter_mode.nil?
    crypter = hash[:crypter] = { mode: crypter_mode }
    # Make sure the token won't get into the encrypted volume's task
    crypter[:token] = crypter_token if (crypter_mode == :encrypt && source_id == volume.id) || (crypter_mode == :decrypt && destination_id == volume.id)
  end
  hash
end

#touch!Object



332
333
334
335
# File 'lib/mclone.rb', line 332

def touch!
  @mtime = DateTime.now if @touch
  self
end