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