X-Git-Url: http://git.draconx.ca/gitweb/homepage.git/blobdiff_plain/5aa756ee68dc2134b6acac8a66af2f1c14521721..e7306bc0bbfea36e6414684b00ad4ef1c7269aed:/layouts/listing.erb diff --git a/layouts/listing.erb b/layouts/listing.erb new file mode 100644 index 0000000..02017a0 --- /dev/null +++ b/layouts/listing.erb @@ -0,0 +1,150 @@ +<% +# 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 UTC" 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] + "#{f[:type]}" + end} + #{ + if key == ".." then "[Parent Directory]" else key end + } + #{f[:displaytime]} + #{f[:displaysize]} + EOF +end +%> + + + + + + + + + +<%= + 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 +%> + +
+ NameLast ModifiedSize