maintenance.execlocal

Exécute localement les scripts préliminaires à la publication et à la contextualisation des sources d'un dépôt.

Modifié le 30/03/23 @author: remy

Traitements à effectuer sur les fichiers d'un dépôt :

  • créer-modifier les sources avant compilation
  • compiler
  • établir des listes de fichiers images à publier
  • établir des listes de données utiles lors de la contextualisation

Le module execlocal

  • Importe le sous-module scantex d'examen des fichiers LateX.
  • Définit la classe Execlocal.

Les traitements sont effectués lors de l'instanciation d'un objet Execlocal. Cette instanciation importe un module spécifique au dépôt.
Actuellement, les sous-modules spécifiques sont exl_mathCours, exl_mathExos et exl_mathPbs.

Les commandes de compilation sont codées dans le fichier init (manifeste) du dépôt. Elles sont lancées par la méthode compil() de la classe Execlocal.
Les données à publier sont extraites par apublierImg().
Les autres traitements sont définis dans la fonction exec() du sous-module spécifique.

Principales propriétés d'un objet Execlocal :

  • .log: journal de l'exécution locale
  • .publiables: liste des fichiers publiables
  • .specific_results: dictionnaire présentant des données spécifiques au dépôt.
  1# -*- coding: utf-8 -*-
  2"""
  3Exécute localement les scripts préliminaires à la publication et à la contextualisation des sources d'un dépôt.
  4
  5Modifié le 30/03/23 @author: remy
  6
  7Traitements à effectuer sur les fichiers d'un dépôt : 
  8
  9- créer-modifier les sources avant compilation
 10- compiler
 11- établir des listes de fichiers images à publier
 12- établir des listes de données utiles lors de la contextualisation
 13
 14Le module `execlocal`
 15- Importe le sous-module [`scantex`](scantex.html) d'examen des fichiers LateX.
 16- Définit la classe `Execlocal`.
 17
 18Les traitements sont effectués lors de l'instanciation d'un objet `Execlocal`. Cette instanciation importe un module spécifique au dépôt.  
 19Actuellement, les sous-modules spécifiques sont 
 20[`exl_mathCours`](exl_mathCours.html), [`exl_mathExos`](exl_mathExos.html) et 
 21[`exl_mathPbs`](exl_mathPbs.html).
 22
 23Les commandes de compilation sont codées dans le fichier `init` (manifeste) du dépôt. Elles sont lancées par la méthode `compil()` de la classe `Execlocal`.  
 24Les données à publier sont extraites par `apublierImg()`.  
 25Les autres traitements sont définis dans la fonction `exec()` du sous-module spécifique.
 26
 27Principales propriétés d'un objet `Execlocal` :
 28
 29- `.log`: journal de l'exécution locale
 30- `.publiables`: liste des fichiers publiables
 31- `.specific_results`: dictionnaire présentant des données spécifiques au dépôt.
 32
 33
 34"""
 35import importlib
 36import subprocess
 37import glob
 38import os.path
 39
 40import scantex
 41
 42
 43class Execlocal:
 44    """Classe d'exécution locale."""
 45
 46    def __init__(self, data):
 47        """
 48        Instancie un objet `Execlocal`.
 49
 50        - récupère les paramètres du dépôt
 51        - initialise la propriété journal (`.log`)
 52        - importe le module spécifique au dépôt
 53        - exécute les traitements spécifiques
 54            - renseigne  `.specific_results`
 55        - exécute les commandes de compilation
 56            - renseigne `.publiables`
 57        
 58
 59        #### Parametres
 60
 61        data :
 62
 63        - TYPE dictionnaire
 64        - DESCRIPTION   codage du *manifeste* du dépôt
 65
 66        La structure de ce dictionnaire est précisée dans le fichier
 67        d'initialisation spécifique [`init_mathExos`](init_mathExos.html)
 68        [`init_mathPbs`](init_mathPbs.html)
 69
 70        #### Renvoie
 71
 72        None.
 73
 74
 75        """
 76        lineprefix = "\n \t \t"
 77        self.log = lineprefix + "Initialisation de la classe Execlocal."
 78        """
 79        Journal d'instanciation d'un objet `Execlocal`.
 80
 81        TYPE chaine de caractères.
 82        """
 83
 84        self.commandes = data['commandes']
 85        self.rel_path = data['relative_path']
 86        self.publish_data = data['publish_data']
 87        self.context_data = data['context_data']
 88
 89        # change de répertoire
 90        maintenance_path = os.getcwd()
 91        os.chdir(self.rel_path)
 92
 93        # importation du module spécifique
 94        module = data['modulespec']
 95        if module:
 96            try:
 97                specific = importlib.import_module(module)
 98                self.log += lineprefix
 99                self.log += "Importation du module spécifique " + module
