]> SALOME platform Git repositories - modules/eficas.git/commitdiff
Salome HOME
F.R: - ajout de la procédure d'installation (rép Installation + 5 fichiers)
authoreficas <>
Wed, 22 May 2002 07:46:29 +0000 (07:46 +0000)
committereficas <>
Wed, 22 May 2002 07:46:29 +0000 (07:46 +0000)
Installation/Doc_technique_install.doc [new file with mode: 0755]
Installation/README [new file with mode: 0755]
Installation/README_install [new file with mode: 0755]
Installation/code_aster.gif [new file with mode: 0755]
Installation/install.py [new file with mode: 0755]

diff --git a/Installation/Doc_technique_install.doc b/Installation/Doc_technique_install.doc
new file mode 100755 (executable)
index 0000000..285a354
Binary files /dev/null and b/Installation/Doc_technique_install.doc differ
diff --git a/Installation/README b/Installation/README
new file mode 100755 (executable)
index 0000000..4a575ba
--- /dev/null
@@ -0,0 +1,30 @@
+
+
+       =================================================
+               Procédure d'installation d'EFICAS
+       =================================================
+
+Pré-requis :
+------------
+
+       - Python 2.1 ou supérieur avec Tkinter
+       - PMW 8.0.5 ou supérieur
+
+Installation :
+--------------
+
+1°) copiez le fichier eficas.tar.gz dans un répertoire temporaire
+
+2°) Décompressez ce fichier comme suit :
+
+       gunzip eficas.tar.gz
+       tar xvf eficas.tar
+
+3°) Vous devriez désormais voir 4 éléments :
+
+       - 1 fichier README_install
+       - 1 fichier install.py
+       - 1 fichier code_aster.gif
+       - 1 répertoire /Eficas
+
+4°) Reportez-vous au fichier README_install pour la suite des actions à entreprendre.
diff --git a/Installation/README_install b/Installation/README_install
new file mode 100755 (executable)
index 0000000..01ee3ff
--- /dev/null
@@ -0,0 +1,40 @@
+\r
+\r
+       =================================================\r
+           Procédure d'installation d'EFICAS (suite)\r
+       =================================================\r
+\r
+Pour lancer la procédure d'installation, tapez :\r
+\r
+       python install.py\r
+\r
+Vous pouvez remplacer 'python' par le chemin d'accès de votre interpréteur Python.\r
+\r
+La procédure d'installation commence par vérifier que votre système contient bien les\r
+pré-requis pour EFICAS (cf README)\r
+\r
+La procédure va vous demander un certain nombre de chemins d'accès nécessaires à l'établissement du\r
+fichier de configuration d'EFICAS qui s'appelle editeur.ini et qui se trouvera, une fois EFICAS,\r
+installé, dans le répertoire Eficas/Accas\r
+\r
+- Répertoire d'installation    : répertoire dans lequel vous voulez installer Eficas\r
+- Répertoire de travail        : répertoire de travail temporaire d'EFICAS\r
+- Répertoire matériaux                 : répertoire dans lequel se trouvent les catalogues matériaux d'ASTER\r
+- Répertoire doc Aster                 : répertoire dans lequel se trouve le manuel U4 de la doc Aster (format pdf)\r
+                                       ex : /logiciels/aster/NEW6/doc/pdf/u4\r
+- Exécutable Acrobat Reader    : chemin d'accès complet à l'exécutable Acrobat Reader\r
+\r
+\r
+Catalogues Aster   :   EFICAS installe par défaut les catalogues Aster v5 et v6 qui se trouvent en\r
+                       /Eficas/Cata.\r
+                       Si vous voulez en installer d'autres, il faut qu'ils se trouvent dans ce même répertoire\r
+                       ou qu'il y ait un lien dans ce répertoire vers le fichier.\r
+                       Pour ajouter d'autres catalogues, il faut aller modifier directement le fichier editeur.ini\r
+\r
+       \r
+\r
+Lancement d'EFICAS :   le fichier à lancer est /Eficas/Editeur/eficas_aster.py\r
+                       il faut le lancer précédé du chemin d'accès à l'interpréteur Python comme\r
+                       pour la procédure d'installation.\r
+\r
+\r
diff --git a/Installation/code_aster.gif b/Installation/code_aster.gif
new file mode 100755 (executable)
index 0000000..2e4e691
Binary files /dev/null and b/Installation/code_aster.gif differ
diff --git a/Installation/install.py b/Installation/install.py
new file mode 100755 (executable)
index 0000000..68b57b0
--- /dev/null
@@ -0,0 +1,949 @@
+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