123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- from django.http import Http404
- from rest_framework.response import Response
- from misago.acl import add_acl
- from misago.categories.models import CATEGORIES_TREE_ID, Category
- from misago.categories.permissions import (
- allow_see_category, allow_browse_category)
- from misago.categories.serializers import BasicCategorySerializer
- from misago.core.shortcuts import (
- get_int_or_404, get_object_or_404, paginate, pagination_dict)
- from misago.readtracker import threadstracker
- from misago.threads.mixins.threadslists import ThreadsListMixin
- 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(object):
- serialize_subcategories = True
- def get_final_queryset(self, request, categories, threads_categories,
- category, list_type):
- return self.get_queryset(request, categories, list_type).filter(
- category__in=threads_categories
- )
- def __call__(self, request):
- try:
- page = int(request.query_params.get('page', 0))
- except ValueError:
- 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)
- queryset = self.get_queryset(request, categories, list_type)
- threads_categories = [category] + subcategories
- rest_queryset = self.get_rest_queryset(
- category, queryset, threads_categories)
- page = paginate(rest_queryset, page, 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, 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)
- visible_subcategories = []
- for thread in threads:
- if (thread.top_category and
- thread.category in threads_categories and
- thread.top_category not in visible_subcategories):
- visible_subcategories.append(thread.top_category.pk)
- if self.serialize_subcategories:
- response_dict['subcategories'] = []
- for subcategory in subcategories:
- if subcategory.pk in visible_subcategories:
- response_dict['subcategories'].append(subcategory.pk)
- add_acl(request.user, threads)
- make_subscription_aware(request.user, threads)
- return Response(dict(
- results=ThreadListSerializer(threads, many=True).data,
- **response_dict))
- class ThreadsListEndpoint(ThreadsListMixin, 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:
- break
- else:
- raise Http404() # disallow root category access
- else:
- raise Http404()
- allow_see_category(request.user, category)
- allow_browse_category(request.user, category)
- return category
- else:
- return categories[0]
- def get_subcategories(self, category, categories):
- subcategories = []
- for subcategory in categories:
- if category.has_child(subcategory):
- subcategories.append(subcategory)
- return subcategories
- 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_rest_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,
- )
- def get_final_queryset(self, request, categories, threads_categories,
- category, list_type):
- queryset = self.get_queryset(request, categories, list_type)
- if category.level:
- announcements = queryset.filter(weight=2)
- pinned = queryset.filter(weight=1, category__in=threads_categories)
- other = queryset.filter(weight=1, category__in=threads_categories)
- return announcements | pinned | other
- else:
- announcements = queryset.filter(weight=2)
- other = queryset.filter(
- weight__lt=2,
- category__in=threads_categories,
- )
- return announcements | other
- threads_list_endpoint = ThreadsListEndpoint()
|