]> git.ozlabs.org Git - patchwork/blob - apps/patchwork/utils.py
[views] Check count() for duplicate bundle patches, rather than try/except
[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, BundlePatch, State, UserProfile
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         'delegate':     'delegate__username',
48     }
49     default_order = ('date', True)
50
51     def __init__(self, str = None, editable = False):
52         self.reversed = False
53         self.editable = editable
54
55         if self.editable:
56             return
57
58         if str is None or str == '':
59             (self.order, self.reversed) = self.default_order
60             return
61
62         reversed = False
63         if str[0] == '-':
64             str = str[1:]
65             reversed = True
66
67         if str not in self.order_map.keys():
68             (self.order, self.reversed) = self.default_order
69             return
70
71         self.order = str
72         self.reversed = reversed
73
74     def __str__(self):
75         str = self.order
76         if self.reversed:
77             str = '-' + str
78         return str
79
80     def name(self):
81         return self.order
82
83     def reversed_name(self):
84         if self.reversed:
85             return self.order
86         else:
87             return '-' + self.order
88
89     def query(self):
90         q = self.order_map[self.order]
91         if self.reversed:
92             q = '-' + q
93         return q
94
95 bundle_actions = ['create', 'add', 'remove']
96 def set_bundle(user, project, action, data, patches, context):
97     # set up the bundle
98     bundle = None
99     if action == 'create':
100         bundle_name = data['bundle_name'].strip()
101         if not bundle_name:
102             return ['No bundle name was specified']
103
104         bundle = Bundle(owner = user, project = project,
105                 name = bundle_name)
106         bundle.save()
107         context.add_message("Bundle %s created" % bundle.name)
108
109     elif action =='add':
110         bundle = get_object_or_404(Bundle, id = data['bundle_id'])
111
112     elif action =='remove':
113         bundle = get_object_or_404(Bundle, id = data['removed_bundle_id'])
114
115     if not bundle:
116         return ['no such bundle']
117
118     for patch in patches:
119         if action == 'create' or action == 'add':
120             bundlepatch_count = BundlePatch.objects.filter(bundle = bundle,
121                         patch = patch).count()
122             if bundlepatch_count == 0:
123                 bundle.append_patch(patch)
124                 context.add_message("Patch '%s' added to bundle %s" % \
125                         (patch.name, bundle.name))
126             else:
127                 context.add_message("Patch '%s' already in bundle %s" % \
128                         (patch.name, bundle.name))
129
130         elif action == 'remove':
131             try:
132                 bp = BundlePatch.objects.get(bundle = bundle, patch = patch)
133                 bp.delete()
134                 context.add_message("Patch '%s' removed from bundle %s\n" % \
135                         (patch.name, bundle.name))
136             except Exception:
137                 pass
138
139     bundle.save()
140
141     return []
142
143
144 def set_patches(user, project, action, data, patches, context):
145     errors = []
146     form = MultiplePatchForm(project = project, data = data)
147
148     try:
149         project = Project.objects.get(id = data['project'])
150     except:
151         errors = ['No such project']
152         return (errors, form)
153
154     str = ''
155
156     # this may be a bundle action, which doesn't modify a patch. in this
157     # case, don't require a valid form, or patch editing permissions
158     if action in bundle_actions:
159         errors = set_bundle(user, project, action, data, patches, context)
160         return (errors, form)
161
162     if not form.is_valid():
163         errors = ['The submitted form data was invalid']
164         return (errors, form)
165
166     for patch in patches:
167         if not patch.is_editable(user):
168             errors.append('You don\'t have permissions to edit the ' + \
169                     'patch "%s"' \
170                     % patch.name)
171             continue
172
173         if action == 'update':
174             form.save(patch)
175             str = 'updated'
176
177         elif action == 'ack':
178             pass
179
180         elif action == 'archive':
181             patch.archived = True
182             patch.save()
183             str = 'archived'
184
185         elif action == 'unarchive':
186             patch.archived = True
187             patch.save()
188             str = 'un-archived'
189
190         elif action == 'delete':
191             patch.delete()
192             str = 'un-archived'
193
194
195     if len(patches) > 0:
196         if len(patches) == 1:
197             str = 'patch ' + str
198         else:
199             str = 'patches ' + str
200         context.add_message(str)
201
202     return (errors, form)
203
204 def userprofile_register_callback(user):
205     profile = UserProfile(user = user)
206     profile.save()
207