30
from GTG.tools.logger import Log
31
from GTG.tools.borg import Borg
30
from GTG.tools.logger import Log
31
from GTG.tools.borg import Borg
32
32
from GTG.backends.genericbackend import GenericBackend
33
from GTG.core import firstrun_tasks
34
from GTG.tools import cleanxml
35
from GTG.core import CoreConfig
33
from GTG.core import firstrun_tasks
34
from GTG.tools import cleanxml
35
from GTG.core import CoreConfig
38
38
class BackendFactory(Borg):
54
53
super(BackendFactory, self).__init__()
55
54
if hasattr(self, "backend_modules"):
56
#This object has already been constructed
55
# This object has already been constructed
58
57
self.backend_modules = {}
59
#Look for backends in the GTG/backends dir
58
# Look for backends in the GTG/backends dir
60
59
this_dir = os.path.dirname(__file__)
61
backend_files = filter(lambda f: f.endswith(".py") and \
62
f.startswith(self.BACKEND_PREFIX), \
60
backend_files = filter(lambda f: f.endswith(".py") and
61
f.startswith(self.BACKEND_PREFIX),
65
64
module_names = map(lambda f: f.replace(".py", ""), backend_files)
66
65
Log.debug("Backends found: " + str(module_names))
66
# Load backend modules
68
67
for module_name in module_names:
69
68
extended_module_name = "GTG.backends." + module_name
71
70
__import__(extended_module_name)
72
71
except ImportError, exception:
73
#Something is wrong with this backend, skipping
74
Log.warning("Backend %s could not be loaded: %s" % \
75
(module_name, str(exception)))
72
# Something is wrong with this backend, skipping
73
Log.warning("Backend %s could not be loaded: %s" %
74
(module_name, str(exception)))
77
76
except Exception, exception:
78
77
# Other exception log as errors
79
Log.error("Malformated backend %s: %s" % \
80
(module_name, str(exception)))
78
Log.error("Malformated backend %s: %s" %
79
(module_name, str(exception)))
83
82
self.backend_modules[module_name] = \
84
sys.modules[extended_module_name]
83
sys.modules[extended_module_name]
86
85
def get_backend(self, backend_name):
101
100
return self.backend_modules
103
def get_new_backend_dict(self, backend_name, additional_parameters = {}):
102
def get_new_backend_dict(self, backend_name, additional_parameters={}):
105
104
Constructs a new backend initialization dictionary. In more
106
105
exact terms, creates a dictionary, containing all the necessary
112
111
module = self.get_backend(backend_name)
113
#Different pids are necessary to discern between backends of the same
112
# Different pids are necessary to discern between backends of the same
115
114
parameters = module.Backend.get_static_parameters()
116
#we all the parameters and their default values in dic
115
# we all the parameters and their default values in dic
117
116
for param_name, param_dic in parameters.iteritems():
118
117
dic[param_name] = param_dic[GenericBackend.PARAM_DEFAULT_VALUE]
119
118
dic["pid"] = str(uuid.uuid4())
134
133
Returns the backend instance, or None is something goes wrong
136
135
if not "module" in dic or not "xmlobject" in dic:
137
Log.debug("Malformed backend configuration found! %s" % \
136
Log.debug("Malformed backend configuration found! %s" %
139
138
module = self.get_backend(dic["module"])
141
Log.debug("could not load module for backend %s" % \
140
Log.debug("could not load module for backend %s" %
144
#we pop the xml object, as it will be redundant when the parameters
143
# we pop the xml object, as it will be redundant when the parameters
145
144
# are set directly in the dict
146
145
xp = dic.pop("xmlobject")
147
#Building the dictionary
146
# Building the dictionary
148
147
parameters_specs = module.Backend.get_static_parameters()
149
148
dic["pid"] = str(xp.getAttribute("pid"))
150
149
for param_name, param_dic in parameters_specs.iteritems():
151
150
if xp.hasAttribute(param_name):
152
#we need to convert the parameter to the right format.
151
# we need to convert the parameter to the right format.
153
152
# we fetch the format from the static_parameters
154
153
param_type = param_dic[GenericBackend.PARAM_TYPE]
155
param_value = GenericBackend.cast_param_type_from_string( \
156
xp.getAttribute(param_name), param_type)
154
param_value = GenericBackend.cast_param_type_from_string(
155
xp.getAttribute(param_name), param_type)
157
156
dic[param_name] = param_value
158
#We put the backend itself in the dict
157
# We put the backend itself in the dict
159
158
dic["backend"] = module.Backend(dic)
160
159
return dic["backend"]
162
161
def get_saved_backends_list(self):
163
162
backends_dic = self._read_backend_configuration_file()
165
#Retrocompatibility: default backend has changed name
164
# Retrocompatibility: default backend has changed name
166
165
for dic in backends_dic:
167
166
if dic["module"] == "localfile":
168
167
dic["module"] = "backend_localfile"
170
169
dic["need_conversion"] = \
171
170
dic["xmlobject"].getAttribute("filename")
173
#Now that the backend list is build, we will construct them
172
# Now that the backend list is build, we will construct them
174
173
for dic in backends_dic:
175
174
self.restore_backend_from_xml(dic)
176
#If no backend available, we create a new using localfile. Xmlobject
175
# If no backend available, we create a new using localfile. Xmlobject
177
176
# will be filled in by the backend
178
177
if len(backends_dic) == 0:
179
178
dic = BackendFactory().get_new_backend_dict(
181
180
dic["backend"].this_is_the_first_run(firstrun_tasks.populate())
182
181
backends_dic.append(dic)
183
182
return backends_dic
193
192
# Read configuration file, if it does not exist, create one
194
193
datafile = os.path.join(CoreConfig().get_data_dir(),
195
CoreConfig.DATA_FILE)
194
CoreConfig.DATA_FILE)
196
195
doc, configxml = cleanxml.openxmlfile(datafile, "config")
197
196
xmlproject = doc.getElementsByTagName("backend")
198
197
# collect configured backends
199
return [{"xmlobject": xp, \
198
return [{"xmlobject": xp,
200
199
"module": xp.getAttribute("module")} for xp in xmlproject]