diff --git a/castellum/appointments/management/commands/send_appointment_reminders.py b/castellum/appointments/management/commands/send_appointment_reminders.py index eac18375f44d64a0af399091c79ca7efd0b1904e..e1ded801c8368f34ef40c76ea625b15326771aa1 100644 --- a/castellum/appointments/management/commands/send_appointment_reminders.py +++ b/castellum/appointments/management/commands/send_appointment_reminders.py @@ -46,7 +46,7 @@ def send_mail_to_subject(ctx, study, appointment): ) -def send_mail_to_study_conductors(study, not_reachable, base_url): +def send_mail_to_study_conductors(study, not_reachable, base_url, ctx): urls = '\n'.join( base_url + reverse( 'execution:participation-detail', @@ -54,16 +54,15 @@ def send_mail_to_study_conductors(study, not_reachable, base_url): ) for appointment in not_reachable ) - with MailContext('internal') as ctx: - return ctx.send_mail( - settings.CASTELLUM_APPOINTMENT_NO_EMAIL_MAIL_SUBJECT.format(study=study), - ( - lambda: {'urls': urls}, - settings.CASTELLUM_APPOINTMENT_NO_EMAIL_MAIL_BODY, - settings.CASTELLUM_APPOINTMENT_NO_EMAIL_MAIL_BODY_EN, - ), - [user.email for user in study.conductors], - ) + return ctx.send_mail( + settings.CASTELLUM_APPOINTMENT_NO_EMAIL_MAIL_SUBJECT.format(study=study), + ( + lambda: {'urls': urls}, + settings.CASTELLUM_APPOINTMENT_NO_EMAIL_MAIL_BODY, + settings.CASTELLUM_APPOINTMENT_NO_EMAIL_MAIL_BODY_EN, + ), + [user.email for user in study.conductors], + ) def send_appointment_reminders(base_url): @@ -71,17 +70,17 @@ def send_appointment_reminders(base_url): reached_count = 0 not_reached_count = 0 - for study in Study.objects.filter(status=Study.EXECUTION): - due_appointments = Appointment.objects.filter( - start__gte=now, - start__lte=now + settings.CASTELLUM_APPOINTMENT_REMINDER_PERIOD, - reminded=False, - session__study=study, - participation__status=Participation.INVITED, - ).select_related('participation__subject') - not_reachable = [] - - with MailContext('recruitment') as ctx: + with MailContext('recruitment') as ctx: + for study in Study.objects.filter(status=Study.EXECUTION): + due_appointments = Appointment.objects.filter( + start__gte=now, + start__lte=now + settings.CASTELLUM_APPOINTMENT_REMINDER_PERIOD, + reminded=False, + session__study=study, + participation__status=Participation.INVITED, + ).select_related('participation__subject') + not_reachable = [] + for appointment in due_appointments: success = send_mail_to_subject(ctx, study, appointment) if success: @@ -90,10 +89,11 @@ def send_appointment_reminders(base_url): not_reached_count += 1 not_reachable.append(appointment) - if not_reachable: - send_mail_to_study_conductors(study, not_reachable, base_url) + if not_reachable: + with MailContext('internal', ctx.connection) as internal_ctx: + send_mail_to_study_conductors(study, not_reachable, base_url, internal_ctx) - due_appointments.update(reminded=True) + due_appointments.update(reminded=True) return reached_count, not_reached_count diff --git a/castellum/utils/mail.py b/castellum/utils/mail.py index 11c5f6df208539c0bad865e665e81f4b8e040117..d4be6ce9dd6a286046027cd15dbf12c999bd7219 100644 --- a/castellum/utils/mail.py +++ b/castellum/utils/mail.py @@ -41,8 +41,9 @@ def render_body_with_fallback(get_mail_data, text, fallback=None, lang=None): class MailContext: - def __init__(self, name=None): - self.connection = None + def __init__(self, name=None, connection=None): + self.connection = connection + self.close_connection = False self.data = { 'from_email': settings.DEFAULT_FROM_EMAIL, 'language': settings.LANGUAGE_CODE, @@ -57,6 +58,7 @@ class MailContext: def __enter__(self): if not self.connection: self.connection = get_connection(**self.data['connection']) + self.close_connection = True try: self.connection.open() except Exception: @@ -66,7 +68,8 @@ class MailContext: return self def __exit__(self, type, value, traceback): - self.connection.close() + if self.close_connection: + self.connection.close() self.connection = None def prepare_body(self, body, recipients_string=''):