Class: FolderStash::FolderTree

Inherits:
Object
  • Object
show all
Defined in:
lib/folder_stash/folder_tree.rb

Overview

A FolderTree represents a nested directory path.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(folders, levels, limit) ⇒ FolderTree

Returns a new instance.

Arguments
  • folders (String) - Array of Folder instances.

  • levels (Integer) - Number of nested subdirectories in a path.

  • limit (Integer) - Number of items allowed in any folder in the tree’s directory path.



27
28
29
30
31
32
# File 'lib/folder_stash/folder_tree.rb', line 27

def initialize(folders, levels, limit)
  @folders = folders
  @path_length = levels ? levels + 1 : nil
  @folder_limit = limit
  @tree_limit = folder_limit ? folder_limit**(path_length) : nil
end

Instance Attribute Details

#folder_limitObject (readonly)

The maximum number of itmes that may be stored in any folder in #folders.



11
12
13
# File 'lib/folder_stash/folder_tree.rb', line 11

def folder_limit
  @folder_limit
end

#foldersObject

An array with instances of Folder, one for each directory in a nested directory path from the #root to the #terminal.



8
9
10
# File 'lib/folder_stash/folder_tree.rb', line 8

def folders
  @folders
end

#path_lengthObject (readonly)

The number of items (directories) in a nested directory path, from the #root (base directory) to the #terminal.



15
16
17
# File 'lib/folder_stash/folder_tree.rb', line 15

def path_length
  @path_length
end

#tree_limitObject (readonly)

Returns the value of attribute tree_limit.



17
18
19
# File 'lib/folder_stash/folder_tree.rb', line 17

def tree_limit
  @tree_limit
end

Class Method Details

.empty(root, levels:, limit:) ⇒ Object



34
35
36
37
38
39
# File 'lib/folder_stash/folder_tree.rb', line 34

def self.empty(root, levels:, limit:)
  folders = [Folder.new(root)]
  tree = new(folders, levels, limit)
  tree.new_branch_in tree.root, levels
  tree
end

.for_path(path, root:, limit:) ⇒ Object



41
42
43
44
45
# File 'lib/folder_stash/folder_tree.rb', line 41

def self.for_path(path, root:, limit:)
  path_items = path_segment path, root
  folders = Folder.folders_for_path_segment root, path_items
  new folders, path_items.count, limit
end

.path_segment(terminal, root) ⇒ Object



47
48
49
# File 'lib/folder_stash/folder_tree.rb', line 47

def self.path_segment(terminal, root)
  File.expand_path(terminal).split('/') - File.expand_path(root).split('/')
end

Instance Method Details

#actual_path_lengthObject

Returns the number of folder in the nested path currently available.



52
53
54
# File 'lib/folder_stash/folder_tree.rb', line 52

def actual_path_length
  folders.count
end

#available_folderObject

Returns the next available folder, searching upstream from the terminal folder to the #root.

Returns #root if root is the only folder.



60
61
62
63
64
# File 'lib/folder_stash/folder_tree.rb', line 60

def available_folder
  return root if flat?

  folders.reverse.find { |folder| folder.count < folder_limit }
end

#branch_pathObject



66
67
68
# File 'lib/folder_stash/folder_tree.rb', line 66

def branch_path
  folders.map(&:basename)
end

#flat?Boolean

Returns:



70
71
72
# File 'lib/folder_stash/folder_tree.rb', line 70

def flat?
  actual_path_length == 1 && path_length.nil?
end

#levels_below(folder) ⇒ Object

Returns the number of levels of folders nested in folder.



75
76
77
78
79
# File 'lib/folder_stash/folder_tree.rb', line 75

def levels_below(folder)
  return if flat?

  subdirectories - folders.index(folder)
end

#new_branch_in(folder, levels = nil) ⇒ Object

Creates a new branch of folders in folder and updates #folders to the new branch.

Returns an array with the full path for the terminal folder in the branch created.

Raises:



91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/folder_stash/folder_tree.rb', line 91

def new_branch_in(folder, levels = nil)
  return if flat?

  raise Errors::BranchError.new(dir: folder.path) if folder == terminal

  raise TreeLimitExceededError.new(tree: self) if folder.count >= folder_limit

  levels ||= levels_below folder
  new_branch = new_paths_in folder, levels
  @folders = folders[0..folders.index(folder)].concat new_branch
  folders.last.create!
end

#rootObject

Returns the root folder.



105
106
107
# File 'lib/folder_stash/folder_tree.rb', line 105

def root
  folders.first
end

#subdirectoriesObject

The nesting depth (Integer) of subdirectories in the base directory.



82
83
84
# File 'lib/folder_stash/folder_tree.rb', line 82

def subdirectories
  path_length - 1
end

#terminalObject

Returns the terminal (most deeply nested) folder.

Returns nil if the tree has not been fully initialized with a branch.



112
113
114
115
116
117
118
# File 'lib/folder_stash/folder_tree.rb', line 112

def terminal
  return root if flat?

  return if actual_path_length < path_length

  folders.last
end