346 lines
13 KiB
Python
Executable file
346 lines
13 KiB
Python
Executable file
#!/usr/bin/env python
|
|
# -*- mode: python; coding: utf-8 -*-
|
|
#
|
|
# ressuscite.py
|
|
# -------------
|
|
#
|
|
# Copyright (C) 2008 Michel Blockelet <blockelet@crans.org>
|
|
#
|
|
# This file is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This file is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
|
|
|
|
u"""Outil pour ressusciter des machines du cimetière."""
|
|
|
|
import os, sys
|
|
import cPickle
|
|
import dialog
|
|
from time import mktime, strptime
|
|
|
|
sys.path.append('/usr/scripts/gestion')
|
|
from ldap_crans import crans_ldap, MachineFixe, MachineWifi
|
|
from gest_crans import select, set_machine
|
|
from whos import aff
|
|
import affich_tools
|
|
import user_tests
|
|
|
|
db = crans_ldap()
|
|
isadm = user_tests.isadm()
|
|
|
|
dlg = dialog.Dialog()
|
|
dlg.setBackgroundTitle('Ressusciter une machine')
|
|
|
|
def menu_principal():
|
|
"""Menu principal de l'interface."""
|
|
choix = ''
|
|
while 1:
|
|
annul, choix = dlg.menu(u"Que souhaitez vous faire ?",
|
|
choices=[("A",u"Ressusciter à partir d'un adhérent",u"Rechercher les anciennes machines d'un adhérent"),
|
|
("D",u"Ressusciter à partir de la date",u"Rechercher à partir de la date de suppression de la machine"),
|
|
("F",u"Ressusciter à partir d'un fichier",u"Récupérer depuis un fichier du cimetière")],
|
|
item_help=1,title=u"Ressusciter")
|
|
if annul: break
|
|
|
|
if choix == 'A':
|
|
# Ressusciter à partir d'un adhérent
|
|
# On sélectionne l'adhérent
|
|
adh = select(db, u'Adhérent duquel rechercher les anciennes machines a', mde='ro')
|
|
if not adh: continue
|
|
|
|
# Est-ce que c'est bien une machine de l'adhérent ?
|
|
def condition(machine, date):
|
|
return (int(machine.dn.split(',', 3)[1].split('=', 2)[1])
|
|
== int(adh.id()) and str(machine.proprio) == ("%s %s"
|
|
% (adh.prenom(), adh.nom())))
|
|
|
|
choixmachine = choixrecherche(condition)
|
|
|
|
if choixmachine != None:
|
|
(machine, date) = choixmachine
|
|
adh = choixadherent(machine, adh)
|
|
if not adh: continue
|
|
ressuscite(adh, machine)
|
|
|
|
elif choix == 'D':
|
|
# Ressusciter à partir de la date
|
|
while 1:
|
|
debut = None
|
|
fin = None
|
|
annul, result = dlg.inputbox(width=54, height=10,
|
|
text=u"Entrez la plage de dates de recherche au format\nJJ/MM/AAAA:JJ/MM/AAAA :\n(Une des deux dates peut ne pas être spécifiée.)\n",
|
|
title=u"Sélection des dates")
|
|
if annul: break
|
|
try:
|
|
[strdebut, strfin] = result.strip().split(':', 1)
|
|
# On teste la validité des dates
|
|
# (strptime émet une erreur si le format est mauvais)
|
|
if len(strdebut) > 0:
|
|
debut = mktime(strptime(strdebut, '%d/%m/%Y'))
|
|
if len(strfin) > 0:
|
|
fin = mktime(strptime(strfin, '%d/%m/%Y')) + 24*60*60
|
|
break
|
|
except:
|
|
dlg.msgbox(text=u"Dates invalides",title=u"Sélection des dates")
|
|
continue
|
|
|
|
# On ne fait la recherche que si on a spécifié une date
|
|
# (c'est mieux de ne pas instancier en mémoire toutes les machines)
|
|
if debut != None or fin != None:
|
|
def condition(machine, date):
|
|
ok = True
|
|
unixdate = mktime(strptime(date, '%Y-%m-%d-%H:%M'))
|
|
if debut != None: ok = (unixdate >= debut)
|
|
if fin != None: ok = ok and (unixdate <= fin)
|
|
return ok
|
|
|
|
choixmachine = choixrecherche(condition)
|
|
|
|
if choixmachine != None:
|
|
(machine, date) = choixmachine
|
|
adh = choixadherent(machine, adh)
|
|
if not adh: continue
|
|
ressuscite(adh, machine)
|
|
|
|
elif choix == 'F':
|
|
# Ressusciter à partir d'un fichier
|
|
fichier = None
|
|
while 1:
|
|
annul, result = dlg.inputbox(width=54, height=12,
|
|
text=u"Vous pouvez aussi exécuter le script sur le fichier\nressuscite [le fichier]\n\nFichier : ",
|
|
init=u"/home/cimetiere/Machine",
|
|
title=u"Sélection du fichier")
|
|
if annul: break
|
|
try:
|
|
fichier = open(result, 'r')
|
|
break
|
|
except:
|
|
dlg.msgbox(text=u"Fichier invalide",title=u"Sélection du fichier")
|
|
continue
|
|
if fichier != None:
|
|
machine = cPickle.load(fichier)
|
|
adh = choixadherent(machine)
|
|
if not adh: continue
|
|
ressuscite(adh, machine)
|
|
|
|
continue
|
|
|
|
|
|
def choixrecherche(condition=None):
|
|
"""Demande les types de machines à chercher, et effectue la recherche avec
|
|
la condition."""
|
|
# On sélectionne le type de machine
|
|
annul, choix = dlg.menu(u"Type de machine ?",
|
|
choices=[("Fixe",u"Machine fixe"),
|
|
("Wifi",u"Machine wireless"),
|
|
("Tous",u"Rechercher les deux types")],
|
|
title=u"Recherche de machine")
|
|
if annul: return None
|
|
|
|
# On cherche les machines
|
|
machines = recherche(choix == 'Fixe' or choix == 'Tous',
|
|
choix == 'Wifi' or choix == 'Tous',
|
|
condition)
|
|
|
|
# Pas de résultat
|
|
if not machines:
|
|
dlg.msgbox(text=u"Aucun résultat",title=u"Recherche")
|
|
return None
|
|
|
|
return choixmachine(machines)
|
|
|
|
|
|
def recherche(fixe=False, wifi=False, condition=None):
|
|
"""Recherche des machines du type demandé, et satisfaisant une condition :
|
|
la fonction condition doit être de la forme
|
|
condition(machine, date)
|
|
et retourner True ou False selon si l'on veut avoir la machine dans la
|
|
liste ou non."""
|
|
# Liste des fichiers à lire
|
|
cimetiere = []
|
|
if fixe: cimetiere = map(lambda s: "/home/cimetiere/MachineFixe/" + s,
|
|
os.listdir("/home/cimetiere/MachineFixe"))
|
|
if wifi: cimetiere += map(lambda s: "/home/cimetiere/MachineWifi/" + s,
|
|
os.listdir("/home/cimetiere/MachineWifi"))
|
|
|
|
# On regarde chacun des fichiers
|
|
valid = []
|
|
for fichier in cimetiere:
|
|
try:
|
|
machine = cPickle.load(open(fichier, 'r'))
|
|
date = fichier[28:44]
|
|
if condition == None or condition(machine, date):
|
|
valid.append((machine, date))
|
|
except:
|
|
pass
|
|
return valid
|
|
|
|
|
|
def choixadherent(machine, oldadh=None):
|
|
"""Permet de choisir l'adhérent à qui rattacher la machine."""
|
|
if oldadh == None:
|
|
oldadhl = db.search(machine.dn.split(',', 2)[1])['adherent']
|
|
else:
|
|
oldadhl = [oldadh]
|
|
|
|
arg = u'--title "" '
|
|
arg += u'--menu "%s.' % machine.proprio
|
|
|
|
# Est-ce que l'adhérent existe encore ?
|
|
if (len(oldadhl) > 0 and str(machine.proprio) == "%s %s"
|
|
% (oldadhl[0].prenom(), oldadhl[0].nom())):
|
|
annul, choix = dlg.menu(u"Le propriétaire de la machine est %s" % machine.proprio,
|
|
choices=[("Garder",u"Ajouter à cet adhérent"),
|
|
("Autre",u"Ajouter à un autre adhérent")],
|
|
title=u"Adhérent auquel rattacher la machine")
|
|
else:
|
|
annul, choix = dlg.menu(u"Cet adhérent n'existe plus dans la base.",
|
|
choices=[("Autre",u"Ajouter à un autre adhérent")],
|
|
title=u"Adhérent auquel rattacher la machine")
|
|
if not annul:
|
|
if choix == "Garder":
|
|
adh = oldadhl[0]
|
|
else:
|
|
adh = select(db, u'Adhérent auquel ajouter la machine a', mde='ro')
|
|
else:
|
|
adh = None
|
|
return adh
|
|
|
|
|
|
def choixmachine(valid):
|
|
"""Choisit une machine dans une liste."""
|
|
# Pas de machines !
|
|
if len(valid) == 1:
|
|
# Une seule réponse
|
|
choix = valid[0]
|
|
else:
|
|
# Il faut choisir
|
|
while 1:
|
|
os.system('clear')
|
|
choix = None
|
|
print "Plusieurs réponses correspondant à votre requête ont été trouvées :"
|
|
|
|
data = []
|
|
i = 1
|
|
for (machine, date) in valid:
|
|
data.append([i, date, str(machine.__class__)[-4:], machine.nom().split('.', 1)[0], machine.mac()])
|
|
i += 1
|
|
print affich_tools.tableau(data,
|
|
titre=[u'id', u'Date destruction', u'Type', u'Nom de machine', u'Adresse MAC'],
|
|
largeur=[5, 16, 4, '*', 17],
|
|
alignement=['d', 'c', 'c', 'c', 'c'])
|
|
|
|
i = affich_tools.prompt(u'Votre choix ? (0 pour annuler) id =')
|
|
try:
|
|
i = int(i)
|
|
except:
|
|
print 'Choix invalide'
|
|
continue
|
|
|
|
if i == 0: break
|
|
if i > len(valid):
|
|
print 'Choix invalide'
|
|
continue
|
|
choix = valid[i-1]
|
|
if choix: break
|
|
|
|
if not choix:
|
|
# Retour à l'interface de recherche
|
|
return None
|
|
return choix
|
|
|
|
|
|
def ressuscite(adh, oldmachine):
|
|
"""Ressuscite une instance de machine."""
|
|
# On regarde quel type de machine c'était
|
|
if str(oldmachine.__class__)[-4:] == 'Fixe':
|
|
strmachine = u"Cette machine était une machine Fixe."
|
|
strdef = 'Fixe'
|
|
elif str(oldmachine.__class__)[-4:] == 'Wifi':
|
|
strmachine = u"Cette machine était une machine Wifi."
|
|
strdef = 'Wifi'
|
|
else:
|
|
strmachine = u"L'ancien type de cette machine est inconnu ..."
|
|
strdef = ''
|
|
|
|
# Certaines fois, on peut vouloir transformer une machine Fixe en Wifi,
|
|
# et inversement (erreurs d'ajout ...)
|
|
annul, choix = dlg.menu(strmachine,
|
|
choices=[("Fixe",u"Ressusciter en tant que machine Fixe"),
|
|
("Wifi",u"Ressusciter en tant que machine Wifi")],
|
|
default_item=strdef,
|
|
title=u"Nouveau type de machine")
|
|
|
|
if annul: return False
|
|
|
|
if choix == 'Fixe':
|
|
machine = MachineFixe(adh)
|
|
elif choix == 'Wifi':
|
|
machine = MachineWifi(adh)
|
|
|
|
err = ""
|
|
|
|
# On remet le nom
|
|
try: machine.nom(str(oldmachine.nom()))
|
|
except ValueError, c: err += c.args[0] + '\n'
|
|
except EnvironmentError, c: err += c.args[0] + '\n'
|
|
|
|
# On remet la MAC
|
|
try: machine.mac(str(oldmachine.mac()))
|
|
except ValueError, c:
|
|
if len(c.args)>1 and c.args[1] == 1 and isadm:
|
|
# Mac en double
|
|
no, res = dlg.yesno(text=u"L'adresse MAC existe déjà, continuer ?", title=u"Adresse MAC")
|
|
if not no:
|
|
try: machine.mac(str(oldmachine.mac()), 1)
|
|
except ValueError, c: err += c.args[0] + '\n'
|
|
except EnvironmentError, c: err += c.args[0] + '\n'
|
|
elif len(c.args)>1 and c.args[1] == 3 and isadm:
|
|
# Mac douteuse
|
|
no, res = dlg.yesno(text=u"L\'adresse MAC ne correspond à aucun constructeur, continuer ?",
|
|
title=u"Adresse MAC")
|
|
if not no:
|
|
try: machine.mac(str(oldmachine.mac()), 1)
|
|
except ValueError, c: err += c.args[0] + '\n'
|
|
except EnvironmentError, c: err += c.args[0] + '\n'
|
|
else:
|
|
err += c.args[0] + '\n'
|
|
except EnvironmentError, c: err += c.args[0] + '\n'
|
|
|
|
# On met une IP automatique
|
|
try: machine.ip('<automatique>')
|
|
except ValueError, c: err += c.args[0] + '\n'
|
|
except EnvironmentError, c: err += c.args[0] + '\n'
|
|
except RuntimeError, c: err += c.args[0] + '\n'
|
|
|
|
# Des erreurs ?
|
|
if err:
|
|
dlg.msgbox(text=u"%s" % err,title=u"Paramètres machine")
|
|
set_machine(machine)
|
|
|
|
return True
|
|
|
|
|
|
if __name__ == '__main__':
|
|
if len(sys.argv) < 2:
|
|
menu_principal()
|
|
os.system("clear")
|
|
else:
|
|
for path in sys.argv[1:]:
|
|
try:
|
|
fichier = open(path, 'r')
|
|
machine = cPickle.load(fichier)
|
|
adh = choixadherent(machine)
|
|
if adh:
|
|
ressuscite(adh, machine)
|
|
except:
|
|
print "Fichier invalide : %s" % fichier
|