Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
import logging
import imp
import pkgutil
import inspect
import contextlib
from configparser import ConfigParser
from ais_parser import get_resource_filename
def load_module(name, paths):
"""Chargez le nom du module en utilisant les chemins de recherche donnés."""
handle, pathname, description = imp.find_module(name, paths)
if handle is not None:
return imp.load_module(name, handle, pathname, description)
else:
return None
def load_all_modules(paths):
"""Chargez tous les modules sur les chemins indiqués."""
modules = {}
for _, name, _ in pkgutil.walk_packages(paths):
try:
modules[name] = load_module(name, paths)
except ImportError as error:
logging.warn("Error Importing Module " + name + ": {}".format(error))
return modules
class Loader:
"""Le Loader réunit des référentiels de données et des programmes,
et exécute des opérations sur eux."""
def __init__(self, config=None):
# charger à partir du fichier si le chemin est fourni
loaded_conf = ConfigParser()
if config is None:
raise RuntimeError("No Config File Defined.")
else:
if isinstance(config, str):
loaded_conf.read(config)
config = loaded_conf
if 'globals' in config:
repopaths = str(config.get('globals', 'repos'))
repopaths = repopaths.split(',')
repopaths.extend([get_resource_filename('repositories')])
else:
repopaths = [get_resource_filename('repositories')]
logging.debug("Paths to repositories: {}".format(repopaths))
# load repo drivers from repopaths
repo_drivers = load_all_modules(repopaths)
# get repo configurations from config
if 'globals' in config:
repo_config = set(config.sections()) - set(['globals'])
else:
repo_config = set(config.sections())
# check which repos we have drivers for
repo_conf_dict = {}
for repo_name in repo_config:
conf = config[repo_name]
if not 'type' in conf:
logging.warning("Repository " + repo_name + " Does not Specify a Type in The config File.")
elif not conf['type'] in repo_drivers:
logging.warning("Driver of Type " + conf['type'] + " for Repository " + repo_name + " Not Found.")
else:
repo_conf_dict[repo_name] = conf
if 'globals' in config:
progpaths = str(config.get('globals', 'progs'))
progpaths = progpaths.split(',')
progpaths.extend([get_resource_filename('programs')])
vispaths = str(config.get('globals', 'visos'))
vispaths = vispaths.split(',')
vispaths.extend([get_resource_filename('filter_for_visualisations')])
else:
progpaths = [get_resource_filename('programs')]
vispaths = [get_resource_filename('filter_for_visualisations')]
expaths = [get_resource_filename('exports')]
# charger des programmes à partir de progpaths
logging.debug("Paths to Programs: {}".format(progpaths))
programs = load_all_modules(progpaths)
# charger des visualisations à partir de vispaths
logging.debug("Paths to Visualisations: {}".format(vispaths))
filter_for_visualisations = load_all_modules(vispaths)
self.repo_drivers = repo_drivers
self.repo_config = repo_conf_dict
self.programs = programs
self.filter_for_visualisations = filter_for_visualisations
def get_datarepositories(self):
"""Renvoie un ensemble de noms de répertoiress de données disponibles"""
return self.repo_config.keys()
def get_repositorycommands(self, repo_name):
"""Renvoie une liste des commandes disponibles pour le référentiel spécifié"""
try:
return self.repo_drivers[self.repo_config[repo_name]['type']].EXPORT_COMMANDS
except AttributeError:
return []
def get_programcommands(self, progname):
"""Renvoie une liste des commandes disponibles pour le programme spécifié"""
try:
return self.programs[progname].EXPORT_COMMANDS
except AttributeError:
return []
def get_filterforvisualisationcommands(self, visname):
"""Renvoie une liste des commandes disponibles pour la visualisation"""
try:
return self.filter_for_visualisations[visname].EXPORT_COMMANDS
except AttributeError:
return []
def get_programs(self):
"""Renvoie un ensemble de noms de programmes disponibles"""
return self.programs.keys()
def get_filterforvisualisations(self):
"""Renvoie un ensemble de noms de visulaisations disponibles"""
return self.filter_for_visualisations.keys()
def execute_repositorycommand(self, reponame, command, **args):
"""Exécutez la commande spécifiée sur le référentiel spécifié."""
if not command in [c[0] for c in self.get_repositorycommands(reponame)]:
raise ValueError("Invalid command {} for repository {}".format(command, reponame))
# classe de répertoire de chargement
repo = self.get_datarepository(reponame)
fns = inspect.getmembers(repo, lambda x: inspect.ismethod(x) and x.__name__ == command)
if len(fns) != 1:
raise RuntimeError("Unable to find method {} in repository {}: {}".format(command, reponame, repo))
with repo:
# appel de commande
fns[0][1](**args)
def execute_programcommand(self, progname, command, **args):
"""Exécuter la commande spécifiée sur le programme spécifié"""
prog = self.get_program(progname)
fns = inspect.getmembers(prog, lambda x: inspect.isfunction(x) and x.__name__ == command)
if len(fns) != 1:
raise RuntimeError("Unable to find function {} in program {}: {}".format(command, progname, prog))
# obtenir des entrées et des sorties
inputs = {}
outputs = {}
for inp in prog.INPUTS:
inputs[inp] = self.get_datarepository(inp, readonly=True)
for out in prog.OUTPUTS:
outputs[out] = self.get_datarepository(out)
with contextlib.ExitStack() as stack:
# préparer les référentiels
for i in inputs:
stack.enter_context(inputs[i])
for i in outputs:
stack.enter_context(outputs[i])
fns[0][1](inputs, outputs, **args)
def execute_filterforvisualisationcommand(self, visname, command, **args):
"""Exécuter la commande spécifiée sur la visualisation spécifiée"""
vis = self.get_filterforvisualisation(visname)
fns = inspect.getmembers(vis, lambda x: inspect.isfunction(x) and x.__name__ == command)
if len(fns) != 1:
raise RuntimeError("Unable to find function {} in visualisation {}: {}".format(command, visname, vis))
fns[0][1](**args)
def get_datarepository(self, name, readonly=False):
"""Renvoie une instance chargée du référentiel de données spécifié."""
return self.repo_drivers[self.repo_config[name]['type']].load(self.repo_config[name], readonly=readonly)
def get_program(self, name):
"""Renvoie le module de programme spécifié."""
return self.programs[name]
def get_filterforvisualisation(self, name):
"""Renvoie le module de visualisation spécifié."""
return self.filter_for_visualisations[name]