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 ba0818bd Add UI for adding seconds
ba0818bd is described below

commit ba0818bd2a2b24c5a65d005ff273575c65bb989e
Author: Sebb <[email protected]>
AuthorDate: Sun Feb 15 00:26:02 2026 +0000

    Add UI for adding seconds
---
 lib/whimsy/asf/meeting-util.rb                     |  1 +
 www/members/check_membernoms.cgi                   |  1 +
 www/members/index.cgi                              |  1 +
 www/members/meeting.cgi                            |  1 +
 www/members/nominate_member.cgi                    |  8 +-
 .../{nominate_member.cgi => second_member.cgi}     | 96 +++++++++-------------
 www/members/watch.cgi                              |  1 +
 7 files changed, 50 insertions(+), 59 deletions(-)

diff --git a/lib/whimsy/asf/meeting-util.rb b/lib/whimsy/asf/meeting-util.rb
index 6d440c1a..ea7f127b 100644
--- a/lib/whimsy/asf/meeting-util.rb
+++ b/lib/whimsy/asf/meeting-util.rb
@@ -29,6 +29,7 @@ module ASF
       '/members/nominate_board.cgi' => 'Nominate someone for the Board',
       'runbook/email_02_nomination_of_members.txt' => 'How To Nominate A New 
Member',
       '/members/nominate_member.cgi' => 'Nominate someone for ASF Member',
+      '/members/second_member.cgi' => 'Second a nomination for ASF Member',
       '/members/proxy.cgi' => 'Submit A Proxy/Check Your Proxies',
       'agenda.txt' => 'Official Meeting Agenda',
       '/members/check_boardnoms.cgi' => 'Cross-check existing Board 
nominations',
diff --git a/www/members/check_membernoms.cgi b/www/members/check_membernoms.cgi
index 5531b547..ab9c635b 100755
--- a/www/members/check_membernoms.cgi
+++ b/www/members/check_membernoms.cgi
@@ -120,6 +120,7 @@ _html do
         'memberless-pmcs.cgi' => 'PMCs with no/few ASF Members',
         'watch.cgi' => 'Watch list for potential Member candidates',
         'nominate_member.cgi' => 'Nominate someone for ASF Member',
+        'second_member.cgi' => 'Second a nomination for ASF Member',
         'check_boardnoms.cgi' => 'Cross-check existing Board nominations',
         'nominate_board.cgi' => 'Nominate someone for the Board',
         ASF::SVN.svnpath!('Meetings') => 'Official Meeting Agenda Directory'
