diff options
-rw-r--r-- | packages/views/__init__.py | 179 | ||||
-rw-r--r-- | packages/views/signoff.py | 187 |
2 files changed, 191 insertions, 175 deletions
diff --git a/packages/views/__init__.py b/packages/views/__init__.py index 4782e457..e02740f2 100644 --- a/packages/views/__init__.py +++ b/packages/views/__init__.py @@ -4,7 +4,6 @@ from django.contrib.admin.widgets import AdminDateWidget from django.contrib.auth.models import User from django.contrib.auth.decorators import permission_required from django.core.serializers.json import DjangoJSONEncoder -from django.db import transaction from django.db.models import Q from django.http import HttpResponse, Http404, HttpResponseForbidden from django.shortcuts import (get_object_or_404, get_list_or_404, @@ -17,21 +16,20 @@ from django.views.generic import list_detail from django.views.generic.simple import direct_to_template from datetime import datetime -from operator import attrgetter from string import Template 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, - SignoffSpecification, Signoff) +from ..models import PackageRelation, PackageGroup from ..utils import (get_group_info, get_differences_info, - get_wrong_permissions, get_signoff_groups, approved_by_signoffs, - PackageSignoffGroup) + get_wrong_permissions) # make other views available from this same package from .flag import flaghelp, flag, flag_confirmed, unflag, unflag_all +from .signoff import signoffs, signoff_package, signoff_options, signoffs_json + class PackageJSONEncoder(DjangoJSONEncoder): pkg_attributes = [ 'pkgname', 'pkgbase', 'repo', 'arch', 'pkgver', @@ -355,175 +353,6 @@ def files_json(request, name, repo, arch): cls=PackageJSONEncoder) return HttpResponse(to_json, mimetype='application/json') - -@permission_required('main.change_package') -@never_cache -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(set(g.target_repo for g in signoff_groups)), - } - return direct_to_template(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 = datetime.utcnow() - 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(simplejson.dumps(data, ensure_ascii=False), - mimetype='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) - 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) - 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 direct_to_template(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 = dict((attr, getattr(obj, attr)) - for attr in self.signoff_group_attrs) - 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): - data = dict((attr, getattr(obj, attr)) - for attr in self.signoff_attrs) - return data - 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') -@never_cache -def signoffs_json(request): - signoff_groups = sorted(get_signoff_groups(), key=attrgetter('pkgbase')) - data = { - 'version': 1, - 'signoff_groups': signoff_groups, - } - to_json = simplejson.dumps(data, ensure_ascii=False, - cls=SignoffJSONEncoder) - response = HttpResponse(to_json, mimetype='application/json') - return response - - def download(request, name, repo, arch): pkg = get_object_or_404(Package, pkgname=name, repo__name__iexact=repo, arch__name=arch) diff --git a/packages/views/signoff.py b/packages/views/signoff.py new file mode 100644 index 00000000..a42c1c66 --- /dev/null +++ b/packages/views/signoff.py @@ -0,0 +1,187 @@ +from datetime import datetime +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 import simplejson +from django.views.decorators.cache import never_cache +from django.views.generic.simple import direct_to_template + +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') +@never_cache +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(set(g.target_repo for g in signoff_groups)), + } + return direct_to_template(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 = datetime.utcnow() + 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(simplejson.dumps(data, ensure_ascii=False), + mimetype='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) + 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) + 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 direct_to_template(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 = dict((attr, getattr(obj, attr)) + for attr in self.signoff_group_attrs) + 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): + data = dict((attr, getattr(obj, attr)) + for attr in self.signoff_attrs) + return data + 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') +@never_cache +def signoffs_json(request): + signoff_groups = sorted(get_signoff_groups(), key=attrgetter('pkgbase')) + data = { + 'version': 1, + 'signoff_groups': signoff_groups, + } + to_json = simplejson.dumps(data, ensure_ascii=False, + cls=SignoffJSONEncoder) + response = HttpResponse(to_json, mimetype='application/json') + return response + +# vim: set ts=4 sw=4 et: |