338 lines
13 KiB
Python
338 lines
13 KiB
Python
#!/bin/bash /usr/scripts/python.sh
|
||
# -*- coding: utf-8 -*-
|
||
|
||
from gestion.affichage import style, tableau
|
||
import importlib
|
||
import os
|
||
import time
|
||
import ldap
|
||
import sys
|
||
import gestion.config as config
|
||
|
||
# Import inutile, mais on en a besoin pour que le
|
||
# script continue à fonctionner.
|
||
import gestion
|
||
import gestion.annuaires_pg
|
||
import gestion.hptools2 as hptools2
|
||
|
||
import lc_ldap.attributs as attributs
|
||
|
||
def try_import(lib):
|
||
"""
|
||
Cette fonction sert à faire de l'import soft : si l'import
|
||
crashe, par exemple, si le fichier de secrets ne peut être
|
||
lu par un apprenti, ça permet toujours d'utiliser ce
|
||
qui n'utilise pas l'import raté.
|
||
"""
|
||
if not isinstance(lib, unicode):
|
||
lib = lib.decode('utf-8')
|
||
try:
|
||
lib = importlib.import_module(lib)
|
||
except:
|
||
if sys.stdout.isatty():
|
||
print (u"Impossible d'importer %s, c'est sans doute un problème de droits." % lib).encode('utf-8')
|
||
lib = None
|
||
return lib
|
||
|
||
def prise_etat(chbre):
|
||
"""Récupère l'état d'une prise"""
|
||
if chbre in ["????", "EXT"]:
|
||
return style(u"Aucune adresse connue", "violet")
|
||
bat = chbre[0].lower()
|
||
chbre = chbre[1:]
|
||
try:
|
||
prise = gestion.annuaires_pg.chbre_prises(batiment=bat, chambre=chbre)
|
||
except gestion.annuaires_pg.ChbreNotFound:
|
||
return style(u"Chambre inconnue", "violet")
|
||
|
||
swid, port = int(prise[0]), int(prise[1:])
|
||
switch_name = "bat%s-%s.adm.crans.org" % (bat, swid)
|
||
|
||
# Si le switch est virtuel, on évite de perdre du temps à query
|
||
# ledit switch qui a une forte proba d'être down.
|
||
if bat in config.bats_virtuels:
|
||
cablage = style(u"Câblée au Crans", "bleu")
|
||
lien = style(u"Prise %s%s virtuelle" % (bat, prise), "violet")
|
||
return u", ".join([lien, cablage])
|
||
|
||
try:
|
||
switch = hptools2.HPSwitch(switch_name)
|
||
except hptools2.SwitchNotFound:
|
||
return style(u"Meh, le switch %s ne répond pas ou n'existe pas." % (switch_name,), "violet")
|
||
except Exception as e:
|
||
return style(u"hptools2 failed (%r)" % e, "rouge")
|
||
vlan_list = switch.get_vlans(port)
|
||
if vlan_list is None:
|
||
return style(u"vlan_list is empty (hptools failed ?)", "rouge")
|
||
|
||
vlans = u" " * (13 + len(chbre))
|
||
vlans += u"Vlan%s : " % (u's' if len(vlan_list) > 1 else u"",) + style(u", ".join([unicode(vlan) for vlan in vlan_list]), "orange")
|
||
|
||
cablage = u" " * (13 + len(chbre))
|
||
|
||
lien = u"Prise %s" % (switch.ports[port].name(),)
|
||
|
||
if not switch.is_enabled(port) == 'up':
|
||
lien += u", " + style(u'désactivée', 'rouge')
|
||
else:
|
||
lien += u", " + style(u'activée', 'cyan')
|
||
if not switch.is_up(port) == 'up':
|
||
lien += u", " + style(u'aucune machine détectée', 'jaune')
|
||
else:
|
||
lien += u", " + style(u'lien actif', 'vert')
|
||
macs = []
|
||
compteur = 0
|
||
for mac in switch.show_port_macs(port)[0]:
|
||
# Toutes les 3 macs, on met un retour à la ligne pour plus de
|
||
# clarté.
|
||
if compteur % 3 == 0 and compteur > 0:
|
||
mac = u'\n' + u' ' * (13 + len(chbre)) + u'MACs: %s' % (mac,)
|
||
macs.append(mac)
|
||
compteur += 1
|
||
lien += u"," + style(u'\n%sMACs: %s' % (u" " * (13 + len(chbre)), u",".join(macs)), 'violet')
|
||
extra_info = gestion.annuaires_pg.chbre_commentaire(bat, chbre).decode('utf-8')
|
||
if extra_info:
|
||
lien += u"\nNote : %s" % (extra_info,)
|
||
|
||
return u",\n".join([lien, vlans, cablage])
|
||
|
||
def timeformat(t, format):
|
||
if isinstance(t, attributs.Attr):
|
||
t = float(t.value)
|
||
return time.strftime(format, time.localtime(t))
|
||
|
||
def blacklists(l):
|
||
bl=[]
|
||
for b in l:
|
||
debut=b['debut'] if b['debut'] == '-' else time.strftime("%d/%m/%Y %H:%M", time.localtime(b['debut']))
|
||
fin=b['fin'] if b['fin'] == '-' else time.strftime("%d/%m/%Y %H:%M", time.localtime(b['fin']))
|
||
couleur='rouge' if b['actif'] else None
|
||
if debut != '-' and fin !='-':
|
||
bl.append(style(u"du %s au %s : %s [%s]" % (debut, fin, b['type'], b['comm']), couleur))
|
||
elif debut != '-':
|
||
bl.append(style(u"À partir du %s : %s [%s]" % (debut, b['type'], b['comm']), couleur))
|
||
elif fin != '-':
|
||
bl.append(style(u"Jusqu'au %s : %s [%s]" % (fin, b['type'], b['comm']), couleur))
|
||
else:
|
||
bl.append(style(u"%s [%s]" % (b['type'], b['comm']), couleur))
|
||
return bl
|
||
|
||
def split(str, *arg):
|
||
return str.split(*arg)
|
||
|
||
def telephone(l):
|
||
tel=[]
|
||
for t in l:
|
||
if len(str(t)) == 10:
|
||
tel.append("%c%c.%c%c.%c%c.%c%c.%c%c" % tuple(map(ord, str(t))))
|
||
else:
|
||
if str(t).startswith("00"):
|
||
t="+%s" % str(t)[2:]
|
||
tel.append(t)
|
||
return tel
|
||
|
||
_ethercodes = None
|
||
def const_of_mac(mac):
|
||
global _ethercodes
|
||
if not _ethercodes:
|
||
_ethercodes = dict()
|
||
with open('/usr/scripts/gestion/ethercodes.dat', 'r') as f:
|
||
# Évite de mettre en RAM tout de suite, on utilise un itérateur
|
||
for line in iter(f.readline, ''):
|
||
line = line.split('\t\t')
|
||
_ethercodes[line[0][0:8].lower()] = line[-1].strip()
|
||
try:
|
||
return mac + u" (%s)" % _ethercodes[mac[0:8]]
|
||
except KeyError:
|
||
return mac
|
||
|
||
templateEnv=None
|
||
def template(dialog=False):
|
||
global templateEnv, style, tableau
|
||
if not templateEnv:
|
||
# un import paresseux, comme ça, pas la peine d'installer jinja2 sur les machines où il n'y en a pas besoin
|
||
import jinja2
|
||
oldstyle = style
|
||
oldtableau = tableau
|
||
newTableau = lambda *args,**kwargs: oldtableau(*args,dialog=dialog,**kwargs)
|
||
tableau = newTableau
|
||
newStyle = lambda *args,**kwargs:oldstyle(*args,dialog=dialog,**kwargs)
|
||
style = newStyle
|
||
#template_path = '/usr/scripts/lc_ldap/printing/templates/'
|
||
template_path = os.path.dirname(os.path.abspath(__file__)) + '/'
|
||
templateLoader = jinja2.FileSystemLoader( searchpath=["/", template_path] )
|
||
templateEnv = jinja2.Environment( loader=templateLoader, trim_blocks=True )
|
||
templateEnv.add_extension('jinja2.ext.do')
|
||
templateEnv.filters['coul'] = newStyle
|
||
templateEnv.filters['blacklists'] = blacklists
|
||
templateEnv.filters['prise_etat'] = prise_etat
|
||
templateEnv.filters['timeformat'] = timeformat
|
||
templateEnv.filters['split'] = split
|
||
templateEnv.filters['telephone'] = telephone
|
||
templateEnv.filters['const_of_mac'] = const_of_mac
|
||
templateEnv.filters['tableau'] = newTableau
|
||
return templateEnv
|
||
|
||
def machine(machine, params):
|
||
params['o']=machine
|
||
return template().get_template("machine").render(params)
|
||
|
||
|
||
def list_machines(machines, width=None):
|
||
data = [
|
||
[
|
||
m['mid'][0],
|
||
m['rid'][0] if m['rid'] else '-',
|
||
str(m['objectClass'][0])[7:],
|
||
str(m['host'][0]).split('.')[0],
|
||
m['ipHostNumber'][0] if m.get('ipHostNumber',[]) else '-',
|
||
m['macAddress'][0],
|
||
m.blacklist_actif()[0] if m.blacklist_actif() else '-',
|
||
]
|
||
for m in machines
|
||
]
|
||
return tableau(data,
|
||
titre = [u'mid', u'rid', u'Type', u'Nom de machine', u'Adresse IP', u'Adresse MAC', u'Limitation'],
|
||
largeur = [5, 5, 6, '*', 15, 17, 10],
|
||
alignement = ['d', 'd', 'c', 'c', 'c', 'c', 'c'],
|
||
width=width)
|
||
|
||
def list_factures(factures, width=None):
|
||
data = []
|
||
for facture in factures:
|
||
controle = facture.get('controle', [""])[0]
|
||
if controle == "TRUE":
|
||
controle = style(u"Validée", "vert")
|
||
elif controle == "FALSE":
|
||
controle = style(u"Invalide", "rouge")
|
||
else:
|
||
controle = u"N/A"
|
||
data.append([
|
||
facture['fid'][0],
|
||
facture['modePaiement'][0],
|
||
style(facture.get('recuPaiement', [])[0], "vert") if facture.get('recuPaiement', []) else style("NON", "rouge"),
|
||
controle,
|
||
' '.join(attr['code'] for attr in facture.get('article',[])),
|
||
u"%s €" % sum([float(a['pu'])*int(a['nombre']) for a in facture.get('article',[])])
|
||
])
|
||
return tableau(
|
||
data,
|
||
titre = [u'fid', u'Mode de paiement', u'Payé', u'Contrôle', u'Articles', u"Total"],
|
||
largeur = [5, 16, 19, 8, '*', 8],
|
||
alignement = ['d', 'g', 'c', 'c', 'g', 'd'],
|
||
width=width)
|
||
|
||
def list_adherents(adherents, width=None):
|
||
return tableau([
|
||
[a['aid'][0],
|
||
u' '.join(unicode(i) for i in a['prenom'] + a['nom']),
|
||
a['chbre'][0], style('o', 'vert') if a.paiement_ok() else style('n', 'rouge'),
|
||
u', '.join(unicode(m['host'][0]).split('.',1)[0] for m in a.machines())
|
||
] for a in adherents ],
|
||
titre = [u'aid', u'Prénom Nom', u'Chbre', u'P', u'Machines'],
|
||
largeur = [5, 35, 5, 1, '*'],
|
||
alignement = ['d', 'c', 'c', 'c', 'g'],
|
||
width=width)
|
||
|
||
def list_clubs(clubs, width=None):
|
||
return tableau([
|
||
[a['cid'][0],
|
||
u' '.join(unicode(i) for i in a['nom']),
|
||
a['chbre'][0], style('o', 'vert') if a.paiement_ok() else style('n', 'rouge'),
|
||
u', '.join(unicode(m['host'][0]).split('.',1)[0] for m in a.machines())
|
||
] for a in clubs ],
|
||
titre = [u'cid', u'Nom', u'Chbre', u'P', u'Machines'],
|
||
largeur = [5, 35, 5, 1, '*'],
|
||
alignement = ['d', 'c', 'c', 'c', 'g'],
|
||
width=width)
|
||
|
||
def proprio(proprio, params):
|
||
params['o']=proprio
|
||
etat_administratif=[]
|
||
if proprio.paiement_ok():
|
||
etat_administratif.append(style(u"à jour", "vert"))
|
||
if not proprio.paiement_ok():
|
||
etat_administratif.append(style(u"cotisation non réglée", "violet"))
|
||
if proprio.fin_adhesion() >= time.time():
|
||
adh = style(u"Adhésion jusqu'au %s" % (time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(proprio.fin_adhesion())),), "vert")
|
||
elif proprio.paiement_ok():
|
||
adh = style(u"Adhésion terminée, mais il y a un sursis.", 'orange')
|
||
else:
|
||
adh = style(u"Pas adhérent actuellement.", 'rouge')
|
||
params["adh"] = adh
|
||
if proprio.fin_connexion() >= time.time():
|
||
conn = style(u"Connexion jusqu'au %s" % (time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(proprio.fin_connexion())),), "vert")
|
||
elif proprio.paiement_ok():
|
||
conn = style(u"Connexion terminée, mais il y a un sursis.", 'orange')
|
||
else:
|
||
conn = style(u"Pas connecté actuellement.", 'rouge')
|
||
params["conn"] = conn
|
||
params['etat_administratif'] = etat_administratif
|
||
|
||
try:
|
||
if proprio.machines():
|
||
params['machines'] = list_machines(proprio.machines())
|
||
if proprio.factures():
|
||
params['factures'] = list_factures(proprio.factures())
|
||
# On essaye d'afficher un adhérent qui n'existe pas encore
|
||
# et donc, on ne peut pas récupérer ses objets enfant
|
||
except ldap.NO_SUCH_OBJECT:
|
||
pass
|
||
return params
|
||
|
||
def club(club, params):
|
||
params=proprio(club, params)
|
||
return template().get_template("club").render(params)
|
||
|
||
def adherent(adherent, params):
|
||
params=proprio(adherent, params)
|
||
return template().get_template("adherent").render(params)
|
||
|
||
def facture(facture, params):
|
||
params['o']=facture
|
||
return template().get_template("facture").render(params)
|
||
|
||
def blacklist(blacklist, params):
|
||
params['o']=blacklist
|
||
return template().get_template("blacklist").render(params)
|
||
|
||
def sprint(object, historique=5, blacklist_len=5, **params):
|
||
from lc_ldap import objets, attributs
|
||
params.update({'historique':historique, "blacklist":blacklist_len})
|
||
if isinstance(object, objets.machine):
|
||
return machine(object, params)
|
||
elif isinstance(object, objets.adherent):
|
||
return adherent(object, params)
|
||
elif isinstance(object, objets.club):
|
||
return club(object, params)
|
||
elif isinstance(object, objets.facture):
|
||
return facture(object, params)
|
||
elif isinstance(object, attributs.blacklist):
|
||
return blacklist(object, params)
|
||
else:
|
||
return str(object)
|
||
|
||
|
||
|
||
def sprint_list(list, width=None):
|
||
from lc_ldap import objets
|
||
mlist={}
|
||
ret=[]
|
||
for o in list:
|
||
mlist[o.__class__] = mlist.get(o.__class__, []) + [o]
|
||
classes = mlist.keys()
|
||
classes.sort()
|
||
for classe in classes:
|
||
list = mlist[classe]
|
||
if issubclass(classe, objets.machine):
|
||
ret.append(list_machines(list, width))
|
||
elif issubclass(classe, objets.adherent):
|
||
ret.append(list_adherents(list, width))
|
||
elif issubclass(classe, objets.club):
|
||
ret.append(list_clubs(list, width))
|
||
elif issubclass(classe, objets.facture):
|
||
ret.append(list_factures(list, width))
|
||
else:
|
||
ret.append("Listes d'objets de classe %s non affichage" % classe.__name__)
|
||
return '\n'.join(ret)
|
||
|