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