#!/usr/bin/python
# -*- coding: iso-8859-1 -*-
#
#########################################################################
#
#  Structure de la base de données : 
#
#     (clef = nom login) ---> (objet de classe CCompte)
#
#
#  Contenu de la classe CCompte : les champs du fichier .info, plus un 
#  champ "plan" contenant le .plan .
#     
#########################################################################

import os
from string import *

class CCompte:
    """ Classe CCompte : image d'un compte. 

    Cette classe encapsule le contenu des fichiers .info et .plan
    pour le compte de login self.Compte  """

    Compte = None
    Actif = 0   # true si un .info ou un .plan existent.
    Pseudo = None   
    Email = None    # automatiquement mis à Compte@rip.ens-cachan.fr
    Logo = None
    Photo = None
    Nom = None
    Devise = None
    Projet = None
    Section = None
    Adresse = None
    Telephone = None
    Plan = None
    URL = None      #  nom de fichier relatif de la page Web  
                    #  en général .www/index.html
                    # ou alors URL
    

    def __init__(self,login = ""):   
        """ Initialisation.

        Cette méthode analyse le contenu du compte (login) et remplit
        self en conséquence. Il est renvoyé 0 dans self.Actif si le compte 
        ne contient ni .info ni .plan. """

        self.Actif = 0
        self.Compte = strip(login)
        
        if not login : return   # en principe, on est en de-shelvage ... 

        Path = "/home/" + login + "/"
        
        try:  # lecture du .info
            f_info = open(Path + ".info","r")
            info = f_info.readlines()

            self.ParseInfo(info,login)
        except:
            # faut probablement gueuler (sauf si le fichier est 
            # légitimement absent)
            pass

        if not (self.URL):
            url = ""
            # rien mis ? on essaye index.html et index.htm dans .www/ :
            if os.path.isfile("/home/"+login+"/www/index.html"):
                url = "/~"+login+"/index.html"
            elif os.path.isfile("/home/"+login+"/www/index.htm"):
                url = "/~"+login+"/index.htm"
            elif os.path.isfile("/home/"+login+"/www/default.htm"):
                url = "/~"+login+"/default.htm"
            self.URL = url

        try: # lecture du .plan
            f_plan = open(Path + ".plan","r")
            self.Plan = f_plan.readlines()[:30]
            self.Active = 1
        except:
            pass

        try: # lecture du .project
            f_project = open(Path + ".project","r")
            self.Projet = f_project.readlines()[:30]
            self.Active = 1
        except:
            pass


        # à ce stade, l'objet est prêt à l'emploi

    def ParseInfo (self,info , login):
        """ Analyse un fichier .info.

        cette routine analyse un fichier .info et transfère ses 
        informations si elles sont cohérentes.
        Les erreurs sont envoyees a self.DisplayError
        """
        
        nom = None
        compte = None
        pseudo = None
        email = login + "@crans.org"
        logo = None
        photo = None
        devise = None
        projet = None
        section = None
        adresse = None
        telephone = None
        url = None
        version = 1
        
        for ligne in info :
            if lstrip(ligne)[:1] == '#': continue # commentaire
             
            
            ligne = rstrip(ligne)  # vire le \012 final
            spl_ligne = split(ligne,":")
            champ = lower(strip(spl_ligne[0]))
            valeur = strip(join(spl_ligne[1:],":"))
            
            
            try:
                if champ=="compte": compte = strip(valeur)
                elif champ=="nom": nom = valeur
                elif champ=="pseudo": pseudo = valeur
                elif champ=="email": email = valeur
                elif champ=="logo":  logo = valeur
                elif champ=="photo": photo = valeur
                elif champ=="devise": devise = valeur
                elif champ=="section": section = valeur
                elif champ=="adresse": adresse = valeur
                elif champ=="telephone": telephone = valeur
                elif champ=="url"  : url = valeur
                elif champ=="version" : version = atoi(strip(valeur))
            except:
                erreur = [" une erreur est survenue sur le champ "+champ+
                          ". Il y a toutes les chances que tu n'aie pas "
                          " respecté la syntaxe de .info. \012",
                          " selon toutes probabilités, une autre erreur "
                          "va se déclencher... on laisse courir.\012",
                          " (non critique)","\012"]
                self.DisplayError(login,erreur)
                pass

                        
        if (url) and (url[:7] != "http://") and (url[:1] != "/"):
            # c'est un nom de fichier.... on verifie qu'il commence par .www
            if url[:5] != ".www/" :
                erreur = ["Le champ url doit etre un URL ou un nom de fichier"
                          "commencant par .www/ \012","(non critique) \012",
                          "\012"]
                self.DisplayError(login,erreur)
            else: # c'est bon.. on en fait un url relatif au site...
                url = "/~"+login+url[:4]
                pass
                
        
        if strip(compte) != strip(login):
            erreur = ["Le champ 'Compte' et le login ne correspondent pas !",
                      " (fatal) ",""]
            self.DisplayError(login,erreur)
            raise SyntaxError
    
        if version < 1:
            erreur = ["La version du fichier (champ Version) est inférieure ",
                      "a 1 ",
                      "(non critique)",""]
            self.DisplayError(login,erreur)
            #raise SyntaxError

        if version > 1:
            erreur = ["Ce mkinfos est probablement obsolète ou une erreur "
                    "  existe  sur le champ Version. ",
                    " (non critique)",""]
            self.DisplayError(login,erreur)


        self.Compte = compte
        self.Actif = 1
        self.Pseudo = pseudo
        self.Email = email
        self.Logo = logo
        self.Photo = photo
        self.Devise = devise
        self.Section = section
        self.Projet = projet
        self.Adresse = adresse
        self.Telephone = telephone
        self.Nom = nom
        self.URL = url
    
        if logo:
            try:
                self.FindLogo()
            except:
                erreur = ["Erreur a la récupération du logo",
                          "(non critique)",
                          ""]
                self.DisplayError(login,erreur)
                pass
        

    def DisplayError(self, login, errorlines):
        """ Affiche une erreur de compilation du .info de 'login'.
        
        errorlines contient un tableau de chaines de caracteres.
        En general, on changera cette routine (par exemple pour 
        envoyer un mail a 'login'
        """

        print "Erreur dans .info , compte =",login
        for i in errorlines:
            print i
        print ""

        
    def FindLogo(self):
        """ Récupere le logo.
        
        Cette routine récupere le logo contenu dans le champ Logo du compte
        'account' et le stocke dans $InfoDir/$login.logo.extension
        Le champ Logo du compte est alors mis à jour.
        """
        
        
        import urllib # urllib.urlopen()
        import posixpath # posixpath.splitext()

        # Où sont stockés les logos
        InfoDir = "/home/httpd/html/info-2/"
        InfoPath = "/info-2/"
        
        if not self.Logo: 
            return # rien a faire !
        logopath = self.Logo
        self.Logo = ""
        olddir = os.getcwd()

        os.chdir("/home/"+self.Compte)
        try:
            rf = urllib.urlopen(logopath)
            
            base,ext = posixpath.splitext(logopath)
            logoname = self.Compte + ".logo" + ext
            f = open(InfoDir + logoname,"w")

            data = rf.read(-1) # tout d'un coup !

            f.write(data) # hop !

            # on ferme !
            f.close()
            rf = None

            # bon on peut mettre a jour le compte maintenant !
            self.Logo = InfoPath + logoname
        finally:
            os.chdir(olddir)

        
        
        
# A ce stade : on a defini une classe "CCompte" capable d'analyser le .info
# et le .plan, une fois donne un nom de login.

# test debug : 

if 0:   
    A = CCompte("chepelov")
    print A.__dict__
