threadactions.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. from django.contrib import messages
  2. from django.shortcuts import redirect, render
  3. from django.utils.translation import ugettext as _
  4. from misago.forums.lists import get_forum_path
  5. from misago.threads import moderation
  6. from misago.threads.forms.moderation import MoveThreadForm
  7. from misago.threads.models import Label
  8. from misago.threads.views.generic.actions import ActionsBase
  9. __all__ = ['ThreadActions']
  10. class ThreadActions(ActionsBase):
  11. query_key = 'thread_action'
  12. is_mass_action = False
  13. def get_available_actions(self, kwargs):
  14. self.thread = kwargs['thread']
  15. self.forum = self.thread.forum
  16. actions = []
  17. if self.forum.acl['can_change_threads_labels'] == 2:
  18. self.forum.labels = Label.objects.get_forum_labels(self.forum)
  19. for label in self.forum.labels:
  20. if label.pk != self.thread.label_id:
  21. name = _('Label as "%(label)s"') % {'label': label.name}
  22. actions.append({
  23. 'action': 'label:%s' % label.slug,
  24. 'icon': 'tag',
  25. 'name': name
  26. })
  27. if self.forum.labels and self.thread.label_id:
  28. actions.append({
  29. 'action': 'unlabel',
  30. 'icon': 'times-circle',
  31. 'name': _("Remove label")
  32. })
  33. if self.forum.acl['can_pin_threads']:
  34. if self.thread.is_pinned:
  35. actions.append({
  36. 'action': 'unpin',
  37. 'icon': 'circle',
  38. 'name': _("Unpin thread")
  39. })
  40. else:
  41. actions.append({
  42. 'action': 'pin',
  43. 'icon': 'star',
  44. 'name': _("Pin thread")
  45. })
  46. if self.forum.acl['can_review_moderated_content']:
  47. if self.thread.is_moderated:
  48. actions.append({
  49. 'action': 'approve',
  50. 'icon': 'check',
  51. 'name': _("Approve thread")
  52. })
  53. if self.forum.acl['can_move_threads']:
  54. actions.append({
  55. 'action': 'move',
  56. 'icon': 'arrow-right',
  57. 'name': _("Move thread")
  58. })
  59. if self.forum.acl['can_close_threads']:
  60. if self.thread.is_closed:
  61. actions.append({
  62. 'action': 'open',
  63. 'icon': 'unlock-alt',
  64. 'name': _("Open thread")
  65. })
  66. else:
  67. actions.append({
  68. 'action': 'close',
  69. 'icon': 'lock',
  70. 'name': _("Close thread")
  71. })
  72. if self.forum.acl['can_hide_threads']:
  73. if self.thread.is_hidden:
  74. actions.append({
  75. 'action': 'unhide',
  76. 'icon': 'eye',
  77. 'name': _("Unhide thread")
  78. })
  79. else:
  80. actions.append({
  81. 'action': 'hide',
  82. 'icon': 'eye-slash',
  83. 'name': _("Hide thread")
  84. })
  85. if self.forum.acl['can_hide_threads'] == 2:
  86. actions.append({
  87. 'action': 'delete',
  88. 'icon': 'times',
  89. 'name': _("Delete thread"),
  90. 'confirmation': _("Are you sure you want to delete this "
  91. "thread? This action can't be undone.")
  92. })
  93. return actions
  94. def action_label(self, request, thread, label_slug):
  95. for label in self.forum.labels:
  96. if label.slug == label_slug:
  97. break
  98. else:
  99. raise moderation.ModerationError(self.invalid_action_message)
  100. moderation.label_thread(request.user, thread, label)
  101. message = _('Thread was labeled "%(label)s".')
  102. messages.success(request, message % {'label': label.name})
  103. def action_unlabel(self, request, thread):
  104. moderation.unlabel_thread(request.user, thread)
  105. messages.success(request, _("Thread label was removed."))
  106. def action_pin(self, request, thread):
  107. moderation.pin_thread(request.user, thread)
  108. messages.success(request, _("Thread was pinned."))
  109. def action_unpin(self, request, thread):
  110. moderation.unpin_thread(request.user, thread)
  111. messages.success(request, _("Thread was unpinned."))
  112. move_thread_full_template = 'misago/thread/move/full.html'
  113. move_thread_modal_template = 'misago/thread/move/modal.html'
  114. def action_move(self, request, thread):
  115. form = MoveThreadForm(acl=request.user.acl, forum=self.forum)
  116. if request.method == "POST" and 'submit' in request.POST:
  117. form = MoveThreadForm(
  118. request.POST, acl=request.user.acl, forum=self.forum)
  119. if form.is_valid():
  120. new_forum = form.cleaned_data['new_forum']
  121. with atomic():
  122. moderation.move_thread(request.user, thread, new_forum)
  123. self.forum.synchronize()
  124. self.forum.save()
  125. new_forum.synchronize()
  126. new_forum.save()
  127. message = _('Thread was moved to "%(forum)s".')
  128. messages.success(request, message % {
  129. 'forum': new_forum.name
  130. })
  131. return None # trigger thread refresh
  132. if request.is_ajax():
  133. template = self.move_thread_modal_template
  134. else:
  135. template = self.move_thread_full_template
  136. return render(request, template, {
  137. 'form': form,
  138. 'forum': self.forum,
  139. 'path': get_forum_path(self.forum),
  140. 'thread': thread
  141. })
  142. def action_close(self, request, thread):
  143. moderation.close_thread(request.user, thread)
  144. messages.success(request, _("Thread was closed."))
  145. def action_open(self, request, thread):
  146. moderation.open_thread(request.user, thread)
  147. messages.success(request, _("Thread was opened."))
  148. def action_unhide(self, request, thread):
  149. moderation.unhide_thread(request.user, thread)
  150. messages.success(request, _("Thread was made visible."))
  151. def action_hide(self, request, thread):
  152. moderation.hide_thread(request.user, thread)
  153. messages.success(request, _("Thread was hid."))
  154. def action_delete(self, request, thread):
  155. moderation.delete_thread(request.user, thread)
  156. message = _('Thread "%(thread)s" was deleted.')
  157. messages.success(request, message % {'thread': thread.title})
  158. return redirect(self.forum.get_absolute_url())