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