avertissement_mails-perdus.py 7.11 KB
Newer Older
1
#! /usr/bin/env python
2
# -*- coding: utf-8 -*-
3

4
# Pour envoyer effectivement des mails, il faut désactiver le debug
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
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)
    

22 23 24
# 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é
25 26 27 28 29 30 31 32 33 34 35
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"

36 37
# 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
38
# le message "too many hops"
39
# On a donc créé le fichier mails_perdus avec la commande suivante :
40
# 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
41
# Le fichier se présente alors sous la forme :
42 43 44
# Mois Jour Heure <emetteur@adresse.mail> -> <recepteur@adresse.mail.2>
file = open('/home/salles/mails_perdus',"r")

45
# On crée les 2 dictionnaire qui vont contenir les 2 types d'avertissemnts à
46
# communiquer :
47
# - les messages envoyés par des adhérents au serveur mais qui ne sont pas 
48 49
#partis vers leur destinataire
unsend = {}
50
# - les messages reçus par le serveur mais non distribués aux adhérents
51 52 53
unreceived = {}

def is_crans(mail) :
54
    """ Détermine si l'adresse mail concerne un adhérent"""
55 56 57 58 59 60 61 62 63
    # 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) :
64
    """ Définit une méthode pour ajouter un mail perdu dans l'un des
65
dictionnaires.
66 67
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']
68 69
"""
    if not dict.has_key(chain) :
70
        # Si la clé n'existe pas : initialisation
71 72
        dict[chain] = [ [value, date] ]
    else :
73
        # Sinon on ajoute le nouveau mail perdu à la liste existante
74 75 76 77 78 79 80
        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()
81
    # Il pourrait y avoir plusieurs expéditeurs pour le même mail
82
    senders = datas[3].split(",")
83
    # Il peut y avoir plusieurs destinataires pour un mail (ça c'est sur)
84 85 86 87 88 89 90 91 92 93 94 95 96 97
    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])

98
    # Pour chaque couple de mail perdu associé à une source et un destinataire
99 100 101 102 103 104 105 106 107 108 109 110 111
    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)

112
    # On passe à la ligne suivante
113 114 115 116 117
    line = file.readline()

file.close()


118 119
# On traite le formatage des mails pour indiquer aux adhérents les
# mails qui ne leur ont pas été délivrés
120 121 122 123 124 125 126 127
for adh in unreceived.keys() :
    text = u"""From: CRANS (Nounous) <nounous@crans.org>
To: %s
Subject: [CRANS] Dysfonctionnement du serveur de mail
Content-Type: text/plain; charset="iso-8859-15"

Bonjour,

128 129 130 131
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.
132

133
Tu trouveras ci-dessous le détail des messages que tu n'as pas pu
134 135
recevoir et/ou envoyer.\n""" % adh
    for unrecv in unreceived[adh] :
136
        text += u""" - mail non reçu : envoyé par %s avant le %s\n""" % (unrecv[0], unrecv[1])
137 138
    text += u"""Nous te conseillons de contacter les personnes qui figurent dans
cette liste si tu souhaites recevoir leur message, car elles n'ont
139
pas été informé de cette erreur de livraison.
140
"""
141
# Au passage, on vérifie s'il n'y a pas des mails que l'adhérents auraient
142 143 144 145 146
# voulu envoyer qui se seraient aussi perdus
    if unsend.has_key(adh) :
        text += u"""
"""
        for unsnd in unsend[adh] :
147
            text += u""" - mail non envoyé : adressé à %s le %s\n""" % (unsnd[0], unsnd[1])
148
            
149 150 151
        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.
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
"""

    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

    
170 171
# Le message est légèrement différent dans le cas où l'adhérent n'a perdu
# des mails qu'à l'envoi.
172 173 174 175 176 177 178 179 180
for adh in unsend.keys() :
    if not unreceived.has_key(adh) :
        text = u"""From: CRANS (Nounous) <nounous@crans.org>
To: %s
Subject: [CRANS] Dysfonctionnement du serveur de mail
Content-Type: text/plain; charset="iso-8859-15"

Bonjour,

181
Nous t'informons que suite à une erreur sur le serveur de mail
182
de l'association, il est fort probable que nous n'ayons pas pu
183 184
transmettre certains de tes messages dans la période allant du
lundi 10/09/2007 23h00 à ce mardi 11/09/2007 9h50.
185

186
Tu trouveras ci-dessous le détail des messages que nous n'avons
187 188 189
pas pu envoyer.\n""" % adh

        for unsnd in unsend[adh] :
190
            text += u""" - mail non envoyé : adressé à %s le %s\n""" % (unsnd[0], unsnd[1])
191

192 193 194
        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.
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
"""

        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

210