You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
6.7 KiB
Python

#!/usr/bin/python3
# -*- mode: python; coding: utf-8 -*-
"""
Script générique pour envoyer des mails en masse ~~au crans~~ à Aurore après un
(petit) fork
"""
import os
import sys
import django
import argparse
from base64 import b64decode
import json
from cprint import cprint
try:
import mail
except ImportError:
cprint("Vérifie bien d'avoir tous les paquets (par exemple python3-jinja2)", "rouge")
def mail_sender(template, From, recipients, PREV=True, SEND=False, cc=None, bcc=None):
"""
``template`` template du mail à envoyer.
``From`` Pour remplir le champ From du mail.
``recipients`` Liste des addresses mails recipiendaires.
``PREV`` Booléen specifiant s'il faut faire un dry-run avec prévisualisation.
Default = True.
``SEND`` Booléen spécifiant s'il faut effectivement envoyer le mail.
Default = False.
``cc`` Liste des addresses mails en copie.
``bcc`` Liste des addresses mails en copie cachée.
"""
echecs = []
if PREV:
print("Envoi simulé")
try:
print("{} destinataires (Ctrl + C pour annuler l'envoi)".format(len(recipients)))
input("Envoyer ? (Ret pour envoyer)\n")
except KeyboardInterrupt:
cprint("\nEnvoi annulé.", "rouge")
sys.exit(1)
with mail.ServerConnection() as conn_smtp:
for line in recipients:
extra_params = {}
if len(line.split(';')) == 3:
# Format Prénom Nom Email
Prenom, Nom, To = line.split(':')
elif len(line.split(';')) == 2:
# Format Prénom Email
Nom, Prenom, To = '', line.split(';')
elif len(line.split(';')) == 1:
# Juste un email
Prenom, Nom, To = '', '', line
else:
# Format Prénom Nom Email ExtraJson
Prenom, Nom, To, extra = line.split(';')
extra_params = json.loads(extra)
print("Envoi du mail à {}".format(To))
try:
params = {'To' : To,
'From' : From,
'lang_info' : 'English version below',
'Prenom' : Prenom,
'Nom': Nom,
}
params.update(extra_params)
mailtxt = mail.generate(
template,
params).as_bytes()
except KeyError: # Il faut corriger le fichier source pour que ça marche
cprint("Félicitation tu viens de tomber sur un bug python (cf {})".format(
"https://bugs.python.org/issue27321"),
"rouge")
raise
if PREV:
print(mailtxt)
try:
if SEND:
conn_smtp.sendmail(From, (To,), mailtxt)
print(" Envoyé !")
else:
print(" Simulé !")
except:
print(sys.exc_info()[:2])
cprint("Erreur lors de l'envoi à {} ".format(To), "rouge")
echecs.append(To)
if not SEND:
cprint("\n\
/!\ Avant d'envoyer réellement ce mail all, as-tu vérifié que:\n\
- Les lignes sont bien formatées à 75-80 caractères ?\n\
- Le texte a été lu et relu ?\n\
- Il existe une version en anglais ?\n\
- Les destinataires sont bien les bons ?\n\
- Il y a bien une signature ?\n",
'rouge'
)
if echecs:
print("\nIl y a eu des erreurs pour les addresses suivantes :")
for echec in echecs:
print(" - {}\n".format(echec))
sys.exit(1)
RE2O = '/var/www/re2o'
if __name__=="__main__":
if not RE2O in sys.path:
sys.path.append(RE2O)
try:
import re2o
except ImportError:
print("Nécessite une instance re2o")
sys.exit(42)
# Setup l'environnement django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 're2o.settings')
django.setup()
parser = argparse.ArgumentParser(
description="Mail all générique. Prend un template en argument.",
add_help=True
)
parser.add_argument(
"-f", "--recipientfile",
help="Un fichier contenant un destinataire par ligne. Les formats acceptés sont : `Prenom:Nom:Email`, `Prenom:Email`, ou tout simplement `Email`. Override tous les filtres. Dans le premier cas, on peut aussi rajouter des paramètres supplémentaires sous format json.",
action="store"
)
parser.add_argument(
"-t", "--template",
help="Un template de mail. Fournir le chemin du dossier principal du mail, relatif à "
+ mail.template_path,
action="store"
)
parser.add_argument(
"-s", "--sender",
help="Spécifier un expéditeur particulier. Par défaut no-reply@auro.re",
action="store",
default="no-reply@auro.re"
)
filtres = parser.add_argument_group('Filtres')
filtres.add_argument(
"-a", "--allaccess",
help="Envoie un mail à toutes les personnes bénéficiant d'une connexion valide.",
action="store_true"
)
filtres.add_argument(
"-A", "--alladh",
help="Envoie un mail à tous les adhérents.",
action="store_true"
)
exclusive = parser.add_mutually_exclusive_group(required=True)
exclusive.add_argument(
"--doit",
help="Lance effectivement le mail",
action="store_true"
)
exclusive.add_argument(
"-p", "--prev",
help="Prévisualise le mail à envoyer",
action="store_true"
)
args = parser.parse_args()
if args.recipientfile:
with open(args.recipientfile, 'r') as recipientfile:
recipients = recipientfile.readlines()
else:
if args.allaccess:
print("{} du mail à toutes les personnes bénéficiant d'une connexion valide (Ctrl + C pour annuler l'envoi)".format("Simulation" if args.prev else "Envoi"))
input("Envoyer ? (Ret pour envoyer)\n")
users = re2o.utils.all_has_access()
elif args.alladh:
print("{} du mail à tous les adhérents (Ctrl + C pour annuler l'envoi)".format("Simulation" if args.prev else "Envoi"))
input("Envoyer ? (Ret pour envoyer)\n")
users = re2o.utils.all_adherent()
else:
print("Spécifier au moins un destinataire")
sys.exit(2)
recipients = ['{}:{}:{}'.format(user.name,
user.surname,
user.get_mail)
for user in users]
mail_sender(args.template, args.sender, recipients, args.prev, args.doit)
sys.exit(0)