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:

  • (Boolean)


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.



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