Script de controle de Stphane.

darcs-hash:20051102010801-41617-78943cd796f888e2e50d930f38c435427715a543.gz
This commit is contained in:
pauget 2005-11-02 02:08:01 +01:00
parent cb0f4c2580
commit f396e533c2

331
admin/controle_tresorier.py Executable file
View file

@ -0,0 +1,331 @@
#! /usr/bin/env python
# -*- coding: iso-8859-15 -*-
# Copyright (C) Stéphane Glondu
# Licence : GPLv2
u"""Ce script permet au trésorier de contrôler plus facilement le travail
des câbleurs.
Usage: %(prog)s {paiement|carte|mail}
Les options sont :
* paiement : contrôle interactif des nouvelles (-)adhésions
* carte : contrôle interactif des nouvelles cartes d'étudiant
* mails : envoyer les mails de rappel"""
import sys, os, re
sys.path.append('/usr/scripts/gestion')
# Fonctions d'affichage
from affich_tools import coul, tableau, prompt
# Importation de la base de données
from ldap_crans import crans_ldap, ann_scol
db = crans_ldap()
# Détermination de l'uid du câbleur
from user_tests import getuser
uid = getuser()
if not uid :
print u"Impossible de déterminer l'utilisateur !"
sys.exit(1)
cableur = db.search('uid=%s' % uid)['adherent'][0]
# Vérification des droits
if u'Contrôleur' not in cableur.droits():
print u"Il faut être contrôleur pour exécuter ce script !"
sys.exit(1)
# Lors des tests sur egon, on m'envoie tous les mails !
from socket import gethostname
testing = gethostname().split(".")[0] == 'egon'
if testing:
print coul(u'Mode testing !', 'violet')
ann_scol = 2004
def _controle_interactif_adherents(liste, quoi):
u"""
Contrôle interactif des adhérents de la liste (quoi = p ou c).
Retourne (nb_OK, nb_pas_OK).
"""
if quoi not in 'pc': raise ValueError
explicite = {'p': u'du paiement', 'c': u"de la carte d'étudiant"}[quoi]
restant = len(liste)
print coul(u'\nContrôle %s des adhérents' % explicite, 'cyan')
print u"Pour chaque entrée, il faut taper 'o' ou 'n' (défaut=n)."
print u"Une autre réponse entraîne l'interruption du processus."
print u"Le format est [nb_restant] Nom, Prénom (aid)."
print
nb = 0
for a in liste:
ok = prompt(u'[%3d] %s, %s (%s) ?'
% (restant, a.nom(), a.prenom(), a.id()), 'n', '').lower()
restant -= 1
if ok == 'o':
modifiable = db.search('aid=%s' % a.id(), 'w')['adherent'][0]
if modifiable._modifiable:
modifiable.controle('+%s' % quoi)
print modifiable.save()
nb += 1
else:
print coul(u'Adhérent %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
elif ok != 'n':
print coul(u'Arrêt du contrôle %s des adhérents' % explicite, 'rouge')
break
return nb, len(liste)-nb
def _controle_interactif_clubs(liste):
u"""
Contrôle interactif des clubs de la liste (uniquement la charte).
Retourne (nb_OK, nb_pas_OK).
"""
restant = len(liste)
print coul(u'\nContrôle de la charte des clubs', 'cyan')
print u"Pour chaque entrée, il faut taper 'o' ou 'n'."
print u"Une autre réponse entraîne l'interruption du processus."
print u"Le format est [nb_restant] Nom (cid)."
print
nb = 0
for c in liste:
ok = prompt(u'[%2d] %s (%s) ?'
% (restant, c.Nom(), c.id()), 'n', '').lower()
restant -= 1
if ok == 'o':
modifiable = db.search('cid=%s' % c.id(), 'w')['club'][0]
if modifiable._modifiable:
modifiable.controle('+p')
print modifiable.save()
nb += 1
else:
print coul(u'Club %s locké, réessayer plus tard' % modifiable.Nom(), 'rouge')
elif ok != 'n':
print coul(u'Arrêt du contrôle de la charte des clubs', 'rouge')
break
return nb, len(liste)-nb
def controle_interactif(quoi):
u"""
Procédure interactive de contrôle des paiements/chartes (quoi=p) et cartes (quoi=c).
"""
if quoi not in 'pc': raise ValueError
todo_list = db.search('%s=%d&controle!=*%s*'
% ({'p': 'paiement', 'c': 'carteEtudiant'}[quoi], ann_scol, quoi))
# Tri de la liste des adhérents selon nom, prénom
# Ça peut se faire plus facilement en Python 2.4 avec l'argument key
todo_list['adherent'].sort(lambda x, y: cmp((x.nom(), x.prenom()), (y.nom(), y.prenom())))
# Traitement des adhérents
oka, noka = _controle_interactif_adherents(todo_list['adherent'], quoi)
if quoi == 'p':
# Tri de la liste des clubs
todo_list['club'].sort(lambda x, y: cmp(x.nom(), y.nom()))
# Traitement des clubs (uniquement la charte)
okc, nokc =_controle_interactif_clubs(todo_list['club'])
print coul(u'\nRécapitulatif des nouveaux contrôles +%s :' % quoi, 'violet')
liste = [(u'Catégorie', u'OK', u'pas OK'),
(u'adhérents', str(oka), str(noka))]
if quoi == 'p':
liste.append((u'clubs', str(okc), str(nokc)))
print tableau([15, 10, 10], liste)
def formater_pour_cableur(liste):
u"""
Formate la liste d'adhérents ou de clubs avec les dates correspondantes.
liste est une liste de couples (date, objet).
"""
lignes = [(u'id', u'Nom', u'Date Heure')]
for date, a in liste:
lignes.append((a.id(), a.Nom(), date))
return tableau([6, 40, 18], lignes)
def formater_pour_bureau(dico):
u"""
Formate la liste d'adhérents ou de clubs avec les câbleurs correspondantes
pour le mail récapitulatif envoyé à bureau.
"""
lignes = [(u'id', u'Nom', u'Câbleur')]
total = 0
for cableur in dico.keys():
for date, a in dico[cableur]:
lignes.append((a.id(), a.Nom(), cableur))
total += 1
return tableau([6, 40, 17], lignes) + '\nTotal : %d' % total
def qui(historique, quoi):
u"""
Recherche le câbleur qui a effectué la dernière modification quoi
dans l'historique, ou qui a inscrit l'adhérent.
Retourne le couple (date_heure, nom_cableur).
"""
regexp = re.compile(r'^([^,]*), ([^ :]*)')
cableur = ('_inconnu_', '_inconnu_')
for ligne in historique:
if quoi in ligne or 'inscription' in ligne:
matched = regexp.match(ligne)
if matched: cableur = matched.group(1), matched.group(2)
return cableur
def chercher_cableurs(liste, quoi):
u"""
Renvoie un dictionnaire cableur->adherents à partir de liste, quoi
désigne le champ qui sera recherché dans l'historique.
"""
resultat = {}
for a in liste:
date, cableur = qui(a.historique(), quoi)
if not resultat.has_key(cableur): resultat[cableur] = []
resultat[cableur].append((date, a))
return resultat
from smtplib import SMTP
from email.MIMEText import MIMEText
def envoyer_mails_rappel():
u"""
Envoyer les mails de rappel aux câbleurs avec bureau en cc,
ainsi que le récapitulatif à bureau.
"""
# On recherche tous les câbleurs concernés
todo_list = db.search('paiement=%d&controle!=*p*' % ann_scol)
paiements = chercher_cableurs(todo_list['adherent'], 'paiement')
chartes = chercher_cableurs(todo_list['club'], 'paiement')
cartes = chercher_cableurs(db.search('carteEtudiant=%d&controle!=*c*' % ann_scol)['adherent'], 'carteEtudiant')
# Méthode de Vince
cableurs = {}
for a in paiements.keys():
if a != '_inconnu_': cableurs[a] = None
for a in chartes.keys():
if a != '_inconnu_': cableurs[a] = None
for a in cartes.keys():
if a != '_inconnu_': cableurs[a] = None
# Squelette à modifier après
msg_skeleton = u"""\
Salut,
Tu me dois des papiers. J'ai mis l'aid ou le cid afin que tu puisses
vérifier facilement dans la base.
%s
Peux-tu confirmer et donner ces papiers le plus rapidement possible à
Florian, Augustin, les laisser au 2B ou directement me les donner ?
--
Stéphane
"""
# Vérification de l'alias pour l'envoi des mails
if u'tresorier' in cableur.alias():
moi = (u'%s <tresorier@crans.org>' % cableur.Nom()).encode('utf8')
else:
moi = (u'%s <%s@crans.org>' % (cableur.Nom(), cableur.canonical_alias())).encode('utf8')
# On se connecte au serveur
s = SMTP()
s.connect()
# On envoie les mails
nb = 0
for c in cableurs.keys():
msg = u''
if c in paiements.keys():
msg += u"\nFiches d'adhésion et cotisations des adhérents :\n"
msg += formater_pour_cableur(paiements[c]) + '\n'
if c in chartes.keys():
msg += u"\nChartes signées des clubs :\n"
msg += formater_pour_cableur(chartes[c]) + '\n'
if c in cartes.keys():
msg += u"\nCarte d'étudiant des adhérents :\n"
msg += formater_pour_cableur(cartes[c]) + '\n'
mail = MIMEText((msg_skeleton % msg).encode('utf8'), _charset='UTF-8')
mail['Subject'] = u'Papiers manquants'.encode('utf8')
mail['From'] = moi
adresse_cableur = '%s@crans.org' % c
mail['To'] = adresse_cableur
mail['Cc'] = 'Bureau <bureau@crans.org>'
if testing:
recipients = ['glondu@crans.org']
else:
recipients = [adresse_cableur, 'bureau@crans.org']
s.sendmail(moi, recipients, mail.as_string())
nb += 1
# On envoie le mail récapitulatif sur bureau
if paiements or chartes or cartes:
msg = u''
msg += u"\nFiches d'adhésion et cotisations des adhérents :\n"
msg += formater_pour_bureau(paiements) + '\n'
msg += u"\nChartes signées des clubs :\n"
msg += formater_pour_bureau(chartes) + '\n'
msg += u"\nCarte d'étudiant des adhérents :\n"
msg += formater_pour_bureau(cartes) + '\n'
msg += u"\n-- \nScript exécuté par %s\n" % cableur.Nom()
mail = MIMEText(msg.encode('utf8'), _charset='utf8')
mail['Subject'] = u'Récapitulatif des papiers manquants'.encode('utf8')
mail['From'] = moi
mail['To'] = 'Bureau <bureau@crans.org>'
if testing:
recipients = ['glondu@crans.org']
else:
recipients = ['bureau@crans.org']
s.sendmail(moi, recipients, mail.as_string())
nb += 1
s.close()
print coul(u"%d mail(s) envoyé(s) avec succès !" % nb, "vert")
def __usage():
u""" Comment ça marche ? """
print __doc__ % {'prog': sys.argv[0]}
sys.exit(1)
if __name__ == '__main__' :
if len(sys.argv) == 2:
if sys.argv[1] == 'paiement':
controle_interactif('p')
elif sys.argv[1] == 'carte':
controle_interactif('c')
elif sys.argv[1] == 'mail':
envoyer_mails_rappel()
else:
__usage()
else:
__usage()
sys.exit(0)