Inital commit
[patchwork] / apps / patchwork / views / patch.py
1 # Patchwork - automated patch tracking system
2 # Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
3 #
4 # This file is part of the Patchwork package.
5 #
6 # Patchwork is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # Patchwork is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with Patchwork; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20
21 from patchwork.models import Patch, Project, Person, RegistrationRequest, Bundle
22 from patchwork.filters import Filters
23 from patchwork.forms import RegisterForm, LoginForm, PatchForm, MultiplePatchForm, CreateBundleForm
24 from patchwork.utils import get_patch_ids, set_patches, Order
25 from patchwork.requestcontext import PatchworkRequestContext
26 from django.shortcuts import render_to_response, get_object_or_404
27 from django.http import HttpResponse, HttpResponseRedirect, \
28              HttpResponseForbidden
29 from django.contrib.auth.models import User
30 from django.contrib.auth.decorators import login_required
31 from django.contrib.auth import authenticate, login
32 import django.core.urlresolvers
33 from patchwork.paginator import Paginator
34 from patchwork.views import generic_list
35
36 def patch(request, patch_id):
37     context = PatchworkRequestContext(request)
38     patch = get_object_or_404(Patch, id=patch_id)
39     context.project = patch.project
40     editable = patch.is_editable(request.user)
41     messages = []
42
43     form = None
44     createbundleform = None
45
46     if editable:
47         form = PatchForm(instance = patch)
48     if request.user.is_authenticated():
49         createbundleform = CreateBundleForm()
50
51     if request.method == 'POST':
52         action = request.POST.get('action', None)
53         if action:
54             action = action.lower()
55
56         if action == 'createbundle':
57             bundle = Bundle(owner = request.user, project = patch.project)
58             createbundleform = CreateBundleForm(instance = bundle,
59                     data = request.POST)
60             if createbundleform.is_valid():
61                 createbundleform.save()
62                 bundle.patches.add(patch)
63                 bundle.save()
64                 createbundleform = CreateBundleForm()
65                 context.add_message('Bundle %s created' % bundle.name)
66
67         elif action == 'addtobundle':
68             bundle = get_object_or_404(Bundle, id = \
69                         request.POST.get('bundle_id'))
70             bundle.patches.add(patch)
71             bundle.save()
72             context.add_message('Patch added to bundle "%s"' % bundle.name)
73
74         # all other actions require edit privs
75         elif not editable:
76             return HttpResponseForbidden()
77
78         elif action is None:
79             form = PatchForm(data = request.POST, instance = patch)
80             if form.is_valid():
81                 form.save()
82                 context.add_message('Patch updated')
83
84         elif action == 'archive':
85             patch.archived = True
86             patch.save()
87             context.add_message('Patch archived')
88
89         elif action == 'unarchive':
90             patch.archived = False
91             patch.save()
92             context.add_message('Patch un-archived')
93
94         elif action == 'ack':
95             pass
96
97         elif action == 'delete':
98             patch.delete()
99
100
101     context['patch'] = patch
102     context['patchform'] = form
103     context['createbundleform'] = createbundleform
104     context['project'] = patch.project
105
106     return render_to_response('patchwork/patch.html', context)
107
108 def content(request, patch_id):
109     patch = get_object_or_404(Patch, id=patch_id)
110     response = HttpResponse(mimetype="text/x-patch")
111     response.write(patch.content)
112     response['Content-Disposition'] = 'attachment; filename=' + \
113         patch.filename().replace(';', '').replace('\n', '')
114     return response
115
116 def mbox(request, patch_id):
117     patch = get_object_or_404(Patch, id=patch_id)
118     response = HttpResponse(mimetype="text/plain")
119     response.write(patch.mbox().as_string(True))
120     response['Content-Disposition'] = 'attachment; filename=' + \
121         patch.filename().replace(';', '').replace('\n', '')
122     return response
123
124
125 def list(request, project_id):
126     project = get_object_or_404(Project, linkname=project_id)
127     context = generic_list(request, project, 'patchwork.views.patch.list',
128             view_args = {'project_id': project.linkname})
129     return render_to_response('patchwork/list.html', context)
130
131     context = PatchworkRequestContext(request,
132             list_view = 'patchwork.views.patch.list',
133             list_view_params = {'project_id': project_id})
134     order = get_order(request)
135     project = get_object_or_404(Project, linkname=project_id)
136     context.project = project
137
138     form = None
139     errors = []
140
141     if request.method == 'POST':
142         action = request.POST.get('action', None)
143         if action:
144             action = action.lower()
145
146         # special case: the user may have hit enter in the 'create bundle'
147         # text field, so if non-empty, assume the create action:
148         if request.POST.get('bundle_name', False):
149             action = 'create'
150
151         ps = []
152         for patch_id in get_patch_ids(request.POST):
153             try:
154                 patch = Patch.objects.get(id = patch_id)
155             except Patch.DoesNotExist:
156                 pass
157             ps.append(patch)
158
159         (errors, form) = set_patches(request.user, action, request.POST, ps)
160         if errors:
161             context['errors'] = errors
162
163
164     elif request.user.is_authenticated() and \
165             project in request.user.get_profile().maintainer_projects.all():
166         form = MultiplePatchForm(project)
167
168     patches = Patch.objects.filter(project=project).order_by(order)
169     patches = context.filters.apply(patches)
170
171     paginator = Paginator(request, patches)
172
173     context.update({
174             'page':             paginator.current_page,
175             'patchform':        form,
176             'project':          project,
177             'errors':           errors,
178             })
179
180     return render_to_response('patchwork/list.html', context)