From 8187b87143081a2be75032db91287f9deb9d1f89 Mon Sep 17 00:00:00 2001 From: Dan McGee Date: Thu, 3 Nov 2011 19:10:07 -0500 Subject: Add signoff options form and data entry page This allows the criteria and other information about certain signoffs to be overridden as necessary. Signed-off-by: Dan McGee --- packages/models.py | 52 ++++++++++++++++++++++++++------- packages/urls.py | 1 + packages/views.py | 40 ++++++++++++++++++++++++- templates/packages/signoff_cell.html | 15 ++++++++-- templates/packages/signoff_options.html | 18 ++++++++++++ templates/packages/signoffs.html | 3 +- 6 files changed, 113 insertions(+), 16 deletions(-) create mode 100644 templates/packages/signoff_options.html diff --git a/packages/models.py b/packages/models.py index 3c319fe..a2b53a0 100644 --- a/packages/models.py +++ b/packages/models.py @@ -38,6 +38,22 @@ class PackageRelation(models.Model): class Meta: unique_together = (('pkgbase', 'user', 'type'),) + +class SignoffSpecificationManager(models.Manager): + def get_from_package(self, pkg): + '''Utility method to pull all relevant name-version fields from a + package and get a matching specification.''' + return self.get( + pkgbase=pkg.pkgbase, pkgver=pkg.pkgver, pkgrel=pkg.pkgrel, + epoch=pkg.epoch, arch=pkg.arch, repo=pkg.repo) + + def get_or_create_from_package(self, pkg): + '''Utility method to pull all relevant name-version fields from a + package and get or create a matching specification.''' + return self.get_or_create( + pkgbase=pkg.pkgbase, pkgver=pkg.pkgver, pkgrel=pkg.pkgrel, + epoch=pkg.epoch, arch=pkg.arch, repo=pkg.repo) + class SignoffSpecification(models.Model): ''' A specification for the signoff policy for this particular revision of a @@ -53,25 +69,40 @@ class SignoffSpecification(models.Model): repo = models.ForeignKey('main.Repo') user = models.ForeignKey(User) created = models.DateTimeField(editable=False) - required = models.PositiveIntegerField(default=2) - enabled = models.BooleanField(default=True) - known_bad = models.BooleanField(default=False) + required = models.PositiveIntegerField(default=2, + help_text="How many signoffs are required for this package?") + enabled = models.BooleanField(default=True, + help_text="Is this package eligible for signoffs?") + known_bad = models.BooleanField(default=False, + help_text="Is package is known to be broken in some way?") comments = models.TextField(null=True, blank=True) + objects = SignoffSpecificationManager() + + @property + def full_version(self): + if self.epoch > 0: + return u'%d:%s-%s' % (self.epoch, self.pkgver, self.pkgrel) + return u'%s-%s' % (self.pkgver, self.pkgrel) + + def __unicode__(self): + return u'%s-%s' % (self.pkgbase, self.full_version) + + class SignoffManager(models.Manager): def get_from_package(self, pkg, user, revoked=False): '''Utility method to pull all relevant name-version fields from a - package and create a matching signoff.''' + package and get a matching signoff.''' not_revoked = not revoked - return Signoff.objects.get( + return self.get( pkgbase=pkg.pkgbase, pkgver=pkg.pkgver, pkgrel=pkg.pkgrel, epoch=pkg.epoch, arch=pkg.arch, repo=pkg.repo, revoked__isnull=not_revoked, user=user) def get_or_create_from_package(self, pkg, user): '''Utility method to pull all relevant name-version fields from a - package and create a matching signoff.''' - return Signoff.objects.get_or_create( + package and get or create a matching signoff.''' + return self.get_or_create( pkgbase=pkg.pkgbase, pkgver=pkg.pkgver, pkgrel=pkg.pkgrel, epoch=pkg.epoch, arch=pkg.arch, repo=pkg.repo, revoked=None, user=user) @@ -196,9 +227,8 @@ def remove_inactive_maintainers(sender, instance, created, **kwargs): post_save.connect(remove_inactive_maintainers, sender=User, dispatch_uid="packages.models") -pre_save.connect(set_created_field, sender=PackageRelation, - dispatch_uid="packages.models") -pre_save.connect(set_created_field, sender=Signoff, - dispatch_uid="packages.models") +for sender in (PackageRelation, SignoffSpecification, Signoff): + pre_save.connect(set_created_field, sender=sender, + dispatch_uid="packages.models") # vim: set ts=4 sw=4 et: diff --git a/packages/urls.py b/packages/urls.py index 576e327..4d391a3 100644 --- a/packages/urls.py +++ b/packages/urls.py @@ -11,6 +11,7 @@ package_patterns = patterns('packages.views', (r'^unflag/all/$', 'unflag_all'), (r'^signoff/$', 'signoff_package'), (r'^signoff/revoke/$', 'signoff_package', {'revoke': True}), + (r'^signoff/options/$', 'signoff_options'), (r'^download/$', 'download'), ) diff --git a/packages/views.py b/packages/views.py index e102760..66bcd3f 100644 --- a/packages/views.py +++ b/packages/views.py @@ -25,7 +25,7 @@ from urllib import urlencode from main.models import Package, PackageFile, Arch, Repo from main.utils import make_choice from mirrors.models import MirrorUrl -from .models import PackageRelation, PackageGroup, Signoff +from .models import PackageRelation, PackageGroup, SignoffSpecification, Signoff from .utils import (get_group_info, get_differences_info, get_wrong_permissions, get_signoff_groups, approved_by_signoffs) @@ -417,6 +417,44 @@ def signoff_package(request, name, repo, arch, revoke=False): return redirect('package-signoffs') +class SignoffOptionsForm(forms.ModelForm): + class Meta: + model = SignoffSpecification + fields = ('required', 'enabled', 'known_bad', 'comments') + +@permission_required('main.change_package') +@never_cache +def signoff_options(request, name, repo, arch): + packages = get_list_or_404(Package, pkgbase=name, + arch__name=arch, repo__name__iexact=repo, repo__testing=True) + package = packages[0] + + # TODO ensure submitter is maintainer and/or packager + + try: + spec = SignoffSpecification.objects.get_from_package(package) + except SignoffSpecification.DoesNotExist: + # create a fake one, but don't save it just yet + spec = SignoffSpecification(pkgbase=package.pkgbase, + pkgver=package.pkgver, pkgrel=package.pkgrel, + epoch=package.epoch, arch=package.arch, repo=package.repo) + spec.user = request.user + + if request.POST: + form = SignoffOptionsForm(request.POST, instance=spec) + if form.is_valid(): + form.save() + return redirect('package-signoffs') + else: + form = SignoffOptionsForm(instance=spec) + + context = { + 'packages': packages, + 'package': package, + 'form': form, + } + return direct_to_template(request, 'packages/signoff_options.html', context) + def flaghelp(request): return direct_to_template(request, 'packages/flaghelp.html') diff --git a/templates/packages/signoff_cell.html b/templates/packages/signoff_cell.html index 8721619..0a63011 100644 --- a/templates/packages/signoff_cell.html +++ b/templates/packages/signoff_cell.html @@ -1,12 +1,23 @@ +{% spaceless %} +{% if group.signoffs %} +{% endif %} {% if group.user_signed_off %} -
+ Revoke Signoff
{% else %} -
+ Signoff
{% endif %} +{% if group.packager == user %} +
+ Packager Options +
+{% endif %} +{% endspaceless %} diff --git a/templates/packages/signoff_options.html b/templates/packages/signoff_options.html new file mode 100644 index 0000000..ee9b8b4 --- /dev/null +++ b/templates/packages/signoff_options.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} + +{% block title %}Arch Linux - Package Signoff Options - {{ package.pkgbase }} {{ package.full_version }} ({{ package.arch.name }}){% endblock %} +{% block head %}{% endblock %} +{% block navbarclass %}anb-packages{% endblock %} + +{% block content %} +
+

Package Signoff Options: {{ package.pkgbase }} {{ package.full_version }} ({{ package.arch.name }})

+
{% csrf_token %} +
+ {{ form.as_p }} +
+

+
+ +
+{% endblock %} diff --git a/templates/packages/signoffs.html b/templates/packages/signoffs.html index 0bdc6d4..9bc7fd7 100644 --- a/templates/packages/signoffs.html +++ b/templates/packages/signoffs.html @@ -50,8 +50,7 @@ {{ group.packager|default:"Unknown" }} {{ group.packages|length }} {{ group.last_update|date }} - - {{ group.approved|yesno|capfirst }} + {{ group.approved|yesno|capfirst }} {% include "packages/signoff_cell.html" %} {% endfor %} -- cgit v1.2.3-24-g4f1b