##// END OF EJS Templates
Removed indexes in RSS. This is caused by problems with negative indexing, and...
Removed indexes in RSS. This is caused by problems with negative indexing, and should not make any difficulties.

File last commit:

r211:5a120222 default
r224:6490e2e7 default
Show More
forms.py
245 lines | 7.1 KiB | text/x-python | PythonLexer
import re
from captcha.fields import CaptchaField
from django import forms
from django.forms.util import ErrorList
from django.utils.translation import ugettext_lazy as _
import time
from boards.models import TITLE_MAX_LENGTH, User
from neboard import settings
from boards import utils
LAST_POST_TIME = "last_post_time"
LAST_LOGIN_TIME = "last_login_time"
LOGIN_DELAY = 60 * 60
MAX_TEXT_LENGTH = 30000
MAX_IMAGE_SIZE = 8 * 1024 * 1024
class PlainErrorList(ErrorList):
def __unicode__(self):
return self.as_text()
def as_text(self):
return ''.join([u'(!) %s ' % e for e in self])
class NeboardForm(forms.Form):
def as_p(self):
"Returns this form rendered as HTML <p>s."
return self._html_output(
normal_row='<div class="form-row">'
'<div class="form-label">'
'%(label)s'
'</div>'
'<div class="form-input">'
'%(field)s'
'</div>'
'%(help_text)s'
'</div>',
error_row='<div class="form-errors">%s</div>',
row_ender='</p>',
help_text_html=' <span class="helptext">%s</span>',
errors_on_separate_row=True)
class PostForm(NeboardForm):
title = forms.CharField(max_length=TITLE_MAX_LENGTH, required=False)
text = forms.CharField(widget=forms.Textarea, required=False)
image = forms.ImageField(required=False)
# This field is for spam prevention only
email = forms.CharField(max_length=100, required=False)
session = None
def clean_title(self):
title = self.cleaned_data['title']
if title:
if len(title) > TITLE_MAX_LENGTH:
raise forms.ValidationError(_('Title must have less than %s '
'characters') %
str(TITLE_MAX_LENGTH))
return title
def clean_text(self):
text = self.cleaned_data['text']
if text:
if len(text) > MAX_TEXT_LENGTH:
raise forms.ValidationError(_('Text must have less than %s '
'characters') %
str(MAX_TEXT_LENGTH))
return text
def clean_image(self):
image = self.cleaned_data['image']
if image:
if image._size > MAX_IMAGE_SIZE:
raise forms.ValidationError(_('Image must be less than %s '
'bytes') % str(MAX_IMAGE_SIZE))
return image
def clean(self):
cleaned_data = super(PostForm, self).clean()
if not self.session:
raise forms.ValidationError('Humans have sessions')
if cleaned_data['email']:
raise forms.ValidationError('A human cannot enter a hidden field')
if not self.errors:
self._clean_text_image()
if not self.errors and self.session:
self._validate_posting_speed()
return cleaned_data
def _clean_text_image(self):
text = self.cleaned_data.get('text')
image = self.cleaned_data.get('image')
if (not text) and (not image):
error_message = _('Either text or image must be entered.')
self._errors['text'] = self.error_class([error_message])
def _validate_posting_speed(self):
can_post = True
if LAST_POST_TIME in self.session:
now = time.time()
last_post_time = self.session[LAST_POST_TIME]
current_delay = int(now - last_post_time)
if current_delay < settings.POSTING_DELAY:
error_message = _('Wait %s seconds after last posting') % str(
settings.POSTING_DELAY - current_delay)
self._errors['text'] = self.error_class([error_message])
can_post = False
if can_post:
self.session[LAST_POST_TIME] = time.time()
class ThreadForm(PostForm):
regex_tags = re.compile(ur'^[\w\s\d]+$', re.UNICODE)
tags = forms.CharField(max_length=100)
def clean_tags(self):
tags = self.cleaned_data['tags']
if tags:
if not self.regex_tags.match(tags):
raise forms.ValidationError(
_('Inappropriate characters in tags.'))
return tags
def clean(self):
cleaned_data = super(ThreadForm, self).clean()
return cleaned_data
class PostCaptchaForm(PostForm):
captcha = CaptchaField()
def __init__(self, *args, **kwargs):
self.request = kwargs['request']
del kwargs['request']
super(PostCaptchaForm, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super(PostCaptchaForm, self).clean()
success = self.is_valid()
utils.update_captcha_access(self.request, success)
if success:
return cleaned_data
else:
raise forms.ValidationError(_("Captcha validation failed"))
class ThreadCaptchaForm(ThreadForm):
captcha = CaptchaField()
def __init__(self, *args, **kwargs):
self.request = kwargs['request']
del kwargs['request']
super(ThreadCaptchaForm, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super(ThreadCaptchaForm, self).clean()
success = self.is_valid()
utils.update_captcha_access(self.request, success)
if success:
return cleaned_data
else:
raise forms.ValidationError(_("Captcha validation failed"))
class SettingsForm(NeboardForm):
theme = forms.ChoiceField(choices=settings.THEMES,
label=_('Theme'))
class ModeratorSettingsForm(SettingsForm):
moderate = forms.BooleanField(required=False, label=_('Enable moderation '
'panel'))
class LoginForm(NeboardForm):
user_id = forms.CharField()
session = None
def clean_user_id(self):
user_id = self.cleaned_data['user_id']
if user_id:
users = User.objects.filter(user_id=user_id)
if len(users) == 0:
raise forms.ValidationError(_('No such user found'))
return user_id
def _validate_login_speed(self):
can_post = True
if LAST_LOGIN_TIME in self.session:
now = time.time()
last_login_time = self.session[LAST_LOGIN_TIME]
current_delay = int(now - last_login_time)
if current_delay < LOGIN_DELAY:
error_message = _('Wait %s minutes after last login') % str(
(LOGIN_DELAY - current_delay) / 60)
self._errors['user_id'] = self.error_class([error_message])
can_post = False
if can_post:
self.session[LAST_LOGIN_TIME] = time.time()
def clean(self):
if not self.session:
raise forms.ValidationError('Humans have sessions')
self._validate_login_speed()
cleaned_data = super(LoginForm, self).clean()
return cleaned_data