4 ## constantes pour les tests de versions
\r
13 import sys,string,re,types,traceback
\r
16 print "Mauvaise installation de Python"
\r
19 REPERTOIRE = os.path.abspath(os.curdir)
\r
21 def strip_points(chaine):
\r
23 Enlève les caractères autres que les chiffres des chaînes
\r
26 for i in range(len(chaine)):
\r
28 dummy = float(chaine[i])
\r
34 class Test_Environnement :
\r
38 def test_plate_forme(self):
\r
40 Teste que la plate-forme est bien supportée
\r
42 if os.name not in ('nt','posix'):
\r
43 self.l_errors.append("La plate-forme %s n'est pas supportée" %os.name)
\r
45 def test_version_python(self):
\r
47 Test de la version de python
\r
49 version = sys.version
\r
50 n = string.index(version,"(") - 1
\r
51 vpyt = strip_points(version[0:n])[0:2] ## recupere les 2 premiers caracteres
\r
52 if int(vpyt)<python_min :
\r
53 self.l_errors.append("La version %s de python n'est plus supportée" %version[0:n])
\r
55 def test_tcl_tk(self):
\r
57 Test des versions de tcl et tk
\r
61 vtcl = Tkinter.tkinter.TCL_VERSION
\r
62 vtk = Tkinter.tkinter.TK_VERSION
\r
64 x = strip_points(vtcl)
\r
66 self.l_errors.append("La version %s de tcl n'est plus supportée" %vtcl)
\r
68 x = strip_points(vtk)
\r
70 self.l_errors.append("La version %s de tk n'est plus supportée" %vtk)
\r
72 self.l_errors.append("Tkinter n'est pas installé")
\r
77 Test de la version de Pmw
\r
82 x = strip_points(vpmw)
\r
84 self.l_errors.append("La version %s de Pmw n'est plus supportée" %vpmw)
\r
86 self.l_errors.append("Pmw n'est pas installé")
\r
90 Active les tests de version Python, versions Tcl/Tk et Pmw
\r
92 self.test_plate_forme()
\r
93 self.test_version_python()
\r
96 if not len(self.l_errors):
\r
97 print "Environnement Ok"
\r
100 print "Il manque des prérequis"
\r
101 print "EFICAS ne peut pas être installé"
\r
102 print "Erreurs : ",string.join(self.l_errors)
\r
106 def __init__(self, master=None, orientation="horizontal", min=0, max=100,
\r
107 width=100, height=25, autoLabel="true", appearance="sunken",
\r
108 fillColor="blue", background="black", labelColor="yellow",
\r
109 labelText="", labelFormat="%d%%", value=50, bd=2):
\r
110 # preserve various values
\r
112 self.orientation=orientation
\r
117 self.autoLabel=autoLabel
\r
118 self.fillColor=fillColor
\r
119 self.labelColor=labelColor
\r
120 self.background=background
\r
121 self.labelText=labelText
\r
122 self.labelFormat=labelFormat
\r
124 self.frame=Tkinter.Frame(master, relief=appearance, bd=bd)
\r
125 self.canvas=Tkinter.Canvas(self.frame, height=height, width=width, bd=0,
\r
126 highlightthickness=0, background=background)
\r
127 self.scale=self.canvas.create_rectangle(0, 0, width, height,
\r
129 self.label=self.canvas.create_text(self.canvas.winfo_reqwidth() / 2,
\r
130 height / 2, text=labelText,
\r
131 anchor="c", fill=labelColor)
\r
133 self.canvas.pack(side='top', fill='x', expand='no')
\r
136 # Trim the values to be between min and max
\r
138 if value > self.max:
\r
140 if value < self.min:
\r
142 # Preserve the new value
\r
144 # Adjust the rectangle
\r
145 if self.orientation == "horizontal":
\r
146 c.coords(self.scale,0, 0,float(value) / self.max * self.width, self.height)
\r
148 c.coords(self.scale,0, self.height - (float(value) / self.max*self.height),self.width, self.height)
\r
149 # Now update the colors
\r
150 c.itemconfig(self.scale, fill=self.fillColor)
\r
151 c.itemconfig(self.label, fill=self.labelColor)
\r
152 # And update the label
\r
153 if self.autoLabel=="true":
\r
154 c.itemconfig(self.label, text=self.labelFormat % value)
\r
156 c.itemconfig(self.label, text=self.labelFormat % self.labelText)
\r
157 c.update_idletasks()
\r
161 from tkMessageBox import showinfo,askyesno,showerror,askretrycancel
\r
165 class SplashScreen(Tkinter.Toplevel):
\r
166 """ Provides a splash screen. Usage:
\r
167 Subclass and override 'CreateWidgets()'
\r
168 In constructor of main window/application call
\r
169 - S = SplashScreen(main=self) (if caller is Toplevel)
\r
170 - S = SplashScreen(main=self.master) (if caller is Frame)
\r
171 - S.quit() after you are done creating your widgets etc.
\r
173 def __init__(self, master,**args):
\r
174 Tkinter.Toplevel.__init__(self, master, relief='groove',borderwidth=5)
\r
175 self.protocol("WM_DELETE_WINDOW",lambda x=0: x+x ) # pour ne pas détruire la fenêtre en pleine copie de fichiers
\r
177 if self.main != None :
\r
178 self.main.withdraw()
\r
179 self.frame = Tkinter.Frame(self)
\r
180 self.frame.pack(expand=1,fill='both')
\r
182 self.geometry("300x200")
\r
183 self.resizable(0,0)
\r
184 self.CreateWidgets()
\r
186 def init(self,args={}):
\r
187 self.text = Tkinter.StringVar()
\r
189 self.icone = 'Editeur/icons/logo_edf.gif'
\r
191 if args == {} : return
\r
192 if args.has_key('text'):
\r
193 self.text.set(args['text'])
\r
194 if args.has_key('titre'):
\r
195 self.title(args['titre'])
\r
196 if args.has_key('code'):
\r
197 self.code = args['code']
\r
199 self.code = 'inconnu'
\r
200 if self.code == 'ASTER' :
\r
201 self.icone = 'Editeur/icons/code_aster.gif'
\r
203 def CreateWidgets(self):
\r
204 fic_image = os.path.join("./", self.icone)
\r
205 if os.path.exists(fic_image):
\r
206 self.catIcon = Tkinter.PhotoImage(file=os.path.join("./", self.icone))
\r
207 Tkinter.Label(self.frame, image=self.catIcon).pack(side=Tkinter.TOP)
\r
209 Tkinter.Label(self.frame, text = "EFICAS pour Code_Aster").pack(side=Tkinter.TOP)
\r
210 self.label = Tkinter.Label(self.frame, textvariable=self.text)
\r
211 self.label.pack(side=Tkinter.TOP,expand=1,fill='both')
\r
212 self.progress = Slider(self.frame,value=0,max=100,orientation='horizontal',
\r
213 fillColor='blue',width=200,height=30,
\r
214 background='white',labelColor='red')
\r
216 def update_barre(self,event=None):
\r
217 """ Permet de faire avancer la barre de progression """
\r
219 self.progress.value = self.progress.value+self.increment
\r
220 self.progress.update()
\r
221 #self.after(100,self.update_barre)
\r
225 def configure_barre(self):
\r
226 """ Calcule l'incrément de progression de la barre en fonction
\r
227 du nombre d'opérations à effectuer afin que le compteur
\r
228 soit à 100% à la fin des opérations"""
\r
229 self.increment = 100./self.ratio
\r
230 self.progress.update()
\r
232 def configure(self,**args):
\r
233 if args.has_key('text'):
\r
234 self.text.set(args['text'])
\r
235 if args.has_key('titre'):
\r
236 self.title(args['titre'])
\r
237 if args.has_key('barre'):
\r
239 self.barre = args['barre']
\r
240 if self.barre == 'oui' and old == 'non':
\r
241 self.progress.frame.pack(in_=self.frame,side='top')
\r
242 elif self.barre == 'non' and old == 'oui':
\r
243 self.progress.frame.pack_forget()
\r
244 if args.has_key('ratio'):
\r
245 self.ratio = args['ratio']
\r
246 self.configure_barre()
\r
250 self.progress = None
\r
253 self.main.deiconify()
\r
255 def centerwindow(window,parent = 'avec'):
\r
256 if parent =='avec':
\r
257 parent = window.winfo_parent()
\r
258 if type(parent) == types.StringType:
\r
260 parent = window._nametowidget(parent)
\r
263 # Find size of window.
\r
264 window.update_idletasks()
\r
265 width = window.winfo_width()
\r
266 height = window.winfo_height()
\r
267 if width == 1 and height == 1:
\r
268 # If the window has not yet been displayed, its size is
\r
269 # reported as 1x1, so use requested size.
\r
270 width = window.winfo_reqwidth()
\r
271 height = window.winfo_reqheight()
\r
272 # Place in centre of screen:
\r
273 if parent =='avec' :
\r
274 x = (window.winfo_screenwidth() - width) / 2 - parent.winfo_vrootx()
\r
275 y = (window.winfo_screenheight() - height) / 3 - parent.winfo_vrooty()
\r
277 x = (window.winfo_screenwidth() - width) / 2
\r
278 y = (window.winfo_screenheight() - height) / 3
\r
283 window.geometry('+%d+%d' % (x, y))
\r
287 Classe utilisée pour représenter chaque option de configuration
\r
289 def __init__(self, pere, nom):
\r
292 self.entree_value = None
\r
293 self.default = None
\r
295 self.pere.register_item(self)
\r
297 def get_valeur(self):
\r
298 return os.path.abspath(self.entree.get())
\r
300 def set_entree(self,entree):
\r
301 self.entree = entree
\r
302 self.pere.register_entree(entree)
\r
304 class Config(Tkinter.Toplevel):
\r
306 Classe principale : une instance de Config est utilisée pour
\r
307 créer l'interface. Toutes les actions (création de répertoire, copie
\r
308 de fichiers ...) sont réalisées par des méthodes de Config ou de ses
\r
311 pat_rep = re.compile(r'^(rep_)([\w_]*)') # expression réguliere pour reconnaitre les
\r
312 # les options qui désignent des répertoires
\r
313 def __init__(self, parent):
\r
314 self.master = parent
\r
315 Tkinter.Toplevel.__init__(self,None)
\r
317 self.title("Installation d'EFICAS")
\r
318 self.geometry("500x320+0+0")
\r
320 self.install_running = 0
\r
321 #évite que la fenêtre puisse être détruite en pleine copie de fichiers
\r
322 self.protocol("WM_DELETE_WINDOW",self.exit )
\r
323 # création des frames
\r
324 self.frame_gen = Tkinter.Frame(self,bd=1,relief='groove')
\r
325 self.frame_gen.place(relx=0,rely=0,relwidth=1,relheight=0.9 )
\r
326 self.frame_but = Tkinter.Frame(self,bd=1,relief='groove')
\r
327 self.frame_but.place(relx=0,rely=0.9 ,relheight=0.1 ,relwidth=1)
\r
328 # création des items de configuration
\r
329 self.make_items_config()
\r
330 # remplissage de la frame générale
\r
331 self.make_frame_gen()
\r
332 # remplissage de la frame boutons
\r
333 self.make_frame_but()
\r
334 # création boîtes de dialogue
\r
335 self.init_complementaire()
\r
337 self.init_systeme()
\r
339 def make_items_config(self):
\r
341 Création des objets Config_item
\r
344 self.items_a_creer = []
\r
345 self.liste_rep_crees = []
\r
347 # designation, texte d'invite , option par defaut(unix), option par defaut(windows), flag obligatoire/facultatif
\r
348 self.l_tx_items = (('rep_install' ,
\r
349 "Répertoire d'installation :",
\r
354 'Répertoire de travail :',
\r
359 'Répertoire matériaux :',
\r
364 "Chemin d'accès à la doc Aster :" ,
\r
370 'Exécutable Acrobat Reader :',
\r
371 '/usr/bin/acroread',
\r
376 for item in self.l_tx_items:
\r
378 setattr(self,nom_item,config_item(self,nom_item))
\r
380 def make_frame_gen(self):
\r
382 Création des zones de saisie des paramètres généraux
\r
384 # Création du label titre de la frame
\r
385 self.information = Tkinter.Label(self.frame_gen,text="CONFIGURATION D'EFICAS")
\r
386 self.information.pack(side="top",pady=10)
\r
387 # création des widgets de saisie des items
\r
388 for txt in self.l_tx_items:
\r
391 if os.name == 'nt':
\r
392 default_value = txt[3]
\r
394 default_value = txt[2]
\r
395 item = getattr(self,nom_item)
\r
396 wdg_item = Pmw.EntryField(self.frame_gen,
\r
398 label_text = txt_item,
\r
399 command = lambda s=self,i=item : s.select_next_entry(i.entree))
\r
400 item.default_value = default_value
\r
401 item.statut = txt[4]
\r
402 item.set_entree(wdg_item)
\r
403 # on affiche les entrées
\r
404 for entree in self.entrees:
\r
405 entree.pack(fill='x', expand=1, padx=10, pady=5)
\r
406 Pmw.alignlabels(self.entrees)
\r
407 self.entrees[0].focus_set()
\r
408 #self.rep_cata_dev.entree.configure(entry_state = 'disabled')
\r
409 self.display_defaults()
\r
411 def make_frame_but(self):
\r
413 Création des boutons de commande Installer et Annuler
\r
415 self.validButton = Tkinter.Button(self.frame_but, text = 'Installer', command = self.run_install)
\r
416 self.exitButton = Tkinter.Button(self.frame_but,
\r
418 command = lambda s=self : s.exit(annule='oui'))
\r
419 self.exitButton.place(relx=0.35,rely=0.5,anchor='center')
\r
420 self.validButton.place(relx=0.65,rely=0.5,anchor='center')
\r
422 def init_complementaire(self):
\r
424 Création de widgets complémentaires (boîtes de dialogue ...)
\r
426 self.erreur_dialog = Pmw.Dialog(self,
\r
427 buttons = ('Modifier', 'Annuler'),
\r
428 defaultbutton = 'Modifier',
\r
430 command = self.erreur_exec)
\r
431 self.erreur_dialog.withdraw()
\r
432 self.fatale_dialog = Pmw.Dialog(self,
\r
433 buttons = ('Annuler',),
\r
435 command = self.fatale_exec)
\r
436 self.fatale_dialog.withdraw()
\r
437 self.info_dialog = Pmw.Dialog(self,
\r
439 title = 'Attention')
\r
440 self.info_dialog.configure(command=self.info_dialog.withdraw())
\r
441 self.info_dialog.withdraw()
\r
442 self.attente = SplashScreen(None,code="ASTER")
\r
443 self.attente.withdraw()
\r
445 def init_systeme(self):
\r
447 Détermine les commandes à exécuter en fonction de l'OS
\r
449 self.d_commandes = {}
\r
450 if os.name == 'nt':
\r
451 self.d_commandes['decompress'] = "unzip.exe "
\r
452 self.d_commandes['copy'] = "copy "
\r
453 self.d_commandes['delete'] = "del "
\r
454 elif os.name == 'posix':
\r
455 self.d_commandes['decompress'] = "gunzip "
\r
456 self.d_commandes['copy'] = "cp "
\r
457 self.d_commandes['delete'] = "rm "
\r
459 def run_install(self):
\r
461 Lance l'installation proprement dite d'EFICAS
\r
463 self.install_running = 1
\r
464 self.afficher_splash()
\r
465 self.deactivate_entries() # Les entrees et les boutons sont desactivees
\r
466 self.deactivate_buttons() # pendant les operations d'installation
\r
467 #self.decompress_archive()
\r
468 #if not os.path.exists(os.path.join(REPERTOIRE,'Eficas')):
\r
469 # self.afficher_fatale("Il manque des fichiers d'EFICAS")
\r
470 # self.install_running = 0
\r
472 self.nb_fichiers = self.compte_fichiers(REPERTOIRE)
\r
473 if self.nb_fichiers == 0:
\r
474 self.afficher_fatale("Il manque des fichiers d'EFICAS")
\r
475 self.install_running = 0
\r
477 # essaie de creer les repertoires.
\r
479 if self.make_dirs() == ECHEC :
\r
480 self.activate_entries()
\r
481 self.activate_buttons()
\r
482 self.install_running = 0
\r
485 self.install_running = 0
\r
486 self.afficher_fatale("Impossible de créer certains répertoires")
\r
488 # affiche la fenêtre avec la barre de progression
\r
489 self.afficher_copie_fichiers()
\r
490 # essaie de copier les fichiers d'EFICAS
\r
492 if self.move_files() == ECHEC:
\r
493 self.afficher_echec("Impossible de copier les fichiers d'EFICAS")
\r
494 self.activate_buttons()
\r
495 self.install_running = 0
\r
498 traceback.print_exc()
\r
499 self.install_running = 0
\r
500 self.afficher_fatale("Impossible de copier certains fichiers")
\r
502 #self.rm_temp_dirs() # efface les répertoires temporaires
\r
504 self.creer_fic_conf() # crée le fichier eficas.conf
\r
506 afficher_info("Impossible de créer le fichier de configuration\n Il est possible de le faire a la main")
\r
507 # self.install_running = 0
\r
508 self.afficher_install_terminee() # A ce stade tout est fait et il ne reste plus qu'à attendre
\r
509 # un clic de souris pour sortir
\r
511 def display_defaults(self):
\r
513 Affiche les valeurs par défaut dans les zones de saisie
\r
515 # racine indique la racine de l'arborescence
\r
516 if os.name == 'nt':
\r
519 racine = os.environ['HOME']
\r
520 # remplit les zones de saisie avec les options par défaut
\r
521 for item in self.items:
\r
522 if item.default_value == None : continue
\r
523 item.default_value = os.path.join(racine,item.default_value)
\r
524 item.entree.insert(0,item.default_value)
\r
526 def register_item(self,item):
\r
528 Enregistre l'item dans la liste des items et éventuellement
\r
529 dans la liste des items à créer (répertoires)
\r
531 self.items.append(item)
\r
532 if self.pat_rep.match(item.nom) :
\r
533 self.items_a_creer.append(item)
\r
535 def register_entree(self,entree):
\r
537 Enregistre la zone de saisie dans la liste des zones
\r
539 self.entrees.append(entree)
\r
541 def select_next_entry(self,entree):
\r
543 Place le focus dans l'entry suivant celle passée en argument
\r
545 index = self.entrees.index(entree)+1
\r
546 if index != len(self.entrees):
\r
547 self.entrees[index].component('entry').focus()
\r
549 def activate_entries(self):
\r
551 Active les entrées. Les zones de saisie deviennent éditables.
\r
553 for item in self.entrees:
\r
554 item.configure(entry_state='normal')
\r
556 def deactivate_entries(self):
\r
558 Désactive les entrées. Les zones ne sont plus éditables.
\r
560 for item in self.entrees: # Les entrees sont desactivees
\r
561 item.configure(entry_state='disabled') # pendant les operations d'installation
\r
563 def activate_buttons(self):
\r
565 active les boutons valider et annuler
\r
567 self.validButton.configure(state = 'normal')
\r
568 self.exitButton.configure(state = 'normal')
\r
570 def deactivate_buttons(self):
\r
572 désactive des boutons valider de annuler
\r
574 self.validButton.configure(state = 'disabled')
\r
575 self.exitButton.configure(state = 'disabled')
\r
577 def erreur_exec(self, result):
\r
579 Callback exécuté lorsque l'utilisateur clique sur un des boutons
\r
580 Modifier/Annuler de la fenêtre de dialogue qui lui présente les erreurs
\r
582 self.erreur_dialog.deactivate(result)
\r
584 if result == 'Annuler':
\r
585 self.install_running = 0
\r
586 self.exit(annule='non')
\r
588 def fatale_exec(self, result):
\r
590 Callback exécuté lorsque l'utilisateur clique sur le bouton
\r
591 Quitter de la fenêtre de dialogue qui lui présente les erreurs fatales
\r
592 Seule solution : sortir de l'installation
\r
594 self.fatale_dialog.deactivate(result)
\r
595 self.install_running = 0
\r
596 self.exit(annule='oui')
\r
598 def test_confirmation(self,flag,nom):
\r
600 Callback activé par le clic sur bouton fenêtre demandant confirmation
\r
601 avant création répertoire facultatif
\r
604 self.confirmation.destroy()
\r
605 self.TEST_confirmation_avant_creation = NON
\r
608 self.confirmation.destroy()
\r
609 self.TEST_confirmation_avant_creation = OUI
\r
611 def afficher_fatale(self, message):
\r
613 Affiche les erreurs fatales
\r
615 self.attente.withdraw()
\r
616 w = Tkinter.Label(self.fatale_dialog.interior(),text = message, pady = 5)
\r
617 w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)
\r
618 self.fatale_dialog.configure(deactivatecommand = w.destroy)
\r
619 self.fatale_dialog.activate()
\r
621 def afficher_echec(self, message):
\r
623 Affiche un message d'erreur
\r
624 Par construction, dès que l'on passe par cette méthode, on sort de l'installation
\r
625 en passant le flag install_running à 0
\r
627 self.attente.withdraw()
\r
628 w = Tkinter.Label(self.erreur_dialog.interior(),text = message, pady = 5)
\r
629 w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)
\r
630 self.erreur_dialog.configure(deactivatecommand = w.destroy)
\r
631 self.erreur_dialog.activate()
\r
633 def confirmation_avant_creation(self,repertoire):
\r
635 Affiche une boite de dialogue pour confirmer la création
\r
636 d'un répertoire facultatif.
\r
638 self.attente.withdraw()
\r
639 self.confirmation = Pmw.Dialog(self,
\r
640 buttons = ('OUI', 'NON'),
\r
641 defaultbutton = 'OUI',
\r
642 title = "Répertoire inexistant",
\r
643 command = lambda f,s=self,r=repertoire : s.test_confirmation(f,r))
\r
644 self.confirmation.withdraw()
\r
645 Tkinter.Label(self.confirmation.interior(),
\r
646 text="Le répertoire %s n'existe pas \n Voulez-vous le créer ?" %repertoire).pack(side='top')
\r
647 self.confirmation.activate(geometry='centerscreenalways')
\r
648 return self.TEST_confirmation_avant_creation
\r
650 def afficher_splash(self):
\r
652 Afficher la boite de message
\r
654 self.attente.deiconify()
\r
655 self.attente.tkraise()
\r
656 centerwindow(self.attente)
\r
657 self.attente.configure(titre="Installation d'EFICAS",
\r
658 text="Vérification intégrité sources Eficas",
\r
661 def afficher_info(self,message):
\r
663 Afficher une boite de warning
\r
665 w = Tkinter.Label(self.info_dialog.interior(),text = message, pady = 5)
\r
666 w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)
\r
667 self.info_dialog.configure(deactivatecommand = w.destroy)
\r
668 self.info_dialog.activate()
\r
670 def afficher_copie_fichiers(self):
\r
672 Afficher la boite de message avec la barre de progression
\r
674 self.attente.deiconify()
\r
675 self.attente.tkraise()
\r
676 self.attente.configure(titre="Installation d'EFICAS",
\r
677 text="copie des fichiers",
\r
679 self.attente.ratio = self.nb_fichiers
\r
680 self.attente.configure_barre()
\r
682 def afficher_install_terminee(self):
\r
684 Afficher le message Installation terminée
\r
687 self.attente.configure(titre="Installation d'EFICAS",
\r
688 text="Installation terminée",
\r
690 self.exitButton.place_forget()
\r
691 self.validButton.place_forget()
\r
692 self.validButton = Tkinter.Button(self.attente.frame,
\r
694 command = self.exit)
\r
695 self.validButton.pack(side='top',pady=5)
\r
696 self.install_running = 0
\r
698 def decompress_archive(self) :
\r
700 Décompresse l'archive d'EFICAS dans un répertoire temporaire (.)
\r
702 print "decompress_archive"
\r
704 commande = os.path.join(REPERTOIRE,self.d_commandes['decompress'])
\r
705 fichier = os.path.join(REPERTOIRE,"eficas.zip")
\r
706 print 'commande =',commande
\r
707 print 'fichier =',fichier
\r
708 os.execv(commande,("eficas.zip",))
\r
710 # self.affiche_echec("Erreur dans la décompression")
\r
712 def normaliser_chemin(self, nom):
\r
714 Retourne le chemin d'accès complet à nom
\r
716 return os.path.abspath(os.path.expanduser(nom))
\r
718 def discriminer_noms(self):
\r
720 Emet un message d'alerte si des zones de saisie ne sont pas remplies
\r
721 ou si des noms de répertoires à créer sont identiques.
\r
724 for item in self.items_a_creer:
\r
725 nom = item.entree.get()
\r
726 if nom == self.rep_install.entree.get(): # il faut ajouter 'Eficas' au chemin du repertoire
\r
727 nom = os.path.join(nom,"Eficas") # d'installation
\r
728 liste_noms.append(nom)
\r
731 for item in self.items_a_creer:
\r
732 nom = item.entree.get()
\r
735 message = "attention : certains répertoires n'ont pas de nom"
\r
736 self.afficher_echec(message)
\r
737 item.entree.component('entry').focus()
\r
743 for item in self.items_a_creer:
\r
744 nom = item.entree.get()
\r
745 if liste_noms.count(nom) >1 :
\r
747 message = "attention : certains répertoires ont le même nom"
\r
748 self.afficher_echec(message)
\r
749 item.entree.component('entry').focus()
\r
754 def compte_fichiers(self,path):
\r
756 Dénombre les fichiers présents dans le répertoire Eficas (et ses sous-répertoires)
\r
759 l_fic = os.listdir(path)
\r
762 if os.path.isdir(os.path.join(path,fic)):
\r
767 nb = nb + self.compte_fichiers(os.path.join(path,rep))
\r
770 def creer_fic_conf(self):
\r
772 Crée le fichier editeur.ini a partir des données saisies
\r
773 par l'administrateur.
\r
775 fichier_conf = os.path.join(self.normaliser_chemin(self.rep_install.get_valeur()),"Eficas/Aster/editeur.ini")
\r
776 f = open(fichier_conf,'w')
\r
777 f.write("path_doc = "+'"'+self.normaliser_chemin(self.rep_docaster.get_valeur())+'"\n')
\r
778 f.write("exec_acrobat = "+'"'+self.normaliser_chemin(self.acrobat.get_valeur())+'"\n')
\r
779 f.write('isdeveloppeur = "NON"\n')
\r
780 f.write("rep_travail = "+'"'+self.normaliser_chemin(self.rep_travail.get_valeur())+'"\n')
\r
781 f.write("rep_cata = "+'"'+os.path.join(self.normaliser_chemin(self.rep_install.get_valeur()),"Eficas/Aster/Cata/")+'"\n') # attention au dernier slash
\r
782 f.write("rep_mat = "+'"'+self.normaliser_chemin(self.rep_mat.get_valeur())+'"\n')
\r
783 cata = """catalogues = (('ASTER','v6',rep_cata + 'cata_STA6.py','python','defaut'),)\n"""
\r
788 def move_files(self):
\r
790 Déplace les fichiers Eficas du répertoire temporaire vers
\r
791 leur répertoire de destination
\r
793 # création du répertoire Eficas
\r
794 rep_eficas = os.path.join(self.rep_install.get_valeur(),'Eficas')
\r
795 self.copy_rep(REPERTOIRE,rep_eficas)
\r
797 def copy_rep(self,rep_dep,rep_arr):
\r
799 Copie le répertoire path_dep et ses sous-répertoires dans path_arr
\r
801 l_fichiers = os.listdir(rep_dep)
\r
802 if not os.path.exists(rep_arr) :
\r
803 # création du répertoire d'arrivée quand il n'existe pas
\r
804 self.mkdirs(rep_arr)
\r
805 for fic in l_fichiers :
\r
806 nom_complet_dep = os.path.join(rep_dep,fic)
\r
807 nom_complet_arr = os.path.join(rep_arr,fic)
\r
808 if os.path.isfile(nom_complet_dep):
\r
809 commande_copie = self.d_commandes['copy']+nom_complet_dep+' '+nom_complet_arr
\r
810 commande_delete= self.d_commandes['delete']+nom_complet_dep
\r
812 os.system(commande_copie)
\r
813 #os.system(commande_delete)
\r
814 self.attente.update_barre()
\r
815 except Exception,e:
\r
817 elif os.path.isdir(nom_complet_dep):
\r
818 self.copy_rep(nom_complet_dep,nom_complet_arr)
\r
820 def rm_temp_dirs(self):
\r
822 Détruit le répertoire temporaire de l'archive d'Eficas
\r
824 rep_arch = os.path.join(REPERTOIRE,'Eficas')
\r
825 self.rm_r(rep_arch)
\r
827 def make_dirs(self):
\r
829 Crée les répertoires d'accueil des fichiers d'EFICAS
\r
831 # création des répertoires dont l'utilisateur a donné le nom
\r
832 if self.discriminer_noms() == ECHEC:
\r
834 for item in self.items_a_creer:
\r
835 if not item.entree.get():
\r
837 nom = item.get_valeur()
\r
838 if nom == self.normaliser_chemin(self.rep_install.entree.get()): # il faut ajouter 'Eficas' au chemin du repertoire
\r
839 nom = os.path.join(nom,"Eficas") # d'installation
\r
840 item.test = self.essai_creer(nom,item.statut)
\r
841 if item.test == ECHEC :
\r
842 item.entree.component('entry').focus()
\r
846 def essai_creer(self, nom, statut):
\r
848 Essaie de créer le répertoire nom s'il n'existe pas déjà.
\r
849 Si statut == 'f' et si le fichier n'existe pas, demande
\r
850 confirmation avant création
\r
852 repertoire = self.normaliser_chemin(nom) # repertoire = chemin absolu de nom
\r
853 if os.path.exists(repertoire):
\r
855 self.afficher_echec("Un fichier ou répertoire de nom "+ repertoire+ " existe déjà !\n"+
\r
856 "L'installation ne peut continuer")
\r
862 # on demande confirmation de création à l'utilisateur
\r
863 test = self.confirmation_avant_creation(repertoire)
\r
868 test = self.mkdirs(repertoire)
\r
870 except Exception,e:
\r
871 message = "La création de "+repertoire+" a échoué :\n %s \n Vérifiez vos droits d'écriture" %str(e) # message d'erreur
\r
872 self.afficher_echec(message)
\r
875 def mkdirs(self,rep):
\r
877 Création récursive des répertoires d'installation.
\r
878 Les noms des répertoires crées sont stockés dans
\r
879 une liste dont se sert la méthode removedir pour
\r
880 restaurer l'environnement initial en cas d'annulation.
\r
882 if rep==os.path.dirname(rep):
\r
885 if os.path.exists(os.path.dirname(rep)):
\r
887 self.liste_rep_crees.append(rep)
\r
890 test = self.mkdirs(os.path.dirname(rep))
\r
893 self.liste_rep_crees.append(rep)
\r
898 def rm_r(self,path):
\r
900 Detruit récursivement path
\r
902 if not os.path.exists(path):
\r
905 if len(os.listdir(path))!=0:
\r
906 for entree in os.listdir(path):
\r
907 entree = os.path.join(path,entree)
\r
910 except Exception,e:
\r
911 self.afficher_info("Impossible de détruire le répertoire : "+path+"\n"+"\n"+str(e)+"\n L'installation continue néanmoins")
\r
913 def removedir(self):
\r
915 Destruction des répertoires déja crées (en cas d'annulation)
\r
917 for rep in self.liste_rep_crees:
\r
919 self.liste_rep_crees = []
\r
921 def exit(self,annule='non'):
\r
923 Tente de sortir de l'application.
\r
924 Echoue si installation en cours
\r
926 if self.install_running :
\r
927 # l'installation est en cours --> on interdit la sortie
\r
928 self.afficher_info("Impossible de quitter tant que l'installation est en cours\n Veuillez patienter")
\r
930 if annule == 'oui' : self.removedir()
\r
933 if __name__ == '__main__':
\r
934 test = Test_Environnement().test()
\r
936 # environnement incomplet --> on sort de la procédure d'installation
\r
941 root = Tkinter.Tk()
\r
942 Pmw.initialise(root)
\r
944 principal = Config(root)
\r
946 except Exception,e:
\r
947 print "Erreur non prévue rencontrée : ",str(e)
\r
948 print "Veuillez prévenir la maintenance"
\r