Commit 018f2d59 authored by glondu's avatar glondu

Factorisation. Preparation de l'envoi des mails.

darcs-hash:20060507164909-68412-59836281afda0c54b73d318d9318e071a0b52246.gz
parent 89d16d3e
......@@ -2,7 +2,7 @@
# -*- coding: iso-8859-15 -*-
"""
Repre les comptes inactifs en parsant les logs de derniere connexion
Repre les comptes inactifs en parsant les logs de dernire connexion
de sshd et dovecot.
"""
......@@ -13,19 +13,37 @@ de sshd et dovecot.
import sys, os, sre, time, cPickle
from time import mktime, time, localtime, strptime, strftime
from socket import gethostname
from smtplib import SMTP
host = gethostname()
mail_address = u'disconnect@crans.org'
mail_sender = u"Comptes inactifs <disconnect@crans.org>"
template_path = '/usr/scripts/templates/comptes_inactifs.%d'
sys.path.append('/usr/scripts/gestion')
from affich_tools import tableau
from email_tools import send_email
from email_tools import send_email, parse_mail_template
from ldap_crans import crans_ldap
from config import ann_scol
db = crans_ldap()
def nb_mails_non_lus(login):
"""
Renvoie le nombre de mails non lus de login, ou None si impossible
dterminer.
"""
try:
maildir = '/var/mail/%s/new' % login
if os.path.isdir(maildir):
return len(os.listdir(maildir))
else:
return 0
except:
# Arrive quand le script n'a pas les bons droits pour lire /var/mail
return None
class ComptesInactifs:
re = sre.compile(r'^(\w+\s+\d+\s+\d+:\d+:\d+).*(?:'
r'dovecot.*Login: user=<|'
......@@ -49,7 +67,7 @@ class ComptesInactifs:
f.write('%s %d\n' % (host, os.getpid()))
f.close()
# A partir de la, on a le lock
# partir de l, on a le lock
if os.path.isfile(filename):
self.dic = cPickle.load(file(filename))
else:
......@@ -62,22 +80,22 @@ class ComptesInactifs:
def update(self, login, timestamp):
"""
Met a jour l'entree correspondant au login donnee, ainsi que
l'entree '!', qui correspond a la plus vieille entree.
Met jour l'entre correspondant au login donn, ainsi que
l'entre '!', qui correspond la plus vieille entre.
"""
dic = self.dic
timestamp = int(timestamp)
# Mise a jour de l'entree la plus vieille
# Mise jour de l'entre la plus vieille
if not dic.has_key('!') or timestamp < dic['!']:
dic['!'] = timestamp
# Mise a jour de l'entree correspondant au login
# Mise jour de l'entre correspondant au login
if not dic.has_key(login) or timestamp > dic[login]:
dic[login] = timestamp
def update_from_syslog(self, loglines):
""" Met a jour le dico avec les lignes de syslog donnees """
""" Met jour le dico avec les lignes de syslog donnes """
annee = localtime(time())[0]
now = time() + 600
nombre = 0
......@@ -95,9 +113,9 @@ class ComptesInactifs:
print '%d ligne(s) pertinente(s)' % nombre
def do_log(self):
""" Lit des lignes de log sur l'entree std et met a jour le dico """
""" Lit des lignes de log sur l'entre std et met jour le dico """
self.update_from_syslog(sys.stdin)
print 'Lecture des logs terminee'
print 'Lecture des logs termine'
def do_dump(self):
""" Affiche le contenu du dico """
......@@ -110,18 +128,28 @@ class ComptesInactifs:
def get_idle_accounts(self, since=32*24*3600):
"""
Renvoie la liste de ceux qui ne se sont pas connectes depuis
since secondes, par defaut un mois (32 jours, pour etre sur).
Renvoie la liste des couples (login, objet Adherent) de ceux qui
ne se sont pas connects depuis since secondes, par dfaut un mois
(32 jours, pour etre sr).
"""
oldest = self.dic.get('!', int(time()))
limit = int(time()) - since
liste = [a
for a in os.listdir('/home')
if os.path.isdir('/var/mail/' + a)
and self.dic.get(a, oldest) < limit]
liste = []
for x in os.listdir('/home'):
if os.path.isdir('/var/mail/' + x) and self.dic.get(x, oldest) < limit:
a = db.search('uid=%s' % x)['adherent']
if a:
liste.append((x, a[0]))
else:
print 'uid=%s introuvable' % x
liste.sort()
return liste
def do_summary(self):
"""
Envoie disconnect un rsume des comptes inactifs depuis plus d'un
mois.
"""
modele = u"""*Membres inscrits ne s'tant pas connects depuis plus d'un mois*
%(inscrits)s
......@@ -141,32 +169,18 @@ L'analyse des logs remonte au %(oldest)s.
--
comptes_inactifs.py
"""
liste = []
for x in self.get_idle_accounts():
a = db.search('uid=%s' % x)['adherent']
if a:
liste.append((x, a[0]))
else:
print 'uid=%s introuvable' % x
liste.sort()
inscrits = []
anciens = []
for (x, a) in liste:
for (x, a) in self.get_idle_accounts():
date = self.dic.get(x)
if date:
date = strftime(u'%d/%m/%Y %H:%M', localtime(date))
else:
date = u'Jamais'
forward = os.path.isfile('/home/%s/.forward' % x) and u'X' or u''
try:
maildir = '/var/mail/%s/new' % x
mail = os.path.isdir(maildir) and os.listdir(maildir) and u'X' or u''
except:
# Arrive quand le script n'a pas les bons droits pour lire
# /var/mail
mail = u'?'
mail = nb_mails_non_lus(x)
mail = mail == None and u'?' or mail > 0 and u'X' or u' '
ligne = (a.id(), x, a.Nom(), date, forward, mail)
if ann_scol in a.paiement():
inscrits.append(ligne)
......@@ -189,6 +203,22 @@ comptes_inactifs.py
u'Comptes inactifs',
modele % locals())
def do_spam(self):
""" Envoie un mail explicatif aux possesseurs de compte inactif """
# Nombre de personnes concernes, en expansant de droite gauche :
# inscrit/ancien, avec/sans procmail, avec/sans mail non lu
# Voir aussi template_path
stats = [0, 0, 0, 0, 0, 0, 0, 0]
# On factorise la connexion
smtp = SMTP()
smtp.connect()
for (x, a) in self.get_idle_accounts():
pass
smtp.quit()
if __name__ == '__main__':
args = sys.argv[1:]
......@@ -199,7 +229,7 @@ if __name__ == '__main__':
commande = args[0]
if commande not in ('log', 'dump', 'summary'):
sys.stderr.write("Commande incorrecte : %s\n" % args[1])
sys.stderr.write("Commande incorrecte : %s\n" % commande)
sys.exit(1)
ci_db = ComptesInactifs('/usr/scripts/var/comptes_inactifs.dict')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment