list.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. from django.http import Http404
  2. from rest_framework.response import Response
  3. from misago.acl import add_acl
  4. from misago.categories.models import CATEGORIES_TREE_ID, Category
  5. from misago.categories.permissions import (
  6. allow_see_category, allow_browse_category)
  7. from misago.categories.serializers import BasicCategorySerializer
  8. from misago.core.shortcuts import (
  9. get_int_or_404, get_object_or_404, paginate, pagination_dict)
  10. from misago.readtracker import threadstracker
  11. from misago.threads.mixins.threadslists import ThreadsListMixin
  12. from misago.threads.serializers import ThreadListSerializer
  13. from misago.threads.subscriptions import make_subscription_aware
  14. from misago.threads.utils import add_categories_to_threads
  15. LIST_TYPES = (
  16. 'all',
  17. 'my',
  18. 'new',
  19. 'unread',
  20. 'subscribed',
  21. )
  22. class BaseListEndpoint(object):
  23. serialize_subcategories = True
  24. def __call__(self, request):
  25. try:
  26. page = int(request.query_params.get('page', 0))
  27. except ValueError:
  28. raise Http404()
  29. list_type = request.query_params.get('list') or 'all'
  30. if list_type not in LIST_TYPES:
  31. raise Http404()
  32. category = self.get_category(request)
  33. self.allow_see_list(request, category, list_type)
  34. subcategories = self.get_subcategories(request, category)
  35. categories = [category] + subcategories
  36. queryset = self.get_queryset(
  37. request, categories, list_type).order_by('-last_post_on')
  38. page = paginate(queryset, page, 24, 6, allow_explicit_first_page=True)
  39. response_dict = pagination_dict(page, include_page_range=False)
  40. if list_type in ('new', 'unread'):
  41. """we already know all threads on list are unread"""
  42. threadstracker.make_unread(page.object_list)
  43. else:
  44. threadstracker.make_threads_read_aware(
  45. request.user, page.object_list)
  46. add_categories_to_threads(categories, page.object_list)
  47. visible_subcategories = []
  48. for thread in page.object_list:
  49. if (thread.top_category and
  50. thread.top_category not in visible_subcategories):
  51. visible_subcategories.append(thread.top_category.pk)
  52. if self.serialize_subcategories:
  53. response_dict['subcategories'] = []
  54. for subcategory in subcategories:
  55. if subcategory.pk in visible_subcategories:
  56. response_dict['subcategories'].append(subcategory.pk)
  57. add_acl(request.user, page.object_list)
  58. make_subscription_aware(request.user, page.object_list)
  59. return Response(dict(
  60. results=ThreadListSerializer(page.object_list, many=True).data,
  61. **response_dict))
  62. class ThreadsListEndpoint(ThreadsListMixin, BaseListEndpoint):
  63. def get_category(self, request):
  64. if request.query_params.get('category'):
  65. category_id = get_int_or_404(request.query_params['category'])
  66. category = get_object_or_404(
  67. Category.objects.select_related('parent'),
  68. tree_id=CATEGORIES_TREE_ID,
  69. id=category_id,
  70. )
  71. allow_see_category(request.user, category)
  72. allow_browse_category(request.user, category)
  73. return category
  74. else:
  75. return Category.objects.root_category()
  76. threads_list_endpoint = ThreadsListEndpoint()