list.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. from itertools import chain
  2. from django.core.urlresolvers import reverse
  3. from django.http import Http404
  4. from django.shortcuts import redirect
  5. from django.utils.translation import ugettext as _
  6. from misago import messages
  7. from misago.acl.exceptions import ACLError403, ACLError404
  8. from misago.apps.errors import error403, error404
  9. from misago.apps.threadtype.list import ThreadsListBaseView, ThreadsListModeration
  10. from misago.conf import settings
  11. from misago.decorators import check_csrf
  12. from misago.models import Forum, Thread, ThreadPrefix
  13. from misago.readstrackers import ThreadsTracker
  14. from misago.utils.pagination import make_pagination
  15. from misago.apps.threads.mixins import TypeMixin
  16. class ThreadsListView(ThreadsListBaseView, ThreadsListModeration, TypeMixin):
  17. def fetch_forum(self):
  18. self.forum = Forum.objects.get(pk=self.kwargs.get('forum'), type='forum')
  19. self.prefixes = ThreadPrefix.objects.forum_prefixes(self.forum)
  20. self.active_prefix = self.kwargs.get('prefix', None)
  21. if self.active_prefix:
  22. for prefix in self.prefixes.values():
  23. if self.active_prefix == prefix.slug:
  24. self.active_prefix = prefix
  25. break
  26. else:
  27. raise ACLError404()
  28. def template_vars(self, context):
  29. context['prefixes'] = self.prefixes
  30. context['active_prefix'] = self.active_prefix
  31. return context
  32. def threads_queryset(self):
  33. announcements = self.request.acl.threads.filter_threads(self.request, self.forum, self.forum.thread_set).filter(weight=2).order_by('-pk')
  34. threads = self.request.acl.threads.filter_threads(self.request, self.forum, self.forum.thread_set).filter(weight__lt=2).order_by('-weight', '-last')
  35. if self.active_prefix:
  36. threads = threads.filter(prefix=self.active_prefix)
  37. # Dont display threads by ignored users (unless they are important)
  38. if self.request.user.is_authenticated():
  39. ignored_users = self.request.user.ignored_users()
  40. if ignored_users:
  41. threads = threads.exclude(start_poster_id__in=ignored_users)
  42. # Add in first and last poster
  43. if settings.avatars_on_threads_list:
  44. announcements = announcements.prefetch_related('start_poster', 'last_poster')
  45. threads = threads.prefetch_related('start_poster', 'last_poster')
  46. return announcements, threads
  47. def fetch_threads(self):
  48. qs_announcements, qs_threads = self.threads_queryset()
  49. self.count = qs_threads.count()
  50. try:
  51. self.pagination = make_pagination(self.kwargs.get('page', 0), self.count, settings.threads_per_page)
  52. except Http404:
  53. return self.threads_list_redirect()
  54. tracker_forum = ThreadsTracker(self.request, self.forum)
  55. for thread in list(chain(qs_announcements, qs_threads[self.pagination['start']:self.pagination['stop']])):
  56. thread.is_read = tracker_forum.is_read(thread)
  57. self.threads.append(thread)
  58. def threads_actions(self):
  59. acl = self.request.acl.threads.get_role(self.forum)
  60. actions = []
  61. try:
  62. if acl['can_approve']:
  63. actions.append(('accept', _('Accept threads')))
  64. if acl['can_change_prefixes']:
  65. actions.append(('prefix:0', _('Remove prefix')))
  66. for prefix in self.prefixes.values():
  67. actions.append(('prefix:%s' % prefix.pk, _('Change prefix to: %(prefix)s') % {'prefix': _(prefix.name)}))
  68. if acl['can_pin_threads'] == 2:
  69. actions.append(('annouce', _('Change to announcements')))
  70. if acl['can_pin_threads'] > 0:
  71. actions.append(('sticky', _('Change to sticky threads')))
  72. if acl['can_pin_threads'] > 0:
  73. actions.append(('normal', _('Change to standard thread')))
  74. if acl['can_move_threads_posts']:
  75. actions.append(('move', _('Move threads')))
  76. actions.append(('merge', _('Merge threads')))
  77. if acl['can_close_threads']:
  78. actions.append(('open', _('Open threads')))
  79. actions.append(('close', _('Close threads')))
  80. if acl['can_delete_threads']:
  81. actions.append(('undelete', _('Restore threads')))
  82. actions.append(('soft', _('Hide threads')))
  83. if acl['can_delete_threads'] == 2:
  84. actions.append(('hard', _('Delete threads')))
  85. except KeyError:
  86. pass
  87. return actions
  88. def action_prefix(self, ids, prefix):
  89. prefixes = self.prefixes
  90. try:
  91. prefix = int(prefix)
  92. except TypeError:
  93. prefix = 0
  94. prefix = prefix or None
  95. if prefix:
  96. if self._action_set_prefix(ids, prefixes[prefix]):
  97. messages.success(self.request, _('Selected threads prefix has been changed to "%(name)s".') % {'name': _(prefixes[prefix].name)}, 'threads')
  98. else:
  99. messages.info(self.request, _('No threads prefix was changed.'), 'threads')
  100. else:
  101. if self._action_remove_prefix(ids):
  102. messages.success(self.request, _('Selected threads prefix has been removed.'), 'threads')
  103. else:
  104. messages.info(self.request, _('No threads prefixes were removed.'), 'threads')
  105. def _action_set_prefix(self, ids, prefix):
  106. changed = []
  107. for thread in self.threads:
  108. if thread.pk in ids and prefix.pk != thread.prefix_id:
  109. changed.append(thread.pk)
  110. thread.prefix = prefix
  111. thread.set_checkpoint(self.request, 'changed_prefix', self.request.user, self.forum, extra=prefix.name)
  112. thread.save(force_update=True)
  113. return changed
  114. def _action_remove_prefix(self, ids):
  115. changed = []
  116. for thread in self.threads:
  117. if thread.pk in ids and not thread.prefix_id:
  118. changed.append(thread.pk)
  119. thread.prefix_id = None
  120. thread.set_checkpoint(self.request, 'removed_prefix', self.request.user, self.forum)
  121. thread.save(force_update=True)
  122. return changed