Commit c5a8c474 authored by Arkadiusz Hiler's avatar Arkadiusz Hiler
Browse files

Stop using RequestContext and use dictionaries



RequestContext is going to be deprecated in future versions of Django in
favor of simple dictionaries.

This requires us to drop the PatchworkRequestContext class and spread
logic it contained around.

Some of the code made it into context processor but most ended up in
generic_list which actually benefits us in better code locality.
Signed-off-by: default avatarArkadiusz Hiler <arkadiusz.hiler@intel.com>
parent 492485df
# Patchwork - automated patch tracking system
# Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
# Copyright (C) 2017 Intel Corporation
#
# This file is part of the Patchwork package.
#
......@@ -17,14 +17,17 @@
# along with Patchwork; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
from __future__ import absolute_import
from django.conf import settings
from django.contrib.sites.models import Site
from django.template import RequestContext
from patchwork.filters import Filters
from patchwork.models import Bundle, Project
from patchwork.models import Bundle
def settings(request):
return {'settings': settings}
def site(request):
return {'site': Site.objects.get_current()}
def bundle(request):
......@@ -32,62 +35,3 @@ def bundle(request):
if not user.is_authenticated():
return {}
return {'bundles': Bundle.objects.filter(owner=user)}
class PatchworkRequestContext(RequestContext):
def __init__(self, request, project=None,
dict=None, processors=None,
list_view=None, list_view_params={}):
self._project = project
self.filters = Filters(request)
if processors is None:
processors = []
processors.append(bundle)
super(PatchworkRequestContext, self).__init__(
request, dict, processors)
self.update({
'filters': self.filters,
'messages': [],
})
if list_view:
params = self.filters.params()
for param in ['order', 'page']:
data = {}
if request.method == 'GET':
data = request.GET
elif request.method == 'POST':
data = request.POST
value = data.get(param, None)
if value:
params.append((param, value))
self.update({
'list_view': {
'view': list_view,
'view_params': list_view_params,
'params': params
}})
self.projects = Project.objects.all()
self.update({
'project': self.project,
'site': Site.objects.get_current(),
'settings': settings,
'other_projects': len(self.projects) > 1
})
def _set_project(self, project):
self._project = project
self.filters.set_project(project)
self.update({'project': self._project})
def _get_project(self):
return self._project
project = property(_get_project, _set_project)
def add_message(self, message):
self['messages'].append(message)
......@@ -19,7 +19,6 @@
from django.conf import settings
from django.core import mail
from django.template import Context
from django.template.loader import render_to_string
......@@ -50,10 +49,10 @@ class ReviewerNotification(NotificationEmail):
self.series = series
self.user = user
self.reviewer = reviewer
self.ctx = Context({'series': series,
'series_url': series_url,
'user': user,
'reviewer': reviewer})
self.ctx = {'series': series,
'series_url': series_url,
'user': user,
'reviewer': reviewer}
def send(self):
# do not notify if the reviewer is the same person that has set this
......
......@@ -83,6 +83,9 @@ if django.VERSION >= (1, 8):
'django.template.context_processors.static',
'django.template.context_processors.tz',
'django.contrib.messages.context_processors.messages',
'patchwork.context_processors.settings',
'patchwork.context_processors.site',
'patchwork.context_processors.bundle',
],
},
},
......
......@@ -127,6 +127,9 @@ bundle_actions = ['create', 'add', 'remove']
def set_bundle(user, project, action, data, patches, context):
# set up the bundle
bundle = None
if 'messages' not in context:
context['messages'] = []
if action == 'create':
bundle_name = data['bundle_name'].strip()
if '/' in bundle_name:
......@@ -141,7 +144,7 @@ def set_bundle(user, project, action, data, patches, context):
bundle = Bundle(owner=user, project=project,
name=bundle_name)
bundle.save()
context.add_message("Bundle %s created" % bundle.name)
context['messages'] += ["Bundle %s created" % bundle.name]
elif action == 'add':
bundle = get_object_or_404(Bundle, id=data['bundle_id'])
......@@ -158,18 +161,18 @@ def set_bundle(user, project, action, data, patches, context):
patch=patch).count()
if bundlepatch_count == 0:
bundle.append_patch(patch)
context.add_message("Patch '%s' added to bundle %s" %
(patch.name, bundle.name))
context['messages'] += ["Patch '%s' added to bundle %s" %
(patch.name, bundle.name)]
else:
context.add_message("Patch '%s' already in bundle %s" %
(patch.name, bundle.name))
context['messages'] += ["Patch '%s' already in bundle %s" %
(patch.name, bundle.name)]
elif action == 'remove':
try:
bp = BundlePatch.objects.get(bundle=bundle, patch=patch)
bp.delete()
context.add_message("Patch '%s' removed from bundle %s\n" %
(patch.name, bundle.name))
context['messages'] += ["Patch '%s' removed from bundle %s\n" %
(patch.name, bundle.name)]
except Exception:
pass
......
......@@ -32,17 +32,35 @@ from patchwork.utils import Order, get_patch_ids, bundle_actions, set_bundle
from patchwork.paginator import Paginator
from patchwork.forms import MultiplePatchForm
from patchwork.models import Comment, Patch
from patchwork.filters import Filters
def generic_list(request, project, view,
view_args={}, filter_settings=[], patches=None,
editable_order=False):
context = PatchworkRequestContext(request,
list_view=view,
list_view_params=view_args)
filters = Filters(request)
params = filters.params()
for param in ['order', 'page']:
data = {}
if request.method == 'GET':
data = request.GET
elif request.method == 'POST':
data = request.POST
value = data.get(param, None)
if value:
params.append((param, value))
context = {
'messages': [],
'project': project,
'filters': filters,
'projects': Project.objects.all(),
'list_view': {'view': view, 'view_params': view_args, 'params': params},
}
context.project = project
data = {}
if request.method == 'GET':
data = request.GET
......@@ -92,11 +110,11 @@ def generic_list(request, project, view,
for (filterclass, setting) in filter_settings:
if isinstance(setting, dict):
context.filters.set_status(filterclass, **setting)
context['filters'].set_status(filterclass, **setting)
elif isinstance(setting, list):
context.filters.set_status(filterclass, *setting)
context['filters'].set_status(filterclass, *setting)
else:
context.filters.set_status(filterclass, setting)
context['filters'].set_status(filterclass, setting)
if patches is None:
patches = Patch.objects.filter(project=project)
......@@ -104,7 +122,7 @@ def generic_list(request, project, view,
# annotate with tag counts
patches = patches.with_tag_counts(project)
patches = context.filters.apply(patches)
patches = context['filters'].apply(patches)
if not editable_order:
patches = order.apply(patches)
......@@ -134,7 +152,7 @@ def process_multiplepatch_form(form, user, action, patches, context):
return ['The submitted form data was invalid']
if len(patches) == 0:
context.add_message("No patches selected; nothing updated")
context['messsages'] += ["No patches selected; nothing updated"]
return errors
changed_patches = 0
......@@ -148,11 +166,11 @@ def process_multiplepatch_form(form, user, action, patches, context):
form.save(patch)
if changed_patches == 1:
context.add_message("1 patch updated")
context['messages'] += ["1 patch updated"]
elif changed_patches > 1:
context.add_message("%d patches updated" % changed_patches)
context['messages'] += ["%d patches updated" % changed_patches]
else:
context.add_message("No patches updated")
context['messages'] += ["No patches updated"]
return errors
......
......@@ -25,16 +25,14 @@ from django.conf import settings
from django.core import urlresolvers
from django.db.models import Q
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response, get_object_or_404
from django.shortcuts import render, get_object_or_404
from django.template.loader import render_to_string
from patchwork.models import (Project, Person, EmailConfirmation, User,
user_name)
from patchwork.requestcontext import PatchworkRequestContext
def projects(request):
context = PatchworkRequestContext(request)
projects = Project.objects.all()
if projects.count() == 1:
......@@ -42,29 +40,27 @@ def projects(request):
urlresolvers.reverse('patch_list',
kwargs={'project_id': projects[0].linkname}))
context['projects'] = projects
return render_to_response('patchwork/projects.html', context)
return render(request, 'patchwork/projects.html', {'projects': projects})
def pwclientrc(request, project_id):
project = get_object_or_404(Project, linkname=project_id)
context = PatchworkRequestContext(request)
context.project = project
context = {'project': project}
if settings.FORCE_HTTPS_LINKS or request.is_secure():
context['scheme'] = 'https'
else:
context['scheme'] = 'http'
response = HttpResponse(content_type="text/plain")
response['Content-Disposition'] = 'attachment; filename=.pwclientrc'
response.write(render_to_string('patchwork/pwclientrc', context))
response.write(render_to_string('patchwork/pwclientrc',
context, request=request))
return response
def pwclient(request):
context = PatchworkRequestContext(request)
response = HttpResponse(content_type="text/x-python")
response['Content-Disposition'] = 'attachment; filename=pwclient'
response.write(render_to_string('patchwork/pwclient', context))
response.write(render_to_string('patchwork/pwclient', {}, request=request))
return response
......@@ -85,14 +81,13 @@ def confirm(request, key):
if conf.active and conf.is_valid():
return views[conf.type](request, conf)
context = PatchworkRequestContext(request)
context['conf'] = conf
context = {'conf': conf}
if not conf.active:
context['error'] = 'inactive'
elif not conf.is_valid():
context['error'] = 'expired'
return render_to_response('patchwork/confirm-error.html', context)
return render(request, 'patchwork/confirm-error.html', context)
def submitter_complete(request):
......@@ -163,8 +158,6 @@ if settings.ENABLE_XMLRPC:
def help(request, path):
context = PatchworkRequestContext(request)
if path in help_pages:
return render_to_response(
'patchwork/help/' + help_pages[path], context)
return render(request, 'patchwork/help/' + help_pages[path], {})
raise Http404
......@@ -23,20 +23,17 @@ from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from django.http import (HttpResponse, HttpResponseRedirect,
HttpResponseNotFound)
from django.shortcuts import render_to_response, get_object_or_404
from django.shortcuts import render, get_object_or_404
from patchwork.filters import DelegateFilter
from patchwork.forms import BundleForm, DeleteBundleForm
from patchwork.models import Patch, Bundle, BundlePatch, Project
from patchwork.requestcontext import PatchworkRequestContext
from patchwork.utils import get_patch_ids
from patchwork.views import generic_list, patch_to_mbox
@login_required
def setbundle(request):
context = PatchworkRequestContext(request)
bundle = None
if request.method == 'POST':
......@@ -91,9 +88,6 @@ def setbundle(request):
bundle = get_object_or_404(Bundle, owner=request.user,
id=request.POST['bundle_id'])
if 'error' in context:
pass
if bundle:
return HttpResponseRedirect(
reverse('bundle', kwargs={'bundle_id': bundle.id})
......@@ -106,8 +100,6 @@ def setbundle(request):
@login_required
def bundles(request, project_id=None):
context = PatchworkRequestContext(request)
if request.method == 'POST':
form_name = request.POST.get('form_name', '')
......@@ -128,10 +120,8 @@ def bundles(request, project_id=None):
bundle.delete_form = DeleteBundleForm(auto_id=False,
initial={'bundle_id': bundle.id})
context['bundles'] = bundles
context['project'] = project
return render_to_response('patchwork/bundles.html', context)
return render(request, 'patchwork/bundles.html',
{'bundles': bundles, 'project': project})
def bundle(request, username, bundlename):
......@@ -192,7 +182,7 @@ def bundle(request, username, bundlename):
context['bundle'] = bundle
context['bundleform'] = form
return render_to_response('patchwork/bundle.html', context)
return render(request, 'patchwork/bundle.html', context)
def mbox(request, username, bundlename):
......
......@@ -23,36 +23,30 @@ from django.conf import settings as conf_settings
from django.core.mail import send_mail
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.shortcuts import render
from django.template.loader import render_to_string
from patchwork.forms import OptinoutRequestForm, EmailForm
from patchwork.models import EmailOptout, EmailConfirmation
from patchwork.requestcontext import PatchworkRequestContext
def settings(request):
context = PatchworkRequestContext(request)
if request.method == 'POST':
form = EmailForm(data=request.POST)
if form.is_valid():
email = form.cleaned_data['email']
is_optout = EmailOptout.objects.filter(email=email).count() > 0
context.update({
'email': email,
'is_optout': is_optout,
})
return render_to_response('patchwork/mail-settings.html', context)
return render(request,
'patchwork/mail-settings.html',
{'email': email,
'is_optout': is_optout})
else:
form = EmailForm()
context['form'] = form
return render_to_response('patchwork/mail-form.html', context)
return render(request, 'patchwork/mail-form.html', {'form': form})
def optout_confirm(request, conf):
context = PatchworkRequestContext(request)
email = conf.email.strip().lower()
# silently ignore duplicated optouts
if EmailOptout.objects.filter(email=email).count() == 0:
......@@ -60,25 +54,21 @@ def optout_confirm(request, conf):
optout.save()
conf.deactivate()
context['email'] = conf.email
return render_to_response('patchwork/optout.html', context)
return render(request, 'patchwork/optout.html', {'email': conf.email})
def optin_confirm(request, conf):
context = PatchworkRequestContext(request)
email = conf.email.strip().lower()
EmailOptout.objects.filter(email=email).delete()
conf.deactivate()
context['email'] = conf.email
return render_to_response('patchwork/optin.html', context)
return render(request, 'patchwork/optin.html', {'email': conf.email})
def optinout(request, action, description):
context = PatchworkRequestContext(request)
context = {}
mail_template = 'patchwork/%s-request.mail' % action
html_template = 'patchwork/%s-request.html' % action
......@@ -92,7 +82,7 @@ def optinout(request, action, description):
'Please review the form and re-submit.') % \
description
context['form'] = form
return render_to_response(html_template, context)
return render(request, html_template, context)
email = form.cleaned_data['email']
if action == 'optin' and \
......@@ -101,7 +91,7 @@ def optinout(request, action, description):
'patchwork opt-out list, so you don\'t ' +
'need to opt back in') % email
context['form'] = form
return render_to_response(html_template, context)
return render(request, html_template, context)
conf = EmailConfirmation(type=action, email=email)
conf.save()
......@@ -117,7 +107,7 @@ def optinout(request, action, description):
'Please try again later.')
context['admins'] = conf_settings.ADMINS
return render_to_response(html_template, context)
return render(request, html_template, context)
def optout(request):
......
......@@ -20,20 +20,18 @@
from __future__ import absolute_import
from django.http import HttpResponse, HttpResponseForbidden, Http404
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import six
from patchwork.forms import PatchForm, CreateBundleForm
from patchwork.models import Patch, Project, Bundle, TestResult
from patchwork.requestcontext import PatchworkRequestContext
from patchwork.views import generic_list, patch_to_mbox
def patch(request, patch_id):
context = PatchworkRequestContext(request)
patch = get_object_or_404(Patch, id=patch_id)
context.project = patch.project
editable = patch.is_editable(request.user)
messages = []
form = None
createbundleform = None
......@@ -57,7 +55,7 @@ def patch(request, patch_id):
bundle.append_patch(patch)
bundle.save()
createbundleform = CreateBundleForm()
context.add_message('Bundle %s created' % bundle.name)
messages += ['Bundle %s created' % bundle.name]
elif action == 'addtobundle':
bundle = get_object_or_404(
......@@ -65,10 +63,10 @@ def patch(request, patch_id):
try:
bundle.append_patch(patch)
bundle.save()
context.add_message('Patch added to bundle "%s"' % bundle.name)
messages += ['Patch added to bundle "%s"' % bundle.name]
except Exception as ex:
context.add_message("Couldn't add patch '%s' to bundle %s: %s"
% (patch.name, bundle.name, ex.message))
messages += ["Couldn't add patch '%s' to bundle %s: %s"
% (patch.name, bundle.name, ex.message)]
# all other actions require edit privs
elif not editable:
......@@ -78,18 +76,20 @@ def patch(request, patch_id):
form = PatchForm(data=request.POST, instance=patch)
if form.is_valid():
form.save()
context.add_message('Patch updated')
messages += ['Patch updated']
context['patch'] = patch
context['series'] = patch.series()
context['patchform'] = form
context['createbundleform'] = createbundleform
context['project'] = patch.project
context['test_results'] = TestResult.objects \
.filter(revision=None, patch=patch) \
.order_by('test__name').select_related('test')
context = {
'series': patch.series(),
'patch': patch,
'patchform': form,
'createbundleform': createbundleform,
'project': patch.project,
'messages': messages,
'test_results': TestResult.objects
.filter(revision=None, patch=patch)
.order_by('test__name').select_related('test')}
return render_to_response('patchwork/patch.html', context)
return render(request, 'patchwork/patch.html', context)
def content(request, patch_id):
......@@ -122,7 +122,7 @@ def list(request, project_id):
project = get_object_or_404(Project, linkname=project_id)
context = generic_list(request, project, 'patch_list',
view_args={'project_id': project.linkname})
return render_to_response('patchwork/list.html', context)
return render(request, 'patchwork/list.html', context)
def _get_patch_or_404(request, msgid):
......
......@@ -23,13 +23,11 @@ from django.contrib.auth.models import User
from django.shortcuts import render_to_response, get_object_or_404
from patchwork.models import Patch, Project, Series
from patchwork.requestcontext import PatchworkRequestContext
def project(request, project_id):
context = PatchworkRequestContext(request)
project = get_object_or_404(Project, linkname=project_id)
context.project = project
context = {'project': project}
context['maintainers'] = User.objects.filter(
profile__maintainer_projects=project)
......
......@@ -26,7 +26,7 @@ from django.conf import settings
from django.core.mail import send_mail
from django.core import urlresolvers
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.shortcuts import render, get_object_or_404
from django.template.loader import render_to_string
from patchwork.filters import DelegateFilter
......@@ -34,12 +34,12 @@ from patchwork.forms import (UserProfileForm, UserPersonLinkForm,
RegistrationForm)
from patchwork.models import (Project, Bundle, Person, EmailConfirmation,
State, EmailOptout)