Salome HOME
81423762e902d1c70f4dea74234b870d044d7140
[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
44 class READERCATA:
45
46    menu_defs=[
47               ('Catalogue',[
48                            ("Rapport de validation catalogue",'visuCRCATA'),
49                          ]
50               )
51              ]
52
53    button_defs=[]
54
55    def __init__(self,appli,parent):
56       self.appli=appli
57       self.parent=parent
58       self.code=self.appli.code
59       self.appli.format_fichier.set('python')
60       self.OpenCata()
61
62       self.cataitem=None
63       #XXX CCAR : Pour le moment je ne construis pas le CATAItem
64       #self.cataitem = catabrowser.CATAItem(self,"Catalogue "+self.code,
65                                            #self.cata,
66                                            #objet_cata_ordonne = self.cata_ordonne_dico)
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       message1 = "Compilation des fichiers Eficas \n\n Veuillez patienter ..."
74       splash._splash.configure(text = message1)
75       if len(self.appli.CONFIGURATION.catalogues) == 1:
76           self.fic_cata = self.appli.CONFIGURATION.catalogues[0][2]
77           self.code = self.appli.CONFIGURATION.catalogues[0][0]
78           self.version_code = self.appli.CONFIGURATION.catalogues[0][1]
79           self.appli.format_fichier.set(self.appli.CONFIGURATION.catalogues[0][3])
80       elif len(self.appli.CONFIGURATION.catalogues) == 0:
81           # aucun catalogue défini dans le fichier Accas/editeur.ini
82           if self.code == 'ASTER' :
83               self.fic_cata = os.path.join(prefs.CODE_PATH,'Cata','cata.py')
84           elif self.code == 'SATURNE' :
85               self.fic_cata = os.path.join(prefs.CODE_PATH,'Cata','cata_saturne.py')
86           elif self.code == 'DESCARTES':
87               self.fic_cata = os.path.join(prefs.CODE_PATH,'Cata','cata_descartes.py')
88           else :
89               print 'Code inconnu'
90               sys.exit(0)
91       else:
92           # plusieurs catalogues sont disponibles : il faut demander à l'utilisateur
93           # lequel il veut utiliser ...
94           self.ask_choix_catalogue()
95       if self.fic_cata == None :
96           self.parent.destroy()
97           sys.exit(0)
98       # détermination de fic_cata_c et fic_cata_p
99       self.fic_cata_c = self.fic_cata + 'c'
100       self.fic_cata_p = os.path.splitext(self.fic_cata)[0]+'_pickled.py'
101       print "Debut compil cata: ",time.clock()
102       # compilation éventuelle du catalogue
103       test = self.compile_cata(self.fic_cata,self.fic_cata_c)
104       print "Fin compil cata: ",time.clock()
105       if not test : showerror("Compilation catalogue","Impossible de compiler le catalogue %s" %self.fic_cata)
106       # import du catalogue
107       print "Debut import_cata: ",time.clock()
108       self.cata = self.import_cata(self.fic_cata)
109       print "Fin import_cata: ",time.clock()
110       if not self.cata : showerror("Import du catalogue","Impossible d'importer le catalogue %s" %self.fic_cata)
111       # analyse du catalogue (ordre des mots-clés)
112       #XXX A priori ceci fait double emploi. Il faut d'abord calculer l'ordre
113       # puis fabriquer le CATAItem
114       #CCAR :self.catalo = catabrowser.CATAItem(self,"Catalogue",self.cata)
115       print "Debut Retrouve_Ordre: ",time.clock()
116       self.Retrouve_Ordre_Cata_Standard()
117       print "Fin Retrouve_Ordre: ",time.clock()
118       # chargement et analyse des catalogues développeur (le cas échéant)
119       if self.appli.CONFIGURATION.isdeveloppeur == 'OUI' :
120           init_rep_cata_dev(self.fic_cata,self.appli.CONFIGURATION.path_cata_dev)
121           fic_cata_dev = os.path.join(self.appli.CONFIGURATION.path_cata_dev,'cata_developpeur.py')
122           if os.path.isfile(fic_cata_dev):
123               # il y a bien un catalogue développeur : il faut récupérer le module_object associé ...
124               test = self.compile_cata(fic_cata_dev,fic_cata_dev+'c')
125               if not test :
126                   showinfo("Compilation catalogue développeur",
127                            "Erreur dans la compilation du catalogue développeur")
128                   self.cata = (self.cata,)
129               else:
130                   self.cata_dev =self.import_cata(fic_cata_dev)
131                   self.Retrouve_Ordre_Cata_Developpeur()
132                   self.cata = (self.cata,self.cata_dev)
133           else:
134               self.cata = (self.cata,)
135       else:
136           self.cata = (self.cata,)
137
138    def import_cata(self,cata):
139       """ 
140           Réalise l'import du catalogue dont le chemin d'accès est donné par cata
141       """
142       import imp
143       splash._splash.configure(text = "Chargement du catalogue")
144       nom_cata = os.path.splitext(os.path.basename(cata))[0]
145       rep_cata = os.path.dirname(cata)
146       sys.path[:0] = [rep_cata]
147       try :
148           f,p,d = imp.find_module(nom_cata)
149           o = imp.load_module(nom_cata,f,p,d)
150           return o
151       except Exception,e:
152           traceback.print_exc()
153           return 0
154
155    def Retrouve_Ordre_Cata_Standard(self):
156       """ 
157           Retrouve l'ordre des mots-clés dans le catalogue, cad :
158            - si ce dernier a été modifié, relance l'analyse du catalogue pour déterminer
159                l'ordre des mots-clés dans le catalogue
160            - s'il n'a pas été modifié, relie le fichier pickle 
161       """
162       time1 = os.path.getmtime(self.fic_cata)
163       try :
164           time2 = os.path.getmtime(self.fic_cata_p)
165       except:
166           time2 = 0
167       if time2 > time1 :
168           # l'objet catalogue n'a pas été modifié depuis le dernier "pickle"
169           self.Get_Ordre_Cata()
170       else :
171           # le catalogue a été modifié depuis le dernier "pickle" :
172           # il faut retrouver l'ordre du catalogue et refaire pickle
173           self.Get_Ordre_Cata(mode='cata')
174       self.appli.affiche_infos("Catalogue standard chargé")
175
176    def Get_Ordre_Cata(self,mode='pickle'):
177       """ 
178           Retrouve l'ordre du catalogue :
179             - mode='pickle ': tente de relire le fichier pickle et sinon lance l'analyse du catalogue
180             - mode='cata'   : force l'analyse du catalogue directement sans relire le pickle
181       """
182       if mode == 'pickle' :
183           try:
184               f = open(self.fic_cata_p)
185               u = cPickle.Unpickler(f)
186               splash._splash.configure(text = "Analyse du catalogue")
187               self.cata_ordonne_dico = u.load()
188               f.close()
189           except :
190               # on peut ne pas arriver à relire le fichier pickle s'il a été altéré
191               # ou (le plus probable) s'il a été créé sous un autre OS
192               self.Get_Ordre_Cata(mode='cata')
193       elif mode == 'cata':
194           splash._splash.configure(text = "Analyse du catalogue",barre='oui')
195           cata_ordonne = analyse_catalogue.analyse_catalogue(self,self.fic_cata)
196           self.cata_ordonne_cr = cata_ordonne.cr
197           self.cata_ordonne_dico = cata_ordonne.dico
198           splash._splash.configure(text = "Sauvegarde des informations sur le catalogue")
199           f = open(self.fic_cata_p,'w+')
200           p = cPickle.Pickler(f)
201           p.dump(self.cata_ordonne_dico)
202           f.close()
203       else :
204           raise Exception("Appel à un mode inconnu de Get_Ordre_Cata : %s" % mode)
205           return
206
207    def ask_choix_catalogue(self):
208       """
209       Ouvre une fenêtre de sélection du catalogue dans le cas où plusieurs
210       ont été définis dans Accas/editeur.ini
211       """
212       # construction du dictionnaire et de la liste des catalogues
213       self.dico_catalogues = {}
214       defaut = None
215       for catalogue in self.appli.CONFIGURATION.catalogues:
216           if catalogue[0] == self.code :
217               self.dico_catalogues[catalogue[1]] = catalogue
218               if len(catalogue) == 5 :
219                   if catalogue[4]=='defaut' : defaut = catalogue[1]
220       liste_choix = self.dico_catalogues.keys()
221       liste_choix.sort()
222       # test si plusieurs catalogues ou non
223       if len(liste_choix) == 0:
224           showerror("Aucun catalogue déclaré pour %s" %self.code)
225           self.quit()
226       elif len(liste_choix) == 1:
227           self.fic_cata = self.dico_catalogues[liste_choix[0]][2]
228           self.version_code = liste_choix[0]
229           return
230       # création d'une boîte de dialogue modale
231       self.fenetre_choix_cata = Pmw.Dialog(self.parent,
232                                            buttons=('OK','ANNULER'),
233                                            defaultbutton = 'OK',
234                                            title = "Choix d'une version du code %s" %self.code,
235                                            command = self.chooseCata)
236       # construction des radioboutons
237       label = `len(liste_choix)`+' versions du code %s sont disponibles\n' %self.code
238       label = label + 'Veuillez choisir celle avec laquelle vous souhaitez travailler :'
239       self.radiobutton = Pmw.RadioSelect(self.fenetre_choix_cata.interior(),
240                                          buttontype='radiobutton',
241                                          labelpos = 'w',
242                                          label_text = label,
243                                          label_font = fontes.standard,
244                                          orient='vertical')
245       for choix in liste_choix :
246           self.radiobutton.add(choix)
247       if defaut == None :
248           # aucun catalogue par défaut n'a été spécifié dans Accas/editeur.ini
249           defaut = liste_choix[0]
250       self.radiobutton.invoke(defaut)
251       self.radiobutton.pack(fill='x',padx=10,pady=10)
252       # centrage de la fenêtre
253       self.fenetre_choix_cata.activate(geometry='centerscreenalways')
254
255    def chooseCata(self,txt):
256       """ 
257           Méthode activée lorsque l'utilisateur a fait son choix et cliqué sur 'OK' ou sur 'ANNULER'
258       """
259       if txt == 'OK' :
260           version_cata = self.radiobutton.getcurselection()
261           self.fic_cata = self.dico_catalogues[version_cata][2]
262           self.version_code = version_cata
263           self.appli.format_fichier.set(self.dico_catalogues[version_cata][3])
264           self.fenetre_choix_cata.destroy()
265       else:
266           self.parent.destroy()
267
268    def compile_cata(self,cata,catac):
269       """ 
270            Teste si le catalogue a bien besoin d'être recompilé et si oui, le compile et
271            affiche un message dans le splash . Retourne 1 si la compilation s'est bien déroulée,
272            0 sinon.
273       """
274       time1 = os.path.getmtime(cata)
275       try:
276           time2 = os.path.getmtime(catac)
277       except:
278           time2 = 0
279       if time1 > time2:
280           try:
281               # le catalogue doit être recompilé avant d'être importé
282               splash._splash.configure(text="Compilation du catalogue\nCela peut prendre une trentaine de secondes ...")
283               py_compile.compile(cata)
284           except:
285               return 0
286       return 1
287
288
289 #--------------------------------------------------------------------------------
290 # Méthodes concernant la barre de progression lors de l'analyse du catalogue
291 #--------------------------------------------------------------------------------
292
293    def configure_barre(self,nbcommandes):
294       """ Configure la barre de progression en lui passant comme paramètre le
295           nombre de commandes du catalogue qui lui sert à déterminer la longueur de son incrément """
296       try:
297           splash._splash.configure(barre='oui',ratio = nbcommandes)
298       except:
299           pass
300
301    def update_barre(self):
302       """ Update la position de la barre de progression : la fait progresser de son incrément """
303       try:
304           splash._splash.update_barre()
305       except:
306           pass
307
308    def visuCRCATA(self):
309       """
310       Méthode permettant l'affichage du rapport de validation
311       """
312       cr = CR( debut = "Début rapport de validation du catalogue",
313                fin = "Fin rapport de validation du catalogue")
314       titre="rapport de validation du catalogue"
315       if hasattr(self,'cata_ordonne_cr') :
316           cr.add(self.cata_ordonne_cr)
317       if hasattr(self,'cata_dev_ordonne_cr') :
318           cr.add(self.cata_dev_ordonne_cr)
319       for cata in self.cata:
320           if hasattr(cata,'JdC'):
321               cr.add(cata.JdC.report())
322       texte_cr = str(cr)
323       self.visu_texte_cr = Fenetre(self.appli,titre=titre,texte=texte_cr)
324