diff options
author | Dan McGee <dan@archlinux.org> | 2011-11-03 23:18:55 +0100 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2011-11-03 23:19:53 +0100 |
commit | 49ac7efd683152e4936f8013bb7a001470260034 (patch) | |
tree | e282b1709998172d319b5956adef9db6472f5bd8 | |
parent | 74d2a5df5ca7ee4b6497a6e7609491d72cdbb309 (diff) | |
download | archweb-49ac7efd683152e4936f8013bb7a001470260034.tar.gz archweb-49ac7efd683152e4936f8013bb7a001470260034.tar.xz |
Package signoff email report, initial revision
Signed-off-by: Dan McGee <dan@archlinux.org>
-rw-r--r-- | packages/management/__init__.py | 0 | ||||
-rw-r--r-- | packages/management/commands/__init__.py | 0 | ||||
-rw-r--r-- | packages/management/commands/signoff_report.py | 110 | ||||
-rw-r--r-- | templates/packages/signoff_report.txt | 27 |
4 files changed, 137 insertions, 0 deletions
diff --git a/packages/management/__init__.py b/packages/management/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/packages/management/__init__.py diff --git a/packages/management/commands/__init__.py b/packages/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/packages/management/commands/__init__.py diff --git a/packages/management/commands/signoff_report.py b/packages/management/commands/signoff_report.py new file mode 100644 index 0000000..17e58f3 --- /dev/null +++ b/packages/management/commands/signoff_report.py @@ -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: diff --git a/templates/packages/signoff_report.txt b/templates/packages/signoff_report.txt new file mode 100644 index 0000000..84e3fc6 --- /dev/null +++ b/templates/packages/signoff_report.txt @@ -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 %} |