2 Ce module sert à lire un catalogue et à construire
3 un objet CataItem pour Eficas.
4 Il s'appuie sur la classe READERCATA
7 import os,sys,py_compile
11 from tkMessageBox import showinfo,showerror
17 import analyse_catalogue
18 from Noyau.N_CR import CR
19 from widgets import Fenetre
27 ("Rapport de validation catalogue",'visuCRCATA'),
34 def __init__(self,appli,parent):
37 self.code=self.appli.code
38 self.appli.format_fichier.set('python')
42 #XXX CCAR : Pour le moment je ne construis pas le CATAItem
43 #self.cataitem = catabrowser.CATAItem(self,"Catalogue "+self.code,
45 #objet_cata_ordonne = self.cata_ordonne_dico)
49 Ouvre le catalogue standard du code courant, cad le catalogue présent
50 dans le répertoire Cata
52 message1 = "Compilation des fichiers Eficas \n\n Veuillez patienter ..."
53 splash._splash.configure(text = message1)
54 if len(self.appli.CONFIGURATION.catalogues) == 1:
55 self.fic_cata = self.appli.CONFIGURATION.catalogues[0][2]
56 self.code = self.appli.CONFIGURATION.catalogues[0][0]
57 self.version_code = self.appli.CONFIGURATION.catalogues[0][1]
58 self.appli.format_fichier.set(self.appli.CONFIGURATION.catalogues[0][3])
59 elif len(self.appli.CONFIGURATION.catalogues) == 0:
60 # aucun catalogue défini dans le fichier Accas/editeur.ini
61 if self.code == 'ASTER' :
62 self.fic_cata = os.path.join(prefs.CODE_PATH,'Cata','cata.py')
63 elif self.code == 'SATURNE' :
64 self.fic_cata = os.path.join(prefs.CODE_PATH,'Cata','cata_saturne.py')
65 elif self.code == 'DESCARTES':
66 self.fic_cata = os.path.join(prefs.CODE_PATH,'Cata','cata_descartes.py')
71 # plusieurs catalogues sont disponibles : il faut demander à l'utilisateur
72 # lequel il veut utiliser ...
73 self.ask_choix_catalogue()
74 if self.fic_cata == None :
77 # détermination de fic_cata_c et fic_cata_p
78 self.fic_cata_c = self.fic_cata + 'c'
79 self.fic_cata_p = os.path.splitext(self.fic_cata)[0]+'_pickled.py'
80 # compilation éventuelle du catalogue
81 test = self.compile_cata(self.fic_cata,self.fic_cata_c)
82 if not test : showerror("Compilation catalogue","Impossible de compiler le catalogue %s" %self.fic_cata)
84 self.cata = self.import_cata(self.fic_cata)
85 if not self.cata : showerror("Import du catalogue","Impossible d'importer le catalogue %s" %self.fic_cata)
86 # analyse du catalogue (ordre des mots-clés)
87 #XXX A priori ceci fait double emploi. Il faut d'abord calculer l'ordre
88 # puis fabriquer le CATAItem
89 #CCAR :self.catalo = catabrowser.CATAItem(self,"Catalogue",self.cata)
90 self.Retrouve_Ordre_Cata_Standard()
91 # chargement et analyse des catalogues développeur (le cas échéant)
92 if self.appli.CONFIGURATION.isdeveloppeur == 'OUI' :
93 init_rep_cata_dev(self.fic_cata,self.appli.CONFIGURATION.path_cata_dev)
94 fic_cata_dev = os.path.join(self.appli.CONFIGURATION.path_cata_dev,'cata_developpeur.py')
95 if os.path.isfile(fic_cata_dev):
96 # il y a bien un catalogue développeur : il faut récupérer le module_object associé ...
97 test = self.compile_cata(fic_cata_dev,fic_cata_dev+'c')
99 showinfo("Compilation catalogue développeur",
100 "Erreur dans la compilation du catalogue développeur")
101 self.cata = (self.cata,)
103 self.cata_dev =self.import_cata(fic_cata_dev)
104 self.Retrouve_Ordre_Cata_Developpeur()
105 self.cata = (self.cata,self.cata_dev)
107 self.cata = (self.cata,)
109 self.cata = (self.cata,)
111 def import_cata(self,cata):
113 Réalise l'import du catalogue dont le chemin d'accès est donné par cata
116 splash._splash.configure(text = "Chargement du catalogue")
117 nom_cata = os.path.splitext(os.path.basename(cata))[0]
118 rep_cata = os.path.dirname(cata)
119 sys.path[:0] = [rep_cata]
121 f,p,d = imp.find_module(nom_cata)
122 o = imp.load_module(nom_cata,f,p,d)
125 traceback.print_exc()
128 def Retrouve_Ordre_Cata_Standard(self):
130 Retrouve l'ordre des mots-clés dans le catalogue, cad :
131 - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
132 l'ordre des mots-clés dans le catalogue
133 - s'il n'a pas été modifié, relie le fichier pickle
135 time1 = os.path.getmtime(self.fic_cata)
137 time2 = os.path.getmtime(self.fic_cata_p)
141 # l'objet catalogue n'a pas été modifié depuis le dernier "pickle"
142 self.Get_Ordre_Cata()
144 # le catalogue a été modifié depuis le dernier "pickle" :
145 # il faut retrouver l'ordre du catalogue et refaire pickle
146 self.Get_Ordre_Cata(mode='cata')
147 self.appli.affiche_infos("Catalogue standard chargé")
149 def Get_Ordre_Cata(self,mode='pickle'):
151 Retrouve l'ordre du catalogue :
152 - mode='pickle ': tente de relire le fichier pickle et sinon lance l'analyse du catalogue
153 - mode='cata' : force l'analyse du catalogue directement sans relire le pickle
155 if mode == 'pickle' :
157 f = open(self.fic_cata_p)
158 u = cPickle.Unpickler(f)
159 splash._splash.configure(text = "Analyse du catalogue")
160 self.cata_ordonne_dico = u.load()
163 # on peut ne pas arriver à relire le fichier pickle s'il a été altéré
164 # ou (le plus probable) s'il a été créé sous un autre OS
165 self.Get_Ordre_Cata(mode='cata')
167 splash._splash.configure(text = "Analyse du catalogue",barre='oui')
168 cata_ordonne = analyse_catalogue.analyse_catalogue(self,self.fic_cata)
169 self.cata_ordonne_cr = cata_ordonne.cr
170 self.cata_ordonne_dico = cata_ordonne.dico
171 splash._splash.configure(text = "Sauvegarde des informations sur le catalogue")
172 f = open(self.fic_cata_p,'w+')
173 p = cPickle.Pickler(f)
174 p.dump(self.cata_ordonne_dico)
177 raise Exception("Appel à un mode inconnu de Get_Ordre_Cata : %s" % mode)
180 def ask_choix_catalogue(self):
182 Ouvre une fenêtre de sélection du catalogue dans le cas où plusieurs
183 ont été définis dans Accas/editeur.ini
185 # construction du dictionnaire et de la liste des catalogues
186 self.dico_catalogues = {}
188 for catalogue in self.appli.CONFIGURATION.catalogues:
189 if catalogue[0] == self.code :
190 self.dico_catalogues[catalogue[1]] = catalogue
191 if len(catalogue) == 5 :
192 if catalogue[4]=='defaut' : defaut = catalogue[1]
193 liste_choix = self.dico_catalogues.keys()
195 # test si plusieurs catalogues ou non
196 if len(liste_choix) == 0:
197 showerror("Aucun catalogue déclaré pour %s" %self.code)
199 elif len(liste_choix) == 1:
200 self.fic_cata = self.dico_catalogues[liste_choix[0]][2]
201 self.version_code = liste_choix[0]
203 # création d'une boîte de dialogue modale
204 self.fenetre_choix_cata = Pmw.Dialog(self.parent,
205 buttons=('OK','ANNULER'),
206 defaultbutton = 'OK',
207 title = "Choix d'une version du code %s" %self.code,
208 command = self.chooseCata)
209 # construction des radioboutons
210 label = `len(liste_choix)`+' versions du code %s sont disponibles\n' %self.code
211 label = label + 'Veuillez choisir celle avec laquelle vous souhaitez travailler :'
212 self.radiobutton = Pmw.RadioSelect(self.fenetre_choix_cata.interior(),
213 buttontype='radiobutton',
216 label_font = fontes.standard,
218 for choix in liste_choix :
219 self.radiobutton.add(choix)
221 # aucun catalogue par défaut n'a été spécifié dans Accas/editeur.ini
222 defaut = liste_choix[0]
223 self.radiobutton.invoke(defaut)
224 self.radiobutton.pack(fill='x',padx=10,pady=10)
225 # centrage de la fenêtre
226 self.fenetre_choix_cata.activate(geometry='centerscreenalways')
228 def chooseCata(self,txt):
230 Méthode activée lorsque l'utilisateur a fait son choix et cliqué sur 'OK' ou sur 'ANNULER'
233 version_cata = self.radiobutton.getcurselection()
234 self.fic_cata = self.dico_catalogues[version_cata][2]
235 self.version_code = version_cata
236 self.appli.format_fichier.set(self.dico_catalogues[version_cata][3])
237 self.fenetre_choix_cata.destroy()
239 self.parent.destroy()
241 def compile_cata(self,cata,catac):
243 Teste si le catalogue a bien besoin d'être recompilé et si oui, le compile et
244 affiche un message dans le splash . Retourne 1 si la compilation s'est bien déroulée,
247 time1 = os.path.getmtime(cata)
249 time2 = os.path.getmtime(catac)
254 # le catalogue doit être recompilé avant d'être importé
255 splash._splash.configure(text="Compilation du catalogue\nCela peut prendre une trentaine de secondes ...")
256 py_compile.compile(cata)
262 #--------------------------------------------------------------------------------
263 # Méthodes concernant la barre de progression lors de l'analyse du catalogue
264 #--------------------------------------------------------------------------------
266 def configure_barre(self,nbcommandes):
267 """ Configure la barre de progression en lui passant comme paramètre le
268 nombre de commandes du catalogue qui lui sert à déterminer la longueur de son incrément """
270 splash._splash.configure(barre='oui',ratio = nbcommandes)
274 def update_barre(self):
275 """ Update la position de la barre de progression : la fait progresser de son incrément """
277 splash._splash.update_barre()
281 def visuCRCATA(self):
283 Méthode permettant l'affichage du rapport de validation
285 cr = CR( debut = "Début rapport de validation du catalogue",
286 fin = "Fin rapport de validation du catalogue")
287 titre="rapport de validation du catalogue"
288 if hasattr(self,'cata_ordonne_cr') :
289 cr.add(self.cata_ordonne_cr)
290 if hasattr(self,'cata_dev_ordonne_cr') :
291 cr.add(self.cata_dev_ordonne_cr)
292 for cata in self.cata:
293 if hasattr(cata,'JdC'):
294 cr.add(cata.JdC.report())
296 self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)