[admin/mail_invalide/,gen_confs/] Mise en place deconnexion pour mail invalide

Maintenant, quand on voit un mail invalide :
/usr/scripts/admin/mail_invalide/mail_invalide.py [mail]...
La personne est deconnectee au bout de 2 semaines si elle n'a pas change
son adresse mail.

 * Le script admin/mail_invalide/mail_invalide.py permet de generer les fiches,
et note l'adherent pour deconnexion 2 semaines plus tard (services_to_restart)
 * admin/mail_invalide/mail_invalide.tex est une fusion des deux
mail_invalide*.tex dans le dossier admin/src/
 * gen_confs/adherents.py s'occupe de marquer le mail comme invalide au bout de
2 semaines s'il n'a pas ete change (il met le flag mailInvalide=TRUE)
 * gen_confs/squid.py genere la liste des deconnectes pour Squid

darcs-hash:20091208003119-ddb99-74b4388950300879400250b9c40716013832d45e.gz
This commit is contained in:
Michel Blockelet 2009-12-08 01:31:19 +01:00
parent 6c68846b28
commit 0f9856085e
6 changed files with 287 additions and 159 deletions

254
admin/mail_invalide/mail_invalide.py Normal file → Executable file
View file

@ -1,161 +1,113 @@
#! /usr/bin/env python #! /usr/bin/env python
# -*- coding: iso-8859-15 -*- # -*- coding: utf-8 -*-
import sys,os,string,time,locale """
locale.setlocale(locale.LC_ALL,'') Script de déconnexion pour mail invalide
sys.path.append("/usr/scripts/gestion")
from email_tools import format_sender
# Import de la base de données Copyright (C) 2009 Michel Blockelet
inspiré de fiche_deconnexion.py par :
Xavier Pessoles, Étienne Chové, Vincent Bernat, Nicolas Salles
Licence : GPL v2
"""
import commands, os, sys, time
sys.path.append('/usr/scripts/gestion') sys.path.append('/usr/scripts/gestion')
from ldap_crans import crans_ldap from ldap_crans import crans_ldap
from config import upload
# logging tools
import syslog
def log(x):
syslog.openlog('GENERATE_MAIL_INVALIDE_NOTICE')
syslog.syslog(x)
syslog.closelog()
sys.path.append('/usr/scripts/lib')
import utils.exceptions
import locale
locale.setlocale(locale.LC_TIME, 'fr_FR.UTF-8')
help = """Script de déconnexion pour mail invalide.
Une fiche sera générée pour chaque adhérent.
Chaque adhérent sera déconnecté 2 semaines plus tard si son adresse mail
n'a pas changé.
Usage: mail_invalide.py [adresse mail]..."""
def generate_ps(proprio):
"""On génère la feuille d'avertissement et on retourne son emplacement."""
barcode = "/usr/scripts/admin/mail_invalide/barcode.eps"
try:
log('Generate invalid mail notice for %s' % proprio.Nom())
# Dossier de génération du ps
dossier = '/usr/scripts/admin/mail_invalide'
# Base pour le nom du fichier
fichier = time.strftime('%Y-%m-%d-%H-%M') + '-mail-%s' % (proprio.Nom().
lower().replace(' ', '-'))
# Création du fichier tex
format_date = '%A %d %B %Y'
template = file('%s/mail_invalide.tex' % dossier).read()
template = template.replace('~prenom~', proprio.prenom().encode('utf-8'))
template = template.replace('~nom~', proprio.nom().encode('utf-8'))
template = template.replace('~chambre~', proprio.chbre().encode('utf-8'))
template = template.replace('~mail~', proprio.email().encode('utf-8'))
template = template.replace('~fin~',
time.strftime(format_date, time.localtime(time.time()+14*86400)))
file('%s/%s.tex' % (dossier, fichier), 'w').write(template)
# Compilation du fichier latex
commands.getstatusoutput('PATH="/bin:/usr/bin" cd %(dossier)s && barcode -n -E -b %(adresse)s%(date)s -o %(barcode)s && latex --interaction=nonstopmode %(base)s.tex && dvips %(base)s.dvi && rm -f %(base)s.dvi %(base)s.aux %(base)s.log %(base)s.tex %(barcode)s'%{'dossier': dossier, 'adresse': adresse, 'date': time.strftime("%Y%m%d-%H%M"), 'base': fichier, 'barcode': barcode})
return '%s/%s.ps' % (dossier, fichier)
except Exception, e:
log('Erreur lors de la génération du ps : ')
log(str(e))
log("Values : adherent:%s" % proprio.Nom())
log(utils.exceptions.formatExc())
raise e
if __name__ == "__main__":
if '--help' in sys.argv or '-h' in sys.argv or len(sys.argv) < 2:
print help
sys.exit(0)
db = crans_ldap() db = crans_ldap()
# Détermination de l'uid du cableur a_imprimer = []
uid = os.getenv('SUDO_UID') a_verifier = []
if not uid :
print "Impossible de déterminer l'utilisateur"
sys.exit(1)
cableur = db.search('uidNumber=%s' % os.getenv('SUDO_UID'),'w')['adherent'][0]
os.chdir("/usr/scripts/admin/mail_invalide") for adresse in sys.argv[1:]:
print " * Recherche de %s ..." % adresse
SRC = "/usr/scripts/admin/src" res = db.search("mail=%s" % adresse, 'w')['adherent']
if len(res) == 0:
# Nom des fichiers print "*** Erreur : aucun résultat pour %s" % adresse
headers = SRC + "/mail_invalide_debut.tex" a_verifier.append(adresse)
texsrc = SRC + "/mail_invalide_texte.tex" elif len(res) > 1:
pdf = time.strftime("mail_invalide-%d-%m-%Y_%Hh%M.pdf",time.localtime(time.time())) print "*** Erreur : plusieurs résultats pour %s :" % adresse
for adh in res:
# Fichiers temporaires à supprimer à la fin print adh.Nom()
mailtex = "mailtmp.tex" a_verifier.append(adresse)
barcode = "barcode.eps"
# Détection d'un manquement d'argument
if len(sys.argv) == 1 :
sys.exit("Erreur: aucune adresse mail fournie")
# On prend la liste des adresses mails données en argument
adresses = sys.argv
# On vire pour celà l'appel au script
adresses.pop(0)
if len(adresses) == 1 :
text = "Bonjour\n\n \
Voici la fiche d'avertissement à remettre à l'adhérent concerné pour\n \
l'informer que l'adresse mail qu'il a fourni n'est pas valide.\n\n \
Il faut donc imprimer la feuille et la mettre dans sa boîte aux\n \
lettres.\n\n"
else: else:
text = "Bonjour\n\n \ print "Génération de la fiche pour %s :" % res[0].Nom().encode('utf-8')
Voici les fiches d'avertissement à remettre aux adhérents concernés\n \ fiche = generate_ps(res[0])
pour les informer que l'adresse mail qu'ils ont fourni n'est pas valide.\n\n \ print fiche
Il faut donc imprimer les feuilles et les mettre dans les boîtes aux\n \ a_imprimer.append(fiche)
lettres correspondantes.\n\n" db.services_to_restart('mail_invalide_expire', ['%s$%s' % (res[0].id(), res[0].mail())], time.time()+14*86400)
text += "-- \nUn script exécuté par %s\n\n" % cableur.Nom().encode('iso8859-1')
text += os.popen("/usr/games/fortune",'r').read()
os.system("cp %s %s" % (headers, mailtex)) if len(a_verifier) + len(a_imprimer) > 0:
file = open(mailtex,'r+') print ''
file.read() print '***** Résultats *****'
if len(a_verifier) > 0:
chbres = [] print ' * Adresses mail à vérifier :'
for adresse in adresses : print ','.join(a_verifier)
os.system("barcode -n -E -b %s%s -o %s" % (adresse,time.strftime("%Y%m%d-%H%M",time.localtime()),barcode)) if len(a_imprimer) > 0:
data = db.search("mail=%s" % adresse,'w') print ' * Fiches à imprimer :'
try : for fiche in a_imprimer:
adherent = data['adherent'][0] print fiche
prenom = adherent.prenom().encode('iso8859-15')
nom = adherent.nom().encode('iso8859-15')
chbre = adherent.chbre()
# L'adhérent a une adresse mail invalide
adherent.mail_invalide(True)
adherent._save()
except :
print("Erreur : l'adresse < %s > n'a pas été trouvée dans la base" % adresse)
adresses.remove(adresse)
if len(adresses) == 0 :
sys.exit("Aucune adresse valide")
continue
chbres.append(chbre)
date = time.strftime("%A %d %B %Y",time.localtime(time.time()+15*24*3600))
if adresse == adresses[0] :
file.write("\\newcommand{\prenom}{%s}\n" % prenom)
file.write("\\newcommand{\\nom}{%s}\n" % nom)
file.write("\\newcommand{\chambre}{%s}\n" % chbre)
file.write("\\newcommand{\email}{\url{%s}}\n" % adresse)
file.write("\\newcommand{\deconnexion}{%s}\n" % date)
else :
file.write("\\renewcommand{\prenom}{%s}\n" % prenom)
file.write("\\renewcommand{\\nom}{%s}\n" % nom)
file.write("\\renewcommand{\chambre}{%s}\n" % chbre)
file.write("\\renewcommand{\email}{\url{%s}}\n" % adresse)
file.write("\\renewcommand{\deconnexion}{%s}\n" % date)
tex_src = open(texsrc, 'r')
file.write(tex_src.read())
tex_src.close()
if adresse != adresses[len(adresses)-1] :
file.write('\\newpage')
else :
file.write('\end{document}')
file.close()
#os.system("latex %s" % mailtex)
os.system("latex \\\\nonstopmode\\\\input %s 1> /dev/null" % mailtex)
os.system("dvips %s 2> /dev/null" % mailtex.replace('.tex','.dvi'))
os.system("ps2pdf %s %s" % (mailtex.replace('.tex','.ps'),pdf))
# Génération du mail avec la pièce jointe
import smtplib
# Here are the email pacakge modules we'll need
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.Encoders import encode_base64
msg = MIMEMultipart()
msg['Subject'] = "Fiche(s) d'avertissement de mail invalide - %s" % time.strftime("%d/%m/%Y",time.localtime(time.time()))
msg['From'] = format_sender(u"%s <%s>" % (cableur.Nom(), cableur.mail()))
msg['To'] = format_sender(u"Câbleurs <respbats@crans.org>")
msg['Cc'] = format_sender(u"Disconnect Team <disconnect@crans.org>")
# msg.preamble = text
# Guarantees the message ends in a newline
# msg.epilogue = ''
fp = open(pdf, 'rb')
img = MIMEBase('application','pdf')
img.set_payload(fp.read())
fp.close()
encode_base64(img) # Ils auraient pu soigner...
img.add_header('Content-Disposition', 'attachment', filename=pdf)
text = MIMEText(text, 'plain', 'iso-8859-1')
msg.attach(text)
msg.attach(img)
while (1 == 1):
print "Mail formaté, prêt à l'envoi."
print " [Envoyer, Abandonner]"
r = sys.stdin.readline().strip()
if (r == "e" or r == "E"):
# Send the email via our own SMTP server.
s = smtplib.SMTP()
s.connect()
s.sendmail(msg['From'], (msg['To'],msg['Cc']), msg.as_string())
s.close()
print "Mail envoyé !"
break
if (r == "a" or r == "A"):
print "Abandon"
os.system("rm -f %s" % pdf)
break
os.system("rm -f %s %s" % (mailtex.replace(".tex",".*"),barcode))

