[stats_cableurs] on affiche les stats sur les machines, par mois

Ignore-this: 3e3d76242fcd7250d97409abb5b53fdb

darcs-hash:20090328124206-bd074-d5a2a44d0daf538ece093e91ce6deb5407128e24.gz
This commit is contained in:
Antoine Durand-Gasselin 2009-03-28 13:42:06 +01:00
parent 4a03074f05
commit f1cb76f449

View file

@ -1,8 +1,6 @@
#!/usr/bin/python
# -*- mode: python; coding: utf-8 -*-
#
# $Id: stats_cableurs.py,v 1.2 2007-09-29 17:50:09 dimino Exp $
#
# stats_cableurs.py
# -----------------
#
@ -25,228 +23,306 @@
# 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
import sys, re, datetime, time
sys.path.append("/usr/scripts/gestion/")
from ldap_crans import crans_ldap
from config import ann_scol
from affich_tools import cprint, anim
import time
from ldap_crans import CransLdap
from affich_tools import cprint
db = crans_ldap()
date_debut_ann_scol = time.mktime((ann_scol, 8, 1, 0, 0, 0, 0, 0, 0))
paiement_ann_scol = "paiement+%d" % ann_scol
db = CransLdap()
__DAYS_IN_PREVIOUS_MONTH = [datetime.timedelta(days) for days in
[ 31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30 ] ]
def parse_ligne_histo(ligne):
u"""Parse une ligne d'historique et renvoie (['dd', 'mm', 'yyyy'],
['date', 'heure', 'who', 'what'])"""
champ = ligne.replace(',', '').replace(': ', '').split(' ')
sdate = champ[0].split('/')
date = datetime.date(int(sdate[2]), int(sdate[1]), int(sdate[0]))
return date, champ
def parse_historique(truc):
u"""Parse l'historique"""
return [ parse_ligne_histo(ligne) for ligne in truc.historique() ]
def dec_date(date):
u"""retranche un mois à la date."""
return (date - __DAYS_IN_PREVIOUS_MONTH[date.month -1])
class ActionsCableurs:
u"""Cette classe s'occupe de recenser l'activité des différents
câbleurs."""
class StatsCableursBase:
u"""Classe prototype pour afficher des stats de câbleurs."""
colonnes = [('score', u'Son score')]
nbmois = 4
stats = {}
sablier = None
def __init__(self, mois):
def __init__(self, mois = -4):
self.sablier = anim(u"Récupération de la liste des câbleurs")
ldap_cableurs = db.search("droits=cableur")['adherent']
for i in ldap_cableurs:
self.stats[i.nom()] = []
self.sablier.reinit()
cprint('OK', 'vert')
self.get_stats(mois)
self.print_results()
def ajoute_actions(self, mois, machine):
u"""Ajoute dans les stats la liste des actions effectués par
chacuns des câbleurs sur la machine pendant les mois."""
for hist in machine.historique():
# On decoupe pour avoir un truc utilisable
champ = hist.replace(',', '').replace(': ', '').split(' ')
date = champ[0].split('/')
# On inspecte la date
if (int (date[1]), int(date[2])) in mois:
if self.stats.has_key(champ[2]):
self.stats[champ[2]].append(champ[3])
if mois > 0:
# si on demande depuis 09 (septembre) , on remonte
# jusqu'à septembre
self.nbmois = (datetime.date.today().month + 12 - mois) % 12
else:
self.stats[champ[2]] = [champ[3]]
# si on demande les stats sur 4 mois, on remonte sur 4
# mois
self.nbmois = - mois
def get_stats(self, mois):
u"""Récupère les statistiques des différents câbleurs sur les
différentes machines"""
# On récupère les statistiques
self.get_stats()
self.sablier = anim(u"Récupération de la liste des machines")
all_machines = db.search('host=*')
self.sablier.cycle()
machines = all_machines['machineFixe'] + all_machines['machineWifi']
self.sablier.reinit()
cprint('OK', 'vert')
# On les affiche
self.print_stats()
self.sablier = anim(u"Récupération des actions sur les machines", iter = len (machines))
for becane in machines:
self.ajoute_actions(mois, becane)
self.sablier.cycle()
self.sablier.reinit()
cprint('OK', 'vert')
def print_results(self, nombre= 0):
u"""Affiche les statistiques d'activité des différents câbleurs"""
def get_stats(self):
u"""Génération dummy de statistiques"""
self.stats = {}
def print_stats(self):
u"""Affiche pour chaque cableur les valeurs de ses différentes colonnes
définies dans self.colonnes."""
stats = self.stats
cableurs = stats.keys()
### Si quelqu'un trouve une manière plus élégante de faire…
try:
cableurs.sort(lambda x, y : cmp(stats[x]['score'], stats[y]['score']), reverse=True)
except TypeError:
cableurs.sort(lambda x, y : cmp(stats[x][0], stats[y][0]), reverse=True)
cableurs = self.stats.keys()
cableurs.sort(lambda x, y : cmp(len (self.stats[x]), len (self.stats[y])), reverse=True)
long_max = reduce(lambda m, c : max(m, len(c)), cableurs, len('cableur'))
colonnes = [('actions', u'Actions'),
('ins', u'Inscription'),
('mac', u'Change MAC'),
('host', u'Change DNS'),
('ip', u'Change IP')]
# Titres des colonnes
ligne = "%-*s" % (long_max, u'Câbleur')
for typ, nom in colonnes:
for typ, nom in self.colonnes:
ligne += " | %s" % nom
cprint(ligne)
# Ligne pour délimiter
ligne = ''.center(long_max, '-')
for typ, nom in colonnes:
for typ, nom in self.colonnes:
ligne += "-+-%s" % ''.center(len(nom), '-')
cprint(ligne)
# Statiqtiques par câbleur
for cableur in cableurs:
acts = self.stats[cableur]
score_cableur = {}
score_cableur['actions'] = len (acts)
for key, chaine in colonnes[1:]:
score_cableur[key] = len ([i for i in acts if re.search(key, i)])
acts = stats[cableur]
ligne = "%-*s" % (long_max, cableur)
for typ, nom in colonnes:
ligne += " | %*d" % (len(nom), score_cableur[typ])
for typ, nom in self.colonnes:
ligne += " | %*d" % (len(nom), acts[typ])
cprint(ligne)
def sort_events(self, events):
u"""Split une liste d'évènements selon les mois"""
sorted_events = []
since = datetime.date.replace(datetime.date.today(), day = 1)
backwards = self.nbmois
def donne_cableur(mois, adherent):
u""" Cherche le cableur qui a inscrit ou réinscrit un adhérent. """
cableur = None
# Est-ce qu'on recherche une inscription ou une reinscription?
if adherent.dateInscription() < date_debut_ann_scol:
action = 'reinscription'
action_filtre = paiement_ann_scol
else:
action = 'inscription'
action_filtre = 'inscription'
while backwards > 0:
sorted_events.append([ ev for ev in events if ev[0] >= since ])
events = [ ev for ev in events if ev[0] < since ]
backwards -= 1
since = dec_date(since)
for hist in adherent.historique():
# On decoupe pour avoir un truc utilisable
champ = hist.replace(',', '').replace(': ', '').split(' ')
# On inspecte la date
date = champ[0].split('/')
if int(date[1]) in mois and int(date[2]) == ann_scol:
# Maintenant on regarde si l'action recherchee est ici
if action_filtre in champ[3:]:
return action, champ[2]
sorted_events.append(events)
return sorted_events
return action, None
def calcul_score(mois):
u""" Calcul le score de tous les cableurs ayant inscrit ou
réinscrit quelqu'un pour l'année en cours. """
class StatsCableursMachines(StatsCableursBase):
u"""Cette classe s'occupe de recenser l'activité des différents
câbleurs sur les machines, ce qui représente le travail typique du
câbleur en milieu d'année"""
liste = db.search("paiement=2008")['adherent']
def ajoute_actions(self, machine, hist):
u"""Ajoute dans hist la liste des actions effectués par
chacuns des câbleurs sur la machine pendant les mois."""
score = {}
for adherent in liste:
action, cableur = donne_cableur(mois, adherent)
if cableur:
if not score.has_key(cableur):
score[cableur] = { 'inscription': 0,
'reinscription': 0 }
score[cableur][action] += 1
for date, champ in parse_historique(machine):
# On calcul le score total pour chaque cableur
for s in score.values():
s['total'] = 2 * s['inscription'] + s['reinscription']
# on ne va pas non plus compter les actions qu'on fait sur
# ses propres machines.
if machine.proprietaire().compte() != champ[2]:
return score
# Il se peut qu'une personne sans les droits câbleur ait
# effectué une action.
try:
hist[champ[2]].append( (date, champ[3]) )
except KeyError:
hist[champ[2]] = [ (date, champ[3]) ]
def classe(score={}):
u""" Retourne la liste des câbleurs classé par score total décroisant. """
cableurs = score.keys()
cableurs.sort(lambda x, y : cmp(score[x]['total'], score[y]['total']), reverse=True)
return cableurs
def get_stats(self):
u"""Récupère les statistiques des différents câbleurs sur les
différentes machines"""
# La liste des câbleurs en tant qu'entité ldap, histoire de bien
# faire apparaître ceux qui n'ont rien fait
ldap_cableurs = db.search("droits=cableur")['adherent']
# On récupère la liste des machines
all_machines = db.search('mid=*')
machines = all_machines['machineFixe'] + all_machines['machineWifi']
# hists permet de répartir toutes les actions sur les différents
# câbleurs.
hists = {}
for i in ldap_cableurs:
hists[i.compte()] = []
# on récupère l'historique des machines que l'on met dans hists
for becane in machines:
self.ajoute_actions(becane, hists)
split_hist = {}
for cableur in hists.keys():
split_hist[cableur] = self.sort_events(hists[cableur])
self.stats[cableur] = [ len(i) for i in split_hist[cableur] ]
score = sum (self.stats[cableur][:-1])
self.stats[cableur].insert(0, score)
month = datetime.date.today()
for i in range(self.nbmois):
self.colonnes.append( (i + 1, "%d/%02d" % (month.month, month.year - 2000)))
month = dec_date(month)
self.colonnes[0] = (0, "%d last" % self.nbmois)
self.colonnes.append( (self.nbmois +1, "< " + self.colonnes[-1][1]) )
if __name__ == "__main__":
nb_affiche = 10
mois = range(8, 11)
if len(sys.argv) > 1:
if sys.argv[1] == '-e':
mois = range(8, 13)
if len(sys.argv) > 2:
try:
nb_affiche = int(sys.argv[2])
except ValueError:
nb_affiche = 10
else:
try:
nb_affiche = int(sys.argv[1])
except ValueError:
nb_affiche = 10
StatsCableursMachines()
if sys.argv[1] == '--efficiency':
ActionsCableurs([(1, 2009), (2, 2009), (3, 2009)])
sys.exit(0)
score = calcul_score(mois)
classement = classe(score)
if nb_affiche > 0:
classement = classement[0:nb_affiche]
# On cherche les noms des câbleurs parceque c'est quand même mieux
nom_reel = {}
for cableur in classement:
nom_reel[cableur] = db.search('uid=%s' % cableur)['adherent'][0].Nom()
# Calcul des statistiques
total_inscription = 0
total_reinscription = 0
total = 0
for s in score.values():
total_inscription += s['inscription']
total_reinscription += s['reinscription']
total += s['total']
cprint(u"""Statistiques globales:
- inscriptions: %(inscription)d
- réinscription: %(reinscription)d
- total: %(total)d
""" % { 'inscription': total_inscription,
'reinscription': total_reinscription,
'total': total }, newline=False)
# Calcul la longueur du nom le plus long
long_max = reduce(lambda m, c : max(m, len(c)), nom_reel.values(), len('cableur'))
colonnes = [('inscription', u'inscription'),
('reinscription', u'réinscription'),
('total', u'score total')]
# Titres des colonnes
ligne = "%-*s" % (long_max, u'câbleur')
for typ, nom in colonnes:
ligne += " | %s" % nom
cprint(ligne)
# Ligne pour délimiter
ligne = ''.center(long_max, '-')
for typ, nom in colonnes:
ligne += "-+-%s" % ''.center(len(nom), '-')
cprint(ligne)
# Statiqtiques par câbleur
for cableur in classement:
score_cableur = score[cableur]
ligne = "%-*s" % (long_max, nom_reel[cableur])
for typ, nom in colonnes:
ligne += " | %*d" % (len(nom), score_cableur[typ])
cprint(ligne)
## class StatsCableursAdherents:
## u"""Cette classe s'occupe de recenser les actions que les câbleurs
## font sur les adhérents (en fait les {,re}adhésions)."""
##
## colonnes = [('inscription', u'inscription'),
## ('reinscription', u'réinscription'),
## ('total', u'score total')]
##
## date_debut_ann_scol = time.mktime((ann_scol, 8, 1, 0, 0, 0, 0, 0, 0))
## paiement_ann_scol = "paiement+%d" % ann_scol
##
## def donne_cableur(mois, adherent):
## u""" Cherche le cableur qui a inscrit ou réinscrit un adhérent. """
## cableur = None
##
## # Est-ce qu'on recherche une inscription ou une reinscription?
## if adherent.dateInscription() < self.date_debut_ann_scol:
## action = 'reinscription'
## action_filtre = self.paiement_ann_scol
## else:
## action = 'inscription'
## action_filtre = 'inscription'
##
## for hist in adherent.historique():
## # On decoupe pour avoir un truc utilisable
## champ = hist.replace(',', '').replace(': ', '').split(' ')
## # On inspecte la date
## date = champ[0].split('/')
## if int(date[1]) in mois and int(date[2]) == ann_scol:
## # Maintenant on regarde si l'action recherchee est ici
## if action_filtre in champ[3:]:
## return action, champ[2]
##
## return action, None
##
## def calcul_score(mois):
## u""" Calcul le score de tous les cableurs ayant inscrit ou
## réinscrit quelqu'un pour l'année en cours. """
##
## liste = db.search("paiement=2008")['adherent']
##
## score = {}
## for adherent in liste:
## action, cableur = donne_cableur(mois, adherent)
## if cableur:
## if not score.has_key(cableur):
## score[cableur] = { 'inscription': 0,
## 'reinscription': 0 }
## score[cableur][action] += 1
##
## # On calcul le score total pour chaque cableur
## for s in score.values():
## s['total'] = 2 * s['inscription'] + s['reinscription']
##
## return score
##
## def classement(score={}):
## u""" Retourne la liste des câbleurs classé par score total décroisant. """
## cableurs = score.keys()
## cableurs.sort(lambda x, y : cmp(score[x]['total'], score[y]['total']), reverse=True)
## return cableurs
##
##
##
## if __name__ == "__main__":
## nb_affiche = 10
## mois = range(8, 11)
## if len(sys.argv) > 1:
## if sys.argv[1] == '-e':
## mois = range(8, 13)
## if len(sys.argv) > 2:
## try:
## nb_affiche = int(sys.argv[2])
## except ValueError:
## nb_affiche = 10
## else:
## try:
## nb_affiche = int(sys.argv[1])
## except ValueError:
## nb_affiche = 10
##
## if sys.argv[1] == '--efficiency':
## ActionsCableurs([(1, 2009), (2, 2009), (3, 2009)])
## sys.exit(0)
##
## score = calcul_score(mois)
## classement = classe(score)
##
## if nb_affiche > 0:
## classement = classement[0:nb_affiche]
##
## # On cherche les noms des câbleurs parceque c'est quand même mieux
## nom_reel = {}
## for cableur in classement:
## nom_reel[cableur] = db.search('uid=%s' % cableur)['adherent'][0].Nom()
##
## # Calcul des statistiques
## total_inscription = 0
## total_reinscription = 0
## total = 0
## for s in score.values():
## total_inscription += s['inscription']
## total_reinscription += s['reinscription']
## total += s['total']
## cprint(u"""Statistiques globales:
## - inscriptions: %(inscription)d
## - réinscription: %(reinscription)d
## - total: %(total)d
##
## """ % { 'inscription': total_inscription,
## 'reinscription': total_reinscription,
## 'total': total }, newline=False)
##
## # Calcul la longueur du nom le plus long
## long_max = reduce(lambda m, c : max(m, len(c)), nom_reel.values(), len('cableur'))
##
##
## # Titres des colonnes
## ligne = "%-*s" % (long_max, u'câbleur')
## for typ, nom in colonnes:
## ligne += " | %s" % nom
## cprint(ligne)
## # Ligne pour délimiter
## ligne = ''.center(long_max, '-')
## for typ, nom in colonnes:
## ligne += "-+-%s" % ''.center(len(nom), '-')
## cprint(ligne)
## # Statiqtiques par câbleur
## for cableur in classement:
## score_cableur = score[cableur]
## ligne = "%-*s" % (long_max, nom_reel[cableur])
## for typ, nom in colonnes:
## ligne += " | %*d" % (len(nom), score_cableur[typ])
## cprint(ligne)