patch.py 4.96 KB
Newer Older
Jeremy Kerr's avatar
Jeremy Kerr committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Patchwork - automated patch tracking system
# Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
#
# This file is part of the Patchwork package.
#
# Patchwork is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Patchwork is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Patchwork; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

20
from __future__ import absolute_import
Jeremy Kerr's avatar
Jeremy Kerr committed
21

22
from django.http import HttpResponse, HttpResponseForbidden, Http404
Stephen Finucane's avatar
Stephen Finucane committed
23
24
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.utils import six
Stephen Finucane's avatar
Stephen Finucane committed
25
26
27
28

from patchwork.forms import PatchForm, CreateBundleForm
from patchwork.models import Patch, Project, Bundle, TestResult
from patchwork.requestcontext import PatchworkRequestContext
29
from patchwork.views import generic_list, patch_to_mbox
Jeremy Kerr's avatar
Jeremy Kerr committed
30

31

Jeremy Kerr's avatar
Jeremy Kerr committed
32
33
34
35
36
37
38
39
40
41
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)

    form = None
    createbundleform = None

    if editable:
42
        form = PatchForm(instance=patch)
Jeremy Kerr's avatar
Jeremy Kerr committed
43
44
45
46
47
48
49
50
51
    if request.user.is_authenticated():
        createbundleform = CreateBundleForm()

    if request.method == 'POST':
        action = request.POST.get('action', None)
        if action:
            action = action.lower()

        if action == 'createbundle':
52
53
54
            bundle = Bundle(owner=request.user, project=patch.project)
            createbundleform = CreateBundleForm(instance=bundle,
                                                data=request.POST)
Jeremy Kerr's avatar
Jeremy Kerr committed
55
56
            if createbundleform.is_valid():
                createbundleform.save()
Jeremy Kerr's avatar
Jeremy Kerr committed
57
                bundle.append_patch(patch)
Jeremy Kerr's avatar
Jeremy Kerr committed
58
59
60
61
62
                bundle.save()
                createbundleform = CreateBundleForm()
                context.add_message('Bundle %s created' % bundle.name)

        elif action == 'addtobundle':
63
64
            bundle = get_object_or_404(
                Bundle, id=request.POST.get('bundle_id'))
Jeremy Kerr's avatar
Jeremy Kerr committed
65
66
67
68
            try:
                bundle.append_patch(patch)
                bundle.save()
                context.add_message('Patch added to bundle "%s"' % bundle.name)
Stephen Finucane's avatar
Stephen Finucane committed
69
            except Exception as ex:
70
71
                context.add_message("Couldn't add patch '%s' to bundle %s: %s"
                                    % (patch.name, bundle.name, ex.message))
Jeremy Kerr's avatar
Jeremy Kerr committed
72

73
        # all other actions require edit privs
Jeremy Kerr's avatar
Jeremy Kerr committed
74
75
76
77
        elif not editable:
            return HttpResponseForbidden()

        elif action is None:
78
            form = PatchForm(data=request.POST, instance=patch)
Jeremy Kerr's avatar
Jeremy Kerr committed
79
80
81
82
83
84
85
86
            if form.is_valid():
                form.save()
                context.add_message('Patch updated')

    context['patch'] = patch
    context['patchform'] = form
    context['createbundleform'] = createbundleform
    context['project'] = patch.project
87
    context['test_results'] = TestResult.objects \
88
89
        .filter(revision=None, patch=patch) \
        .order_by('test__name').select_related('test')
Jeremy Kerr's avatar
Jeremy Kerr committed
90
91
92

    return render_to_response('patchwork/patch.html', context)

93

Jeremy Kerr's avatar
Jeremy Kerr committed
94
95
def content(request, patch_id):
    patch = get_object_or_404(Patch, id=patch_id)
96
    response = HttpResponse(content_type="text/x-patch")
Jeremy Kerr's avatar
Jeremy Kerr committed
97
98
99
100
101
    response.write(patch.content)
    response['Content-Disposition'] = 'attachment; filename=' + \
        patch.filename().replace(';', '').replace('\n', '')
    return response

102

Jeremy Kerr's avatar
Jeremy Kerr committed
103
104
def mbox(request, patch_id):
    patch = get_object_or_404(Patch, id=patch_id)
105
106
107
108
    options = {
        'patch-link': request.GET.get('link', None),
        'request': request,
    }
109
    response = HttpResponse(content_type="text/plain")
Stephen Finucane's avatar
Stephen Finucane committed
110
111
    # NOTE(stephenfin) http://stackoverflow.com/a/28584090/613428
    if six.PY3:
112
        response.write(patch_to_mbox(patch, options).as_bytes(True).decode())
Stephen Finucane's avatar
Stephen Finucane committed
113
    else:
114
        response.write(patch_to_mbox(patch, options).as_string(True))
Jeremy Kerr's avatar
Jeremy Kerr committed
115
116
117
118
119
120
121
122
    response['Content-Disposition'] = 'attachment; filename=' + \
        patch.filename().replace(';', '').replace('\n', '')
    return response


def list(request, project_id):
    project = get_object_or_404(Project, linkname=project_id)
    context = generic_list(request, project, 'patchwork.views.patch.list',
123
                           view_args={'project_id': project.linkname})
Jeremy Kerr's avatar
Jeremy Kerr committed
124
    return render_to_response('patchwork/list.html', context)
125

126

127
128
129
130
131
132
133
def _get_patch_or_404(request, msgid):
    patch = Patch.objects.filter(msgid='<' + msgid + '>').first()
    if patch is None:
        raise Http404("Patch not found")
    return patch


134
def msgid(request, msgid):
135
    patch = _get_patch_or_404(Patch, msgid)
136
    return redirect(patch)