]> git.ozlabs.org Git - patchwork/blob - apps/patchwork/forms.py
Add 'Action Required' meta-state filter
[patchwork] / apps / patchwork / forms.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 django.contrib.auth.models import User
22 from django import forms
23
24 from patchwork.models import Patch, State, Bundle, UserProfile
25 from registration.forms import RegistrationFormUniqueEmail
26 from registration.models import RegistrationProfile
27
28 class RegistrationForm(RegistrationFormUniqueEmail):
29     first_name = forms.CharField(max_length = 30, required = False)
30     last_name = forms.CharField(max_length = 30, required = False)
31     username = forms.CharField(max_length=30, label=u'Username')
32     email = forms.EmailField(max_length=100, label=u'Email address')
33     password = forms.CharField(widget=forms.PasswordInput(),
34                                 label='Password')
35     password1 = forms.BooleanField(required = False)
36     password2 = forms.BooleanField(required = False)
37
38     def save(self, profile_callback = None):
39         user = RegistrationProfile.objects.create_inactive_user( \
40                 username = self.cleaned_data['username'],
41                 password = self.cleaned_data['password'],
42                 email = self.cleaned_data['email'],
43                 profile_callback = profile_callback)
44         user.first_name = self.cleaned_data.get('first_name', '')
45         user.last_name = self.cleaned_data.get('last_name', '')
46         user.save()
47
48         # saving the userprofile causes the firstname/lastname to propagate
49         # to the person objects.
50         user.get_profile().save()
51
52         return user
53
54     def clean(self):
55         return self.cleaned_data
56
57 class LoginForm(forms.Form):
58     username = forms.CharField(max_length = 30)
59     password = forms.CharField(widget = forms.PasswordInput)
60
61 class BundleForm(forms.ModelForm):
62     class Meta:
63         model = Bundle
64         fields = ['name', 'public']
65
66 class CreateBundleForm(forms.ModelForm):
67     def __init__(self, *args, **kwargs):
68         super(CreateBundleForm, self).__init__(*args, **kwargs)
69
70     class Meta:
71         model = Bundle
72         fields = ['name']
73
74     def clean_name(self):
75         name = self.cleaned_data['name']
76         count = Bundle.objects.filter(owner = self.instance.owner, \
77                 name = name).count()
78         if count > 0:
79             raise forms.ValidationError('A bundle called %s already exists' \
80                     % name)
81         return name
82
83 class DelegateField(forms.ModelChoiceField):
84     def __init__(self, project, *args, **kwargs):
85         queryset = User.objects.filter(userprofile__in = \
86                 UserProfile.objects \
87                         .filter(maintainer_projects = project) \
88                         .values('pk').query)
89         super(DelegateField, self).__init__(queryset, *args, **kwargs)
90
91
92 class PatchForm(forms.ModelForm):
93     def __init__(self, instance = None, project = None, *args, **kwargs):
94         if (not project) and instance:
95             project = instance.project
96         if not project:
97             raise Exception("meep")
98         super(PatchForm, self).__init__(instance = instance, *args, **kwargs)
99         self.fields['delegate'] = DelegateField(project, required = False)
100
101     class Meta:
102         model = Patch
103         fields = ['state', 'archived', 'delegate']
104
105 class UserProfileForm(forms.ModelForm):
106     class Meta:
107         model = UserProfile
108         fields = ['primary_project', 'patches_per_page']
109
110 class OptionalDelegateField(DelegateField):
111     no_change_choice = ('*', 'no change')
112
113     def __init__(self, no_change_choice = None, *args, **kwargs):
114         self.filter = None
115         if (no_change_choice):
116             self.no_change_choice = no_change_choice
117         super(OptionalDelegateField, self). \
118             __init__(initial = self.no_change_choice[0], *args, **kwargs)
119
120     def _get_choices(self):
121         choices = list(
122                 super(OptionalDelegateField, self)._get_choices())
123         choices.append(self.no_change_choice)
124         return choices
125
126     choices = property(_get_choices, forms.ChoiceField._set_choices)
127
128     def is_no_change(self, value):
129         return value == self.no_change_choice[0]
130
131     def clean(self, value):
132         if value == self.no_change_choice[0]:
133             return value
134         return super(OptionalDelegateField, self).clean(value)
135
136 class OptionalModelChoiceField(forms.ModelChoiceField):
137     no_change_choice = ('*', 'no change')
138
139     def __init__(self, no_change_choice = None, *args, **kwargs):
140         self.filter = None
141         if (no_change_choice):
142             self.no_change_choice = no_change_choice
143         super(OptionalModelChoiceField, self). \
144             __init__(initial = self.no_change_choice[0], *args, **kwargs)
145
146     def _get_choices(self):
147         choices = list(
148                 super(OptionalModelChoiceField, self)._get_choices())
149         choices.append(self.no_change_choice)
150         return choices
151
152     choices = property(_get_choices, forms.ChoiceField._set_choices)
153
154     def is_no_change(self, value):
155         return value == self.no_change_choice[0]
156
157     def clean(self, value):
158         if value == self.no_change_choice[0]:
159             return value
160         return super(OptionalModelChoiceField, self).clean(value)
161
162 class MultipleBooleanField(forms.ChoiceField):
163     no_change_choice = ('*', 'no change')
164     def __init__(self, *args, **kwargs):
165         super(MultipleBooleanField, self).__init__(*args, **kwargs)
166         self.choices = [self.no_change_choice] + \
167                 [(True, 'Archived'), (False, 'Unarchived')]
168
169     def is_no_change(self, value):
170         return value == self.no_change_choice[0]
171
172 class MultiplePatchForm(PatchForm):
173     state = OptionalModelChoiceField(queryset = State.objects.all())
174     archived = MultipleBooleanField()
175
176     def __init__(self, project, *args, **kwargs):
177         super(MultiplePatchForm, self).__init__(project = project,
178                 *args, **kwargs)
179         self.fields['delegate'] = OptionalDelegateField(project = project,
180                 required = False)
181
182     def save(self, instance, commit = True):
183         opts = instance.__class__._meta
184         if self.errors:
185             raise ValueError("The %s could not be changed because the data "
186                     "didn't validate." % opts.object_name)
187         data = self.cleaned_data
188         # remove 'no change fields' from the data
189         for f in opts.fields:
190             if not f.name in data:
191                 continue
192
193             field = self.fields.get(f.name, None)
194             if not field:
195                 continue
196
197             if field.is_no_change(data[f.name]):
198                 del data[f.name]
199
200         return forms.save_instance(self, instance,
201                 self._meta.fields, 'changed', commit)
202
203 class UserPersonLinkForm(forms.Form):
204     email = forms.EmailField(max_length = 200)