Class: DirSizer

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

Class Method Summary collapse

Class Method Details

.browse_contents(content) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/dir_sizer.rb', line 60

def self.browse_contents(content)
  cli = HighLine.new
  contents = content
  back_stack = []

  loop do
    print_table contents
    a = cli.ask("Type number of directory? ('..' for parent directory, 'e' to exit)")
    case a
    when 'e'
      break
    when '..'
      contents = back_stack.pop
    else
      back_stack.push contents
      next_dir = contents[:dirs_by_size][a.to_i][0]
      contents = contents[:dirs][next_dir]
    end
  end
end

.calculate_size(hash) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/dir_sizer.rb', line 47

def self.calculate_size(hash)
  t = {}
  hash[:dirs].each { |d,h|
    size_d = calculate_size(h)
    t[d] = size_d
  }
  size_dirs = t.values.map{ |v|
    v[:total]
  }.inject { |sum, n| sum + n } || 0
  size_files = hash[:files].values.inject { |sum, n| sum + n } || 0
  { :dirs => t, :total => size_files + size_dirs, :dirs_by_size => t.sort_by{|d,h| h[:total] }.reverse, :dir => hash[:dir] }
end

.calculate_size_hash(dir) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/dir_sizer.rb', line 29

def self.calculate_size_hash(dir)
  print '.' if dir.count('/') < 6
  print dir if dir.count('/') < 4
  r = { :dirs => {}, :files => {}, :dir => dir}
  Dir.entries(dir).each { |e|
    next if ['.', '..'].include? e
    t = File.join(dir, e)
    next if File.symlink? t
    next if @dirs_to_ignore.include? t
    if File.directory?(t)
      r[:dirs][t] = calculate_size_hash(t)
    else
      r[:files][t] = File.stat(t).size
    end
  }
  r
end

.execute(dir) ⇒ Object



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/dir_sizer.rb', line 7

def self.execute(dir)
  unless Dir.exist?(dir) && File.directory?(dir)
    puts "not a directory: #{dir}"
    exit(3)
  end
  init_dirs_to_ignore(dir)

  puts "Calculating size of directory #{dir}"
  size_hash = calculate_size_hash(dir)
  contents = calculate_size(size_hash)
  puts 'done'

  browse_contents(contents)
end

.init_dirs_to_ignore(dir) ⇒ Object



22
23
24
25
26
27
# File 'lib/dir_sizer.rb', line 22

def self.init_dirs_to_ignore(dir)
  @dirs_to_ignore = ['/dev', '/private/var/db/ConfigurationProfiles/Store', '/private/var/folders', '/Volumes/com.apple.TimeMachine.localsnapshots']
  Sys::Filesystem.mounts{ |mount|
    @dirs_to_ignore << mount.mount_point unless mount.mount_point == dir
  }
end


81
82
83
84
85
86
87
88
89
# File 'lib/dir_sizer.rb', line 81

def self.print_table(contents)
  output = []
  output << ['', Filesize.from("#{contents[:total]} B").pretty, contents[:dir]]
  contents[:dirs_by_size].each_with_index{ |t,i|
    s = Filesize.from("#{t[1][:total]} B").pretty
    output << [i, s, t[0]]
  }
  puts Terminal::Table.new :headings => ['Cmd', 'Dir', 'Size'], :rows => output
end