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 0c8567b0 Invitations cross-check
0c8567b0 is described below

commit 0c8567b0691c516333606e9aafdad94d5aee1c05
Author: Sebb <[email protected]>
AuthorDate: Sun Mar 12 17:03:38 2023 +0000

    Invitations cross-check
---
 www/members/invitations.cgi | 133 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)

diff --git a/www/members/invitations.cgi b/www/members/invitations.cgi
new file mode 100755
index 00000000..fd7be8cb
--- /dev/null
+++ b/www/members/invitations.cgi
@@ -0,0 +1,133 @@
+#!/usr/bin/env ruby
+PAGETITLE = "New Member invitations cross-check" # Wvisible:meeting
+$LOAD_PATH.unshift '/srv/whimsy/lib'
+
+require 'wunderbar/bootstrap'
+require 'whimsy/asf'
+require 'mail'
+require 'whimsy/asf/meeting-util'
+
+MAIL_DIR = '/srv/mail/members'
+
+# Encapsulate gathering data to improve error processing
+def setup_data
+  memappfile = ASF::MeetingUtil.get_latest_file('memapp-received.txt')
+
+  # which entries are shown as uninvited; get availid and name
+  notinvited = {}
+  ASF::MeetingUtil.parse_memapp(memappfile).filter_map do |a| 
+    if a.first == 'no'
+      notinvited[a[-2]] = {name: a[-1]}
+    end
+  end
+
+  # find relevant email files (exclude ones before the meeting)
+  yyyymm = File.basename(File.dirname(memappfile))[0..5]
+  yamls = Dir[File.join(MAIL_DIR, '2?????.yaml')].select {|n| File.basename(n, 
'yaml') >= yyyymm }
+  
+  # now find invitations and replies
+  invites = {emails: {}, names: {}}
+  replies = {emails: {}, names: {}}
+
+  yamls.each do |index|
+    mail = YamlFile.read(index)
+    mail.each do |k, v|
+      # This may not find all the invites ...
+      if v[:Subject] =~ /^Invitation to join The Apache Software Foundation 
Membership/
+        to = Mail::AddressList.new(v[:To])
+        to.addresses.each do |add|
+          addr = add.address
+          next if addr == '[email protected]'
+          invites[:emails][addr] = 1
+          invites[:names][add.display_name] = 1 if add.display_name
+        end
+      elsif v[:Subject] =~ /^Re: Invitation to join The Apache Software 
Foundation Membership/
+        add = Mail::Address.new(v[:From])
+        replies[:emails][add.address] = 1
+        replies[:names][add.display_name] = 1 if add.display_name
+      end
+    end
+  end
+
+  nominated_by = {}
+  # might be more than one ...
+  ASF::Person.member_nominees.each do |k, v|
+    nominated_by[k.id] = v.scan(/Nominated by: (.*)/).flatten
+  end
+
+  notinvited.each do |id, v|
+    mails = ASF::Person.new(id).all_mail
+    v[:invited] = match_person(invites, id, v[:name], mails)
+    v[:replied] = match_person(replies, id, v[:name], mails)
+    v[:nominators] = nominated_by[id] || 'unknown'
+  end
+  return notinvited, memappfile, invites, replies, nominated_by
+end
+
+def match_person(hash, id, name, mails)
+  mail = "#{id}@apache.org"
+  return true if hash[:emails].key? mail or hash[:names].key? name
+  return mails.any? {|e| hash[:emails].key? e}
+end
+
+# produce HTML output of reports, highlighting ones that have not (yet)
+# been posted
+_html do
+  _style %{
+    .missing {background-color: yellow}
+    .flexbox {display: flex; flex-flow: row wrap}
+    .flexitem {flex-grow: 1}
+    .flexitem:first-child {order: 2}
+    .flexitem:last-child {order: 1}
+    .count {margin-left: 4em}
+  }
+  _body? do
+    notinvited, memappfile, _ = setup_data
+    memappurl = ASF::SVN.getInfoItem(memappfile, 'url')
+    nominationsurl = memappurl.sub('memapp-received.txt', 
'nominated-members.txt')
+    _whimsy_body(
+      title: PAGETITLE,
+      related: {
+        memappurl => 'memapp-received.txt',
+        'https://lists.apache.org/[email protected]' => 
'[email protected]',
+        nominationsurl => 'nominated-members.txt',
+      },
+      helpblock: -> {
+        _ 'This script checks memapp-received.txt against invitation emails 
seen in [email protected]'
+      }
+    ) do
+
+      _h1 'Nominations listed as not yet invited in memapp-received.txt'
+      _table.table.table_striped do
+        _tr do
+          _th 'id'
+          _th 'name'
+          _th 'invite seen?'
+          _th 'reply seen?'
+          _th 'nominator(s)'
+        end
+    
+        notinvited.each do |id, v|
+          _tr_ do
+            _td id
+            _td v[:name]
+            _td v[:invited]
+            _td v[:replied]
+            _td v[:nominators].join(', ')
+          end
+        end
+      end
+    end
+  end
+end
+
+# produce JSON output
+# N.B. This is activated if the ACCEPT header references 'json'
+_json do
+  notinvited, memappfile, invites, replies, nominated_by = setup_data
+  _notinvited notinvited
+  _memappfile memappfile
+  _invites invites
+  _replies replies
+  _nominated_by nominated_by
+end

Reply via email to