66850026ca
Bug #16519 in Django deprecates mimetype, so update our code accordingly. Signed-off-by: Dan McGee <dan@archlinux.org>
188 lines
6.9 KiB
Python
188 lines
6.9 KiB
Python
import json
|
|
from operator import attrgetter
|
|
|
|
from django import forms
|
|
from django.contrib.auth.decorators import permission_required
|
|
from django.contrib.auth.models import User
|
|
from django.core.serializers.json import DjangoJSONEncoder
|
|
from django.db import transaction
|
|
from django.http import HttpResponse, Http404
|
|
from django.shortcuts import get_list_or_404, redirect, render
|
|
from django.utils.timezone import now
|
|
from django.views.decorators.cache import never_cache
|
|
|
|
from main.models import Package, Arch, Repo
|
|
from ..models import SignoffSpecification, Signoff
|
|
from ..utils import (get_signoff_groups, approved_by_signoffs,
|
|
PackageSignoffGroup)
|
|
|
|
@permission_required('main.change_package')
|
|
def signoffs(request):
|
|
signoff_groups = sorted(get_signoff_groups(), key=attrgetter('pkgbase'))
|
|
for group in signoff_groups:
|
|
group.user = request.user
|
|
|
|
context = {
|
|
'signoff_groups': signoff_groups,
|
|
'arches': Arch.objects.all(),
|
|
'repo_names': sorted({g.target_repo for g in signoff_groups}),
|
|
}
|
|
return render(request, 'packages/signoffs.html', context)
|
|
|
|
@permission_required('main.change_package')
|
|
@never_cache
|
|
def signoff_package(request, name, repo, arch, revoke=False):
|
|
packages = get_list_or_404(Package, pkgbase=name,
|
|
arch__name=arch, repo__name__iexact=repo, repo__testing=True)
|
|
package = packages[0]
|
|
|
|
spec = SignoffSpecification.objects.get_or_default_from_package(package)
|
|
|
|
if revoke:
|
|
try:
|
|
signoff = Signoff.objects.get_from_package(
|
|
package, request.user, False)
|
|
except Signoff.DoesNotExist:
|
|
raise Http404
|
|
signoff.revoked = now()
|
|
signoff.save()
|
|
created = False
|
|
else:
|
|
# ensure we should even be accepting signoffs
|
|
if spec.known_bad or not spec.enabled:
|
|
return render(request, '403.html', status=403)
|
|
signoff, created = Signoff.objects.get_or_create_from_package(
|
|
package, request.user)
|
|
|
|
all_signoffs = Signoff.objects.for_package(package)
|
|
|
|
if request.is_ajax():
|
|
data = {
|
|
'created': created,
|
|
'revoked': bool(signoff.revoked),
|
|
'approved': approved_by_signoffs(all_signoffs, spec),
|
|
'required': spec.required,
|
|
'enabled': spec.enabled,
|
|
'known_bad': spec.known_bad,
|
|
'user': str(request.user),
|
|
}
|
|
return HttpResponse(json.dumps(data, ensure_ascii=False),
|
|
content_type='application/json')
|
|
|
|
return redirect('package-signoffs')
|
|
|
|
class SignoffOptionsForm(forms.ModelForm):
|
|
apply_all = forms.BooleanField(required=False,
|
|
help_text="Apply these options to all architectures?")
|
|
|
|
class Meta:
|
|
model = SignoffSpecification
|
|
fields = ('required', 'enabled', 'known_bad', 'comments')
|
|
|
|
def _signoff_options_all(request, name, repo):
|
|
seen_ids = set()
|
|
with transaction.commit_on_success():
|
|
# find or create a specification for all architectures, then
|
|
# graft the form data onto them
|
|
packages = Package.objects.filter(pkgbase=name,
|
|
repo__name__iexact=repo, repo__testing=True)
|
|
for package in packages:
|
|
try:
|
|
spec = SignoffSpecification.objects.get_from_package(package)
|
|
if spec.pk in seen_ids:
|
|
continue
|
|
except SignoffSpecification.DoesNotExist:
|
|
spec = SignoffSpecification(pkgbase=package.pkgbase,
|
|
pkgver=package.pkgver, pkgrel=package.pkgrel,
|
|
epoch=package.epoch, arch=package.arch,
|
|
repo=package.repo)
|
|
|
|
if spec.user is None:
|
|
spec.user = request.user
|
|
|
|
form = SignoffOptionsForm(request.POST, instance=spec)
|
|
if form.is_valid():
|
|
form.save()
|
|
seen_ids.add(form.instance.pk)
|
|
|
|
@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]
|
|
|
|
if request.user != package.packager and \
|
|
request.user not in package.maintainers:
|
|
return render(request, '403.html', status=403)
|
|
|
|
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)
|
|
|
|
if spec.user is None:
|
|
spec.user = request.user
|
|
|
|
if request.POST:
|
|
form = SignoffOptionsForm(request.POST, instance=spec)
|
|
if form.is_valid():
|
|
if form.cleaned_data['apply_all']:
|
|
_signoff_options_all(request, name, repo)
|
|
else:
|
|
form.save()
|
|
return redirect('package-signoffs')
|
|
else:
|
|
form = SignoffOptionsForm(instance=spec)
|
|
|
|
context = {
|
|
'packages': packages,
|
|
'package': package,
|
|
'form': form,
|
|
}
|
|
return render(request, 'packages/signoff_options.html', context)
|
|
|
|
class SignoffJSONEncoder(DjangoJSONEncoder):
|
|
'''Base JSONEncoder extended to handle all serialization of all classes
|
|
related to signoffs.'''
|
|
signoff_group_attrs = ['arch', 'last_update', 'maintainers', 'packager',
|
|
'pkgbase', 'repo', 'signoffs', 'target_repo', 'version']
|
|
signoff_spec_attrs = ['required', 'enabled', 'known_bad', 'comments']
|
|
signoff_attrs = ['user', 'created', 'revoked']
|
|
|
|
def default(self, obj):
|
|
if isinstance(obj, PackageSignoffGroup):
|
|
data = {attr: getattr(obj, attr)
|
|
for attr in self.signoff_group_attrs}
|
|
data['pkgnames'] = [p.pkgname for p in obj.packages]
|
|
data['package_count'] = len(obj.packages)
|
|
data['approved'] = obj.approved()
|
|
data.update((attr, getattr(obj.specification, attr))
|
|
for attr in self.signoff_spec_attrs)
|
|
return data
|
|
elif isinstance(obj, Signoff):
|
|
return {attr: getattr(obj, attr) for attr in self.signoff_attrs}
|
|
elif isinstance(obj, Arch) or isinstance(obj, Repo):
|
|
return unicode(obj)
|
|
elif isinstance(obj, User):
|
|
return obj.username
|
|
elif isinstance(obj, set):
|
|
return list(obj)
|
|
return super(SignoffJSONEncoder, self).default(obj)
|
|
|
|
@permission_required('main.change_package')
|
|
def signoffs_json(request):
|
|
signoff_groups = sorted(get_signoff_groups(), key=attrgetter('pkgbase'))
|
|
data = {
|
|
'version': 2,
|
|
'signoff_groups': signoff_groups,
|
|
}
|
|
to_json = json.dumps(data, ensure_ascii=False, cls=SignoffJSONEncoder)
|
|
response = HttpResponse(to_json, content_type='application/json')
|
|
return response
|
|
|
|
# vim: set ts=4 sw=4 et:
|