delete.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. from django.core.urlresolvers import reverse
  2. from django.shortcuts import redirect
  3. from django.utils import timezone
  4. from django.utils.translation import ugettext as _
  5. from misago.acl.exceptions import ACLError403, ACLError404
  6. from misago.apps.errors import error403, error404
  7. from misago.messages import Message
  8. from misago.models import Forum, Thread, Post
  9. from misago.apps.threadtype.base import ViewBase
  10. class DeleteHideBaseView(ViewBase):
  11. def _set_context(self):
  12. self.thread = Thread.objects.get(pk=self.kwargs.get('thread'))
  13. self.forum = self.thread.forum
  14. self.proxy = Forum.objects.parents_aware_forum(self.forum)
  15. if self.forum.level:
  16. self.parents = Forum.objects.forum_parents(self.forum.pk)
  17. self.check_forum_type()
  18. self.request.acl.forums.allow_forum_view(self.forum)
  19. self.request.acl.threads.allow_thread_view(self.request.user, self.thread)
  20. if self.kwargs.get('post'):
  21. self.post = self.thread.post_set.get(id=self.kwargs.get('post'))
  22. self.request.acl.threads.allow_post_view(self.request.user, self.thread, self.post)
  23. self.set_context()
  24. def __call__(self, request, **kwargs):
  25. self.request = request
  26. self.kwargs = kwargs
  27. self.parents = []
  28. try:
  29. self._set_context()
  30. self.delete()
  31. self.message()
  32. return self.response()
  33. except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist):
  34. return error404(request)
  35. except ACLError403 as e:
  36. return error403(request, unicode(e))
  37. except ACLError404 as e:
  38. return error404(request, unicode(e))
  39. class DeleteThreadBaseView(DeleteHideBaseView):
  40. def set_context(self):
  41. self.request.acl.threads.allow_delete_thread(self.request.user, self.proxy,
  42. self.thread, self.thread.start_post, True)
  43. # Assert we are not user trying to delete thread with replies
  44. acl = self.request.acl.threads.get_role(self.thread.forum_id)
  45. if not acl['can_delete_threads']:
  46. if self.thread.post_set.exclude(user_id=self.request.user.id).count() > 0:
  47. raise ACLError403(_("Somebody has already replied to this thread. You cannot delete it."))
  48. def delete(self):
  49. self.thread.delete()
  50. self.forum.sync()
  51. self.forum.save(force_update=True)
  52. def message(self):
  53. self.request.messages.set_flash(Message(_('Thread "%(thread)s" has been deleted.') % {'thread': self.thread.name}), 'success', 'threads')
  54. def response(self):
  55. return self.threads_list_redirect()
  56. class HideThreadBaseView(DeleteHideBaseView):
  57. def set_context(self):
  58. self.request.acl.threads.allow_delete_thread(self.request.user, self.proxy,
  59. self.thread, self.thread.start_post)
  60. # Assert we are not user trying to delete thread with replies
  61. acl = self.request.acl.threads.get_role(self.thread.forum_id)
  62. if not acl['can_delete_threads']:
  63. if self.thread.post_set.exclude(user_id=self.request.user.id).count() > 0:
  64. raise ACLError403(_("Somebody has already replied to this thread. You cannot delete it."))
  65. def delete(self):
  66. self.thread.start_post.deleted = True
  67. self.thread.start_post.save(force_update=True)
  68. self.thread.last_post.set_checkpoint(self.request, 'deleted')
  69. self.thread.last_post.save(force_update=True)
  70. self.thread.sync()
  71. self.thread.save(force_update=True)
  72. self.forum.sync()
  73. self.forum.save(force_update=True)
  74. def message(self):
  75. self.request.messages.set_flash(Message(_('Thread "%(thread)s" has been deleted.') % {'thread': self.thread.name}), 'success', 'threads')
  76. def response(self):
  77. if self.request.acl.threads.can_see_deleted_threads(self.thread.forum):
  78. return redirect(reverse(self.type_prefix, kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}))
  79. return self.threads_list_redirect()
  80. class DeleteReplyBaseView(DeleteHideBaseView):
  81. def set_context(self):
  82. self.request.acl.threads.allow_delete_post(self.request.user, self.forum,
  83. self.thread, self.post, True)
  84. acl = self.request.acl.threads.get_role(self.thread.forum_id)
  85. if not acl['can_delete_posts'] and self.thread.post_set.filter(id__gt=self.post.pk).count() > 0:
  86. raise ACLError403(_("Somebody has already replied to this post, you cannot delete it."))
  87. def delete(self):
  88. self.post.delete()
  89. self.thread.sync()
  90. self.thread.save(force_update=True)
  91. self.forum.sync()
  92. self.forum.save(force_update=True)
  93. def message(self):
  94. self.request.messages.set_flash(Message(_("Selected Reply has been deleted.")), 'success', 'threads')
  95. def response(self):
  96. return redirect(reverse(self.type_prefix, kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}))
  97. class HideReplyBaseView(DeleteHideBaseView):
  98. def set_context(self):
  99. self.request.acl.threads.allow_delete_post(self.request.user, self.forum,
  100. self.thread, self.post)
  101. acl = self.request.acl.threads.get_role(self.thread.forum_id)
  102. if not acl['can_delete_posts'] and self.thread.post_set.filter(id__gt=self.post.pk).count() > 0:
  103. raise ACLError403(_("Somebody has already replied to this post, you cannot delete it."))
  104. def delete(self):
  105. self.post.deleted = True
  106. self.post.edit_date = timezone.now()
  107. self.post.edit_user = self.request.user
  108. self.post.edit_user_name = self.request.user.username
  109. self.post.edit_user_slug = self.request.user.username_slug
  110. self.post.save(force_update=True)
  111. self.thread.sync()
  112. self.thread.save(force_update=True)
  113. self.forum.sync()
  114. self.forum.save(force_update=True)
  115. def message(self):
  116. self.request.messages.set_flash(Message(_("Selected Reply has been deleted.")), 'success', 'threads_%s' % self.post.pk)
  117. def response(self):
  118. return self.redirect_to_post(self.post)