Ménage d'hiver partie 2
This commit is contained in:
parent
b9bd5ab1fc
commit
bb0bedf1fd
9 changed files with 204 additions and 205 deletions
|
@ -1 +0,0 @@
|
||||||
stats_cableurs2.py
|
|
204
utils/stats_cableurs.py
Executable file
204
utils/stats_cableurs.py
Executable file
|
@ -0,0 +1,204 @@
|
||||||
|
#!/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 = 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=*))' % (config.gtf_debut_periode_transitoire,), sizelimit=2000)
|
||||||
|
return list(adherents.data)
|
||||||
|
|
||||||
|
@static_var(("data", []))
|
||||||
|
def factures(regen=False):
|
||||||
|
"""Fonction évaluée paresseusement pour retourner la liste des factures"""
|
||||||
|
|
||||||
|
if regen or not factures.data:
|
||||||
|
factures.data = DB.search(u'(&(|(debutAdhesion>=%(now)s)(debutConnexion>=%(now)s))(fid=*))' % {
|
||||||
|
'now': config.gtf_debut_periode_transitoire,
|
||||||
|
}, sizelimit=0)
|
||||||
|
return list(factures.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)(droits=bureau))')
|
||||||
|
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', [])
|
||||||
|
for histo_line in histo:
|
||||||
|
champ = parse_historique(histo_line)[0]
|
||||||
|
champ_action = parse_historique(histo_line)[1]
|
||||||
|
date = parse_historique(histo_line)[2]
|
||||||
|
if (u' inscription' in champ_action or u'Adhesion+' in champ_action) and date > datetime.date(ann_scol, 8, 1):
|
||||||
|
HISTORIQUE.append(champ)
|
||||||
|
|
||||||
|
for facture in factures():
|
||||||
|
histo = facture.get('historique', [])
|
||||||
|
for histo_line in histo:
|
||||||
|
champ = parse_historique(histo_line)[0]
|
||||||
|
champ_action = parse_historique(histo_line)[1]
|
||||||
|
date = parse_historique(histo_line)[2]
|
||||||
|
if u'controle' 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 = controles = 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 += 1
|
||||||
|
if histo_uid == uid and (u"debutAdhesion+" in histo_action):
|
||||||
|
reinscriptions += 1
|
||||||
|
if histo_uid == uid and (u"controle" in histo_action):
|
||||||
|
controles += 1
|
||||||
|
score = 2*inscriptions + reinscriptions + controles
|
||||||
|
SCORES.append(["%s %s" % (prenom, nom), score, inscriptions, reinscriptions, controles])
|
||||||
|
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", u"Contrôles"]
|
||||||
|
largeur = [25, 8, 16, 16, 16]
|
||||||
|
alignement = ["c", "c", "c", "c", "c"]
|
||||||
|
data = [[elem for elem in SCORES[index]] for index in xrange(limit)]
|
||||||
|
total = [0]*4
|
||||||
|
for elem in SCORES:
|
||||||
|
total = [total[i] + elem[i+1] for i in xrange(len(total))]
|
||||||
|
total = [["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)
|
|
@ -1,204 +0,0 @@
|
||||||
#!/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 = 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=*))' % (config.gtf_debut_periode_transitoire,), sizelimit=2000)
|
|
||||||
return list(adherents.data)
|
|
||||||
|
|
||||||
@static_var(("data", []))
|
|
||||||
def factures(regen=False):
|
|
||||||
"""Fonction évaluée paresseusement pour retourner la liste des factures"""
|
|
||||||
|
|
||||||
if regen or not factures.data:
|
|
||||||
factures.data = DB.search(u'(&(|(debutAdhesion>=%(now)s)(debutConnexion>=%(now)s))(fid=*))' % {
|
|
||||||
'now': config.gtf_debut_periode_transitoire,
|
|
||||||
}, sizelimit=0)
|
|
||||||
return list(factures.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)(droits=bureau))')
|
|
||||||
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', [])
|
|
||||||
for histo_line in histo:
|
|
||||||
champ = parse_historique(histo_line)[0]
|
|
||||||
champ_action = parse_historique(histo_line)[1]
|
|
||||||
date = parse_historique(histo_line)[2]
|
|
||||||
if (u' inscription' in champ_action or u'Adhesion+' in champ_action) and date > datetime.date(ann_scol, 8, 1):
|
|
||||||
HISTORIQUE.append(champ)
|
|
||||||
|
|
||||||
for facture in factures():
|
|
||||||
histo = facture.get('historique', [])
|
|
||||||
for histo_line in histo:
|
|
||||||
champ = parse_historique(histo_line)[0]
|
|
||||||
champ_action = parse_historique(histo_line)[1]
|
|
||||||
date = parse_historique(histo_line)[2]
|
|
||||||
if u'controle' 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 = controles = 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 += 1
|
|
||||||
if histo_uid == uid and (u"debutAdhesion+" in histo_action):
|
|
||||||
reinscriptions += 1
|
|
||||||
if histo_uid == uid and (u"controle" in histo_action):
|
|
||||||
controles += 1
|
|
||||||
score = 2*inscriptions + reinscriptions + controles
|
|
||||||
SCORES.append(["%s %s" % (prenom, nom), score, inscriptions, reinscriptions, controles])
|
|
||||||
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", u"Contrôles"]
|
|
||||||
largeur = [25, 8, 16, 16, 16]
|
|
||||||
alignement = ["c", "c", "c", "c", "c"]
|
|
||||||
data = [[elem for elem in SCORES[index]] for index in xrange(limit)]
|
|
||||||
total = [0]*4
|
|
||||||
for elem in SCORES:
|
|
||||||
total = [total[i] + elem[i+1] for i in xrange(len(total))]
|
|
||||||
total = [["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)
|
|
Loading…
Add table
Add a link
Reference in a new issue