# 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
)
)