diff --git a/listepagesperso/mkall.sh b/listepagesperso/mkall.sh new file mode 100755 index 00000000..fd73c7a2 --- /dev/null +++ b/listepagesperso/mkall.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +# Ce script reconstitue la base mkinfos et tout ce qui va avec +# (liste des pages html, etc...) + +cd /usr/scripts/listepagesperso + +# mkinfos (génération de la base) +python mkinfos/mkinfos.py > /var/local/pages_persos/erreurs.txt +cp /tmp/infos.db /var/local/pages_persos/ + +# mkhtml (construction de la page html à partir de base) +python mkinfos/mkhtml.py > /home/httpd/html/pages-index.html diff --git a/listepagesperso/mkinfos/BuildDb.py b/listepagesperso/mkinfos/BuildDb.py new file mode 100755 index 00000000..e1b19e1e --- /dev/null +++ b/listepagesperso/mkinfos/BuildDb.py @@ -0,0 +1,43 @@ +#!/usr/bin/python +# -*- coding: iso-8859-1 -*- +""" +Module BuildDb.py + +Ce module regarde les repertoire dans le home, puis +interroge chaque compte pour lire le .info, le .plan etc... +""" + +import os +from string import * +import CompteRec + +def GrabInfos(aDB): + """ Liste le contenu de /home . + + le resultat est stocke dans le CInfoDb fourni en argument (aDB) + """ + + # Pour debug : on peut ne tester que i comptes + i = -1 + + maison = os.listdir('/home') + + for login in maison: + compte = CompteRec.CCompte(login) + + if compte: # il y a un .info, un .plan ou un .www : + aDB.Put(login,compte) + + i = i - 1 + if not i: break # en debogage, on ne mouline pas tous les comptes ! + + + + +######################## +# debug : + +if 0: + import InfoDb + + GrabInfos(InfoDb.CInfoDb("/tmp/test","n")) diff --git a/listepagesperso/mkinfos/CompteRec.py b/listepagesperso/mkinfos/CompteRec.py new file mode 100755 index 00000000..88bf9b9e --- /dev/null +++ b/listepagesperso/mkinfos/CompteRec.py @@ -0,0 +1,275 @@ +#!/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__ diff --git a/listepagesperso/mkinfos/InfoDb.py b/listepagesperso/mkinfos/InfoDb.py new file mode 100755 index 00000000..8c8ef3e3 --- /dev/null +++ b/listepagesperso/mkinfos/InfoDb.py @@ -0,0 +1,36 @@ +#!/usr/bin/python +# -*- coding: iso-8859-1 -*- + +""" + + Structure de la base de données : + + (clef = nom login) ---> (objet de classe CCompte) + + les objets CCompte sont decrits dans CompteRec.py +""" + +import shelve + +class CInfoDb: + """ Encapsule une base de donnees de .info + + La structure de cet objet est simple, pour chaque login est stocke de + facon persistante l'objet CCompte associe. + """ + + db = None + + def __init__(self,filename,mode="rw"): + self.db = shelve.open(filename,mode) + + def __del__(self): + self.db.close() + + def Put(self,name,obj): + """ Ajoute un element.""" + self.db[name] = obj + + def Get(self,name): + """ recupere un element. """ + return self.db[name] diff --git a/listepagesperso/mkinfos/mkhtml.py b/listepagesperso/mkinfos/mkhtml.py new file mode 100755 index 00000000..d23456e3 --- /dev/null +++ b/listepagesperso/mkinfos/mkhtml.py @@ -0,0 +1,100 @@ +#!/usr/bin/python +# -*- coding: iso-8859-1 -*- + +# première version cradobeurk par Chep +# version améliorée le 26 07 2001 par Tiresias +# chawatage pour déplacement des configs dans /CRANS -- Nico 22/12/01 +# idem dans /usr/scripts/ -- Nico 19/04/05 + + +import InfoDb +import array +import sys +import commands + +#Excluded = ['snepa','lasauce','cineclub','innomine','hubris','gmpcad', +# 'jdr','coope','asme','sono','rilem','krobot'] +Excluded = [] + + +DB=InfoDb.CInfoDb("/var/local/pages_persos/infos.db","r") + +keys = DB.db.keys() +keys.sort() + +print """ + + +Liste des pages perso + + + + + + +

Liste des Pages Perso

+ +

+ Note : Les pages suivantes ne sont pas contrôlées par + l'assocation et leur contenu est sous la responsabilité de leur auteur respectif. + +

+ + + """ + +compteur = 4 + +for key in keys: + compte = DB.Get(key) + #sys.stderr.write('%s\n'%key) + + try: + if compte.URL and not (compte.Compte in Excluded): + s = ' \n " + + print s, # qu'il y ait ou non un pseudo !!! + + if compte.Devise: + s = '\n '+compte.Devise+'' + print s, + print '\n \n ' + + compteur = (compteur + 1)%4 + + except: + pass + +print " \n\ +
\n\ + \n' + + if compte.Logo : l = compte.Logo + else: l = "/images/crans-mini.jpg" + + url = compte.URL + s = s + ' *
' + if compte.Nom: nom = compte.Nom + else: nom = compte.Compte + + + s = s + '\n ' + nom + '
' + + if compte.Pseudo: + s = s + '\n «'+compte.Pseudo+'»
' + + if compteur == 0: + print "
\n\ +
\n Dernière mise à jour : %s\n" % \ + (commands.getoutput("date '+%A %d %B %Y à %X'")) + +print """
+ Si ça ne marche pas (tu as + fait une page mais elle ne s'affiche pas), lis + ceci. + +
+ + + +""" diff --git a/listepagesperso/mkinfos/mkinfos.py b/listepagesperso/mkinfos/mkinfos.py new file mode 100755 index 00000000..96a2291e --- /dev/null +++ b/listepagesperso/mkinfos/mkinfos.py @@ -0,0 +1,41 @@ +#!/usr/bin/python +# -*- coding: iso-8859-1 -*- + +"""Le programme mkinfos. + +Ce programme crée une base /tmp/infos.db qui reflete l'état des comptes +(fichiers .info, .plan et présence de .www/index.html) + +La vocation de ce programme est de tourner au moins une fois toutes les +24 heures. +""" + +import BuildDb +import InfoDb +import CompteRec + +def DisplayError(self, login, errorlines): + """ Affiche une erreur de compilation du .info de 'login'. + + errorlines contient un tableau de chaines de caracteres. + Cette routine est une redefinition de CompteRec.CCompte.DisplayError + """ + + msg = [login] + msg = msg + ["Il y a une erreur dans ton fichier .info ! "] + msg = msg + [""] + msg = msg + ["voila le texte de l'erreur : "] + + for i in errorlines : + msg = msg + [i] + msg = msg + [""] + msg = msg + [" -- le démon 'mkinfos' "] + + for i in msg: + print i + + +print "Création de la base temporaire /tmp/infos.db ... " +CompteRec.CCompte.DisplayError = DisplayError + +BuildDb.GrabInfos(InfoDb.CInfoDb("/tmp/infos.db","n"))