diff --git a/www/members/index.cgi b/www/members/index.cgi
index a60cd21b..facd3d5b 100755
--- a/www/members/index.cgi
+++ b/www/members/index.cgi
@@ -13,6 +13,7 @@ MEETING = {
   'watch.cgi' => 'Potential Member Watch List - tracking candidates for future 
nominations',
   'memberless-pmcs.cgi' => 'Crosscheck PMCs with few/no ASF Members, for 
future nominations',
   'nominate_member.cgi' => 'Nominate someone for ASF Member',
+  'second_member.cgi' => 'Second a nomination for ASF Member',
   'check_membernoms.cgi' => 'Cross-check existing New Member nominations',
   'nominate_board.cgi' => 'Nominate someone for the Board',
   'check_boardnoms.cgi' => 'Cross-check existing Board nominations',
diff --git a/www/members/meeting.cgi b/www/members/meeting.cgi
index a898f59f..c718c2f5 100755
--- a/www/members/meeting.cgi
+++ b/www/members/meeting.cgi
@@ -189,6 +189,7 @@ _html do
          _ul do
             ['/members/nominate_board.cgi',
             '/members/nominate_member.cgi',
+            '/members/second_member.cgi',
             '/members/proxy.cgi',
             '/members/check_boardnoms.cgi',
             '/members/check_membernoms.cgi'].each do |f|
diff --git a/www/members/nominate_member.cgi b/www/members/nominate_member.cgi
index f209314c..0ac31279 100755
--- a/www/members/nominate_member.cgi
+++ b/www/members/nominate_member.cgi
@@ -161,7 +161,13 @@ _html do
           _strong "send an email to the #{MAILING_LIST} list"
           _ ' from you with the nomination, '
           _a 'as is tradition.', href: 
'https://lists.apache.org/[email protected]:2023-2:%22MEMBER%20NOMINATION%22'
-          _ ' This form only supports adding new nominations of existing 
committers; to add seconds or comments, please carefully edit 
nominated-members.txt in SVN.'
+          _p 
+          _p do
+            _ 'This form only supports adding new nominations of existing 
committers; '
+            _ 'there is now a form to '
+            _a 'add seconds to nominations', href: '/members/second_member.cgi'
+            _ 'Alternatively, please carefully edit nominated-members.txt in 
SVN.'
+          end
           _strong ' To nominate a non-committer, '
           _ 'add them manually to nominated-members.txt and use exactly n/a 
for the id, and include both their name and Nominee email:'
           _a 'Lookup committer availIDs', href: '/roster/committer/'
diff --git a/www/members/nominate_member.cgi b/www/members/second_member.cgi
similarity index 57%
copy from www/members/nominate_member.cgi
copy to www/members/second_member.cgi
index f209314c..b6544b0d 100755
--- a/www/members/nominate_member.cgi
+++ b/www/members/second_member.cgi
@@ -1,5 +1,5 @@
 #!/usr/bin/env ruby
-PAGETITLE = "Nominate someone for ASF Member" # Wvisible:meeting
+PAGETITLE = "Second someone for ASF Member" # Wvisible:meeting
 $LOAD_PATH.unshift '/srv/whimsy/lib'
 require 'time'
 require 'wunderbar'
@@ -17,21 +17,20 @@ MAILING_LIST = '[email protected]'
 def emit_form(title, prev_data)
   _whimsy_panel(title, style: 'panel-success') do
     _form.form_horizontal method: 'post' do
-      field = 'availid'
-      _whimsy_forms_input(label: 'Nominee availid', name: field,
-        value: prev_data[field], helptext: 'Enter the availid of the committer 
you are nominating for ASF Membership'
+      field = 'nominee'
+      _whimsy_forms_select(label: 'Nominee', name: field,
+        multiple: false,
+        options: ASF::MemberFiles.nomination_headers,
+        helptext: 'Select the nominee you are seconding for ASF Membership'
       )
-      _whimsy_forms_input(label: 'Nominated by', name: 'nomby', readonly: 
true, value: $USER
-      )
-      _whimsy_forms_input(
-        label: 'Seconded by', name: 'secby', helptext: 'Optional 
comma-separated list of seconds; ONLY if you have confirmed with the seconds 
directly'
+      _whimsy_forms_input(label: 'Seconded by', name: 'secby', readonly: true, 
value: $USER
       )
       field = 'statement'
-      _whimsy_forms_input(label: 'Nomination Statement', name: field, rows: 10,
+      _whimsy_forms_input(label: 'Second Statement', name: field, rows: 10,
         value: prev_data[field], helptext: 'Explain why you believe this 
person would make a good ASF Member, and what projects/communities they work on 
at the ASF'
       )
       _whimsy_forms_submitwrap(
-        noicon: true, label: 'submit', name: 'submit', value: 'submit', 
helptext: 'Checkin this nomination and send email to members@'
+        noicon: true, label: 'submit', name: 'submit', value: 'submit', 
helptext: 'Checkin this second and send email to members@'
       )
     end
   end
@@ -40,15 +39,8 @@ end
 # Validation as needed within the script
 # Returns: 'OK' or a text message describing the problem
 def validate_form(formdata: {})
-  uid = formdata['availid'].downcase
-  return "You MUST provide a nomination statement for Candidate #{uid}; blank 
was provided!" if formdata['statement'].empty?
-  chk = ASF::Person[uid]&.asf_member?
-  chk.nil? and return "Invalid availid supplied: 
(#{uid})\n\nStatement:\n#{formdata['statement']}"
-  # Allow renomination of Emeritus
-  pubname = ASF::Person[uid].public_name
-  chk && !chk.to_s.start_with?('Emeritus') and return "Your nominee #{pubname} 
(#{uid}) is already an ASF member!"
-  already = ASF::MemberFiles.member_nominees
-  return "Candidate (#{uid}) has already been nominated by 
#{already[uid]['Nominated by']}" if already.include? uid
+  nominee = formdata['nominee']
+  return "You MUST provide a second statement for Candidate #{nominee}; blank 
was provided!" if formdata['statement'].empty?
   return 'OK'
 end
 
@@ -56,47 +48,40 @@ end
 # @return true if we think it succeeded; false in all other cases
 def process_form(formdata: {}, wunderbar: {})
   _h3 "Transcript of update to nomination file 
#{ASF::MemberFiles::NOMINATED_MEMBERS}"
-  entry = ASF::MemberFiles.make_member_nomination({
-    availid: formdata['availid'].downcase,
-    nomby: formdata['nomby'],
-    secby: formdata['secby'],
-    statement: formdata['statement']
-  })
-
+  entry = {
+    nominee: formdata['nominee'], # to find the entry
+    secby: formdata['secby'], # add to seconds
+    statement: formdata['statement'] # the data
+  }
   environ = Struct.new(:user, :password).new($USER, $PASSWORD)
-  ASF::MemberFiles.update_member_nominees(environ, wunderbar, [entry], "+= 
#{formdata['availid'].downcase}")
+  x = ASF::MemberFiles.commit_member_second(environ, wunderbar, entry, "+= 
second for #{formdata['nominee'].downcase}")
+  _pre x
   return true
 end
 
-# Send email to members@ with this nomination's data
+# Send email to members@ with this second's data
 # Reports status to user in a _div
-def send_nomination_mail(formdata: {})
-  uid = formdata['availid'].downcase
-  nomby = formdata['nomby']
-  public_name = ASF::Person.new(uid).public_name
+def send_confirmation_mail(formdata: {})
+  nominee = formdata['nominee'].downcase
   secby = formdata.fetch('secby', nil)
-  secby.nil? || secby.empty? ? nomseconds = '' : nomseconds = "Nomination 
seconded by: #{secby}"
   mail_body = <<-MAILBODY
-This nomination for #{public_name} (#{uid}) as a New Member
-Candidate has been added:
+Added second by #{secby} for #{nominee} as a New Member:
 
 #{formdata['statement']}
 
-#{nomseconds}
-
 --
-- #{ASF::Person[nomby].public_name}
+- #{ASF::Person[secby].public_name}
   Email generated by Whimsy (#{File.basename(__FILE__)})
 
 MAILBODY
 # See check_membernoms.cgi which parses this in list archives
-mailsubject = "[MEMBER NOMINATION] #{ASF::Person.new(uid).public_name} 
(#{uid})"
+mailsubject = "[MEMBER SECOND] #{nominee}"
 
   ASF::Mail.configure
   mail = Mail.new do
     to MAILING_LIST
     bcc '[email protected]'
-    from "#{ASF::Person[nomby].public_name} <#{nomby}@apache.org>"
+    from "#{ASF::Person[secby].public_name} <#{secby}@apache.org>"
     subject mailsubject
     text_part do
       body mail_body
@@ -153,30 +138,26 @@ _html do
       helpblock: -> {
         _b "For: #{timelines['meeting_type']} Meeting on: 
#{timelines['meeting_iso']}"
         _p do
+          _br
           _ %Q{
-            Use this form to nominate any Committer the new ASF Membership 
election.
-            It automatically adds a properly formatted nomination to the 
#{ASF::MemberFiles::NOMINATED_MEMBERS} file,
-            and will then 
+            Use this form to add a second to an existing nomination for ASF 
Membership.
+            It automatically adds a properly formatted entry to the 
#{ASF::MemberFiles::NOMINATED_MEMBERS} file,
+            and will then
           }
           _strong "send an email to the #{MAILING_LIST} list"
-          _ ' from you with the nomination, '
-          _a 'as is tradition.', href: 
'https://lists.apache.org/[email protected]:2023-2:%22MEMBER%20NOMINATION%22'
-          _ ' This form only supports adding new nominations of existing 
committers; to add seconds or comments, please carefully edit 
nominated-members.txt in SVN.'
-          _strong ' To nominate a non-committer, '
-          _ 'add them manually to nominated-members.txt and use exactly n/a 
for the id, and include both their name and Nominee email:'
-          _a 'Lookup committer availIDs', href: '/roster/committer/'
+          _ ' from you with the details of the second.'
         end
       }
     ) do
 
       if nomclosed
         _h1 'Nominations are now closed!'
-        _p 'Sorry, no further nominations will be accepted for ballots at this 
meeting.'
+        _p 'Sorry, no further seconds will be accepted for ballots at this 
meeting.'
       else
         _h3 "Nominations close in #{ASFTime.secs2text(t_end - t_now)} at 
#{Time.at(t_end).utc} for Meeting: #{timelines['meeting_iso']}"
       end
 
-      _div id: 'nomination-form' do
+      _div id: 'second-form' do
         if _.post?
           unless nomclosed
             submission = _whimsy_params2formdata(params)
@@ -189,10 +170,9 @@ _html do
           elsif valid == 'OK'
             if process_form(formdata: submission, wunderbar: _)
               _div.alert.alert_success role: 'alert' do
-                _p "Your nomination was submitted to svn; now sending email to 
#{MAILING_LIST}."
+                _p "Your second was submitted to svn; now sending email to 
#{MAILING_LIST}."
               end
-              mailval = send_nomination_mail(formdata: submission)
-              _pre mailval
+              mailval = send_confirmation_mail(formdata: submission)
             else
               _div.alert.alert_danger role: 'alert' do
                 _p do
@@ -214,12 +194,12 @@ _html do
         else # if _.post?
           if nomclosed
             _p do
-              _ 'Sorry, no further nominations will be accepted for ballots at 
this meeting.'
-              _br
-              _a 'See existing nominations.', href: 
'/members/check_membernoms.cgi'
+              _ 'Sorry, no further seconds will be accepted for ballots at 
this meeting.'
+              # _br
+              # _a 'See existing nominations.', href: 
'/members/check_membernoms.cgi'
             end
           else
-            emit_form('Enter your New Member nomination', {})
+            emit_form('Enter your New Member second', {})
           end
         end
       end
diff --git a/www/members/watch.cgi b/www/members/watch.cgi
index 3d206282..9639c84c 100755
--- a/www/members/watch.cgi
+++ b/www/members/watch.cgi
@@ -21,6 +21,7 @@ _html do
       related: {
         '/members/memberless-pmcs.cgi' => 'PMCs with no/few ASF Members',
         '/members/nominate_member.cgi' => 'Nominate someone for ASF Member',
+        '/members/second_member.cgi' => 'Second a nomination for ASF Member',
         '/members/check_membernoms.cgi' => 'Cross-check existing New Member 
Nominations',
         ASF::SVN.svnpath!('Meetings') => 'Official Meeting Agenda Directory'
       },

Reply via email to