#! /usr/bin/env python # -*- coding: iso-8859-15 -*- # Pour envoyer effectivement des mails, il faut désactiver le debug debug = 1 import os,sys import smtplib # Le smtp est assez capricieux for i in range(5): try: mail = smtplib.SMTP('localhost') except: sleep(5) if i == 4: print "Impossible de se connecter au SMTP" sys.exit(1) # On définit ici une liste d'adresse mail qui ne sont pas à prévenir # à utiliser par exemple si on a commencé à prévenir des adhérents mais que # tous ne l'ont pas été try : exempts = [] file = open('/home/salles/mails_envoyes',"r") line = file.readline() while line : exempts.append(line.strip()) line = file.readline() file.close() except : print "Aucune exemption d'adresses mails ne sera prise en compte" # On définit ici la liste des mails perdus et qui sont inscrits dans les logs # Dans le cas du 11/09/2007, les mails perdus étaient identifiables avec # le message "too many hops" # On a donc créé le fichier mails_perdus avec la commande suivante : # cat /var/log/mail.log | grep "too many hops" | grep '(!) FWD via SMTP' | awk -F ' ' '{print $1 " " $2 " " $3 " " $11 " " $12 " " $13}' | tr \[:upper:\] \[:lower:\] | sed 's/,$//g' > mails_perdus # Le fichier se présente alors sous la forme : # Mois Jour Heure -> file = open('/home/salles/mails_perdus',"r") # On crée les 2 dictionnaire qui vont contenir les 2 types d'avertissemnts à # communiquer : # - les messages envoyés par des adhérents au serveur mais qui ne sont pas #partis vers leur destinataire unsend = {} # - les messages reçus par le serveur mais non distribués aux adhérents unreceived = {} def is_crans(mail) : """ Détermine si l'adresse mail concerne un adhérent""" # Je remarque que les adresses de clubs et de mailings-listes ne sont # pas pris en compte @lists.crans. if mail.find('@crans.') > 0 : return 1 else : return 0 def append(dict, chain, value, date) : """ Définit une méthode pour ajouter un mail perdu dans l'un des dictionnaires. Les dictionnaires ont pour clés l'adresse mail d'un adhérent aux quelles sont associés une liste des mails perdus sur la forme ['adresse_mail2', 'date'] """ if not dict.has_key(chain) : # Si la clé n'existe pas : initialisation dict[chain] = [ [value, date] ] else : # Sinon on ajoute le nouveau mail perdu à la liste existante dict[chain].append([value, date]) # On traite maintenant la liste des mails perdus line = file.readline() # Pour chaque mail perdu while line: datas = line.split() # Il pourrait y avoir plusieurs expéditeurs pour le même mail senders = datas[3].split(",") # Il peut y avoir plusieurs destinataires pour un mail (ça c'est sur) receivers = datas[5].split(",") # On tente d'enlever les adresses nulles de ces 2 listes try : senders.remove(u'<>') except : pass try : receivers.remove(u'<>') except : pass # On reformate le champ date en inversant Jour et Mois date = u"%s %s %s" % (datas[1], datas[0], datas[2]) # Pour chaque couple de mail perdu associé à une source et un destinataire for sender in senders : for receiver in receivers : # L'expediteur et le receveur sont du crans ? if is_crans(sender) and is_crans(receiver) : append(unsend, sender, receiver, date) append(unreceived, receiver, sender, date) # L'expediteur est du crans ? if is_crans(sender) and not is_crans(receiver) : append(unsend, sender, receiver, date) # Le receveur est du crans ? if is_crans(receiver) and not is_crans(sender) : append(unreceived, receiver, sender, date) # On passe à la ligne suivante line = file.readline() file.close() # On traite le formatage des mails pour indiquer aux adhérents les # mails qui ne leur ont pas été délivrés for adh in unreceived.keys() : text = u"""From: CRANS (Nounous) To: %s Subject: [CRANS] Dysfonctionnement du serveur de mail Content-Type: text/plain; charset="iso-8859-15" Bonjour, Nous t'informons que suite à une erreur sur le serveur de mail de l'association, il est fort probable que nous ayons égaré des messages te concernant dans la période allant du lundi 10/09/2007 23h00 à ce mardi 11/09/2007 9h50. Tu trouveras ci-dessous le détail des messages que tu n'as pas pu recevoir et/ou envoyer.\n""" % adh for unrecv in unreceived[adh] : text += u""" - mail non reçu : envoyé par %s avant le %s\n""" % (unrecv[0], unrecv[1]) text += u"""Nous te conseillons de contacter les personnes qui figurent dans cette liste si tu souhaites recevoir leur message, car elles n'ont pas été informé de cette erreur de livraison. """ # Au passage, on vérifie s'il n'y a pas des mails que l'adhérents auraient # voulu envoyer qui se seraient aussi perdus if unsend.has_key(adh) : text += u""" """ for unsnd in unsend[adh] : text += u""" - mail non envoyé : adressé à %s le %s\n""" % (unsnd[0], unsnd[1]) text += u"""Pour les mails que tu as pu essayé d'envoyer, et si ce n'est pas déjà le cas, il te faut les réexpédier si tu souhaites que tes destinataires les reçoivent. """ text += u""" -- Les nounous du CRANS""" text = text.encode('iso-8859-15') if debug : print text else : if adh not in exempts : # On essaie d'envoyer le mail car on peut rencontrer des spams # dans le lot des mails perdus try : mail.sendmail('nounous@crans.org', adh, text) except : pass # Le message est légèrement différent dans le cas où l'adhérent n'a perdu # des mails qu'à l'envoi. for adh in unsend.keys() : if not unreceived.has_key(adh) : text = u"""From: CRANS (Nounous) To: %s Subject: [CRANS] Dysfonctionnement du serveur de mail Content-Type: text/plain; charset="iso-8859-15" Bonjour, Nous t'informons que suite à une erreur sur le serveur de mail de l'association, il est fort probable que nous n'ayons pas pu transmettre certains de tes messages dans la période allant du lundi 10/09/2007 23h00 à ce mardi 11/09/2007 9h50. Tu trouveras ci-dessous le détail des messages que nous n'avons pas pu envoyer.\n""" % adh for unsnd in unsend[adh] : text += u""" - mail non envoyé : adressé à %s le %s\n""" % (unsnd[0], unsnd[1]) text += u"""Pour les mails que tu as pu essayé d'envoyer, et si ce n'est pas déjà le cas, il te faut les réexpédier si tu souhaites que tes destinataires les reçoivent. """ text += u""" -- Les nounous du CRANS""" text = text.encode('iso-8859-15') if debug : print text else: if adh not in exempts : try : mail.sendmail('nounous@crans.org', adh, text) except : pass