threads.py 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. from django.db import transaction
  2. from rest_framework import viewsets
  3. from rest_framework.decorators import detail_route, list_route
  4. from rest_framework.parsers import JSONParser
  5. from rest_framework.response import Response
  6. from misago.acl import add_acl
  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 get_int_or_404, get_object_or_404
  11. from misago.readtracker.categoriestracker import read_category
  12. from misago.users.rest_permissions import IsAuthenticatedOrReadOnly
  13. from misago.threads.api.threadendpoints.list import threads_list_endpoint
  14. from misago.threads.models import Thread, Subscription
  15. from misago.threads.permissions.threads import allow_see_thread
  16. from misago.threads.serializers import ThreadSerializer
  17. from misago.threads.subscriptions import make_subscription_aware
  18. class ThreadViewSet(viewsets.ViewSet):
  19. permission_classes = (IsAuthenticatedOrReadOnly, )
  20. parser_classes=(JSONParser, )
  21. TREE_ID = CATEGORIES_TREE_ID
  22. def validate_thread_visible(self, user, thread):
  23. allow_see_thread(user, thread)
  24. def get_thread(self, user, thread_id):
  25. thread = get_object_or_404(Thread.objects.select_related('category'),
  26. id=get_int_or_404(thread_id),
  27. category__tree_id=self.TREE_ID,
  28. )
  29. add_acl(user, thread.category)
  30. add_acl(user, thread)
  31. self.validate_thread_visible(user, thread)
  32. return thread
  33. def list(self, request):
  34. return threads_list_endpoint(request)
  35. def retrieve(self, request, pk=None):
  36. thread = self.get_thread(request.user, pk)
  37. make_subscription_aware(request.user, thread)
  38. return Response(ThreadSerializer(thread).data)
  39. @list_route(methods=['post'])
  40. def read(self, request):
  41. if request.query_params.get('category'):
  42. category_id = get_int_or_404(request.query_params.get('category'))
  43. category = get_object_or_404(Category.objects,
  44. id=category_id,
  45. tree_id=self.TREE_ID,
  46. )
  47. allow_see_category(request.user, category)
  48. allow_browse_category(request.user, category)
  49. else:
  50. category = Category.objects.root_category()
  51. read_category(request.user, category)
  52. return Response({'detail': 'ok'})
  53. @detail_route(methods=['post'])
  54. def subscribe(self, request, pk=None):
  55. thread = self.get_thread(request.user, pk)
  56. with transaction.atomic():
  57. request.user.subscription_set.filter(thread=thread).delete()
  58. if request.data.get('notify'):
  59. request.user.subscription_set.create(
  60. thread=thread,
  61. category=thread.category,
  62. last_read_on=thread.last_post_on,
  63. send_email=False,
  64. )
  65. elif request.data.get('email'):
  66. request.user.subscription_set.create(
  67. thread=thread,
  68. category=thread.category,
  69. last_read_on=thread.last_post_on,
  70. send_email=True,
  71. )
  72. return Response({
  73. 'detail': 'ok',
  74. })