100                # maintenance spécifique
101                truc = specific.exec(data)
102                self.log += truc['log'] 
103                self.specific_results = truc['specific_results']
104            except ImportError as error:
105                self.log += lineprefix + "Module " + error.name + " pas trouvé"
106
107        # liste des commandes de compilation à exécuter
108        self.cmds_list = self.aexecuter()
109
110        # compilations
111        # print('\n')
112        # for obj in self.cmds_list:
113        #    print(obj, '\n')
114        self.compil()
115
116        # renseigne la propriété .publiables
117        self.publiables = self.apublierImg()
118        # fichiers publiables dict path: date
119
120        # retour au répertoire de base
121        os.chdir(maintenance_path)
122
123    def aexecuter(self):
124        """
125        Renvoie une liste d'objets codant des commandes de compilation.
126
127        Associe à chaque type de commande la liste des fichiers sur lesquels
128        elle doit s'appliquer.
129
130        Structure de l'objet codant un type de commande:
131
132            obj = {'ext': type['ext'],
133                   'imgdir': type['imgdir'],
134                   'imgext': type['imgext'],
135                   'command': type['command'],
136                   'fics': []}
137
138
139        """
140        self.log += ("\n \t \t Formation de la liste "
141                     + "des commandes de compilation")
142        aexec = []
143        for type in self.commandes:
144            obj = {'ext': type['ext'],
145                   'imgdir': type['imgdir'],
146                   'imgext': type['imgext'],
147                   'command': type['command'],
148                   'fics': []}
149            imgext = type['imgext']
150            imgdir = type['imgdir']
151            fics = []
152            # print(obj['command'], type['patterns'])
153            for paty in type['patterns']:
154                paty = self.rel_path + paty
155                # print(paty, os.getcwd())
156                fics.extend(glob.glob(paty))
157                # print(fics,"\n")
158
159            for src in fics:
160                srcext = os.path.splitext(src)[1]
161                didi = os.path.dirname(src)
162                img = os.path.join(didi, imgdir, os.path.basename(src))
163                img = img.replace(srcext, imgext)
164                # if ("A_" in src):
165                #    print(src, img)
166                if scantex.acompiler(src, img):
167                    obj['fics'].append(src)
168            aexec.append(obj)
169        return aexec
170
171    def apublierImg(self):
172        """
173        Renvoie un dictionnaire de fichiers publiables.
174
175        - clé = chemin d'un fichier à publier
176        - valeur = timestamp du fichier
177        """
178        self.log += "\n \t \t Récup timesstamps"
179        self.log += " locaux des fichiers à publier \n"
180        docs_n = []
181        times = {}
182        for paty in self.publish_data['patterns']:
183            docs_n += glob.glob(paty)
184        for nom_doc in docs_n:
185            times[self.rel_path + nom_doc] = os.path.getmtime(nom_doc)
186        return times
187
188    def compil(self):
189        """
190        Exécute les commandes de compilation.
191
192        Elles sont codées dans `self.cmds_list`.
193        Un compte rendu est placé dans le journal `self.log`.
194        """
195        self.log += '\n \t \t Exécution des compilations \n'
196        log = ''
197        for obj in self.cmds_list:
198            log += '\t \t \t'
199            log += (str(len(obj['fics'])) + ' commandes '
200                    + str(obj['command']) + ' fichiers : \n')
201            for src in obj['fics']:
202                log += '\t \t \t \t' + src
203                command = obj['command'] + [src]
204                try:
205                    # print(command)
206                    subprocess.run(command)
207                    log += ' OK \n'
208                except subprocess.SubprocessError:
209                    log += ' ERREUR dans exécution de la commande \n'
210        self.log += log
class Execlocal:
 44class Execlocal:
 45    """Classe d'exécution locale."""
 46
 47    def __init__(self, data):
 48        """
 49        Instancie un objet `Execlocal`.
 50
 51        - récupère les paramètres du dépôt
 52        - initialise la propriété journal (`.log`)
 53        - importe le module spécifique au dépôt
 54        - exécute les traitements spécifiques
 55            - renseigne  `.specific_results`
 56        - exécute les commandes de compilation
 57            - renseigne `.publiables`
 58        
 59
 60        #### Parametres
 61
 62        data :
 63
 64        - TYPE dictionnaire
 65        - DESCRIPTION   codage du *manifeste* du dépôt
 66
 67        La structure de ce dictionnaire est précisée dans le fichier
 68        d'initialisation spécifique [`init_mathExos`](init_mathExos.html)
 69        [`init_mathPbs`](init_mathPbs.html)
 70
 71        #### Renvoie
 72
 73        None.
 74
 75
 76        """
 77        lineprefix = "\n \t \t"
 78        self.log = lineprefix + "Initialisation de la classe Execlocal."
 79        """
 80        Journal d'instanciation d'un objet `Execlocal`.
 81
 82        TYPE chaine de caractères.
 83        """
 84
 85        self.commandes = data['commandes']
 86        self.rel_path = data['relative_path']
 87        self.publish_data = data['publish_data']
 88        self.context_data = data['context_data']
 89
 90        # change de répertoire
 91        maintenance_path = os.getcwd()
 92        os.chdir(self.rel_path)
 93
 94        # importation du module spécifique
 95        module = data['modulespec']
 96        if module:
 97            try:
 98                specific = importlib.import_module(module)
 99                self.log += lineprefix
