1 # Patchwork - automated patch tracking system
2 # Copyright (C) 2008 Jeremy Kerr <jk@ozlabs.org>
4 # This file is part of the Patchwork package.
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.
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.
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
21 from django.contrib.auth.models import User
22 from django import forms
24 from patchwork.models import Patch, State, Bundle, UserProfile
25 from registration.forms import RegistrationFormUniqueEmail
26 from registration.models import RegistrationProfile
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(),
35 password1 = forms.BooleanField(required = False)
36 password2 = forms.BooleanField(required = False)
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', '')
48 # saving the userprofile causes the firstname/lastname to propagate
49 # to the person objects.
50 user.get_profile().save()
55 return self.cleaned_data
57 class LoginForm(forms.Form):
58 username = forms.CharField(max_length = 30)
59 password = forms.CharField(widget = forms.PasswordInput)
61 class BundleForm(forms.ModelForm):
64 fields = ['name', 'public']
66 class CreateBundleForm(forms.ModelForm):
67 def __init__(self, *args, **kwargs):
68 super(CreateBundleForm, self).__init__(*args, **kwargs)
75 name = self.cleaned_data['name']
76 count = Bundle.objects.filter(owner = self.instance.owner, \
79 raise forms.ValidationError('A bundle called %s already exists' \
83 class DelegateField(forms.ModelChoiceField):
84 def __init__(self, project, *args, **kwargs):
85 queryset = User.objects.filter(userprofile__in = \
87 .filter(maintainer_projects = project) \
89 super(DelegateField, self).__init__(queryset, *args, **kwargs)
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
97 raise Exception("meep")
98 super(PatchForm, self).__init__(instance = instance, *args, **kwargs)
99 self.fields['delegate'] = DelegateField(project, required = False)
103 fields = ['state', 'archived', 'delegate']
105 class UserProfileForm(forms.ModelForm):
108 fields = ['primary_project', 'patches_per_page']
110 class OptionalDelegateField(DelegateField):
111 no_change_choice = ('*', 'no change')
113 def __init__(self, no_change_choice = None, *args, **kwargs):
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)
120 def _get_choices(self):
122 super(OptionalDelegateField, self)._get_choices())
123 choices.append(self.no_change_choice)
126 choices = property(_get_choices, forms.ChoiceField._set_choices)
128 def is_no_change(self, value):
129 return value == self.no_change_choice[0]
131 def clean(self, value):
132 if value == self.no_change_choice[0]:
134 return super(OptionalDelegateField, self).clean(value)
136 class OptionalModelChoiceField(forms.ModelChoiceField):
137 no_change_choice = ('*', 'no change')
139 def __init__(self, no_change_choice = None, *args, **kwargs):
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)
146 def _get_choices(self):
148 super(OptionalModelChoiceField, self)._get_choices())
149 choices.append(self.no_change_choice)
152 choices = property(_get_choices, forms.ChoiceField._set_choices)
154 def is_no_change(self, value):
155 return value == self.no_change_choice[0]
157 def clean(self, value):
158 if value == self.no_change_choice[0]:
160 return super(OptionalModelChoiceField, self).clean(value)
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')]
169 def is_no_change(self, value):
170 return value == self.no_change_choice[0]
172 class MultiplePatchForm(PatchForm):
173 state = OptionalModelChoiceField(queryset = State.objects.all())
174 archived = MultipleBooleanField()
176 def __init__(self, project, *args, **kwargs):
177 super(MultiplePatchForm, self).__init__(project = project,
179 self.fields['delegate'] = OptionalDelegateField(project = project,
182 def save(self, instance, commit = True):
183 opts = instance.__class__._meta
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:
193 field = self.fields.get(f.name, None)
197 if field.is_no_change(data[f.name]):
200 return forms.save_instance(self, instance,
201 self._meta.fields, 'changed', commit)
203 class UserPersonLinkForm(forms.Form):
204 email = forms.EmailField(max_length = 200)