post.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. from django.contrib import messages
  2. from django.core.exceptions import PermissionDenied
  3. from django.db.transaction import atomic
  4. from django.http import JsonResponse
  5. from django.shortcuts import redirect, render
  6. from django.utils.translation import ugettext as _
  7. from misago.acl import add_acl
  8. from misago.threads import permissions, moderation, goto
  9. from misago.threads.views.generic.base import ViewBase
  10. __all__ = [
  11. 'QuotePostView',
  12. 'ApprovePostView',
  13. 'UnhidePostView',
  14. 'HidePostView',
  15. 'DeletePostView'
  16. ]
  17. class PostView(ViewBase):
  18. is_atomic = True
  19. require_post = True
  20. def dispatch(self, request, *args, **kwargs):
  21. if request.method != "POST" and self.require_post:
  22. response = render(request, 'misago/errorpages/wrong_way.html')
  23. response.status_code = 405
  24. return response
  25. post = None
  26. response = None
  27. if self.is_atomic:
  28. with atomic():
  29. post = self.get_post(request, True, **kwargs)
  30. response = self.real_dispatch(request, post)
  31. else:
  32. post = self.get_post(request, **kwargs)
  33. response = self.real_dispatch(request, post)
  34. if response:
  35. return response
  36. else:
  37. return self.redirect_to_post(request.user, post)
  38. def real_dispatch(self, request, post):
  39. raise NotImplementedError(
  40. "post views have to override real_dispatch method")
  41. def redirect_to_post(self, user, post):
  42. posts_qs = self.exclude_invisible_posts(post.thread.post_set,
  43. user,
  44. post.forum,
  45. post.thread)
  46. return redirect(goto.post(post.thread, posts_qs, post))
  47. class QuotePostView(PostView):
  48. is_atomic = False
  49. require_post = False
  50. def real_dispatch(self, request, post):
  51. quote_tpl = u'[quote="%s, post:%s, topic:%s"]\n%s\n[/quote]'
  52. formats = (post.poster_name, post.pk, post.thread_id, post.original)
  53. return JsonResponse({
  54. 'quote': quote_tpl % formats
  55. })
  56. class ApprovePostView(PostView):
  57. def real_dispatch(self, request, post):
  58. if not post.acl['can_approve']:
  59. raise PermissionDenied(_("You can't approve this post."))
  60. if post.id == post.thread.first_post_id:
  61. moderation.approve_thread(request.user, post.thread)
  62. messages.success(request, _("Thread has been approved."))
  63. else:
  64. moderation.approve_post(request.user, post)
  65. messages.success(request, _("Post has been approved."))
  66. post.thread.synchronize()
  67. post.thread.save()
  68. post.forum.synchronize()
  69. post.forum.save()
  70. class UnhidePostView(PostView):
  71. is_atomic = False
  72. def real_dispatch(self, request, post):
  73. permissions.allow_unhide_post(request.user, post)
  74. moderation.unhide_post(request.user, post)
  75. messages.success(request, _("Post has been made visible."))
  76. class HidePostView(PostView):
  77. is_atomic = False
  78. def real_dispatch(self, request, post):
  79. permissions.allow_hide_post(request.user, post)
  80. moderation.hide_post(request.user, post)
  81. messages.success(request, _("Post has been hidden."))
  82. class DeletePostView(PostView):
  83. def real_dispatch(self, request, post):
  84. post_id = post.id
  85. permissions.allow_delete_post(request.user, post)
  86. moderation.delete_post(request.user, post)
  87. post.thread.synchronize()
  88. post.thread.save()
  89. post.forum.synchronize()
  90. post.forum.save()
  91. posts_qs = self.exclude_invisible_posts(post.thread.post_set,
  92. request.user,
  93. post.forum,
  94. post.thread)
  95. posts_qs = posts_qs.select_related('thread', 'forum')
  96. if post_id < post.thread.last_post_id:
  97. target_post = posts_qs.order_by('id').filter(id__gt=post_id)
  98. else:
  99. target_post = posts_qs.order_by('-id').filter(id__lt=post_id)
  100. target_post = target_post[:1][0]
  101. target_post.thread.forum = target_post.forum
  102. add_acl(request.user, target_post.forum)
  103. add_acl(request.user, target_post.thread)
  104. add_acl(request.user, target_post)
  105. messages.success(request, _("Post has been deleted."))
  106. return self.redirect_to_post(request.user, target_post)