100                self.log += "Importation du module spécifique " + module
101                # maintenance spécifique
102                truc = specific.exec(data)
103                self.log += truc['log'] 
104                self.specific_results = truc['specific_results']
105            except ImportError as error:
106                self.log += lineprefix + "Module " + error.name + " pas trouvé"
107
108        # liste des commandes de compilation à exécuter
109        self.cmds_list = self.aexecuter()
110
111        # compilations
112        # print('\n')
113        # for obj in self.cmds_list:
114        #    print(obj, '\n')
115        self.compil()
116
117        # renseigne la propriété .publiables
118        self.publiables = self.apublierImg()
119        # fichiers publiables dict path: date
120
121        # retour au répertoire de base
122        os.chdir(maintenance_path)
123
124    def aexecuter(self):
125        """
126        Renvoie une liste d'objets codant des commandes de compilation.
127
128        Associe à chaque type de commande la liste des fichiers sur lesquels
129        elle doit s'appliquer.
130
131        Structure de l'objet codant un type de commande:
132
133            obj = {'ext': type['ext'],
134                   'imgdir': type['imgdir'],
135                   'imgext': type['imgext'],
136                   'command': type['command'],
137                   'fics': []}
138
139
140        """
141        self.log += ("\n \t \t Formation de la liste "
142                     + "des commandes de compilation")
143        aexec = []
144        for type in self.commandes:
145            obj = {'ext': type['ext'],
146                   'imgdir': type['imgdir'],
147                   'imgext': type['imgext'],
148                   'command': type['command'],
149                   'fics': []}
150            imgext = type['imgext']
151            imgdir = type['imgdir']
152            fics = []
153            # print(obj['command'], type['patterns'])
154            for paty in type['patterns']:
155                paty = self.rel_path + paty
156                # print(paty, os.getcwd())
157                fics.extend(glob.glob(paty))
158                # print(fics,"\n")
159
160            for src in fics:
161                srcext = os.path.splitext(src)[1]
162                didi = os.path.dirname(src)
163                img = os.path.join(didi, imgdir, os.path.basename(src))
164                img = img.replace(srcext, imgext)
165                # if ("A_" in src):
166                #    print(src, img)
167                if scantex.acompiler(src, img):
168                    obj['fics'].append(src)
169            aexec.append(obj)
170        return aexec
171
172    def apublierImg(self):
173        """
174        Renvoie un dictionnaire de fichiers publiables.
175
176        - clé = chemin d'un fichier à publier
177        - valeur = timestamp du fichier
178        """
179        self.log += "\n \t \t Récup timesstamps"
180        self.log += " locaux des fichiers à publier \n"
181        docs_n = []
182        times = {}
183        for paty in self.publish_data['patterns']:
184            docs_n += glob.glob(paty)
185        for nom_doc in docs_n:
186            times[self.rel_path + nom_doc] = os.path.getmtime(nom_doc)
187        return times
188
189    def compil(self):
190        """
191        Exécute les commandes de compilation.
192
193        Elles sont codées dans `self.cmds_list`.
194        Un compte rendu est placé dans le journal `self.log`.
195        """
196        self.log += '\n \t \t Exécution des compilations \n'
197        log = ''
198        for obj in self.cmds_list:
199            log += '\t \t \t'
200            log += (str(len(obj['fics'])) + ' commandes '
201                    + str(obj['command']) + ' fichiers : \n')
202            for src in obj['fics']:
203                log += '\t \t \t \t' + src
204                command = obj['command'] + [src]
205                try:
206                    # print(command)
207                    subprocess.run(command)
208                    log += ' OK \n'
209                except subprocess.SubprocessError:
210                    log += ' ERREUR dans exécution de la commande \n'
211        self.log += log

