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