##// END OF EJS Templates
Removed deprecated transaction annotations and changed them to atomic
neko259 -
r393:64170e36 default
parent child Browse files
Show More
@@ -1,561 +1,561 b''
1 import hashlib
1 import hashlib
2 import json
2 import json
3 import string
3 import string
4 import time
4 import time
5 from datetime import datetime
5 from datetime import datetime
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
10 from django.http import HttpResponseRedirect
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
16
17 from boards import forms
17 from boards import forms
18 import boards
18 import boards
19 from boards import utils
19 from boards import utils
20 from boards.forms import ThreadForm, PostForm, SettingsForm, PlainErrorList, \
20 from boards.forms import ThreadForm, PostForm, SettingsForm, PlainErrorList, \
21 ThreadCaptchaForm, PostCaptchaForm, LoginForm, ModeratorSettingsForm
21 ThreadCaptchaForm, PostCaptchaForm, LoginForm, ModeratorSettingsForm
22 from boards.models import Post, Tag, Ban, User
22 from boards.models import Post, Tag, Ban, User
23 from boards.models.post import SETTING_MODERATE, REGEX_REPLY
23 from boards.models.post import SETTING_MODERATE, REGEX_REPLY
24 from boards.models.user import RANK_USER
24 from boards.models.user import RANK_USER
25 from boards import authors
25 from boards import authors
26 from boards.utils import get_client_ip
26 from boards.utils import get_client_ip
27 import neboard
27 import neboard
28
28
29
29
30 BAN_REASON_SPAM = 'Autoban: spam bot'
30 BAN_REASON_SPAM = 'Autoban: spam bot'
31
31
32
32
33 def index(request, page=0):
33 def index(request, page=0):
34 context = _init_default_context(request)
34 context = _init_default_context(request)
35
35
36 if utils.need_include_captcha(request):
36 if utils.need_include_captcha(request):
37 threadFormClass = ThreadCaptchaForm
37 threadFormClass = ThreadCaptchaForm
38 kwargs = {'request': request}
38 kwargs = {'request': request}
39 else:
39 else:
40 threadFormClass = ThreadForm
40 threadFormClass = ThreadForm
41 kwargs = {}
41 kwargs = {}
42
42
43 if request.method == 'POST':
43 if request.method == 'POST':
44 form = threadFormClass(request.POST, request.FILES,
44 form = threadFormClass(request.POST, request.FILES,
45 error_class=PlainErrorList, **kwargs)
45 error_class=PlainErrorList, **kwargs)
46 form.session = request.session
46 form.session = request.session
47
47
48 if form.is_valid():
48 if form.is_valid():
49 return _new_post(request, form)
49 return _new_post(request, form)
50 if form.need_to_ban:
50 if form.need_to_ban:
51 # Ban user because he is suspected to be a bot
51 # Ban user because he is suspected to be a bot
52 _ban_current_user(request)
52 _ban_current_user(request)
53 else:
53 else:
54 form = threadFormClass(error_class=PlainErrorList, **kwargs)
54 form = threadFormClass(error_class=PlainErrorList, **kwargs)
55
55
56 threads = []
56 threads = []
57 for thread in Post.objects.get_threads(page=int(page)):
57 for thread in Post.objects.get_threads(page=int(page)):
58 threads.append({
58 threads.append({
59 'thread': thread,
59 'thread': thread,
60 'bumpable': thread.can_bump(),
60 'bumpable': thread.can_bump(),
61 'last_replies': thread.get_last_replies(),
61 'last_replies': thread.get_last_replies(),
62 })
62 })
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
67
68 page_count = Post.objects.get_thread_page_count()
68 page_count = Post.objects.get_thread_page_count()
69 context['pages'] = range(page_count)
69 context['pages'] = range(page_count)
70 page = int(page)
70 page = int(page)
71 if page < page_count - 1:
71 if page < page_count - 1:
72 context['next_page'] = str(page + 1)
72 context['next_page'] = str(page + 1)
73 if page > 0:
73 if page > 0:
74 context['prev_page'] = str(page - 1)
74 context['prev_page'] = str(page - 1)
75
75
76 return render(request, 'boards/posting_general.html',
76 return render(request, 'boards/posting_general.html',
77 context)
77 context)
78
78
79
79
80 @transaction.commit_on_success
80 @transaction.atomic
81 def _new_post(request, form, opening_post=None):
81 def _new_post(request, form, opening_post=None):
82 """Add a new post (in thread or as a reply)."""
82 """Add a new post (in thread or as a reply)."""
83
83
84 ip = get_client_ip(request)
84 ip = get_client_ip(request)
85 is_banned = Ban.objects.filter(ip=ip).exists()
85 is_banned = Ban.objects.filter(ip=ip).exists()
86
86
87 if is_banned:
87 if is_banned:
88 return redirect(you_are_banned)
88 return redirect(you_are_banned)
89
89
90 data = form.cleaned_data
90 data = form.cleaned_data
91
91
92 title = data['title']
92 title = data['title']
93 text = data['text']
93 text = data['text']
94
94
95 text = _remove_invalid_links(text)
95 text = _remove_invalid_links(text)
96
96
97 if 'image' in data.keys():
97 if 'image' in data.keys():
98 image = data['image']
98 image = data['image']
99 else:
99 else:
100 image = None
100 image = None
101
101
102 tags = []
102 tags = []
103
103
104 if not opening_post:
104 if not opening_post:
105 tag_strings = data['tags']
105 tag_strings = data['tags']
106
106
107 if tag_strings:
107 if tag_strings:
108 tag_strings = tag_strings.split(' ')
108 tag_strings = tag_strings.split(' ')
109 for tag_name in tag_strings:
109 for tag_name in tag_strings:
110 tag_name = string.lower(tag_name.strip())
110 tag_name = string.lower(tag_name.strip())
111 if len(tag_name) > 0:
111 if len(tag_name) > 0:
112 tag, created = Tag.objects.get_or_create(name=tag_name)
112 tag, created = Tag.objects.get_or_create(name=tag_name)
113 tags.append(tag)
113 tags.append(tag)
114
114
115 post = Post.objects.create_post(title=title, text=text, ip=ip,
115 post = Post.objects.create_post(title=title, text=text, ip=ip,
116 thread=opening_post, image=image,
116 thread=opening_post, image=image,
117 tags=tags, user=_get_user(request))
117 tags=tags, user=_get_user(request))
118
118
119 thread_to_show = (opening_post.id if opening_post else post.id)
119 thread_to_show = (opening_post.id if opening_post else post.id)
120
120
121 if opening_post:
121 if opening_post:
122 return redirect(reverse(thread, kwargs={'post_id': thread_to_show}) +
122 return redirect(reverse(thread, kwargs={'post_id': thread_to_show}) +
123 '#' + str(post.id))
123 '#' + str(post.id))
124 else:
124 else:
125 return redirect(thread, post_id=thread_to_show)
125 return redirect(thread, post_id=thread_to_show)
126
126
127
127
128 def tag(request, tag_name, page=0):
128 def tag(request, tag_name, page=0):
129 """
129 """
130 Get all tag threads. Threads are split in pages, so some page is
130 Get all tag threads. Threads are split in pages, so some page is
131 requested. Default page is 0.
131 requested. Default page is 0.
132 """
132 """
133
133
134 tag = get_object_or_404(Tag, name=tag_name)
134 tag = get_object_or_404(Tag, name=tag_name)
135 threads = []
135 threads = []
136 for thread in Post.objects.get_threads(tag=tag, page=int(page)):
136 for thread in Post.objects.get_threads(tag=tag, page=int(page)):
137 threads.append({
137 threads.append({
138 'thread': thread,
138 'thread': thread,
139 'bumpable': thread.can_bump(),
139 'bumpable': thread.can_bump(),
140 'last_replies': thread.get_last_replies(),
140 'last_replies': thread.get_last_replies(),
141 })
141 })
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
160
161 page_count = Post.objects.get_thread_page_count(tag=tag)
161 page_count = Post.objects.get_thread_page_count(tag=tag)
162 context['pages'] = range(page_count)
162 context['pages'] = range(page_count)
163 page = int(page)
163 page = int(page)
164 if page < page_count - 1:
164 if page < page_count - 1:
165 context['next_page'] = str(page + 1)
165 context['next_page'] = str(page + 1)
166 if page > 0:
166 if page > 0:
167 context['prev_page'] = str(page - 1)
167 context['prev_page'] = str(page - 1)
168
168
169 context['form'] = form
169 context['form'] = form
170
170
171 return render(request, 'boards/posting_general.html',
171 return render(request, 'boards/posting_general.html',
172 context)
172 context)
173
173
174
174
175 def thread(request, post_id):
175 def thread(request, post_id):
176 """Get all thread posts"""
176 """Get all thread posts"""
177
177
178 if utils.need_include_captcha(request):
178 if utils.need_include_captcha(request):
179 postFormClass = PostCaptchaForm
179 postFormClass = PostCaptchaForm
180 kwargs = {'request': request}
180 kwargs = {'request': request}
181 else:
181 else:
182 postFormClass = PostForm
182 postFormClass = PostForm
183 kwargs = {}
183 kwargs = {}
184
184
185 if request.method == 'POST':
185 if request.method == 'POST':
186 form = postFormClass(request.POST, request.FILES,
186 form = postFormClass(request.POST, request.FILES,
187 error_class=PlainErrorList, **kwargs)
187 error_class=PlainErrorList, **kwargs)
188 form.session = request.session
188 form.session = request.session
189
189
190 opening_post = get_object_or_404(Post, id=post_id)
190 opening_post = get_object_or_404(Post, id=post_id)
191 if form.is_valid():
191 if form.is_valid():
192 return _new_post(request, form, opening_post)
192 return _new_post(request, form, opening_post)
193 if form.need_to_ban:
193 if form.need_to_ban:
194 # Ban user because he is suspected to be a bot
194 # Ban user because he is suspected to be a bot
195 _ban_current_user(request)
195 _ban_current_user(request)
196 else:
196 else:
197 form = postFormClass(error_class=PlainErrorList, **kwargs)
197 form = postFormClass(error_class=PlainErrorList, **kwargs)
198
198
199 posts = Post.objects.get_thread(post_id)
199 posts = Post.objects.get_thread(post_id)
200
200
201 context = _init_default_context(request)
201 context = _init_default_context(request)
202
202
203 context['posts'] = posts
203 context['posts'] = posts
204 context['form'] = form
204 context['form'] = form
205 context['bumpable'] = posts[0].can_bump()
205 context['bumpable'] = posts[0].can_bump()
206 if context['bumpable']:
206 if context['bumpable']:
207 context['posts_left'] = neboard.settings.MAX_POSTS_PER_THREAD - len(
207 context['posts_left'] = neboard.settings.MAX_POSTS_PER_THREAD - len(
208 posts)
208 posts)
209 context['bumplimit_progress'] = str(
209 context['bumplimit_progress'] = str(
210 float(context['posts_left']) /
210 float(context['posts_left']) /
211 neboard.settings.MAX_POSTS_PER_THREAD * 100)
211 neboard.settings.MAX_POSTS_PER_THREAD * 100)
212 context["last_update"] = _datetime_to_epoch(posts[0].last_edit_time)
212 context["last_update"] = _datetime_to_epoch(posts[0].last_edit_time)
213
213
214 return render(request, 'boards/thread.html', context)
214 return render(request, 'boards/thread.html', context)
215
215
216
216
217 def login(request):
217 def login(request):
218 """Log in with user id"""
218 """Log in with user id"""
219
219
220 context = _init_default_context(request)
220 context = _init_default_context(request)
221
221
222 if request.method == 'POST':
222 if request.method == 'POST':
223 form = LoginForm(request.POST, request.FILES,
223 form = LoginForm(request.POST, request.FILES,
224 error_class=PlainErrorList)
224 error_class=PlainErrorList)
225 form.session = request.session
225 form.session = request.session
226
226
227 if form.is_valid():
227 if form.is_valid():
228 user = User.objects.get(user_id=form.cleaned_data['user_id'])
228 user = User.objects.get(user_id=form.cleaned_data['user_id'])
229 request.session['user_id'] = user.id
229 request.session['user_id'] = user.id
230 return redirect(index)
230 return redirect(index)
231
231
232 else:
232 else:
233 form = LoginForm()
233 form = LoginForm()
234
234
235 context['form'] = form
235 context['form'] = form
236
236
237 return render(request, 'boards/login.html', context)
237 return render(request, 'boards/login.html', context)
238
238
239
239
240 def settings(request):
240 def settings(request):
241 """User's settings"""
241 """User's settings"""
242
242
243 context = _init_default_context(request)
243 context = _init_default_context(request)
244 user = _get_user(request)
244 user = _get_user(request)
245 is_moderator = user.is_moderator()
245 is_moderator = user.is_moderator()
246
246
247 if request.method == 'POST':
247 if request.method == 'POST':
248 with transaction.commit_on_success():
248 with transaction.commit_on_success():
249 if is_moderator:
249 if is_moderator:
250 form = ModeratorSettingsForm(request.POST,
250 form = ModeratorSettingsForm(request.POST,
251 error_class=PlainErrorList)
251 error_class=PlainErrorList)
252 else:
252 else:
253 form = SettingsForm(request.POST, error_class=PlainErrorList)
253 form = SettingsForm(request.POST, error_class=PlainErrorList)
254
254
255 if form.is_valid():
255 if form.is_valid():
256 selected_theme = form.cleaned_data['theme']
256 selected_theme = form.cleaned_data['theme']
257
257
258 user.save_setting('theme', selected_theme)
258 user.save_setting('theme', selected_theme)
259
259
260 if is_moderator:
260 if is_moderator:
261 moderate = form.cleaned_data['moderate']
261 moderate = form.cleaned_data['moderate']
262 user.save_setting(SETTING_MODERATE, moderate)
262 user.save_setting(SETTING_MODERATE, moderate)
263
263
264 return redirect(settings)
264 return redirect(settings)
265 else:
265 else:
266 selected_theme = _get_theme(request)
266 selected_theme = _get_theme(request)
267
267
268 if is_moderator:
268 if is_moderator:
269 form = ModeratorSettingsForm(initial={'theme': selected_theme,
269 form = ModeratorSettingsForm(initial={'theme': selected_theme,
270 'moderate': context['moderator']},
270 'moderate': context['moderator']},
271 error_class=PlainErrorList)
271 error_class=PlainErrorList)
272 else:
272 else:
273 form = SettingsForm(initial={'theme': selected_theme},
273 form = SettingsForm(initial={'theme': selected_theme},
274 error_class=PlainErrorList)
274 error_class=PlainErrorList)
275
275
276 context['form'] = form
276 context['form'] = form
277
277
278 return render(request, 'boards/settings.html', context)
278 return render(request, 'boards/settings.html', context)
279
279
280
280
281 def all_tags(request):
281 def all_tags(request):
282 """All tags list"""
282 """All tags list"""
283
283
284 context = _init_default_context(request)
284 context = _init_default_context(request)
285 context['all_tags'] = Tag.objects.get_not_empty_tags()
285 context['all_tags'] = Tag.objects.get_not_empty_tags()
286
286
287 return render(request, 'boards/tags.html', context)
287 return render(request, 'boards/tags.html', context)
288
288
289
289
290 def jump_to_post(request, post_id):
290 def jump_to_post(request, post_id):
291 """Determine thread in which the requested post is and open it's page"""
291 """Determine thread in which the requested post is and open it's page"""
292
292
293 post = get_object_or_404(Post, id=post_id)
293 post = get_object_or_404(Post, id=post_id)
294
294
295 if not post.thread:
295 if not post.thread:
296 return redirect(thread, post_id=post.id)
296 return redirect(thread, post_id=post.id)
297 else:
297 else:
298 return redirect(reverse(thread, kwargs={'post_id': post.thread.id})
298 return redirect(reverse(thread, kwargs={'post_id': post.thread.id})
299 + '#' + str(post.id))
299 + '#' + str(post.id))
300
300
301
301
302 def authors(request):
302 def authors(request):
303 """Show authors list"""
303 """Show authors list"""
304
304
305 context = _init_default_context(request)
305 context = _init_default_context(request)
306 context['authors'] = boards.authors.authors
306 context['authors'] = boards.authors.authors
307
307
308 return render(request, 'boards/authors.html', context)
308 return render(request, 'boards/authors.html', context)
309
309
310
310
311 @transaction.commit_on_success
311 @transaction.atomic
312 def delete(request, post_id):
312 def delete(request, post_id):
313 """Delete post"""
313 """Delete post"""
314
314
315 user = _get_user(request)
315 user = _get_user(request)
316 post = get_object_or_404(Post, id=post_id)
316 post = get_object_or_404(Post, id=post_id)
317
317
318 if user.is_moderator():
318 if user.is_moderator():
319 # TODO Show confirmation page before deletion
319 # TODO Show confirmation page before deletion
320 Post.objects.delete_post(post)
320 Post.objects.delete_post(post)
321
321
322 if not post.thread:
322 if not post.thread:
323 return _redirect_to_next(request)
323 return _redirect_to_next(request)
324 else:
324 else:
325 return redirect(thread, post_id=post.thread.id)
325 return redirect(thread, post_id=post.thread.id)
326
326
327
327
328 @transaction.commit_on_success
328 @transaction.atomic
329 def ban(request, post_id):
329 def ban(request, post_id):
330 """Ban user"""
330 """Ban user"""
331
331
332 user = _get_user(request)
332 user = _get_user(request)
333 post = get_object_or_404(Post, id=post_id)
333 post = get_object_or_404(Post, id=post_id)
334
334
335 if user.is_moderator():
335 if user.is_moderator():
336 # TODO Show confirmation page before ban
336 # TODO Show confirmation page before ban
337 ban, created = Ban.objects.get_or_create(ip=post.poster_ip)
337 ban, created = Ban.objects.get_or_create(ip=post.poster_ip)
338 if created:
338 if created:
339 ban.reason = 'Banned for post ' + str(post_id)
339 ban.reason = 'Banned for post ' + str(post_id)
340 ban.save()
340 ban.save()
341
341
342 return _redirect_to_next(request)
342 return _redirect_to_next(request)
343
343
344
344
345 def you_are_banned(request):
345 def you_are_banned(request):
346 """Show the page that notifies that user is banned"""
346 """Show the page that notifies that user is banned"""
347
347
348 context = _init_default_context(request)
348 context = _init_default_context(request)
349
349
350 ban = get_object_or_404(Ban, ip=utils.get_client_ip(request))
350 ban = get_object_or_404(Ban, ip=utils.get_client_ip(request))
351 context['ban_reason'] = ban.reason
351 context['ban_reason'] = ban.reason
352 return render(request, 'boards/staticpages/banned.html', context)
352 return render(request, 'boards/staticpages/banned.html', context)
353
353
354
354
355 def page_404(request):
355 def page_404(request):
356 """Show page 404 (not found error)"""
356 """Show page 404 (not found error)"""
357
357
358 context = _init_default_context(request)
358 context = _init_default_context(request)
359 return render(request, 'boards/404.html', context)
359 return render(request, 'boards/404.html', context)
360
360
361
361
362 @transaction.commit_on_success
362 @transaction.atomic
363 def tag_subscribe(request, tag_name):
363 def tag_subscribe(request, tag_name):
364 """Add tag to favorites"""
364 """Add tag to favorites"""
365
365
366 user = _get_user(request)
366 user = _get_user(request)
367 tag = get_object_or_404(Tag, name=tag_name)
367 tag = get_object_or_404(Tag, name=tag_name)
368
368
369 if not tag in user.fav_tags.all():
369 if not tag in user.fav_tags.all():
370 user.add_tag(tag)
370 user.add_tag(tag)
371
371
372 return _redirect_to_next(request)
372 return _redirect_to_next(request)
373
373
374
374
375 @transaction.commit_on_success
375 @transaction.atomic
376 def tag_unsubscribe(request, tag_name):
376 def tag_unsubscribe(request, tag_name):
377 """Remove tag from favorites"""
377 """Remove tag from favorites"""
378
378
379 user = _get_user(request)
379 user = _get_user(request)
380 tag = get_object_or_404(Tag, name=tag_name)
380 tag = get_object_or_404(Tag, name=tag_name)
381
381
382 if tag in user.fav_tags.all():
382 if tag in user.fav_tags.all():
383 user.remove_tag(tag)
383 user.remove_tag(tag)
384
384
385 return _redirect_to_next(request)
385 return _redirect_to_next(request)
386
386
387
387
388 def static_page(request, name):
388 def static_page(request, name):
389 """Show a static page that needs only tags list and a CSS"""
389 """Show a static page that needs only tags list and a CSS"""
390
390
391 context = _init_default_context(request)
391 context = _init_default_context(request)
392 return render(request, 'boards/staticpages/' + name + '.html', context)
392 return render(request, 'boards/staticpages/' + name + '.html', context)
393
393
394
394
395 def api_get_post(request, post_id):
395 def api_get_post(request, post_id):
396 """
396 """
397 Get the JSON of a post. This can be
397 Get the JSON of a post. This can be
398 used as and API for external clients.
398 used as and API for external clients.
399 """
399 """
400
400
401 post = get_object_or_404(Post, id=post_id)
401 post = get_object_or_404(Post, id=post_id)
402
402
403 json = serializers.serialize("json", [post], fields=(
403 json = serializers.serialize("json", [post], fields=(
404 "pub_time", "_text_rendered", "title", "text", "image",
404 "pub_time", "_text_rendered", "title", "text", "image",
405 "image_width", "image_height", "replies", "tags"
405 "image_width", "image_height", "replies", "tags"
406 ))
406 ))
407
407
408 return HttpResponse(content=json)
408 return HttpResponse(content=json)
409
409
410
410
411 @transaction.commit_on_success
411 @transaction.atomic
412 def api_get_threaddiff(request, thread_id, last_update_time):
412 def api_get_threaddiff(request, thread_id, last_update_time):
413 """Get posts that were changed or added since time"""
413 """Get posts that were changed or added since time"""
414
414
415 thread = get_object_or_404(Post, id=thread_id)
415 thread = get_object_or_404(Post, id=thread_id)
416
416
417 filter_time = datetime.fromtimestamp(float(last_update_time) / 1000000,
417 filter_time = datetime.fromtimestamp(float(last_update_time) / 1000000,
418 timezone.get_current_timezone())
418 timezone.get_current_timezone())
419
419
420 json_data = {
420 json_data = {
421 'added': [],
421 'added': [],
422 'updated': [],
422 'updated': [],
423 'last_update': None,
423 'last_update': None,
424 }
424 }
425 added_posts = Post.objects.filter(thread=thread,
425 added_posts = Post.objects.filter(thread=thread,
426 pub_time__gt=filter_time)\
426 pub_time__gt=filter_time)\
427 .order_by('pub_time')
427 .order_by('pub_time')
428 updated_posts = Post.objects.filter(thread=thread,
428 updated_posts = Post.objects.filter(thread=thread,
429 pub_time__lte=filter_time,
429 pub_time__lte=filter_time,
430 last_edit_time__gt=filter_time)
430 last_edit_time__gt=filter_time)
431 for post in added_posts:
431 for post in added_posts:
432 json_data['added'].append(get_post(request, post.id).content.strip())
432 json_data['added'].append(get_post(request, post.id).content.strip())
433 for post in updated_posts:
433 for post in updated_posts:
434 json_data['updated'].append(get_post(request, post.id).content.strip())
434 json_data['updated'].append(get_post(request, post.id).content.strip())
435 json_data['last_update'] = _datetime_to_epoch(thread.last_edit_time)
435 json_data['last_update'] = _datetime_to_epoch(thread.last_edit_time)
436
436
437 return HttpResponse(content=json.dumps(json_data))
437 return HttpResponse(content=json.dumps(json_data))
438
438
439
439
440 def get_post(request, post_id):
440 def get_post(request, post_id):
441 """Get the html of a post. Used for popups."""
441 """Get the html of a post. Used for popups."""
442
442
443 post = get_object_or_404(Post, id=post_id)
443 post = get_object_or_404(Post, id=post_id)
444 thread = post.thread
444 thread = post.thread
445 if not thread:
445 if not thread:
446 thread = post
446 thread = post
447
447
448 context = RequestContext(request)
448 context = RequestContext(request)
449 context["post"] = post
449 context["post"] = post
450 context["can_bump"] = thread.can_bump()
450 context["can_bump"] = thread.can_bump()
451 if "truncated" in request.GET:
451 if "truncated" in request.GET:
452 context["truncated"] = True
452 context["truncated"] = True
453
453
454 return render(request, 'boards/post.html', context)
454 return render(request, 'boards/post.html', context)
455
455
456
456
457 def _get_theme(request, user=None):
457 def _get_theme(request, user=None):
458 """Get user's CSS theme"""
458 """Get user's CSS theme"""
459
459
460 if not user:
460 if not user:
461 user = _get_user(request)
461 user = _get_user(request)
462 theme = user.get_setting('theme')
462 theme = user.get_setting('theme')
463 if not theme:
463 if not theme:
464 theme = neboard.settings.DEFAULT_THEME
464 theme = neboard.settings.DEFAULT_THEME
465
465
466 return theme
466 return theme
467
467
468
468
469 def _init_default_context(request):
469 def _init_default_context(request):
470 """Create context with default values that are used in most views"""
470 """Create context with default values that are used in most views"""
471
471
472 context = RequestContext(request)
472 context = RequestContext(request)
473
473
474 user = _get_user(request)
474 user = _get_user(request)
475 context['user'] = user
475 context['user'] = user
476 context['tags'] = user.get_sorted_fav_tags()
476 context['tags'] = user.get_sorted_fav_tags()
477
477
478 theme = _get_theme(request, user)
478 theme = _get_theme(request, user)
479 context['theme'] = theme
479 context['theme'] = theme
480 context['theme_css'] = 'css/' + theme + '/base_page.css'
480 context['theme_css'] = 'css/' + theme + '/base_page.css'
481
481
482 # This shows the moderator panel
482 # This shows the moderator panel
483 moderate = user.get_setting(SETTING_MODERATE)
483 moderate = user.get_setting(SETTING_MODERATE)
484 if moderate == 'True':
484 if moderate == 'True':
485 context['moderator'] = user.is_moderator()
485 context['moderator'] = user.is_moderator()
486 else:
486 else:
487 context['moderator'] = False
487 context['moderator'] = False
488
488
489 return context
489 return context
490
490
491
491
492 def _get_user(request):
492 def _get_user(request):
493 """
493 """
494 Get current user from the session. If the user does not exist, create
494 Get current user from the session. If the user does not exist, create
495 a new one.
495 a new one.
496 """
496 """
497
497
498 session = request.session
498 session = request.session
499 if not 'user_id' in session:
499 if not 'user_id' in session:
500 request.session.save()
500 request.session.save()
501
501
502 md5 = hashlib.md5()
502 md5 = hashlib.md5()
503 md5.update(session.session_key)
503 md5.update(session.session_key)
504 new_id = md5.hexdigest()
504 new_id = md5.hexdigest()
505
505
506 time_now = timezone.now()
506 time_now = timezone.now()
507 user = User.objects.create(user_id=new_id, rank=RANK_USER,
507 user = User.objects.create(user_id=new_id, rank=RANK_USER,
508 registration_time=time_now)
508 registration_time=time_now)
509
509
510 session['user_id'] = user.id
510 session['user_id'] = user.id
511 else:
511 else:
512 user = User.objects.get(id=session['user_id'])
512 user = User.objects.get(id=session['user_id'])
513
513
514 return user
514 return user
515
515
516
516
517 def _redirect_to_next(request):
517 def _redirect_to_next(request):
518 """
518 """
519 If a 'next' parameter was specified, redirect to the next page. This is
519 If a 'next' parameter was specified, redirect to the next page. This is
520 used when the user is required to return to some page after the current
520 used when the user is required to return to some page after the current
521 view has finished its work.
521 view has finished its work.
522 """
522 """
523
523
524 if 'next' in request.GET:
524 if 'next' in request.GET:
525 next_page = request.GET['next']
525 next_page = request.GET['next']
526 return HttpResponseRedirect(next_page)
526 return HttpResponseRedirect(next_page)
527 else:
527 else:
528 return redirect(index)
528 return redirect(index)
529
529
530
530
531 @transaction.commit_on_success
531 @transaction.atomic
532 def _ban_current_user(request):
532 def _ban_current_user(request):
533 """Add current user to the IP ban list"""
533 """Add current user to the IP ban list"""
534
534
535 ip = utils.get_client_ip(request)
535 ip = utils.get_client_ip(request)
536 ban, created = Ban.objects.get_or_create(ip=ip)
536 ban, created = Ban.objects.get_or_create(ip=ip)
537 if created:
537 if created:
538 ban.can_read = False
538 ban.can_read = False
539 ban.reason = BAN_REASON_SPAM
539 ban.reason = BAN_REASON_SPAM
540 ban.save()
540 ban.save()
541
541
542
542
543 def _remove_invalid_links(text):
543 def _remove_invalid_links(text):
544 """
544 """
545 Replace invalid links in posts so that they won't be parsed.
545 Replace invalid links in posts so that they won't be parsed.
546 Invalid links are links to non-existent posts
546 Invalid links are links to non-existent posts
547 """
547 """
548
548
549 for reply_number in re.finditer(REGEX_REPLY, text):
549 for reply_number in re.finditer(REGEX_REPLY, text):
550 post_id = reply_number.group(1)
550 post_id = reply_number.group(1)
551 post = Post.objects.filter(id=post_id)
551 post = Post.objects.filter(id=post_id)
552 if not post.exists():
552 if not post.exists():
553 text = string.replace(text, '>>' + post_id, post_id)
553 text = string.replace(text, '>>' + post_id, post_id)
554
554
555 return text
555 return text
556
556
557
557
558 def _datetime_to_epoch(datetime):
558 def _datetime_to_epoch(datetime):
559 return int(time.mktime(timezone.localtime(
559 return int(time.mktime(timezone.localtime(
560 datetime,timezone.get_current_timezone()).timetuple())
560 datetime,timezone.get_current_timezone()).timetuple())
561 * 1000000 + datetime.microsecond)
561 * 1000000 + datetime.microsecond)
@@ -1,8 +1,8 b''
1 pil
1 pillow
2 django >= 1.5
2 django >= 1.6
3 django_cleanup
3 django_cleanup
4 django-markupfield
4 django-markupfield
5 markdown
5 markdown
6 python-markdown
6 python-markdown
7 django-simple-captcha
7 django-simple-captcha
8 line-profiler
8 line-profiler
General Comments 0
You need to be logged in to leave comments. Login now