moderation.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. from rest_framework import serializers
  2. from django.core.exceptions import PermissionDenied, ValidationError
  3. from django.utils import six
  4. from django.utils.translation import ugettext as _, ugettext_lazy, ungettext
  5. from misago.acl import add_acl
  6. from misago.conf import settings
  7. from misago.threads.models import Thread
  8. from misago.threads.permissions import allow_merge_post, can_start_thread, exclude_invisible_posts
  9. from misago.threads.validators import validate_category, validate_title
  10. POSTS_MERGE_LIMIT = settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL
  11. __all__ = [
  12. 'MergePostsSerializer',
  13. 'NewThreadSerializer',
  14. ]
  15. class MergePostsSerializer(serializers.Serializer):
  16. posts = serializers.ListField(
  17. child=serializers.IntegerField(
  18. error_messages={
  19. 'invalid': ugettext_lazy("One or more post ids received were invalid."),
  20. },
  21. ),
  22. error_messages={
  23. 'required': ugettext_lazy("You have to select at least two posts to merge."),
  24. },
  25. )
  26. def validate_posts(self, data):
  27. data = list(set(data))
  28. if len(data) < 2:
  29. raise serializers.ValidationError(_("You have to select at least two posts to merge."))
  30. if len(data) > POSTS_MERGE_LIMIT:
  31. message = ungettext(
  32. "No more than %(limit)s post can be merged at single time.",
  33. "No more than %(limit)s posts can be merged at single time.",
  34. POSTS_MERGE_LIMIT,
  35. )
  36. raise serializers.ValidationError(message % {'limit': POSTS_MERGE_LIMIT})
  37. user = self.context['user']
  38. thread = self.context['thread']
  39. posts_queryset = exclude_invisible_posts(user, thread.category, thread.post_set)
  40. posts_queryset = posts_queryset.filter(id__in=data).order_by('id')
  41. posts = []
  42. for post in posts_queryset:
  43. post.category = thread.category
  44. post.thread = thread
  45. try:
  46. allow_merge_post(user, post)
  47. except PermissionDenied as e:
  48. raise serializers.ValidationError(six.text_type(e))
  49. if not posts:
  50. posts.append(post)
  51. else:
  52. authorship_error = _("Posts made by different users can't be merged.")
  53. if posts[0].poster_id:
  54. if post.poster_id != posts[0].poster_id:
  55. raise serializers.ValidationError(authorship_error)
  56. else:
  57. if post.poster_id or post.poster_name != posts[0].poster_name:
  58. raise serializers.ValidationError(authorship_error)
  59. if posts[0].pk != thread.first_post_id:
  60. if (posts[0].is_hidden != post.is_hidden or
  61. posts[0].is_unapproved != post.is_unapproved):
  62. raise serializers.ValidationError(_("Posts with different visibility can't be merged."))
  63. posts.append(post)
  64. if len(posts) != len(data):
  65. raise serializers.ValidationError(_("One or more posts to merge could not be found."))
  66. self.posts_cache = posts
  67. return data
  68. class NewThreadSerializer(serializers.Serializer):
  69. title = serializers.CharField()
  70. category = serializers.IntegerField()
  71. weight = serializers.IntegerField(
  72. required=False,
  73. allow_null=True,
  74. max_value=Thread.WEIGHT_GLOBAL,
  75. min_value=Thread.WEIGHT_DEFAULT,
  76. )
  77. is_hidden = serializers.NullBooleanField(required=False)
  78. is_closed = serializers.NullBooleanField(required=False)
  79. def validate_title(self, title):
  80. return validate_title(title)
  81. def validate_category(self, category_id):
  82. self.category = validate_category(self.context, category_id)
  83. if not can_start_thread(self.context, self.category):
  84. raise ValidationError(_("You can't create new threads in selected category."))
  85. return self.category
  86. def validate_weight(self, weight):
  87. try:
  88. add_acl(self.context, self.category)
  89. except AttributeError:
  90. return weight # don't validate weight further if category failed
  91. if weight > self.category.acl.get('can_pin_threads', 0):
  92. if weight == 2:
  93. raise ValidationError(
  94. _("You don't have permission to pin threads globally in this category.")
  95. )
  96. else:
  97. raise ValidationError(
  98. _("You don't have permission to pin threads in this category.")
  99. )
  100. return weight
  101. def validate_is_hidden(self, is_hidden):
  102. try:
  103. add_acl(self.context, self.category)
  104. except AttributeError:
  105. return is_hidden # don't validate hidden further if category failed
  106. if is_hidden and not self.category.acl.get('can_hide_threads'):
  107. raise ValidationError(_("You don't have permission to hide threads in this category."))
  108. return is_hidden
  109. def validate_is_closed(self, is_closed):
  110. try:
  111. add_acl(self.context, self.category)
  112. except AttributeError:
  113. return is_closed # don't validate closed further if category failed
  114. if is_closed and not self.category.acl.get('can_close_threads'):
  115. raise ValidationError(
  116. _("You don't have permission to close threads in this category.")
  117. )
  118. return is_closed