Package signoff email report, initial revision

Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
Dan McGee 2011-11-03 17:18:55 -05:00
parent 74d2a5df5c
commit 49ac7efd68
4 changed files with 137 additions and 0 deletions

View File

View File

View File

@ -0,0 +1,110 @@
# -*- coding: utf-8 -*-
"""
signoff_report command
Send an email summarizing the state of outstanding signoffs for the given
repository.
Usage: ./manage.py signoff_report <email> <repository>
"""
from django.core.urlresolvers import reverse
from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.db.models import Count
from django.template import loader, Context
from collections import namedtuple
from datetime import datetime, timedelta
import logging
from operator import attrgetter
import sys
from main.models import Package, Repo
from packages.models import Signoff
from packages.utils import get_signoff_groups
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s -> %(levelname)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
stream=sys.stderr)
logger = logging.getLogger()
class Command(BaseCommand):
args = "<email> <repository>"
help = "Send a signoff report for the given repository."
def handle(self, *args, **options):
v = int(options.get('verbosity', None))
if v == 0:
logger.level = logging.ERROR
elif v == 1:
logger.level = logging.INFO
elif v == 2:
logger.level = logging.DEBUG
if len(args) != 2:
raise CommandError("email and repository must be provided")
return generate_report(args[0], args[1])
def generate_report(email, repo_name):
repo = Repo.objects.get(name__iexact=repo_name)
# Collect all existing signoffs for these packages
signoff_groups = sorted(get_signoff_groups([repo]),
key=attrgetter('target_repo', 'arch', 'pkgbase'))
complete = []
incomplete = []
new = []
old = []
new_hours = 24
old_days = 14
now = datetime.utcnow()
new_cutoff = now - timedelta(hours=new_hours)
old_cutoff = now - timedelta(days=old_days)
for group in signoff_groups:
if group.approved():
complete.append(group)
else:
incomplete.append(group)
if group.package.last_update > new_cutoff:
new.append(group)
if group.package.last_update < old_cutoff:
old.append(group)
old.sort(key=attrgetter('last_update'))
proto = 'https'
domain = Site.objects.get_current().domain
signoffs_url = '%s://%s%s' % (proto, domain, reverse('package-signoffs'))
# and the fun bit
Leader = namedtuple('Leader', ['user', 'count'])
leaders = Signoff.objects.filter(created__gt=new_cutoff,
revoked__isnull=True).values_list('user').annotate(
signoff_count=Count('pk')).order_by('-signoff_count')[:5]
users = User.objects.in_bulk([l[0] for l in leaders])
leaders = (Leader(users[l[0]], l[1]) for l in leaders)
subject = 'Signoff report for [%s]' % repo.name.lower()
t = loader.get_template('packages/signoff_report.txt')
c = Context({
'repo': repo,
'signoffs_url': signoffs_url,
'incomplete': incomplete,
'complete': complete,
'new': new,
'new_hours': new_hours,
'old': old,
'old_days': old_days,
'leaders': leaders,
})
from_addr = 'Arch Website Notification <nobody@archlinux.org>'
#send_mail(subject, t.render(c), from_addr, email)
print t.render(c)
# vim: set ts=4 sw=4 et:

View File

@ -0,0 +1,27 @@
=== {% autoescape off %}Signoff report for [{{ repo|lower }}] ===
{{ signoffs_url }}
== New packages in [{{ repo|lower}}] in last {{ new_hours }} hours ({{ new|length }} total) ==
{% for group in new %}
* {{ group.pkgbase }}-{{ group.version }} ({{ group.arch }}){% endfor %}
{% regroup incomplete by target_repo as by_repo %}{% for target_repo in by_repo %}
== Incomplete signoffs for [{{ target_repo.grouper|lower }}] ({{ target_repo.list|length }} total) ==
{% for group in target_repo.list %}
* {{ group.pkgbase }}-{{ group.version }} ({{ group.arch }})
{{ group.completed }}/{{ group.required }} signoffs{% endfor %}
{% endfor %}
== Completed signoffs ({{ complete|length }} total) ==
{% for group in complete %}
* {{ group.pkgbase }}-{{ group.version }} ({{ group.arch }}){% endfor %}
== All packages in [{{ repo|lower }}] for more than {{ old_days }} days ({{ old|length }} total) ==
{% for group in old %}
* {{ group.pkgbase }}-{{ group.version }} ({{ group.arch }}), since {{ group.last_update|date }}{% endfor %}
{% endautoescape %}
== Top five in signoffs in last {{ new_hours }} hours ==
{% for leader in leaders %}
{{ forloop.counter }}. {{ leader.user }} - {{ leader.count }} signoffs{% endfor %}