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+"++")
227 if d_env.studies is None:return
228 for study in d_env.studies:
229 print tr("nom etude : %s", study["comm"])
230 print_pours(study,dec="++")
234 # creation du parser des options de la ligne de commande
236 parser=optparse.OptionParser(usage=tr("utilisation : %prog [options]"), version="%prog 1.13")
238 parser.add_option(u"-j","--jdc",dest="comm",type='string',
239 action="callback",callback=check_comm,
240 help=tr("nom du fichier de commandes"))
242 parser.add_option(u"-p","--poursuite", type="string",dest="pours",
243 action="callback", callback=check_poursuite,
244 help=tr("nom du fichier poursuite"))
246 parser.add_option(u"-i","--include",
247 action="callback", callback=check_include,
248 nargs=2, help=tr("numero d'unite suivi du nom du fichier include"))
250 parser.add_option(u"-f","--fich", type="string",dest="fich",
251 action="callback", callback=check_fich,
252 help=tr("fichier decrivant une etude"))
254 parser.add_option(u"-c","--cata", action="store", type="string",dest="cata",
255 help=tr("version de catalogue a utiliser"))
257 parser.add_option(u"-k","--kode", action="store", type="string",dest="code",
258 help=tr("nom du code a utiliser"))
260 parser.add_option(u"-d","--debug", action="store", type="int",dest="debug",
261 help=tr("niveau de debug"))
263 parser.add_option(u"-s","--schema", action="store", type="string",dest="ssCode",
265 # To handle locale information
266 parser.add_option("-l", "--locale", action="store", type="string", dest="locale",
267 help=tr("localisation de l'application, pour la traduction"))
273 parser=create_parser()
274 (options,args)=parser.parse_args(args[1:])
275 if not hasattr(options,"studies"):
279 del parser.values.current
283 if os.path.isfile(file):
284 options.comm.append(file)
285 options.studies.append({"comm":file})
286 #print options.studies
287 elif len(args)==1 and (re.search('.comm',file) or re.search('.map',file)):
292 parser.error(tr("Nombre incorrect d'arguments"))
293 options.comm.append(file)
294 options.studies.append({"comm":file})
295 elif len(args) == 1 and options.locale:
296 print tr("Localisation specifiee pour l'application.")
298 parser.error(tr("Nombre incorrect d'arguments"))
305 def get_unit(d_study,appli):
307 Fonction : construit et retourne un dictionnaire contenant les informations
308 sur les fichiers poursuite et includes sous la forme adaptee
311 [None : nom_fichier, texte_source, unites_associees, # poursuite
312 numero_include : nom_fichier, texte_source, unites_associees, # include
315 d_study : dictionnaire de l'etude
316 appli : objet application EFICAS (permet d'acceder aux services comme get_source)
318 return get_dunit(d_study,appli)
320 def get_dunit(d_unit,appli):
322 if d_unit.has_key(u"pours"):
324 comm=d_unit["pours"]["comm"]
325 g=get_dunit(d_unit["pours"],appli)
326 text=appli.get_source(comm)
329 for k,v in d_unit.items():
330 if k in (u"pours","comm"): continue
331 text=appli.get_source(v)