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