scripts/gestion/dialog/blacklist.py
2015-11-23 23:55:49 +01:00

233 lines
10 KiB
Python

#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
u"""
Copyright (C) Valentin Samir
Licence : GPLv3
"""
import sys
import time
import ldap
import traceback
if '/usr/scripts' not in sys.path:
sys.path.append('/usr/scripts')
from gestion import affichage
import gestion.config as config
import lc_ldap.objets as objets
import lc_ldap.attributs as attributs
import lc
from CPS import TailCall, tailcaller, Continue
from CPS import unicode_of_Error
class Dialog(lc.Dialog):
@tailcaller
def edit_blacklist_select(self, obj, title, cont):
"""
Permet de choisir une blackliste parmis celle de obj oubien une nouvelle blacklist.
Retourne (index, bl) où bl est un dictionnaire représentant la blackliste et index
l'index de la blackliste dans obj['blacklist'] ou new pour une nouvelle blacklist
"""
def box():
choices = [('new', 'Ajouter une nouvelle blackliste')]
index = 0
for bl in obj['blacklist']:
choices.append(
(
str(index),
affichage.style(
"%s [%s]" % (bl['type'], bl['comm']),
'rouge' if bl['actif'] else None,
dialog=True
)
)
)
index+=1
return self.dialog.menu(
"Éditer une blacklist ou en ajouter une nouvelle ?\n(les blacklistes actives apparaissent en rouge)",
width=0,
timeout=self.timeout,
height=0,
menu_height=0,
item_help=0,
title=title,
scrollbar=True,
colors=True,
cancel_label="Retour",
backtitle=self._connected_as(),
choices=choices)
def todo(tag):
if tag == 'new':
return tag, {'debut':0, 'fin':0, 'type':'', 'comm':''}
else:
bl = {}
bl.update(obj['blacklist'][int(tag)].value)
return tag, bl
(code, tag) = self.handle_dialog(cont, box)
retry_cont = TailCall(self.edit_blacklist_select, obj=obj, title=title, cont=cont)
return self.handle_dialog_result(
code=code,
output=tag,
cancel_cont=cont,
error_cont=retry_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [tag])]
)
@tailcaller
def edit_blacklist_type(self, title, cont):
"""Permet de choisir un type de blackliste pour les nouvelles blacklistes"""
retry_cont = TailCall(self.edit_blacklist_type, title=title, cont=cont)
def box():
return self.dialog.menu(
"Choisissez un type de blacklist",
width=0,
height=0,
menu_height=0,
item_help=0,
timeout=self.timeout,
title=title,
scrollbar=True,
colors=True,
cancel_label="Retour",
backtitle=self._connected_as(),
choices=[(k,v) for (k,v) in config.blacklist_items.items()])
def todo(tag, retry_cont):
if tag in config.blacklist_items:
return tag
else:
self.dialog.msgbox("%s n'est pas une blacklist" % tag, timeout=self.timeout,
title="Erreur rencontrée", width=73, height=10)
raise Continue(retry_cont)
(code, tag) = self.handle_dialog(cont, box)
return self.handle_dialog_result(
code=code,
output=tag,
cancel_cont=cont(bl=None),
error_cont=retry_cont,
codes_todo=[([self.dialog.DIALOG_OK], todo, [tag, retry_cont])]
)
def edit_blacklist(self, obj, title, update_obj, cont, bl=None, tag=None, bl_type=None,
debut=None, fin=None, comm=None):
"""Pour éditer les blacklistes d'un objet lc_ldap"""
self_cont = TailCall(self.edit_blacklist, obj=obj, title=title, update_obj=update_obj,
cont=cont, bl=bl, tag=tag, bl_type=bl_type, debut=debut, fin=fin, comm=comm)
# Si bl ou tag ne sont pas définit on les demande
if bl is None or tag is None:
bl_type = None
debut = None
fin = None
comm = None
tag, bl = self.edit_blacklist_select(obj, title, cont(**{update_obj:obj}))
if bl_type is None and tag == 'new':
bl['type'] = self.edit_blacklist_type(title, self_cont(obj=obj))
elif tag == 'new':
bl['type'] = bl_type
# Cas de l'ajout d'un blacklist
if tag == 'new':
# Si debut n'est pas encore spécifié, on le demande
if debut is None:
debut_tuple = self.get_timestamp(title=title, text="Choisir le début de la blacklist",
cont=self_cont(bl=bl, tag=tag, bl_type=None, debut=None, fin=None, comm=None))
debut = int(time.mktime(time.struct_time(debut_tuple + (0, 0, -1))))
# Idem pour fin
if fin is None:
if self.dialog.yesno("Mettre une date de fin ?", title=title,
timeout=self.timeout) == self.dialog.DIALOG_OK:
fin_tuple = self.get_timestamp(title=title, text="Choisir la date de fin :",
cont=self_cont(bl=bl, tag=tag, bl_type=bl_type,
debut=None, fin=None, comm=None))
fin = int(time.mktime(time.struct_time(debut_tuple + (0, 0, -1))))
else:
fin = '-'
bl['debut']=debut
bl['fin']=fin
bl['comm']=self.get_comment(title=title, text="Commentaire ?",
cont=self_cont(bl=bl, tag=tag, bl_type=bl['type'], debut=debut, fin=None, comm=None))
if self.confirm_item(item=attributs.attrify(bl, 'blacklist', self.conn),
title="Ajouter la blacklist ?"):
try:
with self.conn.search(dn=obj.dn, scope=0, mode='rw')[0] as obj:
obj['blacklist'].append(bl)
obj.validate_changes()
obj.history_gen()
obj.save()
# On s'en va en mettant à jour dans la continuation la valeur de obj
raise Continue(self_cont(bl=None, obj=obj))
# On propage les Continue
except self.error_to_raise:
raise
# En cas d'une autre erreur, on l'affiche et on retourne
except (Exception, ldap.OBJECT_CLASS_VIOLATION) as e:
self.dialog.msgbox(traceback.format_exc() if self.debug_enable else ("%s" % unicode_of_Error(e)), timeout=self.timeout,
title="Erreur rencontrée", width=73)
raise Continue(self_cont(obj=obj))
else:
raise Continue(self_cont(bl=None, obj=obj))
# Cas de l'édition d'une blacklist
else:
if debut is None:
# Mettre un warning pour éditer (seulement quand debut vaut None pour ne pas le répéter à chaque fois que l'on revient en arrière par la suite
if not self.confirm_item(item=attributs.attrify(bl, 'blacklist', self.conn), title="Éditer la blackliste ?"):
raise Continue(self_cont(bl=None, obj=obj))
debut = time.localtime(bl['debut'])
debut_tuple = self.get_timestamp(title=title, text="Choisir le début de la blacklist", cont=self_cont(bl=bl, tag=tag, debut=None, fin=None, comm=None),
day=debut.tm_mday,
month=debut.tm_mon,
year=debut.tm_year,
hour=debut.tm_hour,
minute=debut.tm_min,
second=debut.tm_sec
)
debut = int(time.mktime(time.struct_time(debut_tuple + (0, 0, -1))))
bl['debut'] = debut
if fin is None:
if self.dialog.yesno("Mettre une date de fin ?", timeout=self.timeout, title=title) == self.dialog.DIALOG_OK:
if bl['fin'] == '-':
fin = time.localtime()
else:
fin = time.localtime(bl['fin'])
fin_tuple = self.get_timestamp(title=title, text="Choisir la date de fin :", cont=self_cont(bl=bl, tag=tag, debut=debut, fin=None, comm=None),
day=fin.tm_mday,
month=fin.tm_mon,
year=fin.tm_year,
hour=fin.tm_hour,
minute=fin.tm_min,
second=fin.tm_sec
)
fin = int(time.mktime(time.struct_time(debut_tuple + (0, 0, -1))))
else:
fin = '-'
bl['fin'] = fin
bl['comm']=self.get_comment(title=title, text="Commentaire ?", init=bl['comm'], cont=self_cont(bl=bl, tag=tag, bl_type=bl['type'], debut=debut, fin=None, comm=None))
if self.confirm_item(item=attributs.attrify(bl, 'blacklist', self.conn), title="Modifier la blacklist ?"):
try:
with self.conn.search(dn=obj.dn, scope=0, mode='rw')[0] as obj:
obj['blacklist'][int(tag)]=bl
obj.validate_changes()
obj.history_gen()
obj.save()
# On s'en va en mettant à jour dans la continuation la valeur de obj
raise Continue(self_cont(bl=None, obj=obj))
# On propage les Continue
except self.error_to_raise:
raise
# En cas d'une autre erreur, on l'affiche et on retourne au menu d'édition
except (Exception, ldap.OBJECT_CLASS_VIOLATION) as e:
self.dialog.msgbox(traceback.format_exc() if self.debug_enable else "%s" % unicode_of_Error(e), timeout=self.timeout, title="Erreur rencontrée", width=73)
raise Continue(self_cont)
else:
raise Continue(self_cont(bl=None, obj=obj))