blob: 88a7646722dfe689a22e227a12e7ba30709c55d8 [file] [log] [blame]
#!/usr/bin/env ruby
PAGETITLE = "Your Member Meeting Attendance Status and Update Tool" # Wvisible:meeting
$LOAD_PATH.unshift '/srv/whimsy/lib'
require 'whimsy/asf'
require 'wunderbar/bootstrap'
require 'date'
require 'json'
require 'tmpdir'
require 'whimsy/asf/meeting-util'
# produce HTML
_html do
_head_ do
_style :system
_style %{
div.status, .status form, pre.issue {margin-left: 16px}
.btn {margin: 4px}
form {margin-bottom: 1em}
.transcript {margin: 0 16px}
.transcript pre {border: none; line-height: 0}
pre._hilite {background-color: yellow}
form p {margin-top: 1em}
form {display: inline-block}
textarea {width: 100%; height: 8em}
textarea:disabled {background-color: #EEEEEE}
div.alert {background-color: yellow; border: solid 2px red; padding-top: 0}
}
end
_body? do
MEETINGS = ASF::SVN['Meetings']
attendance = ASF::MeetingUtil.get_attendance(MEETINGS)
latest = ASF::MeetingUtil.get_latest(MEETINGS)
@user ||= $USER
@meetingsMissed = (@meetingsMissed || 3).to_i
# Allow a non-participating member to post a request to go emeritus
if _.post? and @status == 'go emeritus' and $USER == @user
# stub out roster functions
require 'mail'
class Committer; def self.serialize(*args); end; end
def _committer(*args); end
def env.user; $USER; end
def env.password; $PASSWORD; end
# issue request
@action = 'request_emeritus'
@userid = $USER
eval IO.read(File.expand_path('../roster/views/actions/memstat.json.rb', __dir__))
# Provide visual feedback
_div.alert do
_h3 'Emeritus request submitted'
_ul do
_li 'Check your email for confirmation.'
_li 'Your status will be updated on Whimsy within 10 minutes.'
end
end
end
# Get live data of members' attendance or current proxies submitted
tracker = ASF::MeetingUtil.tracker(@meetingsMissed)
# determine user's name as found in members.txt
name = ASF::Member.find_text_by_id(@user).to_s.split("\n").first
matrix = attendance['matrix'][name]
# defaults for active users
tracker[@user] ||= {
'missed' => 0,
'status' => 'active - attended meetings recently'
}
active = (tracker[@user]['missed'] < @meetingsMissed)
_whimsy_body(
title: PAGETITLE,
subtitle: active ? 'Your Attendance Status' : 'Poll Of Inactive Members',
relatedtitle: 'More About Meetings',
related: {
'https://www.apache.org/foundation/governance/meetings' => 'How Meetings & Voting Works',
'/members/proxy' => 'Assign A Proxy For Next Meeting',
'/members/non-participants' => 'Members Not Participating',
ASF::SVN.svnpath!('foundation','members.txt') => 'See Official Members.txt File',
ASF::MeetingUtil::RECORDS => 'Official Past Meeting Records'
},
helpblock: -> {
_p "This page shows your personal attendance record at past Member's meetings, as of meeting #{latest}."
_p %{
Inactive members (only) will see a button to request a proxy for the next meeting, and
a second button that they can use to request to go emeritus. They also
will see the text of an issue that will be placed before the membership
for a vote should they not take either of these two options.
}
_p do
_b %{
N.B.
Attendance details for the June 2022 meeting were only added recently.
Unfortunately this was only discovered after an email was sent to members.
Apologies to those of you who received an email in error.
}
end
}
) do
member_status = ASF::Person.find(@user).asf_member?
_p_ do
if member_status != true
_span "#{name}, your current membership status is: "
_code member_status
else
_span "#{name}, your current meeting attendance status is: "
_code tracker[@user]['status']
end
end
if active and member_status == true
att = miss = 0
if !matrix.nil?
matrix.each do |date, status|
if %w(A V P).include? status
att += 1
elsif date != 'active'
miss += 1
end
end
end
if 0 == miss && 0 == att
_p.text_success "No attendance for Member's meetings found yet"
else
_p.text_success "Great! Thanks for attending Member's meetings recently! Overall attends: #{att} Non-attends: #{miss}"
if 0 == miss
_p.text_success "WOW! 100% attendance rate - thanks!"
end
end
end
if not active
_p.alert.alert_warning "Dear #{name}, You have missed the last " +
tracker[@user]['missed'].to_s + " meetings."
_div.status do
wrap = 80
issue_text = `#{MEETINGS}/whimsy-tools/issue-description.py #{name.inspect} #{ASF::SVN['foundation']}`.
gsub(/(.{1,#{wrap}})( +|$\n?)|(.{1,#{wrap}})/, "\\1\\3\n")
if Dir.exist? File.join(latest, 'issues')
_p 'Based on this status, the following text has been placed before the membership as a vote'
else
_p %{
Based on this status, the following text will be placed before the membership as a vote
UNLESS you either assign a proxy for the next meeting or voluntarily request a conversion
to emeritus status.
}
end
_pre.issue issue_text
_p 'Update your status (if you are inactive):'
_form method: 'get', action: 'proxy' do
_button.btn.btn_success 'Request a proxy',
name: 'status', value: 'request proxy',
disabled: $USER != @user ||
tracker[@user]['status'] == 'Proxy received'
end
_form method: 'post' do
_button.btn.btn_warning 'I would like to go emeritus',
name: 'status', value: 'go emeritus',
disabled: $USER != @user ||
tracker[@user]['status'] == 'Emeritus request received'
end
_p_ %{
If you haven't attended or voted in meetings recently, please consider participating, at
least by proxy, in the upcoming membership meeting. Assigning a proxy does NOT prevent
you from attending meetings. Normally, your proxy will just be at the meeting to
mark your attendance. You will still get any vote emails yourself. Remember that
voting at a meeting also counts for attendance.
}
end
end
_h1_ 'Your Attendance history', id: 'attendance'
if not name
_p.alert.alert_danger "#{@user} not found in members.txt"
elsif not matrix
_p.alert.alert_danger "#{name} not found in attendance matrix"
else
_table.table.table_sm style: 'margin: 0 24px; width: auto' do
_thead do
_tr do
_th 'Date'
_th 'Status'
end
end
matrix.sort.reverse.each do |date, status|
next if status == ' '
next if date == 'active'
color = 'bg-danger'
color = 'bg-warning' if %w(e).include? status
color = 'bg-success' if %w(A V P).include? status
_tr_ class: color do
_td do
_a date, href:
ASF::SVN.svnpath!('Meetings') + date
end
case status
when 'A'
_td 'Attended'
when 'V'
_td 'Voted but did not attend'
when 'P'
_td 'Attended via proxy'
when '-'
_td 'Did not attend'
when 'e'
_td 'Went emeritus'
else
_td status
end
end
end
end
end
end
end
end