--- /dev/null
+SUCCES,ECHEC = 1,0\r
+OUI,NON = 1,0\r
+\r
+## constantes pour les tests de versions \r
+\r
+python_min = 21\r
+tcl_min = 83\r
+tk_min = 83\r
+pmw_min = 85\r
+test = 0\r
+\r
+try:\r
+ import sys,string,re,types\r
+ import os,commands\r
+except Exception,e:\r
+ print "Mauvaise installation de Python"\r
+ print str(e)\r
+\r
+REPERTOIRE = os.path.abspath(os.curdir)\r
+\r
+def strip_points(chaine):\r
+ """\r
+ Enlève les caractères autres que les chiffres des chaînes\r
+ """\r
+ x=""\r
+ for i in range(len(chaine)):\r
+ try:\r
+ dummy = float(chaine[i])\r
+ x=x+chaine[i]\r
+ except:\r
+ pass\r
+ return x\r
+\r
+class Test_Environnement :\r
+ def __init__(self):\r
+ self.l_errors = []\r
+\r
+ def test_plate_forme(self):\r
+ """\r
+ Teste que la plate-forme est bien supportée\r
+ """\r
+ if os.name not in ('nt','posix'):\r
+ self.l_errors.append("La plate-forme %s n'est pas supportée" %os.name)\r
+ \r
+ def test_version_python(self):\r
+ """\r
+ Test de la version de python\r
+ """\r
+ version = sys.version\r
+ n = string.index(version,"(") - 1\r
+ vpyt = strip_points(version[0:n])[0:2] ## recupere les 2 premiers caracteres\r
+ if int(vpyt)<python_min :\r
+ self.l_errors.append("La version %s de python n'est plus supportée" %version[0:n])\r
+\r
+ def test_tcl_tk(self):\r
+ """\r
+ Test des versions de tcl et tk\r
+ """\r
+ try:\r
+ import Tkinter\r
+ vtcl = Tkinter.tkinter.TCL_VERSION\r
+ vtk = Tkinter.tkinter.TK_VERSION\r
+ # version tcl\r
+ x = strip_points(vtcl)\r
+ if int(x)<tcl_min :\r
+ self.l_errors.append("La version %s de tcl n'est plus supportée" %vtcl)\r
+ # version tk\r
+ x = strip_points(vtk)\r
+ if int(x)<tk_min :\r
+ self.l_errors.append("La version %s de tk n'est plus supportée" %vtk)\r
+ except Exception,e:\r
+ self.l_errors.append("Tkinter n'est pas installé")\r
+ print str(e)\r
+\r
+ def test_Pmw(self):\r
+ """\r
+ Test de la version de Pmw\r
+ """\r
+ try:\r
+ import Pmw\r
+ vpmw = Pmw._version\r
+ x = strip_points(vpmw)\r
+ if int(x)<pmw_min :\r
+ self.l_errors.append("La version %s de Pmw n'est plus supportée" %vpmw)\r
+ except:\r
+ self.l_errors.append("Pmw n'est pas installé")\r
+\r
+ def test(self):\r
+ """\r
+ Active les tests de version Python, versions Tcl/Tk et Pmw\r
+ """\r
+ self.test_plate_forme()\r
+ self.test_version_python()\r
+ self.test_tcl_tk()\r
+ self.test_Pmw()\r
+ if not len(self.l_errors):\r
+ print "Environnement Ok"\r
+ return 1\r
+ else :\r
+ print "Il manque des prérequis"\r
+ print "EFICAS ne peut pas être installé"\r
+ print "Erreurs : ",string.join(self.l_errors)\r
+ return 0\r
+\r
+class Slider:\r
+ def __init__(self, master=None, orientation="horizontal", min=0, max=100,\r
+ width=100, height=25, autoLabel="true", appearance="sunken",\r
+ fillColor="blue", background="black", labelColor="yellow",\r
+ labelText="", labelFormat="%d%%", value=50, bd=2):\r
+ # preserve various values\r
+ self.master=master\r
+ self.orientation=orientation\r
+ self.min=min\r
+ self.max=max\r
+ self.width=width\r
+ self.height=height\r
+ self.autoLabel=autoLabel\r
+ self.fillColor=fillColor\r
+ self.labelColor=labelColor\r
+ self.background=background\r
+ self.labelText=labelText\r
+ self.labelFormat=labelFormat\r
+ self.value=value\r
+ self.frame=Tkinter.Frame(master, relief=appearance, bd=bd)\r
+ self.canvas=Tkinter.Canvas(self.frame, height=height, width=width, bd=0,\r
+ highlightthickness=0, background=background)\r
+ self.scale=self.canvas.create_rectangle(0, 0, width, height,\r
+ fill=fillColor)\r
+ self.label=self.canvas.create_text(self.canvas.winfo_reqwidth() / 2,\r
+ height / 2, text=labelText,\r
+ anchor="c", fill=labelColor)\r
+ self.update()\r
+ self.canvas.pack(side='top', fill='x', expand='no')\r
+\r
+ def update(self):\r
+ # Trim the values to be between min and max\r
+ value=self.value\r
+ if value > self.max:\r
+ value = self.max\r
+ if value < self.min:\r
+ value = self.min\r
+ # Preserve the new value\r
+ c=self.canvas\r
+ # Adjust the rectangle\r
+ if self.orientation == "horizontal":\r
+ c.coords(self.scale,0, 0,float(value) / self.max * self.width, self.height)\r
+ else:\r
+ c.coords(self.scale,0, self.height - (float(value) / self.max*self.height),self.width, self.height)\r
+ # Now update the colors\r
+ c.itemconfig(self.scale, fill=self.fillColor)\r
+ c.itemconfig(self.label, fill=self.labelColor)\r
+ # And update the label\r
+ if self.autoLabel=="true":\r
+ c.itemconfig(self.label, text=self.labelFormat % value)\r
+ else:\r
+ c.itemconfig(self.label, text=self.labelFormat % self.labelText)\r
+ c.update_idletasks()\r
+try :\r
+ import Tkinter\r
+ import Pmw\r
+ from tkMessageBox import showinfo,askyesno,showerror,askretrycancel\r
+except:\r
+ pass\r
+\r
+class SplashScreen(Tkinter.Toplevel):\r
+ """ Provides a splash screen. Usage:\r
+ Subclass and override 'CreateWidgets()'\r
+ In constructor of main window/application call\r
+ - S = SplashScreen(main=self) (if caller is Toplevel)\r
+ - S = SplashScreen(main=self.master) (if caller is Frame)\r
+ - S.quit() after you are done creating your widgets etc.\r
+ """\r
+ def __init__(self, master,**args):\r
+ Tkinter.Toplevel.__init__(self, master, relief='groove',borderwidth=5)\r
+ self.protocol("WM_DELETE_WINDOW",lambda x=0: x+x ) # pour ne pas détruire la fenêtre en pleine copie de fichiers\r
+ self.main = master\r
+ if self.main != None :\r
+ self.main.withdraw()\r
+ self.frame = Tkinter.Frame(self)\r
+ self.frame.pack(expand=1,fill='both')\r
+ self.init(args)\r
+ self.geometry("300x200")\r
+ self.resizable(0,0)\r
+ self.CreateWidgets()\r
+\r
+ def init(self,args={}):\r
+ self.text = Tkinter.StringVar()\r
+ self.text.set('')\r
+ self.icone = 'logo_edf.gif'\r
+ self.barre = 'non'\r
+ if args == {} : return\r
+ if args.has_key('text'):\r
+ self.text.set(args['text'])\r
+ if args.has_key('titre'):\r
+ self.title(args['titre'])\r
+ if args.has_key('code'):\r
+ self.code = args['code']\r
+ else:\r
+ self.code = 'inconnu'\r
+ if self.code == 'ASTER' :\r
+ self.icone = 'code_aster.gif'\r
+ \r
+ def CreateWidgets(self):\r
+ fic_image = os.path.join("./", self.icone)\r
+ if os.path.exists(fic_image):\r
+ self.catIcon = Tkinter.PhotoImage(file=os.path.join("./", self.icone))\r
+ Tkinter.Label(self.frame, image=self.catIcon).pack(side=Tkinter.TOP)\r
+ else:\r
+ Tkinter.Label(self.frame, text = "EFICAS pour Code_Aster").pack(side=Tkinter.TOP)\r
+ self.label = Tkinter.Label(self.frame, textvariable=self.text)\r
+ self.label.pack(side=Tkinter.TOP,expand=1,fill='both')\r
+ self.progress = Slider(self.frame,value=0,max=100,orientation='horizontal',\r
+ fillColor='blue',width=200,height=30,\r
+ background='white',labelColor='red')\r
+\r
+ def update_barre(self,event=None):\r
+ """ Permet de faire avancer la barre de progression """\r
+ try:\r
+ self.progress.value = self.progress.value+self.increment\r
+ self.progress.update()\r
+ #self.after(100,self.update_barre)\r
+ except:\r
+ pass\r
+\r
+ def configure_barre(self):\r
+ """ Calcule l'incrément de progression de la barre en fonction\r
+ du nombre d'opérations à effectuer afin que le compteur\r
+ soit à 100% à la fin des opérations"""\r
+ self.increment = 100./self.ratio\r
+ self.progress.update()\r
+\r
+ def configure(self,**args):\r
+ if args.has_key('text'):\r
+ self.text.set(args['text'])\r
+ if args.has_key('titre'):\r
+ self.title(args['titre'])\r
+ if args.has_key('barre'):\r
+ old = self.barre\r
+ self.barre = args['barre']\r
+ if self.barre == 'oui' and old == 'non':\r
+ self.progress.frame.pack(in_=self.frame,side='top')\r
+ elif self.barre == 'non' and old == 'oui':\r
+ self.progress.frame.pack_forget()\r
+ if args.has_key('ratio'):\r
+ self.ratio = args['ratio']\r
+ self.configure_barre()\r
+ self.update()\r
+ \r
+ def quit(self):\r
+ self.progress = None\r
+ self.withdraw()\r
+ self.main.update()\r
+ self.main.deiconify()\r
+\r
+def centerwindow(window,parent = 'avec'):\r
+ if parent =='avec':\r
+ parent = window.winfo_parent()\r
+ if type(parent) == types.StringType:\r
+ try:\r
+ parent = window._nametowidget(parent)\r
+ except:\r
+ parent = window\r
+ # Find size of window.\r
+ window.update_idletasks()\r
+ width = window.winfo_width()\r
+ height = window.winfo_height()\r
+ if width == 1 and height == 1:\r
+ # If the window has not yet been displayed, its size is\r
+ # reported as 1x1, so use requested size.\r
+ width = window.winfo_reqwidth()\r
+ height = window.winfo_reqheight()\r
+ # Place in centre of screen:\r
+ if parent =='avec' :\r
+ x = (window.winfo_screenwidth() - width) / 2 - parent.winfo_vrootx()\r
+ y = (window.winfo_screenheight() - height) / 3 - parent.winfo_vrooty()\r
+ else:\r
+ x = (window.winfo_screenwidth() - width) / 2 \r
+ y = (window.winfo_screenheight() - height) / 3\r
+ if x < 0:\r
+ x = 0\r
+ if y < 0:\r
+ y = 0\r
+ window.geometry('+%d+%d' % (x, y))\r
+ \r
+class config_item:\r
+ """\r
+ Classe utilisée pour représenter chaque option de configuration\r
+ """\r
+ def __init__(self, pere, nom):\r
+ self.nom = nom\r
+ self.pere = pere\r
+ self.entree_value = None\r
+ self.default = None\r
+ self.test = None\r
+ self.pere.register_item(self)\r
+\r
+ def get_valeur(self):\r
+ return os.path.abspath(self.entree.get())\r
+ \r
+ def set_entree(self,entree):\r
+ self.entree = entree\r
+ self.pere.register_entree(entree)\r
+\r
+class Config(Tkinter.Toplevel):\r
+ """\r
+ Classe principale : une instance de Config est utilisée pour\r
+ créer l'interface. Toutes les actions (création de répertoire, copie\r
+ de fichiers ...) sont réalisées par des méthodes de Config ou de ses\r
+ composants\r
+ """\r
+ pat_rep = re.compile(r'^(rep_)([\w_]*)') # expression réguliere pour reconnaitre les\r
+ # les options qui désignent des répertoires\r
+ def __init__(self, parent):\r
+ self.master = parent\r
+ Tkinter.Toplevel.__init__(self,None)\r
+ parent.withdraw()\r
+ self.title("Installation d'EFICAS")\r
+ self.geometry("500x320+0+0")\r
+ centerwindow(self)\r
+ self.install_running = 0\r
+ #évite que la fenêtre puisse être détruite en pleine copie de fichiers\r
+ self.protocol("WM_DELETE_WINDOW",self.exit )\r
+ # création des frames\r
+ self.frame_gen = Tkinter.Frame(self,bd=1,relief='groove')\r
+ self.frame_gen.place(relx=0,rely=0,relwidth=1,relheight=0.9 )\r
+ self.frame_but = Tkinter.Frame(self,bd=1,relief='groove')\r
+ self.frame_but.place(relx=0,rely=0.9 ,relheight=0.1 ,relwidth=1)\r
+ # création des items de configuration\r
+ self.make_items_config()\r
+ # remplissage de la frame générale\r
+ self.make_frame_gen()\r
+ # remplissage de la frame boutons\r
+ self.make_frame_but()\r
+ # création boîtes de dialogue\r
+ self.init_complementaire()\r
+ # init système\r
+ self.init_systeme()\r
+ \r
+ def make_items_config(self):\r
+ """\r
+ Création des objets Config_item\r
+ """\r
+ self.items = []\r
+ self.items_a_creer = []\r
+ self.liste_rep_crees = []\r
+ self.entrees = []\r
+ # designation, texte d'invite , option par defaut(unix), option par defaut(windows), flag obligatoire/facultatif\r
+ self.l_tx_items = (('rep_install' ,\r
+ "Répertoire d'installation :",\r
+ 'usr/local',\r
+ '',\r
+ 'o'),\r
+ ('rep_travail' ,\r
+ 'Répertoire de travail :',\r
+ 'tmp',\r
+ 'tmp',\r
+ 'o'),\r
+ ('rep_mat' ,\r
+ 'Répertoire matériaux :',\r
+ None,\r
+ None,\r
+ 'f'),\r
+ ('rep_docaster' ,\r
+ "Chemin d'accès à la doc Aster :" ,\r
+ None,\r
+ None,\r
+ 'f'\r
+ ),\r
+ ('acrobat' ,\r
+ 'Exécutable Acrobat Reader :',\r
+ 'usr/bin/acroread',\r
+ 'acrobat.exe',\r
+ 'o')\r
+ )\r
+\r
+ for item in self.l_tx_items:\r
+ nom_item = item[0]\r
+ setattr(self,nom_item,config_item(self,nom_item))\r
+\r
+ def make_frame_gen(self):\r
+ """\r
+ Création des zones de saisie des paramètres généraux\r
+ """\r
+ # Création du label titre de la frame\r
+ self.information = Tkinter.Label(self.frame_gen,text="CONFIGURATION D'EFICAS")\r
+ self.information.pack(side="top",pady=10)\r
+ # création des widgets de saisie des items\r
+ for txt in self.l_tx_items:\r
+ nom_item = txt[0]\r
+ txt_item = txt[1]\r
+ if os.name == 'nt':\r
+ default_value = txt[3]\r
+ else:\r
+ default_value = txt[2]\r
+ item = getattr(self,nom_item)\r
+ wdg_item = Pmw.EntryField(self.frame_gen,\r
+ labelpos = 'w',\r
+ label_text = txt_item,\r
+ command = lambda s=self,i=item : s.select_next_entry(i.entree))\r
+ item.default_value = default_value\r
+ item.statut = txt[4]\r
+ item.set_entree(wdg_item)\r
+ # on affiche les entrées\r
+ for entree in self.entrees:\r
+ entree.pack(fill='x', expand=1, padx=10, pady=5)\r
+ Pmw.alignlabels(self.entrees)\r
+ self.entrees[0].focus_set()\r
+ #self.rep_cata_dev.entree.configure(entry_state = 'disabled')\r
+ self.display_defaults()\r
+ \r
+ def make_frame_but(self):\r
+ """\r
+ Création des boutons de commande Installer et Annuler\r
+ """\r
+ self.validButton = Tkinter.Button(self.frame_but, text = 'Installer', command = self.run_install)\r
+ self.exitButton = Tkinter.Button(self.frame_but,\r
+ text = 'Annuler',\r
+ command = lambda s=self : s.exit(annule='oui'))\r
+ self.exitButton.place(relx=0.35,rely=0.5,anchor='center')\r
+ self.validButton.place(relx=0.65,rely=0.5,anchor='center')\r
+\r
+ def init_complementaire(self):\r
+ """\r
+ Création de widgets complémentaires (boîtes de dialogue ...)\r
+ """\r
+ self.erreur_dialog = Pmw.Dialog(self,\r
+ buttons = ('Modifier', 'Annuler'),\r
+ defaultbutton = 'Modifier',\r
+ title = 'Erreur',\r
+ command = self.erreur_exec)\r
+ self.erreur_dialog.withdraw()\r
+ self.fatale_dialog = Pmw.Dialog(self,\r
+ buttons = ('Annuler',),\r
+ title = 'Fatal',\r
+ command = self.fatale_exec)\r
+ self.fatale_dialog.withdraw()\r
+ self.info_dialog = Pmw.Dialog(self,\r
+ buttons = ('Ok',),\r
+ title = 'Attention')\r
+ self.info_dialog.configure(command=self.info_dialog.withdraw())\r
+ self.info_dialog.withdraw()\r
+ self.attente = SplashScreen(None,code="ASTER")\r
+ self.attente.withdraw()\r
+\r
+ def init_systeme(self):\r
+ """\r
+ Détermine les commandes à exécuter en fonction de l'OS\r
+ """\r
+ self.d_commandes = {}\r
+ if os.name == 'nt':\r
+ self.d_commandes['decompress'] = "unzip.exe "\r
+ self.d_commandes['copy'] = "copy "\r
+ self.d_commandes['delete'] = "del "\r
+ elif os.name == 'posix':\r
+ self.d_commandes['decompress'] = "gunzip "\r
+ self.d_commandes['copy'] = "cp "\r
+ self.d_commandes['delete'] = "rm "\r
+\r
+ def run_install(self):\r
+ """\r
+ Lance l'installation proprement dite d'EFICAS\r
+ """\r
+ self.install_running = 1\r
+ self.afficher_splash()\r
+ self.deactivate_entries() # Les entrees et les boutons sont desactivees\r
+ self.deactivate_buttons() # pendant les operations d'installation\r
+ #self.decompress_archive()\r
+ if not os.path.exists(os.path.join(REPERTOIRE,'Eficas')):\r
+ self.afficher_fatale("Il manque des fichiers d'EFICAS")\r
+ self.install_running = 0\r
+ return\r
+ self.nb_fichiers = self.compte_fichiers(os.path.join(REPERTOIRE,'Eficas'))\r
+ if self.nb_fichiers == 0:\r
+ self.afficher_fatale("Il manque des fichiers d'EFICAS")\r
+ self.install_running = 0\r
+ return\r
+ # essaie de creer les repertoires.\r
+ try:\r
+ if self.make_dirs() == ECHEC : \r
+ self.activate_entries() \r
+ self.activate_buttons() \r
+ self.install_running = 0\r
+ return\r
+ except:\r
+ self.install_running = 0\r
+ afficher_fatale("Impossible de créer certains répertoires")\r
+ \r
+ # affiche la fenêtre avec la barre de progression\r
+ self.afficher_copie_fichiers() \r
+ # essaie de copier les fichiers d'EFICAS\r
+ try:\r
+ if self.move_files() == ECHEC: \r
+ self.afficher_echec("Impossible de copier les fichiers d'EFICAS")\r
+ self.activate_buttons()\r
+ self.install_running = 0\r
+ return\r
+ except:\r
+ self.install_running = 0\r
+ afficher_fatale("Impossible de copier certains fichiers")\r
+\r
+ self.rm_temp_dirs() # efface les répertoires temporaires\r
+ try:\r
+ self.creer_fic_conf() # crée le fichier eficas.conf\r
+ except:\r
+ afficher_info("Impossible de créer le fichier de configuration\n Il est possible de le faire a la main")\r
+# self.install_running = 0\r
+ self.afficher_install_terminee() # A ce stade tout est fait et il ne reste plus qu'à attendre\r
+ # un clic de souris pour sortir\r
+\r
+ def display_defaults(self):\r
+ """\r
+ Affiche les valeurs par défaut dans les zones de saisie\r
+ """\r
+ # racine indique la racine de l'arborescence\r
+ if os.name == 'nt':\r
+ racine = 'C:\\'\r
+ else:\r
+ racine = os.environ['HOME']\r
+ # remplit les zones de saisie avec les options par défaut\r
+ for item in self.items:\r
+ if item.default_value == None : continue\r
+ item.default_value = os.path.join(racine,item.default_value)\r
+ item.entree.insert(0,item.default_value)\r
+\r
+ def register_item(self,item):\r
+ """\r
+ Enregistre l'item dans la liste des items et éventuellement\r
+ dans la liste des items à créer (répertoires)\r
+ """\r
+ self.items.append(item)\r
+ if self.pat_rep.match(item.nom) :\r
+ self.items_a_creer.append(item)\r
+\r
+ def register_entree(self,entree):\r
+ """\r
+ Enregistre la zone de saisie dans la liste des zones\r
+ """\r
+ self.entrees.append(entree)\r
+\r
+ def select_next_entry(self,entree):\r
+ """\r
+ Place le focus dans l'entry suivant celle passée en argument\r
+ """\r
+ index = self.entrees.index(entree)+1\r
+ if index != len(self.entrees):\r
+ self.entrees[index].component('entry').focus()\r
+\r
+ def activate_entries(self):\r
+ """\r
+ Active les entrées. Les zones de saisie deviennent éditables.\r
+ """\r
+ for item in self.entrees:\r
+ item.configure(entry_state='normal')\r
+\r
+ def deactivate_entries(self):\r
+ """\r
+ Désactive les entrées. Les zones ne sont plus éditables.\r
+ """\r
+ for item in self.entrees: # Les entrees sont desactivees\r
+ item.configure(entry_state='disabled') # pendant les operations d'installation\r
+\r
+ def activate_buttons(self):\r
+ """\r
+ active les boutons valider et annuler\r
+ """\r
+ self.validButton.configure(state = 'normal')\r
+ self.exitButton.configure(state = 'normal')\r
+\r
+ def deactivate_buttons(self):\r
+ """\r
+ désactive des boutons valider de annuler\r
+ """\r
+ self.validButton.configure(state = 'disabled')\r
+ self.exitButton.configure(state = 'disabled')\r
+\r
+ def erreur_exec(self, result):\r
+ """\r
+ Callback exécuté lorsque l'utilisateur clique sur un des boutons\r
+ Modifier/Annuler de la fenêtre de dialogue qui lui présente les erreurs\r
+ """\r
+ self.erreur_dialog.deactivate(result)\r
+ self.removedir()\r
+ if result == 'Annuler':\r
+ self.install_running = 0\r
+ self.exit(annule='non')\r
+\r
+ def fatale_exec(self, result):\r
+ """\r
+ Callback exécuté lorsque l'utilisateur clique sur le bouton\r
+ Quitter de la fenêtre de dialogue qui lui présente les erreurs fatales\r
+ Seule solution : sortir de l'installation\r
+ """\r
+ self.fatale_dialog.deactivate(result)\r
+ self.install_running = 0\r
+ self.exit(annule='oui')\r
+ \r
+ def test_confirmation(self,flag,nom):\r
+ """\r
+ Callback activé par le clic sur bouton fenêtre demandant confirmation\r
+ avant création répertoire facultatif\r
+ """\r
+ if flag == 'NON':\r
+ self.confirmation.destroy()\r
+ self.TEST_confirmation_avant_creation = NON\r
+ return \r
+ else :\r
+ self.confirmation.destroy()\r
+ self.TEST_confirmation_avant_creation = OUI \r
+ \r
+ def afficher_fatale(self, message):\r
+ """\r
+ Affiche les erreurs fatales\r
+ """\r
+ self.attente.withdraw()\r
+ w = Tkinter.Label(self.fatale_dialog.interior(),text = message, pady = 5)\r
+ w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)\r
+ self.fatale_dialog.configure(deactivatecommand = w.destroy)\r
+ self.fatale_dialog.activate()\r
+\r
+ def afficher_echec(self, message):\r
+ """\r
+ Affiche un message d'erreur\r
+ Par construction, dès que l'on passe par cette méthode, on sort de l'installation\r
+ en passant le flag install_running à 0\r
+ """\r
+ self.attente.withdraw()\r
+ w = Tkinter.Label(self.erreur_dialog.interior(),text = message, pady = 5)\r
+ w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)\r
+ self.erreur_dialog.configure(deactivatecommand = w.destroy)\r
+ self.erreur_dialog.activate()\r
+\r
+ def confirmation_avant_creation(self,repertoire):\r
+ """\r
+ Affiche une boite de dialogue pour confirmer la création\r
+ d'un répertoire facultatif.\r
+ """\r
+ self.attente.withdraw()\r
+ self.confirmation = Pmw.Dialog(self,\r
+ buttons = ('OUI', 'NON'),\r
+ defaultbutton = 'OUI',\r
+ title = "Répertoire inexistant",\r
+ command = lambda f,s=self,r=repertoire : s.test_confirmation(f,r))\r
+ self.confirmation.withdraw()\r
+ Tkinter.Label(self.confirmation.interior(),\r
+ text="Le répertoire %s n'existe pas \n Voulez-vous le créer ?" %repertoire).pack(side='top')\r
+ self.confirmation.activate(geometry='centerscreenalways')\r
+ return self.TEST_confirmation_avant_creation\r
+ \r
+ def afficher_splash(self):\r
+ """\r
+ Afficher la boite de message \r
+ """\r
+ self.attente.deiconify()\r
+ self.attente.tkraise()\r
+ centerwindow(self.attente)\r
+ self.attente.configure(titre="Installation d'EFICAS",\r
+ text="Vérification intégrité sources Eficas",\r
+ barre="non")\r
+ \r
+ def afficher_info(self,message):\r
+ """\r
+ Afficher une boite de warning\r
+ """\r
+ w = Tkinter.Label(self.info_dialog.interior(),text = message, pady = 5)\r
+ w.pack(expand = 1, fill = 'both', padx = 4, pady = 4)\r
+ self.info_dialog.configure(deactivatecommand = w.destroy)\r
+ self.info_dialog.activate()\r
+ \r
+ def afficher_copie_fichiers(self):\r
+ """\r
+ Afficher la boite de message avec la barre de progression\r
+ """\r
+ self.attente.deiconify()\r
+ self.attente.tkraise()\r
+ self.attente.configure(titre="Installation d'EFICAS",\r
+ text="copie des fichiers",\r
+ barre="oui")\r
+ self.attente.ratio = self.nb_fichiers\r
+ self.attente.configure_barre()\r
+\r
+ def afficher_install_terminee(self):\r
+ """\r
+ Afficher le message Installation terminée\r
+ """\r
+ self.withdraw()\r
+ self.attente.configure(titre="Installation d'EFICAS",\r
+ text="Installation terminée",\r
+ barre="non")\r
+ self.exitButton.place_forget()\r
+ self.validButton.place_forget()\r
+ self.validButton = Tkinter.Button(self.attente.frame,\r
+ text = 'Quitter',\r
+ command = self.exit)\r
+ self.validButton.pack(side='top',pady=5)\r
+ self.install_running = 0\r
+\r
+ def decompress_archive(self) :\r
+ """\r
+ Décompresse l'archive d'EFICAS dans un répertoire temporaire (.)\r
+ """\r
+ print "decompress_archive"\r
+ #try:\r
+ commande = os.path.join(REPERTOIRE,self.d_commandes['decompress'])\r
+ fichier = os.path.join(REPERTOIRE,"eficas.zip")\r
+ print 'commande =',commande\r
+ print 'fichier =',fichier\r
+ os.execv(commande,("eficas.zip",))\r
+ #except:\r
+ # self.affiche_echec("Erreur dans la décompression")\r
+\r
+ def normaliser_chemin(self, nom):\r
+ """\r
+ Retourne le chemin d'accès complet à nom\r
+ """\r
+ return os.path.abspath(os.path.expanduser(nom))\r
+\r
+ def discriminer_noms(self):\r
+ """\r
+ Emet un message d'alerte si des zones de saisie ne sont pas remplies\r
+ ou si des noms de répertoires à créer sont identiques.\r
+ """\r
+ liste_noms = []\r
+ for item in self.items_a_creer:\r
+ nom = item.entree.get()\r
+ if nom == self.rep_install.entree.get(): # il faut ajouter 'Eficas' au chemin du repertoire\r
+ nom = os.path.join(nom,"Eficas") # d'installation\r
+ liste_noms.append(nom)\r
+\r
+ test = SUCCES\r
+ for item in self.items_a_creer:\r
+ nom = item.entree.get()\r
+ if len(nom) == 0 :\r
+ test = ECHEC\r
+ message = "attention : certains répertoires n'ont pas de nom"\r
+ self.afficher_echec(message)\r
+ item.entree.component('entry').focus()\r
+ break\r
+\r
+ if test == ECHEC :\r
+ return test\r
+\r
+ for item in self.items_a_creer:\r
+ nom = item.entree.get()\r
+ if liste_noms.count(nom) >1 :\r
+ test = ECHEC\r
+ message = "attention : certains répertoires ont le même nom"\r
+ self.afficher_echec(message)\r
+ item.entree.component('entry').focus()\r
+ break\r
+\r
+ return test\r
+\r
+ def compte_fichiers(self,path):\r
+ """\r
+ Dénombre les fichiers présents dans le répertoire Eficas (et ses sous-répertoires)\r
+ """\r
+ nb = 0\r
+ l_fic = os.listdir(path)\r
+ l_rep = []\r
+ for fic in l_fic :\r
+ if os.path.isdir(os.path.join(path,fic)):\r
+ l_rep.append(fic)\r
+ else:\r
+ nb = nb+1\r
+ for rep in l_rep :\r
+ nb = nb + self.compte_fichiers(os.path.join(path,rep))\r
+ return nb\r
+\r
+ def creer_fic_conf(self):\r
+ """\r
+ Crée le fichier editeur.ini a partir des données saisies\r
+ par l'administrateur.\r
+ """\r
+ fichier_conf = os.path.join(self.normaliser_chemin(self.rep_install.get_valeur()),"Eficas/Accas/editeur.ini")\r
+ f = open(fichier_conf,'w')\r
+ f.write("path_doc = "+'"'+self.normaliser_chemin(self.rep_docaster.get_valeur())+'"\n')\r
+ f.write("exec_acrobat = "+'"'+self.normaliser_chemin(self.acrobat.get_valeur())+'"\n')\r
+ f.write('isdeveloppeur = "NON"\n')\r
+ f.write("rep_travail = "+'"'+self.normaliser_chemin(self.rep_travail.get_valeur())+'"\n')\r
+ f.write("rep_cata = "+'"'+os.path.join(self.normaliser_chemin(self.rep_install.get_valeur()),"Eficas/Cata")+'"/\n') # attention au dernier slash\r
+ f.write("rep_mat = "+'"'+self.normaliser_chemin(self.rep_mat.get_valeur())+'"\n')\r
+ cata = """catalogues = (('ASTER','v5',rep_cata + 'cata_aster_v5.py','defaut'),\r
+ ('ASTER','v6',rep_cata + 'cata_aster_v6.py')\r
+ )\n"""\r
+ f.write(cata)\r
+ f.close()\r
+\r
+ def move_files(self):\r
+ """\r
+ Déplace les fichiers Eficas du répertoire temporaire vers\r
+ leur répertoire de destination\r
+ """\r
+ # création du répertoire Eficas\r
+ rep_eficas = os.path.join(self.rep_install.get_valeur(),'Eficas')\r
+ self.copy_rep(os.path.join(REPERTOIRE,'Eficas'),rep_eficas)\r
+\r
+ def copy_rep(self,rep_dep,rep_arr):\r
+ """\r
+ Copie le répertoire path_dep et ses sous-répertoires dans path_arr\r
+ """\r
+ l_fichiers = os.listdir(rep_dep)\r
+ if not os.path.exists(rep_arr) :\r
+ # création du répertoire d'arrivée quand il n'existe pas \r
+ self.mkdirs(rep_arr)\r
+ for fic in l_fichiers :\r
+ nom_complet_dep = os.path.join(rep_dep,fic)\r
+ nom_complet_arr = os.path.join(rep_arr,fic)\r
+ if os.path.isfile(nom_complet_dep):\r
+ commande_copie = self.d_commandes['copy']+nom_complet_dep+' '+nom_complet_arr\r
+ commande_delete= self.d_commandes['delete']+nom_complet_dep\r
+ try:\r
+ os.system(commande_copie)\r
+ os.system(commande_delete)\r
+ self.attente.update_barre()\r
+ except Exception,e:\r
+ pass\r
+ elif os.path.isdir(nom_complet_dep):\r
+ self.copy_rep(nom_complet_dep,nom_complet_arr)\r
+\r
+ def rm_temp_dirs(self):\r
+ """\r
+ Détruit le répertoire temporaire de l'archive d'Eficas\r
+ """\r
+ rep_arch = os.path.join(REPERTOIRE,'Eficas')\r
+ self.rm_r(rep_arch)\r
+\r
+ def make_dirs(self):\r
+ """\r
+ Crée les répertoires d'accueil des fichiers d'EFICAS\r
+ """\r
+ # création des répertoires dont l'utilisateur a donné le nom\r
+ if self.discriminer_noms() == ECHEC:\r
+ return ECHEC\r
+ for item in self.items_a_creer:\r
+ if not item.entree.get():\r
+ continue\r
+ nom = item.get_valeur()\r
+ if nom == self.normaliser_chemin(self.rep_install.entree.get()): # il faut ajouter 'Eficas' au chemin du repertoire\r
+ nom = os.path.join(nom,"Eficas") # d'installation\r
+ item.test = self.essai_creer(nom,item.statut)\r
+ if item.test == ECHEC :\r
+ item.entree.component('entry').focus()\r
+ return ECHEC\r
+ return SUCCES\r
+\r
+ def essai_creer(self, nom, statut):\r
+ """\r
+ Essaie de créer le répertoire nom s'il n'existe pas déjà.\r
+ Si statut == 'f' et si le fichier n'existe pas, demande\r
+ confirmation avant création\r
+ """\r
+ repertoire = self.normaliser_chemin(nom) # repertoire = chemin absolu de nom\r
+ if os.path.exists(repertoire):\r
+ if statut == 'o' :\r
+ self.afficher_echec("Un fichier ou répertoire de nom "+ repertoire+ " existe déjà !\n"+\r
+ "L'installation ne peut continuer")\r
+ return ECHEC\r
+ else:\r
+ return SUCCES\r
+\r
+ if statut == 'f' :\r
+ # on demande confirmation de création à l'utilisateur\r
+ test = self.confirmation_avant_creation(repertoire)\r
+ if test == NON:\r
+ return SUCCES\r
+\r
+ try:\r
+ test = self.mkdirs(repertoire)\r
+ return SUCCES\r
+ except Exception,e:\r
+ message = "La création de "+repertoire+" a échoué :\n %s \n Vérifiez vos droits d'écriture" %str(e) # message d'erreur\r
+ self.afficher_echec(message)\r
+ return ECHEC\r
+\r
+ def mkdirs(self,rep):\r
+ """\r
+ Création récursive des répertoires d'installation.\r
+ Les noms des répertoires crées sont stockés dans\r
+ une liste dont se sert la méthode removedir pour\r
+ restaurer l'environnement initial en cas d'annulation.\r
+ """\r
+ if rep==os.path.dirname(rep):\r
+ return SUCCES\r
+\r
+ if os.path.exists(os.path.dirname(rep)):\r
+ os.mkdir(rep)\r
+ self.liste_rep_crees.append(rep)\r
+ return SUCCES\r
+ else:\r
+ test = self.mkdirs(os.path.dirname(rep))\r
+ if test == SUCCES:\r
+ os.mkdir(rep)\r
+ self.liste_rep_crees.append(rep)\r
+ return SUCCES\r
+ else:\r
+ return ECHEC\r
+\r
+ def rm_r(self,path):\r
+ """\r
+ Detruit récursivement path\r
+ """\r
+ if not os.path.exists(path):\r
+ return\r
+ try:\r
+ if len(os.listdir(path))!=0:\r
+ for entree in os.listdir(path):\r
+ entree = os.path.join(path,entree)\r
+ self.rm_r(entree)\r
+ os.rmdir(path)\r
+ except Exception,e:\r
+ self.afficher_info("Impossible de détruire le répertoire : "+path+"\n"+"\n"+str(e)+"\n L'installation continue néanmoins")\r
+\r
+ def removedir(self):\r
+ """\r
+ Destruction des répertoires déja crées (en cas d'annulation)\r
+ """\r
+ for rep in self.liste_rep_crees:\r
+ self.rm_r(rep)\r
+ self.liste_rep_crees = []\r
+\r
+ def exit(self,annule='non'):\r
+ """\r
+ Tente de sortir de l'application.\r
+ Echoue si installation en cours\r
+ """\r
+ if self.install_running :\r
+ # l'installation est en cours --> on interdit la sortie\r
+ self.afficher_info("Impossible de quitter tant que l'installation est en cours\n Veuillez patienter")\r
+ else:\r
+ if annule == 'oui' : self.removedir()\r
+ self.master.quit()\r
+\r
+if __name__ == '__main__':\r
+ test = Test_Environnement().test()\r
+ if not test :\r
+ # environnement incomplet --> on sort de la procédure d'installation\r
+ sys.exit()\r
+ else:\r
+ import Tkinter\r
+ import Pmw\r
+ root = Tkinter.Tk()\r
+ Pmw.initialise(root)\r
+ try:\r
+ principal = Config(root)\r
+ root.mainloop()\r
+ except Exception,e:\r
+ print "Erreur non prévue rencontrée : ",str(e)\r
+ print "Veuillez prévenir la maintenance"\r
+ sys.exit()\r