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