| #!/usr/bin/env ruby |
| PAGETITLE = "Apache Mailing List Info" # Wvisible:members mail |
| $LOAD_PATH.unshift '/srv/whimsy/lib' |
| |
| # parse mailing list flags and try to interpret them |
| |
| require 'wunderbar' |
| require 'whimsy/asf' |
| require 'whimsy/asf/mlist' |
| require 'wunderbar/bootstrap' |
| require 'wunderbar/jquery/stupidtable' |
| |
| FLAGS = %{ |
| -m message moderation (see also -u) |
| -u user posts (i.e. subscribed or allowed) |
| |
| -mu allow subscribers to post, moderate all others (submod) |
| -mU moderate all posts (modall) |
| -Mu allow subscribers to post, reject all others (subonly) |
| -MU allow anyone to post (open) |
| |
| -mz moderate after checking sender is known |
| -Mz unmoderated, but requires sender to be known |
| |
| -s subscriptions are moderated (usually means the list is private) |
| |
| -x check mime-type, size etc |
| -y send copy to security@apache.org |
| -z check that sender address is known (i.e. @apache.org or in LDAP) |
| } |
| # announce@a.o: mUxYz |
| |
| def type(mu) |
| { |
| mu: 'submod', |
| mU: 'modall', |
| Mu: 'subonly', |
| MU: 'open', |
| }[mu.to_sym] |
| end |
| |
| query = ENV['QUERY_STRING'] || '' |
| params = CGI.parse(query) |
| filter = nil |
| # Only allow letters in the query string so it is safe to use |
| if params['filter'].last =~ %r{^([a-zA-Z]+)$} |
| # Convert xmU into m.......U..x |
| sorted = $1.split('').sort_by(&:upcase) |
| letters = [] |
| letters << sorted[0,1] # first letter needed to start off |
| sorted.each_cons(2).with_index do |(a, b), i| |
| gap = (b.upcase.ord - a.upcase.ord - 1) |
| if gap > 0 |
| gap.times {letters << '.'} |
| else |
| raise ArgumentError,"Repeated letters #{[a, b]} not allowed" |
| end |
| letters << b |
| end |
| filter = Regexp.new(letters.join) |
| end |
| |
| listfilter = params['match'].last |
| |
| mod_counts = ASF::MLIST.list_moderators(nil).first.map {|x,y| [x, y.length]}.to_h |
| |
| list_types = {} |
| ASF::MLIST.list_types(true) {|d,l,t| list_types["#{l}@#{d}"] = t} |
| |
| _html do |
| _body? do |
| _whimsy_body( |
| title: PAGETITLE, |
| related: { |
| 'https://svn.apache.org/repos/infra/infrastructure/apmail/trunk/bin/EZMLM_FLAGS.txt' => |
| 'Description of all flags', |
| 'https://svn.apache.org/repos/infra/infrastructure/apmail/trunk/.ezmlmrc' => |
| '.ezmlmrc file which interprets the flags', |
| 'http://untroubled.org/ezmlm/man/man1/ezmlm-make.1.html' => 'ezmlm-make(1)', |
| 'https://svn.apache.org/repos/infra/infrastructure/apmail/trunk/bin/makelist-apache.sh' => |
| 'makelist-apache.sh - script tp create an ASF list; sets up options for ezmlm-make(1)', |
| 'https://svn.apache.org/repos/infra/infrastructure/apmail/trunk/bin' => |
| 'Location of tools', |
| }, |
| helpblock: -> { |
| _h2 'DRAFT - treat information with caution' |
| _p do |
| _ "This script shows the flag settings for all mailing lists, and attempts to interpret them." |
| end |
| _p %{ |
| 'mod count' is the number of moderators for the list. |
| Lists should ideally have at least 3 moderators to ensure timely responses. |
| The count is enclosed in [] if the list is 'open' or 'subonly' (and not private(s)), |
| because posts (and subscriptions) don't need to be moderated in that case. |
| } |
| _p %{ |
| Note that there are other settings which affect the behaviour, and the initial behaviour defined |
| by the flags can be modified by local changes to the editor script. |
| } |
| _ 'Sample flag meanings' |
| _pre FLAGS |
| } |
| ) do |
| |
| _table.table.table_striped do |
| _thead_ do |
| _tr do |
| _th 'list', data_sort: 'string' |
| _th 'domain', data_sort: 'string' |
| _th "flags #{filter}", data_sort: 'string' |
| _th 'Type (mu)', data_sort: 'string' |
| _th 'mod count', data_sort: 'int' |
| _th 'Known (z)', data_sort: 'string' |
| _th 'Moderate subs(s)', data_sort: 'string' |
| _th 'Archiver type', data_sort: 'string' |
| _th 'Filter (x)', data_sort: 'string' |
| _th 'cc.Security (y)', data_sort: 'string' |
| end |
| end |
| _tbody do |
| ASF::Mail.parse_flags(filter) do |domain, list, flags| |
| lad = "#{list}@#{domain}" |
| next if listfilter and ! lad.include? listfilter |
| mu = flags.tr('^muMU', '') |
| _tr do |
| _td data_sort_value: "#{list}-#{domain}" do |
| _a list, href: "https://lists.apache.org/list.html?#{lad}", target: '_blank' |
| end |
| _td data_sort_value: "#{domain}-#{list}" do |
| _a domain, href: "https://lists.apache.org/list.html?#{lad}", target: '_blank' |
| end |
| _td flags |
| _td do |
| _ mu |
| _ type(mu) |
| end |
| count = mod_counts[lad] |
| if !flags.include?('s') and %w{subonly open}.include? type(mu) |
| # ensure unmoderated lists are not penalised for having few moderators |
| _td data_sort_value: count+100 do |
| _ "[#{count}]" |
| end |
| else |
| if count.to_i < 3 |
| _td class: 'bg-danger' do |
| _ count |
| end |
| else |
| _td count |
| end |
| end |
| _td flags.include? 'z' |
| _td flags.include? 's' |
| _td list_types[lad] |
| _td flags.include? 'x' |
| _td flags.include? 'y' |
| end |
| end |
| end |
| end |
| |
| _script %{ |
| var table = $(".table").stupidtable(); |
| table.on("aftertablesort", function (event, data) { |
| var th = $(this).find("th"); |
| th.find(".arrow").remove(); |
| var dir = $.fn.stupidtable.dir; |
| var arrow = data.direction === dir.ASC ? "↑" : "↓"; |
| th.eq(data.column).append('<span class="arrow">' + arrow +'</span>'); |
| }); |
| } |
| |
| end |
| end |
| end |