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