]> SALOME platform Git repositories - tools/eficas.git/blob - Editeur/readercata.py
Salome HOME
CCAR:
[tools/eficas.git] / Editeur / readercata.py
1 #            CONFIGURATION MANAGEMENT OF EDF VERSION
2 # ======================================================================
3 # COPYRIGHT (C) 1991 - 2002  EDF R&D                  WWW.CODE-ASTER.ORG
4 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
5 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
6 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
7 # (AT YOUR OPTION) ANY LATER VERSION.
8 #
9 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
10 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
11 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
12 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
13 #
14 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
15 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
16 #    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
17 #
18 #
19 # ======================================================================
20 """
21     Ce module sert à lire un catalogue et à construire
22     un objet CataItem pour Eficas.
23     Il s'appuie sur la classe READERCATA
24 """
25 # Modules Python
26 import time
27 import os,sys,py_compile
28 import traceback
29 import cPickle
30 import Pmw
31 from tkMessageBox import showinfo,showerror
32
33 # Modules Eficas
34 import prefs
35 import splash
36 import fontes
37 import analyse_catalogue
38 from Noyau.N_CR import CR
39 from widgets import Fenetre
40 from utils import init_rep_cata_dev
41
42 #import catabrowser
43 import autre_analyse_cata
44
45 class READERCATA:
46
47    menu_defs=[
48               ('Catalogue',[
49                            ("Rapport de validation catalogue",'visuCRCATA'),
50                          ]
51               )
52              ]
53
54    button_defs=[]
55
56    def __init__(self,appli,parent):
57       self.appli=appli
58       self.parent=parent
59       self.code=self.appli.code
60       self.appli.format_fichier.set('python')
61       self.OpenCata()
62       self.cataitem=None
63
64    def OpenCata(self):
65       """ 
66           Ouvre le catalogue standard du code courant, cad le catalogue présent
67           dans le répertoire Cata 
68       """
69       message1 = "Compilation des fichiers Eficas \n\n Veuillez patienter ..."
70       splash._splash.configure(text = message1)
71       if len(self.appli.CONFIGURATION.catalogues) == 1:
72           self.fic_cata = self.appli.CONFIGURATION.catalogues[0][2]
73           self.code = self.appli.CONFIGURATION.catalogues[0][0]
74           self.version_code = self.appli.CONFIGURATION.catalogues[0][1]
75           self.appli.format_fichier.set(self.appli.CONFIGURATION.catalogues[0][3])
76       elif len(self.appli.CONFIGURATION.catalogues) == 0:
77           # aucun catalogue défini dans le fichier Accas/editeur.ini
78           if self.code == 'ASTER' :
79               self.fic_cata = os.path.join(prefs.CODE_PATH,'Cata','cata.py')
80           elif self.code == 'SATURNE' :
81               self.fic_cata = os.path.join(prefs.CODE_PATH,'Cata','cata_saturne.py')
82           elif self.code == 'DESCARTES':
83               self.fic_cata = os.path.join(prefs.CODE_PATH,'Cata','cata_descartes.py')
84           else :
85               print 'Code inconnu'
86               sys.exit(0)
87       else:
88           # plusieurs catalogues sont disponibles : il faut demander à l'utilisateur
89           # lequel il veut utiliser ...
90           self.ask_choix_catalogue()
91       if self.fic_cata == None :
92           self.parent.destroy()
93           sys.exit(0)
94       # détermination de fic_cata_c et fic_cata_p
95       self.fic_cata_c = self.fic_cata + 'c'
96       self.fic_cata_p = os.path.splitext(self.fic_cata)[0]+'_pickled.py'
97       print "Debut compil cata: ",time.clock()
98       # compilation éventuelle du catalogue
99       test = self.compile_cata(self.fic_cata,self.fic_cata_c)
100       print "Fin compil cata: ",time.clock()
101       if not test : showerror("Compilation catalogue","Impossible de compiler le catalogue %s" %self.fic_cata)
102       # import du catalogue
103       print "Debut import_cata: ",time.clock()
104       self.cata = self.import_cata(self.fic_cata)
105       print "Fin import_cata: ",time.clock()
106       if not self.cata : showerror("Import du catalogue","Impossible d'importer le catalogue %s" %self.fic_cata)
107       #
108       # analyse du catalogue (ordre des mots-clés)
109       #
110       print "Debut Retrouve_Ordre: ",time.clock()
111       # Retrouve_Ordre_Cata_Standard fait une analyse textuelle du catalogue
112       # remplacé par Retrouve_Ordre_Cata_Standard_autre qui utilise une numerotation
113       # des mots clés à la création
114       #self.Retrouve_Ordre_Cata_Standard()
115       self.Retrouve_Ordre_Cata_Standard_autre()
116       print "Fin Retrouve_Ordre: ",time.clock()
117       #
118       # chargement et analyse des catalogues développeur (le cas échéant)
119       #
120       if self.appli.CONFIGURATION.isdeveloppeur == 'OUI' :
121           init_rep_cata_dev(self.fic_cata,self.appli.CONFIGURATION.path_cata_dev)
122           fic_cata_dev = os.path.join(self.appli.CONFIGURATION.path_cata_dev,'cata_developpeur.py')
123           if os.path.isfile(fic_cata_dev):
124               # il y a bien un catalogue développeur : il faut récupérer le module_object associé ...
125               test = self.compile_cata(fic_cata_dev,fic_cata_dev+'c')
126               if not test :
127                   showinfo("Compilation catalogue développeur",
128                            "Erreur dans la compilation du catalogue développeur")
129                   self.cata = (self.cata,)
130               else:
131                   self.cata_dev =self.import_cata(fic_cata_dev)
132                   #self.Retrouve_Ordre_Cata_Developpeur()
133                   self.Retrouve_Ordre_Cata_Developpeur_autre()
134                   self.cata = (self.cata,self.cata_dev)
135           else:
136               self.cata = (self.cata,)
137       else:
138           self.cata = (self.cata,)
139
140    def import_cata(self,cata):
141       """ 
142           Réalise l'import du catalogue dont le chemin d'accès est donné par cata
143       """
144       import imp
145       splash._splash.configure(text = "Chargement du catalogue")
146       nom_cata = os.path.splitext(os.path.basename(cata))[0]
147       rep_cata = os.path.dirname(cata)
148       sys.path[:0] = [rep_cata]
149       try :
150           f,p,d = imp.find_module(nom_cata)
151           o = imp.load_module(nom_cata,f,p,d)
152           return o
153       except Exception,e:
154           traceback.print_exc()
155           return 0
156
157    def Retrouve_Ordre_Cata_Standard_autre(self):
158       """ 
159           Construit une structure de données dans le catalogue qui permet
160           à EFICAS de retrouver l'ordre des mots-clés dans le texte du catalogue.
161           Pour chaque entité du catlogue on crée une liste de nom ordre_mc qui
162           contient le nom des mots clés dans le bon ordre
163       """ 
164       self.cata_ordonne_dico=autre_analyse_cata.analyse_catalogue(self.cata)
165
166    def Retrouve_Ordre_Cata_Standard(self):
167       """ 
168           Retrouve l'ordre des mots-clés dans le catalogue, cad :
169            - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
170                l'ordre des mots-clés dans le catalogue
171            - s'il n'a pas été modifié, relie le fichier pickle 
172       """
173       time1 = os.path.getmtime(self.fic_cata)
174       try :
175           time2 = os.path.getmtime(self.fic_cata_p)
176       except:
177           time2 = 0
178       if time2 > time1 :
179           # l'objet catalogue n'a pas été modifié depuis le dernier "pickle"
180           self.Get_Ordre_Cata()
181       else :
182           # le catalogue a été modifié depuis le dernier "pickle" :
183           # il faut retrouver l'ordre du catalogue et refaire pickle
184           self.Get_Ordre_Cata(mode='cata')
185       self.appli.affiche_infos("Catalogue standard chargé")
186
187    def Retrouve_Ordre_Cata_Developpeur(self):
188       """ 
189           Retrouve l'ordre des mots-clés dans le catalogue, cad :
190           - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
191             l'ordre des mots-clés dans le catalogue
192           - s'il n'a pas été modifié, relie le fichier pickle 
193       """
194       if self.code != 'ASTER' : return
195       fic_cata = os.path.join(self.appli.CONFIGURATION.path_cata_dev,'cata_developpeur.py')
196       message="Chargement catalogue développeur présent dans :\n %s..." % self.appli.CONFIGURATION.path_cata_dev
197       splash._splash.configure(text = message,barre='oui')
198       cata_dev_ordonne = analyse_cata.analyse_catalogue(self,self.fic_cata)
199       self.cata_dev_ordonne_cr = cata_dev_ordonne.cr
200       cata_dev_ordonne_dico = cata_dev_ordonne.entites
201       self.cata_ordonne_dico.update(cata_dev_ordonne_dico)
202       self.appli.affiche_infos(" catalogue(s) développeur(s) chargé(s)" )
203
204    def Retrouve_Ordre_Cata_Developpeur_autre(self):
205       """
206           Retrouve l'ordre des mots-clés dans le catalogue, cad :
207           - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
208             l'ordre des mots-clés dans le catalogue
209           - s'il n'a pas été modifié, relie le fichier pickle
210       """
211       if self.code != 'ASTER' : return
212       message="Chargement catalogue développeur présent dans :\n %s..." % self.appli.CONFIGURATION.path_cata_dev
213       splash._splash.configure(text = message,barre='oui')
214       cata_dev_ordonne_dico = autre_analyse_cata.analyse_catalogue(self.cata_dev)
215       self.cata_ordonne_dico.update(cata_dev_ordonne_dico)
216       self.appli.affiche_infos(" catalogue(s) développeur(s) chargé(s)" )
217
218    def Get_Ordre_Cata(self,mode='pickle'):
219       """ 
220           Retrouve l'ordre du catalogue :
221             - mode='pickle ': tente de relire le fichier pickle et sinon lance l'analyse du catalogue
222             - mode='cata'   : force l'analyse du catalogue directement sans relire le pickle
223       """
224       if mode == 'pickle' :
225           try:
226               f = open(self.fic_cata_p)
227               u = cPickle.Unpickler(f)
228               splash._splash.configure(text = "Analyse du catalogue")
229               self.cata_ordonne_dico = u.load()
230               f.close()
231           except :
232               # on peut ne pas arriver à relire le fichier pickle s'il a été altéré
233               # ou (le plus probable) s'il a été créé sous un autre OS
234               self.Get_Ordre_Cata(mode='cata')
235       elif mode == 'cata':
236           splash._splash.configure(text = "Analyse du catalogue",barre='oui')
237           cata_ordonne = analyse_catalogue.analyse_catalogue(self,self.fic_cata)
238           self.cata_ordonne_cr = cata_ordonne.cr
239           self.cata_ordonne_dico = cata_ordonne.entites
240           splash._splash.configure(text = "Sauvegarde des informations sur le catalogue")
241           f = open(self.fic_cata_p,'w+')
242           p = cPickle.Pickler(f)
243           p.dump(self.cata_ordonne_dico)
244           f.close()
245       else :
246           raise Exception("Appel à un mode inconnu de Get_Ordre_Cata : %s" % mode)
247           return
248
249    def ask_choix_catalogue(self):
250       """
251       Ouvre une fenêtre de sélection du catalogue dans le cas où plusieurs
252       ont été définis dans Accas/editeur.ini
253       """
254       # construction du dictionnaire et de la liste des catalogues
255       self.dico_catalogues = {}
256       defaut = None
257       for catalogue in self.appli.CONFIGURATION.catalogues:
258           if catalogue[0] == self.code :
259               self.dico_catalogues[catalogue[1]] = catalogue
260               if len(catalogue) == 5 :
261                   if catalogue[4]=='defaut' : defaut = catalogue[1]
262       liste_choix = self.dico_catalogues.keys()
263       liste_choix.sort()
264       # test si plusieurs catalogues ou non
265       if len(liste_choix) == 0:
266           showerror("Aucun catalogue déclaré pour %s" %self.code)
267           self.quit()
268       elif len(liste_choix) == 1:
269           self.fic_cata = self.dico_catalogues[liste_choix[0]][2]
270           self.version_code = liste_choix[0]
271           return
272       # création d'une boîte de dialogue modale
273       self.fenetre_choix_cata = Pmw.Dialog(self.parent,
274                                            buttons=('OK','ANNULER'),
275                                            defaultbutton = 'OK',
276                                            title = "Choix d'une version du code %s" %self.code,
277                                            command = self.chooseCata)
278       # construction des radioboutons
279       label = `len(liste_choix)`+' versions du code %s sont disponibles\n' %self.code
280       label = label + 'Veuillez choisir celle avec laquelle vous souhaitez travailler :'
281       self.radiobutton = Pmw.RadioSelect(self.fenetre_choix_cata.interior(),
282                                          buttontype='radiobutton',
283                                          labelpos = 'w',
284                                          label_text = label,
285                                          label_font = fontes.standard,
286                                          orient='vertical')
287       for choix in liste_choix :
288           self.radiobutton.add(choix)
289       if defaut == None :
290           # aucun catalogue par défaut n'a été spécifié dans Accas/editeur.ini
291           defaut = liste_choix[0]
292       self.radiobutton.invoke(defaut)
293       self.radiobutton.pack(fill='x',padx=10,pady=10)
294       # centrage de la fenêtre
295       self.fenetre_choix_cata.activate(geometry='centerscreenalways')
296
297    def chooseCata(self,txt):
298       """ 
299           Méthode activée lorsque l'utilisateur a fait son choix et cliqué sur 'OK' ou sur 'ANNULER'
300       """
301       if txt == 'OK' :
302           version_cata = self.radiobutton.getcurselection()
303           self.fic_cata = self.dico_catalogues[version_cata][2]
304           self.version_code = version_cata
305           self.appli.format_fichier.set(self.dico_catalogues[version_cata][3])
306           self.fenetre_choix_cata.destroy()
307       else:
308           self.parent.destroy()
309
310    def compile_cata(self,cata,catac):
311       """ 
312            Teste si le catalogue a bien besoin d'être recompilé et si oui, le compile et
313            affiche un message dans le splash . Retourne 1 si la compilation s'est bien déroulée,
314            0 sinon.
315       """
316       time1 = os.path.getmtime(cata)
317       try:
318           time2 = os.path.getmtime(catac)
319       except:
320           time2 = 0
321       if time1 > time2:
322           try:
323               # le catalogue doit être recompilé avant d'être importé
324               splash._splash.configure(text="Compilation du catalogue\nCela peut prendre une trentaine de secondes ...")
325               py_compile.compile(cata)
326           except:
327               return 0
328       return 1
329
330
331 #--------------------------------------------------------------------------------
332 # Méthodes concernant la barre de progression lors de l'analyse du catalogue
333 #--------------------------------------------------------------------------------
334
335    def configure_barre(self,nbcommandes):
336       """ Configure la barre de progression en lui passant comme paramètre le
337           nombre de commandes du catalogue qui lui sert à déterminer la longueur de son incrément """
338       try:
339           splash._splash.configure(barre='oui',ratio = nbcommandes)
340       except:
341           pass
342
343    def update_barre(self):
344       """ Update la position de la barre de progression : la fait progresser de son incrément """
345       try:
346           splash._splash.update_barre()
347       except:
348           pass
349
350    def visuCRCATA(self):
351       """
352       Méthode permettant l'affichage du rapport de validation
353       """
354       cr = CR( debut = "Début rapport de validation du catalogue",
355                fin = "Fin rapport de validation du catalogue")
356       titre="rapport de validation du catalogue"
357       if hasattr(self,'cata_ordonne_cr') :
358           cr.add(self.cata_ordonne_cr)
359       if hasattr(self,'cata_dev_ordonne_cr') :
360           cr.add(self.cata_dev_ordonne_cr)
361       for cata in self.cata:
362           if hasattr(cata,'JdC'):
363               cr.add(cata.JdC.report())
364       texte_cr = str(cr)
365       self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)
366