1 # -*- coding: iso-8859-15 -*-
3 Ce module centralise les informations issues de la ligne de commande.
5 La ligne de commande est parsee avec l'aide du module python optparse.
6 Les options possibles sont : -c, -j, -p, -d, -i, -f comme definies ci-dessous.
8 Un exemple typique d'utilisation est :
9 >>> ./appli.py -c V7.3 -d 1 -j aa -i 11 iii -p ppp -i 22 ii -j bb -f ff
11 qui demande a l'application d'ouvrir trois jeux de commandes.
13 Le premier (aa) a un include (11,iii) et est la suite du fichier poursuite ppp
14 qui a lui meme un include (22,ii).
16 Le deuxieme bb est un jeu de commandes simple.
18 Le troisieme est decrit dans le fichier ff de type .ini
19 qui est parse par le module ConfigParser.
20 Chaque section du fichier decrit un jeu de commandes.
21 Un include est specifie par: numero logique=nom du fichier
22 Une poursuite est specifiee par: poursuite=reference a un jeu de commande
23 Cette reference correspond a un nom de section decrivant le jeu de commandes.
24 Le jeu de commandes maitre est donne par l'entree globale jdc dans la section jdc.
37 La session utilisera le catalogue V7.3 en mode debug.
41 from optparse import OptionValueError
43 import ConfigParser, os
45 # Les valeurs decodees par optparse sont mises dans un objet dictionnaire-like.
46 # On l'utilise comme environnement de session.
49 # L'attribut "studies" de d_env est une liste dans laquelle on range les etudes de niveau global.
50 # Une étude est stockée dans un dictionnaire.
51 # La clé "comm" du dictionnaire donne le nom du fichier de commandes principal
52 # La clé (optionnelle) "pours" du dictionnaire donne les informations pour une poursuite
53 # La valeur associée à la clé est un dictionnaire qui contient les informations sur
54 # le nom du fichier de commandes de la poursuite (clé "comm"), une éventuelle poursuite
55 # (clé "pours") et les includes (clés entières associées à des noms de fichier).
59 # Les informations (dictionnaire) associées au fichier de commandes en cours de traitement
60 # sont stockées dans parser.values.current
61 # En general, il faut utiliser current et pas parser.values.studies car les informations
62 # sont stockées hiérarchiquement
65 def check_comm(option, opt_str, value, parser):
66 if not hasattr(parser.values,"studies"):
67 parser.values.studies=[]
69 if not os.path.isfile(value):
70 raise OptionValueError("le fichier de commandes %s n'existe pas" % value)
71 parser.values.comm.append(value)
72 d_study={"comm":value}
73 parser.values.current=d_study
74 parser.values.studies.append(d_study)
76 def check_poursuite(option, opt_str, value, parser):
77 if parser.values.comm is None:
78 raise OptionValueError("un fichier de commandes doit etre defini avant une poursuite %s" % value)
79 if not os.path.isfile(value):
80 raise OptionValueError("le fichier poursuite %s n'existe pas" % value)
81 #current : fichier de commandes en cours de traitement (dictionnaire des infos)
82 comm=parser.values.current
83 d_study={"comm":value}
85 parser.values.current=d_study
87 def check_include(option, opt_str, value, parser):
89 args=[int(parser.rargs[0]),parser.rargs[1]]
91 raise OptionValueError("include mal defini %s" % parser.rargs[0:2])
96 if parser.values.comm is None:
97 raise OptionValueError("un fichier de commandes doit etre defini avant un include %s" % args)
98 if not os.path.isfile(args[1]):
99 raise OptionValueError("le fichier include %s n'existe pas" % args[1])
101 comm=parser.values.current
102 comm[args[0]]=args[1]
105 def check_jdc(config,jdc,parser,fich):
107 Fonction : analyse une section de fichier .ini pour en extraire
108 les informations sur les fichiers poursuite et includes
109 définis dans cette section
111 parser : objet analyseur de la ligne de commande
112 fich : nom du fichier .ini en cours d'analyse
113 config : objet de la classe ConfigParser permettant de parser le fichier fich
114 jdc : nom de la section du fichier fich à analyser
118 for o in config.options(jdc):
120 p=config.get(jdc,"poursuite")
122 if not config.has_option(p,"comm"):
123 raise OptionValueError("jdc %s manque fichier comm dans section %s" % (fich,p))
124 comm=config.get(p,"comm")
125 if not os.path.isfile(comm):
126 raise OptionValueError("jdc %s, le fichier de commandes %s n'existe pas" % (fich,comm))
128 pours=check_jdc(config,p,parser,fich)
130 d_study["pours"]=pours
135 # si le parametre est un entier, il s'agit d'un include
136 inc=config.get(jdc,o)
139 if not os.path.isfile(inc):
140 raise OptionValueError("jdc %s fichier include %s, %s n'existe pas" % (fich,unit,inc))
145 def check_fich(option, opt_str, fich, parser):
147 Fonction : parse le fichier fich (format .ini)
149 option : option en cours de traitement
150 opt_str : chaine de caracteres utilisee par l'utilisateur
151 fich : nom du fichier .ini donné par l'utilisateur
152 parser : objet parseur des options de la ligne de commande
154 if not os.path.isfile(fich):
155 raise OptionValueError("le fichier jdc %s n'existe pas" % fich)
156 if parser.values.fich is None:
157 parser.values.fich=[]
158 parser.values.fich.append(fich)
159 if not hasattr(parser.values,"studies"):
160 parser.values.studies=[]
161 parser.values.comm=[]
162 config = ConfigParser.ConfigParser()
164 if not config.has_option("jdc","jdc"):
165 raise OptionValueError("jdc %s manque option jdc dans section jdc")
166 jdc=config.get("jdc","jdc")
168 if not config.has_option(jdc,"comm"):
169 raise OptionValueError("jdc %s manque fichier comm dans section %s" % (fich,jdc))
170 comm=config.get(jdc,"comm")
171 if not os.path.isfile(comm):
172 raise OptionValueError("jdc %s, le fichier de commandes %s n'existe pas" % (fich,comm))
173 parser.values.comm.append(comm)
175 d_study=check_jdc(config,jdc,parser,fich)
177 parser.values.studies.append(d_study)
179 def print_pours(d_pours,dec=''):
180 # Les fichiers includes d'abord
181 for k,v in d_pours.items():
182 if k in ("pours","comm"):continue
183 print dec+" include",k," :",v
185 if d_pours.has_key("pours"):
186 # Description de la poursuite
187 print dec+" fichier poursuite:",d_pours["pours"]["comm"]
188 print_pours(d_pours["pours"],dec=dec+"++")
192 if d_env.studies is None:return
193 for study in d_env.studies:
194 print "nom etude:",study["comm"]
195 print_pours(study,dec="++")
199 # creation du parser des options de la ligne de commande
200 parser=optparse.OptionParser(usage="usage: %prog [options]",version="%prog 1.8")
202 parser.add_option("-j","--jdc",dest="comm",type='string',
203 action="callback",callback=check_comm,
204 help="nom du fichier de commandes")
205 parser.add_option("-p","--poursuite", type="string",dest="pours",
206 action="callback", callback=check_poursuite,
207 help="nom du fichier poursuite")
208 parser.add_option("-i","--include",
209 action="callback", callback=check_include,
210 nargs=2, help="numero d'unite suivi du nom du fichier include")
212 parser.add_option("-f","--fich", type="string",dest="fich",
213 action="callback", callback=check_fich,
214 help="fichier decrivant une etude")
216 parser.add_option("-c","--cata", action="store", type="string",dest="cata",
217 help="version de catalogue a utiliser")
219 parser.add_option("-d","--debug", action="store", type="int",dest="debug",
220 help="niveau de debug")
225 parser=create_parser()
226 (options,args)=parser.parse_args(args)
227 if not hasattr(options,"studies"):
231 del parser.values.current
236 for file in args[1:]:
237 if os.path.isfile(file):
238 options.comm.append(file)
239 options.studies.append({"comm":file})
241 parser.error("incorrect number of arguments")
248 def get_unit(d_study,appli):
250 Fonction : construit et retourne un dictionnaire contenant les informations
251 sur les fichiers poursuite et includes sous la forme adaptée
253 [None : nom_fichier, texte_source, unites_associees, # poursuite
254 numero_include : nom_fichier, texte_source, unites_associees, # include
256 d_study : dictionnaire de l'etude
257 appli : objet application EFICAS (permet d'acceder aux services comme get_source)
259 return get_dunit(d_study,appli)
261 def get_dunit(d_unit,appli):
263 if d_unit.has_key("pours"):
265 comm=d_unit["pours"]["comm"]
266 g=get_dunit(d_unit["pours"],appli)
267 text=appli.get_source(comm)
270 for k,v in d_unit.items():
271 if k in ("pours","comm"): continue
272 text=appli.get_source(v)