#!/bin/bash /usr/scripts/python.sh # -*- coding: utf-8 -*- # # stats_cableurs.py # ----------------- # # 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 # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This file is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. """ Ce script permet de se faire mousser en listant les câbleurs et leurs stats. """ import sys import datetime import argparse import lc_ldap.shortcuts as shortcuts import lc_ldap.crans_utils as crans_utils import gestion.config as config import gestion.affichage as affichage from cranslib.decorators import static_var from config import ann_scol ### Appels à LDAP et tri initial sur l'année en cours. DB = shortcuts.lc_ldap_readonly() SCORES = [] HISTORIQUE = [] ENCODING = config.out_encoding @static_var(("data", [])) def adherents(regen=False): """Fonction évaluée paresseusement pour retourner la liste des adhérents""" if regen or not adherents.data: adherents.data = DB.search(u'(&(debutAdhesion>=%s)(aid=*))' % (crans_utils.to_generalized_time_format(config.debut_periode_transitoire)), sizelimit=2000) return list(adherents.data) @static_var(("data", [])) def cableurs(regen=False): """Fonction évaluée paresseusement pour retourner la liste des câbleurs""" if regen or not cableurs.data: cableurs.data = DB.search(u'(|(droits=cableur)(droits=nounou))') return list(cableurs.data) #### On prends les historiques de tout les adhérents def parse_historique(ligne): """Parse une ligne d'historique et renvoie [ligne parsée],action du cableur, date de l'action""" champ = ligne.value.replace(',', '').replace(':', '').split(' ', 3) sdate = champ[0].split('/') date = datetime.date(int(sdate[2]), int(sdate[1]), int(sdate[0])) champ_action = champ[3] return (champ, champ_action, date) def actions_cableurs(): """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 ((u' inscription' in champ_action or u'Adhesion+' in champ_action) and date > datetime.date(ann_scol, 8, 1)): HISTORIQUE.append(champ) return HISTORIQUE #### On parse l'historique et on trie def score_cableurs(): """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 index in range (0, len(HISTORIQUE)): histo_uid = HISTORIQUE[index][2] histo_action = HISTORIQUE[index][3] if histo_uid == uid and histo_action == u' inscription': inscriptions = inscriptions + 1 if histo_uid == uid and (u"debutAdhesion+" in histo_action): 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(): """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(): """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(): """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(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)] total = ['Total',0,0,0] for elem in SCORES: total[1]+=elem[1] total[2]+=elem[2] total[3]+=elem[3] total = [total] print affichage.tableau(data, titre=titre, largeur=largeur, alignement=alignement, swap=swap).encode(ENCODING) print affichage.tableau(total, titre=titre, largeur=largeur, alignement=alignement, swap=swap).encode(ENCODING) #### 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() if ARGS.nocolour: SWAP = [] else: SWAP = [None, "vert"] 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) print affichage.style(u"""stats_cableurs n'est pas un jouet, ni un outil pour comparer qui de deux membres actifs a fait le plus de câblages. C'est un outil qui sert au conseil d'administration et aux nounous pour le suivi. De plus, l'utiliser à tort et à travers occasionne de la charge sur la base de données des adhérents, que le script doit aller lire pour afficher les résultats. Merci d'user de ce script avec parcimonie, et de ne pas jouer à "qui à la plus grosse".""", ['rouge']).encode(ENCODING)