keeweb/app/scripts/plugins/plugin-manager.js

139 lines
4.4 KiB
JavaScript
Raw Normal View History

2017-02-19 10:29:18 +01:00
const Backbone = require('backbone');
2017-02-18 23:46:59 +01:00
const Plugin = require('./plugin');
2017-02-19 10:29:18 +01:00
const PluginCollection = require('./plugin-collection');
2017-02-19 18:51:52 +01:00
const SettingsStore = require('../comp/settings-store');
const Logger = require('../util/logger');
2017-02-18 23:46:59 +01:00
2017-02-19 10:29:18 +01:00
const PluginManager = Backbone.Model.extend({
defaults: {
2017-02-19 12:40:21 +01:00
installing: null,
lastInstall: null,
2017-02-19 10:29:18 +01:00
plugins: new PluginCollection()
},
2017-02-18 23:46:59 +01:00
2017-02-19 18:51:52 +01:00
logger: new Logger('plugin-mgr'),
init() {
const ts = this.logger.ts();
return SettingsStore.load('plugins').then(state => {
2017-02-19 20:09:09 +01:00
if (!state || !state.plugins || !state.plugins.length) {
2017-02-19 18:51:52 +01:00
return;
}
const promises = state.plugins.map(plugin => this.loadPlugin(plugin));
return Promise.all(promises).then(loadedPlugins => {
const plugins = this.get('plugins');
plugins.add(loadedPlugins.filter(plugin => plugin));
this.logger.info(`Loaded ${plugins.length} plugins`, this.logger.ts(ts));
});
});
},
2017-05-13 22:36:07 +02:00
install(url, expectedManifest) {
2017-02-19 12:40:21 +01:00
const lastInstall = { url, dt: new Date() };
this.set({ installing: url, lastInstall: lastInstall });
2017-05-13 22:36:07 +02:00
return Plugin.loadFromUrl(url, expectedManifest).then(plugin => {
2017-04-08 23:35:26 +02:00
return this.uninstall(plugin.id).then(() => {
2017-04-27 23:49:32 +02:00
return plugin.install(true).then(() => {
2017-02-19 15:57:41 +01:00
this.get('plugins').push(plugin);
2017-02-19 12:40:21 +01:00
this.set({ installing: null });
2017-02-19 18:51:52 +01:00
this.saveState();
2017-02-19 10:29:18 +01:00
});
2017-04-08 23:35:26 +02:00
});
}).catch(e => {
2017-02-19 12:40:21 +01:00
this.set({ installing: null, lastInstall: _.extend(lastInstall, { error: e.toString() }) });
2017-02-19 10:29:18 +01:00
throw e;
2017-02-18 23:46:59 +01:00
});
2017-02-19 12:40:21 +01:00
},
uninstall(id) {
const plugins = this.get('plugins');
const plugin = plugins.get(id);
if (!plugin) {
return Promise.resolve();
}
2017-04-26 22:06:07 +02:00
this.trigger('change');
2017-02-19 12:40:21 +01:00
return plugin.uninstall().then(() => {
plugins.remove(id);
2017-04-26 22:06:07 +02:00
this.trigger('change');
this.saveState();
});
},
disable(id) {
const plugins = this.get('plugins');
const plugin = plugins.get(id);
if (!plugin || plugin.get('status') !== Plugin.STATUS_ACTIVE) {
return Promise.resolve();
}
this.trigger('change');
return plugin.disable().then(() => {
this.trigger('change');
this.saveState();
});
},
activate(id) {
const plugins = this.get('plugins');
const plugin = plugins.get(id);
if (!plugin || plugin.get('status') === Plugin.STATUS_ACTIVE) {
return Promise.resolve();
}
this.trigger('change');
return plugin.install(true).then(() => {
this.trigger('change');
2017-02-19 19:14:09 +01:00
this.saveState();
2017-02-19 12:40:21 +01:00
});
2017-02-19 18:51:52 +01:00
},
2017-04-08 23:35:26 +02:00
update(id) {
const plugins = this.get('plugins');
const oldPlugin = plugins.get(id);
2017-04-27 14:50:36 +02:00
const validStatuses = [Plugin.STATUS_ACTIVE, Plugin.STATUS_INACTIVE, Plugin.STATUS_NONE, Plugin.STATUS_ERROR, Plugin.STATUS_INVALID];
if (!oldPlugin || validStatuses.indexOf(oldPlugin.get('status')) < 0) {
2017-04-08 23:35:26 +02:00
return Promise.reject();
}
const url = oldPlugin.get('url');
2017-04-26 22:06:07 +02:00
this.trigger('change');
2017-04-08 23:35:26 +02:00
return Plugin.loadFromUrl(url).then(newPlugin => {
return oldPlugin.update(newPlugin).then(() => {
2017-04-26 22:06:07 +02:00
this.trigger('change');
2017-04-08 23:35:26 +02:00
this.saveState();
}).catch(e => {
2017-04-26 22:06:07 +02:00
this.trigger('change');
2017-04-08 23:35:26 +02:00
throw e;
});
}).catch(e => {
2017-04-26 22:06:07 +02:00
this.trigger('change');
2017-04-08 23:35:26 +02:00
throw e;
});
},
2017-02-19 18:51:52 +01:00
loadPlugin(desc) {
2017-04-08 23:35:26 +02:00
const plugin = new Plugin({
manifest: desc.manifest,
url: desc.url,
local: true
});
2017-04-26 22:06:07 +02:00
return plugin.install(desc.enabled)
2017-02-19 18:51:52 +01:00
.then(() => plugin)
2017-04-08 17:34:27 +02:00
.catch(() => plugin);
2017-02-19 18:51:52 +01:00
},
saveState() {
SettingsStore.save('plugins', {
plugins: this.get('plugins').map(plugin => ({
manifest: plugin.get('manifest'),
2017-04-26 22:06:07 +02:00
url: plugin.get('url'),
enabled: plugin.get('status') === 'active'
2017-02-19 18:51:52 +01:00
}))
});
2017-04-26 22:06:07 +02:00
},
getStatus(id) {
const plugin = this.get('plugins').get(id);
return plugin ? plugin.get('status') : '';
2017-02-18 23:46:59 +01:00
}
2017-02-19 10:29:18 +01:00
});
2017-02-18 23:46:59 +01:00
2017-02-19 10:29:18 +01:00
module.exports = new PluginManager();