View file

@ -0,0 +1,140 @@
\documentclass[11pt,a4paper,oneside]{article}
\usepackage{aeguill}
\usepackage{fancyhdr}
\usepackage{url}
\usepackage{vmargin}
\usepackage{ifthen}
\usepackage{pstricks}
\usepackage{multicol}
\usepackage{alltt}
\usepackage[dvips]{eso-pic,graphicx}
%\usepackage[dvips]{color}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[french]{babel}
\newboolean{mailcrans}
\setpapersize{A4}
\setmarginsrb{18mm}{14mm}{18mm}{14mm}{\headheight}{12pt}{\footheight}{20pt}
\pagestyle{fancy}
\renewcommand{\headrulewidth}{0.8pt}
\renewcommand{\footrulewidth}{0.2pt}
\lhead{\textbf{Notification d'adresse mail invalide}}
\rhead{\textbf{CR@NS}}
\cfoot{\textbf{CR@NS}}
%Define snow flakes
\newcommand{\flakepart}{%
\pspolygon(0,0)(0.5,1)(0.5,3)(1.9,4.4)(1.2,5.1)(0.5,4.4)(0.5,5.7)(-0.5,5.7)(-0.5,4.4)(-1.2,5.1)(-1.9,4.4)(-0.5,3)(-0.5,1)}
\newcommand{\snowflake}[1]{%
\psset{unit=#1}%
\multips{0}(0,0){1}{\flakepart}%
\multips{60}(0,0){1}{\flakepart}%
\multips{120}(0,0){1}{\flakepart}%
\multips{180}(0,0){1}{\flakepart}%
\multips{240}(0,0){1}{\flakepart}%
\multips{300}(0,0){1}{\flakepart}%
}
\newcommand{\multiflake}{%
\rput(0.0 ,1.6){\snowflake{0.06}}%
\rput(0.2 ,0.0){\snowflake{0.06}}%
\rput(0.5 ,0.6){\snowflake{0.04}}%
\rput(0.1 ,1 ){\snowflake{0.04}}%
\rput(0.8 ,1.4){\snowflake{0.06}}%
}
\begin{document}
{\setlength{\unitlength}{1in}
\begin{picture}(0,0)
\put(-0.3,-2.3){\includegraphics[width=3cm]{/usr/scripts/admin/src/logo.eps}}
\put(6,-3){\resizebox{1cm}{7cm}{\rotatebox{90}{\includegraphics[width=7cm]{barcode.eps}}}}
\psset{linecolor=lightgray}
\put(-0.4,-0.6){\multiflake}
\end{picture}}
\begin{center}
\begin{minipage}[c]{0.9\textwidth}
\begin{center}
\begin{tabular}[c]{c}
\hline
\vspace{0.1cm} \\
\Huge{\textbf{Notification d'adresse mail}} \\
\Huge{\textbf{invalide}}\\
\vspace{0.1cm} \\
\hline
\end{tabular}
\end{center}
\end{minipage}
\end{center}
\vspace{0.2cm}
\begin{center}
\begin{minipage}[c]{0.5\textwidth}
\textbf{Nom} \dotfill{} ~nom~ \\
\textbf{Prénom} \dotfill{} ~prenom~ \\
\textbf{Chambre} \dotfill{} ~chambre~ \\
\textbf{Email} \dotfill{} ~mail~ \\
\end{minipage}
\end{center}
\vspace{0.5cm}
\noindent\begin{center}
\noindent\fcolorbox[gray]{0}{0.85}{%
\begin{minipage}[t]{0.7\textwidth}%
\begin{center}
\large Nous t'informons que l'adresse mail que tu as fournie lors de
ton adhésion est invalide au jour d'aujourd'hui.
\end{center}
\end{minipage}}
\end{center}
\vspace{0.8cm}
Un mail a été envoyé à l'adresse mail que nous connaissons, à savoir :
~mail~\ et un message nous est revenu. Donc le message ne t'a pas été
délivré.
\vspace{0.3cm}
Dans le cadre du fonctionnement de l'association, il est nécessaire
de pouvoir joindre les adhérents par mail afin d'obtenir des réponses rapides
aux questions que peuvent se poser les membres actifs quant à ton utilisation
du réseau. D'autre part un mail est un moyen simple et rapide pour te
communiquer des informations sur l'association quand le besoin s'en fait
sentir.
\vspace{0.3cm}
Plusieurs raisons peuvent expliquer des dysfonctionnements dans la réception
du mail. On peut compter dans la liste :
\begin{itemize}
\item L'adresse email n'existe pas
\item La boîte aux lettres de destination est pleine donc le mail a été rejeté
\item Une erreur de recopie s'est produite au moment de ton inscription.
\end{itemize}
\vspace{0.3cm}
Pour corriger cela, il te faut nous indiquer une adresse mail pour laquelle
ce problème ne se posera plus.
Tu peux venir à la Kfet pour rencontrer un des nombreux membres actifs en
permanence ou bien envoyer un mail à \emph{cableurs@crans.org}.
\vspace{1cm}
\noindent\begin{center}
\noindent\fcolorbox[gray]{0}{0.85}{
\begin{minipage}[t]{0.7\textwidth}
\begin{center}
\large Dans le cas où tu ne réagirais pas avant le ~fin~, ta connexion
au réseau sera supprimée.
\end{center}
\end{minipage}}
\end{center}
\vspace{0.3cm}
\end{document}

View file

@ -199,6 +199,26 @@ class mail_ajout_droits:
traceback.print_exc() traceback.print_exc()
class mail_invalide_expire:
# Passage d'un mail en invalide 2 semaines après notification
debug = True
def __init__(self, args):
self.args = args
def reconfigure(self):
cprint(u'Passage en mail invalide', 'gras')
db = crans_ldap()
for arg in self.args:
aid, old_mail = arg.split('$')
adhl = db.search("aid=%s" % aid, 'w')['adherent']
if len(adhl) > 0:
adh = adhl[0]
if adh.mail() == old_mail:
adh.mail_invalide(True)
adh.save()
class ML_ens: class ML_ens:
debug = True debug = True

View file

@ -165,6 +165,10 @@ class rouge(base_reconfigure):
from adherents import mail_valide from adherents import mail_valide
self._do(mail_valide(args)) self._do(mail_valide(args))
def mail_invalide_expire(self, args):
from adherents import mail_invalide_expire
self._do(mail_invalide_expire(args))
def mail_ajout_droits(self, args): def mail_ajout_droits(self, args):
from adherents import mail_ajout_droits from adherents import mail_ajout_droits
self._do(mail_ajout_droits(args)) self._do(mail_ajout_droits(args))
@ -242,6 +246,10 @@ class sable(base_reconfigure):
from gen_confs.squid import squid_chbre from gen_confs.squid import squid_chbre
self._do(squid_chbre()) self._do(squid_chbre())
def bl_mail_invalide(self):
from gen_confs.squid import squid_mail
self._do(squid_mail())
def blacklist_virus(self): def blacklist_virus(self):
from gen_confs.squid import squid_virus from gen_confs.squid import squid_virus
self._do(squid_virus()) self._do(squid_virus())

View file

@ -57,48 +57,53 @@ class squid(gen_config) :
fic.close() fic.close()
class squid_upload(squid) : class squid_upload(squid) :
""" Genère le fichier blacklist-upload pour squid """ """ Génère le fichier blacklist-upload pour squid """
FICHIER = "/etc/squid3/blacklist_upload" FICHIER = "/etc/squid3/blacklist_upload"
chaine = "upload" chaine = "upload"
class squid_p2p(squid) : class squid_p2p(squid) :
""" Genère le fichier blacklist-p2p pour squid """ """ Génère le fichier blacklist-p2p pour squid """
FICHIER = "/etc/squid3/blacklist_p2p" FICHIER = "/etc/squid3/blacklist_p2p"
chaine = "p2p" chaine = "p2p"
class squid_autodisc_upload(squid) : class squid_autodisc_upload(squid) :
""" Genère le fichier blacklist-autodiscupload pour squid """ """ Génère le fichier blacklist-autodiscupload pour squid """
FICHIER = "/etc/squid3/blacklist_autodisc_upload" FICHIER = "/etc/squid3/blacklist_autodisc_upload"
chaine = "autodisc_upload" chaine = "autodisc_upload"
class squid_autodisc_p2p(squid) : class squid_autodisc_p2p(squid) :
""" Genère le fichier blacklist-autodisc-p2p pour squid """ """ Génère le fichier blacklist-autodisc-p2p pour squid """
FICHIER = "/etc/squid3/blacklist_autodisc_p2p" FICHIER = "/etc/squid3/blacklist_autodisc_p2p"
chaine = "autodisc_p2p" chaine = "autodisc_p2p"
class squid_virus(squid) : class squid_virus(squid) :
""" Genère le fichier blacklist-virus pour squid """ """ Génère le fichier blacklist-virus pour squid """
FICHIER = "/etc/squid3/blacklist_virus" FICHIER = "/etc/squid3/blacklist_virus"
chaine = "virus" chaine = "virus"
class squid_warez(squid) : class squid_warez(squid) :
""" Genère le fichier blacklist-warez pour squid """ """ Génère le fichier blacklist-warez pour squid """
FICHIER = "/etc/squid3/blacklist_warez" FICHIER = "/etc/squid3/blacklist_warez"
chaine = "warez" chaine = "warez"
class squid_bloq(squid) : class squid_bloq(squid) :
""" Genère le fichier blacklist-bloq pour squid """ """ Génère le fichier blacklist-bloq pour squid """
FICHIER = "/etc/squid3/blacklist_bloq" FICHIER = "/etc/squid3/blacklist_bloq"
chaine = "bloq" chaine = "bloq"
class squid_carte(squid) : class squid_carte(squid) :
""" Genère le fichier blacklist-carte pour squid """ """ Génère le fichier blacklist-carte pour squid """
actif = bl_carte_et_actif actif = bl_carte_et_actif
if not actif : restart_cmd = '' if not actif : restart_cmd = ''
FICHIER = "/etc/squid3/blacklist_carte_et" FICHIER = "/etc/squid3/blacklist_carte_et"
chaine = "carteEtudiant!=%i"%ann_scol chaine = "carteEtudiant!=%i"%ann_scol
class squid_chbre(squid) : class squid_chbre(squid) :
""" Genère le fichier blacklist-chbre pour squid """ """ Génère le fichier blacklist-chbre pour squid """
FICHIER = "/etc/squid3/blacklist_chbre" FICHIER = "/etc/squid3/blacklist_chbre"
chaine = "chbre=????" chaine = "chbre=????"
class squid_mail(squid) :
""" Génère le fichier blacklist-mail pour squid """
FICHIER = "/etc/squid3/blacklist_mail"
chaine = "mailInvalide=TRUE&uid!=*"

View file

@ -489,7 +489,7 @@ class CransLdap:
Si new commence par '-', on supprime le service si son start Si new commence par '-', on supprime le service si son start
est dans le futur. est dans le futur.
Si new commence par '--', on supprime le service de condition. Si new commence par '--', on supprime le service sans condition.
""" """
if new: new = preattr(new)[1] if new: new = preattr(new)[1]
@ -2032,6 +2032,9 @@ class Adherent(BaseProprietaire):
elif valeur != None: elif valeur != None:
raise ValueError, u"mail_invalide prend un booléen comme argument" raise ValueError, u"mail_invalide prend un booléen comme argument"
# on met à jour la blackliste sur sable
self.services_to_restart('bl_mail_invalide')
# renvoie la valeur trouvée dans la base # renvoie la valeur trouvée dans la base
return bool(self._data.get('mailInvalide', [])) return bool(self._data.get('mailInvalide', []))