This is an automated email from the ASF dual-hosted git repository.
sebb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/whimsy.git
The following commit(s) were added to refs/heads/master by this push:
new 2474937 Add members-notify check
2474937 is described below
commit 24749373a1a15b034125559269ec06f3e8f9cb06
Author: Sebb <[email protected]>
AuthorDate: Sat Mar 5 13:07:21 2022 +0000
Add members-notify check
---
lib/whimsy/asf/mlist.rb | 5 ++
www/members/subscriptions2.cgi | 176 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 181 insertions(+)
diff --git a/lib/whimsy/asf/mlist.rb b/lib/whimsy/asf/mlist.rb
index 341fe3d..2687deb 100644
--- a/lib/whimsy/asf/mlist.rb
+++ b/lib/whimsy/asf/mlist.rb
@@ -35,6 +35,11 @@ module ASF
return list_filter('sub', 'apache.org', 'members', archivers),
(File.mtime(LIST_TIME) rescue File.mtime(LIST_SUBS))
end
+ # Return an array of members-notify@ subscribers followed by the file
update time
+ def self.members_notify_subscribers(archivers=true)
+ return list_filter('sub', 'apache.org', 'members-notify', archivers),
(File.mtime(LIST_TIME) rescue File.mtime(LIST_SUBS))
+ end
+
# Return an array of private@pmc subscribers followed by the file update
time
# By default does not return the standard archivers
# pmc can either be a pmc name, in which case it uses
private@<pmc>.apache.org
diff --git a/www/members/subscriptions2.cgi b/www/members/subscriptions2.cgi
new file mode 100755
index 0000000..296092f
--- /dev/null
+++ b/www/members/subscriptions2.cgi
@@ -0,0 +1,176 @@
+#!/usr/bin/env ruby
+
+# TODO: combine with members@ script
+
+PAGETITLE = "Apache members-notify@ Subscription Crosscheck" # Wvisible:members
+$LOAD_PATH.unshift '/srv/whimsy/lib'
+
+require 'wunderbar'
+require 'whimsy/asf'
+require 'whimsy/asf/mlist'
+require 'wunderbar/bootstrap'
+require 'wunderbar/jquery/stupidtable'
+
+subscribers, modtime = ASF::MLIST.members_notify_subscribers(false) #
excluding archivers
+
+_html do
+ _body? do
+ _whimsy_body(
+ title: PAGETITLE,
+ related: {
+ '/roster/members' => 'Listing Of All Members',
+ '/committers/subscribe' => 'Committers Self-Subscribe Tool',
+ 'https://lists.apache.org' => 'Apache Ponymail List Archives'
+ },
+ helpblock: -> {
+ _p! do
+ _ "This process starts with the list of subscribers (updated
#{modtime}) to "
+ _a '[email protected]', href:
'https://mail-search.apache.org/members/private-arch/members-notify/'
+ _br
+ _ 'These are matched against '
+ _a 'members.txt', href: ASF::SVN.svnpath!('foundation',
'members.txt')
+ _ ', '
+ _a 'iclas.txt', href: ASF::SVN.svnpath!('officers', 'iclas.txt')
+ _ ', and '
+ _code 'ldapsearch mail'
+ _ ' to attempt to match the email address to an Apache ID.'
+ _br
+ _ 'Those that are not found are listed as '
+ _code.text_danger '*missing*'
+ _ '. Emeritus members are '
+ _em 'listed in italics'
+ _ '. Non ASF members are '
+ _span.text_danger 'listed in red'
+ _ '.'
+ end
+ _p! do
+ _ 'The resulting list is then cross-checked against '
+ _code 'ldapsearch cn=member'
+ _ '. Membership that is only listed in one of these two sources is
also '
+ _span.text_danger 'listed in red'
+ _ '.'
+ end
+ _p! do
+ _ 'Separate tables below show '
+ _a 'Members not subscribed to the list', href: "#unsub"
+ _ ', and '
+ _a 'Copyable list of Members not subscribed', href: "#unsublist"
+ _ ', and '
+ _a 'Entries in LDAP but not members.txt', href: "#ldap"
+ _ '.'
+ end
+ }
+ ) do
+ ldap = ASF.members
+
+ members = ASF::Member.new.map {|id, _text| ASF::Person.find(id)}
+ ASF::Person.preload('cn', members)
+ maillist = ASF::Mail.list
+
+ subscriptions = []
+ subscribers.each do |line|
+ person = maillist[line.downcase]
+ person ||= maillist[line.downcase.sub(/[-+]\w+@/, '@')] # allow for
trailing +- suffix
+ if person
+ id = person.id
+ id = '*notinavail*' if id == 'notinavail'
+ else
+ person = ASF::Person.find('notinavail')
+ id = '*missing*'
+ end
+ subscriptions << [id, person, line]
+ end
+
+ _table.table do
+ _tr do
+ _th 'id', data_sort: 'string'
+ _th 'email', data_sort: 'string'
+ _th 'name', data_sort: 'string'
+ end
+ subscriptions.sort.each do |id, person, email|
+ _tr_ do
+ if id.include? '*'
+ _td.text_danger id
+ elsif not person.asf_member?
+ _td.text_danger id, title: 'Non Member', data_sort_value: '1'
+ elsif person.asf_member? != true
+ _td(data_sort_value: '2') {_em id, title: 'Emeritus'}
+ elsif not ldap.include? person
+ _td(data_sort_value: '3') {_strong.text_danger id, title: 'Not in
LDAP'}
+ else
+ _td id
+ end
+ _td email
+
+ if id.include? '*'
+ _td ''
+ else
+ _td person.public_name
+ end
+ end
+ end
+ end
+
+ missing = members - (subscriptions.map {|_id, person, _email| person})
+ missing.delete_if {|person| person.asf_member? != true} # remove emeritus
+
+ unless missing.empty?
+ _h3_.unsub! 'Not subscribed to the list'
+ _table.table do
+ _tr_ do
+ _th 'id'
+ _th 'name'
+ end
+ missing.sort_by(&:name).each do |person|
+ _tr do
+ if not ldap.include? person
+ _td {_strong.text_danger person.id, title: 'Not in LDAP'}
+ else
+ _td person.id
+ end
+ if person.public_name
+ _td person.public_name
+ else
+ _td.text_danger '*notinavail*'
+ end
+ end
+ end
+ end
+ _h3_.unsublist! 'Handy List of Unsubscribed Emails'
+ _p do
+ missing.each do |person|
+ _ "#{person.id}@apache.org, "
+ end
+ end
+ end
+
+ extras = ldap - members
+
+ unless extras.empty?
+ _h3_.ldap! 'In LDAP but not in members.txt'
+ _table.table do
+ _tr_ do
+ _th 'id'
+ _th 'name'
+ end
+ extras.sort.each do |person|
+ _tr do
+ _td person.id
+ _td person.public_name
+ 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