1 import config
2 import db
3 import os
4 from shutil import rmtree
5
6 from plugins.model import Plugin
7
23
25 '''
26 Enables a plugin if all the deps are met. Else it raises UnmetDependencyException.
27 Returns the list of enabled plugins. In this case, enable means this plugins will be enabled
28 in the future: this function will only be called when the user enables a plugin in the
29 pluginmanager.PluginListView.
30 '''
31 enabled_plugins = []
32 plugin = self.get_plugin_by_name(name)
33 if plugin == None:
34 return enabled_plugins
35
36 plugins_deps = self.__get_dependencies(plugin)
37
38 for plugin_dep in plugins_deps:
39 if not plugin_dep.is_enabled():
40 self.__enable_plugin(plugin_dep)
41 enabled_plugins.append(plugin_dep)
42
43 return enabled_plugins
44
46 '''
47 Disables a plugin and all plugins that have given plugin as a dependency.
48 Returns the list of disabled plugins. In this case, disable means this plugins will be disabled
49 in the future: this function will only be called when the user disables a plugin in the
50 pluginmanager.PluginListView.
51 '''
52 disabled_plugins = []
53 plugin = self.get_plugin_by_name(name)
54 if plugin == None:
55 return disabled_plugins
56
57 plugins_deps = self.__get_reverse_dependencies(plugin)
58
59 for plugin_dep in plugins_deps:
60 if plugin_dep.is_enabled():
61 self.__disable_plugin(plugin_dep)
62 disabled_plugins.append(plugin_dep)
63
64 return disabled_plugins
65
67 '''
68 Uninstall the given plugin. There are two ways of uninstall:
69 * When delete_files is false, then this function only deletes
70 all plugin's data in the db. In this way you can reinstall the
71 plugin when you want.
72 * When delete_files is true, then this function delete all plugin's
73 data in the db and plugin's directory. In this way all data is
74 deleted, so you have to get the whole plugin to reinstall.
75
76 Either way, this function always removes the installed files in static/
77 and templates/ for this plugin.
78
79 Before uninstalling a plugin, it MUST be disabled and obviously all
80 the plugins that have the plugin as a dependency.
81 '''
82 plugin = self.get_plugin_by_name(name)
83 if plugin.enabled == True:
84 return False
85
86 plugin.uninstall()
87
88
89 orm = db.connect()
90 query = orm.query(Plugin).filter(Plugin.name == name)
91 if query.count() == 1:
92 orm.delete(query.first())
93 orm.commit()
94
95 static_dir = os.path.join(config.curdir, 'static/plugins', name)
96 if os.path.islink(static_dir):
97 os.unlink(static_dir)
98 templates_dir = os.path.join(config.curdir, 'templates/plugins', name)
99 if os.path.islink(templates_dir):
100 os.unlink(templates_dir)
101
102
103 if delete_files:
104 path = os.path.join(config.pluginsdir, name)
105 rmtree(path)
106
107 self.plugins.remove(plugin)
108
109
110 pmodule = __import__('pluginmanager.plugins.%s.%s' % (plugin.name, 'model'), fromlist=["true"])
111 db.drop_from_model(pmodule)
112
113 return True
114
116 '''
117 Look for new instances in plugins' directory and
118 add to self.plugins.
119 '''
120 plugins_name = (p.name for p in self.plugins)
121
122 for plugin_name in self.__get_plugins_directories():
123 if not plugin_name in plugins_name:
124 instance = self.__instance_plugin(plugin_name)
125 self.plugins.append(instance)
126
128 '''
129 Return the instance of the plugin whose name is given.
130 None is returned if the instance is not found.
131 '''
132 for plugin in self.plugins:
133 if plugin.name == name:
134 return plugin
135 return None
136
138 '''
139 Return a instance list of the enabled plugins.
140 '''
141 return (i for i in self.plugins if i.is_enabled())
142
160
161
163 '''
164 Called only by __enable_plugin when a plugin has not been installed before.
165
166 * Creates the tables in the database from the plugin model
167 * installs the static/ and templates/ plugin directories in
168 static/plugins/<pluginname> and templates/plugins/<pluginname>/
169 * calls to the install() function of the given plugin
170 '''
171
172
173 orm = db.connect()
174 dbplugin = Plugin(plugin)
175 dbplugin.enabled = True
176 orm.add(dbplugin)
177 orm.commit()
178 pmodule = __import__('pluginmanager.plugins.%s.%s' % (plugin.name, 'model'), fromlist=["true"])
179 db.create_from_model(pmodule)
180
181
182 plugin_static_dir = os.path.join(config.pluginsdir, plugin.name, 'static')
183 if os.path.isdir(plugin_static_dir):
184
185 plugins_static_dir = os.path.join(config.curdir, 'static/plugins')
186 if not os.path.isdir(plugins_static_dir):
187
188
189 os.mkdir(plugins_static_dir)
190
191
192 new_static_dir = os.path.join(plugins_static_dir, plugin.name)
193 os.symlink(plugin_static_dir, new_static_dir)
194
195
196 plugin_templates_dir = os.path.join(config.pluginsdir, plugin.name, 'templates')
197 if os.path.isdir(plugin_templates_dir):
198 plugins_templates_dir = os.path.join(config.curdir, 'templates/plugins')
199 if not os.path.isdir(plugins_templates_dir):
200 os.mkdir(plugins_templates_dir)
201 new_templates_dir = os.path.join(plugins_templates_dir, plugin.name)
202 os.symlink(plugin_templates_dir, new_templates_dir)
203
204 plugin.install()
205
215
218 '''
219 Recursively returns the list of the dependencies of the given plugins.
220 If any of the dependencies is not met then it will raise a
221 UnMetDependencyException.
222
223 The list of plugins dependencies will include the plugin itself which
224 will be at the end of the list, and the list of dependencies will be
225 ordered in such a way that they can be safely activated one by one,
226 because any of the listed plugins will be preceded by its dependencies.
227
228 It will only be called by enable_plugin().
229 '''
230
231 if checked_deps is None: checked_deps = []
232 if checked_plugins is None: checked_plugins = []
233
234
235
236 checked_plugins.append(plugin.name)
237 for dep in plugin.get_dependencies():
238 if dep.dependon in (i.name for i in checked_deps):
239 continue
240 if dep.dependon in checked_plugins:
241 continue
242 if not dep.is_met():
243
244
245 pass
246 self.__get_dependencies(dep.get_plugin(), checked_deps,
247 checked_plugins)
248
249 checked_deps.append(plugin)
250 return checked_deps
251
254 '''
255 Recursively returns the list of the reverse dependencies of the given
256 plugins.
257
258 The list of plugins dependencies will include the plugin itself which
259 will be at the end of the list, and the list of dependencies will be
260 ordered in such a way that they can be safely desactivated one by one,
261 because any of the listed plugins will be preceded by its dependencies.
262
263 It will only be called by disable_plugin().
264 '''
265
266 if checked_deps is None: checked_deps = []
267 if checked_plugins is None: checked_plugins = []
268
269
270 checked_plugins.append(plugin.name)
271
272 for p in self.get_enabled_plugins():
273
274 if p in checked_plugins:
275 continue
276 if p.name in checked_plugins:
277 continue
278
279 for dep in p.get_dependencies():
280 if dep.is_met_by(plugin):
281 self.__get_reverse_dependencies(self, p, checked_deps,
282 checked_plugins)
283
284 checked_deps.append(plugin)
285 return checked_deps
286
293
295 '''
296 Return the list of the directories of plugins that there are
297 in the plugins directory.
298 '''
299 return (i for i in os.listdir(config.pluginsdir)
300 if os.path.isdir(os.path.join(config.pluginsdir, i)))
301