##// END OF EJS Templates
Optimized one query, removed debug code from settings so that it is run only...
neko259 -
r472:df52a056 default
parent child Browse files
Show More
@@ -1,564 +1,564 b''
1 __author__ = 'neko259'
1 __author__ = 'neko259'
2
2
3 import hashlib
3 import hashlib
4 import string
4 import string
5 import time
5 import time
6 import re
6 import re
7
7
8 from django.core import serializers
8 from django.core import serializers
9 from django.core.urlresolvers import reverse
9 from django.core.urlresolvers import reverse
10 from django.http import HttpResponseRedirect, Http404
10 from django.http import HttpResponseRedirect, Http404
11 from django.http.response import HttpResponse
11 from django.http.response import HttpResponse
12 from django.template import RequestContext
12 from django.template import RequestContext
13 from django.shortcuts import render, redirect, get_object_or_404
13 from django.shortcuts import render, redirect, get_object_or_404
14 from django.utils import timezone
14 from django.utils import timezone
15 from django.db import transaction
15 from django.db import transaction
16 from django.views.decorators.cache import cache_page
16 from django.views.decorators.cache import cache_page
17 from django.views.i18n import javascript_catalog
17 from django.views.i18n import javascript_catalog
18
18
19 from boards import forms
19 from boards import forms
20 import boards
20 import boards
21 from boards import utils
21 from boards import utils
22 from boards.forms import ThreadForm, PostForm, SettingsForm, PlainErrorList, \
22 from boards.forms import ThreadForm, PostForm, SettingsForm, PlainErrorList, \
23 ThreadCaptchaForm, PostCaptchaForm, LoginForm, ModeratorSettingsForm
23 ThreadCaptchaForm, PostCaptchaForm, LoginForm, ModeratorSettingsForm
24 from boards.models import Post, Tag, Ban, User
24 from boards.models import Post, Tag, Ban, User
25 from boards.models.post import SETTING_MODERATE, REGEX_REPLY
25 from boards.models.post import SETTING_MODERATE, REGEX_REPLY
26 from boards.models.user import RANK_USER
26 from boards.models.user import RANK_USER
27 from boards import authors
27 from boards import authors
28 from boards.utils import get_client_ip
28 from boards.utils import get_client_ip
29 import neboard
29 import neboard
30
30
31
31
32 BAN_REASON_SPAM = 'Autoban: spam bot'
32 BAN_REASON_SPAM = 'Autoban: spam bot'
33 MODE_GALLERY = 'gallery'
33 MODE_GALLERY = 'gallery'
34 MODE_NORMAL = 'normal'
34 MODE_NORMAL = 'normal'
35
35
36
36
37 def index(request, page=0):
37 def index(request, page=0):
38 context = _init_default_context(request)
38 context = _init_default_context(request)
39
39
40 if utils.need_include_captcha(request):
40 if utils.need_include_captcha(request):
41 threadFormClass = ThreadCaptchaForm
41 threadFormClass = ThreadCaptchaForm
42 kwargs = {'request': request}
42 kwargs = {'request': request}
43 else:
43 else:
44 threadFormClass = ThreadForm
44 threadFormClass = ThreadForm
45 kwargs = {}
45 kwargs = {}
46
46
47 if request.method == 'POST':
47 if request.method == 'POST':
48 form = threadFormClass(request.POST, request.FILES,
48 form = threadFormClass(request.POST, request.FILES,
49 error_class=PlainErrorList, **kwargs)
49 error_class=PlainErrorList, **kwargs)
50 form.session = request.session
50 form.session = request.session
51
51
52 if form.is_valid():
52 if form.is_valid():
53 return _new_post(request, form)
53 return _new_post(request, form)
54 if form.need_to_ban:
54 if form.need_to_ban:
55 # Ban user because he is suspected to be a bot
55 # Ban user because he is suspected to be a bot
56 _ban_current_user(request)
56 _ban_current_user(request)
57 else:
57 else:
58 form = threadFormClass(error_class=PlainErrorList, **kwargs)
58 form = threadFormClass(error_class=PlainErrorList, **kwargs)
59
59
60 threads = []
60 threads = []
61 for thread_to_show in Post.objects.get_threads(page=int(page)):
61 for thread_to_show in Post.objects.get_threads(page=int(page)):
62 threads.append(_get_template_thread(thread_to_show))
62 threads.append(_get_template_thread(thread_to_show))
63
63
64 # TODO Make this generic for tag and threads list pages
64 # TODO Make this generic for tag and threads list pages
65 context['threads'] = None if len(threads) == 0 else threads
65 context['threads'] = None if len(threads) == 0 else threads
66 context['form'] = form
66 context['form'] = form
67 context['current_page'] = int(page)
67 context['current_page'] = int(page)
68
68
69 page_count = Post.objects.get_thread_page_count()
69 page_count = Post.objects.get_thread_page_count()
70 context['pages'] = range(page_count)
70 context['pages'] = range(page_count)
71 page = int(page)
71 page = int(page)
72 if page < page_count - 1:
72 if page < page_count - 1:
73 context['next_page'] = str(page + 1)
73 context['next_page'] = str(page + 1)
74 if page > 0:
74 if page > 0:
75 context['prev_page'] = str(page - 1)
75 context['prev_page'] = str(page - 1)
76
76
77 return render(request, 'boards/posting_general.html',
77 return render(request, 'boards/posting_general.html',
78 context)
78 context)
79
79
80
80
81 @transaction.atomic
81 @transaction.atomic
82 def _new_post(request, form, opening_post=None):
82 def _new_post(request, form, opening_post=None):
83 """Add a new post (in thread or as a reply)."""
83 """Add a new post (in thread or as a reply)."""
84
84
85 ip = get_client_ip(request)
85 ip = get_client_ip(request)
86 is_banned = Ban.objects.filter(ip=ip).exists()
86 is_banned = Ban.objects.filter(ip=ip).exists()
87
87
88 if is_banned:
88 if is_banned:
89 return redirect(you_are_banned)
89 return redirect(you_are_banned)
90
90
91 data = form.cleaned_data
91 data = form.cleaned_data
92
92
93 title = data['title']
93 title = data['title']
94 text = data['text']
94 text = data['text']
95
95
96 text = _remove_invalid_links(text)
96 text = _remove_invalid_links(text)
97
97
98 if 'image' in data.keys():
98 if 'image' in data.keys():
99 image = data['image']
99 image = data['image']
100 else:
100 else:
101 image = None
101 image = None
102
102
103 tags = []
103 tags = []
104
104
105 if not opening_post:
105 if not opening_post:
106 tag_strings = data['tags']
106 tag_strings = data['tags']
107
107
108 if tag_strings:
108 if tag_strings:
109 tag_strings = tag_strings.split(' ')
109 tag_strings = tag_strings.split(' ')
110 for tag_name in tag_strings:
110 for tag_name in tag_strings:
111 tag_name = string.lower(tag_name.strip())
111 tag_name = string.lower(tag_name.strip())
112 if len(tag_name) > 0:
112 if len(tag_name) > 0:
113 tag, created = Tag.objects.get_or_create(name=tag_name)
113 tag, created = Tag.objects.get_or_create(name=tag_name)
114 tags.append(tag)
114 tags.append(tag)
115 post_thread = None
115 post_thread = None
116 else:
116 else:
117 post_thread = opening_post.thread_new
117 post_thread = opening_post.thread_new
118
118
119 post = Post.objects.create_post(title=title, text=text, ip=ip,
119 post = Post.objects.create_post(title=title, text=text, ip=ip,
120 thread=post_thread, image=image,
120 thread=post_thread, image=image,
121 tags=tags, user=_get_user(request))
121 tags=tags, user=_get_user(request))
122
122
123 thread_to_show = (opening_post.id if opening_post else post.id)
123 thread_to_show = (opening_post.id if opening_post else post.id)
124
124
125 if opening_post:
125 if opening_post:
126 return redirect(reverse(thread, kwargs={'post_id': thread_to_show}) +
126 return redirect(reverse(thread, kwargs={'post_id': thread_to_show}) +
127 '#' + str(post.id))
127 '#' + str(post.id))
128 else:
128 else:
129 return redirect(thread, post_id=thread_to_show)
129 return redirect(thread, post_id=thread_to_show)
130
130
131
131
132 def tag(request, tag_name, page=0):
132 def tag(request, tag_name, page=0):
133 """
133 """
134 Get all tag threads. Threads are split in pages, so some page is
134 Get all tag threads. Threads are split in pages, so some page is
135 requested. Default page is 0.
135 requested. Default page is 0.
136 """
136 """
137
137
138 tag = get_object_or_404(Tag, name=tag_name)
138 tag = get_object_or_404(Tag, name=tag_name)
139 threads = []
139 threads = []
140 for thread_to_show in Post.objects.get_threads(page=int(page), tag=tag):
140 for thread_to_show in Post.objects.get_threads(page=int(page), tag=tag):
141 threads.append(_get_template_thread(thread_to_show))
141 threads.append(_get_template_thread(thread_to_show))
142
142
143 if request.method == 'POST':
143 if request.method == 'POST':
144 form = ThreadForm(request.POST, request.FILES,
144 form = ThreadForm(request.POST, request.FILES,
145 error_class=PlainErrorList)
145 error_class=PlainErrorList)
146 form.session = request.session
146 form.session = request.session
147
147
148 if form.is_valid():
148 if form.is_valid():
149 return _new_post(request, form)
149 return _new_post(request, form)
150 if form.need_to_ban:
150 if form.need_to_ban:
151 # Ban user because he is suspected to be a bot
151 # Ban user because he is suspected to be a bot
152 _ban_current_user(request)
152 _ban_current_user(request)
153 else:
153 else:
154 form = forms.ThreadForm(initial={'tags': tag_name},
154 form = forms.ThreadForm(initial={'tags': tag_name},
155 error_class=PlainErrorList)
155 error_class=PlainErrorList)
156
156
157 context = _init_default_context(request)
157 context = _init_default_context(request)
158 context['threads'] = None if len(threads) == 0 else threads
158 context['threads'] = None if len(threads) == 0 else threads
159 context['tag'] = tag
159 context['tag'] = tag
160 context['current_page'] = int(page)
160 context['current_page'] = int(page)
161
161
162 page_count = Post.objects.get_thread_page_count(tag=tag)
162 page_count = Post.objects.get_thread_page_count(tag=tag)
163 context['pages'] = range(page_count)
163 context['pages'] = range(page_count)
164 page = int(page)
164 page = int(page)
165 if page < page_count - 1:
165 if page < page_count - 1:
166 context['next_page'] = str(page + 1)
166 context['next_page'] = str(page + 1)
167 if page > 0:
167 if page > 0:
168 context['prev_page'] = str(page - 1)
168 context['prev_page'] = str(page - 1)
169
169
170 context['form'] = form
170 context['form'] = form
171
171
172 return render(request, 'boards/posting_general.html',
172 return render(request, 'boards/posting_general.html',
173 context)
173 context)
174
174
175
175
176 def thread(request, post_id, mode=MODE_NORMAL):
176 def thread(request, post_id, mode=MODE_NORMAL):
177 """Get all thread posts"""
177 """Get all thread posts"""
178
178
179 if utils.need_include_captcha(request):
179 if utils.need_include_captcha(request):
180 postFormClass = PostCaptchaForm
180 postFormClass = PostCaptchaForm
181 kwargs = {'request': request}
181 kwargs = {'request': request}
182 else:
182 else:
183 postFormClass = PostForm
183 postFormClass = PostForm
184 kwargs = {}
184 kwargs = {}
185
185
186 opening_post = get_object_or_404(Post, id=post_id)
186 if request.method == 'POST':
187 if request.method == 'POST':
187 form = postFormClass(request.POST, request.FILES,
188 form = postFormClass(request.POST, request.FILES,
188 error_class=PlainErrorList, **kwargs)
189 error_class=PlainErrorList, **kwargs)
189 form.session = request.session
190 form.session = request.session
190
191
191 opening_post = get_object_or_404(Post, id=post_id)
192 if form.is_valid():
192 if form.is_valid():
193 return _new_post(request, form, opening_post)
193 return _new_post(request, form, opening_post)
194 if form.need_to_ban:
194 if form.need_to_ban:
195 # Ban user because he is suspected to be a bot
195 # Ban user because he is suspected to be a bot
196 _ban_current_user(request)
196 _ban_current_user(request)
197 else:
197 else:
198 form = postFormClass(error_class=PlainErrorList, **kwargs)
198 form = postFormClass(error_class=PlainErrorList, **kwargs)
199
199
200 thread_to_show = get_object_or_404(Post, id=post_id).thread_new
200 thread_to_show = opening_post.thread_new
201
201
202 context = _init_default_context(request)
202 context = _init_default_context(request)
203
203
204 posts = thread_to_show.get_replies()
204 posts = thread_to_show.get_replies()
205 context['form'] = form
205 context['form'] = form
206 context["last_update"] = _datetime_to_epoch(thread_to_show.last_edit_time)
206 context["last_update"] = _datetime_to_epoch(thread_to_show.last_edit_time)
207 context["thread"] = thread_to_show
207 context["thread"] = thread_to_show
208
208
209 if MODE_NORMAL == mode:
209 if MODE_NORMAL == mode:
210 context['bumpable'] = thread_to_show.can_bump()
210 context['bumpable'] = thread_to_show.can_bump()
211 if context['bumpable']:
211 if context['bumpable']:
212 context['posts_left'] = neboard.settings.MAX_POSTS_PER_THREAD - posts \
212 context['posts_left'] = neboard.settings.MAX_POSTS_PER_THREAD - posts \
213 .count()
213 .count()
214 context['bumplimit_progress'] = str(
214 context['bumplimit_progress'] = str(
215 float(context['posts_left']) /
215 float(context['posts_left']) /
216 neboard.settings.MAX_POSTS_PER_THREAD * 100)
216 neboard.settings.MAX_POSTS_PER_THREAD * 100)
217
217
218 context['posts'] = posts
218 context['posts'] = posts
219
219
220 document = 'boards/thread.html'
220 document = 'boards/thread.html'
221 elif MODE_GALLERY == mode:
221 elif MODE_GALLERY == mode:
222 context['posts'] = posts.filter(image_width__gt=0)
222 context['posts'] = posts.filter(image_width__gt=0)
223
223
224 document = 'boards/thread_gallery.html'
224 document = 'boards/thread_gallery.html'
225 else:
225 else:
226 raise Http404
226 raise Http404
227
227
228 return render(request, document, context)
228 return render(request, document, context)
229
229
230
230
231 def login(request):
231 def login(request):
232 """Log in with user id"""
232 """Log in with user id"""
233
233
234 context = _init_default_context(request)
234 context = _init_default_context(request)
235
235
236 if request.method == 'POST':
236 if request.method == 'POST':
237 form = LoginForm(request.POST, request.FILES,
237 form = LoginForm(request.POST, request.FILES,
238 error_class=PlainErrorList)
238 error_class=PlainErrorList)
239 form.session = request.session
239 form.session = request.session
240
240
241 if form.is_valid():
241 if form.is_valid():
242 user = User.objects.get(user_id=form.cleaned_data['user_id'])
242 user = User.objects.get(user_id=form.cleaned_data['user_id'])
243 request.session['user_id'] = user.id
243 request.session['user_id'] = user.id
244 return redirect(index)
244 return redirect(index)
245
245
246 else:
246 else:
247 form = LoginForm()
247 form = LoginForm()
248
248
249 context['form'] = form
249 context['form'] = form
250
250
251 return render(request, 'boards/login.html', context)
251 return render(request, 'boards/login.html', context)
252
252
253
253
254 def settings(request):
254 def settings(request):
255 """User's settings"""
255 """User's settings"""
256
256
257 context = _init_default_context(request)
257 context = _init_default_context(request)
258 user = _get_user(request)
258 user = _get_user(request)
259 is_moderator = user.is_moderator()
259 is_moderator = user.is_moderator()
260
260
261 if request.method == 'POST':
261 if request.method == 'POST':
262 with transaction.atomic():
262 with transaction.atomic():
263 if is_moderator:
263 if is_moderator:
264 form = ModeratorSettingsForm(request.POST,
264 form = ModeratorSettingsForm(request.POST,
265 error_class=PlainErrorList)
265 error_class=PlainErrorList)
266 else:
266 else:
267 form = SettingsForm(request.POST, error_class=PlainErrorList)
267 form = SettingsForm(request.POST, error_class=PlainErrorList)
268
268
269 if form.is_valid():
269 if form.is_valid():
270 selected_theme = form.cleaned_data['theme']
270 selected_theme = form.cleaned_data['theme']
271
271
272 user.save_setting('theme', selected_theme)
272 user.save_setting('theme', selected_theme)
273
273
274 if is_moderator:
274 if is_moderator:
275 moderate = form.cleaned_data['moderate']
275 moderate = form.cleaned_data['moderate']
276 user.save_setting(SETTING_MODERATE, moderate)
276 user.save_setting(SETTING_MODERATE, moderate)
277
277
278 return redirect(settings)
278 return redirect(settings)
279 else:
279 else:
280 selected_theme = _get_theme(request)
280 selected_theme = _get_theme(request)
281
281
282 if is_moderator:
282 if is_moderator:
283 form = ModeratorSettingsForm(initial={'theme': selected_theme,
283 form = ModeratorSettingsForm(initial={'theme': selected_theme,
284 'moderate': context['moderator']},
284 'moderate': context['moderator']},
285 error_class=PlainErrorList)
285 error_class=PlainErrorList)
286 else:
286 else:
287 form = SettingsForm(initial={'theme': selected_theme},
287 form = SettingsForm(initial={'theme': selected_theme},
288 error_class=PlainErrorList)
288 error_class=PlainErrorList)
289
289
290 context['form'] = form
290 context['form'] = form
291
291
292 return render(request, 'boards/settings.html', context)
292 return render(request, 'boards/settings.html', context)
293
293
294
294
295 def all_tags(request):
295 def all_tags(request):
296 """All tags list"""
296 """All tags list"""
297
297
298 context = _init_default_context(request)
298 context = _init_default_context(request)
299 context['all_tags'] = Tag.objects.get_not_empty_tags()
299 context['all_tags'] = Tag.objects.get_not_empty_tags()
300
300
301 return render(request, 'boards/tags.html', context)
301 return render(request, 'boards/tags.html', context)
302
302
303
303
304 def jump_to_post(request, post_id):
304 def jump_to_post(request, post_id):
305 """Determine thread in which the requested post is and open it's page"""
305 """Determine thread in which the requested post is and open it's page"""
306
306
307 post = get_object_or_404(Post, id=post_id)
307 post = get_object_or_404(Post, id=post_id)
308
308
309 if not post.thread:
309 if not post.thread:
310 return redirect(thread, post_id=post.id)
310 return redirect(thread, post_id=post.id)
311 else:
311 else:
312 return redirect(reverse(thread, kwargs={'post_id': post.thread.id})
312 return redirect(reverse(thread, kwargs={'post_id': post.thread.id})
313 + '#' + str(post.id))
313 + '#' + str(post.id))
314
314
315
315
316 def authors(request):
316 def authors(request):
317 """Show authors list"""
317 """Show authors list"""
318
318
319 context = _init_default_context(request)
319 context = _init_default_context(request)
320 context['authors'] = boards.authors.authors
320 context['authors'] = boards.authors.authors
321
321
322 return render(request, 'boards/authors.html', context)
322 return render(request, 'boards/authors.html', context)
323
323
324
324
325 @transaction.atomic
325 @transaction.atomic
326 def delete(request, post_id):
326 def delete(request, post_id):
327 """Delete post"""
327 """Delete post"""
328
328
329 user = _get_user(request)
329 user = _get_user(request)
330 post = get_object_or_404(Post, id=post_id)
330 post = get_object_or_404(Post, id=post_id)
331
331
332 if user.is_moderator():
332 if user.is_moderator():
333 # TODO Show confirmation page before deletion
333 # TODO Show confirmation page before deletion
334 Post.objects.delete_post(post)
334 Post.objects.delete_post(post)
335
335
336 if not post.thread:
336 if not post.thread:
337 return _redirect_to_next(request)
337 return _redirect_to_next(request)
338 else:
338 else:
339 return redirect(thread, post_id=post.thread.id)
339 return redirect(thread, post_id=post.thread.id)
340
340
341
341
342 @transaction.atomic
342 @transaction.atomic
343 def ban(request, post_id):
343 def ban(request, post_id):
344 """Ban user"""
344 """Ban user"""
345
345
346 user = _get_user(request)
346 user = _get_user(request)
347 post = get_object_or_404(Post, id=post_id)
347 post = get_object_or_404(Post, id=post_id)
348
348
349 if user.is_moderator():
349 if user.is_moderator():
350 # TODO Show confirmation page before ban
350 # TODO Show confirmation page before ban
351 ban, created = Ban.objects.get_or_create(ip=post.poster_ip)
351 ban, created = Ban.objects.get_or_create(ip=post.poster_ip)
352 if created:
352 if created:
353 ban.reason = 'Banned for post ' + str(post_id)
353 ban.reason = 'Banned for post ' + str(post_id)
354 ban.save()
354 ban.save()
355
355
356 return _redirect_to_next(request)
356 return _redirect_to_next(request)
357
357
358
358
359 def you_are_banned(request):
359 def you_are_banned(request):
360 """Show the page that notifies that user is banned"""
360 """Show the page that notifies that user is banned"""
361
361
362 context = _init_default_context(request)
362 context = _init_default_context(request)
363
363
364 ban = get_object_or_404(Ban, ip=utils.get_client_ip(request))
364 ban = get_object_or_404(Ban, ip=utils.get_client_ip(request))
365 context['ban_reason'] = ban.reason
365 context['ban_reason'] = ban.reason
366 return render(request, 'boards/staticpages/banned.html', context)
366 return render(request, 'boards/staticpages/banned.html', context)
367
367
368
368
369 def page_404(request):
369 def page_404(request):
370 """Show page 404 (not found error)"""
370 """Show page 404 (not found error)"""
371
371
372 context = _init_default_context(request)
372 context = _init_default_context(request)
373 return render(request, 'boards/404.html', context)
373 return render(request, 'boards/404.html', context)
374
374
375
375
376 @transaction.atomic
376 @transaction.atomic
377 def tag_subscribe(request, tag_name):
377 def tag_subscribe(request, tag_name):
378 """Add tag to favorites"""
378 """Add tag to favorites"""
379
379
380 user = _get_user(request)
380 user = _get_user(request)
381 tag = get_object_or_404(Tag, name=tag_name)
381 tag = get_object_or_404(Tag, name=tag_name)
382
382
383 if not tag in user.fav_tags.all():
383 if not tag in user.fav_tags.all():
384 user.add_tag(tag)
384 user.add_tag(tag)
385
385
386 return _redirect_to_next(request)
386 return _redirect_to_next(request)
387
387
388
388
389 @transaction.atomic
389 @transaction.atomic
390 def tag_unsubscribe(request, tag_name):
390 def tag_unsubscribe(request, tag_name):
391 """Remove tag from favorites"""
391 """Remove tag from favorites"""
392
392
393 user = _get_user(request)
393 user = _get_user(request)
394 tag = get_object_or_404(Tag, name=tag_name)
394 tag = get_object_or_404(Tag, name=tag_name)
395
395
396 if tag in user.fav_tags.all():
396 if tag in user.fav_tags.all():
397 user.remove_tag(tag)
397 user.remove_tag(tag)
398
398
399 return _redirect_to_next(request)
399 return _redirect_to_next(request)
400
400
401
401
402 def static_page(request, name):
402 def static_page(request, name):
403 """Show a static page that needs only tags list and a CSS"""
403 """Show a static page that needs only tags list and a CSS"""
404
404
405 context = _init_default_context(request)
405 context = _init_default_context(request)
406 return render(request, 'boards/staticpages/' + name + '.html', context)
406 return render(request, 'boards/staticpages/' + name + '.html', context)
407
407
408
408
409 def api_get_post(request, post_id):
409 def api_get_post(request, post_id):
410 """
410 """
411 Get the JSON of a post. This can be
411 Get the JSON of a post. This can be
412 used as and API for external clients.
412 used as and API for external clients.
413 """
413 """
414
414
415 post = get_object_or_404(Post, id=post_id)
415 post = get_object_or_404(Post, id=post_id)
416
416
417 json = serializers.serialize("json", [post], fields=(
417 json = serializers.serialize("json", [post], fields=(
418 "pub_time", "_text_rendered", "title", "text", "image",
418 "pub_time", "_text_rendered", "title", "text", "image",
419 "image_width", "image_height", "replies", "tags"
419 "image_width", "image_height", "replies", "tags"
420 ))
420 ))
421
421
422 return HttpResponse(content=json)
422 return HttpResponse(content=json)
423
423
424
424
425 def get_post(request, post_id):
425 def get_post(request, post_id):
426 """Get the html of a post. Used for popups."""
426 """Get the html of a post. Used for popups."""
427
427
428 post = get_object_or_404(Post, id=post_id)
428 post = get_object_or_404(Post, id=post_id)
429 thread = post.thread_new
429 thread = post.thread_new
430
430
431 context = RequestContext(request)
431 context = RequestContext(request)
432 context["post"] = post
432 context["post"] = post
433 context["can_bump"] = thread.can_bump()
433 context["can_bump"] = thread.can_bump()
434 if "truncated" in request.GET:
434 if "truncated" in request.GET:
435 context["truncated"] = True
435 context["truncated"] = True
436
436
437 return render(request, 'boards/post.html', context)
437 return render(request, 'boards/post.html', context)
438
438
439 @cache_page(86400)
439 @cache_page(86400)
440 def cached_js_catalog(request, domain='djangojs', packages=None):
440 def cached_js_catalog(request, domain='djangojs', packages=None):
441 return javascript_catalog(request, domain, packages)
441 return javascript_catalog(request, domain, packages)
442
442
443
443
444 def _get_theme(request, user=None):
444 def _get_theme(request, user=None):
445 """Get user's CSS theme"""
445 """Get user's CSS theme"""
446
446
447 if not user:
447 if not user:
448 user = _get_user(request)
448 user = _get_user(request)
449 theme = user.get_setting('theme')
449 theme = user.get_setting('theme')
450 if not theme:
450 if not theme:
451 theme = neboard.settings.DEFAULT_THEME
451 theme = neboard.settings.DEFAULT_THEME
452
452
453 return theme
453 return theme
454
454
455
455
456 def _init_default_context(request):
456 def _init_default_context(request):
457 """Create context with default values that are used in most views"""
457 """Create context with default values that are used in most views"""
458
458
459 context = RequestContext(request)
459 context = RequestContext(request)
460
460
461 user = _get_user(request)
461 user = _get_user(request)
462 context['user'] = user
462 context['user'] = user
463 context['tags'] = user.get_sorted_fav_tags()
463 context['tags'] = user.get_sorted_fav_tags()
464 context['posts_per_day'] = float(Post.objects.get_posts_per_day())
464 context['posts_per_day'] = float(Post.objects.get_posts_per_day())
465
465
466 theme = _get_theme(request, user)
466 theme = _get_theme(request, user)
467 context['theme'] = theme
467 context['theme'] = theme
468 context['theme_css'] = 'css/' + theme + '/base_page.css'
468 context['theme_css'] = 'css/' + theme + '/base_page.css'
469
469
470 # This shows the moderator panel
470 # This shows the moderator panel
471 moderate = user.get_setting(SETTING_MODERATE)
471 moderate = user.get_setting(SETTING_MODERATE)
472 if moderate == 'True':
472 if moderate == 'True':
473 context['moderator'] = user.is_moderator()
473 context['moderator'] = user.is_moderator()
474 else:
474 else:
475 context['moderator'] = False
475 context['moderator'] = False
476
476
477 return context
477 return context
478
478
479
479
480 def _get_user(request):
480 def _get_user(request):
481 """
481 """
482 Get current user from the session. If the user does not exist, create
482 Get current user from the session. If the user does not exist, create
483 a new one.
483 a new one.
484 """
484 """
485
485
486 session = request.session
486 session = request.session
487 if not 'user_id' in session:
487 if not 'user_id' in session:
488 request.session.save()
488 request.session.save()
489
489
490 md5 = hashlib.md5()
490 md5 = hashlib.md5()
491 md5.update(session.session_key)
491 md5.update(session.session_key)
492 new_id = md5.hexdigest()
492 new_id = md5.hexdigest()
493
493
494 time_now = timezone.now()
494 time_now = timezone.now()
495 user = User.objects.create(user_id=new_id, rank=RANK_USER,
495 user = User.objects.create(user_id=new_id, rank=RANK_USER,
496 registration_time=time_now)
496 registration_time=time_now)
497
497
498 session['user_id'] = user.id
498 session['user_id'] = user.id
499 else:
499 else:
500 user = User.objects.get(id=session['user_id'])
500 user = User.objects.get(id=session['user_id'])
501
501
502 return user
502 return user
503
503
504
504
505 def _redirect_to_next(request):
505 def _redirect_to_next(request):
506 """
506 """
507 If a 'next' parameter was specified, redirect to the next page. This is
507 If a 'next' parameter was specified, redirect to the next page. This is
508 used when the user is required to return to some page after the current
508 used when the user is required to return to some page after the current
509 view has finished its work.
509 view has finished its work.
510 """
510 """
511
511
512 if 'next' in request.GET:
512 if 'next' in request.GET:
513 next_page = request.GET['next']
513 next_page = request.GET['next']
514 return HttpResponseRedirect(next_page)
514 return HttpResponseRedirect(next_page)
515 else:
515 else:
516 return redirect(index)
516 return redirect(index)
517
517
518
518
519 @transaction.atomic
519 @transaction.atomic
520 def _ban_current_user(request):
520 def _ban_current_user(request):
521 """Add current user to the IP ban list"""
521 """Add current user to the IP ban list"""
522
522
523 ip = utils.get_client_ip(request)
523 ip = utils.get_client_ip(request)
524 ban, created = Ban.objects.get_or_create(ip=ip)
524 ban, created = Ban.objects.get_or_create(ip=ip)
525 if created:
525 if created:
526 ban.can_read = False
526 ban.can_read = False
527 ban.reason = BAN_REASON_SPAM
527 ban.reason = BAN_REASON_SPAM
528 ban.save()
528 ban.save()
529
529
530
530
531 def _remove_invalid_links(text):
531 def _remove_invalid_links(text):
532 """
532 """
533 Replace invalid links in posts so that they won't be parsed.
533 Replace invalid links in posts so that they won't be parsed.
534 Invalid links are links to non-existent posts
534 Invalid links are links to non-existent posts
535 """
535 """
536
536
537 for reply_number in re.finditer(REGEX_REPLY, text):
537 for reply_number in re.finditer(REGEX_REPLY, text):
538 post_id = reply_number.group(1)
538 post_id = reply_number.group(1)
539 post = Post.objects.filter(id=post_id)
539 post = Post.objects.filter(id=post_id)
540 if not post.exists():
540 if not post.exists():
541 text = string.replace(text, '>>' + post_id, post_id)
541 text = string.replace(text, '>>' + post_id, post_id)
542
542
543 return text
543 return text
544
544
545
545
546 def _datetime_to_epoch(datetime):
546 def _datetime_to_epoch(datetime):
547 return int(time.mktime(timezone.localtime(
547 return int(time.mktime(timezone.localtime(
548 datetime,timezone.get_current_timezone()).timetuple())
548 datetime,timezone.get_current_timezone()).timetuple())
549 * 1000000 + datetime.microsecond)
549 * 1000000 + datetime.microsecond)
550
550
551
551
552 def _get_template_thread(thread_to_show):
552 def _get_template_thread(thread_to_show):
553 """Get template values for thread"""
553 """Get template values for thread"""
554
554
555 last_replies = thread_to_show.get_last_replies()
555 last_replies = thread_to_show.get_last_replies()
556 skipped_replies_count = thread_to_show.get_replies().count() \
556 skipped_replies_count = thread_to_show.get_replies().count() \
557 - len(last_replies) - 1
557 - len(last_replies) - 1
558 return {
558 return {
559 'thread': thread_to_show,
559 'thread': thread_to_show,
560 'op': thread_to_show.get_replies()[0],
560 'op': thread_to_show.get_replies()[0],
561 'bumpable': thread_to_show.can_bump(),
561 'bumpable': thread_to_show.can_bump(),
562 'last_replies': last_replies,
562 'last_replies': last_replies,
563 'skipped_replies': skipped_replies_count,
563 'skipped_replies': skipped_replies_count,
564 }
564 }
@@ -1,241 +1,247 b''
1 # Django settings for neboard project.
1 # Django settings for neboard project.
2 import os
2 import os
3 from boards.mdx_neboard import markdown_extended
3 from boards.mdx_neboard import markdown_extended
4
4
5 DEBUG = True
5 DEBUG = True
6 TEMPLATE_DEBUG = DEBUG
6 TEMPLATE_DEBUG = DEBUG
7
7
8 ADMINS = (
8 ADMINS = (
9 # ('Your Name', 'your_email@example.com'),
9 # ('Your Name', 'your_email@example.com'),
10 ('admin', 'admin@example.com')
10 ('admin', 'admin@example.com')
11 )
11 )
12
12
13 MANAGERS = ADMINS
13 MANAGERS = ADMINS
14
14
15 DATABASES = {
15 DATABASES = {
16 'default': {
16 'default': {
17 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
17 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
18 'NAME': 'database.db', # Or path to database file if using sqlite3.
18 'NAME': 'database.db', # Or path to database file if using sqlite3.
19 'USER': '', # Not used with sqlite3.
19 'USER': '', # Not used with sqlite3.
20 'PASSWORD': '', # Not used with sqlite3.
20 'PASSWORD': '', # Not used with sqlite3.
21 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
21 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
22 'PORT': '', # Set to empty string for default. Not used with sqlite3.
22 'PORT': '', # Set to empty string for default. Not used with sqlite3.
23 'CONN_MAX_AGE': None,
23 'CONN_MAX_AGE': None,
24 }
24 }
25 }
25 }
26
26
27 # Local time zone for this installation. Choices can be found here:
27 # Local time zone for this installation. Choices can be found here:
28 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
28 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
29 # although not all choices may be available on all operating systems.
29 # although not all choices may be available on all operating systems.
30 # In a Windows environment this must be set to your system time zone.
30 # In a Windows environment this must be set to your system time zone.
31 TIME_ZONE = 'Europe/Kiev'
31 TIME_ZONE = 'Europe/Kiev'
32
32
33 # Language code for this installation. All choices can be found here:
33 # Language code for this installation. All choices can be found here:
34 # http://www.i18nguy.com/unicode/language-identifiers.html
34 # http://www.i18nguy.com/unicode/language-identifiers.html
35 LANGUAGE_CODE = 'en'
35 LANGUAGE_CODE = 'en'
36
36
37 SITE_ID = 1
37 SITE_ID = 1
38
38
39 # If you set this to False, Django will make some optimizations so as not
39 # If you set this to False, Django will make some optimizations so as not
40 # to load the internationalization machinery.
40 # to load the internationalization machinery.
41 USE_I18N = True
41 USE_I18N = True
42
42
43 # If you set this to False, Django will not format dates, numbers and
43 # If you set this to False, Django will not format dates, numbers and
44 # calendars according to the current locale.
44 # calendars according to the current locale.
45 USE_L10N = True
45 USE_L10N = True
46
46
47 # If you set this to False, Django will not use timezone-aware datetimes.
47 # If you set this to False, Django will not use timezone-aware datetimes.
48 USE_TZ = True
48 USE_TZ = True
49
49
50 # Absolute filesystem path to the directory that will hold user-uploaded files.
50 # Absolute filesystem path to the directory that will hold user-uploaded files.
51 # Example: "/home/media/media.lawrence.com/media/"
51 # Example: "/home/media/media.lawrence.com/media/"
52 MEDIA_ROOT = './media/'
52 MEDIA_ROOT = './media/'
53
53
54 # URL that handles the media served from MEDIA_ROOT. Make sure to use a
54 # URL that handles the media served from MEDIA_ROOT. Make sure to use a
55 # trailing slash.
55 # trailing slash.
56 # Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
56 # Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
57 MEDIA_URL = '/media/'
57 MEDIA_URL = '/media/'
58
58
59 # Absolute path to the directory static files should be collected to.
59 # Absolute path to the directory static files should be collected to.
60 # Don't put anything in this directory yourself; store your static files
60 # Don't put anything in this directory yourself; store your static files
61 # in apps' "static/" subdirectories and in STATICFILES_DIRS.
61 # in apps' "static/" subdirectories and in STATICFILES_DIRS.
62 # Example: "/home/media/media.lawrence.com/static/"
62 # Example: "/home/media/media.lawrence.com/static/"
63 STATIC_ROOT = ''
63 STATIC_ROOT = ''
64
64
65 # URL prefix for static files.
65 # URL prefix for static files.
66 # Example: "http://media.lawrence.com/static/"
66 # Example: "http://media.lawrence.com/static/"
67 STATIC_URL = '/static/'
67 STATIC_URL = '/static/'
68
68
69 # Additional locations of static files
69 # Additional locations of static files
70 # It is really a hack, put real paths, not related
70 # It is really a hack, put real paths, not related
71 STATICFILES_DIRS = (
71 STATICFILES_DIRS = (
72 os.path.dirname(__file__) + '/boards/static',
72 os.path.dirname(__file__) + '/boards/static',
73
73
74 # '/d/work/python/django/neboard/neboard/boards/static',
74 # '/d/work/python/django/neboard/neboard/boards/static',
75 # Put strings here, like "/home/html/static" or "C:/www/django/static".
75 # Put strings here, like "/home/html/static" or "C:/www/django/static".
76 # Always use forward slashes, even on Windows.
76 # Always use forward slashes, even on Windows.
77 # Don't forget to use absolute paths, not relative paths.
77 # Don't forget to use absolute paths, not relative paths.
78 )
78 )
79
79
80 # List of finder classes that know how to find static files in
80 # List of finder classes that know how to find static files in
81 # various locations.
81 # various locations.
82 STATICFILES_FINDERS = (
82 STATICFILES_FINDERS = (
83 'django.contrib.staticfiles.finders.FileSystemFinder',
83 'django.contrib.staticfiles.finders.FileSystemFinder',
84 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
84 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
85 )
85 )
86
86
87 if DEBUG:
87 if DEBUG:
88 STATICFILES_STORAGE = \
88 STATICFILES_STORAGE = \
89 'django.contrib.staticfiles.storage.StaticFilesStorage'
89 'django.contrib.staticfiles.storage.StaticFilesStorage'
90 else:
90 else:
91 STATICFILES_STORAGE = \
91 STATICFILES_STORAGE = \
92 'django.contrib.staticfiles.storage.CachedStaticFilesStorage'
92 'django.contrib.staticfiles.storage.CachedStaticFilesStorage'
93
93
94 # Make this unique, and don't share it with anybody.
94 # Make this unique, and don't share it with anybody.
95 SECRET_KEY = '@1rc$o(7=tt#kd+4s$u6wchm**z^)4x90)7f6z(i&amp;55@o11*8o'
95 SECRET_KEY = '@1rc$o(7=tt#kd+4s$u6wchm**z^)4x90)7f6z(i&amp;55@o11*8o'
96
96
97 # List of callables that know how to import templates from various sources.
97 # List of callables that know how to import templates from various sources.
98 TEMPLATE_LOADERS = (
98 TEMPLATE_LOADERS = (
99 'django.template.loaders.filesystem.Loader',
99 'django.template.loaders.filesystem.Loader',
100 'django.template.loaders.app_directories.Loader',
100 'django.template.loaders.app_directories.Loader',
101 )
101 )
102
102
103 TEMPLATE_CONTEXT_PROCESSORS = (
103 TEMPLATE_CONTEXT_PROCESSORS = (
104 'django.core.context_processors.media',
104 'django.core.context_processors.media',
105 'django.core.context_processors.static',
105 'django.core.context_processors.static',
106 'django.core.context_processors.request',
106 'django.core.context_processors.request',
107 'django.contrib.auth.context_processors.auth',
107 'django.contrib.auth.context_processors.auth',
108 )
108 )
109
109
110 MIDDLEWARE_CLASSES = (
110 MIDDLEWARE_CLASSES = (
111 'django.contrib.sessions.middleware.SessionMiddleware',
111 'django.contrib.sessions.middleware.SessionMiddleware',
112 'django.middleware.locale.LocaleMiddleware',
112 'django.middleware.locale.LocaleMiddleware',
113 'django.middleware.common.CommonMiddleware',
113 'django.middleware.common.CommonMiddleware',
114 'django.contrib.auth.middleware.AuthenticationMiddleware',
114 'django.contrib.auth.middleware.AuthenticationMiddleware',
115 'django.contrib.messages.middleware.MessageMiddleware',
115 'django.contrib.messages.middleware.MessageMiddleware',
116 'boards.middlewares.BanMiddleware',
116 'boards.middlewares.BanMiddleware',
117 'boards.middlewares.MinifyHTMLMiddleware',
117 'boards.middlewares.MinifyHTMLMiddleware',
118 )
118 )
119
119
120 ROOT_URLCONF = 'neboard.urls'
120 ROOT_URLCONF = 'neboard.urls'
121
121
122 # Python dotted path to the WSGI application used by Django's runserver.
122 # Python dotted path to the WSGI application used by Django's runserver.
123 WSGI_APPLICATION = 'neboard.wsgi.application'
123 WSGI_APPLICATION = 'neboard.wsgi.application'
124
124
125 TEMPLATE_DIRS = (
125 TEMPLATE_DIRS = (
126 # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
126 # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
127 # Always use forward slashes, even on Windows.
127 # Always use forward slashes, even on Windows.
128 # Don't forget to use absolute paths, not relative paths.
128 # Don't forget to use absolute paths, not relative paths.
129 'templates',
129 'templates',
130 )
130 )
131
131
132 INSTALLED_APPS = (
132 INSTALLED_APPS = (
133 'django.contrib.auth',
133 'django.contrib.auth',
134 'django.contrib.contenttypes',
134 'django.contrib.contenttypes',
135 'django.contrib.sessions',
135 'django.contrib.sessions',
136 # 'django.contrib.sites',
136 # 'django.contrib.sites',
137 'django.contrib.messages',
137 'django.contrib.messages',
138 'django.contrib.staticfiles',
138 'django.contrib.staticfiles',
139 # Uncomment the next line to enable the admin:
139 # Uncomment the next line to enable the admin:
140 'django.contrib.admin',
140 'django.contrib.admin',
141 # Uncomment the next line to enable admin documentation:
141 # Uncomment the next line to enable admin documentation:
142 # 'django.contrib.admindocs',
142 # 'django.contrib.admindocs',
143 'django.contrib.humanize',
143 'django.contrib.humanize',
144 'django_cleanup',
144 'django_cleanup',
145 'boards',
145 'boards',
146 'captcha',
146 'captcha',
147 'south',
147 'south',
148 'debug_toolbar',
148 'debug_toolbar',
149 )
149 )
150
150
151 DEBUG_TOOLBAR_PANELS = (
151 DEBUG_TOOLBAR_PANELS = (
152 'debug_toolbar.panels.version.VersionDebugPanel',
152 'debug_toolbar.panels.version.VersionDebugPanel',
153 'debug_toolbar.panels.timer.TimerDebugPanel',
153 'debug_toolbar.panels.timer.TimerDebugPanel',
154 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
154 'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
155 'debug_toolbar.panels.headers.HeaderDebugPanel',
155 'debug_toolbar.panels.headers.HeaderDebugPanel',
156 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
156 'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
157 'debug_toolbar.panels.template.TemplateDebugPanel',
157 'debug_toolbar.panels.template.TemplateDebugPanel',
158 'debug_toolbar.panels.sql.SQLDebugPanel',
158 'debug_toolbar.panels.sql.SQLDebugPanel',
159 'debug_toolbar.panels.signals.SignalDebugPanel',
159 'debug_toolbar.panels.signals.SignalDebugPanel',
160 'debug_toolbar.panels.logger.LoggingPanel',
160 'debug_toolbar.panels.logger.LoggingPanel',
161 )
161 )
162
162
163 # TODO: NEED DESIGN FIXES
163 # TODO: NEED DESIGN FIXES
164 CAPTCHA_OUTPUT_FORMAT = (u' %(hidden_field)s '
164 CAPTCHA_OUTPUT_FORMAT = (u' %(hidden_field)s '
165 u'<div class="form-label">%(image)s</div>'
165 u'<div class="form-label">%(image)s</div>'
166 u'<div class="form-text">%(text_field)s</div>')
166 u'<div class="form-text">%(text_field)s</div>')
167
167
168 # A sample logging configuration. The only tangible logging
168 # A sample logging configuration. The only tangible logging
169 # performed by this configuration is to send an email to
169 # performed by this configuration is to send an email to
170 # the site admins on every HTTP 500 error when DEBUG=False.
170 # the site admins on every HTTP 500 error when DEBUG=False.
171 # See http://docs.djangoproject.com/en/dev/topics/logging for
171 # See http://docs.djangoproject.com/en/dev/topics/logging for
172 # more details on how to customize your logging configuration.
172 # more details on how to customize your logging configuration.
173 LOGGING = {
173 LOGGING = {
174 'version': 1,
174 'version': 1,
175 'disable_existing_loggers': False,
175 'disable_existing_loggers': False,
176 'filters': {
176 'filters': {
177 'require_debug_false': {
177 'require_debug_false': {
178 '()': 'django.utils.log.RequireDebugFalse'
178 '()': 'django.utils.log.RequireDebugFalse'
179 }
179 }
180 },
180 },
181 'handlers': {
181 'handlers': {
182 'mail_admins': {
182 'mail_admins': {
183 'level': 'ERROR',
183 'level': 'ERROR',
184 'filters': ['require_debug_false'],
184 'filters': ['require_debug_false'],
185 'class': 'django.utils.log.AdminEmailHandler'
185 'class': 'django.utils.log.AdminEmailHandler'
186 }
186 }
187 },
187 },
188 'loggers': {
188 'loggers': {
189 'django.request': {
189 'django.request': {
190 'handlers': ['mail_admins'],
190 'handlers': ['mail_admins'],
191 'level': 'ERROR',
191 'level': 'ERROR',
192 'propagate': True,
192 'propagate': True,
193 },
193 },
194 }
194 }
195 }
195 }
196
196
197 MARKUP_FIELD_TYPES = (
197 MARKUP_FIELD_TYPES = (
198 ('markdown', markdown_extended),
198 ('markdown', markdown_extended),
199 )
199 )
200 # Custom imageboard settings
200 # Custom imageboard settings
201 # TODO These should me moved to
201 # TODO These should me moved to
202 MAX_POSTS_PER_THREAD = 10 # Thread bumplimit
202 MAX_POSTS_PER_THREAD = 10 # Thread bumplimit
203 MAX_THREAD_COUNT = 500 # Old threads will be deleted to preserve this count
203 MAX_THREAD_COUNT = 500 # Old threads will be deleted to preserve this count
204 THREADS_PER_PAGE = 3
204 THREADS_PER_PAGE = 3
205 SITE_NAME = 'Neboard'
205 SITE_NAME = 'Neboard'
206
206
207 THEMES = [
207 THEMES = [
208 ('md', 'Mystic Dark'),
208 ('md', 'Mystic Dark'),
209 ('md_centered', 'Mystic Dark (centered)'),
209 ('md_centered', 'Mystic Dark (centered)'),
210 ('sw', 'Snow White'),
210 ('sw', 'Snow White'),
211 ('pg', 'Photon Gray'),
211 ('pg', 'Photon Gray'),
212 ]
212 ]
213
213
214 DEFAULT_THEME = 'md'
214 DEFAULT_THEME = 'md'
215
215
216 POPULAR_TAGS = 10
216 POPULAR_TAGS = 10
217 LAST_REPLIES_COUNT = 3
217 LAST_REPLIES_COUNT = 3
218
218
219 ENABLE_CAPTCHA = False
219 ENABLE_CAPTCHA = False
220 # if user tries to post before CAPTCHA_DEFAULT_SAFE_TIME. Captcha will be shown
220 # if user tries to post before CAPTCHA_DEFAULT_SAFE_TIME. Captcha will be shown
221 CAPTCHA_DEFAULT_SAFE_TIME = 30 # seconds
221 CAPTCHA_DEFAULT_SAFE_TIME = 30 # seconds
222 POSTING_DELAY = 20 # seconds
222 POSTING_DELAY = 20 # seconds
223
223
224 COMPRESS_HTML = True
224 COMPRESS_HTML = True
225
225
226 # Debug mode middlewares
227 if DEBUG:
228 MIDDLEWARE_CLASSES += (
229 'boards.profiler.ProfilerMiddleware',
230 'debug_toolbar.middleware.DebugToolbarMiddleware',
231 )
232
226 def custom_show_toolbar(request):
233 def custom_show_toolbar(request):
227 return DEBUG
234 return DEBUG
228
235
229 DEBUG_TOOLBAR_CONFIG = {
236 DEBUG_TOOLBAR_CONFIG = {
230 'INTERCEPT_REDIRECTS': False,
237 'INTERCEPT_REDIRECTS': False,
231 'SHOW_TOOLBAR_CALLBACK': custom_show_toolbar,
238 'SHOW_TOOLBAR_CALLBACK': custom_show_toolbar,
232 'HIDE_DJANGO_SQL': False,
239 'HIDE_DJANGO_SQL': False,
233 'ENABLE_STACKTRACES': True,
240 'ENABLE_STACKTRACES': True,
234 }
241 }
235
242
236 # Debug mode middlewares
243 # FIXME Uncommenting this fails somehow. Need to investigate this
237 if DEBUG:
244 #DEBUG_TOOLBAR_PANELS += (
238 MIDDLEWARE_CLASSES += (
245 # 'debug_toolbar.panels.profiling.ProfilingDebugPanel',
239 'boards.profiler.ProfilerMiddleware',
246 #)
240 'debug_toolbar.middleware.DebugToolbarMiddleware',
247
241 )
General Comments 0
You need to be logged in to leave comments. Login now