#-- # Copyright (c) 2007 - 2013 Jeremy Hinegardner # All rights reserved. Licensed under the BSD license. See LICENSE for details #++ require 'erb' module Heel # generate html index pages of a directory # class DirectoryIndexer attr_reader :options attr_reader :template_file attr_reader :template def initialize( template_file, options ) @template = nil @template_file = template_file @options = options reload_template end def should_ignore?(fname) options[:ignore_globs].each do |glob| return true if ::File.fnmatch(glob,fname) end false end def mime_map @mime_map ||= Heel::MimeMap.new end def highlighting? @options.fetch( :highlighting, false) end def reload_on_template_change? @options.fetch( :reload_template_on_change, false ) end def using_icons? @options.fetch( :using_icons, false ) end def reload_template fstat = File.stat(@template_file) @template_mtime ||= fstat.mtime if @template.nil? or fstat.mtime > @template_mtime then @template = ::ERB.new(File.read(@template_file)) end end # generate the directory index html page of a directory # def index_page_for(req) reload_template if reload_on_template_change? dir = req.request_path entries = [] Dir.entries(dir).each do |entry| next if should_ignore?(entry) next if dir == @options[:document_root] and entry == ".." stat = File.stat(File.join(dir,entry)) entry_data = OpenStruct.new entry_data.name = entry == ".." ? "Parent Directory" : entry entry_data.link = entry entry_data.size = num_to_bytes(stat.size) entry_data.last_modified = stat.mtime.strftime("%Y-%m-%d %H:%M:%S") if stat.directory? then entry_data.content_type = "Directory" entry_data.size = "-" entry_data.name += "/" if using_icons? then entry_data.icon_url = File.join(options[:icon_url], MimeMap.icons_by_mime_type[:directory]) end else entry_data.mime_type = mime_map.mime_type_of(entry) entry_data.content_type = entry_data.mime_type.content_type if using_icons? then entry_data.icon_url = File.join(options[:icon_url], mime_map.icon_for(entry_data.mime_type)) end end entries << entry_data end template_vars = TemplateVars.new( :base_uri => req.path_info ) template_vars.entries = entries.sort_by { |e| e.link } template_vars.homepage = Heel::Configuration::HOMEPAGE return template.result( template_vars.binding_for_template ) end # essentially this is strfbytes from facets # def num_to_bytes(num,fmt="%.2f") case when num < 1024 "#{num} bytes" when num < 1024**2 "#{fmt % (num.to_f / 1024)} KB" when num < 1024**3 "#{fmt % (num.to_f / 1024**2)} MB" when num < 1024**4 "#{fmt % (num.to_f / 1024**3)} GB" when num < 1024**5 "#{fmt % (num.to_f / 1024**4)} TB" else "#{num} bytes" end end end end