#! /usr/bin/env python # -*- encoding: iso-8859-15 -*- # Envoi d'un mail donné à certains adherents # Premier parametre : critere de recherche # Second parametre, fichier à envoyer import smtplib import sys,os import ldap_crans import time import socket from email_tools import format_sender POSTFIX_CONF = "/etc/postfix/main.cf" LIMIT_CONF = "smtpd_client_message_rate_limit = 10\n" def reload_postfix(): os.system("/etc/init.d/postfix reload") def reconf_postfix(): # Est-ce qu'on est sur rouge ?! if socket.gethostname() != "rouge": print u"Il y a trop de destinataires, il faut se logger sur rouge pour lever\n(temporairement) la limite." sys.exit(1) conf_fd = open (POSTFIX_CONF, 'r') lines = conf_fd.readlines() nlines = [] conf_fd.close() # On regarde s'il y a la limite dans le fichier de conf de postfix limit="no" for line in lines: if line == LIMIT_CONF: nlines+=u"## mail_all.py a commenté la ligne suivante" nlines+="# smtpd_client_message_rate_limit = 10\n" limit="yes" else: nlines+=line if limit == "no": print u"Fatal! Il n'y a pas l'air d'y avoir de limite dans le fichier de conf de\npostfix" sys.exit(1) if limit == "yes": # Si oui, on demande à l'utilisateur si on y touche negatif = ["N", "n", ""] positif = ["O", "o", "Y", "y"] poursuivre = "x" while not (poursuivre in negatif + positif): poursuivre = raw_input("Il y a trop de destinataires, il faut réécrire la conf de postfix [o/N] ") if poursuivre in negatif: print "Ok, on ne touche pas au fichier..." sys.exit(0) assert (poursuivre in positif) # On réécrit la conf try: nconf_fd = open (POSTFIX_CONF, "w") print u"Réécriture de la configuration de postfix" nconf_fd.writelines(nlines) nconf_fd.close () except IOError: print u"Je n'arrive pas à réécrire la conf de postfix, es-tu root ?" sys.exit(1) reload_postfix() return(limit,lines) if __name__ == "__main__": if len(sys.argv) != 3: print """Usage: Ce script permet d'envoyer un mail à toute une catégorie d'adhérents. Le premier paramètre est le critère de recherche : paiement=ok pour les adhérents en règle paiement=ok&paiement!=2004 pour ceux qui n'ont pas encore payé pour cette année chbre=????&paiement=ok pour ceux dont la chambre est inconnue paiement=ok&carteEtudiant!=2004 pour ceux qui n'ont pas de carte d'étudiant Le second paramètre est un fichier texte qui contient le message à envoyer. Il doit également contenir les entêtes, à l'exception du destinataire qui sera rajouté par le script. /!\ Ce script ne demande aucune confirmation, il faut veiller à vérifier avec who que l'on cible bien les utilisateurs que l'on veut. Et si on veut vérifier que le mail a une bonne tête on se l'envoie d'abord en mettant login=machin comme critère de recherche. /!\ Ce script a pour but de spammer, et spammer c'est mal. Il faut donc contourner les limitations qui ont été mises en place au Cr@ns. Si plus de 10 mails doivent être envoyés, il faut le faire depuis rouge, et ce en root. """ sys.exit(0) # On en est là # On ouvre la base et on cherche adherents = ldap_crans.crans_ldap().search(sys.argv[1])['adherent'] card= len(adherents) print "%d adhérent(s) a/ont été trouvé(s)..." % card time.sleep(3) # On dort un peu, ctrl-c welcome limit="no" if card >= 10: (limit, backup_conf) = reconf_postfix() # Il faudra quoiqu'il arrive rétablir la conf de postfix # try capture-t-il les SIGTERM ?! try: try: texte = "".join(file(sys.argv[2], "r").readlines()) except IOError: print "Impossible d'ouvrir le fichier à envoyer, merci, au revoir." sys.exit(1) echecs = [] s = smtplib.SMTP() s.connect('smtp.crans.org') for adherent in adherents: mail = adherent.mail().encode("iso-8859-15", "ignore") if "@" not in mail: mail = mail + "@crans.org" print "Envoi du mail à %s <%s>..." % (adherent.Nom().encode("iso-8859-15","ignore"), mail) try: recipient = format_sender(u'"%s" <%s>\n' % (adherent.Nom(), mail)) s.sendmail('bulk+%s@crans.org' % mail.replace("@",'-at-'), (mail,), "To: %s\n%s" % (recipient, texte)) except: print "Erreur lors de l'envoi à %s <%s>..." % (adherent.Nom().encode("iso-8859-15","ignore"), mail) echecs.append(mail) else: # Tout va bien pass if echecs: print "\nIl y a eu des erreurs :" print echecs s.close() # On rétablit la conf de postfix finally: if limit == "yes": try: conf_fd= open (POSTFIX_CONF, "w") print u"Restauration de la configuration de postfix" conf_fd.writelines (backup_conf) conf_fd.close() reload_postfix() except IOError: print "Could not rewrite postfix conf..." sys.exit(1)