Classe d'exécution locale.

Execlocal(data)
 47    def __init__(self, data):
 48        """
 49        Instancie un objet `Execlocal`.
 50
 51        - récupère les paramètres du dépôt
 52        - initialise la propriété journal (`.log`)
 53        - importe le module spécifique au dépôt
 54        - exécute les traitements spécifiques
 55            - renseigne  `.specific_results`
 56        - exécute les commandes de compilation
 57            - renseigne `.publiables`
 58        
 59
 60        #### Parametres
 61
 62        data :
 63
 64        - TYPE dictionnaire
 65        - DESCRIPTION   codage du *manifeste* du dépôt
 66
 67        La structure de ce dictionnaire est précisée dans le fichier
 68        d'initialisation spécifique [`init_mathExos`](init_mathExos.html)
 69        [`init_mathPbs`](init_mathPbs.html)
 70
 71        #### Renvoie
 72
 73        None.
 74
 75
 76        """
 77        lineprefix = "\n \t \t"
 78        self.log = lineprefix + "Initialisation de la classe Execlocal."
 79        """
 80        Journal d'instanciation d'un objet `Execlocal`.
 81
 82        TYPE chaine de caractères.
 83        """
 84
 85        self.commandes = data['commandes']
 86        self.rel_path = data['relative_path']
 87        self.publish_data = data['publish_data']
 88        self.context_data = data['context_data']
 89
 90        # change de répertoire
 91        maintenance_path = os.getcwd()
 92        os.chdir(self.rel_path)
 93
 94        # importation du module spécifique
 95        module = data['modulespec']
 96        if module:
 97            try:
 98                specific = importlib.import_module(module)
 99                self.log += lineprefix
100                self.log += "Importation du module spécifique " + module
101                # maintenance spécifique
102                truc = specific.exec(data)
103                self.log += truc['log'] 
104                self.specific_results = truc['specific_results']
105            except ImportError as error:
106                self.log += lineprefix + "Module " + error.name + " pas trouvé"
107
108        # liste des commandes de compilation à exécuter
109        self.cmds_list = self.aexecuter()
110
111        # compilations
112        # print('\n')
113        # for obj in self.cmds_list:
114        #    print(obj, '\n')
115        self.compil()
116
117        # renseigne la propriété .publiables
118        self.publiables = self.apublierImg()
119        # fichiers publiables dict path: date
120
121        # retour au répertoire de base
122        os.chdir(maintenance_path)

Instancie un objet Execlocal.

  • récupère les paramètres du dépôt
  • initialise la propriété journal (.log)
  • importe le module spécifique au dépôt
  • exécute les traitements spécifiques
    • renseigne .specific_results
  • exécute les commandes de compilation
    • renseigne .publiables

