jumps.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. from django.core.urlresolvers import reverse
  2. from django.shortcuts import redirect
  3. from django.template import RequestContext
  4. from django.utils.translation import ugettext as _
  5. from misago.acl.utils import ACLError403, ACLError404
  6. from misago.authn.decorators import block_guest
  7. from misago.csrf.decorators import check_csrf
  8. from misago.forums.models import Forum
  9. from misago.messages import Message
  10. from misago.readstracker.trackers import ThreadsTracker
  11. from misago.threads.models import Thread, Post
  12. from misago.threads.views.base import BaseView
  13. from misago.views import error403, error404
  14. from misago.utils import make_pagination
  15. class JumpView(BaseView):
  16. def fetch_thread(self, thread):
  17. self.thread = Thread.objects.get(pk=thread)
  18. self.forum = self.thread.forum
  19. self.request.acl.forums.allow_forum_view(self.forum)
  20. self.request.acl.threads.allow_thread_view(self.request.user, self.thread)
  21. def fetch_post(self, post):
  22. self.post = self.thread.post_set.get(pk=post)
  23. self.request.acl.threads.allow_post_view(self.request.user, self.thread, self.post)
  24. def redirect(self, post):
  25. pagination = make_pagination(0, self.request.acl.threads.filter_posts(self.request, self.thread, self.thread.post_set.filter(date__lt=post.date)).count() + 1, self.request.settings.posts_per_page)
  26. if pagination['total'] > 1:
  27. return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug, 'page': pagination['total']}) + ('#post-%s' % post.pk))
  28. return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}) + ('#post-%s' % post.pk))
  29. def make_jump(self):
  30. raise NotImplementedError('JumpView cannot be called directly.')
  31. def __call__(self, request, slug=None, thread=None, post=None):
  32. self.request = request
  33. try:
  34. self.fetch_thread(thread)
  35. if post:
  36. self.fetch_post(post)
  37. return self.make_jump()
  38. except (Thread.DoesNotExist, Post.DoesNotExist):
  39. return error404(self.request)
  40. except ACLError403 as e:
  41. return error403(request, e.message)
  42. except ACLError404 as e:
  43. return error404(request, e.message)
  44. class ShowHiddenRepliesView(JumpView):
  45. def make_jump(self):
  46. @block_guest
  47. @check_csrf
  48. def view(request):
  49. ignored_exclusions = request.session.get('unignore_threads', [])
  50. ignored_exclusions.append(self.thread.pk)
  51. request.session['unignore_threads'] = ignored_exclusions
  52. request.messages.set_flash(Message(_('Replies made to this thread by members on your ignore list have been revealed.')), 'success', 'threads')
  53. return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}))
  54. return view(self.request)
  55. class LastReplyView(JumpView):
  56. def make_jump(self):
  57. return self.redirect(self.thread.post_set.order_by('-id')[:1][0])
  58. class FindReplyView(JumpView):
  59. def make_jump(self):
  60. return self.redirect(self.post)
  61. class NewReplyView(JumpView):
  62. def make_jump(self):
  63. if not self.request.user.is_authenticated():
  64. return self.redirect(self.thread.post_set.order_by('-id')[:1][0])
  65. tracker = ThreadsTracker(self.request, self.forum)
  66. read_date = tracker.get_read_date(self.thread)
  67. post = self.thread.post_set.filter(date__gt=read_date).order_by('id')[:1]
  68. if not post:
  69. return self.redirect(self.thread.post_set.order_by('-id')[:1][0])
  70. return self.redirect(post[0])
  71. class FirstModeratedView(JumpView):
  72. def make_jump(self):
  73. if not self.request.acl.threads.can_approve(self.forum):
  74. raise ACLError404()
  75. try:
  76. return self.redirect(
  77. self.thread.post_set.get(moderated=True))
  78. except Post.DoesNotExist:
  79. return error404(self.request)
  80. class FirstReportedView(JumpView):
  81. def make_jump(self):
  82. if not self.request.acl.threads.can_mod_posts(self.forum):
  83. raise ACLError404()
  84. try:
  85. return self.redirect(
  86. self.thread.post_set.get(reported=True))
  87. except Post.DoesNotExist:
  88. return error404(self.request)