postsactions.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. from django.contrib import messages
  2. from django.db.transaction import atomic
  3. from django.http import Http404
  4. from django.shortcuts import redirect
  5. from django.utils.translation import ungettext, ugettext_lazy, ugettext as _
  6. from misago.threads import moderation
  7. from misago.threads.paginator import Paginator
  8. from misago.threads.views.generic.actions import ActionsBase, ReloadAfterDelete
  9. __all__ = ['PostsActions']
  10. def atomic_post_action(f):
  11. def decorator(self, request, posts):
  12. with atomic():
  13. self.forum.lock()
  14. self.thread.lock()
  15. for post in posts:
  16. post.thread = self.thread
  17. response = f(self, request, posts)
  18. self.thread.synchronize()
  19. self.thread.save()
  20. self.forum.synchronize()
  21. self.forum.save()
  22. return response
  23. return decorator
  24. class PostsActions(ActionsBase):
  25. select_items_message = ugettext_lazy(
  26. "You have to select at least one post.")
  27. is_mass_action = True
  28. def redirect_after_deletion(self, request, queryset):
  29. paginator = Paginator(queryset, 10, 3)
  30. current_page = int(request.resolver_match.kwargs.get('page', 0))
  31. if paginator.num_pages < current_page:
  32. namespace = request.resolver_match.namespace
  33. url_name = request.resolver_match.url_name
  34. kwars = request.resolver_match.kwargs
  35. kwars['page'] = paginator.num_pages
  36. if kwars['page'] == 1:
  37. del kwars['page']
  38. return redirect('%s:%s' % (namespace, url_name), **kwars)
  39. else:
  40. return redirect(request.path)
  41. def get_available_actions(self, kwargs):
  42. self.thread = kwargs['thread']
  43. self.forum = self.thread.forum
  44. actions = []
  45. if self.forum.acl['can_hide_posts']:
  46. actions.append({
  47. 'action': 'unhide',
  48. 'icon': 'eye',
  49. 'name': _("Reveal posts")
  50. })
  51. actions.append({
  52. 'action': 'hide',
  53. 'icon': 'eye-slash',
  54. 'name': _("Hide posts")
  55. })
  56. if self.forum.acl['can_hide_posts'] == 2:
  57. actions.append({
  58. 'action': 'delete',
  59. 'icon': 'times',
  60. 'name': _("Delete posts"),
  61. 'confirmation': _("Are you sure you want to delete selected "
  62. "posts? This action can't be undone.")
  63. })
  64. return actions
  65. @atomic_post_action
  66. def action_unhide(self, request, posts):
  67. changed_posts = 0
  68. for post in posts:
  69. if moderation.unhide_post(request.user, post):
  70. changed_posts += 1
  71. if changed_posts:
  72. message = ungettext(
  73. '%(changed)d post was made visible.',
  74. '%(changed)d posts were made visible.',
  75. changed_posts)
  76. messages.success(request, message % {'changed': changed_posts})
  77. else:
  78. message = _("No posts were made visible.")
  79. messages.info(request, message)
  80. @atomic_post_action
  81. def action_hide(self, request, posts):
  82. changed_posts = 0
  83. for post in posts:
  84. if moderation.hide_post(request.user, post):
  85. changed_posts += 1
  86. if changed_posts:
  87. message = ungettext(
  88. '%(changed)d post was hidden.',
  89. '%(changed)d posts were hidden.',
  90. changed_posts)
  91. messages.success(request, message % {'changed': changed_posts})
  92. else:
  93. message = _("No posts were hidden.")
  94. messages.info(request, message)
  95. pass
  96. @atomic_post_action
  97. def action_delete(self, request, posts):
  98. changed_posts = 0
  99. first_deleted = None
  100. for post in posts:
  101. if moderation.delete_post(request.user, post):
  102. changed_posts += 1
  103. if not first_deleted:
  104. first_deleted = post
  105. if changed_posts:
  106. message = ungettext(
  107. '%(changed)d post was deleted.',
  108. '%(changed)d posts were deleted.',
  109. changed_posts)
  110. messages.success(request, message % {'changed': changed_posts})
  111. return ReloadAfterDelete()
  112. else:
  113. message = _("No posts were deleted.")
  114. messages.info(request, message)