]> git.ozlabs.org Git - patchwork/blob - apps/patchwork/forms.py
[views] Restructure profile view, simplify bundle access
[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
144     def __init__(self, no_change_choice = None, *args, **kwargs):
145         self.filter = None
146         if (no_change_choice):
147             self.no_change_choice = no_change_choice
148         super(OptionalModelChoiceField, self). \
149             __init__(initial = self.no_change_choice[0], *args, **kwargs)
150
151     def _get_choices(self):
152         choices = list(
153                 super(OptionalModelChoiceField, self)._get_choices())
154         choices.append(self.no_change_choice)
155         return choices
156
157     choices = property(_get_choices, forms.ChoiceField._set_choices)
158
159     def is_no_change(self, value):
160         return value == self.no_change_choice[0]
161
162     def clean(self, value):
163         if value == self.no_change_choice[0]:
164             return value
165         return super(OptionalModelChoiceField, self).clean(value)
166
167 class MultipleBooleanField(forms.ChoiceField):
168     no_change_choice = ('*', 'no change')
169     def __init__(self, *args, **kwargs):
170         super(MultipleBooleanField, self).__init__(*args, **kwargs)
171         self.choices = [self.no_change_choice] + \
172                 [(True, 'Archived'), (False, 'Unarchived')]
173
174     def is_no_change(self, value):
175         return value == self.no_change_choice[0]
176
177 class MultiplePatchForm(PatchForm):
178     state = OptionalModelChoiceField(queryset = State.objects.all())
179     archived = MultipleBooleanField()
180
181     def __init__(self, project, *args, **kwargs):
182         super(MultiplePatchForm, self).__init__(project = project,
183                 *args, **kwargs)
184         self.fields['delegate'] = OptionalDelegateField(project = project,
185                 required = False)
186
187     def save(self, instance, commit = True):
188         opts = instance.__class__._meta
189         if self.errors:
190             raise ValueError("The %s could not be changed because the data "
191                     "didn't validate." % opts.object_name)
192         data = self.cleaned_data
193         # remove 'no change fields' from the data
194         for f in opts.fields:
195             if not f.name in data:
196                 continue
197
198             field = self.fields.get(f.name, None)
199             if not field:
200                 continue
201
202             if field.is_no_change(data[f.name]):
203                 del data[f.name]
204
205         return forms.save_instance(self, instance,
206                 self._meta.fields, 'changed', commit)
207
208 class UserPersonLinkForm(forms.Form):
209     email = forms.EmailField(max_length = 200)