diff --git a/boards/authors.py b/boards/authors.py --- a/boards/authors.py +++ b/boards/authors.py @@ -1,24 +1,31 @@ +from django.utils.translation import ugettext_lazy as _ + __author__ = 'neko259' +ROLE_AUTHOR = _('author') +ROLE_DEVELOPER = _('developer') +ROLE_JS_DEV = _('javascript developer') +ROLE_DESIGNER = _('designer') + authors = { 'neko259': { 'name': 'Pavel Ryapolov', 'contacts': ['neko259@gmail.com'], - 'roles': ['author', 'developer'], + 'roles': [ROLE_AUTHOR, ROLE_DEVELOPER], }, 'ilyas': { 'name': 'Ilyas Babayev', 'contacts': ['zamesilyasa@gmail.com'], - 'roles': ['author', 'developer'], + 'roles': [ROLE_AUTHOR, ROLE_DEVELOPER], }, 'ritsufag': { 'name': 'Aiko Kirino', 'contacts': ['ritsufag@gmail.com'], - 'roles': ['javascript developer', 'designer'], + 'roles': [ROLE_JS_DEV, ROLE_DESIGNER], }, 'Tenno Seremel': { 'name': 'anonymous', 'contacts': ['html@serenareem.net'], - 'roles': ['javascript developer', 'designer'], + 'roles': [ROLE_JS_DEV, ROLE_DESIGNER], }, } \ No newline at end of file diff --git a/boards/forms.py b/boards/forms.py --- a/boards/forms.py +++ b/boards/forms.py @@ -9,6 +9,12 @@ 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): @@ -41,9 +47,6 @@ class NeboardForm(forms.Form): class PostForm(NeboardForm): - MAX_TEXT_LENGTH = 30000 - MAX_IMAGE_SIZE = 8 * 1024 * 1024 - title = forms.CharField(max_length=TITLE_MAX_LENGTH, required=False) text = forms.CharField(widget=forms.Textarea, required=False) image = forms.ImageField(required=False) @@ -57,34 +60,36 @@ class PostForm(NeboardForm): title = self.cleaned_data['title'] if title: if len(title) > TITLE_MAX_LENGTH: - raise forms.ValidationError('Title must have less than' + - str(TITLE_MAX_LENGTH) + - ' characters.') + 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) > self.MAX_TEXT_LENGTH: - raise forms.ValidationError('Text must have less than ' + - str(self.MAX_TEXT_LENGTH) + - ' characters.') + 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 > self.MAX_IMAGE_SIZE: - raise forms.ValidationError('Image must be less than ' + - str(self.MAX_IMAGE_SIZE) + - ' bytes.') + 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 cleaned_data['email']: - raise forms.ValidationError('A human cannot enter a hidden field') + 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() @@ -112,9 +117,8 @@ class PostForm(NeboardForm): current_delay = int(now - last_post_time) if current_delay < settings.POSTING_DELAY: - error_message = 'Wait ' + str(settings.POSTING_DELAY - - current_delay)\ - + ' seconds after last posting' + 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 @@ -198,8 +202,11 @@ class ModeratorSettingsForm(SettingsForm class LoginForm(NeboardForm): + user_id = forms.CharField() + session = None + def clean_user_id(self): user_id = self.cleaned_data['user_id'] if user_id: @@ -209,7 +216,31 @@ class LoginForm(NeboardForm): 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 + return cleaned_data \ No newline at end of file diff --git a/boards/locale/ru/LC_MESSAGES/django.mo b/boards/locale/ru/LC_MESSAGES/django.mo index 85f3e03ca1688517c25b0fca50235e6a9f42858c..ec0094b350013506b542867bc5240c7e17594633 GIT binary patch literal 5134 zc$|$^TWl2989uZrz5%vzNDGwakOUG+ciA4Jd1xQns+Sq5eJGXMhp2sMpHit3QeXQ0=RfOR zs7brl%y%yT`7hu9|7ZN?^-sJd@H>p>vv~G=LWmQxp25i;?x2$HlU3hH(?gefmJHSr^T_BnKHgGNQDiA8f4WIBz!c_ZYnYFP8qULSYPeqR*RbCYfKLPKu^9!% zflmQnTf_dHUBmobU&C?z2>1%c1B?MTt!18%0yhDVujTWn*K*BX2JQv^8h8Ns$#rc1 z&^oS{*MK{KW5DNtAFSiJLoIh-;{#v>_!NR^0JhXJZ?9@RRm*z5q4$4S%kj?FvVXs< z<^K77E&KP8K37@CxVetwjOuxF9sAc+$Nsn)zYe?z{AL~NtwHl7$*+3m@zr{rH{fo{ zTRrQW0UibZqMpw^iN(#pr`L18>|f9Oy})kZt@WIre*sSd*ER6D5nvtJZ{RrI()d9G z`}?y7w)fWtj^{xG*G&bAW)<--STEHO^*8xUzYQ9xX7}pxEx@V{sn<@W#jcSPcjC$%t!8xNJ)iTAkQ_rb4z9>q+ zEgC;BI9{sNeS$fsxDV_7XEhRMtIN(yjntEIJo^RnOSMDy9p!YBmWh;|+o7>ha6jm4 zSmpdBwIMT>ZOT5^G){SPz;UG^ZS$;Jjf!L@BmE)lr9F|%`9qHDi9?1hTe}EsGc67| znY8rHbG|riWc~gjL!L1*R@(3_$Cd+zm4VD*XL#7OApu3csnoMl(PCyy-xMvD=et&4 z&NtICXQxdU`=&@)c)LougkRRMF=)!+oaf6vQ$nBVn(3%W*+yRm>kf{w)vRHg8F9pf z^$)Se0S83T5?SO~R82V>(mV&wqEb@|qU3;z)v?X3kn^>IF2oA!U1Wt`%%U1% z`O7&6>>o3;nGt@IPdYW2JD%k`?uh6%5LvhB`<6ZEiSDd}th%Cm#P*GIqQ@AN!-fs5 zD#w^2KD<5kTIM-zW~^b065KZ;y{rLNqO#|q)LNc&&C@wcrIohSi!}_vg@{=&UeQSBkXhS%bDogEMBv$zr5P^~6czjN$dWR@RrLJ=Ca)8Wt{+Zb7Kn z<6W+E((Lymt?9^d5P)t<$gbq!qsf<3@_6c4cWY-yH5G>IN7}tXD;+tM8}uSQPC{09 zb@oJ5HR4dDMU{DDEWSGudodEfc@2jA7aP zRXup7-`v}CB(kq0M~)4cZX{**J89%KA@}uJesxzS=Ng&F5yu_&64K79sn@)FzvN-_ z3--2nthqTZw{Mp;jBRa>$K^{hCKGCYpt-TQ)zrL)hU!GDDISxrzs^S>6Wf6^ahz$~ zvA-I(c(4@Agy(~qU@BM)rh`ctj)r4cSPbTZJSG_2qxJBOa7+dZm`;Tg!K@4>gWK4d z3@=7Sa1C-ZG8}`N`EWu6Z$fA+SPak8NeJYFSrOb?j*lGD z@r{RX6oVNT!Mn5#MR^ht!A;1HvIR{Q+zqe7k1@=z5}_bc1V1RcDq*QWUd@qN=*`27 z@_3p;M1TlR2Difr_F;;G!X9}#LF7WX0QxVn2V?*iv0b3ayhPHa(x)EG>nLNJ^ zYv+}Tsg=rwf>-4*tzvqF5BaDB1w}+~N$5HP6(o5J$0o3(lDMFH213Nzw@O4_3on!k z;SS}0fmALKNoCpn_}v>+R=O6WvQ(|aGs!RM{GwvFD(Qz*1dHUWE>Tp^#c+b${~pdR zsl};cQLmi!N5cxQa>JBII*U?zkJPA~OtNvvl>KN*c6HJ%)ouVze!dF;&#B*|QrtJ1W zuU~$g@7MTx4=;$1xdDn_ibprDBzT9c-^DwxI)?74c}2-Mk-Aju`LdyI|2uTkO>q\n" "Language-Team: LANGUAGE \n" @@ -18,31 +18,71 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: forms.py:96 +#: authors.py:5 +msgid "author" +msgstr "автор" + +#: authors.py:6 +msgid "developer" +msgstr "разработчик" + +#: authors.py:7 +msgid "javascript developer" +msgstr "разработчик javascript" + +#: authors.py:8 +msgid "designer" +msgstr "дизайнер" + +#: forms.py:63 +#, python-format +msgid "Title must have less than %s characters" +msgstr "Заголовок должен иметь меньше %s символов" + +#: forms.py:72 +#, python-format +msgid "Text must have less than %s characters" +msgstr "Текст должен быть короче %s символов" + +#: forms.py:81 +#, python-format +msgid "Image must be less than %s bytes" +msgstr "Изображение должно быть менее %s байт" + +#: forms.py:107 msgid "Either text or image must be entered." msgstr "Текст или картинка должны быть введены." -#: forms.py:130 +#: forms.py:120 +#, python-format +msgid "Wait %s seconds after last posting" +msgstr "Подождите %s секунд после последнего постинга" + +#: forms.py:140 msgid "Inappropriate characters in tags." msgstr "Недопустимые символы в тегах." -#: forms.py:158 forms.py:179 +#: forms.py:168 forms.py:189 msgid "Captcha validation failed" msgstr "Проверка капчи провалена" -#: forms.py:185 +#: forms.py:195 msgid "Theme" msgstr "Тема" -#: forms.py:190 +#: forms.py:200 msgid "Enable moderation panel" msgstr "Включить панель модерации" -#: forms.py:202 -#, fuzzy +#: forms.py:215 msgid "No such user found" msgstr "Теги не найдены." +#: forms.py:229 +#, python-format +msgid "Wait %s minutes after last login" +msgstr "Подождите %s минут после последнего входа" + #: templates/boards/404.html:6 msgid "Not found" msgstr "Не найдено" @@ -122,11 +162,11 @@ msgstr "Удалить" msgid "Ban IP" msgstr "Заблокировать IP" -#: templates/boards/posting_general.html:74 templates/boards/thread.html:116 +#: templates/boards/posting_general.html:74 templates/boards/thread.html:121 msgid "replies" msgstr "ответов" -#: templates/boards/posting_general.html:75 templates/boards/thread.html:117 +#: templates/boards/posting_general.html:75 templates/boards/thread.html:122 msgid "images" msgstr "изображений" @@ -156,20 +196,24 @@ msgstr "Текст" msgid "Image" msgstr "Изображение" -#: templates/boards/posting_general.html:163 templates/boards/thread.html:104 +#: templates/boards/posting_general.html:155 templates/boards/thread.html:95 +msgid "e-mail" +msgstr "" + +#: templates/boards/posting_general.html:168 templates/boards/thread.html:109 msgid "Post" msgstr "Отправить" -#: templates/boards/posting_general.html:165 +#: templates/boards/posting_general.html:170 msgid "Tags must be delimited by spaces. Text or image is required." msgstr "" "Теги должны быть разделены пробелами. Текст или изображение обязательны." -#: templates/boards/posting_general.html:168 templates/boards/thread.html:106 +#: templates/boards/posting_general.html:173 templates/boards/thread.html:111 msgid "Text syntax" msgstr "Синтаксис текста" -#: templates/boards/posting_general.html:178 +#: templates/boards/posting_general.html:183 msgid "Pages:" msgstr "Страницы: " @@ -209,7 +253,7 @@ msgstr "Теги не найдены." msgid "Reply to thread" msgstr "Ответить в тему" -#: templates/boards/thread.html:118 +#: templates/boards/thread.html:123 msgid "Last update: " msgstr "Последнее обновление: " @@ -283,15 +327,3 @@ msgstr "Ссылка на сообщение" #~ msgid "gets" #~ msgstr "гетов" - -#~ msgid "author" -#~ msgstr "автор" - -#~ msgid "developer" -#~ msgstr "разработчик" - -#~ msgid "javascript developer" -#~ msgstr "разработчик javascript" - -#~ msgid "designer" -#~ msgstr "дизайнер" diff --git a/boards/views.py b/boards/views.py --- a/boards/views.py +++ b/boards/views.py @@ -167,6 +167,8 @@ def login(request): if request.method == 'POST': form = LoginForm(request.POST, request.FILES, error_class=PlainErrorList) + form.session = request.session + if form.is_valid(): user = User.objects.get(user_id=form.cleaned_data['user_id']) request.session['user_id'] = user.id