summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan McGee <dan@archlinux.org>2011-11-03 19:10:07 -0500
committerDan McGee <dan@archlinux.org>2011-11-03 19:10:07 -0500
commit8187b87143081a2be75032db91287f9deb9d1f89 (patch)
tree3da2e4f1c38caa2e8f1069daa94c42a73343b535
parente3e3e498765ab416a2902adf114cd3270e3eb12e (diff)
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 <dan@archlinux.org>
-rw-r--r--packages/models.py52
-rw-r--r--packages/urls.py1
-rw-r--r--packages/views.py40
-rw-r--r--templates/packages/signoff_cell.html15
-rw-r--r--templates/packages/signoff_options.html18
-rw-r--r--templates/packages/signoffs.html3
6 files changed, 113 insertions, 16 deletions
diff --git a/packages/models.py b/packages/models.py
index 3c319fe7..a2b53a06 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 576e3279..4d391a3c 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 e102760b..66bcd3fc 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 87216193..0a630119 100644
--- a/templates/packages/signoff_cell.html
+++ b/templates/packages/signoff_cell.html
@@ -1,12 +1,23 @@
+{% spaceless %}
+{% if group.signoffs %}
<ul>
{% for signoff in group.signoffs %}
<li class="signed-username" title="Signed off by {{ signoff.user }}">{{ signoff.user }}{% if signoff.revoked %} (revoked){% endif %}</li>
{% endfor %}
</ul>
+{% endif %}
{% if group.user_signed_off %}
-<div><a class="signoff-link" href="{{ group.package.get_absolute_url }}signoff/revoke/"
+<div>
+ <a class="signoff-link" href="{{ group.package.get_absolute_url }}signoff/revoke/"
title="Revoke signoff {{ group.pkgbase }} for {{ group.arch }}">Revoke Signoff</a></div>
{% else %}
-<div><a class="signoff-link" href="{{ group.package.get_absolute_url }}signoff/"
+<div>
+ <a class="signoff-link" href="{{ group.package.get_absolute_url }}signoff/"
title="Signoff {{ group.pkgbase }} for {{ group.arch }}">Signoff</a></div>
{% endif %}
+{% if group.packager == user %}
+<div>
+ <a class="signoff-options" href="{{ group.package.get_absolute_url }}signoff/options/">Packager Options</a>
+</div>
+{% endif %}
+{% endspaceless %}
diff --git a/templates/packages/signoff_options.html b/templates/packages/signoff_options.html
new file mode 100644
index 00000000..ee9b8b47
--- /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 %}<meta name="robots" content="noindex"/>{% endblock %}
+{% block navbarclass %}anb-packages{% endblock %}
+
+{% block content %}
+<div id="signoff-options" class="box">
+ <h2>Package Signoff Options: {{ package.pkgbase }} {{ package.full_version }} ({{ package.arch.name }})</h2>
+ <form id="signoff-options-form" method="post">{% csrf_token %}
+ <fieldset>
+ {{ form.as_p }}
+ </fieldset>
+ <p><label></label> <input title="Set Signoff Options" type="submit" value="Set Signoff Options" /></p>
+ </form>
+
+</div>
+{% endblock %}
diff --git a/templates/packages/signoffs.html b/templates/packages/signoffs.html
index 0bdc6d46..9bc7fd74 100644
--- a/templates/packages/signoffs.html
+++ b/templates/packages/signoffs.html
@@ -50,8 +50,7 @@
<td>{{ group.packager|default:"Unknown" }}</td>
<td>{{ group.packages|length }}</td>
<td>{{ group.last_update|date }}</td>
- <td class="signoff-{{ group.approved|yesno }}">
- {{ group.approved|yesno|capfirst }}</td>
+ <td class="signoff-{{ group.approved|yesno }}">{{ group.approved|yesno|capfirst }}</td>
<td>{% include "packages/signoff_cell.html" %}</td>
</tr>
{% endfor %}