threadslists.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. from django.core.urlresolvers import reverse
  2. from django.db.models import Q
  3. from django.shortcuts import redirect
  4. from django.utils.translation import ugettext_lazy, ugettext as _
  5. from misago.core.shortcuts import paginate
  6. from misago.forums.lists import get_forums_list, get_forum_path
  7. from misago.threads.posting import (PostingInterrupt, EditorFormset,
  8. START, REPLY, EDIT)
  9. from misago.threads.models import ANNOUNCEMENT, Thread
  10. from misago.threads.views.generic.base import ViewBase
  11. __all__ = ['OrderThreadsMixin', 'ThreadsView', 'ForumView']
  12. class OrderThreadsMixin(object):
  13. order_by = (
  14. ('recently-replied', ugettext_lazy("Recently replied")),
  15. ('last-replied', ugettext_lazy("Last replied")),
  16. ('most-replied', ugettext_lazy("Most replied")),
  17. ('least-replied', ugettext_lazy("Least replied")),
  18. ('newest', ugettext_lazy("Newest")),
  19. ('oldest', ugettext_lazy("Oldest")),
  20. )
  21. def get_ordering(self, kwargs):
  22. if kwargs.get('sort') in [o[0] for o in self.order_by]:
  23. return kwargs.get('sort')
  24. else:
  25. return self.order_by[0][0]
  26. def is_ordering_default(self, order_by):
  27. return self.order_by[0][0] == order_by
  28. def get_ordering_name(self, order_by):
  29. for ordering in self.order_by:
  30. if ordering[0] == order_by:
  31. return ordering[1]
  32. def get_orderings_dicts(self, exclude_ordering, links_params):
  33. url_kwargs = links_params.copy()
  34. dicts = []
  35. for ordering in self.order_by:
  36. if not dicts:
  37. url_kwargs.pop('sort', None)
  38. else:
  39. url_kwargs['sort'] = ordering[0]
  40. if ordering[0] != exclude_ordering:
  41. dicts.append({
  42. 'url': reverse(self.link_name, kwargs=url_kwargs),
  43. 'name': ordering[1],
  44. })
  45. return dicts
  46. class ThreadsView(ViewBase):
  47. def get_threads(self, request, kwargs):
  48. queryset = self.get_threads_queryset(request, forum)
  49. threads_qs = queryset.filter(weight__lt=ANNOUNCEMENT)
  50. threads_qs = threads_qs.order_by('-weight', '-last_post_id')
  51. page = paginate(threads_qs, kwargs.get('page', 0), 30, 10)
  52. threads = []
  53. for announcement in queryset.filter(weight=ANNOUNCEMENT):
  54. threads.append(announcement)
  55. for thread in page.object_list:
  56. threads.append(thread)
  57. for thread in threads:
  58. thread.forum = forum
  59. return page, threads
  60. def get_threads_queryset(self, request):
  61. return forum.thread_set.all().order_by('-last_post_id')
  62. def add_threads_reads(self, request, threads):
  63. for thread in threads:
  64. thread.is_new = False
  65. import random
  66. for thread in threads:
  67. thread.is_new = random.choice((True, False))
  68. class ForumView(OrderThreadsMixin, ThreadsView):
  69. """
  70. Basic view for threads lists
  71. """
  72. template = 'misago/threads/list.html'
  73. def get_threads(self, request, forum, kwargs, order_by=None, limit=None):
  74. queryset = self.get_threads_queryset(request, forum)
  75. queryset = self.filter_all_querysets(request, forum, queryset)
  76. announcements_qs = queryset.filter(weight=ANNOUNCEMENT)
  77. threads_qs = queryset.filter(weight__lt=ANNOUNCEMENT)
  78. announcements_qs = self.filter_announcements_queryset(
  79. request, forum, announcements_qs)
  80. threads_qs = self.filter_threads_queryset(request, forum, threads_qs)
  81. threads_qs, announcements_qs = self.order_querysets(
  82. order_by, threads_qs, announcements_qs)
  83. page = paginate(threads_qs, kwargs.get('page', 0), 20, 10)
  84. threads = []
  85. for announcement in announcements_qs:
  86. threads.append(announcement)
  87. for thread in page.object_list:
  88. threads.append(thread)
  89. for thread in threads:
  90. thread.forum = forum
  91. return page, threads
  92. def order_querysets(self, order_by, threads, announcements):
  93. if order_by == 'recently-replied':
  94. threads = threads.order_by('-weight', '-last_post')
  95. announcements = announcements.order_by('-last_post')
  96. if order_by == 'last-replied':
  97. threads = threads.order_by('weight', 'last_post')
  98. announcements = announcements.order_by('last_post')
  99. if order_by == 'most-replied':
  100. threads = threads.order_by('-weight', '-replies')
  101. announcements = announcements.order_by('-replies')
  102. if order_by == 'least-replied':
  103. threads = threads.order_by('weight', 'replies')
  104. announcements = announcements.order_by('replies')
  105. if order_by == 'newest':
  106. threads = threads.order_by('-weight', '-id')
  107. announcements = announcements.order_by('-id')
  108. if order_by == 'oldest':
  109. threads = threads.order_by('weight', 'id')
  110. announcements = announcements.order_by('id')
  111. return threads, announcements
  112. def filter_all_querysets(self, request, forum, queryset):
  113. if request.user.is_authenticated():
  114. condition_author = Q(starter_id=request.user.id)
  115. can_mod = forum.acl['can_review_moderated_content']
  116. can_hide = forum.acl['can_hide_threads']
  117. if not can_mod and not can_hide:
  118. condition = Q(is_moderated=False) & Q(is_hidden=False)
  119. queryset = queryset.filter(condition_author | condition)
  120. elif not can_mod:
  121. condition = Q(is_moderated=False)
  122. queryset = queryset.filter(condition_author | condition)
  123. elif not can_hide:
  124. condition = Q(is_hidden=False)
  125. queryset = queryset.filter(condition_author | condition)
  126. else:
  127. if not forum.acl['can_review_moderated_content']:
  128. queryset = queryset.filter(is_moderated=False)
  129. if not forum.acl['can_hide_threads']:
  130. queryset = queryset.filter(is_hidden=False)
  131. return queryset
  132. def filter_threads_queryset(self, request, forum, queryset):
  133. if forum.acl['can_see_own_threads']:
  134. if request.user.is_authenticated():
  135. queryset = queryset.filter(starter_id=request.user.id)
  136. else:
  137. queryset = queryset.filter(starter_id=0)
  138. return queryset
  139. def filter_announcements_queryset(self, request, forum, queryset):
  140. return queryset
  141. def get_threads_queryset(self, request, forum):
  142. return forum.thread_set.all().order_by('-last_post_id')
  143. def get_default_link_params(self, forum):
  144. message = "forum views have to define get_default_link_params"
  145. raise NotImplementedError()
  146. def dispatch(self, request, *args, **kwargs):
  147. forum = self.get_forum(request, **kwargs)
  148. links_params = self.get_default_link_params(forum)
  149. if forum.lft + 1 < forum.rght:
  150. forum.subforums = get_forums_list(request.user, forum)
  151. else:
  152. forum.subforums = []
  153. order_by = self.get_ordering(kwargs)
  154. if self.is_ordering_default(kwargs.get('sort')):
  155. kwargs.pop('sort')
  156. return redirect('misago:forum', **kwargs)
  157. elif not self.is_ordering_default(order_by):
  158. links_params['sort'] = order_by
  159. page, threads = self.get_threads(request, forum, kwargs, order_by)
  160. self.add_threads_reads(request, threads)
  161. return self.render(request, {
  162. 'forum': forum,
  163. 'path': get_forum_path(forum),
  164. 'page': page,
  165. 'paginator': page.paginator,
  166. 'threads': threads,
  167. 'link_name': self.link_name,
  168. 'links_params': links_params,
  169. 'order_name': self.get_ordering_name(order_by),
  170. 'order_by': self.get_orderings_dicts(order_by, links_params),
  171. })