participants.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. from django.contrib.auth import get_user_model
  2. from django.core.exceptions import PermissionDenied
  3. from django.utils import six
  4. from django.utils.translation import ugettext as _
  5. from django.utils.translation import ungettext
  6. from rest_framework import serializers
  7. from misago.categories import PRIVATE_THREADS_ROOT_NAME
  8. from . import PostingEndpoint, PostingMiddleware
  9. from misago.threads.participants import add_participants, set_owner
  10. from misago.threads.permissions import allow_message_user
  11. UserModel = get_user_model()
  12. class ParticipantsMiddleware(PostingMiddleware):
  13. def use_this_middleware(self):
  14. if self.mode == PostingEndpoint.START:
  15. return self.tree_name == PRIVATE_THREADS_ROOT_NAME
  16. return False
  17. def get_serializer(self):
  18. return ParticipantsSerializer(data=self.request.data, context={
  19. 'user': self.user
  20. })
  21. def save(self, serializer):
  22. set_owner(self.thread, self.user)
  23. add_participants(self.request, self.thread, serializer.users_cache)
  24. class ParticipantsSerializer(serializers.Serializer):
  25. to = serializers.ListField(
  26. child=serializers.CharField(),
  27. required=True
  28. )
  29. def validate_to(self, usernames):
  30. clean_usernames = self.clean_usernames(usernames)
  31. self.users_cache = self.get_users(clean_usernames)
  32. def clean_usernames(self, usernames):
  33. clean_usernames = []
  34. for name in usernames:
  35. clean_name = name.strip().lower()
  36. if clean_name == self.context['user'].slug:
  37. raise serializers.ValidationError(
  38. _("You can't include yourself on the list of users to invite to new thread."))
  39. if clean_name and clean_name not in clean_usernames:
  40. clean_usernames.append(clean_name)
  41. if not clean_usernames:
  42. raise serializers.ValidationError(_("You have to enter user names."))
  43. max_participants = self.context['user'].acl['max_private_thread_participants']
  44. if max_participants and len(clean_usernames) > max_participants:
  45. message = ungettext(
  46. "You can't add more than %(users)s user to private thread (you've added %(added)s).",
  47. "You can't add more than %(users)s users to private thread (you've added %(added)s).",
  48. max_participants)
  49. raise serializers.ValidationError(message % {
  50. 'users': max_participants,
  51. 'added': len(clean_usernames)
  52. })
  53. return list(set(clean_usernames))
  54. def get_users(self, usernames):
  55. users = []
  56. for user in UserModel.objects.filter(slug__in=usernames):
  57. try:
  58. allow_message_user(self.context['user'], user)
  59. except PermissionDenied as e:
  60. raise serializers.ValidationError(six.text_type(e))
  61. users.append(user)
  62. if len(usernames) != len(users):
  63. invalid_usernames = set(usernames) - set([u.slug for u in users])
  64. sorted_usernames = sorted(invalid_usernames)
  65. message = _("One or more users could not be found: %(usernames)s")
  66. raise serializers.ValidationError(
  67. message % {'usernames': ', '.join(sorted_usernames)})
  68. return users