class Shrine::Storage::Scp

Attributes

directory[R]
host[R]
options[R]
permissions[R]
prefix[R]
ssh_host[R]

Public Class Methods

new(directory:, ssh_host: nil, host: nil, prefix: nil, options: %w[-q], permissions: 0600) click to toggle source
# File lib/shrine/storage/scp.rb, line 11
def initialize(directory:, ssh_host: nil, host: nil, prefix: nil, options: %w[-q], permissions: 0600)
  # Initializes a storage for uploading via scp.
  #
  # :directory
  # :  the path where files will be transferred to
  #
  # :ssh_host
  # :  optional user@hostname for remote scp transfers over ssh
  #
  # :host
  # :  URLs will by default be relative if `:prefix` is set, and you
  #    can use this option to set a CDN host (e.g. `//abc123.cloudfront.net`).
  #
  # :prefix
  # :  The directory relative to `directory` to which files will be stored,
  #    and it is included in the URL.
  #
  # :options
  # :  Additional arguments specific to scp
  #    https://linux.die.net/man/1/scp
  #
  # :permissions
  # :  bit pattern for permissions to set on uploaded files
  #
  @directory   = directory.chomp(File::SEPARATOR)
  @ssh_host    = ssh_host
  @host        = host.chomp(File::SEPARATOR) if host
  @prefix      = prefix.chomp(File::SEPARATOR) if prefix
  @options     = options
  @permissions = permissions
end

Public Instance Methods

clear!() click to toggle source
# File lib/shrine/storage/scp.rb, line 73
def clear!
  file_path = path("*")
  bash "rm -rf #{file_path}"
end
delete(id) click to toggle source
# File lib/shrine/storage/scp.rb, line 68
def delete(id)
  file_path = path(id)
  bash "rm -rf #{file_path}"
end
download(id) click to toggle source
# File lib/shrine/storage/scp.rb, line 49
def download(id)
  file = scp_down(id)
  file
end
exists?(id) click to toggle source
# File lib/shrine/storage/scp.rb, line 59
def exists?(id)
  file_path = File.join(directory, id)
  bash "ls -la #{file_path}"
end
open(id) click to toggle source
# File lib/shrine/storage/scp.rb, line 54
def open(id)
  file = scp_down(id)
  file.tap(&:open)
end
upload(io, id, **) click to toggle source
# File lib/shrine/storage/scp.rb, line 43
def upload(io, id, **)
  file = write_io(io, id)
  scp_up(id, file.path)
  file
end
url(id, **_options) click to toggle source
# File lib/shrine/storage/scp.rb, line 64
def url(id, **_options)
  File.join([host, prefix, id].compact)
end

Private Instance Methods

bash(sh) click to toggle source
# File lib/shrine/storage/scp.rb, line 84
def bash(sh)
  command = "bash -c '#{sh}' > /dev/null 2>&1; echo $?"
  command = "ssh #{ssh_host} \"#{command}\"" if ssh_host
  `#{command}`.chomp == "0"
end
path(id) click to toggle source
# File lib/shrine/storage/scp.rb, line 120
def path(id)
  File.join([directory, prefix, id].compact)
end
scp_bin() click to toggle source
# File lib/shrine/storage/scp.rb, line 110
def scp_bin
  scp_bin = `which scp`.chomp
  raise "scp could not be found." if scp_bin.empty?
  scp_bin
end
scp_down(id) click to toggle source
# File lib/shrine/storage/scp.rb, line 97
def scp_down(id)
  source = path(id)
  source = "#{ssh_host}:#{source}" if ssh_host
  tmp = tempfile!(id)

  tmp if scp_transfer(source: source, destination: tmp.path)
end
scp_options() click to toggle source
# File lib/shrine/storage/scp.rb, line 116
def scp_options
  options.join(" ")
end
scp_transfer(source:, destination:) click to toggle source
# File lib/shrine/storage/scp.rb, line 105
def scp_transfer(source:, destination:)
  command = [scp_bin, scp_options, source, destination].join(" ")
  system command
end
scp_up(id, tmp_path) click to toggle source
# File lib/shrine/storage/scp.rb, line 90
def scp_up(id, tmp_path)
  FileUtils.chmod(permissions, tmp_path)
  destination = path(id)
  destination = "#{ssh_host}:#{destination}" if ssh_host
  scp_transfer(source: tmp_path, destination: destination)
end
ssh?() click to toggle source
# File lib/shrine/storage/scp.rb, line 80
def ssh?
  ssh_host
end
tempfile!(id) click to toggle source
# File lib/shrine/storage/scp.rb, line 124
def tempfile!(id)
  Tempfile.new(["shrine-scp-", File.extname(id)], binmode: true)
end
write_io(io, id) click to toggle source
# File lib/shrine/storage/scp.rb, line 128
def write_io(io, id)
  tmp = tempfile!(id)
  IO.copy_stream(io, tmp)
  tmp.tap(&:open)
  tmp
end