Changeset View
Changeset View
Standalone View
Standalone View
profiles/signals.py
- This file was added.
| from typing import Dict | |||||
| import logging | |||||
| from django.contrib.auth.models import User | |||||
| from django.db.models.signals import post_save | |||||
| from django.dispatch import receiver | |||||
| from blender_id_oauth_client import signals as bid_signals | |||||
| from profiles.models import Profile | |||||
| logger = logging.getLogger(__name__) | |||||
| @receiver(bid_signals.user_created) | |||||
| def fill_profile( | |||||
| sender: object, instance: User, oauth_info: Dict[str, str], **kwargs: object | |||||
| ) -> None: | |||||
| """ | |||||
| Update a Profile when a new OAuth user is created. | |||||
| Copy 'full_name' from the received 'oauth_info' and attempt to copy avatar from Blender ID. | |||||
sybren: Logging `'User pk={instance.pk} ...` will make it clear what the logged number is. Blender ID… | |||||
| """ | |||||
| if not hasattr(instance, 'profile'): | |||||
| logger.warning(f'User pk={instance.pk} is missing a profile') | |||||
Done Inline ActionsUse oauth_info.get('full_name') or '' for safety. Also put the fact that 'full_name' is used in the docstring. sybren: Use `oauth_info.get('full_name') or ''` for safety. Also put the fact that `'full_name'` is… | |||||
| return | |||||
Done Inline ActionsHow are communication errors handled here? And disk I/O errors saving the avatar? sybren: How are communication errors handled here? And disk I/O errors saving the avatar? | |||||
| instance.profile.full_name = oauth_info.get('full_name') or '' | |||||
| instance.profile.save() | |||||
| instance.profile.copy_avatar_from_blender_id() | |||||
Done Inline ActionsAdd a docstring that explains what this function is for. sybren: Add a docstring that explains what this function is for. | |||||
| @receiver(post_save, sender=User) | |||||
Done Inline Actionsif not getattr(instance, 'profile', None) will cover both the case that it just isn't there, or the hypothetical case that the property is there but set to None. sybren: `if not getattr(instance, 'profile', None)` will cover both the case that it just isn't there… | |||||
| def create_profile(sender: object, instance: User, created: bool, **kwargs: object) -> None: | |||||
| """Create a Profile record for a newly created User.""" | |||||
| if not created: | |||||
| return | |||||
| if not getattr(instance, 'profile', None): | |||||
| logger.info('Creating new Profile for user pk={instance.pk}') | |||||
| Profile.objects.create(user=instance) | |||||
Logging 'User pk={instance.pk} ... will make it clear what the logged number is. Blender ID account numbers are also numerical.