From 22fc2f1c0ac2f65642615352927d62e9d0064fc1 Mon Sep 17 00:00:00 2001 From: glondu Date: Sun, 26 Mar 2006 06:01:12 +0200 Subject: [PATCH] Pour viter toute confusion future, on stocke les dates de blacklist en nombre de secondes coules depuis Epoch. darcs-hash:20060326040112-68412-f01c2b7b858e2b5ece65beac8b7943ad7919724c.gz --- gestion/gest_crans.py | 55 +++++++++++---- gestion/ldap_crans.py | 156 +++++++++++++++++++++--------------------- gestion/whos.py | 20 ++++-- 3 files changed, 134 insertions(+), 97 deletions(-) diff --git a/gestion/gest_crans.py b/gestion/gest_crans.py index d7c89f98..77e7a93b 100755 --- a/gestion/gest_crans.py +++ b/gestion/gest_crans.py @@ -23,7 +23,8 @@ To = ['fred@crans.org' , 'glondu@crans.org', 'chove@crans.org'] import string, os, sys from whos import aff -import time, signal, getopt +import signal, getopt +from time import strftime, strptime, localtime, mktime import re import affich_tools, config @@ -810,28 +811,33 @@ def confirm(clas) : affich_tools.prompt(u"Appuyez sur ENTREE pour continuer") def set_blackliste(clas) : - """ Edite ou ajoute un item de la blackliste """ + """ Édite ou ajoute un item de la blackliste """ bl = clas.blacklist() if not bl : # Pas d'entrée à éditer index = -1 else : - arg = u'--title "Edition blackliste de %s" ' % clas.Nom() + arg = u'--title "Édition blackliste de %s" ' % clas.Nom() arg+= u'--menu "Choisir l\'entrée à éditer :" 0 0 0 ' arg+= u'"0" "Ajouter une nouvelle entrée" ' i = 1 for b in bl : - arg += '"%i" "%s" ' % (i, b) + champs = b.split('$') + arg += '"%i" "%s [%s]" ' % (i, champs[2], champs[3]) i += 1 - annul , res = dialog(arg) + annul, res = dialog(arg) if annul : return 1 index = int(res[0]) - 1 - # Edition - if index != -1 : - t = clas.blacklist()[index].split(',') + # Édition + if index != -1: + t = clas.blacklist()[index].split('$') + if t[0] != 'now': + t[0] = strftime('%d/%m/%Y %H:%M', localtime(int(t[0]))) + if t[1] != 'now' and t[1] != '-': + t[1] = strftime('%d/%m/%Y %H:%M', localtime(int(t[1]))) else : - t = [ 'now' , '-', '', '' ] + t = ['now', '-', '', ''] step = 1 while 1 : @@ -857,16 +863,37 @@ def set_blackliste(clas) : arg+= u'"- pour fin indéterminée" 2 25 "" 0 0 0 0 ' arg+= u'"Les jours de début et de fin sont inclus." 3 1 "" 0 0 0 0 ' arg+= u'"Sanction : %s" 4 1 "" 0 0 0 0 ' % t[2] - arg+= u'"Commentaire : (ne pas mettre de virgule)" 5 1 "%s" 6 1 52 0 ' % t[3] + arg+= u'"Commentaire : " 5 1 "%s" 6 1 52 0 ' % t[3] annul , r = dialog(arg) if annul : return 1 # Ajout des heures t[0] = r[0].strip() - if len(t[0]) == 10 : t[0] += ' 00:00' + if len(t[0]) == 10: t[0] += ' 00:00' t[1] = r[1].strip() - if len(t[1]) == 10 : t[1] += ' 23:59' + if len(t[1]) == 10: t[1] += ' 23:59' + + # Vérification des heures + try: + if t[0] != 'now': + t[0] = int(mktime(strptime(t[0], '%d/%m/%Y %H:%M'))) + except: + arg = u'--title "Erreur" ' + arg+= u'--msgbox "Heure de début incorrecte (%s)\n\n\n" 0 0' % t[0] + dialog(arg) + step -= 1 + continue + try: + if t[1] != 'now' and t[1] != '-': + t[1] = int(mktime(strptime(t[1], '%d/%m/%Y %H:%M'))) + except: + arg = u'--title "Erreur" ' + arg+= u'--msgbox "Heure de fin incorrecte (%s)\n\n\n" 0 0' % t[1] + dialog(arg) + step -= 1 + continue + # Commentaire c = r[2].strip() login = script_utilisateur @@ -882,7 +909,7 @@ def set_blackliste(clas) : if index == -1 : clas.blacklist(t) else : - clas.blacklist( ( index, t ) ) + clas.blacklist(( index, t )) step += 1 except ValueError, c : arg = u'--title "Erreur" ' @@ -2038,7 +2065,7 @@ Subject: Bugreport %s # Erreur trop tot probablement serv = '' if serv : - mn = int(time.strftime('%M')) + mn = int(strftime('%M')) # Restart toutes les 10 min : 03, 13, 23, 33, 43, 53 t = ( 13 - mn % 10 ) % 10 + 1 # Certaines machines le font -Aà 4-b if t == 0 : t = 10 diff --git a/gestion/ldap_crans.py b/gestion/ldap_crans.py index 47fc3f38..5daf197d 100755 --- a/gestion/ldap_crans.py +++ b/gestion/ldap_crans.py @@ -16,7 +16,6 @@ import ldap, ldap.modlist import config, annuaires, iptools, chgpass, user_tests, cPickle from chgpass import chgpass from affich_tools import coul, prompt -from time import sleep, localtime date_format = '%d/%m/%Y %H:%M' hostname = gethostname().split(".")[0] @@ -158,18 +157,16 @@ def is_actif(sanction): Retourne True ou False suivant si la sanction fournie (chaîne venant de blacklist) est active ou non """ - bl = sanction.split(',') - try: - now = time.time() - debut = time.mktime( time.strptime(bl[0], date_format) ) - if bl[1] == '-': - fin = now + 1 - else: - fin = time.mktime( time.strptime(bl[1], date_format) ) - return debut < now and fin > now - except: - return False - + bl = sanction.split('$') + now = time.time() + debut = int(bl[0]) + if bl[1] == '-': + fin = now + 1 + else: + fin = int(bl[1]) + return debut < now and fin > now + + def format_mac(mac): """ Formatage des adresses mac @@ -323,7 +320,7 @@ class crans_ldap: sys.stderr.write("ERREUR : serveur LDAP injoignable\n") sys.exit(1) else: - sleep(0.3) + time.sleep(0.3) def exist(self, arg): """ @@ -620,7 +617,7 @@ class crans_ldap: # considéré non ok s'il n'a pas fourni sa carte d'etudiant # alors que l'on est desormais en periode de bloquage # définifif (cf config.py). - if localtime()[1] == 9: + if time.localtime()[1] == 9: # Pour septembre paiement année précédente ok el = "(|(paiement=%d)(paiement=%d))" % (ann_scol, ann_scol-1) else: @@ -792,9 +789,11 @@ class crans_ldap: __machines = () def all_machines(self, graphic=False): - """Renvoie toutes les machines autorisées. + """ + Renvoie toutes les machines autorisées. - Cela affiche des trucs et des bidules si graphic est à True.""" + Cela affiche des trucs et des bidules si graphic est à True. + """ if graphic: from affich_tools import anim, cprint, OK if not self.__machines: # Récolte des données @@ -843,23 +842,26 @@ class base_classes_crans(crans_ldap): def blacklist_actif(self): """ Vérifie si l'instance courante est blacklistée. - Retourne les sanctions en cours (liste) - Retourne une liste vide si aucune sanction en cours + Retourne les sanctions en cours (liste). + Retourne une liste vide si aucune sanction en cours. """ return self.blacklist_all()[0].keys() def blacklist_all(self): """ - Vérifie si l'instance courante est blacklistée ou a été blacklistée. - Retourne les sanctions en cours sous forme de dictionnaire avec comme clef - la sanction et comme valeur une liste de couple de dates correspondant aux + Vérifie si l'instance courante est blacklistée ou a été + blacklistée. Retourne les sanctions en cours sous la forme + d'un couple de deux dictionnaires (l'un pour les sanctions + actives, l'autre pour les inactive), chacun ayant comme + clef la sanction et comme valeur une liste de couple de + dates (en secondes depuis epoch) correspondant aux différentes périodes de sanctions. - ex: { 'upload' : (('17/11/2004 00:00','20/11/2004 00:00'), ('...', '...')) } + ex: {'upload': [(1143336210, 1143509010), ...]} """ bl_liste = self._data.get('blacklist', []) - if 'machineWifi' in self._data['objectClass'] or 'machineFixe' in self._data['objectClass']: + if isinstance(self, Machine): # Il faut aussi regarder la blackliste du propriétaire p = self.proprietaire() bl_liste += p.blacklist() @@ -868,44 +870,42 @@ class base_classes_crans(crans_ldap): inactifs = {} for sanction in bl_liste: - s = sanction.split(',')[2] + champs = sanction.split('$') + s = champs[2] if is_actif(sanction): - if not s in actifs: - actifs[s] = [] - actifs[s].append((sanction.split(',')[0], - sanction.split(',')[1])) + actifs.setdefault(s, []).append((champs[0], champs[1])) else: - if not s in inactifs: - inactifs[s] = [] - inactifs[s].append((sanction.split(',')[0], - sanction.split(',')[1])) + inactifs.setdefault(s, []).append((champs[0], champs[1])) return (actifs, inactifs) def blacklist(self, new=None): """ Blacklistage de la ou de toutes la machines du propriétaire - new est une liste de 4 termes: - [ debut_sanction, fin_sanction, sanction, commentaire ] - début et fin doivent être sous la forme donnée par date_format - pour un début ou fin immédiate mettre now - pour une fin indéterminée mettre '-' - - pour modifier une entrée donner un tuple de deux termes : - ( index dans blacklist à modifier, nouvelle liste ) - l'index est celui obtenu dans la liste retournée par blacklist() + * new est une liste de 4 termes : + [debut_sanction, fin_sanction, sanction, commentaire] + * début et fin sont le nombre de secondes depuis epoch + * pour un début ou fin immédiate mettre now + * pour une fin indéterminée mettre '-' + Les données sont stockées dans la base sous la forme : + debut$fin$sanction$commentaire + Pour modifier une entrée donner un tuple de deux termes : + (index dans blacklist à modifier, nouvelle liste), + l'index étant celui dans la liste retournée par blacklist(). """ - if not self._data.has_key('blacklist'): - self._data['blacklist'] = [] - liste = list(self._data['blacklist']) - if new == None: return map(decode, liste) + liste = self._data.setdefault('blacklist', [])[:] + if new == None: + return map(decode, liste) if type(new) == tuple: - # Modif + # Modification index = new[0] new = new[1] if new == '': liste.pop(index) + # La ligne suivante est inutile, elle est laissée dans un souci de clarté self._set('blacklist', liste) + # La liste n'a pas changé, mais son contenu, lui, a bien changé + self.modifs.setdefault('blacklist', None) return liste else: index = -1 @@ -913,55 +913,57 @@ class base_classes_crans(crans_ldap): if type(new) != list or len(new) != 4: raise TypeError - # Verif que les dates sont OK - if new[0] == 'now': - new[0] = time.strftime(date_format) - debut = 0 + # Verification que les dates sont OK + if new[0] == 'now': + debut = new[0] = int(time.time()) else: - try: debut = int(time.mktime(time.strptime(new[0], date_format))) + try: debut = new[0] = int(new[0]) except: raise ValueError(u'Date de début blacklist invalide') - if new[1] == 'now': - new[1] = time.strftime(date_format) - fin = 0 - elif new[1] != '-': - try: fin = int(time.mktime(time.strptime(new[1], date_format))) - except: raise ValueError(u'Date de fin blacklist invalide') - else: + if new[1] == 'now': + fin = new[1] = int(time.time()) + elif new[1] == '-': fin = -1 + else: + try: fin = new[1] = int(new[1]) + except: raise ValueError(u'Date de fin blacklist invalide') if debut == fin: - raise ValueError(u'Dates de début et fin identiques') + raise ValueError(u'Dates de début et de fin identiques') + elif fin != -1 and debut > fin: + raise ValueError(u'Date de fin avant date de début') - # On prend en compte le fuseau horaire et on dépasse la fin - # de sanction d'1min pour être sur quelle périmé. - fin = fin+60-time.timezone + # On dépasse la fin de sanction d'1min pour être sûr qu'elle est périmée. + fin = fin + 60 - new_c = ','.join(new) + new_c = '$'.join(map(str, new)) new_c = preattr(new_c)[1] - if index != -1: - liste[index] = new_c + touched = True + if index != -1: + if liste[index] == new_c: + touched = False + else: + liste[index] = new_c else: - liste = liste + [ new_c ] + liste.append(new_c) - if self._data['blacklist'] != liste: + if touched: + # La ligne suivante est inutile, elle est laissée dans un souci de clarté self._data['blacklist'] = liste self.modifs.setdefault('blacklist_' + new[2], None) if not hasattr(self, "_blacklist_restart"): self._blacklist_restart = {} - if not self._blacklist_restart.has_key(new[2]): - self._blacklist_restart[new[2]] = [ debut, fin ] - else: - if debut not in self._blacklist_restart[new[2]]: - self._blacklist_restart[new[2]].append(debut) - if fin != -1 and fin not in self._blacklist_restart[new[2]]: - self._blacklist_restart[new[2]].append(fin) + restart = self._blacklist_restart.setdefault(new[2], []) + if debut not in restart: + restart.append(debut) + if fin != -1 and fin not in restart: + restart.append(fin) return liste def restore(self): - """ Restore les données à l'état initial """ + """ Restore les données à l'état initial (ou pas) """ self._data = self._init_data.copy() self.modifs = {} @@ -1079,7 +1081,7 @@ class base_classes_crans(crans_ldap): liste_historique.append(ligne) modif = ', '.join(liste_historique) - timestamp = localtime() + timestamp = time.localtime() hist = "%s, %s" % ( time.strftime(date_format, timestamp), script_utilisateur ) # On loggue diff --git a/gestion/whos.py b/gestion/whos.py index 5cdbf1d8..a6ca6a22 100755 --- a/gestion/whos.py +++ b/gestion/whos.py @@ -48,6 +48,7 @@ except: base = None +from time import strftime, localtime from ldap_crans import is_actif, crans_ldap, ann_scol, AssociationCrans, hostname from ldap_crans import MachineWifi, BorneWifi from affich_tools import * @@ -640,22 +641,29 @@ def club_details(club) : ########################################### # Fonctions annexes de formatage de données -def _blacklist(clas) : +def _blacklist(clas): """ Formatage blackliste de la classe fournie """ f = u'' - for event in clas.blacklist() : - if is_actif(event) : + for event in clas.blacklist(): + if is_actif(event): # Colorisation si sanction en cours c = 'rouge' else : c = 'blanc' - f += u"%s\n\t " % coul(u'du %s au %s : %s, %s' % tuple(event.split(',')) ,c) + event = event.split('$') + dates = strftime('%d/%m/%Y %H:%M', localtime(int(event[0]))) + if event[1] == '-': + dates = u'à partir du %s' % dates + else: + dates = u'du %s au ' % dates + dates += strftime('%d/%m/%Y %H:%M', localtime(int(event[1]))) + f += u"%s\n\t " % coul(u'%s : %s [%s]' % (dates, event[2], event[3]), c) f = f[:-6] # supression des espaces superflus - if f : + if f: return coul(u'Blackliste : ', 'gras') + f - else : + else: return '' def _info(clas) :