lib/servel/index.rb in servel-0.11.0 vs lib/servel/index.rb in servel-0.12.0

- old
+ new

@@ -1,43 +1,91 @@ -class Servel::Index - def initialize(url_root:, url_path:, fs_path:) - @url_root = url_root - @url_path = url_path - @fs_path = fs_path - end - - def render - Servel::HamlContext.render('index.haml', locals) - end - - def locals - { - url_root: @url_root, - url_path: @url_path, - directories: directories, - files: files - } - end - - def directories - list = @fs_path.children.select { |child| child.directory? } - list = sort_paths(list).map { |path| Servel::EntryFactory.for(path) } - - unless @url_path == "/" - list.unshift(Servel::EntryFactory.parent("../")) - list.unshift(Servel::EntryFactory.top(@url_root == "" ? "/" : @url_root)) - end - - list.unshift(Servel::EntryFactory.home("/")) if @url_root != "" - - list - end - - def files - list = @fs_path.children.select { |child| child.file? } - sort_paths(list).map { |path| Servel::EntryFactory.for(path) } - end - - def sort_paths(paths) - Naturalsorter::Sorter.sort(paths.map(&:to_s), true).map { |path| Pathname.new(path) } - end +class Servel::Index + extend Servel::Instrumentation + LOCALS_CACHE = LruRedux::ThreadSafeCache.new(100) + SORT_METHODS = ["name", "mtime", "size", "type"] + SORT_DIRECTIONS = ["asc", "desc"] + + def initialize(url_root:, url_path:, fs_path:, params:) + @url_root = url_root + @url_path = url_path + @fs_path = fs_path + @params = params + end + + def render + Servel::HamlContext.render('index.haml', locals) + end + + def sort_method + param = @params["_servel_sort_method"] + param = "name" unless SORT_METHODS.include?(param) + param + end + + def sort_direction + param = @params["_servel_sort_direction"] + param = "asc" unless SORT_DIRECTIONS.include?(param) + param + end + + def locals_cache_key + @locals_cache_key ||= [@fs_path.to_s, @fs_path.mtime.to_i, sort_method, sort_direction].join("-") + end + + def locals + LOCALS_CACHE.getset(locals_cache_key) { build_locals } + end + + def build_locals + entries = @fs_path.children.map { |path| Servel::EntryFactory.for(path) } + + { + url_root: @url_root, + url_path: @url_path, + directories: directories(entries), + files: files(entries), + sort: { + method: sort_method, + direction: sort_direction + } + } + end + + def directories(entries) + list = apply_sort(entries.select { |entry| entry.directory? }) + + unless @url_path == "/" + list.unshift(Servel::EntryFactory.parent("../")) + list.unshift(Servel::EntryFactory.top(@url_root == "" ? "/" : @url_root)) + end + + list.unshift(Servel::EntryFactory.home("/")) if @url_root != "" + + list + end + + def files(entries) + apply_sort(entries.select { |entry| entry.file? }) + end + + def apply_sort(entries) + entries = case sort_method + when "name" + Naturalsorter::Sorter.sort_by_method(entries, :name, true) + when "mtime" + entries.sort_by { |entry| entry.mtime } + when "size" + entries.sort_by { |entry| entry.size || 0 } + when "type" + entries.sort_by { |entry| entry.type } + end + + entries.reverse! if sort_direction == "desc" + entries + end + + def sort_entries(entries) + Naturalsorter::Sorter.sort_by_method(entries, :name, true) + end + + instrument :locals, :directories, :files, :sort_entries end \ No newline at end of file