%
# Nick's web site: Generate directory listing.
#
# Copyright © 2021 Nick Bowler
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see
mydir = rep_uri
files = {}
@items.find_all(@item[:pattern]).each do |item|
t = item[:updated_at]
item.reps.each do |rep|
next if rep == @rep
p = rep_uri(rep)
d, f = File.split(p)
next unless "#{d}/" == mydir
if p =~ %r{/$}
displaysize = Dir.children(File.dirname(rep.raw_path)).length - 1
size = displaysize - 1000000
type = :DIR
else
size = File.size(rep.raw_path)
displaysize = human_filesize(size)
type = nil
end
files[f] = {
sorttime: if t then t.to_f else 0.0 end,
displaytime: if t then t.getutc.strftime "%Y-%m-%d %H:%M\u00a0UTC" end,
displaysize: displaysize,
size: size,
type: type,
}
end
end
if @items["#{File.dirname(mydir)}/index.lst"]
files[".."] = { type: :UP }
end
def render_entry(files, key)
f = files[key]
return <<~EOF
#{if f[:type]
""
end} |
#{
if key == ".." then "[Parent Directory]" else key end
} |
#{f[:displaytime]} |
#{f[:displaysize]} |
EOF
end
%>
|
Name |
Last Modified |
Size |
<%=
parentrow = if files[".."] then "#{render_entry(files, "..")}" end
files.delete("..")
if parentrow then "#{parentrow}
" end
%>
<%
by_name = files.keys.sort{ |a, b| strverscmp(a, b) }
by_name.each do |key|
entry = render_entry(files, key)
%>
<%= entry %>
<% end %>
<%
def meta_cmp(files, key, a, b)
av, bv = files[a][key], files[b][key]
return av <=> bv if av != bv
return strverscmp(a, b)
end
by_date = files.keys.sort { |a, b| meta_cmp(files, :sorttime, a, b) }
by_size = files.keys.sort { |a, b| meta_cmp(files, :size, a, b) }
listnames = [ "namerev", "datefwd", "daterev", "sizefwd", "sizerev" ]
lists = [ by_name.reverse, by_date, by_date.reverse, by_size, by_size.reverse ]
if parentrow
%>
<%= parentrow %>
<%
end
evenmap = (0..(lists.length-1)).map { false }
even = false
while not (elems = lists.map(&:first)).compact.empty?
matches = (0..(lists.length-1)).to_a.keep_if { |x| evenmap[x] == even }
if !matches.empty?
elems = elems.values_at(*matches).compact
mode = elems.group_by{|a| a}.max{|a, b| a[1].length <=> b[1].length}[0]
matches = []
lists.each_index do |i|
if evenmap[i] == even and lists[i].first.eql? mode
lists[i].shift
evenmap[i] ^= true
evenmap[i] = nil if lists[i].empty?
matches << i
end
end
%>
<%= render_entry(files, mode) %>
<%
else
%>
|
<%
end
even ^= true
end
%>