threads.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. from django.core.exceptions import PermissionDenied
  2. from django.db import transaction
  3. from django.utils.translation import gettext as _
  4. from rest_framework import viewsets
  5. from rest_framework.decorators import detail_route, list_route
  6. from rest_framework.parsers import JSONParser
  7. from rest_framework.response import Response
  8. from misago.acl import add_acl
  9. from misago.categories.models import CATEGORIES_TREE_ID, Category
  10. from misago.categories.permissions import (
  11. allow_see_category, allow_browse_category)
  12. from misago.core.shortcuts import get_int_or_404, get_object_or_404
  13. from misago.readtracker.categoriestracker import read_category
  14. from misago.readtracker.threadstracker import make_read_aware
  15. from misago.users.rest_permissions import IsAuthenticatedOrReadOnly
  16. from misago.threads.api.threadendpoints.list import threads_list_endpoint
  17. from misago.threads.api.threadendpoints.merge import threads_merge_endpoint
  18. from misago.threads.api.threadendpoints.patch import thread_patch_endpoint
  19. from misago.threads.models import Thread, Subscription
  20. from misago.threads.moderation import threads as moderation
  21. from misago.threads.permissions.threads import allow_see_thread
  22. from misago.threads.serializers import ThreadSerializer
  23. from misago.threads.subscriptions import make_subscription_aware
  24. class ThreadViewSet(viewsets.ViewSet):
  25. permission_classes = (IsAuthenticatedOrReadOnly, )
  26. parser_classes=(JSONParser, )
  27. TREE_ID = CATEGORIES_TREE_ID
  28. def validate_thread_visible(self, user, thread):
  29. allow_see_thread(user, thread)
  30. def get_thread(self, user, thread_id):
  31. thread = get_object_or_404(Thread.objects.select_related('category'),
  32. id=get_int_or_404(thread_id),
  33. category__tree_id=self.TREE_ID,
  34. )
  35. add_acl(user, thread.category)
  36. add_acl(user, thread)
  37. self.validate_thread_visible(user, thread)
  38. return thread
  39. def list(self, request):
  40. return threads_list_endpoint(request)
  41. def retrieve(self, request, pk=None):
  42. thread = self.get_thread(request.user, pk)
  43. make_read_aware(request.user, thread)
  44. make_subscription_aware(request.user, thread)
  45. return Response(ThreadSerializer(thread).data)
  46. def partial_update(self, request, pk=None):
  47. thread = self.get_thread(request.user, pk)
  48. return thread_patch_endpoint.dispatch(request, thread)
  49. def destroy(self, request, pk=None):
  50. thread = self.get_thread(request.user, pk)
  51. if thread.acl.get('can_hide') == 2:
  52. moderation.delete_thread(request.user, thread)
  53. return Response({'detail': 'ok'})
  54. else:
  55. raise PermissionDenied(
  56. _("You don't have permission to delete this thread."))
  57. @list_route(methods=['post'])
  58. def read(self, request):
  59. if request.query_params.get('category'):
  60. category_id = get_int_or_404(request.query_params.get('category'))
  61. category = get_object_or_404(Category.objects,
  62. id=category_id,
  63. tree_id=self.TREE_ID,
  64. )
  65. allow_see_category(request.user, category)
  66. allow_browse_category(request.user, category)
  67. else:
  68. category = Category.objects.root_category()
  69. read_category(request.user, category)
  70. return Response({'detail': 'ok'})
  71. @list_route(methods=['post'])
  72. def merge(self, request):
  73. return threads_merge_endpoint(request)