Inital commit
[patchwork] / apps / patchwork / utils.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.forms import MultiplePatchForm
22 from patchwork.models import Bundle, Project, State
23 from django.conf import settings
24 from django.shortcuts import render_to_response, get_object_or_404
25
26 def get_patch_ids(d, prefix = 'patch_id'):
27     ids = []
28
29     for (k, v) in d.items():
30         a = k.split(':')
31         if len(a) != 2:
32             continue
33         if a[0] != prefix:
34             continue
35         if not v:
36             continue
37         ids.append(a[1])
38
39     return ids
40
41 class Order(object):
42     order_map = {
43         'date':         'date',
44         'name':         'name',
45         'state':        'state__ordering',
46         'submitter':    'submitter__name'
47     }
48     default_order = 'date'
49
50     def __init__(self, str = None):
51         self.reversed = False
52
53         if str is None or str == '':
54             self.order = self.default_order
55             return
56
57         reversed = False
58         if str[0] == '-':
59             str = str[1:]
60             reversed = True
61
62         if str not in self.order_map.keys():
63             self.order = self.default_order
64             return
65
66         self.order = str
67         self.reversed = reversed
68
69     def __str__(self):
70         str = self.order
71         if self.reversed:
72             str = '-' + str
73         return str
74
75     def name(self):
76         return self.order
77
78     def reversed_name(self):
79         if self.reversed:
80             return self.order
81         else:
82             return '-' + self.order
83
84     def query(self):
85         q = self.order_map[self.order]
86         if self.reversed:
87             q = '-' + q
88         return q
89
90 bundle_actions = ['create', 'add', 'remove']
91 def set_bundle(user, action, data, patches, context):
92     # set up the bundle
93     bundle = None
94     if action == 'create':
95         bundle = Bundle(owner = user, project = project,
96                 name = data['bundle_name'])
97         bundle.save()
98         str = 'added to new bundle "%s"' % bundle.name
99         auth_required = False
100
101     elif action =='add':
102         bundle = get_object_or_404(Bundle, id = data['bundle_id'])
103         str = 'added to bundle "%s"' % bundle.name
104         auth_required = False
105
106     elif action =='remove':
107         bundle = get_object_or_404(Bundle, id = data['removed_bundle_id'])
108         str = 'removed from bundle "%s"' % bundle.name
109         auth_required = False
110
111     if not bundle:
112         return ['no such bundle']
113
114     for patch in patches:
115         if action == 'create' or action == 'add':
116             bundle.patches.add(patch)
117
118         elif action == 'remove':
119             bundle.patches.remove(patch)
120
121     if len(patches) > 0:
122         if len(patches) == 1:
123             str = 'patch ' + str
124         else:
125             str = 'patches ' + str
126         context.add_message(str)
127
128     bundle.save()
129
130     return []
131
132
133 def set_patches(user, action, data, patches, context):
134     errors = []
135     form = MultiplePatchForm(data = data)
136
137     try:
138         project = Project.objects.get(id = data['project'])
139     except:
140         errors = ['No such project']
141         return (errors, form)
142
143     str = ''
144
145     print "action: ", action
146
147     # this may be a bundle action, which doesn't modify a patch. in this
148     # case, don't require a valid form, or patch editing permissions
149     if action in bundle_actions:
150         errors = set_bundle(user, action, data, patches, context)
151         return (errors, form)
152
153     if not form.is_valid():
154         errors = ['The submitted form data was invalid']
155         return (errors, form)
156
157     for patch in patches:
158         if not patch.is_editable(user):
159             errors.append('You don\'t have permissions to edit the ' + \
160                     'patch "%s"' \
161                     % patch.name)
162             continue
163
164         if action == 'update':
165             form.save(patch)
166             str = 'updated'
167
168         elif action == 'ack':
169             pass
170
171         elif action == 'archive':
172             patch.archived = True
173             patch.save()
174             str = 'archived'
175
176         elif action == 'unarchive':
177             patch.archived = True
178             patch.save()
179             str = 'un-archived'
180
181         elif action == 'delete':
182             patch.delete()
183             str = 'un-archived'
184
185
186     if len(patches) > 0:
187         if len(patches) == 1:
188             str = 'patch ' + str
189         else:
190             str = 'patches ' + str
191         context.add_message(str)
192
193     return (errors, form)