From 096a243c77090a2b86300e904e71e45ae70f8a6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre-Elliott=20B=C3=A9cue?= Date: Mon, 1 Sep 2014 00:06:15 +0200 Subject: [PATCH] =?UTF-8?q?[stats=5Fcableurs2]=20Maj=20pour=20les=20adh?= =?UTF-8?q?=C3=A9sions=20glissantes,=20et=20rationalisation.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Il y a une fonction pour afficher des tableaux, j'ai ajouté le colour swapping sur les lignes. * Le parsing des arguments est amélioré. * J'ai viré les tabulations. * Il faut aérer le code ! --- gestion/affichage.py | 32 ++++-- utils/stats_cableurs2.py | 217 +++++++++++++++++---------------------- 2 files changed, 119 insertions(+), 130 deletions(-) diff --git a/gestion/affichage.py b/gestion/affichage.py index 7e905f6c..abd164b7 100755 --- a/gestion/affichage.py +++ b/gestion/affichage.py @@ -9,8 +9,8 @@ # --------- # # Décorateur : -# static_var(name, val), un décorateur pour créer une variable -# statique dans une fonction +# static_var([(name, val)]), un décorateur pour créer des variables +# statiques dans une fonction # # Fonctions : # getTerminalSize(), une fonction qui récupère le couple @@ -47,14 +47,15 @@ term_format = '\x1b\[[0-1];([0-9]|[0-9][0-9])m' dialog_format = '\\\Z.' sep_col = u"|" -def static_var(name, val): +def static_var(couples): """Decorator setting static variable to a function. """ def decorate(fun): functools.wraps(fun) - setattr(fun, name, val) + for (name, val) in couples: + setattr(fun, name, val) return fun return decorate @@ -220,7 +221,7 @@ def nostyle(dialog=False): return "\Zn" return "\033[1;0m" -@static_var("styles", {}) +@static_var([("styles", {})]) def style(texte, what=[], dialog=False): """ Pretty text is pretty @@ -396,7 +397,7 @@ def format_data(data, format): return "%.2f %s" % (data/oct_sizes[i], oct_names[i]) return "%.0f o" % (data) -def tableau(data, titre=None, largeur=None, alignement=None, format=None, dialog=False, width=None, styles=None): +def tableau(data, titre=None, largeur=None, alignement=None, format=None, dialog=False, width=None, styles=None, swap=[]): """ Retourne une chaine formatée repésentant un tableau. @@ -418,6 +419,10 @@ def tableau(data, titre=None, largeur=None, alignement=None, format=None, dialog o = octet Si None, s pour chaque colonne width : force la largeur + + styles : applique une liste de styles, un à chaque colonne. + + swap : Met styles à None et alterne une ligne sur deux niveau couleurs. """ if data and isinstance(data, list): @@ -428,6 +433,11 @@ def tableau(data, titre=None, largeur=None, alignement=None, format=None, dialog if format is None: format = ['s'] * nb_cols + if swap != []: + styles = None + else: + swap = [None] + if styles is None: styles = [None] * nb_cols @@ -465,7 +475,15 @@ def tableau(data, titre=None, largeur=None, alignement=None, format=None, dialog # Les données ############# - chaine += u'\n'.join([sep_col + sep_col.join([style(ligne[i], styles[i]) for i in range(nb_cols)]) + sep_col for ligne in data]) + j = 0 + for ligne in data: + chaine += u"%s" % (sep_col,) + if swap: + chaine += sep_col.join([style(ligne[i], swap[j]) for i in range(nb_cols)]) + else: + chaine += sep_col.join([style(ligne[i], styles[i]) for i in range(nb_cols)]) + chaine += u"%s\n" % (sep_col,) + j = (j + 1) % len(swap) return chaine diff --git a/utils/stats_cableurs2.py b/utils/stats_cableurs2.py index e3a332cb..f9b85ff7 100755 --- a/utils/stats_cableurs2.py +++ b/utils/stats_cableurs2.py @@ -1,10 +1,11 @@ #!/bin/bash /usr/scripts/python.sh # -*- coding: utf-8 -*- # -# stats.py +# stats_cableurs.py # ----------------- # -# Copyright (C) 2013,2014 Raphaël-David Lasseri , +# Copyright (C) 2013-2015 Raphaël-David Lasseri , +# Pierre-Elliott Bécue , # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -20,154 +21,124 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. -import sys, re, datetime, string +import sys +import re +import datetime +import string import argparse from lc_ldap import shortcuts -from gestion.config import ann_scol - +import lc_ldap.crans_utils as crans_utils +import gestion.config as config +import gestion.affichage as affichage ### Appels à LDAP et tri initial sur l'année en cours db = shortcuts.lc_ldap_readonly() -adherents=db.search(u'(&(paiement=%s)(aid=*))' % (ann_scol), sizelimit=2000) -cableurs= db.search(u'(|(droits=cableur)(droits=nounou))') -scores=[] -historique=[] - +adherents = db.search(u'(&(debutAdhesion>=%s)(aid=*))' % (crans_utils.toGeneralizedTimeFormat(config.debut_periode_transitoire)), sizelimit=2000) +cableurs = db.search(u'(|(droits=cableur)(droits=nounou))') +scores = [] +historique = [] #### On prends les historiques de tout les adhérents def parse_historique(ligne): - u"""Parse une ligne d'historique et renvoie [ligne parsée],action - du cableur, date de l'action""" - champ = ligne.value.replace(',','').replace(':','').split(' ') - sdate = champ[0].split('/') - date = datetime.date(int(sdate[2]),int(sdate[1]),int(sdate[0])) - champ_action=champ[4] - return champ,champ_action,date + """Parse une ligne d'historique et renvoie [ligne parsée],action + du cableur, date de l'action""" + champ = ligne.value.replace(',','').replace(':','').split(' ') + sdate = champ[0].split('/') + date = datetime.date(int(sdate[2]),int(sdate[1]),int(sdate[0])) + champ_action=champ[4] + return champ,champ_action,date def actions_cableurs(): - u"""Renvoie l'historique de tous les adherents et tri en fonction - des actions éffectuées.""" - for adherent in adherents: - histo=adherent.get('historique',None) - for j in range (0,len(histo)): - champ=parse_historique(histo[j])[0] - champ_action=parse_historique(histo[j])[1] - date=parse_historique(histo[j])[2] - if ((champ_action==u'inscription' or champ_action==u'paiement+'+str(ann_scol)) or len(champ)>5 and (champ[5]==u'paiement+'+str(ann_scol) or champ[5]==u'inscription')) and date > datetime.date(ann_scol,8,1) : - historique.append(champ) - return historique + """Renvoie l'historique de tous les adherents et tri en fonction + des actions éffectuées.""" + for adherent in adherents: + histo=adherent.get('historique',None) + for j in range (0,len(histo)): + champ=parse_historique(histo[j])[0] + champ_action=parse_historique(histo[j])[1] + date=parse_historique(histo[j])[2] + if ((champ_action == u'inscription' or champ_action == u'debutAdhesion+%s' % (crans_utils.toGeneralizedTimeFormat(config.debut_periode_transitoire),) ) or len(champ) > 5 and (champ[5] == u'debutAdhesion+%s' % (crans_utils.toGeneralizedTimeFormat(config.debut_periode_transitoire), ) or champ[5] == u'inscription')) and date > datetime.date(config.ann_scol, 8, 16) : + historique.append(champ) + return historique -#### On parse l'historique et on trie +#### On parse l'historique et on trie def score_cableurs(): - u"""Calcul le score de tout les câbleurs en fonction des actions - effectuées """ - for cableur in cableurs: - inscriptions=reinscriptions=0 - nom=cableur.get(u'nom',None)[0].value - prenom=cableur.get(u'prenom',None)[0].value - uid=cableur.get(u'uid',None)[0].value - for l in range (0,len(historique)): - histo_uid=historique[l][2] - histo_action=historique[l][4] - if histo_uid==uid and histo_action==u'inscription': - inscriptions=inscriptions+1 - if histo_uid==uid and (histo_action==u'paiement+'+str(ann_scol) or (len(historique[l])>5 and (historique[l][5]==u'paiement+'+str(ann_scol)))): - reinscriptions=reinscriptions+1 - score = 2*inscriptions+reinscriptions - scores.append([prenom+' '+nom,score,inscriptions,reinscriptions]) - return scores + """Calcul le score de tout les câbleurs en fonction des actions + effectuées """ + for cableur in cableurs: + inscriptions = reinscriptions=0 + nom = cableur.get(u'nom',None)[0].value + prenom = cableur.get(u'prenom',None)[0].value + uid = cableur.get(u'uid',None)[0].value + for l in range (0,len(historique)): + histo_uid = historique[l][2] + histo_action = historique[l][4] + if histo_uid == uid and histo_action == u'inscription': + inscriptions = inscriptions+1 + if histo_uid == uid and (histo_action == u'debutAdhesion+%s' % (crans_utils.toGeneralizedTimeFormat(config.debut_periode_transitoire),) or (len(historique[l])>5 and (historique[l][5] == u'debutAdhesion+%s' % (crans_utils.toGeneralizedTimeFormat(config.debut_periode_transitoire),)))): + reinscriptions = reinscriptions+1 + score = 2*inscriptions + reinscriptions + scores.append(["%s %s" % (prenom, nom), score, inscriptions, reinscriptions]) + return scores ### Tri par score def sort_by_score(): - u"""Tri la liste des câbleurs par ordre de score décroissant de score""" - return score_cableurs().sort(key=lambda x:int(x[1]),reverse=True) + """Tri la liste des câbleurs par ordre de score décroissant de score""" + return score_cableurs().sort(key=lambda x:int(x[1]),reverse=True) def sort_by_inverse_score(): - u"""Tri la liste des câbleurs par ordre de score croissant de score""" - return score_cableurs().sort(key=lambda x:int(x[1])) - + """Tri la liste des câbleurs par ordre de score croissant de score""" + return score_cableurs().sort(key=lambda x:int(x[1])) def cableurs_utiles(): - u"""Renvoi le nombre de cableurs ayant un score non nul""" - useless_cableurs=0 - for k in range(0,len(cableurs)): - if (scores[k][1]==0): - useless_cableurs=useless_cableurs+1 - return len(cableurs)-useless_cableurs + """Renvoi le nombre de cableurs ayant un score non nul""" + useless_cableurs=0 + for k in range(0,len(cableurs)): + if (scores[k][1] == 0): + useless_cableurs = useless_cableurs+1 + return len(cableurs) - useless_cableurs #### Affichage ou x est le nombre de câbleurs à afficher -def show_all(x): - u"""Tableau fait main pour un effet plus visuel""" - print '\033[0m ' + '\033[4m|',' '*8,u'Câbleur',' '*6,'|',u'Score',' |',u'Inscriptions',' ','|',u'Réinscriptions','\033[0m' - for k in range(0,x): - if k%2==01: - print '\033[92m',string.ljust('|'+unicode((scores[k][0])),25), string.ljust('|'+str(scores[k][1]),8), string.ljust('|'+str(scores[k][2]),16),string.ljust('|'+str(scores[k][3]),16),'\033[0m' - else: - print '\033[0m',string.ljust('|'+unicode((scores[k][0])),25), string.ljust('|'+str(scores[k][1]),8), string.ljust('|'+str(scores[k][2]),16),string.ljust('|'+str(scores[k][3]),16),'\033[0m' - -def show_all_no_color(x): - u"""Tableau fait main pour un effet plus visuel sans couleur""" - print '\033[0m ' + '\033[4m|',' '*8,u'Câbleur',' '*6,'|',u'Score',' |',u'Inscriptions',' ','|',u'Réinscriptions','\033[0m' - for k in range(0,x): - print '\033[0m',string.ljust('|'+unicode((scores[k][0])),25), string.ljust('|'+str(scores[k][1]),8), string.ljust('|'+str(scores[k][2]),16),string.ljust('|'+str(scores[k][3]),16),'\033[0m' +def show_all(limit, swap): + """Tableau fait main pour un effet plus visuel""" + titre = [u"Câbleur", u"Score", u"Inscriptions", u"Réinscriptions"] + largeur = [25, 8, 16, 16] + alignement = ["c", "c", "c", "c"] + data = [[elem for elem in scores[index]] for index in xrange(limit)] + print affichage.tableau(data, titre=titre, largeur=largeur, alignement=alignement, swap=swap) #### On définit le Parser if __name__ == "__main__": + actions_cableurs() + parser = argparse.ArgumentParser() + parser.add_argument("-a", "--all", help="Affiche les scores de tout les câbleurs", action="store_true") + parser.add_argument("-t", "--top", help="Affiche seulement les meilleurs câbleurs", action="store_true") + parser.add_argument("-s", "--scores", help="Affiche seulement les câbleurs ayant un score non nul", action="store_true") + parser.add_argument("-m", "--menage", help="Affiche seulement les câbleurs ayant un score nul", action="store_true") + parser.add_argument("-n", "--nocolour", help="Désactive la couleur", action="store_true") + args = parser.parse_args() - actions_cableurs() + if args.nocolour: + swap = [] + else: + swap = [None, "vert"] - parser = argparse.ArgumentParser() - parser.add_argument("-a", "--all", help="Affiche les scores de tout les câbleurs", - action="store_true") - parser.add_argument("-t", "--top", help="Affiche seulement les meilleurs câbleurs", - action="store_true") - parser.add_argument("-s", "--scores", help="Affiche seulement les câbleurs ayant un score non nul", - action="store_true") - parser.add_argument("-m", "--menage", help="Affiche seulement les câbleurs ayant un score nul", - action="store_true") - parser.add_argument("-a_nc", "--ncall", help="Affiche les scores de tout les câbleurs (sans couleur)", - action="store_true") - parser.add_argument("-t_nc", "--nctop", - action="store_true") - parser.add_argument("-s_nc", "--ncscores", - action="store_true") - parser.add_argument("-m_nc", "--ncmenage", - action="store_true") - - - - args = parser.parse_args() - if args.all: - sort_by_score() - show_all(len(cableurs)) - elif args.scores: - sort_by_score() - show_all(cableurs_utiles()) - elif args.menage: - sort_by_inverse_score() - show_all(len(cableurs)-cableurs_utiles()) - elif args.top: - sort_by_score() - show_all(5) - - elif args.ncall: - sort_by_score() - show_all_no_color(len(cableurs)) - - elif args.ncscores: - sort_by_score() - show_all_no_color(cableurs_utiles()) - elif args.ncmenage: - sort_by_inverse_score() - show_all_no_color(len(cableurs)-cableurs_utiles()) - elif args.nctop: - sort_by_score() - show_all_no_color(5) - - else: - sort_by_score() - show_all(10) + if args.all: + sort_by_score() + show_all(len(cableurs), swap=swap) + elif args.scores: + sort_by_score() + show_all(cableurs_utiles(), swap=swap) + elif args.menage: + sort_by_inverse_score() + show_all(len(cableurs)-cableurs_utiles(), swap=swap) + elif args.top: + sort_by_score() + show_all(5, swap=swap) + else: + sort_by_score() + show_all(10, swap=swap)