threadslist.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. from django.conf import settings
  2. from django.core.exceptions import PermissionDenied
  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 as _, ugettext_lazy
  7. from misago.categories.models import CATEGORIES_TREE_ID, Category
  8. from misago.categories.permissions import (
  9. allow_see_category, allow_browse_category)
  10. from misago.core.shortcuts import (
  11. get_object_or_404, paginate, pagination_dict, validate_slug)
  12. from misago.readtracker import threadstracker
  13. from misago.threads.models import Thread
  14. from misago.threads.permissions import exclude_invisible_threads
  15. from misago.threads.utils import add_categories_to_threads
  16. LISTS_NAMES = {
  17. 'my': ugettext_lazy("Your threads"),
  18. 'new': ugettext_lazy("New threads"),
  19. 'unread': ugettext_lazy("Unread threads"),
  20. 'subscribed': ugettext_lazy("subscribed threads"),
  21. }
  22. def get_threads_queryset(user, categories, list_type):
  23. queryset = Thread.objects.all()
  24. return exclude_invisible_threads(user, categories, queryset)
  25. class BaseList(View):
  26. template_name = 'misago/threadslist/threads.html'
  27. preloaded_data_prefix = ''
  28. def allow_see_list(self, request, category, list_type):
  29. if request.user.is_anonymous():
  30. if list_type == 'my':
  31. raise PermissionDenied( _("You have to sign in to see list of "
  32. "threads that you have started."))
  33. if list_type == 'new':
  34. raise PermissionDenied(_("You have to sign in to see list of "
  35. "threads you haven't read."))
  36. if list_type == 'unread':
  37. raise PermissionDenied(_("You have to sign in to see list of "
  38. "threads with new replies."))
  39. if list_type == 'subscribed':
  40. raise PermissionDenied(_("You have to sign in to see list of "
  41. "threads you are subscribing."))
  42. def get_category(self, request, **kwargs):
  43. return Category.objects.root_category()
  44. def get_queryset(self, request, categories, list_type):
  45. return get_threads_queryset(request.user, categories, list_type)
  46. def get_subcategories(self, request, category):
  47. if category.is_leaf_node():
  48. return []
  49. visible_categories = request.user.acl['visible_categories']
  50. queryset = category.get_descendants().filter(id__in=visible_categories)
  51. return list(queryset.order_by('lft'))
  52. def get_extra_context(self, request, category, subcategories, list_type):
  53. return {}
  54. def get(self, request, **kwargs):
  55. try:
  56. page = int(request.GET.get('page', 0))
  57. if page == 1:
  58. page = None
  59. except ValueError:
  60. raise Http404()
  61. list_type = kwargs['list_type']
  62. category = self.get_category(request, **kwargs)
  63. self.allow_see_list(request, category, list_type)
  64. subcategories = self.get_subcategories(request, category)
  65. categories = [category] + subcategories
  66. queryset = self.get_queryset(request, categories, list_type)
  67. page = paginate(queryset, page, 24, 6)
  68. paginator = pagination_dict(page)
  69. threadstracker.make_threads_read_aware(request.user, page.object_list)
  70. add_categories_to_threads(categories, page.object_list)
  71. visible_subcategories = []
  72. for thread in page.object_list:
  73. if (thread.top_category and
  74. thread.top_category not in visible_subcategories):
  75. visible_subcategories.append(thread.top_category.pk)
  76. category.subcategories = []
  77. for subcategory in subcategories:
  78. if subcategory.pk in visible_subcategories:
  79. category.subcategories.append(subcategory)
  80. extra_context = self.get_extra_context(
  81. request, category, subcategories, list_type)
  82. show_toolbar = False
  83. if paginator['count']:
  84. if category.subcategories:
  85. show_toolbar = True
  86. if request.user.is_authenticated():
  87. show_toolbar = True
  88. return render(request, self.template_name, dict(
  89. category=category,
  90. show_toolbar=show_toolbar,
  91. list_type=list_type,
  92. list_name=LISTS_NAMES.get(list_type),
  93. threads=page.object_list,
  94. paginator=paginator,
  95. count=paginator['count'],
  96. **extra_context
  97. ))
  98. class ThreadsList(BaseList):
  99. template_name = 'misago/threadslist/threads.html'
  100. def get_extra_context(self, request, category, subcategories, list_type):
  101. return {
  102. 'is_index': not settings.MISAGO_CATEGORIES_ON_INDEX
  103. }
  104. class CategoryThreadsList(ThreadsList):
  105. template_name = 'misago/threadslist/category.html'
  106. preloaded_data_prefix = 'CATEGORY_'
  107. def get_category(self, request, **kwargs):
  108. category = get_object_or_404(Category.objects.select_related('parent'),
  109. tree_id=CATEGORIES_TREE_ID,
  110. id=kwargs['category_id'],
  111. )
  112. allow_see_category(request.user, category)
  113. allow_browse_category(request.user, category)
  114. validate_slug(category, kwargs['category_slug'])
  115. return category
  116. class PrivateThreadsList(ThreadsList):
  117. template_name = 'misago/threadslist/private_threads.html'
  118. preloaded_data_prefix = 'PRIVATE_'
  119. def get_category(self, request, **kwargs):
  120. return Category.objects.private_threads()
  121. def get_subcategories(self, request, category):
  122. return []