Source code for eucrim.users.profile_management

# SPDX-FileCopyrightText: 2024 Thomas Breitner <t.breitner@csl.mpg.de>
#
# SPDX-License-Identifier: EUPL-1.2

"""
This module handles the creation or update of ProfilePages for user instances
and notifications in various cases.
"""

import logging
from django.utils.text import slugify
from django.utils.crypto import get_random_string


# Get an instance of a logger
logger = logging.getLogger(__name__)


# def disable_submitted_notifications(instance):
#     """
#     Todo: Code not working:
#     RelatedObjectDoesNotExist at /admin/users/add/
#     CustomUser has no wagtail_userprofile.
#     Perhaps better to try to set de default value for ``submitted_notifications``
#     to ``False``.
#     """
#     try:
#         instance.wagtail_userprofile.update(submitted_notifications=False)
#         instance.wagtail_userprofile.save()
#     except ObjectDoesNotExist:
#         logger.warning(
#             '[eucrim] instance "{}" does not have a "wagtail_userprofile" - not '
#             'able to set submitted_notifications to False'.format(  # noqa: E501
#                 instance
#             )
#         )


[docs] def create_profile_page(instance): """ Adding a new ProfilePage for a given user. """ from eucrim.profile.models import ProfilePage, ProfileIndexPage from eucrim.core.models import HomePage # check if a ProfileIndexPage exists if ProfileIndexPage.objects.exists(): profile_index_page = ProfileIndexPage.objects.first() else: profile_index_page = ProfileIndexPage( title="Authors", slug="authors", show_in_menus=True, ) home_page = HomePage.objects.first() home_page.add_child(instance=profile_index_page) profile_index_page.save_revision().publish() # when adding a superuser via `createsuperuser`, there must be a # first_name and a last_name if instance.is_superuser: instance.last_name = "fixme-lastname-{}".format(get_random_string(length=8)) instance.first_name = "fixme-firstname-{}".format(get_random_string(length=8)) # fill profile page with data from user model profile_page = ProfilePage( user=instance, owner=instance, title=instance.last_name, slug=slugify(f"{instance.last_name}-{instance.first_name}"), first_name=instance.first_name, last_name=instance.last_name, email=instance.email, is_author=instance.is_author, is_team=instance.is_team, team_role=instance.team_role, ) # saving our ProfilePage instance as a child page of # our profile_index_page profile_index_page.add_child(instance=profile_page) profile_page.save() profile_page.unpublish() # This notification email is disabled in favour of the article-published # author email. # notify user about new profile page via email: # send_email(recipient_list=[instance.email], user=instance, page=profile_page, mail_template='profile_created') logger.warning( '[eucrim] profile page "{}" created'.format( # noqa: E501 profile_page ) )
[docs] def update_profile_page(instance, profile_page, set_user=False): """ Only update an existing ProfilePage with ``is_author`` and ``is_team`` attributes. """ profile_page.is_author = instance.is_author profile_page.is_team = instance.is_team profile_page.team_role = instance.team_role profile_page.is_association_manager = instance.is_association_manager if set_user: profile_page.user = set_user profile_page.owner = instance profile_page.title = instance.last_name profile_page.email = instance.email profile_page.save() logger.info( '[eucrim] profile page "{}" updated'.format( # noqa: E501 profile_page ) )
[docs] def modify_profile_page(instance, user_state_action, fields_changed): if instance.is_team or instance.is_author: from eucrim.profile.models import ProfilePage # check if a ProfilePage for this user instance already exists profile_exists = False matched_by_user = False try: profile_page = ProfilePage.objects.get(user=instance) update_profile_page(instance, profile_page) profile_exists = True matched_by_user = True print( '[eucrim] profile page "{}" matched by user "{}"'.format( # noqa: E501 profile_page, instance, ) ) except ProfilePage.DoesNotExist: pass if not matched_by_user: try: # We had some caseses where ProfilePage instances were added manually # and the profile_page.user attribute was not set. So we do a second # check against the slug. proposed_slug = slugify(f"{instance.last_name}-{instance.first_name}") profile_page = ProfilePage.objects.get(slug=proposed_slug) update_profile_page(instance, profile_page, set_user=instance) profile_exists = True print( '[eucrim] user "{}" matched profile page {} by slug {} '.format( # noqa: E501 instance, profile_page, proposed_slug, ) ) except ProfilePage.DoesNotExist: pass if not profile_exists: # print("* this profile does NOT exist, creating one") create_profile_page(instance)
[docs] def notify_association_manager(instance, user_state_action, fields_changed): """ Notify new association managers via email. Only send email if user with 'is_association_manager' is added or existing user gets 'is_association_manager'. """ from ..core.utils import send_email if (user_state_action == "created" and instance.is_association_manager) or ( "is_association_manager", True, ) in fields_changed.items(): from eucrim.association.models import AssociationIndexPage association_index_page = AssociationIndexPage.objects.first() send_email( recipient_list=[instance.email], user=instance, page=association_index_page, mail_template="association_manager", ) logger.warning( '[eucrim] user "{}" configured as an association manager, sent email notification to "{}"'.format( # noqa: E501 instance, instance.email, ) )
[docs] def user_tasks(instance, user_state_action, fields_changed): """ Modifying the ProfilePage for a given user. Creating a new ProfilePage or modifying an existing ProfilePage. Notifies if given user is an AssociationManager. """ # if instance.is_superuser: # # be sure to do nothing here when dealing with a superuser # return # only triggered for assocation managers: notify_association_manager(instance, user_state_action, fields_changed) # only triggered for team or author members: modify_profile_page(instance, user_state_action, fields_changed) if user_state_action == "created": # we're disableing this notification setting per default # commented out, does not work, see func statement above # print("Trying to disable submitted notification setting...") # print(dir(instance.wagtail_userprofile)) # disable_submitted_notifications(instance) pass elif user_state_action == "modified": pass else: logger.error( '[eucrim] user "{}" NOT modified or created (user_state_action: "{}") - this should never happen!'.format( # noqa: E501 instance, user_state_action ) )