threadslist.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. from django.conf import settings
  2. from django.core.urlresolvers import reverse
  3. from django.http import Http404
  4. from django.shortcuts import render
  5. from django.views.generic import View
  6. from django.utils.translation import ugettext_lazy
  7. from misago.acl import add_acl
  8. from misago.categories.models import CATEGORIES_TREE_ID, Category
  9. from misago.categories.permissions import (
  10. allow_see_category, allow_browse_category)
  11. from misago.categories.serializers import (
  12. BasicCategorySerializer, CategorySerializer)
  13. from misago.core.shortcuts import (
  14. get_object_or_404, paginate, pagination_dict, validate_slug)
  15. from misago.readtracker import threadstracker
  16. from misago.threads.serializers import ThreadSerializer
  17. from misago.threads.mixins.threadslists import ThreadsListMixin
  18. from misago.threads.utils import add_categories_to_threads
  19. LISTS_NAMES = {
  20. 'my': ugettext_lazy("Your threads"),
  21. 'new': ugettext_lazy("New threads"),
  22. 'unread': ugettext_lazy("Unread threads"),
  23. 'subscribed': ugettext_lazy("Subscribed threads"),
  24. }
  25. class BaseList(View):
  26. template_name = 'misago/threadslist/threads.html'
  27. preloaded_data_prefix = ''
  28. def get_extra_context(self, request, category, subcategories, list_type):
  29. return {}
  30. def set_extra_frontend_context(self, request, category, subcategories,
  31. list_type):
  32. pass
  33. def get(self, request, **kwargs):
  34. try:
  35. page = int(request.GET.get('page', 0))
  36. if page == 1:
  37. page = None
  38. except ValueError:
  39. raise Http404()
  40. list_type = kwargs['list_type']
  41. category = self.get_category(request, **kwargs)
  42. self.allow_see_list(request, category, list_type)
  43. subcategories = self.get_subcategories(request, category)
  44. categories = [category] + subcategories
  45. queryset = self.get_queryset(
  46. request, categories, list_type).order_by('-last_post_on')
  47. page = paginate(queryset, page, 24, 6)
  48. paginator = pagination_dict(page, include_page_range=False)
  49. if list_type in ('new', 'unread'):
  50. """we already know all threads on list are unread"""
  51. threadstracker.make_unread(page.object_list)
  52. else:
  53. threadstracker.make_threads_read_aware(
  54. request.user, page.object_list)
  55. add_categories_to_threads(categories, page.object_list)
  56. visible_subcategories = []
  57. for thread in page.object_list:
  58. if (thread.top_category and
  59. thread.top_category not in visible_subcategories):
  60. visible_subcategories.append(thread.top_category.pk)
  61. category.subcategories = []
  62. for subcategory in subcategories:
  63. if subcategory.pk in visible_subcategories:
  64. category.subcategories.append(subcategory)
  65. extra_context = self.get_extra_context(
  66. request, category, subcategories, list_type)
  67. show_toolbar = False
  68. if paginator['count']:
  69. if category.subcategories:
  70. show_toolbar = True
  71. if request.user.is_authenticated():
  72. show_toolbar = True
  73. add_acl(request.user, page.object_list)
  74. request.frontend_context.update({
  75. 'THREADS': dict(
  76. results=ThreadSerializer(page.object_list, many=True).data,
  77. subcategories=BasicCategorySerializer(
  78. category.subcategories, many=True).data,
  79. **paginator),
  80. 'CATEGORIES': CategorySerializer(categories, many=True).data,
  81. })
  82. if category.special_role:
  83. request.frontend_context['CATEGORIES'][0]['special_role'] = True
  84. self.set_frontend_context(request, category, subcategories, list_type)
  85. return render(request, self.template_name, dict(
  86. category=category,
  87. show_toolbar=show_toolbar,
  88. list_type=list_type,
  89. list_name=LISTS_NAMES.get(list_type),
  90. threads=page.object_list,
  91. paginator=paginator,
  92. count=paginator['count'],
  93. **extra_context
  94. ))
  95. class ThreadsList(BaseList, ThreadsListMixin):
  96. template_name = 'misago/threadslist/threads.html'
  97. def get_category(self, request, **kwargs):
  98. return Category.objects.root_category()
  99. def get_extra_context(self, request, category, subcategories, list_type):
  100. return {
  101. 'is_index': not settings.MISAGO_CATEGORIES_ON_INDEX
  102. }
  103. def set_frontend_context(self, request, category, subcategories, list_type):
  104. request.frontend_context.update({
  105. 'THREADS_API_URL': reverse('misago:api:thread-list'),
  106. })
  107. class CategoryThreadsList(ThreadsList, ThreadsListMixin):
  108. template_name = 'misago/threadslist/category.html'
  109. preloaded_data_prefix = 'CATEGORY_'
  110. def get_category(self, request, **kwargs):
  111. category = get_object_or_404(Category.objects.select_related('parent'),
  112. tree_id=CATEGORIES_TREE_ID,
  113. id=kwargs['category_id'],
  114. )
  115. allow_see_category(request.user, category)
  116. allow_browse_category(request.user, category)
  117. validate_slug(category, kwargs['category_slug'])
  118. return category
  119. class PrivateThreadsList(ThreadsList):
  120. template_name = 'misago/threadslist/private_threads.html'
  121. preloaded_data_prefix = 'PRIVATE_'
  122. def get_category(self, request, **kwargs):
  123. return Category.objects.private_threads()
  124. def get_subcategories(self, request, category):
  125. return []