diff options
Diffstat (limited to 'code/directory.rb')
-rw-r--r-- | code/directory.rb | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/code/directory.rb b/code/directory.rb new file mode 100644 index 00000000..c42392aa --- /dev/null +++ b/code/directory.rb @@ -0,0 +1,350 @@ +class Directory + BAD_TIME = Time.at(0) + MOVIE_EXTENSIONS = %w(avi mpg mpeg mp4 mp5 ogv ogm wmv mkv flv fid vob div divx) + class Entry #{{{ + # Let's just cache every shit, because i don't want + # to call File methods all the time + + + def initialize(dirname, basename=nil) + if basename + @path = File.join(dirname, basename) + @dirname = dirname + @basename = basename + else + @path = dirname + @dirname = File.dirname(dirname) + @basename = File.basename(dirname) + end + @name, @ext = @basename.split_at_last_dot +# @ext = @basename.from_last('.') || '' + @movie = MOVIE_EXTENSIONS.include?(@ext) + @size = 0 + @exists = false + @rights = '----------' + @readlink = '' + @symlink = false + @writable = false + @infostring = '' + @executable = false + @type = :nonexistent + @mtime = BAD_TIME + @ctime = BAD_TIME + @marked = false + end + + attr_reader *%w( + basename mtime rights type path ext + infostring readlink basename size ctime name + ) + + attr_accessor(:marked) + + def to_s() @path end + def exists?() @exists end + def marked?() @marked end + def symlink?() @symlink end + def movie?() @movie end + def broken_symlink?() @symlink and !@exists end + def dir?() @type == :dir end + def file?() @type == :file end + def writable?() @writable end + def executable?() @executable end + def mimetype() + if @type == :dir + nil + else + Fm::MIMETYPES[@ext] + end + end + + def delete! + if @type == :dir + Dir.delete(@path) rescue nil + else + File.delete(@path) rescue nil + end + end + + def refresh + if File.exists?(@path) + if File.ctime(@path) != @ctime + get_data + end + else + get_data + end + end + + def sh + @path.sh + end + + def in? path + to_s[0, path.size] == path + end + + def get_data + @size = 0 + @infostring = '' + + @exists = File.exists?(@path) + if @exists + @writable = File.writable?(@path) + @symlink = File.symlink?(@path) + if @symlink + @readlink = File.readlink(@path) + end + if File.directory?(@path) + @type = :dir + begin + sz = Dir.entries(@path).size - 2 + @size = sz + rescue + sz = "?" + end + @infostring << "#{sz}" + elsif File.socket?(@path) + @type = :socket + else + @type = :file + @size = File.size(@path) + if File.size?(@path) + @infostring << " #{File.size(@path).bytes 2}" + else + @infostring << "" + end + end + @rights = File.modestr(@path) + @executable = File.executable?(@path) + @mtime = File.mtime(@path) + @ctime = File.ctime(@path) + + else + if File.symlink?(@path) + @readlink = File.readlink(@path) + @infostring = '->' + @symlink = true + else + @symlink = false + end + @executable = false + @writable = false + @type = :nonexistent + @rights = '----------' + @mtime = BAD_TIME + @ctime = BAD_TIME + end + end + end #}}} + + PLACEHOLDER = Entry.new('/', 'placeholder') + + def initialize(path, allow_delay=false) + @path = path + @pos = 0 + @files = [PLACEHOLDER] + @file_size = 0 + @pointed_file = nil + @width = 1000 + @read = false + @empty = true + @scheduled = false + + refresh + end + + def read_dir + @mtime = File.mtime(@path) + @files = Dir.new(@path).to_a + if OPTIONS['hidden'] + @files -= ['.', '..', 'lost+found'] + else + @files.reject!{|x| x[0] == ?. or x == 'lost+found'} + end + + if @files.empty? + @files = ['.'] + end + + @files_raw = @files.map{|bn| File.join(@path, bn)} + @files.map!{|basename| Entry.new(@path, basename)} + end + + attr_reader(:path, :files, :pos, :width, :files_raw, + :file_size, :read) + attr_accessor(:scheduled) + + def scheduled?() @scheduled end + def read?() @read end + + def pos=(x) +# if @files.size <= 1 or x < 0 +# x = 0 +# elsif x > @files.size +# x = @files.size - 1 +# end + @pos = x + make_sure_cursor_is_in_range() + @pointed_file = @files[x] + resize + end + + def recheck_stuff() +# log "pointed file: #@pointed_file" +# log @files_raw +# log "" + if test = @files_raw.index(@pointed_file) +# log("if") + @pos = test + else +# log("else") + make_sure_cursor_is_in_range() + end + end + + def make_sure_cursor_is_in_range() + if @files.size <= 1 or @pos < 0 + @pos = 0 + elsif @pos > @files.size + @pos = @files.size - 1 + end + end + + def find_file(x) + x = File.basename(x) + + files.each_with_index do |file, i| + if file.basename == x + self.pos = i + end + end + end + + def empty?() + Dir.entries(@path).size <= 2 + end + + def restore() + for f in @files + f.marked = false + end + end + + def pointed_file=(x) + if @files_raw.include?(x) + @pointed_file = x + @pos = @files_raw.index(x) + else + self.pos = 0 + end + resize + end + + def size() @files.size end + + def resize() + pos = Fm.get_offset(self, lines) + if @files.empty? + @width = 0 + else + @width = 0 + @files[pos, lines-2].each_with_index do |fn, ix| + ix += pos + sz = fn.basename.size + fn.infostring.size + 2 + @width = sz if @width < sz + end +# @width = @files[pos,lines-2].map{|x| File.basename(x).size}.max + end + end + + def get_file_info() + @file_size = 0 + @files.each do |f| + f.refresh + @file_size += f.size if f.file? + end + @read = true + end + +# def refresh() +# @files = Dir.new(@path).to_a +# if OPTIONS['hidden'] +# @files -= ['.', '..', 'lost+found'] +# else +# @files.reject!{|x| x[0] == ?. or x == 'lost+found'} +# end +# if @files.empty? +# @files = ['.'] +# end +# @files.map!{|basename| Entry.new(@path, basename)} +# +# if @pos >= @files.size +# @pos = @files.size - 1 +# elsif @files.include?(@pointed_file) +# @pos = @files.index(@pointed_file) +# end +# end + def refresh(info=false) + if File.mtime(@path) != @mtime + read_dir + end + if info + log("getting file info of #{@path}") + get_file_info + end + sort + end + + def schedule() + @scheduled = true + Fm.schedule(self) + end + + def refresh!() + oldfile = @pointed_file + read_dir + get_file_info + sort + + if @files.include? oldfile + self.pointed_file = oldfile + end + end + + def sort_sub(x, y) + case OPTIONS['sort'] + when :name + x.basename <=> y.basename + when :ext + x.ext <=> y.ext + when :type + x.ext.filetype <=> y.ext.filetype + when :size + x.size <=> y.size + when :ctime + x.ctime <=> y.ctime + when :mtime + x.mtime <=> y.mtime + else + x.basename <=> y.basename + end + end + + def sort() + @files = @files.sort {|x,y| + if OPTIONS['dir_first'] + if x.dir? + if y.dir? then sort_sub(x, y) else -1 end + else + if y.dir? then 1 else sort_sub(x, y) end + end + else + sort_sub(x, y) + end + } + @files.reverse! if OPTIONS['sort_reverse'] + @files_raw = @files.map{|x| x.to_s} + end +end + |