Add ptl_nominations_last_day email template
This consumes (and modifies) render-statistics. Factoring this out will be done at the end of the series Change-Id: I878de8288f1ac047d844085f05261a6d3b1daac1
This commit is contained in:
parent
069e2828f7
commit
ffe1aa3c8b
@ -69,6 +69,53 @@ def collect_project_stats(basedir, verbose, projects):
|
||||
', '.join(candidates)))
|
||||
|
||||
|
||||
def election_summary():
|
||||
now = datetime.datetime.now(tz=pytz.utc)
|
||||
now = now.replace(microsecond=0)
|
||||
event = utils.get_event('PTL Nominations')
|
||||
start, end = event['start'], event['end']
|
||||
duration = (end - start)
|
||||
remaining = (end - now)
|
||||
progress = (duration - remaining)
|
||||
|
||||
p_progress = as_percentage(progress.total_seconds(),
|
||||
duration.total_seconds())
|
||||
p_candidate = as_percentage(counts['with_candidate'], counts['projects'])
|
||||
p_nominations = as_percentage(counts['nominations'], counts['projects'])
|
||||
|
||||
need_election.sort()
|
||||
without_candidate.sort()
|
||||
|
||||
output = ""
|
||||
output += ("%-25s @ %s\n" % ("Nominations started", as_utctime(start)))
|
||||
output += ("%-25s @ %s\n" % ("Nominations end", as_utctime(end)))
|
||||
output += ("%-25s : %s\n" % ("Nominations duration", duration))
|
||||
output += ("%-25s : %s\n" % ("Nominations remaining", remaining))
|
||||
output += ("%-25s : %6.2f%%\n" % ("Nominations progress", p_progress))
|
||||
output += ("-" * 51)
|
||||
output += ("\n")
|
||||
output += ("%-25s : %5d\n" % ("Projects[1]", counts['projects']))
|
||||
output += ("%-25s : %5d (%6.2f%%)\n" % ("Projects with candidates",
|
||||
counts['with_candidate'],
|
||||
p_candidate))
|
||||
output += ("%-25s : %5d (%6.2f%%)\n" % ("Projects with election",
|
||||
counts['nominations'],
|
||||
p_nominations))
|
||||
output += ("-" * 51)
|
||||
output += ("\n")
|
||||
output += ("%-25s : %d (%s)\n" % ("Need election",
|
||||
len(need_election),
|
||||
" ".join(need_election)))
|
||||
output += ("%-25s : %d (%s)\n" % ("Need appointment",
|
||||
len(without_candidate),
|
||||
" ".join(without_candidate)))
|
||||
output += ("=" * 51)
|
||||
output += ("\n")
|
||||
output += ("%-25s @ %s\n" % ("Stats gathered", as_utctime(now)))
|
||||
|
||||
return output
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Investigate PTL Nominations')
|
||||
parser.add_argument('-v', '--verbose', action="count", default=0,
|
||||
@ -94,45 +141,9 @@ def main():
|
||||
args.basedir = os.path.expanduser(args.basedir)
|
||||
collect_project_stats(args.basedir, args.verbose, args.projects)
|
||||
|
||||
now = datetime.datetime.now(tz=pytz.utc)
|
||||
now = now.replace(microsecond=0)
|
||||
event = utils.get_event('PTL Nominations')
|
||||
start, end = event['start'], event['end']
|
||||
duration = (end - start)
|
||||
remaining = (end - now)
|
||||
progress = (duration - remaining)
|
||||
|
||||
p_progress = as_percentage(progress.total_seconds(),
|
||||
duration.total_seconds())
|
||||
p_candidate = as_percentage(counts['with_candidate'], counts['projects'])
|
||||
p_nominations = as_percentage(counts['nominations'], counts['projects'])
|
||||
|
||||
need_election.sort()
|
||||
without_candidate.sort()
|
||||
|
||||
if args.verbose:
|
||||
print("-" * 51)
|
||||
print("%-25s @ %s" % ("Nominations started", as_utctime(start)))
|
||||
print("%-25s @ %s" % ("Nominations end", as_utctime(end)))
|
||||
print("%-25s : %s" % ("Nominations duration", duration))
|
||||
print("%-25s : %s" % ("Nominations remaining", remaining))
|
||||
print("%-25s : %6.2f%%" % ("Nominations progress", p_progress))
|
||||
print("-" * 51)
|
||||
print("%-25s : %5d" % ("Projects[1]", counts['projects']))
|
||||
print("%-25s : %5d (%6.2f%%)" % ("Projects with candidates",
|
||||
counts['with_candidate'],
|
||||
p_candidate))
|
||||
print("%-25s : %5d (%6.2f%%)" % ("Projects with election",
|
||||
counts['nominations'],
|
||||
p_nominations))
|
||||
print("-" * 51)
|
||||
print("%-25s : %d (%s)" % ("Need election", len(need_election),
|
||||
" ".join(need_election)))
|
||||
print("%-25s : %d (%s)" % ("Need appointment", len(without_candidate),
|
||||
" ".join(without_candidate)))
|
||||
print("=" * 51)
|
||||
print("%-25s @ %s" % ("Stats gathered", as_utctime(now)))
|
||||
|
||||
print(election_summary())
|
||||
print("")
|
||||
print("[1] These numbers include the following projects that have a "
|
||||
"candidate that is approved my only a single election official:"
|
||||
|
@ -2,8 +2,10 @@ from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
from openstack_election.cmds import render_statistics as stats
|
||||
from openstack_election import config
|
||||
from openstack_election import utils
|
||||
|
||||
@ -35,6 +37,11 @@ if conf['election_type'] == 'tc':
|
||||
release=conf['release'],
|
||||
)
|
||||
elif conf['election_type'] == 'ptl':
|
||||
# NOTE(tonyb): We need an empty item last to ensure the path ends in a
|
||||
# tailing '/'
|
||||
stats.collect_project_stats(os.path.join(utils.CANDIDATE_PATH,
|
||||
conf['release'], ''),
|
||||
False, [])
|
||||
ptl_fmt_args = dict(
|
||||
nom_end_date=utils.get_event('PTL Nominations')['end_str'],
|
||||
time_frame=time_frame,
|
||||
@ -42,6 +49,9 @@ elif conf['election_type'] == 'ptl':
|
||||
ending_release=end_release,
|
||||
future_release=end_release.lower(),
|
||||
email_deadline=conf['timeframe']['email_deadline'],
|
||||
num_projects_without_candidates=len(stats.without_candidate),
|
||||
election_summary_stats=stats.election_summary(),
|
||||
leaderless_url=LEADERLESS_URL,
|
||||
)
|
||||
|
||||
|
||||
@ -114,7 +124,7 @@ Happy running,
|
||||
print(email_text % (ptl_fmt_args))
|
||||
|
||||
|
||||
def ptl_nominations_last_days(num_projects_without_candidates):
|
||||
def ptl_nominations_last_days():
|
||||
email_text = """
|
||||
A quick reminder that we are in the last hours for PTL candidate
|
||||
nominations.
|
||||
@ -126,19 +136,21 @@ Make sure your nomination has been submitted to the openstack/election
|
||||
repository and approved by election officials.
|
||||
|
||||
Election statistics[2]:
|
||||
%(election_summary_stats)s
|
||||
|
||||
This means that with approximately 2 days left, %s projects will
|
||||
This means that with approximately 2 days left, %(num_projects_without_candidates)s projects will
|
||||
be deemed leaderless. In this case the TC will oversee PTL selection as
|
||||
described by [3].
|
||||
|
||||
Thank you,
|
||||
|
||||
[1] http://governance.openstack.org/election/#how-to-submit-a-candidacy
|
||||
[2] Assuming the open reviews below are validated
|
||||
[2] Any open reviews at
|
||||
https://review.openstack.org/#/q/is:open+project:openstack/election
|
||||
[3] %s"""
|
||||
have not been factored into these stats.
|
||||
[3] %(leaderless_url)s""" # noqa
|
||||
|
||||
print(email_text % (num_projects_without_candidates, LEADERLESS_URL))
|
||||
print(email_text % (ptl_fmt_args))
|
||||
|
||||
|
||||
def ptl_end_nominations(projects_no_candidates,
|
||||
@ -465,6 +477,7 @@ def main():
|
||||
parser_ptl = cmd_parsers.add_parser('ptl')
|
||||
parser_ptl.add_argument('template',
|
||||
choices=['election_season', 'nominations_kickoff',
|
||||
'nominations_last_days',
|
||||
])
|
||||
parser_tc = cmd_parsers.add_parser('tc')
|
||||
parser_tc.add_argument('template',
|
||||
|
Loading…
Reference in New Issue
Block a user