participants.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. from django.contrib.auth import get_user_model
  2. from django.utils.translation import ugettext as _
  3. from misago.core import deprecations
  4. from misago.core.mail import build_mail, send_messages
  5. from .events import record_event
  6. from .models import ThreadParticipant
  7. def has_participants(thread):
  8. return thread.threadparticipant_set.exists()
  9. def make_participants_aware(user, thread):
  10. thread.participants_list = []
  11. thread.participant = None
  12. participants_qs = ThreadParticipant.objects.filter(thread=thread)
  13. participants_qs = participants_qs.select_related('user')
  14. for participant in participants_qs.order_by('-is_owner', 'user__slug'):
  15. participant.thread = thread
  16. thread.participants_list.append(participant)
  17. if participant.user == user:
  18. thread.participant = participant
  19. return thread.participants_list
  20. def set_users_unread_private_threads_sync(
  21. users=None, participants=None, exclude_user=None):
  22. users_ids = []
  23. if users:
  24. users_ids += [u.pk for u in users]
  25. if participants:
  26. users_ids += [p.user_id for p in participants]
  27. if exclude_user:
  28. users_ids = filter(lambda u: u != exclude_user.pk, users_ids)
  29. if not users_ids:
  30. return
  31. User = get_user_model()
  32. User.objects.filter(id__in=set(users_ids)).update(
  33. sync_unread_private_threads=True
  34. )
  35. def set_owner(thread, user):
  36. """
  37. Set user as thread's owner
  38. """
  39. ThreadParticipant.objects.set_owner(thread, user)
  40. def change_owner(request, thread, user):
  41. """
  42. Replace thread's owner with other
  43. """
  44. ThreadParticipant.objects.set_owner(thread, user)
  45. set_users_unread_private_threads_sync(
  46. participants=thread.participants_list,
  47. exclude_user=request.user
  48. )
  49. if thread.participant and thread.participant.is_owner:
  50. record_event(request, thread, 'changed_owner', {
  51. 'user': {
  52. 'username': user.username,
  53. 'url': user.get_absolute_url(),
  54. }
  55. })
  56. else:
  57. record_event(request, thread, 'tookover')
  58. def add_participant(request, thread, user):
  59. """
  60. Adds single participant to thread, registers this on the event
  61. """
  62. add_participants(request, thread, [user])
  63. if request.user == user:
  64. record_event(request, thread, 'entered_thread')
  65. else:
  66. record_event(request, thread, 'added_participant', {
  67. 'user': {
  68. 'username': user.username,
  69. 'url': user.get_absolute_url(),
  70. }
  71. })
  72. def add_participants(request, thread, users):
  73. """
  74. Add multiple participants to thread, set "recound private threads" flag on them
  75. notify them about being added to thread
  76. """
  77. ThreadParticipant.objects.add_participants(thread, users)
  78. try:
  79. thread_participants = thread.participants_list
  80. except AttributeError:
  81. thread_participants = []
  82. set_users_unread_private_threads_sync(
  83. users=users,
  84. participants=thread_participants,
  85. exclude_user=request.user
  86. )
  87. emails = []
  88. for user in users:
  89. if user != request.user:
  90. emails.append(build_noticiation_email(request, thread, user))
  91. if emails:
  92. send_messages(emails)
  93. def build_noticiation_email(request, thread, user):
  94. subject = _('%(user)s has invited you to participate in private thread "%(thread)s"')
  95. subject_formats = {
  96. 'thread': thread.title,
  97. 'user': request.user.username
  98. }
  99. return build_mail(
  100. request,
  101. user,
  102. subject % subject_formats,
  103. 'misago/emails/privatethread/added',
  104. {
  105. 'thread': thread
  106. }
  107. )
  108. def remove_participant(request, thread, user):
  109. """
  110. Remove thread participant, set "recound private threads" flag on user
  111. """
  112. removed_owner = False
  113. remaining_participants = []
  114. for participant in thread.participants_list:
  115. if participant.user == user:
  116. removed_owner = participant.is_owner
  117. else:
  118. remaining_participants.append(participant.user)
  119. set_users_unread_private_threads_sync(participants=thread.participants_list)
  120. if not remaining_participants:
  121. thread.delete()
  122. else:
  123. thread.threadparticipant_set.filter(user=user).delete()
  124. if removed_owner:
  125. thread.is_closed = True # flag thread to close
  126. if request.user == user:
  127. event_type = 'owner_left'
  128. else:
  129. event_type = 'removed_owner'
  130. else:
  131. if request.user == user:
  132. event_type = 'participant_left'
  133. else:
  134. event_type = 'removed_participant'
  135. record_event(request, thread, event_type, {
  136. 'user': {
  137. 'username': user.username,
  138. 'url': user.get_absolute_url(),
  139. }
  140. })