#!/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 = sys.stdout.encoding or "UTF-8" @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)