jumps.py 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. from django.core.urlresolvers import reverse
  2. from django.shortcuts import redirect
  3. from django.template import RequestContext
  4. from misago.acl.utils import ACLError403, ACLError404
  5. from misago.forums.models import Forum
  6. from misago.readstracker.trackers import ThreadsTracker
  7. from misago.threads.models import Thread, Post
  8. from misago.threads.views.base import BaseView
  9. from misago.views import error403, error404
  10. from misago.utils import make_pagination
  11. class JumpView(BaseView):
  12. def fetch_thread(self, thread):
  13. self.thread = Thread.objects.get(pk=thread)
  14. self.forum = self.thread.forum
  15. self.request.acl.forums.allow_forum_view(self.forum)
  16. self.request.acl.threads.allow_thread_view(self.request.user, self.thread)
  17. def fetch_post(self, post):
  18. self.post = self.thread.post_set.get(pk=post)
  19. self.request.acl.threads.allow_post_view(self.request.user, self.thread, self.post)
  20. def redirect(self, post):
  21. 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)
  22. if pagination['total'] > 1:
  23. return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug, 'page': pagination['total']}) + ('#post-%s' % post.pk))
  24. return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}) + ('#post-%s' % post.pk))
  25. def make_jump(self):
  26. raise NotImplementedError('JumpView cannot be called directly.')
  27. def __call__(self, request, slug=None, thread=None, post=None):
  28. self.request = request
  29. try:
  30. self.fetch_thread(thread)
  31. if post:
  32. self.fetch_post(post)
  33. return self.make_jump()
  34. except (Thread.DoesNotExist, Post.DoesNotExist):
  35. return error404(self.request)
  36. except ACLError403 as e:
  37. return error403(request, e.message)
  38. except ACLError404 as e:
  39. return error404(request, e.message)
  40. class LastReplyView(JumpView):
  41. def make_jump(self):
  42. return self.redirect(self.thread.post_set.order_by('-id')[:1][0])
  43. class FindReplyView(JumpView):
  44. def make_jump(self):
  45. return self.redirect(self.post)
  46. class NewReplyView(JumpView):
  47. def make_jump(self):
  48. if not self.request.user.is_authenticated():
  49. return self.redirect(self.thread.post_set.order_by('-id')[:1][0])
  50. tracker = ThreadsTracker(self.request, self.forum)
  51. read_date = tracker.get_read_date(self.thread)
  52. post = self.thread.post_set.filter(date__gt=read_date).order_by('id')[:1]
  53. if not post:
  54. return self.redirect(self.thread.post_set.order_by('-id')[:1][0])
  55. return self.redirect(post[0])
  56. class FirstModeratedView(JumpView):
  57. def make_jump(self):
  58. if not self.request.acl.threads.can_approve(self.forum):
  59. raise ACLError404()
  60. try:
  61. return self.redirect(
  62. self.thread.post_set.get(moderated=True))
  63. except Post.DoesNotExist:
  64. return error404(self.request)
  65. class FirstReportedView(JumpView):
  66. def make_jump(self):
  67. if not self.request.acl.threads.can_mod_posts(self.forum):
  68. raise ACLError404()
  69. try:
  70. return self.redirect(
  71. self.thread.post_set.get(reported=True))
  72. except Post.DoesNotExist:
  73. return error404(self.request)