123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- from django.http import Http404
- from rest_framework.response import Response
- from misago.acl import add_acl
- from misago.categories.models import Category
- from misago.categories.permissions import allow_see_category, allow_browse_category
- from misago.core.shortcuts import get_int_or_404, paginate, pagination_dict
- from misago.readtracker import threadstracker
- from misago.threads.mixins.threadslist import ThreadsListMixin
- from misago.threads.permissions.privatethreads import allow_use_private_threads
- from misago.threads.serializers import ThreadListSerializer
- from misago.threads.subscriptions import make_subscription_aware
- from misago.threads.utils import add_categories_to_threads
- LIST_TYPES = (
- 'all',
- 'my',
- 'new',
- 'unread',
- 'subscribed',
- 'unapproved',
- )
- class BaseListEndpoint(ThreadsListMixin):
- serialize_subcategories = True
- def __call__(self, request):
- try:
- page_no = int(request.query_params.get('page', 0))
- except (ValueError, TypeError):
- raise Http404()
- list_type = request.query_params.get('list') or 'all'
- if list_type not in LIST_TYPES:
- raise Http404()
- categories = self.get_categories(request)
- category = self.get_category(request, categories)
- self.allow_see_list(request, category, list_type)
- subcategories = self.get_subcategories(category, categories)
- base_queryset = self.get_base_queryset(request, categories, list_type)
- threads_categories = [category] + subcategories
- threads_queryset = self.get_threads_queryset(category, base_queryset, threads_categories)
- page = paginate(threads_queryset, page_no, 24, 6, allow_explicit_first_page=True)
- response_dict = pagination_dict(page, include_page_range=False)
- if page.number > 1:
- threads = list(page.object_list)
- else:
- pinned_threads = self.get_pinned_threads(category, base_queryset, threads_categories)
- threads = list(pinned_threads) + list(page.object_list)
- if list_type in ('new', 'unread'):
- # we already know all threads on list are unread
- threadstracker.make_unread(threads)
- else:
- threadstracker.make_threads_read_aware(request.user, threads)
- add_categories_to_threads(category, categories, threads)
- if self.serialize_subcategories:
- response_dict['subcategories'] = []
- visible_subcategories = self.get_visible_subcategories(threads, threads_categories)
- for subcategory in subcategories:
- if subcategory in visible_subcategories:
- response_dict['subcategories'].append(subcategory.pk)
- add_acl(request.user, threads)
- make_subscription_aware(request.user, threads)
- response_dict['results'] = ThreadListSerializer(threads, many=True).data
- return Response(response_dict)
- class ThreadsListEndpoint(BaseListEndpoint):
- def get_category(self, request, categories):
- if request.query_params.get('category'):
- category_id = get_int_or_404(request.query_params['category'])
- for category in categories:
- if category.pk == category_id:
- if category.level:
- allow_see_category(request.user, category)
- allow_browse_category(request.user, category)
- return category
- else:
- raise Http404() # disallow root category access
- raise Http404()
- return categories[0]
- def get_pinned_threads(self, category, queryset, threads_categories):
- if category.level:
- return list(queryset.filter(weight=2)) + list(queryset.filter(
- weight=1,
- category__in=threads_categories
- ))
- else:
- return queryset.filter(weight=2)
- def get_threads_queryset(self, category, queryset, threads_categories):
- if category.level:
- return queryset.filter(
- weight=0,
- category__in=threads_categories,
- )
- else:
- return queryset.filter(
- weight__lt=2,
- category__in=threads_categories,
- )
- threads_list_endpoint = ThreadsListEndpoint()
- class PrivateThreadsListEndpoint(BaseListEndpoint):
- def get_category(self, request, categories):
- allow_use_private_threads(request.user)
- return Category.objects.private_threads()
- def get_subcategories(self, category, categories):
- return []
- def get_pinned_threads(self, category, queryset, threads_categories):
- return []
- def get_threads_queryset(self, category, queryset, threads_categories):
- return queryset.filter(category__in=threads_categories)
- private_threads_list_endpoint = PrivateThreadsListEndpoint()
|