#! /usr/bin/env python # -*- coding: iso-8859-15 -*- # Copyright (C) Frédéric Pauget # Licence : GPLv2 """Ce script permet de recherche et d'afficher le détail d'une machine ou d'un adhérent. Usage: %(prog)s [options] La chaine de recherche peut être : * soit un terme unique, dans ce cas la recherche sera effectuée sur les champs en bleu ci-dessous. * soit du type "champ1=valeur1&champ2!=valeur2 ...", les résultats seront alors limités aux entrées correspondantes à tous les critères. Les champs de recherche possibles sont : %(champs_rech)s Recherche sur prise possible (utiliser uniquement ce champ dans ce cas) Les options de recherches sont : * limitations sur l'affichage : -a ou --adherent : limitation de l'affichage aux adhérents -m ou --machine : limitation de l'affichage aux machines -c ou --club : limitation de l'affichage aux clubs -b ou --bornes : limitation de l'affichage aux bornes wifi --crans : recherche uniquement les machines du crans * options d'affichage : -t ou --tech : affichages des infos techniques des machines à la place des infos administratives dans les résumés. -i ou --ipsec : montre la clef ipsec des machines wifi -l ou --limit= : limite du nombre de résultats pour utiliser le mode d'affichage condensé au lieu du mode détaillé (défaut %(limit_aff_details)i) -L ou --limit-historique= : limitation du nombre de lignes d'historique affichées (défaut %(limit_aff_historique)i) """ try: import sys,locale loc = locale.getdefaultlocale() if loc[1]: sys.reallysetdefaultencoding(loc[1]) except: pass base = None from ldap_crans import is_actif , crans_ldap, ann_scol, crans, hostname from affich_tools import * import user_tests import popen2, commands limit_aff_details = 1 limit_aff_historique = 4 aff_ipsec = 0 def unicode_print(truc) : """ Conversion de truc en iso-8859-15 puis affichage à l'écran """ print truc.encode('iso-8859-15','ignore') def aff(qqch,mtech=0) : """ Affichage de qqch. qqch peut être une liste d'instances des classes adhérent ou machine (un seul type dans la liste) dans ce cas : * si la longueur de la liste est inférieure à limit_aff_details affiche les propriétés détaillées de chaque élément. * sinon résume dans un tabeau des principales propriétés si qqch est une instance seul la traité comme une liste à une élément Si mtech = 1 affiches les infomations techniques des machines plutot qu'administratives dans le tableau des propriétés """ if type(qqch) != list : qqch = [ qqch ] if len(qqch) > limit_aff_details : t = qqch[0].idn if t == 'aid' : unicode_print(adhers_brief(qqch)) elif t == 'mid' : if mtech : unicode_print(list_machines(qqch)) else : unicode_print(machines_brief(qqch)) elif t == 'cid' : unicode_print(clubs_brief(qqch)) else : i = 0 for c in qqch : t = c.idn if i : print coul(u'='*80,'cyan') i = 1 if t == 'aid' : unicode_print(adher_details(c)) elif t == 'mid' : unicode_print(machine_details(c)) elif t == 'cid' : unicode_print(club_details(c)) if len(qqch) > 1: print u"Total: %d" % len(qqch) def adhers_brief(adhers) : """ Formatage sous forme de tableau des infos sur la liste d'adhérent fournie : * aid * prénom nom * chambre * machines """ data = [ ( u'aid' , u'Prénom Nom' , u'Chbre', u'P', u'C', u'Machines' ) ] for a in adhers : ## Etat administratif ok = u'\x1b[1;32mo\x1b[1;0m' ook = u'\x1b[1;32mO\x1b[1;0m' nok = u'\x1b[1;31mn\x1b[1;0m' # Paiement if ann_scol in a.paiement(): if 'p' in a.controle(): paid = ook else: paid = ok else : paid = nok # Précablage if ann_scol+1 in a.paiement() : paid = coul(paid,'f_vert') # Carte d'étudiant if ann_scol in a.carteEtudiant(): if 'c' in a.controle(): carte = ook else: carte = ok else : carte = nok machines = '' # Récupération des machines for machine in a.machines() : nom = machine.nom().split('.')[0] if machine.blacklist_actif() : k = 'rouge' else : k= '' if machines : machines += ', ' + coul(nom,k) else : machines = coul(nom,k) # Données data.append((a.id() , a.Nom(), a.chbre(),paid,carte,machines )) return u"Machines en rouge = machines avec limitation de services\n" + \ u"P : paiement année en cours, le fond vert indique le précâblage\n" + \ u"C : carte d'étudiant année en cours\n" + \ tableau([5, 30 , 5, 1, 1, '*'], data) def machines_brief(machines) : """ Formatage sous forme d'un tableau des propriétés de la liste de machine : * mid * type (fixe ou wifi, born) * nom * adresse IP * adresse MAC * si blacklistée """ data = [ ( u'mid' , u'Type', u'Nom de machine', u'Propriétaire', u'Chbre', u'Limitation' ) ] for m in machines : t, bl = __bases_machines(m) # Propriétaire a = m.proprietaire() p = a.Nom() # A jour administrativement if ann_scol not in a.paiement() or ann_scol not in a.carteEtudiant() : p = coul(p,'rouge') # Données data.append((m.id() , t, m.nom().split('.')[0], p, a.chbre(), bl)) return u"Le propriétaire en rouge signale un problème administratif\n" + \ tableau([5, 4, 18, '*', 5, 10], data) def clubs_brief(clubs) : """ Formatage sous forme de tableau des infos sur la liste de clubs fournie : * cid * nom * local * machines """ data = [ ( u'cid' , u'Nom ', u'Local',u'P', u'Responsable', u'Machines' ) ] for c in clubs : ## Etat administratif ok = u'\x1b[1;32mo\x1b[1;0m' ook = u'\x1b[1;32mO\x1b[1;0m' nok = u'\x1b[1;31mn\x1b[1;0m' # Paiement if ann_scol in c.paiement(): if 'p' in c.controle(): paid = ook else: paid = ok else : paid = nok # Précablage if ann_scol+1 in c.paiement() : paid = coul(paid,'f_vert') machines = '' # Récupération des machines for machine in c.machines() : nom = machine.nom().split('.')[0] if machine.blacklist_actif() : k = 'rouge' else : k= '' if machines : machines += ', ' + coul(nom,k) else : machines = coul(nom,k) # Responsable resp = c.responsable().Nom() # Données data.append((c.id() , c.Nom(), c.local(),paid, resp, machines )) return u"Machines en rouge = machines avec limitation de services\n" + \ u"P : signature charte année en cours, le fond vert indique le précâblage\n" + \ tableau([5, '*' , 6, 1, 21, 15], data) def list_machines(machines) : """ Formatage sous forme d'un tableau des propriétés de la liste de machine : * mid * type (fixe ou wifi) * nom * adresse IP * adresse MAC * si blacklistée """ data = [ ( u'mid' , u'Type', u'Nom de machine', u'Adresse IP', u'Adresse MAC', u'Limitation' ) ] for m in machines : t, bl = __bases_machines(m) # Données data.append((m.id() , t, m.nom().split('.')[0], m.ip(), m.mac(), bl)) return tableau([5, 4, '*', 17, 19, 10], data) def list_bornes(bornes) : """ Formatage sous forme d'un tableau des propriétés de la liste de bornes wifi : * mid * nom * adresse IP * adresse MAC * État * puissance * canal * lieu (la première remarque en fait) """ data = [ ( u'mid' , u'Nom', u'Adresse IP', u'Adresse MAC', u'E', u'Can' , u'P', u'Pris', u'Lieu') ] ok = u'\x1b[1;32mu\x1b[1;0m' nok = u'\x1b[1;31md\x1b[1;0m' for b in bornes : t, bl = __bases_machines(b) if t != 'born' : continue # Données try : l = [x for x in b.info() if not x[0]=='<'][0] if len(l) > 11 : l = l[0:11] except : l = u'????' if borne_etat(b.nom()): etat = ok else: etat = nok if '-' in b.puissance() : puiss = coul(b.puissance(),'rouge') else : puiss = b.puissance() data.append((b.id() , b.nom().split('.')[0], b.ip(), b.mac(), etat, b.canal(), puiss, b.prise(),l )) return u"Can=canaux, P=puissance, E=état\n" + tableau([4, 13, 15, 17, 1, 5, 3, 4, '*'], data) def adher_details(adher) : """ Affichage du détail des propriétés d'un adhérent """ f='' # Aid f+= coul(u'aid=%s ' % adher.id() ,'bleu') # Nom, prenom f += coul(u'Nom : ','gras') + "%s\n" % adher.Nom() # Mail GL = RMH = u'' if adher.mail().find('@')!=-1 : f += coul(u'Adresse mail : ','gras') + "%s" % adher.mail() else : f += coul(u'Login : ','gras') + "%s\t" % adher.mail() # controurneGreylisting if not adher.contourneGreylist(): GL = u' (%s)'%coul(u'GreyList','gris') if adher.rewriteMailHeaders(): RMH = u' (%s)'%coul(u'réécriture en-têtes mail','gris') alias = ', '.join([adher.cannonical_alias()] + adher.alias()) if alias : if alias[0]==',' : # Cannonical étéait vide alias = alias[2:] f += coul(u'Alias : ','gras') + alias f+= GL f+= RMH f+= u'\n' # Etat administratif f += coul(u'Etat administratif : ','gras') jour=1 if ann_scol not in adher.carteEtudiant() : f += coul(u"manque carte d'étudiant",'violet') jour = 0 if ann_scol not in adher.paiement() : if not jour : f += ' et ' f += coul(u"cotisation %s/%d non réglée"% (ann_scol, ann_scol+1 ),'violet') jour = 0 if jour : f += coul(u"à jour",'vert') if 'k' not in adher.controle(): f += u' (caution non payée)' f += '\n' # Telephone tel = adher.tel() if tel != 'inconnu' : try : tel = u'%s %s %s %s %s' % ( tel[:2], tel[2:4], tel[4:6], tel[6:8], tel[8:] ) except : pass f += coul(u'Numéro de téléphone : ','gras') + "%s\n" % tel.ljust(12) # Adresse chbre = adher.chbre() if chbre == 'EXT' : # Adhérent extérieur addr = adher.adresse() if addr[0] : f += coul(u'Adresse : ','gras') f += addr[0] + u'\n' if addr[1] != ' ' : f += u' ' + addr[1] + u'\n' f+= u' ' + addr[2] + u' ' + addr[3] + '\n' elif chbre == '????' : f += coul(u'Chambre invalide\n','violet') else : # Chambre + prise (d'après annuaire) f += coul(u'Chambre : ','gras') + u"%s " % chbre f += u'(%s)' % prise_etat(adher.chbre()) f += u'\n' # Etudes if adher.etudes(1).isdigit() : f += coul(u'Etudes : ','gras')+ "%s %s%s\n" % \ ( adher.etudes(0), adher.etudes(1), adher.etudes(2) ) elif adher.etudes(0) : f += coul(u'Etudes : ','gras')+ "%s %s %s\n" % \ ( adher.etudes(0), adher.etudes(1), adher.etudes(2) ) # Solde solde = adher.solde() if solde : f += coul(u'Solde : ','gras') if solde < 0 : f+= coul(str(solde).replace('.',','),'rouge') else : f += str(solde).replace('.',',') f += u" Euros\n" # Role dans l'assoce d = adher.droits() if d : f += coul(u"Droits sur les serveurs : ",'gras') + ', '.join(d) f += u'\n' # Paiement if adher.paiement() : if len(adher.paiement()) == 1 : f += coul(u'Cotisation payée pour l\'année scolaire :','gras') else : f += coul(u'Cotisation payée pour les années scolaires :','gras') g = u'' for an in adher.paiement() : g += u" %i-%i" % ( an, an+1 ) if len(g) > 35 : f += '\n\t' f += g if 'p' in adher.controle(): f += coul(u' (OK)', 'vert') f += u'\n' # Cartes d'étudiant fournie if adher.carteEtudiant() : if len(adher.carteEtudiant()) == 1 : f += coul(u"Carte d'étudiant fournie pour l'année scolaire :",'gras') else : f += coul(u"Carte d'étudiant fournie pour les années scolaires :",'gras') g = u'' for an in adher.carteEtudiant() : g += u" %i-%i" % ( an, an+1 ) if len(g) > 25 : f += '\n\t' f += g if 'c' in adher.controle(): f += coul(u' (OK)', 'vert') f += u'\n' f += _blacklist(adher) f += _info(adher) f += _hist(adher) # Formatage des machines aussi f += coul(u'Machine(s) : ','gras') m = adher.machines() if m : f += u'\n' + list_machines(m) else : f += u'aucune' return f clients_ipsec = None def ipsec_ok(machine) : """Indique si une machine est correctement authentifiée""" prefix="" if hostname != "ragnarok": if not os.path.isfile("/usr/scripts/gestion/clef-encap"): return None prefix = "ssh -i /usr/scripts/gestion/clef-encap root@nectaris.crans.org " clients = globals()['clients_ipsec'] if clients == None: clients = commands.getoutput("%snetstat -r -f encap | awk '($1 == \"0/0\") {print $3}'" % prefix).split("\n") globals()['clients_ipsec'] = clients return machine.nom() in clients def machine_details(machine) : """ Formatage du détail des propriétés d'une machine """ f = '' f+= coul(u'mid=%s ' % machine.id(),'bleu') # Type de machine if machine.ipsec() : a='Machine wifi' elif machine.canal() : a='Borne wifi' else : a='Machine fixe' f+= coul(a+' : ' ,'gras') f+= "%s\n" % machine.nom() # Alias ? alias = machine.alias() if alias : f += coul(u'Alias : ' ,'gras') + ', '.join(alias) f+= '\n' f+= coul(u'IP : ','gras') + "%s\t\t" %machine.ip() f+= coul(u'MAC : ','gras') + "%s\n" %machine.mac() # Propriétaire f+= coul(u'Propriétaire : ','gras') try : f += machine.proprio + coul(' (adhérent détruit)', 'jaune') a = crans() except : a = machine.proprietaire() f += "%s" % a.Nom() if a.chbre()!='CRA' : f += " (%s)" % a.chbre() else : f += coul(u'\t\tPrise : ','gras') + machine.prise() f+= '\n' # Adhérent blacklisté ? bl = a.blacklist_actif() if bl : f += coul(u'Restrictions sur adhérent : ','gras') f += coul(u', '.join(bl),'rouge') f += '\n' # Borne wifi if machine.puissance() : f += coul(u'Puissance : ','gras') + u"%4.d" % int(machine.puissance()) f += coul(u'\tCanaux : ', 'gras') + machine.canal() f += coul(u'\tÉtat : ', 'gras') if borne_etat(machine.nom()): f += coul(u'borne active', 'vert') f += '\n' # S'il y a des clients, on les liste canal_clients = borne_clients_canal(machine.nom()) clients = canal_clients["mac-rssi"] canal = canal_clients["canal"] f += coul(u'\t Canal courant : ', 'gras') + u"%d" % canal f += "\n" if clients and base: f += coul(u'Clients : \n','gras') for (client, rssi) in clients: # On va chercher le nom correspondant à l'adresse MAC res = base.search("mac=%s" % client)['machine'] authentification="" if not res: client_nom = '????' else: client_nom = ", ".join(["%s [%s]" % (x.nom().split(".")[0], x.proprietaire().Nom()) for x in res]) # On va regarder si le client est authentifié auth_ok = ipsec_ok(x) if auth_ok != None: if auth_ok: authentification = "; IPSec: %s" % OK else: authentification = "; IPSec: %s" % ERREUR # On va choisir la bonne couleur pour le RSSI if rssi > -88: coul_rssi = 'vert' elif rssi > -93: coul_rssi = 'jaune' else: coul_rssi = 'rouge' f += u' %s (%s) (RSSI: %s%s)\n' % (client, client_nom, coul("%d" % rssi, coul_rssi), authentification) else: f += coul(u'borne éteinte','rouge') f += '\n' if aff_ipsec and machine.ipsec() : f += coul(u'Clef IPsec : ','gras') + machine.ipsec() f += '\n' # Ports spéciaux if machine.portTCPin() : f += coul(u'Ports TCP ouvert ext->machine : ','gras') + machine.portTCPin() + '\n' if machine.portTCPout() : f += coul(u'Ports TCP ouvert machine->ext : ','gras') + machine.portTCPout() + '\n' if machine.portTCPin() : f += coul(u'Ports UDP ouvert ext->machine : ','gras') + machine.portUDPin() + '\n' if machine.portUDPout() : f += coul(u'Ports UDP ouvert machine->ext : ','gras') + machine.portUDPout() + '\n' # Exemption d'upload if machine.exempt() : f += coul(u'Upload exempté vers : ','gras') + ', '.join(machine.exempt()) + '\n' f += _blacklist(machine) f += _info(machine) f += _hist(machine) return f def club_details(club) : """ Affichage du détail des propriétés d'un adhérent """ f='' # Cid f+= coul(u'cid=%s ' % club.id() ,'bleu') # Nom f += coul(u'Nom : ','gras') + "%s\n" % club.Nom() # responsale f += coul(u'Responsable : ','gras') + "%s\n" % club.responsable().Nom() # Etat administratif f += coul(u'Etat administratif : ','gras') jour=1 if ann_scol not in club.paiement() : if not jour : f += ' et ' f += coul(u"charte %s/%d non signée"% (ann_scol, ann_scol+1 ),'violet') jour = 0 if jour : f += coul(u"à jour",'vert') f += '\n' # Chambre + prise f += coul(u'Local : ','gras') + "%s " % club.local() f += u'(%s)' % prise_etat(club.chbre()) f += u'\n' # Paiement if club.paiement() : f += coul(u'Charte signée pour les années scolaires :','gras') g = '' for an in club.paiement() : g += " %i-%i" % ( an, an+1 ) if len(g) > 35 : f += '\n\t' f += g if 'p' in club.controle(): f += coul(u' (OK)', 'vert') f += '\n' login = club.compte() if login : f += coul(u'Login : ','gras') + login alias = club.alias() if alias : f += coul(u'\tAlias : ','gras') + ', '.join(alias) f+= u'\n' f += _blacklist(club) f += _info(club) f += _hist(club) # Formatage des machines aussi f += coul(u'Machine(s) : ','gras') m = club.machines() if m : f += '\n' + list_machines(m) else : f += 'aucune' return f ########################################### # Fonctions annexes de formatage de données def _blacklist(clas) : """ Formatage blackliste de la classe fournie """ f = u'' 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) f = f[:-6] # supression des espaces superflus if f : return coul(u'Blackliste : ', 'gras') + f else : return '' def _info(clas) : """ Formatage des remarques de la classe fournie """ f= u'' c = clas.info() if c : f += coul(u'Remarque :\n ' ,'gras') f += u'\n '.join(c) f += u'\n' return f def _hist(clas) : """ Formatage de l'historique de la classe fournie """ if limit_aff_historique==0 : return '' f='' h = clas.historique() h.reverse() if h : f += coul(u'Historique : ','gras') for i in range(0,limit_aff_historique) : try : a = h[i] # Produit une erreur si i trop grand if i !=0 : f += ' ' f += '%s\n' % a except : break try : if h[i+1] : f += ' [...]\n' except : None return f def __bases_machines(m) : """ Retourne [ type de la machines, blacklist ] """ #Type if m.ipsec() : t='wifi' elif m.canal() : t='born' else : t='fixe' # Déconnectée ? b = m.blacklist_actif() if not b : bl = '-' elif len(b) == 1 : bl = coul(b[0],'rouge') else : bl = coul(u'cf détails','rouge') return t , bl def borne_etat(borne) : """Renvoie vrai si la borne est up, faux sinon""" # On utilise fping, en cas d'erreur, on considere # que la borne est down (alors qu'elle peut simplement # ne pas exister) try: retour = os.system("fping -q -c 1 %s > /dev/null 2> /dev/null" % borne) return (retour == 0) except: return False def borne_clients_canal(borne) : """Renvoie la liste des adresses MAC associées à la borne ainsi que le canal. Chaque adresse MAC est en fait contenue dans un couple comprenant l'adresse MAC et le RSSI du client associé. On en profite pour renvoyer également le canal en cours de la borne. On fait cela dans la même fonction car cela évite de faire deux connexions ssh (ce qui est fort coûteux). Au final, on renvoie un dictionnaire - mac-rssi: une liste de couples (MAC, RSSI) - canal: le canal en cours """ macs = [] canal = -1 # Uniquement possible pour les admins et si on a la clef for clef in ["/etc/wifi/ssh/wifi","/usr/scripts/gestion/clef-wifi"]: if os.path.isfile(clef) and user_tests.isadm(): try: wl = popen2.Popen3("ssh -o StrictHostKeyChecking=no -i %s root@%s 'cat /tmp/auth-mac.dump ; echo -n \"CANAL \" ; /usr/sbin/nvram get wl0_channel' 2> /dev/null" % (clef, borne)) wl.tochild.close() for line in wl.fromchild.readlines(): # Chaque ligne est de la forme # 00:11:22:33:44:55 -20 line = line.strip().split() if line[0] == "CANAL": canal = int(line[-1]) else: macs.append((line[0].strip(), int(line[1].strip()))) except: pass break # Pas la peine d'essayer une autre clef return {"canal": canal, "mac-rssi": macs} def prise_etat(chbre) : """ Retoune l'état de la prise associée à la chbre """ f = u'' try: # On met aussi l'état from hptools import sw_chbre, ConversationError prise = sw_chbre(chbre) f += u'prise %s' % prise.prise_brute rows, cols = get_screen_size() if prise.is_up() : f += u', ' + coul(u'machine branchée','vert') reste_cols = cols - 45 if prise.eth_mode().find('10Mbits')!=-1 : f+= u', ' + coul(u'prise en 10Mbps','jaune') reste_cols -= 17 f+=', ' macs = prise.show_prise_mac() if len(macs) == 0: if reste_cols < 20 : # Faut aller à la ligne f += u'\n ' f += coul(u'aucune MAC détectée', 'jaune') else: if len(macs) == 1 and reste_cols > 25 : # Une seule mac et on a assez de place f += u"MAC: %s" % macs[0] else : # On va à la ligne # Combien d'adresses MAC peut-on mettre par ligne ? # Une adresse MAC =~ 20 caracteres cols -= 17 # On met 15espaces devant chaque ligne parligne = int(cols/20) count = 0 while len(macs) > 0: if count % parligne == 0: f += u'\n MACs: ' else: f += u', ' f += u"%s" % macs.pop() count += 1 elif not prise.is_enable() : f+= u', ' + coul(u'prise désactivée','rouge') else : f+= u', activée, lien non détecté' except ConversationError, r: # Switch non manageable ou down f += ', ' f+= {'Unknown host (No such file or directory)' : u'switch non manageable', 'Failure in sendto (Operation not permitted)' : u'infos prise non dispo : filtre vers adm par fw', 'sh: line 1: command not found' : u'infos prise non dispo depuis cette machine' }.get(r.args[0],r.args[0]) except ValueError, r : f = r except : f = u'infos prise non dispo : erreur interne' return f ############################################################################## ## Partie dévolue au système de recherche def __usage_brief(err='') : """ Message d'erreur """ if err : cprint(err,'gras') print u"Pour obtenir de l'aide sur l'utilisation de ce programme utilisez l'option -h" sys.exit(2) def __usage() : """ Comment ca marche ? """ list = [''] for c in base.auto_search_champs.values() : for champ in c : coul_champ = coul(champ,'bleu') if list[-1] == '' : list[-1] = coul_champ l = len(champ) else : l += len(champ) + 2 if l < 80 : list[-1] += ', ' + coul_champ else : list.append(coul_champ) l = len(champ) for c in base.non_auto_search_champs.values() : for champ in c : l += len(champ) + 2 if l < 80 : list[-1] += ', ' + champ else : list.append(champ) l = len(champ) print __doc__ % { 'prog' : sys.argv[0].split('/')[-1].split('.')[0] , 'champs_rech' : '\n'.join(list) , 'limit_aff_details' : limit_aff_details , 'limit_aff_historique' : limit_aff_historique } sys.exit(0) def __recherche() : """ Recherche et affichage des résultats à partir des options founies (sys.argv) """ global aff_ipsec, limit_aff_details, limit_aff_historique, debug # Récupération des options if len(sys.argv) == 1 : # Pas d'option fournie __usage_brief() try : options, arg = getopt.getopt(sys.argv[1:], 'hamctbil:L:', [ 'debug', 'help', 'adherent', 'machine', 'club' , 'tech', 'bornes', 'limit=', 'limit-historique=', 'ipsec', 'crans' ]) except getopt.error, msg : __usage_brief(msg) # Traitement des options only_adh=0 only_mac=0 only_club=0 only_bornes=0 only_crans=0 mtech = 0 for opt, val in options : if opt == '-h' or opt=='--help' : __usage() elif opt =='--debug' : # Mode debug debug = 1 elif opt == '-l' or opt =='--limit': # Passage mode condensé, mode détaillé try : limit_aff_details = int(val) except : __usage_brief('Valeur du paramètre %s incorecte (doit être un entier positif)' % opt) elif opt == '-L' or opt =='--limit-historique': # Limitation du nombre de lignes d'historique try : limit_aff_historique = int(val) except : __usage_brief('Valeur du paramètre %s incorecte (doit être un entier positif)' % opt) elif opt in [ '-a', '--adherent' ] : only_adh = 1 print "Affichage limité aux adhérents." elif opt in [ '-m', '--machine' ] : only_mac = 1 print "Affichage limité aux machines." elif opt in [ '-c', '--club' ] : only_club = 1 print "Affichage limité aux clubs." elif opt == '--crans' : only_crans = 1 mtech = 1 print "Affichage limité aux machines du crans." elif opt in [ '-b', '--bornes' ] : only_bornes = 1 print "Affichage limité aux bornes wifi." # On va tenter de limiter un peu la recherche if not arg : # Recherche initiale sans critère arg = [ 'canal=*&host=*.crans.org'] elif arg[0].find('=')!=-1 : # Recherche avec critères arg += [ '&canal=*' ] elif opt in [ '-t', '--tech' ] : # Format affichage des machines mtech = 1 elif opt in [ '-i', '--ipsec' ] : # Affichage des clefs ipsec aff_ipsec = 1 if only_adh + only_mac + only_club + only_bornes > 1 : __usage_brief('Options utilisées incompatibles') arg = ' '.join(arg) # Cas particulier de recherche sur prise if arg.count('=') == 1 and arg.split('=')[0] == 'prise' : prise = arg.split('=')[1] # Récupération de la chambre try: from annuaires import reverse chbre = reverse(prise[0].lower())[prise[1:]] except KeyError: try: chbre = reverse(prise[0].lower())[prise[1:]+'-'] except KeyError: chbre=None if chbre: if len(chbre) != 1 : print u"Prise correspondante à plusieurs chambres %s " % ' '.join(chbre) return # On fait la recherche sur la chambre chbre= prise[0] + chbre[0] #print u"Recherche sur chambre %s" % chbre arg = 'chbre=%s' % chbre # sinon on ne fait rien et on recherche sur le champ prise try: if only_crans : res = { 'machine' : crans().machines() , 'adherent' : [] , 'club' : [] } else : if not arg : # Pas de chaine de recherche fournie __usage_brief('Chaine de recherche incorrecte.') res = base.search(arg) except ValueError, c : __usage_brief(c.args[0]) # Traitement du résultat if not res['adherent'] and not res['machine'] and not res['club']: # Pas de résultat dans la base # Recherche sur chambre ? if arg.count('=') == 1 and arg.split('=')[0] == 'chbre' : # Affichage des infos de la chambre chbre = arg.split('=')[1] print u"Chambre %s inoccupée ou invalide (%s)" % (chbre,prise_etat(chbre)) else : print u"Aucun résultat trouvé." sys.exit(3) # L'affichage souhaité a été précisé ? elif only_bornes : if not res['machine'] : print 'Aucun résultat à afficher' sys.exit(4) else : if len(res['machine']) > limit_aff_details : unicode_print(list_bornes(res['machine'])) else : aff(res['machine']) elif only_adh : if res['adherent'] : aff(res['adherent']) elif res['machine'] : to_aff=[] traite =[] for m in res['machine'] : a = m.proprietaire() if a.idn != 'aid' or a.id() in traite : continue traite.append(a.id()) to_aff.append(m.proprietaire()) if not(to_aff) : print 'Aucun résultat à afficher' sys.exit(4) aff(to_aff) elif res['club'] : print 'Aucun résultat à afficher' sys.exit(4) elif only_mac : if res['machine'] : aff(res['machine'],mtech) else : to_aff = [] for a in res['adherent'] + res['club'] : to_aff += a.machines() aff(to_aff) elif only_club : if res['club'] : aff(res['club']) elif res['machine'] : to_aff=[] traite =[] for m in res['machine'] : a = m.proprietaire() if a.idn != 'cid' or a.id() in traite : continue if a.id() in traite : continue traite.append(a.id()) to_aff.append(m.proprietaire()) if not(to_aff) : print 'Aucun résultat à afficher' sys.exit(4) aff(to_aff) elif res['adherent'] : print 'Aucun résultat à afficher' sys.exit(4) # Non : on affiche tout. else : if res['adherent'] : cprint("Résultats trouvés parmi les adhérents :",'cyan') aff(res['adherent']) if res['machine'] : cprint("Résultats trouvés parmi les machines :",'cyan') aff(res['machine'],mtech) if res['club']: cprint("Résultats trouvés parmi les clubs :",'cyan') aff(res['club']) if __name__ == '__main__' : global debug debug = 0 import sys, getopt base = crans_ldap() try : __recherche() except KeyboardInterrupt : print "Recherche interrompue par l'utilisateur." sys.exit(255) except SystemExit, c : # Fin sys.exit(c) except : print """Une erreur fatale s'est produite durant l'exécution. Pour l'amélioration de ce programme merci de prévenir nounou en spécifiant la marche à suivre pour reproduire cette erreur.""" if debug : print '-'*40 print 'Détails techniques :' import traceback traceback.print_exc() sys.exit(1)