class BFS::Bucket::FTP

FTP buckets are operating on ftp servers

Attributes

perm[R]

Public Class Methods

new(host, prefix: nil, **opts) click to toggle source

Initializes a new bucket @param [String] host the host name @param [Hash] opts options @option opts [Integer] :port custom port. Default: 21. @option opts [Boolean] :ssl will attempt to use SSL. @option opts [String] :username user name for login. @option opts [String] :password password for login. @option opts [String] :passive connect in passive mode. Default: true. @option opts [String] :prefix optional prefix.

Calls superclass method
# File lib/bfs/bucket/ftp.rb, line 19
def initialize(host, prefix: nil, **opts)
  super(**opts)

  @client = Net::FTP.new(host, **opts)
  @client.binary = true

  if prefix # rubocop:disable Style/GuardClause
    prefix = norm_path(prefix)
    mkdir_p(prefix)
    @client.chdir(prefix)
  end
end

Public Instance Methods

close() click to toggle source

Closes the underlying connection

# File lib/bfs/bucket/ftp.rb, line 87
def close
  @client.close
end
create(path, encoding: self.encoding, perm: self.perm, **_opts, &block) click to toggle source

Creates a new file and opens it for writing

# File lib/bfs/bucket/ftp.rb, line 59
def create(path, encoding: self.encoding, perm: self.perm, **_opts, &block)
  path = norm_path(path)
  BFS::Writer.new(path, encoding: encoding, perm: perm) do |t|
    mkdir_p File.dirname(path)
    @client.put(t, path)
  end.perform(&block)
end
glob(pattern = '**/*', **_opts) click to toggle source

Iterates over the contents of a bucket using a glob pattern

# File lib/bfs/bucket/ftp.rb, line 42
def glob(pattern = '**/*', **_opts)
  Enumerator.new do |y|
    walk(pattern) do |path, entry|
      y << file_info(path, entry) if File.fnmatch?(pattern, path, File::FNM_PATHNAME)
    end
  end
end
info(path, **_opts) click to toggle source

Info returns the object info

# File lib/bfs/bucket/ftp.rb, line 51
def info(path, **_opts)
  path = norm_path(path)
  BFS::FileInfo.new(path: path, size: @client.size(path), mtime: @client.mtime(path))
rescue Net::FTPPermError
  raise BFS::FileNotFound, path
end
ls(pattern = '**/*', **_opts) click to toggle source

Lists the contents of a bucket using a glob pattern

# File lib/bfs/bucket/ftp.rb, line 33
def ls(pattern = '**/*', **_opts)
  Enumerator.new do |y|
    walk(pattern) do |path, _|
      y << path if File.fnmatch?(pattern, path, File::FNM_PATHNAME)
    end
  end
end
open(path, encoding: self.encoding, perm: self.perm, tempdir: nil, **_opts, &block) click to toggle source

Opens an existing file for reading

# File lib/bfs/bucket/ftp.rb, line 68
def open(path, encoding: self.encoding, perm: self.perm, tempdir: nil, **_opts, &block)
  path = norm_path(path)
  temp = Tempfile.new(File.basename(path), tempdir, encoding: encoding, perm: perm)
  temp.close

  @client.get(path, temp.path)
  File.open(temp.path, encoding: encoding, &block)
rescue Net::FTPPermError
  raise BFS::FileNotFound, path
end
rm(path, **_opts) click to toggle source

Deletes a file.

# File lib/bfs/bucket/ftp.rb, line 80
def rm(path, **_opts)
  path = norm_path(path)
  @client.delete(path)
rescue Net::FTPPermError # rubocop:disable Lint/SuppressedException
end

Private Instance Methods

file_info(path, entry) click to toggle source
# File lib/bfs/bucket/ftp.rb, line 93
def file_info(path, entry)
  BFS::FileInfo.new(path: path, size: entry.filesize, mtime: entry.mtime)
end
mkdir_p(path) click to toggle source
# File lib/bfs/bucket/ftp.rb, line 117
def mkdir_p(path)
  parts = path.split('/').reject(&:empty?)
  (0...parts.size).each do |i|
    @client.mkdir parts[0..i].join('/')
  rescue Net::FTPPermError # rubocop:disable Lint/SuppressedException
  end
end
walk(pattern, &block) click to toggle source
# File lib/bfs/bucket/ftp.rb, line 97
def walk(pattern, &block)
  dir = pattern[%r{^[^*?\{\}\[\]]+/}]
  dir&.chomp!('/')
  walk_r(dir, &block)
end
walk_r(dir) { |path, entry| ... } click to toggle source
# File lib/bfs/bucket/ftp.rb, line 103
def walk_r(dir, &block)
  entries = @client.list(dir || '.')
  entries.each do |ent|
    entry = Net::FTP::List.parse(ent)
    if entry.dir?
      subdir = [dir, entry.basename].compact.join('/')
      walk_r(subdir, &block)
    elsif entry.file?
      path = [dir, entry.basename].compact.join('/')
      yield(path, entry)
    end
  end
end