ScoDoc/app/email.py

122 lines
3.6 KiB
Python
Raw Normal View History

2021-05-29 18:22:51 +02:00
# -*- coding: UTF-8 -*
2022-03-04 20:02:50 +01:00
##############################################################################
# ScoDoc
2023-01-02 13:16:27 +01:00
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
2022-03-04 20:02:50 +01:00
# See LICENSE
##############################################################################
2021-05-29 18:22:51 +02:00
from threading import Thread
2022-03-04 20:02:50 +01:00
from flask import current_app, g
2021-05-29 18:22:51 +02:00
from flask_mail import Message
2022-03-04 20:02:50 +01:00
2021-05-29 18:22:51 +02:00
from app import mail
from app.models.departements import Departement
from app.models.config import ScoDocSiteConfig
2022-03-04 20:02:50 +01:00
from app.scodoc import sco_preferences
2021-05-29 18:22:51 +02:00
def send_async_email(app, msg):
2022-04-02 10:56:10 +02:00
"Send an email, async"
2021-05-29 18:22:51 +02:00
with app.app_context():
mail.send(msg)
2021-08-26 23:43:54 +02:00
def send_email(
2022-03-04 20:02:50 +01:00
subject: str,
sender: str,
recipients: list,
text_body: str,
html_body="",
bcc=(),
attachments=(),
2021-08-26 23:43:54 +02:00
):
"""
2022-03-04 20:02:50 +01:00
Send an email. _All_ ScoDoc mails SHOULD be sent using this function.
2021-08-26 23:43:54 +02:00
If html_body is specified, build a multipart message with HTML content,
else send a plain text email.
2022-03-04 20:02:50 +01:00
attachements: list of dict { 'filename', 'mimetype', 'data' }
2021-08-26 23:43:54 +02:00
"""
2022-03-04 20:02:50 +01:00
msg = Message(subject, sender=sender, recipients=recipients, bcc=bcc)
2021-05-29 18:22:51 +02:00
msg.body = text_body
msg.html = html_body
2022-03-04 20:02:50 +01:00
if attachments:
for attachment in attachments:
msg.attach(
attachment["filename"], attachment["mimetype"], attachment["data"]
)
2021-08-26 23:43:54 +02:00
send_message(msg)
2022-03-04 20:02:50 +01:00
def send_message(msg: Message):
"""Send a message.
All ScoDoc emails MUST be sent by this function.
In mail debug mode, addresses are discarded and all mails are sent to the
specified debugging address.
"""
email_test_mode_address = False
2022-03-04 20:02:50 +01:00
if hasattr(g, "scodoc_dept"):
# on est dans un département, on peut accéder aux préférences
email_test_mode_address = sco_preferences.get_preference(
"email_test_mode_address"
)
if email_test_mode_address:
# Mode spécial test: remplace les adresses de destination
orig_to = msg.recipients
orig_cc = msg.cc
orig_bcc = msg.bcc
msg.recipients = [email_test_mode_address]
msg.cc = None
msg.bcc = None
msg.subject = "[TEST SCODOC] " + msg.subject
msg.body = (
f"""--- Message ScoDoc dérouté pour tests ---
Adresses d'origine:
to : {orig_to}
cc : {orig_cc}
bcc: {orig_bcc}
2023-08-23 01:42:03 +02:00
---
2022-03-04 20:02:50 +01:00
\n\n"""
+ msg.body
)
current_app.logger.info(
2023-08-23 01:42:03 +02:00
f"""email sent to{
' (mode test)' if email_test_mode_address else ''
}: {msg.recipients}
from sender {msg.sender}
"""
)
2021-05-29 18:22:51 +02:00
Thread(
target=send_async_email, args=(current_app._get_current_object(), msg)
).start()
def get_from_addr(dept_acronym: str = None):
"""L'adresse "from" à utiliser pour envoyer un mail
Si le departement est spécifié, ou si l'attribut `g.scodoc_dept`existe,
2023-08-23 01:42:03 +02:00
prend le `email_from_addr` des préférences de ce département si ce champ
est non vide.
Sinon, utilise le paramètre global `email_from_addr`.
Sinon, la variable de config `SCODOC_MAIL_FROM`.
"""
dept_acronym = dept_acronym or getattr(g, "scodoc_dept", None)
if dept_acronym:
dept = Departement.query.filter_by(acronym=dept_acronym).first()
if dept:
from_addr = (
sco_preferences.get_preference("email_from_addr", dept_id=dept.id) or ""
).strip()
if from_addr:
return from_addr
return (
ScoDocSiteConfig.get("email_from_addr")
or current_app.config["SCODOC_MAIL_FROM"]
or "none"
)