1 # -*- coding: utf-8 -*-
5 ## constantes pour les tests de versions
\r
14 import sys,string,re,types,traceback
\r
17 print "Mauvaise installation de Python"
\r
20 REPERTOIRE = os.path.abspath(os.curdir)
\r
22 def strip_points(chaine):
\r
24 Enlève les caractères autres que les chiffres des chaînes
\r
27 for i in range(len(chaine)):
\r
29 dummy = float(chaine[i])
\r
35 class Test_Environnement :
\r
39 def test_plate_forme(self):
\r
41 Teste que la plate-forme est bien supportée
\r
43 if os.name not in ('nt','posix'):
\r
44 self.l_errors.append("La plate-forme %s n'est pas supportée" %os.name)
\r
46 def test_version_python(self):
\r
48 Test de la version de python
\r
50 version = sys.version
\r
51 n = string.index(version,"(") - 1
\r
52 vpyt = strip_points(version[0:n])[0:2] ## recupere les 2 premiers caracteres
\r
53 if int(vpyt)<python_min :
\r
54 self.l_errors.append("La version %s de python n'est plus supportée" %version[0:n])
\r
56 def test_tcl_tk(self):
\r
58 Test des versions de tcl et tk
\r
62 vtcl = Tkinter.tkinter.TCL_VERSION
\r
63 vtk = Tkinter.tkinter.TK_VERSION
\r
65 x = strip_points(vtcl)
\r
67 self.l_errors.append("La version %s de tcl n'est plus supportée" %vtcl)
\r
69 x = strip_points(vtk)
\r
71 self.l_errors.append("La version %s de tk n'est plus supportée" %vtk)
\r
73 self.l_errors.append("Tkinter n'est pas installé")
\r
78 Test de la version de Pmw
\r
83 x = strip_points(vpmw)
\r
85 self.l_errors.append("La version %s de Pmw n'est plus supportée" %vpmw)
\r
87 self.l_errors.append("Pmw n'est pas installé")
\r
91 Active les tests de version Python, versions Tcl/Tk et Pmw
\r
93 self.test_plate_forme()
\r
94 self.test_version_python()
\r
97 if not len(self.l_errors):
\r
98 print "Environnement Ok"
\r
101 print "Il manque des prérequis"
\r
102 print "EFICAS ne peut pas être installé"
\r
103 print "Erreurs : ",string.join(self.l_errors)
\r
107 def __init__(self, master=None, orientation="horizontal", min=0, max=100,
\r
108 width=100, height=25, autoLabel="true", appearance="sunken",
\r
109 fillColor="blue", background="black", labelColor="yellow",
\r
110 labelText="", labelFormat="%d%%", value=50, bd=2):
\r
111 # preserve various values
\r
113 self.orientation=orientation
\r
118 self.autoLabel=autoLabel
\r
119 self.fillColor=fillColor
\r
120 self.labelColor=labelColor
\r
121 self.background=background
\r
122 self.labelText=labelText
\r
123 self.labelFormat=labelFormat
\r
125 self.frame=Tkinter.Frame(master, relief=appearance, bd=bd)
\r
126 self.canvas=Tkinter.Canvas(self.frame, height=height, width=width, bd=0,
\r
127 highlightthickness=0, background=background)
\r
128 self.scale=self.canvas.create_rectangle(0, 0, width, height,
\r
130 self.label=self.canvas.create_text(self.canvas.winfo_reqwidth() / 2,
\r
131 height / 2, text=labelText,
\r
132 anchor="c", fill=labelColor)
\r
134 self.canvas.pack(side='top', fill='x', expand='no')
\r
137 # Trim the values to be between min and max
\r
139 if value > self.max:
\r
141 if value < self.min:
\r
143 # Preserve the new value
\r
145 # Adjust the rectangle
\r
146 if self.orientation == "horizontal":
\r
147 c.coords(self.scale,0, 0,float(value) / self.max * self.width, self.height)
\r
149 c.coords(self.scale,0, self.height - (float(value) / self.max*self.height),self.width, self.height)
\r
150 # Now update the colors
\r
151 c.itemconfig(self.scale, fill=self.fillColor)
\r
152 c.itemconfig(self.label, fill=self.labelColor)
\r
153 # And update the label
\r
154 if self.autoLabel=="true":
\r
155 c.itemconfig(self.label, text=self.labelFormat % value)
\r
157 c.itemconfig(self.label, text=self.labelFormat % self.labelText)
\r
158 c.update_idletasks()
\r
162 from tkMessageBox import showinfo,askyesno,showerror,askretrycancel
\r
166 class SplashScreen(Tkinter.Toplevel):
\r
167 """ Provides a splash screen. Usage:
\r
168 Subclass and override 'CreateWidgets()'
\r
169 In constructor of main window/application call
\r
170 - S = SplashScreen(main=self) (if caller is Toplevel)
\r
171 - S = SplashScreen(main=self.master) (if caller is Frame)
\r
172 - S.quit() after you are done creating your widgets etc.
\r
174 def __init__(self, master,**args):
\r
175 Tkinter.Toplevel.__init__(self, master, relief='groove',borderwidth=5)
\r
176 self.protocol("WM_DELETE_WINDOW",lambda x=0: x+x ) # pour ne pas détruire la fenêtre en pleine copie de fichiers
\r
178 if self.main != None :
\r
179 self.main.withdraw()
\r
180 self.frame = Tkinter.Frame(self)
\r
181 self.frame.pack(expand=1,fill='both')
\r
183 self.geometry("300x200")
\r
184 self.resizable(0,0)
\r
185 self.CreateWidgets()
\r
187 def init(self,args={}):
\r
188 self.text = Tkinter.StringVar()
\r
190 self.icone = 'Editeur/icons/logo_edf.gif'
\r
192 if args == {} : return
\r
193 if args.has_key('text'):
\r
194 self.text.set(args['text'])
\r
195 if args.has_key('titre'):
\r
196 self.title(args['titre'])
\r
197 if args.has_key('code'):
\r
198 self.code = args['code']
\r
200 self.code = 'inconnu'
\r
201 if self.code == 'ASTER' :
\r
202 self.icone = 'Editeur/icons/code_aster.gif'
\r
204 def CreateWidgets(self):
\r
205 fic_image = os.path.join("./", self.icone)
\r
206 if os.path.exists(fic_image):
\r
207 self.catIcon = Tkinter.PhotoImage(file=os.path.join("./", self.icone))
\r
208 Tkinter.Label(self.frame, image=self.catIcon).pack(side=Tkinter.TOP)
\r
210 Tkinter.Label(self.frame, text = "EFICAS pour Code_Aster").pack(side=Tkinter.TOP)
\r
211 self.label = Tkinter.Label(self.frame, textvariable=self.text)
\r
212 self.label.pack(side=Tkinter.TOP,expand=1,fill='both')
\r
213 self.progress = Slider(self.frame,value=0,max=100,orientation='horizontal',
\r
214 fillColor='blue',width=200,height=30,
\r
215 background='white',labelColor='red')
\r
217 def update_barre(self,event=None):
\r
218 """ Permet de faire avancer la barre de progression """
\r
220 self.progress.value = self.progress.value+self.increment
\r
221 self.progress.update()
\r
222 #self.after(100,self.update_barre)
\r
226 def configure_barre(self):
\r
227 """ Calcule l'incrément de progression de la barre en fonction
\r
228 du nombre d'opérations à effectuer afin que le compteur
\r
229 soit à 100% à la fin des opérations"""
\r
230 self.increment = 100./self.ratio
\r
231 self.progress.update()
\r
233 def configure(self,**args):
\r
234 if args.has_key('text'):
\r
235 self.text.set(args['text'])
\r
236 if args.has_key('titre'):
\r
237 self.title(args['titre'])
\r
238 if args.has_key('barre'):
\r
240 self.barre = args['barre']
\r
241 if self.barre == 'oui' and old == 'non':
\r
242 self.progress.frame.pack(in_=self.frame,side='top')
\r
243 elif self.barre == 'non' and old == 'oui':
\r
244 self.progress.frame.pack_forget()
\r
245 if args.has_key('ratio'):
\r
246 self.ratio = args['ratio']
\r
247 self.configure_barre()
\r
251 self.progress = None
\r
254 self.main.deiconify()
\r
256 def centerwindow(window,parent = 'avec'):
\r
257 if parent =='avec':
\r
258 parent = window.winfo_parent()
\r
259 if type(parent) == types.StringType:
\r
261 parent = window._nametowidget(parent)
\r
264 # Find size of window.
\r
265 window.update_idletasks()
\r
266 width = window.winfo_width()
\r
267 height = window.winfo_height()
\r
268 if width == 1 and height == 1:
\r
269 # If the window has not yet been displayed, its size is
\r
270 # reported as 1x1, so use requested size.
\r
271 width = window.winfo_reqwidth()
\r
272 height = window.winfo_reqheight()
\r
273 # Place in centre of screen:
\r
274 if parent =='avec' :
\r
275 x = (window.winfo_screenwidth() - width) / 2 - parent.winfo_vrootx()
\r
276 y = (window.winfo_screenheight() - height) / 3 - parent.winfo_vrooty()
\r
278 x = (window.winfo_screenwidth() - width) / 2
\r
279 y = (window.winfo_screenheight() - height) / 3
\r
284 window.geometry('+%d+%d' % (x, y))
\r
288 Classe utilisée pour représenter chaque option de configuration
\r
290 def __init__(self, pere, nom):
\r
293 self.entree_value = None
\r
294 self.default = None
\r
296 self.pere.register_item(self)
\r
298 def get_valeur(self):
\r
299 return os.path.abspath(self.entree.get())
\r
301 def set_entree(self,entree):
\r
302 self.entree = entree
\r
303 self.pere.register_entree(entree)
\r
305 class Config(Tkinter.Toplevel):
\r
307 Classe principale : une instance de Config est utilisée pour
\r
308 créer l'interface. Toutes les actions (création de répertoire, copie
\r
309 de fichiers ...) sont réalisées par des méthodes de Config ou de ses
\r
312 pat_rep = re.compile(r'^(rep_)([\w_]*)') # expression réguliere pour reconnaitre les
\r
313 # les options qui désignent des répertoires
\r
314 def __init__(self, parent):
\r
315 self.master = parent
\r
316 Tkinter.Toplevel.__init__(self,None)
\r
318 self.title("Installation d'EFICAS")
\r
319 self.geometry("500x320+0+0")
\r
321 self.install_running = 0
\r
322 #évite que la fenêtre puisse être détruite en pleine copie de fichiers
\r
323 self.protocol("WM_DELETE_WINDOW",self.exit )
\r
324 # création des frames
\r
325 self.frame_gen = Tkinter.Frame(self,bd=1,relief='groove')
\r
326 self.frame_gen.place(relx=0,rely=0,relwidth=1,relheight=0.9 )
\r
327 self.frame_but = Tkinter.Frame(self,bd=1,relief='groove')
\r
328 self.frame_but.place(relx=0,rely=0.9 ,relheight=0.1 ,relwidth=1)
\r
329 # création des items de configuration
\r
330 self.make_items_config()
\r
331 # remplissage de la frame générale
\r
332 self.make_frame_gen()
\r
333 # remplissage de la frame boutons
\r
334 self.make_frame_but()
\r
335 # création boîtes de dialogue
\r
336 self.init_complementaire()
\r
338 self.init_systeme()
\r
340 def make_items_config(self):
\r
342 Création des objets Config_item
\r
345 self.items_a_creer = []
\r
346 self.liste_rep_crees = []
\r
348 # designation, texte d'invite , option par defaut(unix), option par defaut(windows), flag obligatoire/facultatif
\r
349 self.l_tx_items = (('rep_install' ,
\r
350 "Répertoire d'installation :",
\r
355 'Répertoire de travail :',
\r
360 'Répertoire matériaux :',
\r
365 "Chemin d'accès à la doc Aster :" ,
\r
371 'Exécutable Acrobat Reader :',
\r
372 '/usr/bin/acroread',
\r
377 for item in self.l_tx_items:
\r
379 setattr(self,nom_item,config_item(self,nom_item))
\r
381 def make_frame_gen(self):
\r
383 Création des zones de saisie des paramètres généraux
\r
385 # Création du label titre de la frame
\r
386 self.information = Tkinter.Label(self.frame_gen,text="CONFIGURATION D'EFICAS")
\r
387 self.information.pack(side="top",pady=10)
\r
388 # création des widgets de saisie des items
\r
389 for txt in self.l_tx_items:
\r
392 if os.name == 'nt':
\r
393 default_value = txt[3]
\r
395 default_value = txt[2]
\r
396 item = getattr(self,nom_item)
\r
397 wdg_item = Pmw.EntryField(self.frame_gen,
\r
399 label_text = txt_item,
\r
400 command = lambda s=self,i=item : s.select_next_entry(i.entree))
\r
401 item.default_value = default_value
\r
402 item.statut = txt[4]
\r
403 item.set_entree(wdg_item)
\r
404 # on affiche les entrées
\r
405 for entree in self.entrees:
\r
406 entree.pack(fill='x', expand=1, padx=10, pady=5)
\r
407 Pmw.alignlabels(self.entrees)
\r
408 self.entrees[0].focus_set()
\r
409 #self.rep_cata_dev.entree.configure(entry_state = 'disabled')
\r
410 self.display_defaults()
\r
412 def make_frame_but(self):
\r
414 Création des boutons de commande Installer et Annuler
\r
416 self.validButton = Tkinter.Button(self.frame_but, text = 'Installer', command = self.run_install)
\r
417 self.exitButton = Tkinter.Button(self.frame_but,
\r
419 command = lambda s=self : s.exit(annule='oui'))
\r
420 self.exitButton.place(relx=0.35,rely=0.5,anchor='center')
\r
421 self.validButton.place(relx=0.65,rely=0.5,anchor='center')
\r
423 def init_complementaire(self):
\r
425 Création de widgets complémentaires (boîtes de dialogue ...)
\r
427 self.erreur_dialog = Pmw.Dialog(self,
\r
428 buttons = ('Modifier', 'Annuler'),
\r
429 defaultbutton = 'Modifier',
\r
431 command = self.erreur_exec)
\r
432 self.erreur_dialog.withdraw()
\r
433 self.fatale_dialog = Pmw.Dialog(self,
\r
434 buttons = ('Annuler',),
\r
436 command = self.fatale_exec)
\r
437 self.fatale_dialog.withdraw()
\r
438 self.info_dialog = Pmw.Dialog(self,
\r
440 title = 'Attention')
\r
441 self.info_dialog.configure(command=self.info_dialog.withdraw())
\r
442 self.info_dialog.withdraw()
\r
443 self.attente = SplashScreen(None,code="ASTER")
\r
444 self.attente.withdraw()
\r
446 def init_systeme(self):
\r
448 Détermine les commandes à exécuter en fonction de l'OS
\r
450 self.d_commandes = {}
\r
451 if os.name == 'nt':
\r
452 self.d_commandes['decompress'] = "unzip.exe "
\r
453 self.d_commandes['copy'] = "copy "
\r
454 self.d_commandes['delete'] = "del "
\r
455 elif os.name == 'posix':
\r
456 self.d_commandes['decompress'] = "gunzip "
\r
457 self.d_commandes['copy'] = "cp "
\r
458 self.d_commandes['delete'] = "rm "
\r
460 def run_install(self):
\r
462 Lance l'installation proprement dite d'EFICAS
\r
464 self.install_running = 1
\r
465 self.afficher_splash()
\r
466 self.deactivate_entries() # Les entrees et les boutons sont desactivees
\r
467 self.deactivate_buttons() # pendant les operations d'installation
\r
468 #self.decompress_archive()
\r
469 #if not os.path.exists(os.path.join(REPERTOIRE,'Eficas')):
\r
470 # self.afficher_fatale("Il manque des fichiers d'EFICAS")
\r
471 # self.install_running = 0
\r
473 self.nb_fichiers = self.compte_fichiers(REPERTOIRE)
\r
474 if self.nb_fichiers == 0:
\r
475 self.afficher_fatale("Il manque des fichiers d'EFICAS")
\r
476 self.install_running = 0
\r
478 # essaie de creer les repertoires.
\r
480 if self.make_dirs() == ECHEC :
\r
481 self.activate_entries()
\r
482 self.activate_buttons()
\r
483 self.install_running = 0
\r
486 self.install_running = 0
\r
487 self.afficher_fatale("Impossible de créer certains répertoires")
\r
489 # affiche la fenêtre avec la barre de progression
\r
490 self.afficher_copie_fichiers()
\r
491 # essaie de copier les fichiers d'EFICAS
\r
493 if self.move_files() == ECHEC:
\r
494 self.afficher_echec("Impossible de copier les fichiers d'EFICAS")
\r
495 self.activate_buttons()
\r
496 self.install_running = 0
\r
499 traceback.print_exc()
\r
500 self.install_running = 0
\r
501 self.afficher_fatale("Impossible de copier certains fichiers")
\r
503 #self.rm_temp_dirs() # efface les répertoires temporaires
\r
505 self.creer_fic_conf() # crée le fichier eficas.conf
\r
507 afficher_info("Impossible de créer le fichier de configuration\n Il est possible de le faire a la main")
\r
508 # self.install_running = 0
\r
509 self.afficher_install_terminee() # A ce stade tout est fait et il ne reste plus qu'à attendre
\r
510 # un clic de souris pour sortir
\r
512 def display_defaults(self):
\r
514 Affiche les valeurs par défaut dans les zones de saisie
\r
516 # racine indique la racine de l'arborescence
\r
517 if os.name == 'nt':
\r
520 racine = os.environ['HOME']
\r
521 # remplit les zones de saisie avec les options par défaut
\r
522 for item in self.items:
\r
523 if item.default_value == None : continue
\r
524 item.default_value = os.path.join(racine,item.default_value)
\r
525 item.entree.insert(0,item.default_value)
\r
527 def register_item(self,item):
\r
529 Enregistre l'item dans la liste des items et éventuellement
\r
530 dans la liste des items à créer (répertoires)
\r
532 self.items.append(item)
\r
533 if self.pat_rep.match(item.nom) :
\r
534 self.items_a_creer.append(item)
\r
536 def register_entree(self,entree):
\r
538 Enregistre la zone de saisie dans la liste des zones
\r
540 self.entrees.append(entree)
\r
542 def select_next_entry(self,entree):
\r
544 Place le focus dans l'entry suivant celle passée en argument
\r
546 index = self.entrees.index(entree)+1
\r
547 if index != len(self.entrees):
\r
548 self.entrees[index].component('entry').focus()
\r
550 def activate_entries(self):
\r
552 Active les entrées. Les zones de saisie deviennent éditables.
\r
554 for item in self.entrees:
\r
555 item.configure(entry_state='normal')
\r
557 def deactivate_entries(self):
\r
559 Désactive les entrées. Les zones ne sont plus éditables.
\r
561 for item in self.entrees: # Les entrees sont desactivees
\r
562 item.configure(entry_state='disabled') # pendant les operations d'installation
\r
564 def activate_buttons(self):
\r
566 active les boutons valider et annuler
\r
568 self.validButton.configure(state = 'normal')
\r
569 self.exitButton.configure(state = 'normal')
\r
571 def deactivate_buttons(self):
\r
573 désactive des boutons valider de annuler
\r
575 self.validButton.configure(state = 'disabled')
\r
576 self.exitButton.configure(state = 'disabled')
\r
578 def erreur_exec(self, result):
\r
580 Callback exécuté lorsque l'utilisateur clique sur un des boutons
\r
581 Modifier/Annuler de la fenêtre de dialogue qui lui présente les erreurs
\r
583 self.erreur_dialog.deactivate(result)
\r
585 if result == 'Annuler':
\r
586 self.install_running = 0
\r
587 self.exit(annule='non')
\r
589 def fatale_exec(self, result):
\r
591 Callback exécuté lorsque l'utilisateur clique sur le bouton
\r
592 Quitter de la fenêtre de dialogue qui lui présente les erreurs fatales
\r
593 Seule solution : sortir de l'installation
\r
595 self.fatale_dialog.deactivate(result)
\r
596 self.install_running = 0
\r
597 self.exit(annule='oui')
\r
599 def test_confirmation(self,flag,nom):
\r
601 Callback activé par le clic sur bouton fenêtre demandant confirmation
\r
602 avant création répertoire facultatif
\r
605 self.confirmation.destroy()
\r
606 self.TEST_confirmation_avant_creation = NON
\r
609 self.confirmation.destroy()
\r
610 self.TEST_confirmation_avant_creation = OUI
\r
612 def afficher_fatale(self, message):
\r
614 Affiche les erreurs fatales
\r
616 self.attente.withdraw()
\r
617 w = Tkinter.Label(self.fatale_dialog.interior(),text = message, pady = 5)
\r
618 w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)
\r
619 self.fatale_dialog.configure(deactivatecommand = w.destroy)
\r
620 self.fatale_dialog.activate()
\r
622 def afficher_echec(self, message):
\r
624 Affiche un message d'erreur
\r
625 Par construction, dès que l'on passe par cette méthode, on sort de l'installation
\r
626 en passant le flag install_running à 0
\r
628 self.attente.withdraw()
\r
629 w = Tkinter.Label(self.erreur_dialog.interior(),text = message, pady = 5)
\r
630 w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)
\r
631 self.erreur_dialog.configure(deactivatecommand = w.destroy)
\r
632 self.erreur_dialog.activate()
\r
634 def confirmation_avant_creation(self,repertoire):
\r
636 Affiche une boite de dialogue pour confirmer la création
\r
637 d'un répertoire facultatif.
\r
639 self.attente.withdraw()
\r
640 self.confirmation = Pmw.Dialog(self,
\r
641 buttons = ('OUI', 'NON'),
\r
642 defaultbutton = 'OUI',
\r
643 title = "Répertoire inexistant",
\r
644 command = lambda f,s=self,r=repertoire : s.test_confirmation(f,r))
\r
645 self.confirmation.withdraw()
\r
646 Tkinter.Label(self.confirmation.interior(),
\r
647 text="Le répertoire %s n'existe pas \n Voulez-vous le créer ?" %repertoire).pack(side='top')
\r
648 self.confirmation.activate(geometry='centerscreenalways')
\r
649 return self.TEST_confirmation_avant_creation
\r
651 def afficher_splash(self):
\r
653 Afficher la boite de message
\r
655 self.attente.deiconify()
\r
656 self.attente.tkraise()
\r
657 centerwindow(self.attente)
\r
658 self.attente.configure(titre="Installation d'EFICAS",
\r
659 text="Vérification intégrité sources Eficas",
\r
662 def afficher_info(self,message):
\r
664 Afficher une boite de warning
\r
666 w = Tkinter.Label(self.info_dialog.interior(),text = message, pady = 5)
\r
667 w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)
\r
668 self.info_dialog.configure(deactivatecommand = w.destroy)
\r
669 self.info_dialog.activate()
\r
671 def afficher_copie_fichiers(self):
\r
673 Afficher la boite de message avec la barre de progression
\r
675 self.attente.deiconify()
\r
676 self.attente.tkraise()
\r
677 self.attente.configure(titre="Installation d'EFICAS",
\r
678 text="copie des fichiers",
\r
680 self.attente.ratio = self.nb_fichiers
\r
681 self.attente.configure_barre()
\r
683 def afficher_install_terminee(self):
\r
685 Afficher le message Installation terminée
\r
688 self.attente.configure(titre="Installation d'EFICAS",
\r
689 text="Installation terminée",
\r
691 self.exitButton.place_forget()
\r
692 self.validButton.place_forget()
\r
693 self.validButton = Tkinter.Button(self.attente.frame,
\r
695 command = self.exit)
\r
696 self.validButton.pack(side='top',pady=5)
\r
697 self.install_running = 0
\r
699 def decompress_archive(self) :
\r
701 Décompresse l'archive d'EFICAS dans un répertoire temporaire (.)
\r
703 print "decompress_archive"
\r
705 commande = os.path.join(REPERTOIRE,self.d_commandes['decompress'])
\r
706 fichier = os.path.join(REPERTOIRE,"eficas.zip")
\r
707 print 'commande =',commande
\r
708 print 'fichier =',fichier
\r
709 os.execv(commande,("eficas.zip",))
\r
711 # self.affiche_echec("Erreur dans la décompression")
\r
713 def normaliser_chemin(self, nom):
\r
715 Retourne le chemin d'accès complet à nom
\r
717 return os.path.abspath(os.path.expanduser(nom))
\r
719 def discriminer_noms(self):
\r
721 Emet un message d'alerte si des zones de saisie ne sont pas remplies
\r
722 ou si des noms de répertoires à créer sont identiques.
\r
725 for item in self.items_a_creer:
\r
726 nom = item.entree.get()
\r
727 if nom == self.rep_install.entree.get(): # il faut ajouter 'Eficas' au chemin du repertoire
\r
728 nom = os.path.join(nom,"Eficas") # d'installation
\r
729 liste_noms.append(nom)
\r
732 for item in self.items_a_creer:
\r
733 nom = item.entree.get()
\r
736 message = "attention : certains répertoires n'ont pas de nom"
\r
737 self.afficher_echec(message)
\r
738 item.entree.component('entry').focus()
\r
744 for item in self.items_a_creer:
\r
745 nom = item.entree.get()
\r
746 if liste_noms.count(nom) >1 :
\r
748 message = "attention : certains répertoires ont le même nom"
\r
749 self.afficher_echec(message)
\r
750 item.entree.component('entry').focus()
\r
755 def compte_fichiers(self,path):
\r
757 Dénombre les fichiers présents dans le répertoire Eficas (et ses sous-répertoires)
\r
760 l_fic = os.listdir(path)
\r
763 if os.path.isdir(os.path.join(path,fic)):
\r
768 nb = nb + self.compte_fichiers(os.path.join(path,rep))
\r
771 def creer_fic_conf(self):
\r
773 Crée le fichier editeur.ini a partir des données saisies
\r
774 par l'administrateur.
\r
776 fichier_conf = os.path.join(self.normaliser_chemin(self.rep_install.get_valeur()),"Eficas/Aster/editeur.ini")
\r
777 f = open(fichier_conf,'w')
\r
778 f.write("path_doc = "+'"'+self.normaliser_chemin(self.rep_docaster.get_valeur())+'"\n')
\r
779 f.write("exec_acrobat = "+'"'+self.normaliser_chemin(self.acrobat.get_valeur())+'"\n')
\r
780 f.write('isdeveloppeur = "NON"\n')
\r
781 f.write("rep_travail = "+'"'+self.normaliser_chemin(self.rep_travail.get_valeur())+'"\n')
\r
782 f.write("rep_cata = "+'"'+os.path.join(self.normaliser_chemin(self.rep_install.get_valeur()),"Eficas/Aster/Cata/")+'"\n') # attention au dernier slash
\r
783 f.write("rep_mat = "+'"'+self.normaliser_chemin(self.rep_mat.get_valeur())+'"\n')
\r
784 cata = """catalogues = (('ASTER','v6',rep_cata + 'cata_STA6.py','python','defaut'),)\n"""
\r
789 def move_files(self):
\r
791 Déplace les fichiers Eficas du répertoire temporaire vers
\r
792 leur répertoire de destination
\r
794 # création du répertoire Eficas
\r
795 rep_eficas = os.path.join(self.rep_install.get_valeur(),'Eficas')
\r
796 self.copy_rep(REPERTOIRE,rep_eficas)
\r
798 def copy_rep(self,rep_dep,rep_arr):
\r
800 Copie le répertoire path_dep et ses sous-répertoires dans path_arr
\r
802 l_fichiers = os.listdir(rep_dep)
\r
803 if not os.path.exists(rep_arr) :
\r
804 # création du répertoire d'arrivée quand il n'existe pas
\r
805 self.mkdirs(rep_arr)
\r
806 for fic in l_fichiers :
\r
807 nom_complet_dep = os.path.join(rep_dep,fic)
\r
808 nom_complet_arr = os.path.join(rep_arr,fic)
\r
809 if os.path.isfile(nom_complet_dep):
\r
810 commande_copie = self.d_commandes['copy']+nom_complet_dep+' '+nom_complet_arr
\r
811 commande_delete= self.d_commandes['delete']+nom_complet_dep
\r
813 os.system(commande_copie)
\r
814 #os.system(commande_delete)
\r
815 self.attente.update_barre()
\r
816 except Exception,e:
\r
818 elif os.path.isdir(nom_complet_dep):
\r
819 self.copy_rep(nom_complet_dep,nom_complet_arr)
\r
821 def rm_temp_dirs(self):
\r
823 Détruit le répertoire temporaire de l'archive d'Eficas
\r
825 rep_arch = os.path.join(REPERTOIRE,'Eficas')
\r
826 self.rm_r(rep_arch)
\r
828 def make_dirs(self):
\r
830 Crée les répertoires d'accueil des fichiers d'EFICAS
\r
832 # création des répertoires dont l'utilisateur a donné le nom
\r
833 if self.discriminer_noms() == ECHEC:
\r
835 for item in self.items_a_creer:
\r
836 if not item.entree.get():
\r
838 nom = item.get_valeur()
\r
839 if nom == self.normaliser_chemin(self.rep_install.entree.get()): # il faut ajouter 'Eficas' au chemin du repertoire
\r
840 nom = os.path.join(nom,"Eficas") # d'installation
\r
841 item.test = self.essai_creer(nom,item.statut)
\r
842 if item.test == ECHEC :
\r
843 item.entree.component('entry').focus()
\r
847 def essai_creer(self, nom, statut):
\r
849 Essaie de créer le répertoire nom s'il n'existe pas déjà.
\r
850 Si statut == 'f' et si le fichier n'existe pas, demande
\r
851 confirmation avant création
\r
853 repertoire = self.normaliser_chemin(nom) # repertoire = chemin absolu de nom
\r
854 if os.path.exists(repertoire):
\r
856 self.afficher_echec("Un fichier ou répertoire de nom "+ repertoire+ " existe déjà !\n"+
\r
857 "L'installation ne peut continuer")
\r
863 # on demande confirmation de création à l'utilisateur
\r
864 test = self.confirmation_avant_creation(repertoire)
\r
869 test = self.mkdirs(repertoire)
\r
871 except Exception,e:
\r
872 message = "La création de "+repertoire+" a échoué :\n %s \n Vérifiez vos droits d'écriture" %str(e) # message d'erreur
\r
873 self.afficher_echec(message)
\r
876 def mkdirs(self,rep):
\r
878 Création récursive des répertoires d'installation.
\r
879 Les noms des répertoires crées sont stockés dans
\r
880 une liste dont se sert la méthode removedir pour
\r
881 restaurer l'environnement initial en cas d'annulation.
\r
883 if rep==os.path.dirname(rep):
\r
886 if os.path.exists(os.path.dirname(rep)):
\r
888 self.liste_rep_crees.append(rep)
\r
891 test = self.mkdirs(os.path.dirname(rep))
\r
894 self.liste_rep_crees.append(rep)
\r
899 def rm_r(self,path):
\r
901 Detruit récursivement path
\r
903 if not os.path.exists(path):
\r
906 if len(os.listdir(path))!=0:
\r
907 for entree in os.listdir(path):
\r
908 entree = os.path.join(path,entree)
\r
911 except Exception,e:
\r
912 self.afficher_info("Impossible de détruire le répertoire : "+path+"\n"+"\n"+str(e)+"\n L'installation continue néanmoins")
\r
914 def removedir(self):
\r
916 Destruction des répertoires déja crées (en cas d'annulation)
\r
918 for rep in self.liste_rep_crees:
\r
920 self.liste_rep_crees = []
\r
922 def exit(self,annule='non'):
\r
924 Tente de sortir de l'application.
\r
925 Echoue si installation en cours
\r
927 if self.install_running :
\r
928 # l'installation est en cours --> on interdit la sortie
\r
929 self.afficher_info("Impossible de quitter tant que l'installation est en cours\n Veuillez patienter")
\r
931 if annule == 'oui' : self.removedir()
\r
934 if __name__ == '__main__':
\r
935 test = Test_Environnement().test()
\r
937 # environnement incomplet --> on sort de la procédure d'installation
\r
942 root = Tkinter.Tk()
\r
943 Pmw.initialise(root)
\r
945 principal = Config(root)
\r
947 except Exception,e:
\r
948 print "Erreur non prévue rencontrée : ",str(e)
\r
949 print "Veuillez prévenir la maintenance"
\r