threadactions.py 7.0 KB

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