scripts/utils/stats_cableurs2.py
2015-08-28 14:41:10 +02:00

174 lines
6.5 KiB
Python
Executable file

#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
#
# stats_cableurs.py
# -----------------
#
# Copyright (C) 2013-2015 Raphaël-David Lasseri <lasseri@crans.org>,
# Pierre-Elliott Bécue <becue@crans.org>,
#
# 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)