#!/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 
#  
# maj_variante
#  
# script de maj d'une variante depuis un serveur enregistré
# 
# les fichiers situés dans /usr/share/eole/creole/patchs/variantes et
# /usr/share/eole/creole/dicos/variantes seront remontés sur zephir
# (idem pour les fichiers définis dans fichiers_variante)
#       
###########################################################################

import os, sys, shutil, getpass, hashlib
from zephir.lib_zephir import *
from creole.config import eoleroot
try:
    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 la variante du module installé"""
    print '\n** procédure de mise à jour 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'
    # 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 recherche le n° de module et de variante du serveur installé
    id_module = info_serveur[1][0]['module_actuel']
    id_variante = info_serveur[1][0]['variante']
    # recherche du libelle du module
    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]))
    # recherche du libelle de la variante
    info_variante = convert(zephir_proxy.modules.get_variante(id_variante))
    if info_variante[0] == 0:
        sys.exit("erreur de recherche de la variante actuelle dans zephir \n(%s)" % info_variante[1])
        
    if info_variante[1][0]['libelle'] == 'standard':
        sys.exit("\nla variante par défaut d'un module ne peut pas être modifiée\n")
        
    msg = "\nmise à jour des patchs et dictionnaires :\n variante '%s' (n°%d) du module %s\n"
    print msg % (info_variante[1][0]['libelle'], id_variante, info_module[1][0]['libelle'])
    
    print("""** Attention, les anciens patchs et dictionnaires locaux vont être écrasés. **""")
    pass_var = getpass.getpass("""Entrez le mot de passe de la variante (ou rien) : """)
    # 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
    temp_dir = os.path.join(eoleroot, 'fichiers_perso')
    try:
        os.mkdir(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
    # création d'un répertoire temporaire
    try:
        os.makedirs(os.path.join(eoleroot, 'fichiers_zephir'))
    except:
        pass
    # on récupère la liste des fichiers à conserver sur zephir
    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:
        cmd_cp = ['/bin/cp -rpf %s/zephir_conf/fichiers_variante %s/' % (zephir_dir, os.path.join(eoleroot, 'fichiers_zephir'))]
        for fichier in fic_liste:
            if fichier.startswith('/'):
                if '::' in fichier:
                    fichier, container = fichier.split('::')
                else:
                    container = None
                if fichier.endswith(os.sep):
                    # on strippe le / final pour les répertoires si besoin
                    fichier = fichier[:-1]
                if container:
                    fichier = "%s::%s" % (fichier, container)
                fic_path = get_container_file(fichier)
                if os.path.exists(fic_path):
                    cmd_cp.append('/bin/cp -rpf %s %s' % (fic_path, os.path.join(eoleroot, 'fichiers_zephir', os.path.basename(fichier))))
                else:
                    print("   fichier %s non trouvé !" % fichier)
        # on recopie ces fichiers dans le répertoire temporaire si besoin
        if len(cmd_cp) > 1:
            os.system("; ".join(cmd_cp))


    # rqe: pour les patchs et dicos, la commande install_variante lancée sur zéphir va chercher le sous-répertoire de la variante
    cmd_tar = """cd %s ; /bin/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)
    shutil.rmtree(temp_dir)
    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
    # 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, hashlib.md5(pass_var).hexdigest()))
    if res[0] == 0:
        sys.exit(res[1])
    else:
        log('ZEPHIR', 0, 'mise à jour de la variante %s (module %s)' % (id_variante, info_module[1][0]['id']))
    print(" - suppression de l'archive locale...")
    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("** mise à jour de la variante terminée **\n")

if __name__ == '__main__':
    main()
