class FolderStash::FileUsher

FileUsher stores files in a directory tree with a defined maximum number of items per directory.

It will create new subdirectories to store files in if a subdirectory has reached the maximum number of items.

Constants

CURRENT_STORE_PATH

Attributes

directory[R]

The working directory where all subdirectories and files are stored.

tree[R]

An instance of FolderTree.

Public Class Methods

new(dir, **opts) click to toggle source

Returns a new instance.

Arguments
Options
  • nesting_levels - the number of subdirectories below directory in the path of files that are stored (default: 2).

  • folder_limit - the maximum number of items allowed per directory (default: 10000).

  • link_location - the directory where the current_directory symlink is stored. When not specified, the symlink will be in directory

Setting nesting_levels to nil will also set the folder_limit. Conversely, setting folder_limit to nil also set nesting_levels to nil.

# File lib/folder_stash/file_usher.rb, line 36
def initialize(dir, **opts)
  raise Errors::NoDirectoryError, dir: dir unless File.directory? dir

  @options = { nesting_levels: 2, folder_limit: 10_000 }.update(opts)
  @directory = dir
  @current_directory = File.join @options.fetch(:link_location, directory),
                                 CURRENT_STORE_PATH

  @tree = init_existing || init_new(nesting_levels)
  link_target
end

Public Instance Methods

copy(file, new_basename = nil, pathtype: :tree) click to toggle source

Copies file to linked path.

The optional new_basename argument is passed when the file is to be renamed.

# File lib/folder_stash/file_usher.rb, line 52
def copy(file, new_basename = nil, pathtype: :tree)
  filename = new_basename || File.basename(file)
  path = store_path(filename)
  File.open(path, 'wb') { |f| f.write(File.new(file).read) }
  file_path path, pathtype
end
current_directory() click to toggle source

Returns the full path (String) to the current directory symlink.

# File lib/folder_stash/file_usher.rb, line 60
def current_directory
  File.expand_path @current_directory
end
current_path() click to toggle source

Returns the full directory path for current_folder

# File lib/folder_stash/file_usher.rb, line 65
def current_path
  current_folder.path
end
folder_limit() click to toggle source

The number of items allowed in any directory in a nested directory path.

Will be nil if nesting_levels is nil.

# File lib/folder_stash/file_usher.rb, line 72
def folder_limit
  return unless @options.fetch :nesting_levels

  @options.fetch :folder_limit
end
linked_path() click to toggle source

Returns the directory path the current_directory symlink points to.

# File lib/folder_stash/file_usher.rb, line 79
def linked_path
  File.readlink current_directory
end
move(file, new_basename = nil, pathtype: :tree) click to toggle source

Moves file to the linked_path.

The optional new_basename argument is passed when the file is to be renamed.

# File lib/folder_stash/file_usher.rb, line 87
def move(file, new_basename = nil, pathtype: :tree)
  filename = new_basename || File.basename(file)
  path = store_path(filename)
  FileUtils.mv File.expand_path(file), path
  file_path path, pathtype
end
nesting_levels() click to toggle source

The number of nested subdirectories.

# File lib/folder_stash/file_usher.rb, line 95
def nesting_levels
  return unless @options.fetch :folder_limit

  tree&.path_length || @options.fetch(:nesting_levels)
end

Private Instance Methods

available_folder() click to toggle source

Returns the next available folder in tree. Will raise OutOfStorageError if none is available.

# File lib/folder_stash/file_usher.rb, line 105
def available_folder
  folder = tree.available_folder
  raise Errors::TreeLimitExceededError.new(tree: tree) unless folder

  folder
end
current_directory?() click to toggle source

Returns true if the current directory symlink exists in directory.

# File lib/folder_stash/file_usher.rb, line 113
def current_directory?
  File.exist? current_directory
end
current_folder() click to toggle source

Returns a Folder that is currently the FolderTree#terminal.

# File lib/folder_stash/file_usher.rb, line 118
def current_folder
  tree.terminal
end
file_path(path, pathtype) click to toggle source

Returns the path for path as :absolute, :relative, only the nested subdirectories in the :tree, or only the :branch.

# File lib/folder_stash/file_usher.rb, line 124
def file_path(path, pathtype)
  treepath = tree.branch_path.append(File.basename(path))
  case pathtype
  when :absolute
    File.realpath path
  when :relative
    treepath[0] = directory
    treepath.join('/')
  when :branch
    treepath[1..-1].join('/')
  when :tree
    treepath.join('/')
  end
end
init_existing() click to toggle source

Creates the folder tree in an existing directory with current_directory symlink.

# File lib/folder_stash/file_usher.rb, line 141
def init_existing
  return unless current_directory?

  FolderTree.for_path linked_path, root: directory, limit: folder_limit
end
init_new(levels) click to toggle source

Creates the folder tree for a new direcrory without current_directory symlink.

# File lib/folder_stash/file_usher.rb, line 149
def init_new(levels)
  FolderTree.empty directory, levels: levels, limit: folder_limit
end
store_path(filename) click to toggle source

Returns the next available path (String) for a file to be stored under. filename is the basename for the file to be stored.

# File lib/folder_stash/file_usher.rb, line 162
def store_path(filename)
  update_link if folder_limit && current_folder.count >= folder_limit
  File.join current_directory, filename
end