1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2013 EDF R&D
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 Ce module centralise les informations issues de la ligne de commande.
23 La ligne de commande est parsee avec l'aide du module python optparse.
24 Les options possibles sont : -c, -j, -p, -d, -i, -f comme definies ci-dessous.
26 Un exemple typique d'utilisation est :
27 >>> ./appli.py -c V7.3 -d 1 -j aa -i 11 iii -p ppp -i 22 ii -j bb -f ff
29 qui demande a l'application d'ouvrir trois jeux de commandes.
31 Le premier (aa) a un include (11,iii) et est la suite du fichier poursuite ppp
32 qui a lui meme un include (22,ii).
34 Le deuxieme bb est un jeu de commandes simple.
36 Le troisieme est decrit dans le fichier ff de type .ini
37 qui est parse par le module ConfigParser.
38 Chaque section du fichier decrit un jeu de commandes.
39 Un include est specifie par: numero logique=nom du fichier
40 Une poursuite est specifiee par: poursuite=reference a un jeu de commande
41 Cette reference correspond a un nom de section decrivant le jeu de commandes.
42 Le jeu de commandes maitre est donne par l'entree globale jdc dans la section jdc.
55 La session utilisera le catalogue V7.3 en mode debug.
60 from optparse import OptionValueError
62 from Tools import optparse
63 from Tools.optparse import OptionValueError
69 from Extensions.i18n import tr
71 # Les valeurs decodees par optparse sont mises dans un objet dictionnaire-like.
72 # On l'utilise comme environnement de session.
75 # L'attribut "studies" de d_env est une liste dans laquelle on range les etudes de niveau global.
76 # Une etude est stockee dans un dictionnaire.
77 # La cle "comm" du dictionnaire donne le nom du fichier de commandes principal
78 # La cle (optionnelle) "pours" du dictionnaire donne les informations pour une poursuite
79 # La valeur associee a la cle est un dictionnaire qui contient les informations sur
80 # le nom du fichier de commandes de la poursuite (cle "comm"), une eventuelle poursuite
81 # (cle "pours") et les includes (cles entieres associees a des noms de fichier).
85 # Les informations (dictionnaire) associees au fichier de commandes en cours de traitement
86 # sont stockees dans parser.values.current
87 # En general, il faut utiliser current et pas parser.values.studies car les informations
88 # sont stockees hierarchiquement
91 def check_comm(option, opt_str, value, parser):
92 if not hasattr(parser.values,"studies"):
93 parser.values.studies=[]
95 if not os.path.isfile(value):
96 raise OptionValueError(tr("le fichier de commandes %s n'existe pas", value))
97 parser.values.comm.append(value)
98 d_study={"comm":value}
99 parser.values.current=d_study
100 parser.values.studies.append(d_study)
102 def check_poursuite(option, opt_str, value, parser):
103 if parser.values.comm is None:
104 raise OptionValueError(tr("un fichier de commandes doit etre defini avant une poursuite %s", value))
105 if not os.path.isfile(value):
106 raise OptionValueError(tr("le fichier poursuite %s n'existe pas", value))
107 #current : fichier de commandes en cours de traitement (dictionnaire des infos)
108 comm=parser.values.current
109 d_study={"comm":value}
110 comm["pours"]=d_study
111 parser.values.current=d_study
113 def check_include(option, opt_str, value, parser):
115 args=[int(parser.rargs[0]),parser.rargs[1]]
117 raise OptionValueError(tr("include mal defini %s", parser.rargs[0:2]))
122 if parser.values.comm is None:
123 raise OptionValueError(tr("un fichier de commandes doit etre defini avant un include %s", args))
124 if not os.path.isfile(args[1]):
125 raise OptionValueError(tr("le fichier include %s n'existe pas", args[1]))
127 comm=parser.values.current
128 comm[args[0]]=args[1]
131 def check_jdc(config,jdc,parser,fich):
133 Fonction : analyse une section de fichier .ini pour en extraire
134 les informations sur les fichiers poursuite et includes
135 definis dans cette section
137 parser : objet analyseur de la ligne de commande
138 fich : nom du fichier .ini en cours d'analyse
139 config : objet de la classe ConfigParser permettant de parser le fichier fich
140 jdc : nom de la section du fichier fich à analyser
144 for o in config.options(jdc):
146 p=config.get(jdc,"poursuite")
148 if not config.has_option(p,"comm"):
149 raise OptionValueError(tr(" jdc %(v_1)s manque \
150 fichier comm dans section %(v_2)s", \
151 {'v_1': fich, 'v_2': p}))
152 comm=config.get(p,"comm")
153 if not os.path.isfile(comm):
154 raise OptionValueError(tr("jdc %(v_1)s, le fichier\
155 de commandes %(v_2)s n'existe pas", \
156 {'v_1': fich, 'v_2': comm}))
158 pours=check_jdc(config,p,parser,fich)
160 d_study["pours"]=pours
165 # si le parametre est un entier, il s'agit d'un include
166 inc=config.get(jdc,o)
167 except EficasException:
169 if not os.path.isfile(inc):
170 raise OptionValueError(tr(" jdc %(v_1)s \
171 fichier include %(v_2)s, %(v_3)s \
173 {'v_1': fich, 'v_2': unit, 'v_3': inc}))
178 def check_fich(option, opt_str, fich, parser):
180 Fonction : parse le fichier fich (format .ini)
182 option : option en cours de traitement
183 opt_str : chaine de caracteres utilisee par l'utilisateur
184 fich : nom du fichier .ini donne par l'utilisateur
185 parser : objet parseur des options de la ligne de commande
187 if not os.path.isfile(fich):
188 raise OptionValueError(tr(" le fichier jdc %s n'existe pas", str(fich)))
189 if parser.values.fich is None:
190 parser.values.fich=[]
191 parser.values.fich.append(fich)
192 if not hasattr(parser.values,"studies"):
193 parser.values.studies=[]
194 parser.values.comm=[]
195 config = ConfigParser.ConfigParser()
197 if not config.has_option(u"jdc","jdc"):
198 raise OptionValueError(tr(" jdc %s manque option jdc dans section jdc", str(fich)))
199 jdc=config.get(u"jdc","jdc")
201 if not config.has_option(jdc,"comm"):
202 raise OptionValueError(tr(" jdc %(v_1)s manque fichier comm \
203 dans section %(v_2)s", {'v_1': fich, 'v_2': jdc}))
204 comm=config.get(jdc,"comm")
205 if not os.path.isfile(comm):
206 raise OptionValueError(tr("jdc %(v_1)s, le fichier de commandes \
207 %(v_2)s n'existe pas", {'v_1': fich, 'v_2': comm}))
208 parser.values.comm.append(comm)
210 d_study=check_jdc(config,jdc,parser,fich)
212 parser.values.studies.append(d_study)
214 def print_pours(d_pours,dec=''):
215 # Les fichiers includes d'abord
216 for k,v in d_pours.items():
217 if k in (u"pours","comm"):continue
218 print ( tr("%(v_1)s include %(v_2)s : %(v_3)s", {'v_1': str(dec), 'v_2': str(k), 'v_3': str(v)}))
220 if d_pours.has_key(u"pours"):
221 # Description de la poursuite
222 print (tr("%(v_1)s fichier poursuite: %(v_2)s", {'v_1': dec, 'v_2': d_pours["pours"]["comm"]}))
223 print_pours(d_pours["pours"],dec=dec+"++")
226 if d_env.studies is None:return
227 for study in d_env.studies:
228 print (tr("nom etude : %s", study["comm"]))
229 print_pours(study,dec="++")
232 # creation du parser des options de la ligne de commande
234 parser=optparse.OptionParser(usage=tr("utilisation : %prog [options]"), version="%prog 1.13")
236 parser.add_option(u"-j","--jdc",dest="comm",type='string',
237 action="callback",callback=check_comm,
238 help=tr("nom du fichier de commandes"))
240 parser.add_option(u"-p","--poursuite", type="string",dest="pours",
241 action="callback", callback=check_poursuite,
242 help=tr("nom du fichier poursuite"))
244 parser.add_option(u"-i","--include",
245 action="callback", callback=check_include,
246 nargs=2, help=tr("numero d'unite suivi du nom du fichier include"))
248 parser.add_option(u"-f","--fich", type="string",dest="fich",
249 action="callback", callback=check_fich,
250 help=tr("fichier decrivant une etude"))
252 parser.add_option(u"-c","--cata", action="store", type="string",dest="cata",
253 help=tr("version de catalogue a utiliser"))
255 parser.add_option(u"-k","--kode", action="store", type="string",dest="code",
256 help=tr("nom du code a utiliser"))
258 parser.add_option(u"-d","--debug", action="store", type="int",dest="debug",
259 help=tr("niveau de debug"))
261 parser.add_option(u"-s","--schema", action="store", type="string",dest="ssCode",
263 # To handle locale information
264 parser.add_option("-l", "--locale", action="store", type="string", dest="locale",
265 help=tr("localisation de l'application, pour la traduction"))
271 parser=create_parser()
272 (options,args)=parser.parse_args(args[1:])
273 if not hasattr(options,"studies"):
277 del parser.values.current
281 if os.path.isfile(file):
282 options.comm.append(file)
283 options.studies.append({"comm":file})
284 #print options.studies
285 elif len(args)==1 and (re.search('.comm',file) or re.search('.map',file)):
290 parser.error(tr("Nombre incorrect d'arguments"))
291 options.comm.append(file)
292 options.studies.append({"comm":file})
293 elif len(args) == 1 and options.locale:
294 print (tr("Localisation specifiee pour l'application."))
296 parser.error(tr("Nombre incorrect d'arguments"))
303 def get_unit(d_study,appli):
305 Fonction : construit et retourne un dictionnaire contenant les informations
306 sur les fichiers poursuite et includes sous la forme adaptee
309 [None : nom_fichier, texte_source, unites_associees, # poursuite
310 numero_include : nom_fichier, texte_source, unites_associees, # include
313 d_study : dictionnaire de l'etude
314 appli : objet application EFICAS (permet d'acceder aux services comme get_source)
316 return get_dunit(d_study,appli)
318 def get_dunit(d_unit,appli):
320 if d_unit.has_key(u"pours"):
322 comm=d_unit["pours"]["comm"]
323 g=get_dunit(d_unit["pours"],appli)
324 text=appli.get_source(comm)
327 for k,v in d_unit.items():
328 if k in (u"pours","comm"): continue
329 text=appli.get_source(v)