##// END OF EJS Templates
Small code cleanups
neko259 -
r721:1814d7a8 default
parent child Browse files
Show More
@@ -1,31 +1,35
1 __author__ = 'neko259'
2
1 3 from django.utils.translation import ugettext_lazy as _
2 4
3 __author__ = 'neko259'
5 ATTR_ROLES = 'roles'
6 ATTR_CONTACTS = 'contacts'
7 ATTR_NAME = 'name'
4 8
5 9 ROLE_AUTHOR = _('author')
6 10 ROLE_DEVELOPER = _('developer')
7 11 ROLE_JS_DEV = _('javascript developer')
8 12 ROLE_DESIGNER = _('designer')
9 13
10 14 authors = {
11 15 'neko259': {
12 'name': 'Pavel Ryapolov',
13 'contacts': ['neko259@gmail.com'],
14 'roles': [ROLE_AUTHOR, ROLE_DEVELOPER],
16 ATTR_NAME: 'Pavel Ryapolov',
17 ATTR_CONTACTS: ['neko259@gmail.com'],
18 ATTR_ROLES: [ROLE_AUTHOR, ROLE_DEVELOPER],
15 19 },
16 20 'ilyas': {
17 'name': 'Ilyas Babayev',
18 'contacts': ['zamesilyasa@gmail.com'],
19 'roles': [ROLE_AUTHOR, ROLE_DEVELOPER],
21 ATTR_NAME: 'Ilyas Babayev',
22 ATTR_CONTACTS: ['zamesilyasa@gmail.com'],
23 ATTR_ROLES: [ROLE_AUTHOR, ROLE_DEVELOPER],
20 24 },
21 25 'ritsufag': {
22 'name': 'Aiko Kirino',
23 'contacts': ['ritsufag@gmail.com'],
24 'roles': [ROLE_JS_DEV, ROLE_DESIGNER],
26 ATTR_NAME: 'Aiko Kirino',
27 ATTR_CONTACTS: ['ritsufag@gmail.com'],
28 ATTR_ROLES: [ROLE_JS_DEV, ROLE_DESIGNER],
25 29 },
26 30 'Tenno Seremel': {
27 'name': 'anonymous',
28 'contacts': ['html@serenareem.net'],
29 'roles': [ROLE_JS_DEV, ROLE_DESIGNER],
31 ATTR_NAME: 'anonymous',
32 ATTR_CONTACTS: ['html@serenareem.net'],
33 ATTR_ROLES: [ROLE_JS_DEV, ROLE_DESIGNER],
30 34 },
31 35 } No newline at end of file
@@ -1,30 +1,39
1 __author__ = 'neko259'
2
1 3 from boards import utils, settings
2 4 from boards.models import Post
3 5 from boards.models.post import SETTING_MODERATE
4 6
5 __author__ = 'neko259'
7 CONTEXT_SITE_NAME = 'site_name'
8 CONTEXT_VERSION = 'version'
9 CONTEXT_MODERATOR = 'moderator'
10 CONTEXT_THEME_CSS = 'theme_css'
11 CONTEXT_THEME = 'theme'
12 CONTEXT_PPD = 'posts_per_day'
13 CONTEXT_TAGS = 'tags'
14 CONTEXT_USER = 'user'
6 15
7 16
8 17 def user_and_ui_processor(request):
9 18 context = {}
10 19
11 20 user = utils.get_user(request)
12 context['user'] = user
13 context['tags'] = user.fav_tags.all()
14 context['posts_per_day'] = float(Post.objects.get_posts_per_day())
21 context[CONTEXT_USER] = user
22 context[CONTEXT_TAGS] = user.fav_tags.all()
23 context[CONTEXT_PPD] = float(Post.objects.get_posts_per_day())
15 24
16 25 theme = utils.get_theme(request, user)
17 context['theme'] = theme
18 context['theme_css'] = 'css/' + theme + '/base_page.css'
26 context[CONTEXT_THEME] = theme
27 context[CONTEXT_THEME_CSS] = 'css/' + theme + '/base_page.css'
19 28
20 29 # This shows the moderator panel
21 30 moderate = user.get_setting(SETTING_MODERATE)
22 31 if moderate == 'True':
23 context['moderator'] = user.is_moderator()
32 context[CONTEXT_MODERATOR] = user.is_moderator()
24 33 else:
25 context['moderator'] = False
34 context[CONTEXT_MODERATOR] = False
26 35
27 context['version'] = settings.VERSION
28 context['site_name'] = settings.SITE_NAME
36 context[CONTEXT_VERSION] = settings.VERSION
37 context[CONTEXT_SITE_NAME] = settings.SITE_NAME
29 38
30 39 return context No newline at end of file
@@ -1,355 +1,356
1 1 import re
2 2 import time
3 3 import hashlib
4 4
5 5 from captcha.fields import CaptchaField
6 6 from django import forms
7 7 from django.forms.util import ErrorList
8 8 from django.utils.translation import ugettext_lazy as _
9 9
10 10 from boards.mdx_neboard import formatters
11 11 from boards.models.post import TITLE_MAX_LENGTH
12 12 from boards.models import User, PostImage
13 13 from neboard import settings
14 14 from boards import utils
15 15 import boards.settings as board_settings
16 16
17 17 VETERAN_POSTING_DELAY = 5
18 18
19 19 ATTRIBUTE_PLACEHOLDER = 'placeholder'
20 20
21 21 LAST_POST_TIME = 'last_post_time'
22 22 LAST_LOGIN_TIME = 'last_login_time'
23 23 TEXT_PLACEHOLDER = _('''Type message here. You can reply to message >>123 like
24 24 this. 2 new lines are required to start new paragraph.''')
25 25 TAGS_PLACEHOLDER = _('tag1 several_words_tag')
26 26
27 27 ERROR_IMAGE_DUPLICATE = _('Such image was already posted')
28 28
29 29 LABEL_TITLE = _('Title')
30 30 LABEL_TEXT = _('Text')
31 31 LABEL_TAG = _('Tag')
32 32 LABEL_SEARCH = _('Search')
33 33
34 34 TAG_MAX_LENGTH = 20
35 35
36 36 REGEX_TAG = ur'^[\w\d]+$'
37 37
38 38
39 39 class FormatPanel(forms.Textarea):
40 40 def render(self, name, value, attrs=None):
41 41 output = '<div id="mark-panel">'
42 42 for formatter in formatters:
43 43 output += u'<span class="mark_btn"' + \
44 44 u' onClick="addMarkToMsg(\'' + formatter.format_left + \
45 45 '\', \'' + formatter.format_right + '\')">' + \
46 46 formatter.preview_left + formatter.name + \
47 47 formatter.preview_right + u'</span>'
48 48
49 49 output += '</div>'
50 50 output += super(FormatPanel, self).render(name, value, attrs=None)
51 51
52 52 return output
53 53
54 54
55 55 class PlainErrorList(ErrorList):
56 56 def __unicode__(self):
57 57 return self.as_text()
58 58
59 59 def as_text(self):
60 60 return ''.join([u'(!) %s ' % e for e in self])
61 61
62 62
63 63 class NeboardForm(forms.Form):
64 64
65 65 def as_div(self):
66 66 """
67 67 Returns this form rendered as HTML <as_div>s.
68 68 """
69 69
70 70 return self._html_output(
71 71 # TODO Do not show hidden rows in the list here
72 72 normal_row='<div class="form-row"><div class="form-label">'
73 73 '%(label)s'
74 74 '</div></div>'
75 75 '<div class="form-row"><div class="form-input">'
76 76 '%(field)s'
77 77 '</div></div>'
78 78 '<div class="form-row">'
79 79 '%(help_text)s'
80 80 '</div>',
81 81 error_row='<div class="form-row">'
82 82 '<div class="form-label"></div>'
83 83 '<div class="form-errors">%s</div>'
84 84 '</div>',
85 85 row_ender='</div>',
86 86 help_text_html='%s',
87 87 errors_on_separate_row=True)
88 88
89 89 def as_json_errors(self):
90 90 errors = []
91 91
92 92 for name, field in self.fields.items():
93 93 if self[name].errors:
94 94 errors.append({
95 95 'field': name,
96 96 'errors': self[name].errors.as_text(),
97 97 })
98 98
99 99 return errors
100 100
101 101
102 102 class PostForm(NeboardForm):
103 103
104 104 title = forms.CharField(max_length=TITLE_MAX_LENGTH, required=False,
105 105 label=LABEL_TITLE)
106 106 text = forms.CharField(
107 107 widget=FormatPanel(attrs={ATTRIBUTE_PLACEHOLDER: TEXT_PLACEHOLDER}),
108 108 required=False, label=LABEL_TEXT)
109 109 image = forms.ImageField(required=False, label=_('Image'),
110 widget=forms.ClearableFileInput(attrs={'accept': 'image/*'}))
110 widget=forms.ClearableFileInput(
111 attrs={'accept': 'image/*'}))
111 112
112 113 # This field is for spam prevention only
113 114 email = forms.CharField(max_length=100, required=False, label=_('e-mail'),
114 115 widget=forms.TextInput(attrs={
115 116 'class': 'form-email'}))
116 117
117 118 session = None
118 119 need_to_ban = False
119 120
120 121 def clean_title(self):
121 122 title = self.cleaned_data['title']
122 123 if title:
123 124 if len(title) > TITLE_MAX_LENGTH:
124 125 raise forms.ValidationError(_('Title must have less than %s '
125 126 'characters') %
126 127 str(TITLE_MAX_LENGTH))
127 128 return title
128 129
129 130 def clean_text(self):
130 131 text = self.cleaned_data['text'].strip()
131 132 if text:
132 133 if len(text) > board_settings.MAX_TEXT_LENGTH:
133 134 raise forms.ValidationError(_('Text must have less than %s '
134 135 'characters') %
135 136 str(board_settings
136 137 .MAX_TEXT_LENGTH))
137 138 return text
138 139
139 140 def clean_image(self):
140 141 image = self.cleaned_data['image']
141 142 if image:
142 if image._size > board_settings.MAX_IMAGE_SIZE:
143 if image.size > board_settings.MAX_IMAGE_SIZE:
143 144 raise forms.ValidationError(
144 145 _('Image must be less than %s bytes')
145 146 % str(board_settings.MAX_IMAGE_SIZE))
146 147
147 148 md5 = hashlib.md5()
148 149 for chunk in image.chunks():
149 150 md5.update(chunk)
150 151 image_hash = md5.hexdigest()
151 152 if PostImage.objects.filter(hash=image_hash).exists():
152 153 raise forms.ValidationError(ERROR_IMAGE_DUPLICATE)
153 154
154 155 return image
155 156
156 157 def clean(self):
157 158 cleaned_data = super(PostForm, self).clean()
158 159
159 160 if not self.session:
160 161 raise forms.ValidationError('Humans have sessions')
161 162
162 163 if cleaned_data['email']:
163 164 self.need_to_ban = True
164 165 raise forms.ValidationError('A human cannot enter a hidden field')
165 166
166 167 if not self.errors:
167 168 self._clean_text_image()
168 169
169 170 if not self.errors and self.session:
170 171 self._validate_posting_speed()
171 172
172 173 return cleaned_data
173 174
174 175 def _clean_text_image(self):
175 176 text = self.cleaned_data.get('text')
176 177 image = self.cleaned_data.get('image')
177 178
178 179 if (not text) and (not image):
179 180 error_message = _('Either text or image must be entered.')
180 181 self._errors['text'] = self.error_class([error_message])
181 182
182 183 def _validate_posting_speed(self):
183 184 can_post = True
184 185
185 186 # TODO Remove this, it's only for test
186 187 if not 'user_id' in self.session:
187 188 return
188 189
189 190 user = User.objects.get(id=self.session['user_id'])
190 191 if user.is_veteran():
191 192 posting_delay = VETERAN_POSTING_DELAY
192 193 else:
193 194 posting_delay = settings.POSTING_DELAY
194 195
195 196 if LAST_POST_TIME in self.session:
196 197 now = time.time()
197 198 last_post_time = self.session[LAST_POST_TIME]
198 199
199 200 current_delay = int(now - last_post_time)
200 201
201 202 if current_delay < posting_delay:
202 203 error_message = _('Wait %s seconds after last posting') % str(
203 204 posting_delay - current_delay)
204 205 self._errors['text'] = self.error_class([error_message])
205 206
206 207 can_post = False
207 208
208 209 if can_post:
209 210 self.session[LAST_POST_TIME] = time.time()
210 211
211 212
212 213 class ThreadForm(PostForm):
213 214
214 215 regex_tags = re.compile(ur'^[\w\s\d]+$', re.UNICODE)
215 216
216 217 tags = forms.CharField(
217 218 widget=forms.TextInput(attrs={ATTRIBUTE_PLACEHOLDER: TAGS_PLACEHOLDER}),
218 219 max_length=100, label=_('Tags'), required=True)
219 220
220 221 def clean_tags(self):
221 222 tags = self.cleaned_data['tags'].strip()
222 223
223 224 if not tags or not self.regex_tags.match(tags):
224 225 raise forms.ValidationError(
225 226 _('Inappropriate characters in tags.'))
226 227
227 228 return tags
228 229
229 230 def clean(self):
230 231 cleaned_data = super(ThreadForm, self).clean()
231 232
232 233 return cleaned_data
233 234
234 235
235 236 class PostCaptchaForm(PostForm):
236 237 captcha = CaptchaField()
237 238
238 239 def __init__(self, *args, **kwargs):
239 240 self.request = kwargs['request']
240 241 del kwargs['request']
241 242
242 243 super(PostCaptchaForm, self).__init__(*args, **kwargs)
243 244
244 245 def clean(self):
245 246 cleaned_data = super(PostCaptchaForm, self).clean()
246 247
247 248 success = self.is_valid()
248 249 utils.update_captcha_access(self.request, success)
249 250
250 251 if success:
251 252 return cleaned_data
252 253 else:
253 254 raise forms.ValidationError(_("Captcha validation failed"))
254 255
255 256
256 257 class ThreadCaptchaForm(ThreadForm):
257 258 captcha = CaptchaField()
258 259
259 260 def __init__(self, *args, **kwargs):
260 261 self.request = kwargs['request']
261 262 del kwargs['request']
262 263
263 264 super(ThreadCaptchaForm, self).__init__(*args, **kwargs)
264 265
265 266 def clean(self):
266 267 cleaned_data = super(ThreadCaptchaForm, self).clean()
267 268
268 269 success = self.is_valid()
269 270 utils.update_captcha_access(self.request, success)
270 271
271 272 if success:
272 273 return cleaned_data
273 274 else:
274 275 raise forms.ValidationError(_("Captcha validation failed"))
275 276
276 277
277 278 class SettingsForm(NeboardForm):
278 279
279 280 theme = forms.ChoiceField(choices=settings.THEMES,
280 281 label=_('Theme'))
281 282
282 283
283 284 class ModeratorSettingsForm(SettingsForm):
284 285
285 286 moderate = forms.BooleanField(required=False, label=_('Enable moderation '
286 287 'panel'))
287 288
288 289
289 290 class LoginForm(NeboardForm):
290 291
291 292 user_id = forms.CharField()
292 293
293 294 session = None
294 295
295 296 def clean_user_id(self):
296 297 user_id = self.cleaned_data['user_id']
297 298 if user_id:
298 299 users = User.objects.filter(user_id=user_id)
299 300 if len(users) == 0:
300 301 raise forms.ValidationError(_('No such user found'))
301 302
302 303 return user_id
303 304
304 305 def _validate_login_speed(self):
305 306 can_post = True
306 307
307 308 if LAST_LOGIN_TIME in self.session:
308 309 now = time.time()
309 310 last_login_time = self.session[LAST_LOGIN_TIME]
310 311
311 312 current_delay = int(now - last_login_time)
312 313
313 314 if current_delay < board_settings.LOGIN_TIMEOUT:
314 315 error_message = _('Wait %s minutes after last login') % str(
315 316 (board_settings.LOGIN_TIMEOUT - current_delay) / 60)
316 317 self._errors['user_id'] = self.error_class([error_message])
317 318
318 319 can_post = False
319 320
320 321 if can_post:
321 322 self.session[LAST_LOGIN_TIME] = time.time()
322 323
323 324 def clean(self):
324 325 if not self.session:
325 326 raise forms.ValidationError('Humans have sessions')
326 327
327 328 self._validate_login_speed()
328 329
329 330 cleaned_data = super(LoginForm, self).clean()
330 331
331 332 return cleaned_data
332 333
333 334
334 335 class AddTagForm(NeboardForm):
335 336
336 337 tag = forms.CharField(max_length=TAG_MAX_LENGTH, label=LABEL_TAG)
337 338 method = forms.CharField(widget=forms.HiddenInput(), initial='add_tag')
338 339
339 340 def clean_tag(self):
340 341 tag = self.cleaned_data['tag']
341 342
342 343 regex_tag = re.compile(REGEX_TAG, re.UNICODE)
343 344 if not regex_tag.match(tag):
344 345 raise forms.ValidationError(_('Inappropriate characters in tags.'))
345 346
346 347 return tag
347 348
348 349 def clean(self):
349 350 cleaned_data = super(AddTagForm, self).clean()
350 351
351 352 return cleaned_data
352 353
353 354
354 355 class SearchForm(NeboardForm):
355 356 query = forms.CharField(max_length=500, label=LABEL_SEARCH, required=False) No newline at end of file
@@ -1,202 +1,207
1 1 # coding=utf-8
2 2
3 3 import markdown
4 from markdown.inlinepatterns import Pattern, SubstituteTagPattern
4 from markdown.inlinepatterns import Pattern
5 5 from markdown.util import etree
6
6 7 import boards
7 8
9
8 10 __author__ = 'neko259'
9 11
10 12
11 13 AUTOLINK_PATTERN = r'(https?://\S+)'
12 14 QUOTE_PATTERN = r'^(?<!>)(>[^>].*)$'
13 15 REFLINK_PATTERN = r'((>>)(\d+))'
14 16 SPOILER_PATTERN = r'%%([^(%%)]+)%%'
15 17 COMMENT_PATTERN = r'^(//(.+))'
16 18 STRIKETHROUGH_PATTERN = r'~(.+)~'
17 19 DASH_PATTERN = r'--'
18 20
19 21
20 22 class TextFormatter():
21 23 """
22 24 An interface for formatter that can be used in the text format panel
23 25 """
24 26
27 def __init__(self):
28 pass
29
25 30 name = ''
26 31
27 32 # Left and right tags for the button preview
28 33 preview_left = ''
29 34 preview_right = ''
30 35
31 36 # Left and right characters for the textarea input
32 37 format_left = ''
33 38 format_right = ''
34 39
35 40
36 41 class AutolinkPattern(Pattern):
37 42 def handleMatch(self, m):
38 43 link_element = etree.Element('a')
39 44 href = m.group(2)
40 45 link_element.set('href', href)
41 46 link_element.text = href
42 47
43 48 return link_element
44 49
45 50
46 51 class QuotePattern(Pattern, TextFormatter):
47 52 name = ''
48 53 preview_left = '<span class="quote">&gt; '
49 54 preview_right = '</span>'
50 55
51 56 format_left = '&gt;'
52 57
53 58 def handleMatch(self, m):
54 59 quote_element = etree.Element('span')
55 60 quote_element.set('class', 'quote')
56 61 quote_element.text = m.group(2)
57 62
58 63 return quote_element
59 64
60 65
61 66 class ReflinkPattern(Pattern):
62 67 def handleMatch(self, m):
63 68 post_id = m.group(4)
64 69
65 70 posts = boards.models.Post.objects.filter(id=post_id)
66 71 if posts.count() > 0:
67 72 ref_element = etree.Element('a')
68 73
69 74 post = posts[0]
70 75
71 76 ref_element.set('href', post.get_url())
72 77 ref_element.text = m.group(2)
73 78
74 79 return ref_element
75 80
76 81
77 82 class SpoilerPattern(Pattern, TextFormatter):
78 83 name = 's'
79 84 preview_left = '<span class="spoiler">'
80 85 preview_right = '</span>'
81 86
82 87 format_left = '%%'
83 88 format_right = '%%'
84 89
85 90 def handleMatch(self, m):
86 91 quote_element = etree.Element('span')
87 92 quote_element.set('class', 'spoiler')
88 93 quote_element.text = m.group(2)
89 94
90 95 return quote_element
91 96
92 97
93 98 class CommentPattern(Pattern, TextFormatter):
94 99 name = ''
95 100 preview_left = '<span class="comment">// '
96 101 preview_right = '</span>'
97 102
98 103 format_left = '//'
99 104
100 105 def handleMatch(self, m):
101 106 quote_element = etree.Element('span')
102 107 quote_element.set('class', 'comment')
103 108 quote_element.text = '//' + m.group(3)
104 109
105 110 return quote_element
106 111
107 112
108 113 class StrikeThroughPattern(Pattern, TextFormatter):
109 114 name = 's'
110 115 preview_left = '<span class="strikethrough">'
111 116 preview_right = '</span>'
112 117
113 118 format_left = '~'
114 119 format_right = '~'
115 120
116 121 def handleMatch(self, m):
117 122 quote_element = etree.Element('span')
118 123 quote_element.set('class', 'strikethrough')
119 124 quote_element.text = m.group(2)
120 125
121 126 return quote_element
122 127
123 128
124 129 class ItalicPattern(TextFormatter):
125 130 name = 'i'
126 131 preview_left = '<i>'
127 132 preview_right = '</i>'
128 133
129 134 format_left = '_'
130 135 format_right = '_'
131 136
132 137
133 138 class BoldPattern(TextFormatter):
134 139 name = 'b'
135 140 preview_left = '<b>'
136 141 preview_right = '</b>'
137 142
138 143 format_left = '__'
139 144 format_right = '__'
140 145
141 146
142 147 class CodePattern(TextFormatter):
143 148 name = 'code'
144 149 preview_left = '<code>'
145 150 preview_right = '</code>'
146 151
147 152 format_left = ' '
148 153
149 154
150 155 class DashPattern(Pattern):
151 156 def handleMatch(self, m):
152 157 return u'—'
153 158
154 159
155 160 class NeboardMarkdown(markdown.Extension):
156 161 def extendMarkdown(self, md, md_globals):
157 162 self._add_neboard_patterns(md)
158 163 self._delete_patterns(md)
159 164
160 165 def _delete_patterns(self, md):
161 166 del md.parser.blockprocessors['quote']
162 167
163 168 del md.inlinePatterns['image_link']
164 169 del md.inlinePatterns['image_reference']
165 170
166 171 def _add_neboard_patterns(self, md):
167 172 autolink = AutolinkPattern(AUTOLINK_PATTERN, md)
168 173 quote = QuotePattern(QUOTE_PATTERN, md)
169 174 reflink = ReflinkPattern(REFLINK_PATTERN, md)
170 175 spoiler = SpoilerPattern(SPOILER_PATTERN, md)
171 176 comment = CommentPattern(COMMENT_PATTERN, md)
172 177 strikethrough = StrikeThroughPattern(STRIKETHROUGH_PATTERN, md)
173 178 dash = DashPattern(DASH_PATTERN, md)
174 179
175 180 md.inlinePatterns[u'autolink_ext'] = autolink
176 181 md.inlinePatterns[u'spoiler'] = spoiler
177 182 md.inlinePatterns[u'strikethrough'] = strikethrough
178 183 md.inlinePatterns[u'comment'] = comment
179 184 md.inlinePatterns[u'reflink'] = reflink
180 185 md.inlinePatterns[u'quote'] = quote
181 186 md.inlinePatterns[u'dash'] = dash
182 187
183 188
184 189 def make_extension(configs=None):
185 190 return NeboardMarkdown(configs=configs)
186 191
187 192 neboard_extension = make_extension()
188 193
189 194
190 195 def markdown_extended(markup):
191 196 return markdown.markdown(markup, [neboard_extension, 'nl2br'],
192 197 safe_mode='escape')
193 198
194 199 formatters = [
195 200 QuotePattern,
196 201 SpoilerPattern,
197 202 ItalicPattern,
198 203 BoldPattern,
199 204 CommentPattern,
200 205 StrikeThroughPattern,
201 206 CodePattern,
202 207 ]
@@ -1,42 +1,46
1 1 from django.shortcuts import redirect
2 2 from boards import utils
3 3 from boards.models import Ban
4 4 from django.utils.html import strip_spaces_between_tags
5 5 from django.conf import settings
6 6 from boards.views.banned import BannedView
7 7
8 8 RESPONSE_CONTENT_TYPE = 'Content-Type'
9 9
10 10 TYPE_HTML = 'text/html'
11 11
12 12
13 13 class BanMiddleware:
14 14 """
15 15 This is run before showing the thread. Banned users don't need to see
16 16 anything
17 17 """
18 18
19 def __init__(self):
20 pass
21
19 22 def process_view(self, request, view_func, view_args, view_kwargs):
20 23
21 24 if view_func != BannedView.as_view:
22 25 ip = utils.get_client_ip(request)
23 26 bans = Ban.objects.filter(ip=ip)
24 27
25 28 if bans.exists():
26 29 ban = bans[0]
27 30 if not ban.can_read:
28 31 return redirect('banned')
29 32
30 33
31 34 class MinifyHTMLMiddleware(object):
32 35 def process_response(self, request, response):
33 36 try:
34 37 compress_html = settings.COMPRESS_HTML
35 38 except AttributeError:
36 39 compress_html = False
37 40
38 41 if RESPONSE_CONTENT_TYPE in response\
39 and TYPE_HTML in response[RESPONSE_CONTENT_TYPE] and compress_html:
42 and TYPE_HTML in response[RESPONSE_CONTENT_TYPE]\
43 and compress_html:
40 44 response.content = strip_spaces_between_tags(
41 45 response.content.strip())
42 46 return response No newline at end of file
@@ -1,23 +1,26
1 1 import sys
2 2 from cStringIO import StringIO
3 3 from django.conf import settings
4 4 import line_profiler
5 5
6 6
7 class ProfilerMiddleware(object):
7 class ProfilerMiddleware():
8 def __init__(self):
9 self.profiler = None
10
8 11 def process_view(self, request, callback, callback_args, callback_kwargs):
9 12 if settings.DEBUG and 'prof' in request.GET:
10 13 self.profiler = line_profiler.LineProfiler()
11 14 self.profiler.add_function(callback)
12 15 self.profiler.enable()
13 16 args = (request,) + callback_args
14 17 return callback(*args, **callback_kwargs)
15 18
16 19 def process_response(self, request, response):
17 20 if settings.DEBUG and 'prof' in request.GET:
18 21 out = StringIO()
19 22 old_stdout, sys.stdout = sys.stdout, out
20 23 self.profiler.print_stats()
21 24 sys.stdout = old_stdout
22 25 response.content = '<pre>%s</pre>' % out.getvalue()
23 26 return response
@@ -1,33 +1,41
1 1 from django.shortcuts import render
2 2 from django.template import RequestContext
3 3 from django.views.generic import View
4 4 from haystack.query import SearchQuerySet
5 5 from boards.abstracts.paginator import get_paginator
6 6 from boards.forms import SearchForm, PlainErrorList
7 7
8 FORM_QUERY = 'query'
9
10 CONTEXT_QUERY = 'query'
11 CONTEXT_FORM = 'form'
12 CONTEXT_PAGE = 'page'
13
14 REQUEST_PAGE = 'page'
15
8 16 __author__ = 'neko259'
9 17
10 18 TEMPLATE = 'search/search.html'
11 19
12 20
13 21 class BoardSearchView(View):
14 22 def get(self, request):
15 23 context = RequestContext(request)
16 24 form = SearchForm(request.GET, error_class=PlainErrorList)
17 context['form'] = form
25 context[CONTEXT_FORM] = form
18 26
19 27 if form.is_valid():
20 query = form.cleaned_data['query']
28 query = form.cleaned_data[FORM_QUERY]
21 29 if len(query) >= 3:
22 30 results = SearchQuerySet().auto_query(query).order_by('-id') \
23 31 .highlight()
24 32 paginator = get_paginator(results, 10)
25 33
26 if 'page' in request.GET:
27 page = int(request.GET['page'])
34 if REQUEST_PAGE in request.GET:
35 page = int(request.GET[REQUEST_PAGE])
28 36 else:
29 37 page = 1
30 context['page'] = paginator.page(page)
31 context['query'] = query
38 context[CONTEXT_PAGE] = paginator.page(page)
39 context[CONTEXT_QUERY] = query
32 40
33 41 return render(request, TEMPLATE, context) No newline at end of file
@@ -1,9 +1,10
1 line_profiler
1 2 haystack
2 3 pillow
3 4 django>=1.6
4 5 django_cleanup
5 6 django-markupfield
6 7 markdown
7 8 python-markdown
8 9 django-simple-captcha
9 10 line-profiler
General Comments 0
You need to be logged in to leave comments. Login now