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