liberator 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/dir.rb +12 -0
- data/lib/liberator/controller.rb +45 -0
- data/lib/liberator/directory.rb +48 -0
- data/lib/liberator/view.rb +89 -0
- data/lib/liberator.rb +1 -0
- metadata +5 -1
data/lib/dir.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
class Dir
|
2
|
+
def self.real_entries(path)
|
3
|
+
Dir.entries(path).select do |entry|
|
4
|
+
absolute_path = path + '/' + entry
|
5
|
+
!File.symlink?(absolute_path) && entry != '.' && entry != '..'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.size(path)
|
10
|
+
`du -ks "#{path}"`.split("\t").first.to_i if Dir.exists? path
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Liberator
|
2
|
+
class Controller
|
3
|
+
def initialize(view=nil)
|
4
|
+
@view = view
|
5
|
+
@directory = Directory.new Dir.pwd
|
6
|
+
render
|
7
|
+
end
|
8
|
+
|
9
|
+
def listen
|
10
|
+
loop do
|
11
|
+
handle_key @view.capture_keystroke unless @view.nil?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def handle_key(key)
|
16
|
+
case key
|
17
|
+
when 'q'
|
18
|
+
@view.close
|
19
|
+
exit
|
20
|
+
when 'j'
|
21
|
+
@directory.select_next_entry
|
22
|
+
render
|
23
|
+
when 'k'
|
24
|
+
@directory.select_previous_entry
|
25
|
+
render
|
26
|
+
when 10
|
27
|
+
if File.directory? @directory.selected_entry[:path]
|
28
|
+
@directory = Directory.new @directory.selected_entry[:path]
|
29
|
+
render
|
30
|
+
end
|
31
|
+
when 'h'
|
32
|
+
@directory = @directory.parent
|
33
|
+
render
|
34
|
+
when 'x'
|
35
|
+
@directory.delete_selected_entry if @view.confirm_delete
|
36
|
+
@directory.refresh
|
37
|
+
render
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def render
|
42
|
+
@view.refresh(@directory.path, @directory.entries, @directory.selected_index) unless @view.nil?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Liberator
|
2
|
+
class Directory
|
3
|
+
attr_reader :path, :entries, :selected_index
|
4
|
+
def initialize(path)
|
5
|
+
@path = File.expand_path path
|
6
|
+
cache_entries
|
7
|
+
end
|
8
|
+
|
9
|
+
def selected_entry
|
10
|
+
@entries[@selected_index]
|
11
|
+
end
|
12
|
+
|
13
|
+
def select_previous_entry
|
14
|
+
@selected_index -= 1 if @selected_index > 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def select_next_entry
|
18
|
+
@selected_index += 1 unless @selected_index >= @entries.size-1
|
19
|
+
end
|
20
|
+
|
21
|
+
def parent
|
22
|
+
Directory.new File.expand_path(@path + '/..')
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete_selected_entry
|
26
|
+
FileUtils.rm_rf selected_entry[:path]
|
27
|
+
end
|
28
|
+
|
29
|
+
def refresh
|
30
|
+
@entries = Dir.real_entries(@path).collect do |entry|
|
31
|
+
absolute_path = @path + '/' + entry
|
32
|
+
|
33
|
+
if File.file? absolute_path
|
34
|
+
size = File.size absolute_path
|
35
|
+
elsif File.directory? absolute_path
|
36
|
+
size = Dir.size absolute_path
|
37
|
+
else
|
38
|
+
next
|
39
|
+
end
|
40
|
+
|
41
|
+
{ path: absolute_path, size: size }
|
42
|
+
end
|
43
|
+
@entries = @entries.compact.sort_by { |entry| 1.0/entry[:size].to_f }
|
44
|
+
@selected_index = 0
|
45
|
+
end
|
46
|
+
alias_method :cache_entries, :refresh
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Liberator
|
2
|
+
class View
|
3
|
+
GIGABYTE = 1048576
|
4
|
+
MEGABYTE = 1024
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
# Initialize curses view.
|
8
|
+
Curses.init_screen
|
9
|
+
Curses.noecho
|
10
|
+
Curses.curs_set 0
|
11
|
+
Curses.cbreak
|
12
|
+
@height = Curses.stdscr.maxy
|
13
|
+
@width = Curses.stdscr.maxx
|
14
|
+
|
15
|
+
@entry_window = Curses::Window.new @height-1, @width, 0, 0
|
16
|
+
|
17
|
+
@status_bar = Curses::Window.new 1, @width, @height-1, 0
|
18
|
+
@status_bar.standout
|
19
|
+
|
20
|
+
@scroll_offset = 0
|
21
|
+
end
|
22
|
+
|
23
|
+
def refresh(directory, entries, selected_index)
|
24
|
+
height = @entry_window.maxy
|
25
|
+
|
26
|
+
# Clear the screen manually, since clear function causes blinking.
|
27
|
+
@entry_window.setpos 0, 0
|
28
|
+
height.times { @entry_window.deleteln }
|
29
|
+
|
30
|
+
# Figure out what to draw based on the selected entry and height of the window.
|
31
|
+
if selected_index < height-1
|
32
|
+
visible_range = (0...height)
|
33
|
+
elsif selected_index == entries.size-1 # last item selected
|
34
|
+
visible_range = (entries.size-height..entries.size)
|
35
|
+
else
|
36
|
+
visible_range = (selected_index-height+2..selected_index+1)
|
37
|
+
end
|
38
|
+
|
39
|
+
entries[visible_range].each_with_index do |entry, index|
|
40
|
+
# Turn on highlighting, if this entry is selected.
|
41
|
+
@entry_window.standout if index+visible_range.begin == selected_index
|
42
|
+
|
43
|
+
# Get the file/directory name, without its full path.
|
44
|
+
name = entry[:path][entry[:path].rindex('/')+1..-1]
|
45
|
+
name += '/' if File.directory? entry[:path]
|
46
|
+
|
47
|
+
# Add the row to the window, appending a right-justified human-readable size.
|
48
|
+
@entry_window << name + formatted_size(entry[:size]).rjust(@entry_window.maxx - name.length)
|
49
|
+
|
50
|
+
# Stop highlighting.
|
51
|
+
@entry_window.standend
|
52
|
+
end
|
53
|
+
|
54
|
+
update_status_bar directory
|
55
|
+
end
|
56
|
+
|
57
|
+
def update_status_bar(content)
|
58
|
+
@status_bar.setpos 0, 0
|
59
|
+
formatted_content = content.ljust @width
|
60
|
+
@status_bar << formatted_content
|
61
|
+
|
62
|
+
@status_bar.refresh
|
63
|
+
end
|
64
|
+
|
65
|
+
def formatted_size(size)
|
66
|
+
if size > GIGABYTE
|
67
|
+
"#{size / GIGABYTE} GB"
|
68
|
+
elsif size > MEGABYTE
|
69
|
+
"#{size / MEGABYTE} MB"
|
70
|
+
else
|
71
|
+
"#{size} KB"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def capture_keystroke
|
76
|
+
@entry_window.getch
|
77
|
+
end
|
78
|
+
|
79
|
+
def confirm_delete
|
80
|
+
update_status_bar "Really delete? (y to confirm)"
|
81
|
+
capture_keystroke == 'y'
|
82
|
+
end
|
83
|
+
|
84
|
+
def close
|
85
|
+
# Clean up curses view.
|
86
|
+
Curses.close_screen
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/liberator.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: liberator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -20,7 +20,11 @@ executables:
|
|
20
20
|
extensions: []
|
21
21
|
extra_rdoc_files: []
|
22
22
|
files:
|
23
|
+
- lib/dir.rb
|
23
24
|
- lib/liberator.rb
|
25
|
+
- lib/liberator/controller.rb
|
26
|
+
- lib/liberator/directory.rb
|
27
|
+
- lib/liberator/view.rb
|
24
28
|
- bin/liberator
|
25
29
|
homepage: https://github.com/jmacdonald/liberator
|
26
30
|
licenses: []
|