Parametres

data :

  • TYPE dictionnaire
  • DESCRIPTION codage du manifeste du dépôt

La structure de ce dictionnaire est précisée dans le fichier d'initialisation spécifique init_mathExos init_mathPbs

Renvoie

None.

log

Journal d'instanciation d'un objet Execlocal.

TYPE chaine de caractères.

def aexecuter(self):
124    def aexecuter(self):
125        """
126        Renvoie une liste d'objets codant des commandes de compilation.
127
128        Associe à chaque type de commande la liste des fichiers sur lesquels
129        elle doit s'appliquer.
130
131        Structure de l'objet codant un type de commande:
132
133            obj = {'ext': type['ext'],
134                   'imgdir': type['imgdir'],
135                   'imgext': type['imgext'],
136                   'command': type['command'],
137                   'fics': []}
138
139
140        """
141        self.log += ("\n \t \t Formation de la liste "
142                     + "des commandes de compilation")
143        aexec = []
144        for type in self.commandes:
145            obj = {'ext': type['ext'],
146                   'imgdir': type['imgdir'],
147                   'imgext': type['imgext'],
148                   'command': type['command'],
149                   'fics': []}
150            imgext = type['imgext']
151            imgdir = type['imgdir']
152            fics = []
153            # print(obj['command'], type['patterns'])
154            for paty in type['patterns']:
155                paty = self.rel_path + paty
156                # print(paty, os.getcwd())
157                fics.extend(glob.glob(paty))
158                # print(fics,"\n")
159
160            for src in fics:
161                srcext = os.path.splitext(src)[1]
162                didi = os.path.dirname(src)
163                img = os.path.join(didi, imgdir, os.path.basename(src))
164                img = img.replace(srcext, imgext)
165                # if ("A_" in src):
166                #    print(src, img)
167                if scantex.acompiler(src, img):
168                    obj['fics'].append(src)
169            aexec.append(obj)
170        return aexec

Renvoie une liste d'objets codant des commandes de compilation.

Associe à chaque type de commande la liste des fichiers sur lesquels elle doit s'appliquer.

Structure de l'objet codant un type de commande:

obj = {'ext': type['ext'],
       'imgdir': type['imgdir'],
       'imgext': type['imgext'],
       'command': type['command'],
       'fics': []}
def apublierImg(self):
172    def apublierImg(self):
173        """
174        Renvoie un dictionnaire de fichiers publiables.
175
176        - clé = chemin d'un fichier à publier
177        - valeur = timestamp du fichier
178        """
179        self.log += "\n \t \t Récup timesstamps"
180        self.log += " locaux des fichiers à publier \n"
181        docs_n = []
182        times = {}
183        for paty in self.publish_data['patterns']:
184            docs_n += glob.glob(paty)
185        for nom_doc in docs_n:
186            times[self.rel_path + nom_doc] = os.path.getmtime(nom_doc)
187        return times

Renvoie un dictionnaire de fichiers publiables.

  • clé = chemin d'un fichier à publier
  • valeur = timestamp du fichier
def compil(self):
189    def compil(self):
190        """
191        Exécute les commandes de compilation.
192
193        Elles sont codées dans `self.cmds_list`.
194        Un compte rendu est placé dans le journal `self.log`.
195        """
196        self.log += '\n \t \t Exécution des compilations \n'
197        log = ''
198        for obj in self.cmds_list:
199            log += '\t \t \t'
200            log += (str(len(obj['fics'])) + ' commandes '
201                    + str(obj['command']) + ' fichiers : \n')
202            for src in obj['fics']:
203                log += '\t \t \t \t' + src
204                command = obj['command'] + [src]
205                try:
206                    # print(command)
207                    subprocess.run(command)
208                    log += ' OK \n'
209                except subprocess.SubprocessError:
210                    log += ' ERREUR dans exécution de la commande \n'
211        self.log += log

Exécute les commandes de compilation.

Elles sont codées dans self.cmds_list. Un compte rendu est placé dans le journal self.log.