#!/usr/bin/env python
# -*- coding: utf-8 -*-
###########################################################################
# Eole NG - 2007  
# Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon)
# Licence CeCill  cf /root/LicenceEole.txt
# eole@ac-dijon.fr 
#  
# creation_variante.py
#  
# script de création de variante depuis un modules Eole enregistré sur Zephir
#       
###########################################################################

import time,os,sys,shutil,getpass
from hashlib import md5
from creole.config import eoleroot
from pyeole.ihm import print_orange
try:
    from zephir.lib_zephir import *
    import zephir.zephir_conf.zephir_conf as config
except:
    sys.exit("""Ce serveur n'est pas enregistré dans une base zephir.
    utilisez la procédure enregistrement_zephir pour y remédier""")

def main():
    """enregistrement des dictionnaires et patches dans une variante du module installé"""
    print '\n** procédure de création de variante ** \n'
    print_orange('Attention, les dictionnaires ne sont pas remontés automatiquement sur Zéphir')
    print '\nVeuillez :'
    print "- les gérer via la page 'dictionnaires personnalisés' de la distribution 2.4"
    print '- les activer ensuite dans la variante\n'
    lock(['uucp','maj','reconfigure','configure'])
    # saisie des informations de connexion
    login = raw_input("login pour l'application zephir : ")
    passwd = getpass.getpass("mot de passe pour %s : " % login)
    # création du proxy avec zephir
    zephir_proxy = EoleProxy('https://'+login+':'+passwd+'@'+config.adresse_zephir+':7080',transport=TransportEole())
    # on récupère les informations sur le serveur dans la base zephir
    try:
        info_serveur = convert(zephir_proxy.serveurs.get_serveur(config.id_serveur))
    except xmlrpclib.ProtocolError:
        sys.exit("""erreur d'authentification ou zephir non disponible""")
    if info_serveur[0] == 0:
        sys.exit("erreur de recherche du serveur dans la base zephir : "+str(info_serveur[1]))
    # on vérifie le n° de module du serveur installé
    id_module = info_serveur[1][0]['module_actuel']
    info_module = convert(zephir_proxy.modules.get_module(id_module))
    if info_module[0] == 0:
        sys.exit("erreur de recherche du module dans la base zephir : "+str(info_module[1]))
    print """\n** création d'une variante pour le module '%s' **""" % info_module[1][0]['libelle']
    # on affiche les variantes disponibles pour le module installé
    liste_variantes = convert(zephir_proxy.modules.get_variante())
    variantes = [""]
    if liste_variantes[0] == 1:
        for var in liste_variantes[1]:
            if var['module'] == id_module:
                variantes.append(str(var['libelle']))
    else:
        sys.exit('erreur de recherche des variantes : '+str(liste_modules[1]))
    # choix du nom de la variante
    nom_ok = 0
    while not nom_ok:
        new_var = raw_input("\nentrez le nom de la nouvelle variante\n[rien pour la liste des variantes existantes] : ")
        # demande d'affichage de la liste des variantes existantes
        if new_var == "":
            os.system('clear')
            print '\n** liste des variante du module %s **\n' % info_module[1][0]['libelle']
            for variante in variantes[1:]:
                print variante
        # si la variante existe déjà, on recommence
        if new_var in variantes:
            if new_var != "":
                os.system('clear')
                print "\n** cette variante existe déjà, utilisez la procédure maj_variante pour la modifier **\n"
        else:
            nom_ok = 1

    # saisie d'un mot de passe pour la variante
    # par défaut, on prend le mot de passe utilisé pour le login zephir ?
    pass_ok = 0
    while not pass_ok:
        pass_var = getpass.getpass("mot de passe de la variante (ou rien) : ")
        if pass_var == "":
            pass_ok = 1
        else:
            # Sinon on demande une confirmation
            pass_conf = getpass.getpass("Entrez à nouveau le mot de passe pour vérification :")
            if pass_conf == pass_var:
                pass_ok = 1
                pass_var = md5(pass_var).hexdigest()
            else:
                print ("\n** Erreur de confirmation du mot de passe recommencez **\n")

    print("\n\n** mise en place de la variante **\n - ajout de la variante dans la base zephir...")
    # préparation de l'archive contenant les patchs et les dicos
    print(" - création de l'archive des patchs et dictionnaires locaux...")
    # préparation de la liste des fichiers référencés dans la liste des dictionnaires locaux
    fic_persos = []
    temp_dir = os.path.join(eoleroot, 'fichiers_perso')
    try:
        os.makedirs(temp_dir)
    except:
        pass
    cmd_cp = ['/bin/cp','-rpf']
    cmd_cp.extend(templates_for_level('variante'))
    cmd_cp.append(temp_dir)
    # on recopie ces fichiers dans le répertoire temporaire si besoin
    if len(cmd_cp) > 3:
        os.system(" ".join(cmd_cp))
    # préparation des fichiers spécifiques au module
    # on récupère la liste des fichiers à conserver sur zephir
    try:
        os.makedirs(os.path.join(eoleroot, 'fichiers_zephir'))
    except:
        pass
    try:
        fic_module = open('%s/zephir_conf/fichiers_variante' % zephir_dir,'r')
        fic_liste = fic_module.read().split('\n')
        fic_module.close()
    except IOError:
        pass
    else:
        # création d'un répertoire temporaire contenant les fichiers
        cmd_cp = ['/bin/cp','-rpf','%s/zephir_conf/fichiers_variante' % zephir_dir]
        for fichier in fic_liste:
            if fichier.startswith('/'):
                if os.path.exists(fichier):
                    cmd_cp.append(fichier)
                else:
                    print("   fichier %s non trouvé !" % fichier)
        cmd_cp.append(os.path.join(eoleroot, 'fichiers_zephir'))
        # on recopie ces fichiers dans le répertoire temporaire si besoin
        if len(cmd_cp) > 3:
            os.system(" ".join(cmd_cp))
            
    cmd_tar = """cd %s ; tar --same-owner -cphf /tmp/variante%s.tar patch dicos fichiers_perso fichiers_zephir 2>/dev/null""" % (eoleroot, config.id_serveur)
    os.system(cmd_tar)
    try:
        shutil.rmtree(temp_dir)
        shutil.rmtree(os.path.join(eoleroot, 'fichiers_zephir'))
    except:
        print('erreur de supression des répertoires temporaires')

    if not os.path.isfile('/tmp/variante%s.tar' % config.id_serveur):
        return 0, "erreur de creation de l'archive"
    # création du fichier de vérification de checksum
    print(" - création de la signature md5 de l'archive...")
    cmd_md5 = """cd /tmp; /usr/bin/md5sum -b variante%s.tar""" % config.id_serveur
    output = os.popen(cmd_md5)
    # lecture du résultat de la commande
    res_md5 = output.readlines()
    output.close()
    # envoi de l'archive
    print(" - envoi de l'archive au serveur zephir...")
    cmd_uucp = """/usr/bin/uucp -r '/tmp/variante%s.tar' 'zephir!~'""" % config.id_serveur
    res = os.system(cmd_uucp)
    if res == 0:
        os.system('/usr/sbin/uucico -S zephir')
    if res != 0:
        return 0, """erreur d'envoi du  fichier /tmp/variante%s.tar par uucp""" % config.id_serveur
    # création de la variante dans la base de données
    res_ajout = convert(zephir_proxy.modules.add_variante(id_module,u(new_var)))
    # on vérifie que l'ajout de la variante est fait
    if res_ajout[0] == 0:
        sys.exit("erreur de création de la variante : "+str(res_ajout[1]))
    # on récupère son identifiant
    id_variante = res_ajout[1]
    print(" - variante créée dans la base avec l'id %s ..." % id_variante)
    # on inscrit le serveur dans cette variante
    print(" - inscription du serveur à cette variante...")
    zephir_proxy.serveurs.edit_serveur(config.id_serveur,u({'variante':id_variante}))
    # une fois le transfert terminé, déclenchement de la commande install_variante sur le serveur zephir
    print(" - vérification de l'archive et mise en place des données...")
    res = convert(zephir_proxy.uucp.install_variante(config.id_serveur,res_md5[0],login,pass_var))
    if res[0] == 0:
        print res[1]
    else:
        # on enregistre la création dans le log
        log('ZEPHIR',-2,'mise en place de la variante %s (module %s)' % (new_var,id_module))
    print(" - suppression de l'archive locale...")
    unlock(['uucp','maj','reconfigure','configure'])
    try:
        os.unlink("/tmp/variante%s.tar" % config.id_serveur)
    except:
        print("   (l'archive /tmp/variante%s.tar n'a pas pu être supprimée)" % config.id_serveur)
    print("** installation de la variante terminée **\n")

if __name__ == '__main__':
    main()
