#!/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)