##// END OF EJS Templates
Removed old forms, refactored some code for forms and images. Use the same code to compute hash of an image in form and when saving image
neko259 -
r937:eaceb3a3 default
parent child Browse files
Show More
@@ -1,6 +1,5 b''
1 import re
1 import re
2 import time
2 import time
3 import hashlib
4
3
5 from django import forms
4 from django import forms
6 from django.forms.util import ErrorList
5 from django.forms.util import ErrorList
@@ -10,16 +9,17 b' from boards.mdx_neboard import formatter'
10 from boards.models.post import TITLE_MAX_LENGTH
9 from boards.models.post import TITLE_MAX_LENGTH
11 from boards.models import PostImage, Tag
10 from boards.models import PostImage, Tag
12 from neboard import settings
11 from neboard import settings
13 from boards import utils
14 import boards.settings as board_settings
12 import boards.settings as board_settings
15
13
14 REGEX_TAGS = re.compile(r'^[\w\s\d]+$', re.UNICODE)
15
16 VETERAN_POSTING_DELAY = 5
16 VETERAN_POSTING_DELAY = 5
17
17
18 ATTRIBUTE_PLACEHOLDER = 'placeholder'
18 ATTRIBUTE_PLACEHOLDER = 'placeholder'
19
19
20 LAST_POST_TIME = 'last_post_time'
20 LAST_POST_TIME = 'last_post_time'
21 LAST_LOGIN_TIME = 'last_login_time'
21 LAST_LOGIN_TIME = 'last_login_time'
22 TEXT_PLACEHOLDER = _('''Type message here. Use formatting panel for more advanced usage.''')
22 TEXT_PLACEHOLDER = _('Type message here. Use formatting panel for more advanced usage.')
23 TAGS_PLACEHOLDER = _('tag1 several_words_tag')
23 TAGS_PLACEHOLDER = _('tag1 several_words_tag')
24
24
25 ERROR_IMAGE_DUPLICATE = _('Such image was already posted')
25 ERROR_IMAGE_DUPLICATE = _('Such image was already posted')
@@ -31,10 +31,13 b" LABEL_SEARCH = _('Search')"
31
31
32 TAG_MAX_LENGTH = 20
32 TAG_MAX_LENGTH = 20
33
33
34 REGEX_TAG = r'^[\w\d]+$'
35
36
34
37 class FormatPanel(forms.Textarea):
35 class FormatPanel(forms.Textarea):
36 """
37 Panel for text formatting. Consists of buttons to add different tags to the
38 form text area.
39 """
40
38 def render(self, name, value, attrs=None):
41 def render(self, name, value, attrs=None):
39 output = '<div id="mark-panel">'
42 output = '<div id="mark-panel">'
40 for formatter in formatters:
43 for formatter in formatters:
@@ -59,6 +62,9 b' class PlainErrorList(ErrorList):'
59
62
60
63
61 class NeboardForm(forms.Form):
64 class NeboardForm(forms.Form):
65 """
66 Form with neboard-specific formatting.
67 """
62
68
63 def as_div(self):
69 def as_div(self):
64 """
70 """
@@ -143,10 +149,7 b' class PostForm(NeboardForm):'
143 _('Image must be less than %s bytes')
149 _('Image must be less than %s bytes')
144 % str(board_settings.MAX_IMAGE_SIZE))
150 % str(board_settings.MAX_IMAGE_SIZE))
145
151
146 md5 = hashlib.md5()
152 image_hash = PostImage.get_hash(image)
147 for chunk in image.chunks():
148 md5.update(chunk)
149 image_hash = md5.hexdigest()
150 if PostImage.objects.filter(hash=image_hash).exists():
153 if PostImage.objects.filter(hash=image_hash).exists():
151 raise forms.ValidationError(ERROR_IMAGE_DUPLICATE)
154 raise forms.ValidationError(ERROR_IMAGE_DUPLICATE)
152
155
@@ -203,8 +206,6 b' class PostForm(NeboardForm):'
203
206
204 class ThreadForm(PostForm):
207 class ThreadForm(PostForm):
205
208
206 regex_tags = re.compile(r'^[\w\s\d]+$', re.UNICODE)
207
208 tags = forms.CharField(
209 tags = forms.CharField(
209 widget=forms.TextInput(attrs={ATTRIBUTE_PLACEHOLDER: TAGS_PLACEHOLDER}),
210 widget=forms.TextInput(attrs={ATTRIBUTE_PLACEHOLDER: TAGS_PLACEHOLDER}),
210 max_length=100, label=_('Tags'), required=True)
211 max_length=100, label=_('Tags'), required=True)
@@ -212,17 +213,17 b' class ThreadForm(PostForm):'
212 def clean_tags(self):
213 def clean_tags(self):
213 tags = self.cleaned_data['tags'].strip()
214 tags = self.cleaned_data['tags'].strip()
214
215
215 if not tags or not self.regex_tags.match(tags):
216 if not tags or not REGEX_TAGS.match(tags):
216 raise forms.ValidationError(
217 raise forms.ValidationError(
217 _('Inappropriate characters in tags.'))
218 _('Inappropriate characters in tags.'))
218
219
219 tag_models = []
220 required_tag_exists = False
220 required_tag_exists = False
221 for tag in tags.split():
221 for tag in tags.split():
222 tag_model = Tag.objects.filter(name=tag.strip().lower(),
222 tag_model = Tag.objects.filter(name=tag.strip().lower(),
223 required=True)
223 required=True)
224 if tag_model.exists():
224 if tag_model.exists():
225 required_tag_exists = True
225 required_tag_exists = True
226 break
226
227
227 if not required_tag_exists:
228 if not required_tag_exists:
228 raise forms.ValidationError(_('Need at least 1 required tag.'))
229 raise forms.ValidationError(_('Need at least 1 required tag.'))
@@ -241,65 +242,5 b' class SettingsForm(NeboardForm):'
241 label=_('Theme'))
242 label=_('Theme'))
242
243
243
244
244 class AddTagForm(NeboardForm):
245
246 tag = forms.CharField(max_length=TAG_MAX_LENGTH, label=LABEL_TAG)
247 method = forms.CharField(widget=forms.HiddenInput(), initial='add_tag')
248
249 def clean_tag(self):
250 tag = self.cleaned_data['tag']
251
252 regex_tag = re.compile(REGEX_TAG, re.UNICODE)
253 if not regex_tag.match(tag):
254 raise forms.ValidationError(_('Inappropriate characters in tags.'))
255
256 return tag
257
258 def clean(self):
259 cleaned_data = super(AddTagForm, self).clean()
260
261 return cleaned_data
262
263
264 class SearchForm(NeboardForm):
245 class SearchForm(NeboardForm):
265 query = forms.CharField(max_length=500, label=LABEL_SEARCH, required=False)
246 query = forms.CharField(max_length=500, label=LABEL_SEARCH, required=False)
266
267
268 class LoginForm(NeboardForm):
269
270 password = forms.CharField()
271
272 session = None
273
274 def clean_password(self):
275 password = self.cleaned_data['password']
276 if board_settings.MASTER_PASSWORD != password:
277 raise forms.ValidationError(_('Invalid master password'))
278
279 return password
280
281 def _validate_login_speed(self):
282 can_post = True
283
284 if LAST_LOGIN_TIME in self.session:
285 now = time.time()
286 last_login_time = self.session[LAST_LOGIN_TIME]
287
288 current_delay = int(now - last_login_time)
289
290 if current_delay < board_settings.LOGIN_TIMEOUT:
291 error_message = _('Wait %s minutes after last login') % str(
292 (board_settings.LOGIN_TIMEOUT - current_delay) / 60)
293 self._errors['password'] = self.error_class([error_message])
294
295 can_post = False
296
297 if can_post:
298 self.session[LAST_LOGIN_TIME] = time.time()
299
300 def clean(self):
301 self._validate_login_speed()
302
303 cleaned_data = super(LoginForm, self).clean()
304
305 return cleaned_data
@@ -56,10 +56,7 b' class PostImage(models.Model, Viewable):'
56 """
56 """
57
57
58 if not self.pk and self.image:
58 if not self.pk and self.image:
59 md5 = hashlib.md5()
59 self.hash = PostImage.get_hash(self.image)
60 for chunk in self.image.chunks():
61 md5.update(chunk)
62 self.hash = md5.hexdigest()
63 super(PostImage, self).save(*args, **kwargs)
60 super(PostImage, self).save(*args, **kwargs)
64
61
65 def __str__(self):
62 def __str__(self):
@@ -81,3 +78,13 b' class PostImage(models.Model, Viewable):'
81 self.image.url_200x150,
78 self.image.url_200x150,
82 str(self.hash), str(self.pre_width),
79 str(self.hash), str(self.pre_width),
83 str(self.pre_height), str(self.width), str(self.height))
80 str(self.pre_height), str(self.width), str(self.height))
81
82 @staticmethod
83 def get_hash(image):
84 """
85 Gets hash of an image.
86 """
87 md5 = hashlib.md5()
88 for chunk in image.chunks():
89 md5.update(chunk)
90 return md5.hexdigest()
General Comments 0
You need to be logged in to leave comments. Login now