class Mclone::Task

Constants

CRYPTER_MODES
MODES

Attributes

crypter_mode[R]
destination_id[R]
destination_root[R]
exclude[R]
id[R]
include[R]
mode[R]
mtime[R]
source_id[R]
source_root[R]

Public Class Methods

new(session, mode, source_id, source_root, destination_id, destination_root, include: nil, exclude: nil, crypter_mode: nil, crypter_token: nil, crypter_password: nil) click to toggle source
# 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
restore(session, hash) click to toggle source
# File lib/mclone.rb, line 285
def self.restore(session, hash)
  obj = allocate
  obj.send(:from_h, session, hash)
  obj
end

Public Instance Methods

==(other)
Alias for: eql?
crypter_token() click to toggle source

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

# 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) click to toggle source
# 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
Also aliased as: ==
exclude=(mask) click to toggle source
# File lib/mclone.rb, line 278
def exclude=(mask)
  @exclude = mask.nil? || mask == '-' ? nil : mask # TODO: verify mask
  touch!
  mask
end
hash() click to toggle source
# File lib/mclone.rb, line 186
def hash
  @hash ||= source_id.hash ^ destination_id.hash ^ source_root.hash ^ destination_root.hash
end
include=(mask) click to toggle source
# File lib/mclone.rb, line 271
def include=(mask)
  @include = mask.nil? || mask == '-' ? nil : mask # TODO: verify mask
  touch!
  mask
end
mode=(mode) click to toggle source
# File lib/mclone.rb, line 264
def mode=(mode)
  @mode = MODES.include?(mode = mode.intern) ? mode : raise(Task::Error, %(unknown mode "#{mode}"))
  touch!
  mode
end
to_h(volume) click to toggle source
# 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!() click to toggle source
# File lib/mclone.rb, line 332
def touch!
  @mtime = DateTime.now if @touch
  self
end

Private Instance Methods

from_h(session, hash) click to toggle source
# File lib/mclone.rb, line 292
        def from_h(session, hash)
  @session = session
  @touch = false
  @id = hash.extract(:task)
  @mtime = DateTime.parse(hash.extract(:mtime)) rescue DateTime.now # Deleting mtime entry from json can be used to modify data out of mclone
  @source_id = hash.extract(:source, :volume)
  @destination_id = hash.extract(:destination, :volume)
  @source_root = hash.dig(:source, :root)
  @destination_root = hash.dig(:destination, :root)
  self.mode = hash.extract(:mode)
  self.include = hash.dig(:include)
  self.exclude = hash.dig(:exclude)
  set_crypter_mode hash.dig(:crypter, :mode)
  @assigned_token = register_crypter_token(hash.dig(:crypter, :token)) unless crypter_mode.nil?
ensure
  @touch = true
end
register_crypter_token(token) click to toggle source
# File lib/mclone.rb, line 232
        def register_crypter_token(token)
  unless token.nil?
    @@crypter_tokens[id] = @@crypter_tokens[id].nil? ? token : raise(Task::Error, %(attempt to re-register token for task "#{id}"))
  end
  token
end
set_crypter_mode(mode) click to toggle source
# File lib/mclone.rb, line 228
        def set_crypter_mode(mode)
  @crypter_mode = mode.nil? ? nil : (CRYPTER_MODES.include?(mode = mode.intern) ? mode : raise(Task::Error, %(unknown crypt mode "#{mode}")))
end