163 lines
5.4 KiB
Python
Executable file
163 lines
5.4 KiB
Python
Executable file
#!/bin/bash /usr/scripts/python.sh
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
Effectue la recréditation des impressions qui n'ont pas été effectuées
|
||
par l'imprimante, soit ne sont pas sorties correctement, et contiennent
|
||
des logs d'erreur.
|
||
|
||
Le script est fait pour éviter de recréditer plusieurs fois les mêmes
|
||
impressions, et croise dans l'historique de l'adhérent les impressions
|
||
(débits), et les créditations que ce script a lui même déjà effectuées.
|
||
|
||
Un mail est envoyé pour signaler les activités de crédits.
|
||
L'exécution se fait pas appel du script suivi de l'aid.
|
||
|
||
Auteurs : Gabriel Détraz <detraz@crans.org>
|
||
Pierre-Elliott Bécue <becue@crans.org>
|
||
avec contributions importantes de Daniel Stan, Valentin Samir et Lucas Serrano
|
||
"""
|
||
|
||
# Import des modules génériques
|
||
import argparse
|
||
import sys
|
||
import datetime
|
||
import re
|
||
from utils.sendmail import actually_sendmail
|
||
|
||
# Imports des scripts développés au Crans
|
||
import lc_ldap.shortcuts
|
||
import lc_ldap.filter2 as lfilter
|
||
import gestion.config as config
|
||
from pythondialog.dialog import Dialog
|
||
from gestion import mail
|
||
|
||
# On ouvre une connexion LDAP à la base de test une fois pour toute.
|
||
conn = lc_ldap.shortcuts.lc_ldap_admin()
|
||
|
||
# Des fonctions...
|
||
IMP_DONE_REGEX = re.compile(r".*respbats : debit (?P<montant>[^ ]*) Euros \[impression\((?P<jid>.*)\):.*fichiers/(?P<login>.*)/(?P<file>[^ ]*) .*\]")
|
||
IMP_DEJ_REMB_REGEX = re.compile(r".*credit (?P<montant>[^ ]*) Euros \[Impression ratee, jid=(?P<jid>.*), tache=(?P<fichier>.*)\]")
|
||
|
||
def do_remb(args):
|
||
"""Fonction appelant l'interface curses et listant les remboursements
|
||
possibles.
|
||
|
||
"""
|
||
|
||
rendu = []
|
||
|
||
adh = conn.search(lfilter.human_to_ldap(args.filtre.decode(config.encoding.in_encoding)), mode="w")
|
||
# conn.search peut retourner une liste vide.
|
||
if not adh:
|
||
return []
|
||
|
||
with adh[0] as adh:
|
||
liste_rembs = find_rembs(adh)
|
||
while True:
|
||
(ret, val) = dialog_remb(liste_rembs)
|
||
if ret:
|
||
adh.save()
|
||
break
|
||
else:
|
||
selected = liste_rembs[int(val)]
|
||
if confirm(selected):
|
||
adh.update_solde(float(selected["montant"]), u"Impression ratee, jid=%(jid)s, tache=%(file)s" % selected)
|
||
_ = liste_rembs.pop(int(val))
|
||
rendu.append(selected)
|
||
else:
|
||
continue
|
||
send_mail(rendu, adh)
|
||
return
|
||
|
||
def find_rembs(adh):
|
||
"""Fonction qui calcule les entrées remboursables d'un adhérent
|
||
|
||
"""
|
||
|
||
now = datetime.datetime.now()
|
||
begin = now - datetime.timedelta(days=config.impression.delta_recredit_jours)
|
||
liste_taches = list()
|
||
liste_rembs = list()
|
||
|
||
for ent in adh["historique"]:
|
||
date = ent.get_datetime()
|
||
if date > begin:
|
||
match_entry = IMP_DONE_REGEX.match(unicode(ent))
|
||
if match_entry is not None:
|
||
liste_taches.append(match_entry.groupdict())
|
||
continue
|
||
match_entry = IMP_DEJ_REMB_REGEX.match(unicode(ent))
|
||
if match_entry is not None:
|
||
liste_rembs.append(match_entry.groupdict())
|
||
continue
|
||
|
||
# On génère la liste avant le return, pour ne pas la regénérer autant de fois qu'il
|
||
# y a de tâches dans liste_taches
|
||
jid_rembs = [remb["jid"] for remb in liste_rembs]
|
||
return [tache for tache in liste_taches if tache['jid'] not in jid_rembs]
|
||
|
||
def dialog_remb(liste_rembs):
|
||
"""Crée une boîte de dialogue à partir de la liste des remboursements, pour
|
||
en faire un.
|
||
|
||
"""
|
||
if not liste_rembs:
|
||
return (1, "")
|
||
|
||
dialog = Dialog()
|
||
choices = [("%s" % liste_rembs.index(dico), "Remb impression du fichier %(file)s (montant: %(montant)s, jid: %(jid)s)." % dico) for dico in liste_rembs]
|
||
|
||
return dialog.menu("Quelle impression souhaitez-vous rembourser ?", width=0, height=0, menu_height=0, title="Remboursement", choices=choices, cancel_label="Quitter", backtitle=u"Remboursement d'impressions ratées.")
|
||
|
||
def confirm(dico):
|
||
"""Demande avec dialog si on doit confirmer le remboursement.
|
||
|
||
"""
|
||
dialog = Dialog()
|
||
return dialog.yesno("Confirmer le remboursement ?") == dialog.DIALOG_OK
|
||
|
||
def send_mail(liste_rendus, adh):
|
||
"""Si la liste des remboursements est non-vide, envoie un mail pour prévenir
|
||
les imprimeurs.
|
||
|
||
"""
|
||
if not liste_rendus:
|
||
return
|
||
|
||
montant = sum([float(dico["montant"]) for dico in liste_rendus])
|
||
affs = [dico['file'] for dico in liste_rendus]
|
||
login = unicode(adh["uid"][0])
|
||
|
||
To = 'impression@crans.org'
|
||
From = 'impression@crans.org'
|
||
mailtxt = mail.generate('remboursement_impressions', {
|
||
'To': To,
|
||
'From': From,
|
||
'adhname': login,
|
||
'taches': u', '.join(affs),
|
||
'montant': montant,
|
||
'imprimeur': lc_ldap.shortcuts.current_user,
|
||
})
|
||
|
||
# print mailtxt.as_string()
|
||
actually_sendmail(From, (To,), mailtxt)
|
||
|
||
#Un bloc de test
|
||
if __name__ == "__main__":
|
||
parser = argparse.ArgumentParser(description="Script pour recréditer les adhérents.", add_help=False)
|
||
parser.add_argument('-h', '--help', help="Affiche ce message et quitte.", action="store_true")
|
||
parser.add_argument('filtre', type=str, nargs="?", help="Le filtre LDAP à utiliser")
|
||
|
||
# Et on parse
|
||
args = parser.parse_args()
|
||
|
||
if args.help:
|
||
parser.print_help()
|
||
sys.exit(0)
|
||
else:
|
||
if not args.filtre:
|
||
parser.print_help()
|
||
sys.exit(1)
|
||
else:
|
||
do_remb(args)
|
||
|