#!/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 Pierre-Elliott Bécue 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".*debit (?P[^ ]*) Euros \[impression\((?P.*)\):.*/(?P.*)/(?P[^ ]*) .*\]") IMP_DEJ_REMB_REGEX = re.compile(r".*credit (?P[^ ]*) Euros \[Impression ratee, jid=(?P.*), tache=(?P.*)\]") 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.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]) # print adh.get_mail() To = adh.get_mail() From = 'impression@crans.org' Cc = '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, Cc), 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('-d', '--do-it', help="Sans cette option, le script ne fait rien (la méthode canonique de remboursement est via l'intranet)", action="store_true") 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) elif not args.do_it: print "Pour pouvoir utiliser ce script, merci de fournir l'option -d ou --do-it. La méthode usuelle pour recréditer une impression foirée est de passer par l'interface d'impression de l'Intranet. Allez d'abord voir là-bas si vous pouvez faire le recrédit, et ensuite utilisez ce script. Merci :)" sys.exit(1) else: if not args.filtre: parser.print_help() sys.exit(1) else: do_remb(args)