class Paperclip::Storage::Ftp::Server

Attributes

connect_timeout[RW]
connection[R]
host[RW]
ignore_connect_errors[RW]
passive[RW]
password[RW]
port[RW]
user[RW]

Public Class Methods

new(options = {}) click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 15
def initialize(options = {})
  options.each do |k,v|
    send("#{k}=", v)
  end

  @port ||= Net::FTP::FTP_PORT
end

Public Instance Methods

close_connection() click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 42
def close_connection
  connection.close if connected?
end
connected?() click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 46
def connected?
  connection && !connection.closed?
end
delete_file(remote_file_path) click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 86
def delete_file(remote_file_path)
  connection.delete(remote_file_path)
rescue Net::FTPPermError
  # This happens if the file is already deleted
end
directory_tree(file_paths) click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 75
def directory_tree(file_paths)
  directories = file_paths.map do |path|
    Pathname.new(path).dirname.to_s.split("/").reject(&:empty?)
  end
  tree = Hash.new {|h, k| h[k] = Hash.new(&h.default_proc)}
  directories.each do |directory|
    directory.inject(tree){|h,k| h[k]}
  end
  tree
end
establish_connection() click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 23
def establish_connection
  @connection = Net::FTP.new
  @connection.passive = passive

  if ignore_connect_errors
    begin
      connect
    rescue SystemCallError => e
      Paperclip.log("could not connect to ftp://#{user}@#{host}:#{port} (#{e})")
      @connection = nil
      return
    end
  else
    connect
  end

  @connection.login(user, password)
end
file_exists?(path) click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 50
def file_exists?(path)
  pathname = Pathname.new(path)
  connection.nlst(pathname.dirname.to_s).map{|f| File.basename f }.include?(pathname.basename.to_s)
rescue Net::FTPTempError, Net::FTPPermError
  false
end
get_file(remote_file_path, local_file_path) click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 57
def get_file(remote_file_path, local_file_path)
  connection.getbinaryfile(remote_file_path, local_file_path)
end
mktree(tree, base = "/") click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 101
def mktree(tree, base = "/")
  return unless tree.any?

  existing_files =
    begin
      connection.nlst(base)
    rescue Net::FTPError
      []
    end

  tree.reject{|k,_| existing_files.include?(k)}.each do |directory, sub_directories|
    begin
      connection.mkdir(base + directory)
    rescue Net::FTPPermError
      # This error can be caused by an already existing directory,
      # maybe it was created in the meantime.
    end
  end

  tree.each do |directory, sub_directories|
    mktree(sub_directories, base + directory + "/")
  end
end
put_file(local_file_path, remote_file_path) click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 61
def put_file(local_file_path, remote_file_path)
  pathname = Pathname.new(remote_file_path)
  connection.putbinaryfile(local_file_path, remote_file_path)
end
put_files(file_paths) click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 66
def put_files(file_paths)
  tree = directory_tree(file_paths.values)
  mktree(tree)

  file_paths.each do |local_file_path, remote_file_path|
    put_file(local_file_path, remote_file_path)
  end
end
rmdir_p(dir_path) click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 92
def rmdir_p(dir_path)
  while(true)
    connection.rmdir(dir_path)
    dir_path = File.dirname(dir_path)
  end
rescue Net::FTPTempError, Net::FTPPermError
  # Stop trying to remove parent directories
end

Private Instance Methods

connect() click to toggle source
# File lib/paperclip/storage/ftp/server.rb, line 127
def connect
  if connect_timeout
    Timeout.timeout(connect_timeout, Errno::ETIMEDOUT) do
      @connection.connect(host, port)
    end
  else
    @connection.connect(host, port)
  end
end