]> git.ozlabs.org Git - patchwork/blob - apps/patchwork/forms.py
10c93a42b199946034a4acdbe97dd626b6d1e1b0
[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 DeleteBundleForm(forms.Form):
84     name = 'deletebundleform'
85     form_name = forms.CharField(initial = name, widget = forms.HiddenInput)
86     bundle_id = forms.IntegerField(widget = forms.HiddenInput)
87
88 class DelegateField(forms.ModelChoiceField):
89     def __init__(self, project, *args, **kwargs):
90         queryset = User.objects.filter(userprofile__in = \
91                 UserProfile.objects \
92                         .filter(maintainer_projects = project) \
93                         .values('pk').query)
94         super(DelegateField, self).__init__(queryset, *args, **kwargs)
95
96
97 class PatchForm(forms.ModelForm):
98     def __init__(self, instance = None, project = None, *args, **kwargs):
99         if (not project) and instance:
100             project = instance.project
101         if not project:
102             raise Exception("meep")
103         super(PatchForm, self).__init__(instance = instance, *args, **kwargs)
104         self.fields['delegate'] = DelegateField(project, required = False)
105
106     class Meta:
107         model = Patch
108         fields = ['state', 'archived', 'delegate']
109
110 class UserProfileForm(forms.ModelForm):
111     class Meta:
112         model = UserProfile
113         fields = ['primary_project', 'patches_per_page']
114
115 class OptionalDelegateField(DelegateField):
116     no_change_choice = ('*', 'no change')
117
118     def __init__(self, no_change_choice = None, *args, **kwargs):
119         self.filter = None
120         if (no_change_choice):
121             self.no_change_choice = no_change_choice
122         super(OptionalDelegateField, self). \
123             __init__(initial = self.no_change_choice[0], *args, **kwargs)
124
125     def _get_choices(self):
126         choices = list(
127                 super(OptionalDelegateField, self)._get_choices())
128         choices.append(self.no_change_choice)
129         return choices
130
131     choices = property(_get_choices, forms.ChoiceField._set_choices)
132
133     def is_no_change(self, value):
134         return value == self.no_change_choice[0]
135
136     def clean(self, value):
137         if value == self.no_change_choice[0]:
138             return value
139         return super(OptionalDelegateField, self).clean(value)
140
141 class OptionalModelChoiceField(forms.ModelChoiceField):
142     no_change_choice = ('*', 'no change')
143     to_field_name = None
144
145     def __init__(self, no_change_choice = None, *args, **kwargs):
146         self.filter = None
147         if (no_change_choice):
148             self.no_change_choice = no_change_choice
149         super(OptionalModelChoiceField, self). \
150             __init__(initial = self.no_change_choice[0], *args, **kwargs)
151
152     def _get_choices(self):
153         choices = list(
154                 super(OptionalModelChoiceField, self)._get_choices())
155         choices.append(self.no_change_choice)
156         return choices
157
158     choices = property(_get_choices, forms.ChoiceField._set_choices)
159
160     def is_no_change(self, value):
161         return value == self.no_change_choice[0]
162
163     def clean(self, value):
164         if value == self.no_change_choice[0]:
165             return value
166         return super(OptionalModelChoiceField, self).clean(value)
167
168 class MultipleBooleanField(forms.ChoiceField):
169     no_change_choice = ('*', 'no change')
170     def __init__(self, *args, **kwargs):
171         super(MultipleBooleanField, self).__init__(*args, **kwargs)
172         self.choices = [self.no_change_choice] + \
173                 [(True, 'Archived'), (False, 'Unarchived')]
174
175     def is_no_change(self, value):
176         return value == self.no_change_choice[0]
177
178 class MultiplePatchForm(PatchForm):
179     state = OptionalModelChoiceField(queryset = State.objects.all())
180     archived = MultipleBooleanField()
181
182     def __init__(self, project, *args, **kwargs):
183         super(MultiplePatchForm, self).__init__(project = project,
184                 *args, **kwargs)
185         self.fields['delegate'] = OptionalDelegateField(project = project,
186                 required = False)
187
188     def save(self, instance, commit = True):
189         opts = instance.__class__._meta
190         if self.errors:
191             raise ValueError("The %s could not be changed because the data "
192                     "didn't validate." % opts.object_name)
193         data = self.cleaned_data
194         # remove 'no change fields' from the data
195         for f in opts.fields:
196             if not f.name in data:
197                 continue
198
199             field = self.fields.get(f.name, None)
200             if not field:
201                 continue
202
203             if field.is_no_change(data[f.name]):
204                 del data[f.name]
205
206         return forms.save_instance(self, instance,
207                 self._meta.fields, 'changed', commit)
208
209 class UserPersonLinkForm(forms.Form):
210     email = forms.EmailField(max_length = 200)