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