75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
from typing import Dict
|
|
import logging
|
|
|
|
from actstream.actions import follow, unfollow
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.auth.models import Group
|
|
from django.db.models.signals import m2m_changed, pre_save
|
|
from django.dispatch import receiver
|
|
from django.utils.dateparse import parse_datetime
|
|
|
|
from blender_id_oauth_client import signals as bid_signals
|
|
|
|
from constants.activity import Flag
|
|
from extensions.models import Extension
|
|
from users.blender_id import BIDSession
|
|
|
|
User = get_user_model()
|
|
bid = BIDSession()
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@receiver(pre_save, sender=User)
|
|
def _record_changes(
|
|
sender: object, instance: User, update_fields: object, **kwargs: object
|
|
) -> None:
|
|
was_changed, old_state = instance.pre_save_record(update_fields=update_fields)
|
|
|
|
instance.record_status_change(was_changed, old_state, **kwargs)
|
|
|
|
|
|
@receiver(bid_signals.user_created)
|
|
def update_user(
|
|
sender: object, instance: User, oauth_info: Dict[str, str], **kwargs: object
|
|
) -> None:
|
|
"""Update a User when a new OAuth user is created.
|
|
|
|
Copy 'full_name' from the received 'oauth_info' and attempt to copy avatar from Blender ID.
|
|
"""
|
|
instance.full_name = oauth_info.get('full_name') or ''
|
|
instance.confirmed_email_at = parse_datetime(oauth_info.get('confirmed_email_at') or '')
|
|
instance.save()
|
|
|
|
bid.copy_avatar_from_blender_id(user=instance)
|
|
bid.copy_badges_from_blender_id(user=instance)
|
|
|
|
|
|
@receiver(m2m_changed, sender=User.groups.through)
|
|
def update_moderator_follows(instance, action, model, reverse, pk_set, **kwargs):
|
|
"""Users becoming moderators should follow all extensions,
|
|
and users that stop being moderators should no longer follow all extensions.
|
|
The flag=Flag.MODERATOR is used to avoid deleting follow relations that were created in contexts
|
|
other than moderator's duties.
|
|
"""
|
|
if action not in ['post_add', 'post_remove']:
|
|
return
|
|
|
|
moderators = Group.objects.get(name='moderators')
|
|
extensions = Extension.objects.all()
|
|
users = []
|
|
if model == Group and not reverse:
|
|
if moderators.pk not in pk_set:
|
|
return
|
|
users = [instance]
|
|
else:
|
|
if instance != moderators:
|
|
return
|
|
users = User.objects.filter(pk__in=pk_set)
|
|
|
|
for user in users:
|
|
for extension in extensions:
|
|
if action == 'post_remove':
|
|
unfollow(user, extension, send_action=False, flag=Flag.MODERATOR)
|
|
elif action == 'post_add':
|
|
follow(user, extension, send_action=False, flag=Flag.MODERATOR)
|