Show More
@@ -1,24 +1,31 b'' | |||
|
1 | from django.utils.translation import ugettext_lazy as _ | |
|
2 | ||
|
1 | 3 | __author__ = 'neko259' |
|
2 | 4 | |
|
5 | ROLE_AUTHOR = _('author') | |
|
6 | ROLE_DEVELOPER = _('developer') | |
|
7 | ROLE_JS_DEV = _('javascript developer') | |
|
8 | ROLE_DESIGNER = _('designer') | |
|
9 | ||
|
3 | 10 | authors = { |
|
4 | 11 | 'neko259': { |
|
5 | 12 | 'name': 'Pavel Ryapolov', |
|
6 | 13 | 'contacts': ['neko259@gmail.com'], |
|
7 | 'roles': ['author', 'developer'], | |
|
14 | 'roles': [ROLE_AUTHOR, ROLE_DEVELOPER], | |
|
8 | 15 | }, |
|
9 | 16 | 'ilyas': { |
|
10 | 17 | 'name': 'Ilyas Babayev', |
|
11 | 18 | 'contacts': ['zamesilyasa@gmail.com'], |
|
12 | 'roles': ['author', 'developer'], | |
|
19 | 'roles': [ROLE_AUTHOR, ROLE_DEVELOPER], | |
|
13 | 20 | }, |
|
14 | 21 | 'ritsufag': { |
|
15 | 22 | 'name': 'Aiko Kirino', |
|
16 | 23 | 'contacts': ['ritsufag@gmail.com'], |
|
17 | 'roles': ['javascript developer', 'designer'], | |
|
24 | 'roles': [ROLE_JS_DEV, ROLE_DESIGNER], | |
|
18 | 25 | }, |
|
19 | 26 | 'Tenno Seremel': { |
|
20 | 27 | 'name': 'anonymous', |
|
21 | 28 | 'contacts': ['html@serenareem.net'], |
|
22 | 'roles': ['javascript developer', 'designer'], | |
|
29 | 'roles': [ROLE_JS_DEV, ROLE_DESIGNER], | |
|
23 | 30 | }, |
|
24 | 31 | } No newline at end of file |
@@ -9,6 +9,12 b' from neboard import settings' | |||
|
9 | 9 | from boards import utils |
|
10 | 10 | |
|
11 | 11 | LAST_POST_TIME = "last_post_time" |
|
12 | LAST_LOGIN_TIME = "last_login_time" | |
|
13 | ||
|
14 | LOGIN_DELAY = 60 * 60 | |
|
15 | ||
|
16 | MAX_TEXT_LENGTH = 30000 | |
|
17 | MAX_IMAGE_SIZE = 8 * 1024 * 1024 | |
|
12 | 18 | |
|
13 | 19 | |
|
14 | 20 | class PlainErrorList(ErrorList): |
@@ -41,9 +47,6 b' class NeboardForm(forms.Form):' | |||
|
41 | 47 | |
|
42 | 48 | class PostForm(NeboardForm): |
|
43 | 49 | |
|
44 | MAX_TEXT_LENGTH = 30000 | |
|
45 | MAX_IMAGE_SIZE = 8 * 1024 * 1024 | |
|
46 | ||
|
47 | 50 | title = forms.CharField(max_length=TITLE_MAX_LENGTH, required=False) |
|
48 | 51 | text = forms.CharField(widget=forms.Textarea, required=False) |
|
49 | 52 | image = forms.ImageField(required=False) |
@@ -57,34 +60,36 b' class PostForm(NeboardForm):' | |||
|
57 | 60 | title = self.cleaned_data['title'] |
|
58 | 61 | if title: |
|
59 | 62 | if len(title) > TITLE_MAX_LENGTH: |
|
60 |
raise forms.ValidationError('Title must have less than' |
|
|
61 |
|
|
|
62 |
|
|
|
63 | raise forms.ValidationError(_('Title must have less than %s ' | |
|
64 | 'characters') % | |
|
65 | str(TITLE_MAX_LENGTH)) | |
|
63 | 66 | return title |
|
64 | 67 | |
|
65 | 68 | def clean_text(self): |
|
66 | 69 | text = self.cleaned_data['text'] |
|
67 | 70 | if text: |
|
68 |
if len(text) > |
|
|
69 |
raise forms.ValidationError('Text must have less than ' |
|
|
70 |
|
|
|
71 |
|
|
|
71 | if len(text) > MAX_TEXT_LENGTH: | |
|
72 | raise forms.ValidationError(_('Text must have less than %s ' | |
|
73 | 'characters') % | |
|
74 | str(MAX_TEXT_LENGTH)) | |
|
72 | 75 | return text |
|
73 | 76 | |
|
74 | 77 | def clean_image(self): |
|
75 | 78 | image = self.cleaned_data['image'] |
|
76 | 79 | if image: |
|
77 |
if image._size > |
|
|
78 |
raise forms.ValidationError('Image must be less than ' |
|
|
79 |
str( |
|
|
80 | ' bytes.') | |
|
80 | if image._size > MAX_IMAGE_SIZE: | |
|
81 | raise forms.ValidationError(_('Image must be less than %s ' | |
|
82 | 'bytes') % str(MAX_IMAGE_SIZE)) | |
|
81 | 83 | return image |
|
82 | 84 | |
|
83 | 85 | def clean(self): |
|
84 | 86 | cleaned_data = super(PostForm, self).clean() |
|
85 | 87 | |
|
86 | if cleaned_data['email']: | |
|
87 |
|
|
|
88 | if not self.session: | |
|
89 | raise forms.ValidationError('Humans have sessions') | |
|
90 | ||
|
91 | if cleaned_data['email']: | |
|
92 | raise forms.ValidationError('A human cannot enter a hidden field') | |
|
88 | 93 | |
|
89 | 94 | if not self.errors: |
|
90 | 95 | self._clean_text_image() |
@@ -112,9 +117,8 b' class PostForm(NeboardForm):' | |||
|
112 | 117 | current_delay = int(now - last_post_time) |
|
113 | 118 | |
|
114 | 119 | if current_delay < settings.POSTING_DELAY: |
|
115 |
error_message = 'Wait ' |
|
|
116 |
|
|
|
117 | + ' seconds after last posting' | |
|
120 | error_message = _('Wait %s seconds after last posting') % str( | |
|
121 | settings.POSTING_DELAY - current_delay) | |
|
118 | 122 | self._errors['text'] = self.error_class([error_message]) |
|
119 | 123 | |
|
120 | 124 | can_post = False |
@@ -198,8 +202,11 b' class ModeratorSettingsForm(SettingsForm' | |||
|
198 | 202 | |
|
199 | 203 | |
|
200 | 204 | class LoginForm(NeboardForm): |
|
205 | ||
|
201 | 206 | user_id = forms.CharField() |
|
202 | 207 | |
|
208 | session = None | |
|
209 | ||
|
203 | 210 | def clean_user_id(self): |
|
204 | 211 | user_id = self.cleaned_data['user_id'] |
|
205 | 212 | if user_id: |
@@ -209,7 +216,31 b' class LoginForm(NeboardForm):' | |||
|
209 | 216 | |
|
210 | 217 | return user_id |
|
211 | 218 | |
|
219 | def _validate_login_speed(self): | |
|
220 | can_post = True | |
|
221 | ||
|
222 | if LAST_LOGIN_TIME in self.session: | |
|
223 | now = time.time() | |
|
224 | last_login_time = self.session[LAST_LOGIN_TIME] | |
|
225 | ||
|
226 | current_delay = int(now - last_login_time) | |
|
227 | ||
|
228 | if current_delay < LOGIN_DELAY: | |
|
229 | error_message = _('Wait %s minutes after last login') % str( | |
|
230 | (LOGIN_DELAY - current_delay) / 60) | |
|
231 | self._errors['user_id'] = self.error_class([error_message]) | |
|
232 | ||
|
233 | can_post = False | |
|
234 | ||
|
235 | if can_post: | |
|
236 | self.session[LAST_LOGIN_TIME] = time.time() | |
|
237 | ||
|
212 | 238 | def clean(self): |
|
239 | if not self.session: | |
|
240 | raise forms.ValidationError('Humans have sessions') | |
|
241 | ||
|
242 | self._validate_login_speed() | |
|
243 | ||
|
213 | 244 | cleaned_data = super(LoginForm, self).clean() |
|
214 | 245 | |
|
215 |
return cleaned_data |
|
|
246 | return cleaned_data No newline at end of file |
|
1 | NO CONTENT: modified file, binary diff hidden |
@@ -7,7 +7,7 b' msgid ""' | |||
|
7 | 7 | msgstr "" |
|
8 | 8 | "Project-Id-Version: PACKAGE VERSION\n" |
|
9 | 9 | "Report-Msgid-Bugs-To: \n" |
|
10 |
"POT-Creation-Date: 2013-09-1 |
|
|
10 | "POT-Creation-Date: 2013-09-18 21:02+0300\n" | |
|
11 | 11 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
|
12 | 12 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
|
13 | 13 | "Language-Team: LANGUAGE <LL@li.org>\n" |
@@ -18,31 +18,71 b' msgstr ""' | |||
|
18 | 18 | "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" |
|
19 | 19 | "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" |
|
20 | 20 | |
|
21 |
#: |
|
|
21 | #: authors.py:5 | |
|
22 | msgid "author" | |
|
23 | msgstr "автор" | |
|
24 | ||
|
25 | #: authors.py:6 | |
|
26 | msgid "developer" | |
|
27 | msgstr "разработчик" | |
|
28 | ||
|
29 | #: authors.py:7 | |
|
30 | msgid "javascript developer" | |
|
31 | msgstr "разработчик javascript" | |
|
32 | ||
|
33 | #: authors.py:8 | |
|
34 | msgid "designer" | |
|
35 | msgstr "дизайнер" | |
|
36 | ||
|
37 | #: forms.py:63 | |
|
38 | #, python-format | |
|
39 | msgid "Title must have less than %s characters" | |
|
40 | msgstr "Заголовок должен иметь меньше %s символов" | |
|
41 | ||
|
42 | #: forms.py:72 | |
|
43 | #, python-format | |
|
44 | msgid "Text must have less than %s characters" | |
|
45 | msgstr "Текст должен быть короче %s символов" | |
|
46 | ||
|
47 | #: forms.py:81 | |
|
48 | #, python-format | |
|
49 | msgid "Image must be less than %s bytes" | |
|
50 | msgstr "Изображение должно быть менее %s байт" | |
|
51 | ||
|
52 | #: forms.py:107 | |
|
22 | 53 | msgid "Either text or image must be entered." |
|
23 | 54 | msgstr "Текст или картинка должны быть введены." |
|
24 | 55 | |
|
25 |
#: forms.py:1 |
|
|
56 | #: forms.py:120 | |
|
57 | #, python-format | |
|
58 | msgid "Wait %s seconds after last posting" | |
|
59 | msgstr "Подождите %s секунд после последнего постинга" | |
|
60 | ||
|
61 | #: forms.py:140 | |
|
26 | 62 | msgid "Inappropriate characters in tags." |
|
27 | 63 | msgstr "Недопустимые символы в тегах." |
|
28 | 64 | |
|
29 |
#: forms.py:1 |
|
|
65 | #: forms.py:168 forms.py:189 | |
|
30 | 66 | msgid "Captcha validation failed" |
|
31 | 67 | msgstr "Проверка капчи провалена" |
|
32 | 68 | |
|
33 |
#: forms.py:1 |
|
|
69 | #: forms.py:195 | |
|
34 | 70 | msgid "Theme" |
|
35 | 71 | msgstr "Тема" |
|
36 | 72 | |
|
37 |
#: forms.py: |
|
|
73 | #: forms.py:200 | |
|
38 | 74 | msgid "Enable moderation panel" |
|
39 | 75 | msgstr "Включить панель модерации" |
|
40 | 76 | |
|
41 |
#: forms.py:2 |
|
|
42 | #, fuzzy | |
|
77 | #: forms.py:215 | |
|
43 | 78 | msgid "No such user found" |
|
44 | 79 | msgstr "Теги не найдены." |
|
45 | 80 | |
|
81 | #: forms.py:229 | |
|
82 | #, python-format | |
|
83 | msgid "Wait %s minutes after last login" | |
|
84 | msgstr "Подождите %s минут после последнего входа" | |
|
85 | ||
|
46 | 86 | #: templates/boards/404.html:6 |
|
47 | 87 | msgid "Not found" |
|
48 | 88 | msgstr "Не найдено" |
@@ -122,11 +162,11 b' msgstr "\xd0\xa3\xd0\xb4\xd0\xb0\xd0\xbb\xd0\xb8\xd1\x82\xd1\x8c"' | |||
|
122 | 162 | msgid "Ban IP" |
|
123 | 163 | msgstr "Заблокировать IP" |
|
124 | 164 | |
|
125 |
#: templates/boards/posting_general.html:74 templates/boards/thread.html:11 |
|
|
165 | #: templates/boards/posting_general.html:74 templates/boards/thread.html:121 | |
|
126 | 166 | msgid "replies" |
|
127 | 167 | msgstr "ответов" |
|
128 | 168 | |
|
129 |
#: templates/boards/posting_general.html:75 templates/boards/thread.html:1 |
|
|
169 | #: templates/boards/posting_general.html:75 templates/boards/thread.html:122 | |
|
130 | 170 | msgid "images" |
|
131 | 171 | msgstr "изображений" |
|
132 | 172 | |
@@ -156,20 +196,24 b' msgstr "\xd0\xa2\xd0\xb5\xd0\xba\xd1\x81\xd1\x82"' | |||
|
156 | 196 | msgid "Image" |
|
157 | 197 | msgstr "Изображение" |
|
158 | 198 | |
|
159 |
#: templates/boards/posting_general.html:1 |
|
|
199 | #: templates/boards/posting_general.html:155 templates/boards/thread.html:95 | |
|
200 | msgid "e-mail" | |
|
201 | msgstr "" | |
|
202 | ||
|
203 | #: templates/boards/posting_general.html:168 templates/boards/thread.html:109 | |
|
160 | 204 | msgid "Post" |
|
161 | 205 | msgstr "Отправить" |
|
162 | 206 | |
|
163 |
#: templates/boards/posting_general.html:1 |
|
|
207 | #: templates/boards/posting_general.html:170 | |
|
164 | 208 | msgid "Tags must be delimited by spaces. Text or image is required." |
|
165 | 209 | msgstr "" |
|
166 | 210 | "Теги должны быть разделены пробелами. Текст или изображение обязательны." |
|
167 | 211 | |
|
168 |
#: templates/boards/posting_general.html:1 |
|
|
212 | #: templates/boards/posting_general.html:173 templates/boards/thread.html:111 | |
|
169 | 213 | msgid "Text syntax" |
|
170 | 214 | msgstr "Синтаксис текста" |
|
171 | 215 | |
|
172 |
#: templates/boards/posting_general.html:1 |
|
|
216 | #: templates/boards/posting_general.html:183 | |
|
173 | 217 | msgid "Pages:" |
|
174 | 218 | msgstr "Страницы: " |
|
175 | 219 | |
@@ -209,7 +253,7 b' msgstr "\xd0\xa2\xd0\xb5\xd0\xb3\xd0\xb8 \xd0\xbd\xd0\xb5 \xd0\xbd\xd0\xb0\xd0\xb9\xd0\xb4\xd0\xb5\xd0\xbd\xd1\x8b."' | |||
|
209 | 253 | msgid "Reply to thread" |
|
210 | 254 | msgstr "Ответить в тему" |
|
211 | 255 | |
|
212 |
#: templates/boards/thread.html:1 |
|
|
256 | #: templates/boards/thread.html:123 | |
|
213 | 257 | msgid "Last update: " |
|
214 | 258 | msgstr "Последнее обновление: " |
|
215 | 259 | |
@@ -283,15 +327,3 b' msgstr "\xd0\xa1\xd1\x81\xd1\x8b\xd0\xbb\xd0\xba\xd0\xb0 \xd0\xbd\xd0\xb0 \xd1\x81\xd0\xbe\xd0\xbe\xd0\xb1\xd1\x89\xd0\xb5\xd0\xbd\xd0\xb8\xd0\xb5"' | |||
|
283 | 327 | |
|
284 | 328 | #~ msgid "gets" |
|
285 | 329 | #~ msgstr "гетов" |
|
286 | ||
|
287 | #~ msgid "author" | |
|
288 | #~ msgstr "автор" | |
|
289 | ||
|
290 | #~ msgid "developer" | |
|
291 | #~ msgstr "разработчик" | |
|
292 | ||
|
293 | #~ msgid "javascript developer" | |
|
294 | #~ msgstr "разработчик javascript" | |
|
295 | ||
|
296 | #~ msgid "designer" | |
|
297 | #~ msgstr "дизайнер" |
@@ -167,6 +167,8 b' def login(request):' | |||
|
167 | 167 | if request.method == 'POST': |
|
168 | 168 | form = LoginForm(request.POST, request.FILES, |
|
169 | 169 | error_class=PlainErrorList) |
|
170 | form.session = request.session | |
|
171 | ||
|
170 | 172 | if form.is_valid(): |
|
171 | 173 | user = User.objects.get(user_id=form.cleaned_data['user_id']) |
|
172 | 174 | request.session['user_id'] = user.id |
General Comments 0
You need to be logged in to leave comments.
Login now