]> git.openstreetmap.org Git - osqa.git/blob - forum/forms/general.py
Configure logging "the Django way" and ensure that all messages are written to the...
[osqa.git] / forum / forms / general.py
1 from django import forms
2 import re
3 from django.utils.translation import ugettext as _
4 from django.utils.safestring import mark_safe
5 from forum import settings
6 from forum.models import User
7 from forum.modules import call_all_handlers
8 import urllib
9 import logging
10
11 DEFAULT_NEXT = getattr(settings, 'APP_BASE_URL')
12 def clean_next(next):
13     if next is None:
14         return DEFAULT_NEXT
15     next = urllib.unquote(next)
16     if not isinstance(next, unicode):
17         next = unicode(next, 'utf-8')
18     next = next.strip()
19     if next.startswith('/'):
20         return next
21     return DEFAULT_NEXT
22
23 def get_next_url(request):
24     return clean_next(request.REQUEST.get('next'))
25
26 class StrippedNonEmptyCharField(forms.CharField):
27     def clean(self,value):
28         value = value.strip()
29         if self.required and value == '':
30             raise forms.ValidationError(_('this field is required'))
31         return value
32
33 class NextUrlField(forms.CharField):
34     def __init__(self):
35         super(NextUrlField,self).__init__(max_length = 255,widget = forms.HiddenInput(),required = False)
36     def clean(self,value):
37         return clean_next(value)
38
39 login_form_widget_attrs = { 'class': 'required login' }
40 username_re = re.compile(r'^[\-\w\s ]+$', re.UNICODE)
41
42 class UserNameField(StrippedNonEmptyCharField):
43     def __init__(self,db_model=User, db_field='username', must_exist=False,skip_clean=False,label=_('choose a username'),**kw):
44         self.must_exist = must_exist
45         self.skip_clean = skip_clean
46         self.db_model = db_model 
47         self.db_field = db_field
48         error_messages={'required':_('user name is required'),
49                         'taken':_('sorry, this name is taken, please choose another'),
50                         'forbidden':_('sorry, this name is not allowed, please choose another'),
51                         'missing':_('sorry, there is no user with this name'),
52                         'multiple-taken':_('sorry, we have a serious error - user name is taken by several users'),
53                         'invalid':_('user name can only consist of letters, empty space, hyphens and underscore'),
54                         'toshort':_('user name is to short, please use at least %d characters') % settings.MIN_USERNAME_LENGTH
55                     }
56         if 'error_messages' in kw:
57             error_messages.update(kw['error_messages'])
58             del kw['error_messages']
59         super(UserNameField,self).__init__(max_length=30,
60                 widget=forms.TextInput(attrs=login_form_widget_attrs),
61                 label=label,
62                 error_messages=error_messages,
63                 **kw
64                 )
65
66     def clean(self,username):
67         """ validate username """
68         if self.skip_clean == True:
69             return username
70         if hasattr(self, 'user_instance') and isinstance(self.user_instance, User):
71             if username == self.user_instance.username:
72                 return username
73         try:
74             username = super(UserNameField, self).clean(username)
75         except forms.ValidationError:
76             raise forms.ValidationError(self.error_messages['required'])
77         if len(username) < settings.MIN_USERNAME_LENGTH:
78             raise forms.ValidationError(self.error_messages['toshort'])
79         if self.required and not username_re.match(username):
80             raise forms.ValidationError(self.error_messages['invalid'])
81         if username in settings.RESERVED_USERNAMES:
82             raise forms.ValidationError(self.error_messages['forbidden'])
83         try:
84             user = self.db_model.objects.get(
85                     **{'%s' % self.db_field : username}
86             )
87             if user:
88                 if self.must_exist:
89                     return username
90                 else:
91                     raise forms.ValidationError(self.error_messages['taken'])
92         except self.db_model.DoesNotExist:
93             if self.must_exist:
94                 raise forms.ValidationError(self.error_messages['missing'])
95             else:
96                 return username
97         except self.db_model.MultipleObjectsReturned:
98             raise forms.ValidationError(self.error_messages['multiple-taken'])
99
100 class UserEmailField(forms.EmailField):
101     def __init__(self,skip_clean=False,**kw):
102         self.skip_clean = skip_clean
103         super(UserEmailField,self).__init__(widget=forms.TextInput(attrs=dict(login_form_widget_attrs,
104             maxlength=200)), label=mark_safe(_('your email address')),
105             error_messages={'required':_('email address is required'),
106                             'invalid':_('please enter a valid email address'),
107                             'taken':_('this email is already used by someone else, please choose another'),
108                             },
109             **kw
110             )
111
112     def clean(self,email):
113         """ validate if email exist in database
114         from legacy register
115         return: raise error if it exist """
116         email = super(UserEmailField,self).clean(email.strip())
117         if self.skip_clean:
118             return email
119         if settings.EMAIL_UNIQUE == True:
120             try:
121                 user = User.objects.get(email = email)
122                 raise forms.ValidationError(self.error_messages['taken'])
123             except User.DoesNotExist:
124                 return email
125             except User.MultipleObjectsReturned:
126                 raise forms.ValidationError(self.error_messages['taken'])
127         else:
128             return email 
129
130 class UserRealNameField(StrippedNonEmptyCharField):
131     def __init__(self, db_model=User, db_field='real_name', must_exist=True, skip_clean=False, label=_('Your real name'),**kw):
132         self.must_exist = must_exist
133         self.skip_clean = skip_clean
134         self.db_model = db_model
135         self.db_field = db_field
136         error_messages={'required':_('Real name is required')
137                     }
138         if 'error_messages' in kw:
139             error_messages.update(kw['error_messages'])
140             del kw['error_messages']
141         super(UserRealNameField,self).__init__(max_length=100,
142                 widget=forms.TextInput(attrs=login_form_widget_attrs),
143                 label=label,
144                 error_messages=error_messages,
145                 **kw
146                 )
147
148     def clean(self, real_name):
149         if self.skip_clean == True:
150             return real_name
151         try:
152             return super(UserRealNameField, self).clean(real_name)
153         except forms.ValidationError:
154             raise forms.ValidationError(self.error_messages['required'])
155
156 class SetPasswordForm(forms.Form):
157     password1 = forms.CharField(widget=forms.PasswordInput(attrs=login_form_widget_attrs),
158                                 label=_('choose password'),
159                                 error_messages={'required':_('password is required')},
160                                 )
161     password2 = forms.CharField(widget=forms.PasswordInput(attrs=login_form_widget_attrs),
162                                 label=mark_safe(_('retype password')),
163                                 error_messages={'required':_('please, retype your password'),
164                                                 'nomatch':_('sorry, entered passwords did not match, please try again')},
165                                 )
166
167     def __init__(self, data=None, user=None, *args, **kwargs):
168         super(SetPasswordForm, self).__init__(data, *args, **kwargs)
169
170     def clean_password2(self):
171         """
172         Validates that the two password inputs match.
173         
174         """
175         if 'password1' in self.cleaned_data:
176             if self.cleaned_data['password1'] == self.cleaned_data['password2']:
177                 self.password = self.cleaned_data['password2']
178                 self.cleaned_data['password'] = self.cleaned_data['password2']
179                 return self.cleaned_data['password2']
180             else:
181                 del self.cleaned_data['password2']
182                 raise forms.ValidationError(self.fields['password2'].error_messages['nomatch'])
183         else:
184             return self.cleaned_data['password2']
185
186 class SimpleCaptchaForm(forms.Form):
187     fields = {}
188
189     def __init__(self, *args, **kwargs):
190         super(SimpleCaptchaForm, self).__init__(*args, **kwargs)
191
192         spam_fields = call_all_handlers('create_anti_spam_field')
193         if spam_fields:
194             spam_fields = dict(spam_fields)
195             for name, field in spam_fields.items():
196                 self.fields[name] = field
197
198             self._anti_spam_fields = spam_fields.keys()
199         else:
200             self._anti_spam_fields = []