#! /usr/bin/env python
# -*- encoding: utf-8 -*-

"""
Script de génération de feuille de déconnexion pour :
    - upload
    - p2p

Copyright (C) Xavier Pessoles, Étienne Chové, Vincent Bernat, Nicolas Salles
Licence : GPL v2
"""

encoding = "UTF-8"

import sys
sys.path.append('/usr/scripts/gestion')
sys.path.append('/usr/scripts')

from ldap_crans import crans_ldap
from config import upload

import time
from unicodedata import normalize
import commands

# logging tools
import syslog
def log(x):
    syslog.openlog('GENERATE_DECONNEXION_NOTICE')
    syslog.syslog(x)
    syslog.closelog()

from cranslib.utils import exceptions

import locale
locale.setlocale(locale.LC_TIME, 'fr_FR.utf8')


sanctions = ['upload', 'p2p']

help = """Script de génération d'une feuille de déconnexion.
Les sanctions disponibles sont :
\t--%s
usage: generate.py --sanction recherche_ldap
Le motif de recherche dans la base ldap doit donner un résultat unique""" % "\n\t--".join(map(lambda x: x,sanctions))

def decode(s):
    u"""
    Retourne un unicode à partir de s
    s doit être en utf-8
    """

    if type(s) is unicode:
        # Si s est déjà un unicode, on ne décode pas
        return s
    else:
        return s.decode('utf-8', 'ignore') # On ignore les erreurs

def strip_accents(a):
    u""" Supression des accents de la chaîne fournie """
    res = normalize('NFKD', decode(a)).encode('ASCII', 'ignore')
    return res.replace(' ', '_').replace("'", '')

def generate_ps(sanction, proprio, db):
    """En fonction de la sanction à appliquer au propriétaire,
    on génère la feuille de déconnexion et on retourne son nom et
    emplacement."""
    try:
        log('Generate deconnexion notice for %s' % proprio.Nom())
        # Dossier de génération du ps
        dossier = '/usr/scripts/surveillance/fiche_deconnexion'

        # Base pour le nom du fichier
        fichier = time.strftime('%Y-%m-%d-%H-%M') + '-%s-%s' % (sanction,
            strip_accents(proprio.Nom().lower().replace(' ', '-')))

        # Création du fichier tex
        format_date = '%A %d %B %Y'
        template = file('%s/deconnexion_%s.tex' % (dossier, sanction)).read()
        template = template.replace('~prenom~', proprio.prenom().encode(encoding))
        template = template.replace('~nom~', proprio.nom().encode(encoding))
        template = template.replace('~chambre~', proprio.chbre().encode(encoding))
        template = template.replace('~mail~', proprio.email().encode(encoding))
        template = template.replace('~debut~', time.strftime(format_date, time.localtime()))
        template = template.replace('~fin~', time.strftime(format_date, time.localtime(time.time()+14*86400)))
        # filtrage des autodisc
        historique = [ bl.encode(encoding, 'ignore').split('$') for bl in proprio.blacklist() if bl.split('$')[2] == 'autodisc_%s' % sanction ]
        # transfomation en tuple (date, sanction)
        historique = [ (time.strftime('%A %d %B %Y', time.localtime(int(bl[0]))), bl[-1]) for bl in historique ]
        # On ne prend au maximum que les 5 dernières occurences
        historique = historique[-7:]
        # tranformation en ligne
        if sanction == 'upload' :
            # On donne la valeur de l'upload
            historique = [ '%s & %s & Mo'%(bl[0], bl[1].split(' ')[-2]) for bl in historique ]
        else :
            # On donne juste la date
            historique = [ '%s' % bl[0] for bl in historique ]
        # assemblage des lignes
        historique = r"""\\
        """.join(historique)
        template = template.replace('~historique~', historique)
        if sanction == 'upload' :
            template = template.replace('~limitehard~', str(upload.hard))
        template = template.replace('~nbadher~', str(len(db.search('paiement=ok')['adherent'])))

        file('%s/%s.tex' % (dossier, fichier), 'w').write(template)

        # Compilation du fichier latex
        # Paquets nécessaires : texlive-latex-base, texlive-latex-recommended,
        # texlive-latex-extra, texlive-lang-french, texlive-luatex,
        # texlive-pstricks
        commande = 'PATH="/bin:/usr/bin" cd %(dossier)s && latex %(base)s.tex && dvips %(base)s.dvi && rm -f %(base)s.dvi %(base)s.aux %(base)s.log %(base)s.tex'%{'dossier': dossier, 'base': fichier}
        status, output = commands.getstatusoutput(commande)
        if status != 0:
            log('Erreur lors de la génération du ps : ')
            log(output)
        return '%s/%s.ps' % (dossier, fichier)
    except Exception, e:
        log('Erreur lors de la génération du ps : ')
        log(str(e))
        log("Values : sanction:%s adherent:%s" % (sanction,
            strip_accents(proprio.Nom())))
        log(exceptions.formatExc())
        raise e

if __name__ == "__main__":
    def log(x):
        print x

    def aide():
        print help
        sys.exit(0)

    if '--help' in sys.argv or '-h' in sys.argv:
        aide()

    db = crans_ldap()

    sanction = ''
    for s in sanctions :
        if '--%s' % s in sys.argv:
            sanction = s

    if not sanction :
        print "Erreur : aucune sanction définie.\n"
        aide()

    if len(sys.argv) <= 2 :
        print "Erreur : aucun motif de recherche défini.\n"
        aide()
    else :
        motif = sys.argv[-1]

    recherche = db.search(motif)['adherent']

    if len(recherche) == 0:
        print "Erreur : aucun résultat pour %s.\n" % motif
        aide()
    elif len(recherche) != 1:
        print "Erreur : plusieurs résultats pour %s.\n" % motif
        aide()
    else :
        adherent = recherche[0]

    # On génére alors le postscript
    fichier = generate_ps(sanction, adherent, db)
    print u'Le fichier %s a été généré.' % fichier
