##// END OF EJS Templates
Fixed links to not existing messages
neko259 -
r388:2d312aa9 default
parent child Browse files
Show More
@@ -1,560 +1,560 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.commit_on_success
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.commit_on_success
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.commit_on_success
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.commit_on_success
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.commit_on_success
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 def api_get_threaddiff(request, thread_id, last_update_time):
411 def api_get_threaddiff(request, thread_id, last_update_time):
412 """Get posts that were changed or added since time"""
412 """Get posts that were changed or added since time"""
413
413
414 thread = get_object_or_404(Post, id=thread_id)
414 thread = get_object_or_404(Post, id=thread_id)
415
415
416 filter_time = datetime.fromtimestamp(float(last_update_time) / 1000000,
416 filter_time = datetime.fromtimestamp(float(last_update_time) / 1000000,
417 timezone.get_current_timezone())
417 timezone.get_current_timezone())
418
418
419 json_data = {
419 json_data = {
420 'added': [],
420 'added': [],
421 'updated': [],
421 'updated': [],
422 'last_update': None,
422 'last_update': None,
423 }
423 }
424 added_posts = Post.objects.filter(thread=thread,
424 added_posts = Post.objects.filter(thread=thread,
425 pub_time__gt=filter_time)\
425 pub_time__gt=filter_time)\
426 .order_by('pub_time')
426 .order_by('pub_time')
427 updated_posts = Post.objects.filter(thread=thread,
427 updated_posts = Post.objects.filter(thread=thread,
428 pub_time__lte=filter_time,
428 pub_time__lte=filter_time,
429 last_edit_time__gt=filter_time)
429 last_edit_time__gt=filter_time)
430 for post in added_posts:
430 for post in added_posts:
431 json_data['added'].append(get_post(request, post.id).content.strip())
431 json_data['added'].append(get_post(request, post.id).content.strip())
432 for post in updated_posts:
432 for post in updated_posts:
433 json_data['updated'].append(get_post(request, post.id).content.strip())
433 json_data['updated'].append(get_post(request, post.id).content.strip())
434 json_data['last_update'] = _datetime_to_epoch(thread.last_edit_time)
434 json_data['last_update'] = _datetime_to_epoch(thread.last_edit_time)
435
435
436 return HttpResponse(content=json.dumps(json_data))
436 return HttpResponse(content=json.dumps(json_data))
437
437
438
438
439 def get_post(request, post_id):
439 def get_post(request, post_id):
440 """Get the html of a post. Used for popups."""
440 """Get the html of a post. Used for popups."""
441
441
442 post = get_object_or_404(Post, id=post_id)
442 post = get_object_or_404(Post, id=post_id)
443 thread = post.thread
443 thread = post.thread
444 if not thread:
444 if not thread:
445 thread = post
445 thread = post
446
446
447 context = RequestContext(request)
447 context = RequestContext(request)
448 context["post"] = post
448 context["post"] = post
449 context["can_bump"] = thread.can_bump()
449 context["can_bump"] = thread.can_bump()
450 if "truncated" in request.GET:
450 if "truncated" in request.GET:
451 context["truncated"] = True
451 context["truncated"] = True
452
452
453 return render(request, 'boards/post.html', context)
453 return render(request, 'boards/post.html', context)
454
454
455
455
456 def _get_theme(request, user=None):
456 def _get_theme(request, user=None):
457 """Get user's CSS theme"""
457 """Get user's CSS theme"""
458
458
459 if not user:
459 if not user:
460 user = _get_user(request)
460 user = _get_user(request)
461 theme = user.get_setting('theme')
461 theme = user.get_setting('theme')
462 if not theme:
462 if not theme:
463 theme = neboard.settings.DEFAULT_THEME
463 theme = neboard.settings.DEFAULT_THEME
464
464
465 return theme
465 return theme
466
466
467
467
468 def _init_default_context(request):
468 def _init_default_context(request):
469 """Create context with default values that are used in most views"""
469 """Create context with default values that are used in most views"""
470
470
471 context = RequestContext(request)
471 context = RequestContext(request)
472
472
473 user = _get_user(request)
473 user = _get_user(request)
474 context['user'] = user
474 context['user'] = user
475 context['tags'] = user.get_sorted_fav_tags()
475 context['tags'] = user.get_sorted_fav_tags()
476
476
477 theme = _get_theme(request, user)
477 theme = _get_theme(request, user)
478 context['theme'] = theme
478 context['theme'] = theme
479 context['theme_css'] = 'css/' + theme + '/base_page.css'
479 context['theme_css'] = 'css/' + theme + '/base_page.css'
480
480
481 # This shows the moderator panel
481 # This shows the moderator panel
482 moderate = user.get_setting(SETTING_MODERATE)
482 moderate = user.get_setting(SETTING_MODERATE)
483 if moderate == 'True':
483 if moderate == 'True':
484 context['moderator'] = user.is_moderator()
484 context['moderator'] = user.is_moderator()
485 else:
485 else:
486 context['moderator'] = False
486 context['moderator'] = False
487
487
488 return context
488 return context
489
489
490
490
491 def _get_user(request):
491 def _get_user(request):
492 """
492 """
493 Get current user from the session. If the user does not exist, create
493 Get current user from the session. If the user does not exist, create
494 a new one.
494 a new one.
495 """
495 """
496
496
497 session = request.session
497 session = request.session
498 if not 'user_id' in session:
498 if not 'user_id' in session:
499 request.session.save()
499 request.session.save()
500
500
501 md5 = hashlib.md5()
501 md5 = hashlib.md5()
502 md5.update(session.session_key)
502 md5.update(session.session_key)
503 new_id = md5.hexdigest()
503 new_id = md5.hexdigest()
504
504
505 time_now = timezone.now()
505 time_now = timezone.now()
506 user = User.objects.create(user_id=new_id, rank=RANK_USER,
506 user = User.objects.create(user_id=new_id, rank=RANK_USER,
507 registration_time=time_now)
507 registration_time=time_now)
508
508
509 session['user_id'] = user.id
509 session['user_id'] = user.id
510 else:
510 else:
511 user = User.objects.get(id=session['user_id'])
511 user = User.objects.get(id=session['user_id'])
512
512
513 return user
513 return user
514
514
515
515
516 def _redirect_to_next(request):
516 def _redirect_to_next(request):
517 """
517 """
518 If a 'next' parameter was specified, redirect to the next page. This is
518 If a 'next' parameter was specified, redirect to the next page. This is
519 used when the user is required to return to some page after the current
519 used when the user is required to return to some page after the current
520 view has finished its work.
520 view has finished its work.
521 """
521 """
522
522
523 if 'next' in request.GET:
523 if 'next' in request.GET:
524 next_page = request.GET['next']
524 next_page = request.GET['next']
525 return HttpResponseRedirect(next_page)
525 return HttpResponseRedirect(next_page)
526 else:
526 else:
527 return redirect(index)
527 return redirect(index)
528
528
529
529
530 @transaction.commit_on_success
530 @transaction.commit_on_success
531 def _ban_current_user(request):
531 def _ban_current_user(request):
532 """Add current user to the IP ban list"""
532 """Add current user to the IP ban list"""
533
533
534 ip = utils.get_client_ip(request)
534 ip = utils.get_client_ip(request)
535 ban, created = Ban.objects.get_or_create(ip=ip)
535 ban, created = Ban.objects.get_or_create(ip=ip)
536 if created:
536 if created:
537 ban.can_read = False
537 ban.can_read = False
538 ban.reason = BAN_REASON_SPAM
538 ban.reason = BAN_REASON_SPAM
539 ban.save()
539 ban.save()
540
540
541
541
542 def _remove_invalid_links(text):
542 def _remove_invalid_links(text):
543 """
543 """
544 Replace invalid links in posts so that they won't be parsed.
544 Replace invalid links in posts so that they won't be parsed.
545 Invalid links are links to non-existent posts
545 Invalid links are links to non-existent posts
546 """
546 """
547
547
548 for reply_number in re.finditer(REGEX_REPLY, text):
548 for reply_number in re.finditer(REGEX_REPLY, text):
549 post_id = reply_number.group(1)
549 post_id = reply_number.group(1)
550 post = Post.objects.filter(id=post_id)
550 post = Post.objects.filter(id=post_id)
551 if not post.exists():
551 if not post.exists():
552 text = string.replace(text, '>>' + id, id)
552 text = string.replace(text, '>>' + post_id, post_id)
553
553
554 return text
554 return text
555
555
556
556
557 def _datetime_to_epoch(datetime):
557 def _datetime_to_epoch(datetime):
558 return int(time.mktime(timezone.localtime(
558 return int(time.mktime(timezone.localtime(
559 datetime,timezone.get_current_timezone()).timetuple())
559 datetime,timezone.get_current_timezone()).timetuple())
560 * 1000000 + datetime.microsecond)
560 * 1000000 + datetime.microsecond)
General Comments 0
You need to be logged in to leave comments. Login now