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