MrDraw/src/octoprint/plugins/pluginmanager/static/js/pluginmanager.js

1203 lines
49 KiB
JavaScript
Raw Normal View History

(function (global, factory) {
if (typeof define === "function" && define.amd) {
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
define(["OctoPrintClient"], factory);
} else {
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
factory(global.OctoPrintClient);
}
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
})(this, function(OctoPrintClient) {
var OctoPrintPluginManagerClient = function(base) {
this.base = base;
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
OctoPrintPluginManagerClient.prototype.get = function(refresh, opts) {
var refresh_repo, refresh_notices;
if (_.isPlainObject(refresh)) {
refresh_repo = refresh.repo || false;
refresh_notices = refresh.notices || false;
} else {
refresh_repo = refresh;
refresh_notices = false;
}
var query = [];
if (refresh_repo) query.push("refresh_repository=true");
if (refresh_notices) query.push("refresh_notices=true");
return this.base.get(this.base.getSimpleApiUrl("pluginmanager") + ((query.length) ? "?" + query.join("&") : ""), opts);
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
OctoPrintPluginManagerClient.prototype.getWithRefresh = function(opts) {
return this.get(true, opts);
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
OctoPrintPluginManagerClient.prototype.getWithoutRefresh = function(opts) {
return this.get(false, opts);
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
OctoPrintPluginManagerClient.prototype.install = function(pluginUrl, dependencyLinks, opts) {
var data = {
url: pluginUrl,
dependency_links: !!dependencyLinks
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
return this.base.simpleApiCommand("pluginmanager", "install", data, opts);
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
OctoPrintPluginManagerClient.prototype.reinstall = function(plugin, pluginUrl, dependencyLinks, opts) {
var data = {
url: pluginUrl,
dependency_links: !!dependencyLinks,
reinstall: plugin,
force: true
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
return this.base.simpleApiCommand("pluginmanager", "install", data, opts);
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
OctoPrintPluginManagerClient.prototype.uninstall = function(plugin, opts) {
var data = {
plugin: plugin
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
return this.base.simpleApiCommand("pluginmanager", "uninstall", data, opts);
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
OctoPrintPluginManagerClient.prototype.enable = function(plugin, opts) {
var data = {
plugin: plugin
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
return this.base.simpleApiCommand("pluginmanager", "enable", data, opts);
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
OctoPrintPluginManagerClient.prototype.disable = function(plugin, opts) {
var data = {
plugin: plugin
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
return this.base.simpleApiCommand("pluginmanager", "disable", data, opts);
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
OctoPrintPluginManagerClient.prototype.upload = function(file) {
return this.base.upload(this.base.getBlueprintUrl("pluginmanager") + "upload_archive", file);
};
Allow multiple instances of the JS client We now have a global OctoPrintClient, which is the class from which all clients are derived, and a global OctoPrint, which is a single instance already setup and ready to use in case we only need one. It would be cleaner to have clients create that singular instance themselves, but we need to maintain backward compatibility for now with how we established the client to work with the 1.3.0 release. New clients can be create with client = new OctoPrintClient({ /* options */ }); Alternatively the options can be left out and set at a later point: client = new OctoPrintClient(); /* ... */ client.options = { /* options */ }; Individual client components register themselves with OctoPrintClient via OctoPrintClient.registerComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.<name>", e.g. "OctoPrint.files". Plugin components register themselves with OctoPrintClient via OctoPrintClient.registerPluginComponent(name, component) from the component JS files. Just like before their instances are then available in the individual client instances under "<client>.plugins .<name>", e.g. "OctoPrint.plugins.softwareupdate". This should make it possible to create dashboard pages utilizing the JS client that monitor the status of multiple OctoPrint instances, without workarounds such as having to swap out the options globally before each request. See #1681 for the corresponding discussion.
2017-01-20 10:34:19 +00:00
OctoPrintClient.registerPluginComponent("pluginmanager", OctoPrintPluginManagerClient);
return OctoPrintPluginManagerClient;
});
$(function() {
function PluginManagerViewModel(parameters) {
var self = this;
self.loginState = parameters[0];
self.settingsViewModel = parameters[1];
self.printerState = parameters[2];
self.systemViewModel = parameters[3];
self.config_repositoryUrl = ko.observable();
self.config_repositoryTtl = ko.observable();
self.config_noticesUrl = ko.observable();
self.config_noticesTtl = ko.observable();
self.config_pipAdditionalArgs = ko.observable();
self.config_pipForceUser = ko.observable();
self.configurationDialog = $("#settings_plugin_pluginmanager_configurationdialog");
self.plugins = new ItemListHelper(
"plugin.pluginmanager.installedplugins",
{
"name": function (a, b) {
// sorts ascending
if (a["name"].toLocaleLowerCase() < b["name"].toLocaleLowerCase()) return -1;
if (a["name"].toLocaleLowerCase() > b["name"].toLocaleLowerCase()) return 1;
return 0;
}
},
{
},
"name",
[],
[],
5
);
self.repositoryplugins = new ItemListHelper(
"plugin.pluginmanager.repositoryplugins",
{
"title": function (a, b) {
// sorts ascending
if (a["title"].toLocaleLowerCase() < b["title"].toLocaleLowerCase()) return -1;
if (a["title"].toLocaleLowerCase() > b["title"].toLocaleLowerCase()) return 1;
return 0;
},
"published": function (a, b) {
// sorts descending
if (a["published"].toLocaleLowerCase() > b["published"].toLocaleLowerCase()) return -1;
if (a["published"].toLocaleLowerCase() < b["published"].toLocaleLowerCase()) return 1;
return 0;
}
},
{
"filter_installed": function(plugin) {
return !self.installed(plugin);
},
"filter_incompatible": function(plugin) {
return plugin.is_compatible.octoprint && plugin.is_compatible.os;
}
},
"title",
["filter_installed", "filter_incompatible"],
[],
0
);
self.uploadElement = $("#settings_plugin_pluginmanager_repositorydialog_upload");
self.uploadButton = $("#settings_plugin_pluginmanager_repositorydialog_upload_start");
self.repositoryAvailable = ko.observable(false);
self.repositorySearchQuery = ko.observable();
self.repositorySearchQuery.subscribe(function() {
self.performRepositorySearch();
});
self.installUrl = ko.observable();
self.uploadFilename = ko.observable();
self.loglines = ko.observableArray([]);
self.installedPlugins = ko.observableArray([]);
self.followDependencyLinks = ko.observable(false);
self.pipAvailable = ko.observable(false);
self.pipVersion = ko.observable();
self.pipInstallDir = ko.observable();
self.pipUseUser = ko.observable();
self.pipVirtualEnv = ko.observable();
self.pipAdditionalArgs = ko.observable();
self.pipPython = ko.observable();
self.safeMode = ko.observable();
self.pipUseUserString = ko.pureComputed(function() {
return self.pipUseUser() ? "yes" : "no";
});
self.pipVirtualEnvString = ko.pureComputed(function() {
return self.pipVirtualEnv() ? "yes" : "no";
});
self.working = ko.observable(false);
self.workingTitle = ko.observable();
self.workingDialog = undefined;
self.workingOutput = undefined;
self.restartCommandSpec = undefined;
self.systemViewModel.systemActions.subscribe(function() {
var lastResponse = self.systemViewModel.lastCommandResponse;
if (!lastResponse || !lastResponse.core) {
self.restartCommandSpec = undefined;
return;
}
var restartSpec = _.filter(lastResponse.core, function(spec) { return spec.action == "restart" });
self.restartCommandSpec = restartSpec != undefined && restartSpec.length > 0 ? restartSpec[0] : undefined;
});
self.notifications = [];
self.noticeNotifications = [];
self.hiddenNoticeNotifications = {};
self.noticeCount = ko.observable(0);
self.noticeCountText = ko.pureComputed(function() {
var count = self.noticeCount();
if (count == 0) {
return gettext("There are no plugin notices. Great!");
} else if (count == 1) {
return gettext("There is a plugin notice for one of your installed plugins.");
} else {
return _.sprintf(gettext("There are %(count)d plugin notices for one or more of your installed plugins."), {count: count});
}
});
self.enableManagement = ko.pureComputed(function() {
return !self.printerState.isPrinting();
});
self.enableToggle = function(data) {
var command = self._getToggleCommand(data);
return self.enableManagement() && (command == "disable" || !data.safe_mode_victim || data.safe_mode_enabled) && data.key != 'pluginmanager';
};
self.enableUninstall = function(data) {
return self.enableManagement()
&& (data.origin != "entry_point" || self.pipAvailable())
&& data.managable
&& !data.bundled
&& data.key != 'pluginmanager'
&& !data.pending_uninstall;
};
self.enableRepoInstall = function(data) {
return self.enableManagement() && self.pipAvailable() && !self.safeMode() && self.isCompatible(data);
};
self.invalidUrl = ko.pureComputed(function() {
var url = self.installUrl();
return url !== undefined && url.trim() != "" && !(_.startsWith(url.toLocaleLowerCase(), "http://") || _.startsWith(url.toLocaleLowerCase(), "https://"));
});
self.enableUrlInstall = ko.pureComputed(function() {
var url = self.installUrl();
return self.enableManagement() && self.pipAvailable() && !self.safeMode() && url !== undefined && url.trim() != "" && !self.invalidUrl();
});
self.invalidArchive = ko.pureComputed(function() {
var name = self.uploadFilename();
return name !== undefined && !(_.endsWith(name.toLocaleLowerCase(), ".zip") || _.endsWith(name.toLocaleLowerCase(), ".tar.gz") || _.endsWith(name.toLocaleLowerCase(), ".tgz") || _.endsWith(name.toLocaleLowerCase(), ".tar"));
});
self.enableArchiveInstall = ko.pureComputed(function() {
var name = self.uploadFilename();
return self.enableManagement() && self.pipAvailable() && !self.safeMode() && name !== undefined && name.trim() != "" && !self.invalidArchive();
});
self.uploadElement.fileupload({
dataType: "json",
maxNumberOfFiles: 1,
autoUpload: false,
add: function(e, data) {
if (data.files.length == 0) {
return false;
}
self.uploadFilename(data.files[0].name);
self.uploadButton.unbind("click");
self.uploadButton.bind("click", function() {
self._markWorking(gettext("Installing plugin..."), gettext("Installing plugin from uploaded archive..."));
data.formData = {
dependency_links: self.followDependencyLinks()
};
data.submit();
return false;
});
},
done: function(e, data) {
var response = data.result;
if (response.result) {
self._markDone();
} else {
self._markDone(response.reason);
}
self.uploadButton.unbind("click");
self.uploadFilename(undefined);
},
fail: function(e, data) {
new PNotify({
title: gettext("Something went wrong"),
text: gettext("Please consult octoprint.log for details"),
type: "error",
hide: false
});
self._markDone("Could not install plugin, unknown error.");
self.uploadButton.unbind("click");
self.uploadFilename(undefined);
}
});
self.performRepositorySearch = function() {
var query = self.repositorySearchQuery();
if (query !== undefined && query.trim() != "") {
query = query.toLocaleLowerCase();
self.repositoryplugins.changeSearchFunction(function(entry) {
return entry && (entry["title"].toLocaleLowerCase().indexOf(query) > -1 || entry["description"].toLocaleLowerCase().indexOf(query) > -1);
});
} else {
self.repositoryplugins.resetSearch();
}
return false;
};
self.fromResponse = function(data, options) {
self._fromPluginsResponse(data.plugins, options);
self._fromRepositoryResponse(data.repository, options);
self._fromPipResponse(data.pip, options);
self.safeMode(data.safe_mode || false);
};
self._fromPluginsResponse = function(data, options) {
var evalNotices = options.eval_notices || false;
var ignoreNoticeHidden = options.ignore_notice_hidden || false;
var ignoreNoticeIgnored = options.ignore_notice_ignored || false;
if (evalNotices) self._removeAllNoticeNotifications();
var installedPlugins = [];
var noticeCount = 0;
_.each(data, function(plugin) {
installedPlugins.push(plugin.key);
if (evalNotices && plugin.notifications && plugin.notifications.length) {
_.each(plugin.notifications, function(notification) {
noticeCount++;
if (!ignoreNoticeIgnored && self._isNoticeNotificationIgnored(plugin.key, notification.date)) return;
if (!ignoreNoticeHidden && self._isNoticeNotificationHidden(plugin.key, notification.date)) return;
self._showPluginNotification(plugin, notification);
});
}
});
if (evalNotices) self.noticeCount(noticeCount);
self.installedPlugins(installedPlugins);
self.plugins.updateItems(data);
};
self._fromRepositoryResponse = function(data) {
self.repositoryAvailable(data.available);
if (data.available) {
self.repositoryplugins.updateItems(data.plugins);
} else {
self.repositoryplugins.updateItems([]);
}
};
self._fromPipResponse = function(data) {
self.pipAvailable(data.available);
if (data.available) {
self.pipVersion(data.version);
self.pipInstallDir(data.install_dir);
self.pipUseUser(data.use_user);
self.pipVirtualEnv(data.virtual_env);
self.pipAdditionalArgs(data.additional_args);
self.pipPython(data.python);
} else {
self.pipVersion(undefined);
self.pipInstallDir(undefined);
self.pipUseUser(undefined);
self.pipVirtualEnv(undefined);
self.pipAdditionalArgs(undefined);
}
};
self.requestData = function(options) {
if (!self.loginState.isAdmin()) {
return;
}
if (!_.isPlainObject(options)) {
options = {
refresh_repo: options,
refresh_notices: false,
eval_notices: false
};
}
options.refresh_repo = options.refresh_repo || false;
options.refresh_notices = options.refresh_notices || false;
options.eval_notices = options.eval_notices || false;
OctoPrint.plugins.pluginmanager.get({repo: options.refresh_repo, notices: options.refresh_notices})
.done(function(data) {
self.fromResponse(data, options);
});
};
self.togglePlugin = function(data) {
if (!self.loginState.isAdmin()) {
return;
}
if (!self.enableManagement()) {
return;
}
if (data.key == "pluginmanager") return;
var onSuccess = function() {
self.requestData();
},
onError = function() {
new PNotify({
title: gettext("Something went wrong"),
text: gettext("Please consult octoprint.log for details"),
type: "error",
hide: false
})
};
if (self._getToggleCommand(data) == "enable") {
if (data.safe_mode_victim && !data.safe_mode_enabled) return;
OctoPrint.plugins.pluginmanager.enable(data.key)
.done(onSuccess)
.fail(onError);
} else {
var perform = function() {
OctoPrint.plugins.pluginmanager.disable(data.key)
.done(onSuccess)
.fail(onError);
};
if (data.disabling_discouraged) {
var message = _.sprintf(gettext("You are about to disable \"%(name)s\"."), {name: data.name})
+ "</p><p>" + data.disabling_discouraged;
showConfirmationDialog({
title: gettext("This is not recommended"),
message: message,
question: gettext("Do you still want to disable it?"),
cancel: gettext("Keep enabled"),
proceed: gettext("Disable anyway"),
onproceed: perform
})
} else {
perform();
}
}
};
self.showRepository = function() {
self.repositoryDialog.modal("show");
};
self.pluginDetails = function(data) {
window.open(data.page);
};
self.installFromRepository = function(data) {
if (!self.loginState.isAdmin()) {
return;
}
if (!self.enableManagement()) {
return;
}
self.installPlugin(data.archive, data.title, (self.installed(data) ? data.id : undefined), data.follow_dependency_links || self.followDependencyLinks());
};
self.installPlugin = function(url, name, reinstall, followDependencyLinks) {
if (!self.loginState.isAdmin()) {
return;
}
if (!self.enableManagement()) {
return;
}
if (url === undefined) {
url = self.installUrl();
}
if (!url) return;
if (followDependencyLinks === undefined) {
followDependencyLinks = self.followDependencyLinks();
}
var workTitle, workText;
if (!reinstall) {
workTitle = gettext("Installing plugin...");
if (name) {
workText = _.sprintf(gettext("Installing plugin \"%(name)s\" from %(url)s..."), {url: url, name: name});
} else {
workText = _.sprintf(gettext("Installing plugin from %(url)s..."), {url: url});
}
} else {
workTitle = gettext("Reinstalling plugin...");
workText = _.sprintf(gettext("Reinstalling plugin \"%(name)s\" from %(url)s..."), {url: url, name: name});
}
self._markWorking(workTitle, workText);
var onSuccess = function(response) {
if (response.result) {
self._markDone();
} else {
self._markDone(response.reason)
}
self.requestData();
self.installUrl("");
},
onError = function() {
self._markDone("Could not install plugin, unknown error, please consult octoprint.log for details");
new PNotify({
title: gettext("Something went wrong"),
text: gettext("Please consult octoprint.log for details"),
type: "error",
hide: false
});
};
if (reinstall) {
OctoPrint.plugins.pluginmanager.reinstall(reinstall, url, followDependencyLinks)
.done(onSuccess)
.fail(onError)
.always(onAlways);
} else {
OctoPrint.plugins.pluginmanager.install(url, followDependencyLinks)
.done(onSuccess)
.fail(onError)
.always(onAlways);
}
};
self.uninstallPlugin = function(data) {
if (!self.loginState.isAdmin()) {
return;
}
if (!self.enableManagement()) {
return;
}
if (data.bundled) return;
if (data.key == "pluginmanager") return;
self._markWorking(gettext("Uninstalling plugin..."), _.sprintf(gettext("Uninstalling plugin \"%(name)s\""), {name: data.name}));
OctoPrint.plugins.pluginmanager.uninstall(data.key)
.done(function() {
self.requestData();
})
.fail(function() {
new PNotify({
title: gettext("Something went wrong"),
text: gettext("Please consult octoprint.log for details"),
type: "error",
hide: false
});
})
.always(function() {
self._markDone();
});
};
self.refreshRepository = function() {
if (!self.loginState.isAdmin()) {
return;
}
self.requestData({refresh_repo: true});
};
self.refreshNotices = function() {
if (!self.loginState.isAdmin()) {
return;
}
self.requestData({refresh_notices: true, eval_notices: true, ignore_notice_hidden: true, ignore_notice_ignored: true});
};
self.reshowNotices = function() {
if (!self.loginState.isAdmin()) {
return;
}
self.requestData({eval_notices: true, ignore_notice_hidden: true, ignore_notice_ignored: true});
};
self.showPluginSettings = function() {
self._copyConfig();
self.configurationDialog.modal();
};
self.savePluginSettings = function() {
var repository = self.config_repositoryUrl();
if (repository != undefined && repository.trim() == "") {
repository = null;
}
var repositoryTtl;
try {
repositoryTtl = parseInt(self.config_repositoryTtl());
} catch (ex) {
repositoryTtl = null;
}
var notices = self.config_noticesUrl();
if (notices != undefined && notices.trim() == "") {
notices = null;
}
var noticesTtl;
try {
noticesTtl = parseInt(self.config_noticesTtl());
} catch (ex) {
noticesTtl = null;
}
var pipArgs = self.config_pipAdditionalArgs();
if (pipArgs != undefined && pipArgs.trim() == "") {
pipArgs = null;
}
var data = {
plugins: {
pluginmanager: {
repository: repository,
repository_ttl: repositoryTtl,
notices: notices,
notices_ttl: noticesTtl,
pip_args: pipArgs,
pip_force_user: self.config_pipForceUser()
}
}
};
self.settingsViewModel.saveData(data, function() {
self.configurationDialog.modal("hide");
self._copyConfig();
self.requestData({refresh_repo: true, refresh_notices: true, eval_notices: true});
});
};
self._copyConfig = function() {
self.config_repositoryUrl(self.settingsViewModel.settings.plugins.pluginmanager.repository());
self.config_repositoryTtl(self.settingsViewModel.settings.plugins.pluginmanager.repository_ttl());
self.config_noticesUrl(self.settingsViewModel.settings.plugins.pluginmanager.notices());
self.config_noticesTtl(self.settingsViewModel.settings.plugins.pluginmanager.notices_ttl());
self.config_pipAdditionalArgs(self.settingsViewModel.settings.plugins.pluginmanager.pip_args());
self.config_pipForceUser(self.settingsViewModel.settings.plugins.pluginmanager.pip_force_user());
};
self.installed = function(data) {
return _.includes(self.installedPlugins(), data.id);
};
self.isCompatible = function(data) {
return data.is_compatible.octoprint && data.is_compatible.os;
};
self.installButtonText = function(data) {
return self.isCompatible(data) ? (self.installed(data) ? gettext("Reinstall") : gettext("Install")) : (data.disabled ? gettext("Disabled") : gettext("Incompatible"));
};
self._displayNotification = function(response, titleSuccess, textSuccess, textRestart, textReload, titleError, textError) {
var notification;
var beforeClose = function(notification) {
self.notifications = _.without(self.notifications, notification);
};
if (response.result) {
if (response.needs_restart) {
var options = {
title: titleSuccess,
text: textRestart,
buttons: {
closer: true,
sticker: false
},
callbacks: {
before_close: beforeClose
},
hide: false
};
if (self.restartCommandSpec) {
options.confirm = {
confirm: true,
buttons: [{
text: gettext("Restart now"),
click: function () {
showConfirmationDialog({
message: gettext("This will restart your OctoPrint server."),
onproceed: function() {
OctoPrint.system.executeCommand("core", "restart")
.done(function() {
new PNotify({
title: gettext("Restart in progress"),
text: gettext("The server is now being restarted in the background")
})
})
.fail(function() {
new PNotify({
title: gettext("Something went wrong"),
text: gettext("Trying to restart the server produced an error, please check octoprint.log for details. You'll have to restart manually.")
})
});
}
});
}
}]
}
}
notification = PNotify.singleButtonNotify(options);
} else if (response.needs_refresh) {
notification = PNotify.singleButtonNotify({
title: titleSuccess,
text: textReload,
confirm: {
confirm: true,
buttons: [{
text: gettext("Reload now"),
click: function () {
location.reload(true);
}
}]
},
buttons: {
closer: true,
sticker: false
},
callbacks: {
before_close: beforeClose
},
hide: false
})
} else {
notification = new PNotify({
title: titleSuccess,
text: textSuccess,
type: "success",
callbacks: {
before_close: beforeClose
},
hide: false
})
}
} else {
notification = new PNotify({
title: titleError,
text: textError,
type: "error",
callbacks: {
before_close: beforeClose
},
hide: false
});
}
self.notifications.push(notification);
};
self._markWorking = function(title, line) {
self.working(true);
self.workingTitle(title);
self.loglines.removeAll();
self.loglines.push({line: line, stream: "message"});
self._scrollWorkingOutputToEnd();
self.workingDialog.modal({keyboard: false, backdrop: "static", show: true});
};
self._markDone = function(error) {
self.working(false);
if (error) {
self.loglines.push({line: gettext("Error!"), stream: "error"});
self.loglines.push({line: error, stream: "error"})
} else {
self.loglines.push({line: gettext("Done!"), stream: "message"});
}
self._scrollWorkingOutputToEnd();
};
self._scrollWorkingOutputToEnd = function() {
self.workingOutput.scrollTop(self.workingOutput[0].scrollHeight - self.workingOutput.height());
};
self._getToggleCommand = function(data) {
var disable = (data.enabled || data.pending_enable || (data.safe_mode_victim && data.safe_mode_enabled)) && !data.pending_disable;
return disable ? "disable" : "enable";
};
self.toggleButtonCss = function(data) {
var icon = self._getToggleCommand(data) == "enable" ? "icon-circle-blank" : "icon-circle";
var disabled = (self.enableToggle(data)) ? "" : " disabled";
return icon + disabled;
};
self.toggleButtonTitle = function(data) {
var command = self._getToggleCommand(data);
if (command == "enable") {
if (data.safe_mode_victim && !data.safe_mode_enabled) {
return gettext("Disabled due to active safe mode");
} else {
return gettext("Enable Plugin");
}
} else {
return gettext("Disable Plugin");
}
};
self.showPluginNotifications = function(plugin) {
if (!plugin.notifications || plugin.notifications.length == 0) return;
self._removeAllNoticeNotificationsForPlugin(plugin.key);
_.each(plugin.notifications, function(notification) {
self._showPluginNotification(plugin, notification);
});
};
self.showPluginNotificationsLinkText = function(plugins) {
if (!plugins.notifications || plugins.notifications.length == 0) return;
var count = plugins.notifications.length;
var importantCount = _.filter(plugins.notifications, function(notification) { return notification.important }).length;
if (count > 1) {
if (importantCount) {
return _.sprintf(gettext("There are %(count)d notices (%(important)d marked as important) available regarding this plugin - click to show!"), {count: count, important: importantCount});
} else {
return _.sprintf(gettext("There are %(count)d notices available regarding this plugin - click to show!"), {count: count});
}
} else {
if (importantCount) {
return gettext("There is an important notice available regarding this plugin - click to show!");
} else {
return gettext("There is a notice available regarding this plugin - click to show!");
}
}
};
self._showPluginNotification = function(plugin, notification) {
var name = plugin.name;
var version = plugin.version;
var important = notification.important;
var link = notification.link;
var title;
if (important) {
title = _.sprintf(gettext("Important notice regarding plugin \"%(name)s\""), {name: name});
} else {
title = _.sprintf(gettext("Notice regarding plugin \"%(name)s\""), {name: name});
}
var text = "";
if (notification.versions && notification.versions.length > 0) {
var versions = _.map(notification.versions, function(v) { return (v == version) ? "<strong>" + v + "</strong>" : v; }).join(", ");
text += "<small>" + _.sprintf(gettext("Affected versions: %(versions)s"), {versions: versions}) + "</small>";
} else {
text += "<small>" + gettext("Affected versions: all") + "</small>";
}
text += "<p>" + notification.text + "</p>";
if (link) {
text += "<p><a href='" + link + "' target='_blank'>" + gettext("Read more...") + "</a></p>";
}
var beforeClose = function(notification) {
if (!self.noticeNotifications[plugin.key]) return;
self.noticeNotifications[plugin.key] = _.without(self.noticeNotifications[plugin.key], notification);
};
var options = {
title: title,
text: text,
type: (important) ? "error" : "notice",
before_close: beforeClose,
hide: false,
confirm: {
confirm: true,
buttons: [{
text: gettext("Later"),
click: function(notice) {
self._hideNoticeNotification(plugin.key, notification.date);
notice.remove();
notice.get().trigger("pnotify.cancel", notice);
}
}, {
text: gettext("Mark read"),
click: function(notice) {
self._ignoreNoticeNotification(plugin.key, notification.date);
notice.remove();
notice.get().trigger("pnotify.cancel", notice);
}
}]
},
buttons: {
sticker: false,
closer: false
}
};
if (!self.noticeNotifications[plugin.key]) {
self.noticeNotifications[plugin.key] = [];
}
self.noticeNotifications[plugin.key].push(new PNotify(options));
};
self._removeAllNoticeNotifications = function() {
_.each(_.keys(self.noticeNotifications), function(key) {
self._removeAllNoticeNotificationsForPlugin(key);
});
};
self._removeAllNoticeNotificationsForPlugin = function(key) {
if (!self.noticeNotifications[key] || !self.noticeNotifications[key].length) return;
_.each(self.noticeNotifications[key], function(notification) {
notification.remove();
});
};
self._hideNoticeNotification = function(key, date) {
if (!self.hiddenNoticeNotifications[key]) {
self.hiddenNoticeNotifications[key] = [];
}
if (!_.contains(self.hiddenNoticeNotifications[key], date)) {
self.hiddenNoticeNotifications[key].push(date);
}
};
self._isNoticeNotificationHidden = function(key, date) {
if (!self.hiddenNoticeNotifications[key]) return false;
return _.any(_.map(self.hiddenNoticeNotifications[key], function(d) { return date == d; }));
};
var noticeLocalStorageKey = "plugin.pluginmanager.seen_notices";
self._ignoreNoticeNotification = function(key, date) {
if (!Modernizr.localstorage)
return false;
if (!self.loginState.isAdmin())
return false;
var currentString = localStorage[noticeLocalStorageKey];
var current;
if (currentString === undefined) {
current = {};
} else {
current = JSON.parse(currentString);
}
if (!current[self.loginState.username()]) {
current[self.loginState.username()] = {};
}
if (!current[self.loginState.username()][key]) {
current[self.loginState.username()][key] = [];
}
if (!_.contains(current[self.loginState.username()][key], date)) {
current[self.loginState.username()][key].push(date);
localStorage[noticeLocalStorageKey] = JSON.stringify(current);
}
};
self._isNoticeNotificationIgnored = function(key, date) {
if (!Modernizr.localstorage)
return false;
if (localStorage[noticeLocalStorageKey] == undefined)
return false;
var knownData = JSON.parse(localStorage[noticeLocalStorageKey]);
if (!self.loginState.isAdmin())
return true;
var userData = knownData[self.loginState.username()];
if (userData === undefined)
return false;
return userData[key] && _.contains(userData[key], date);
};
self.onBeforeBinding = function() {
self.settings = self.settingsViewModel.settings;
};
self.onUserLoggedIn = function(user) {
if (user.admin) {
self.requestData({eval_notices: true});
} else {
self.onUserLoggedOut();
}
};
self.onUserLoggedOut = function() {
self._closeAllNotifications();
};
self._closeAllNotifications = function() {
if (self.notifications) {
_.each(self.notifications, function(notification) {
notification.remove();
});
}
};
self.onServerDisconnect = function() {
self._closeAllNotifications();
return true;
};
self.onStartup = function() {
self.workingDialog = $("#settings_plugin_pluginmanager_workingdialog");
self.workingOutput = $("#settings_plugin_pluginmanager_workingdialog_output");
self.repositoryDialog = $("#settings_plugin_pluginmanager_repositorydialog");
$("#settings_plugin_pluginmanager_repositorydialog_list").slimScroll({
height: "306px",
size: "5px",
distance: "0",
railVisible: true,
alwaysVisible: true,
scrollBy: "102px"
});
};
self.onDataUpdaterPluginMessage = function(plugin, data) {
if (plugin != "pluginmanager") {
return;
}
if (!self.loginState.isAdmin()) {
return;
}
if (!data.hasOwnProperty("type")) {
return;
}
var messageType = data.type;
if (messageType == "loglines" && self.working()) {
_.each(data.loglines, function(line) {
self.loglines.push(self._preprocessLine(line));
});
self._scrollWorkingOutputToEnd();
} else if (messageType == "result") {
var titleSuccess, textSuccess, textRestart, textReload, titleError, textError;
var action = data.action;
var name = "Unknown";
if (action == "install") {
var unknown = false;
if (data.hasOwnProperty("plugin")) {
if (data.plugin == "unknown") {
unknown = true;
} else {
name = data.plugin.name;
}
}
if (unknown) {
titleSuccess = _.sprintf(gettext("Plugin installed"));
textSuccess = gettext("A plugin was installed successfully, however it was impossible to detect which one. Please Restart OctoPrint to make sure everything will be registered properly");
textRestart = textSuccess;
textReload = textSuccess;
} else if (data.was_reinstalled) {
titleSuccess = _.sprintf(gettext("Plugin \"%(name)s\" reinstalled"), {name: name});
textSuccess = gettext("The plugin was reinstalled successfully");
textRestart = gettext("The plugin was reinstalled successfully, however a restart of OctoPrint is needed for that to take effect.");
textReload = gettext("The plugin was reinstalled successfully, however a reload of the page is needed for that to take effect.");
} else {
titleSuccess = _.sprintf(gettext("Plugin \"%(name)s\" installed"), {name: name});
textSuccess = gettext("The plugin was installed successfully");
textRestart = gettext("The plugin was installed successfully, however a restart of OctoPrint is needed for that to take effect.");
textReload = gettext("The plugin was installed successfully, however a reload of the page is needed for that to take effect.");
}
titleError = gettext("Something went wrong");
var source = "unknown";
if (data.hasOwnProperty("source")) {
source = data.source;
}
var sourceType = "unknown";
if (data.hasOwnProperty("source_type")) {
sourceType = data.source_type;
}
if (data.hasOwnProperty("reason")) {
if (data.was_reinstalled) {
if (sourceType == "path") {
textError = _.sprintf(gettext("Reinstalling the plugin from file failed: %(reason)s"), {reason: data.reason});
} else {
textError = _.sprintf(gettext("Reinstalling the plugin from \"%(source)s\" failed: %(reason)s"), {reason: data.reason, source: source});
}
} else {
if (sourceType == "path") {
textError = _.sprintf(gettext("Installing the plugin from file failed: %(reason)s"), {reason: data.reason});
} else {
textError = _.sprintf(gettext("Installing the plugin from \"%(source)s\" failed: %(reason)s"), {reason: data.reason, source: source});
}
}
} else {
if (data.was_reinstalled) {
if (sourceType == "path") {
textError = gettext("Reinstalling the plugin from file failed, please see the log for details.");
} else {
textError = _.sprintf(gettext("Reinstalling the plugin from \"%(source)s\" failed, please see the log for details."), {source: source});
}
} else {
if (sourceType == "path") {
textError = gettext("Installing the plugin from file failed, please see the log for details.");
} else {
textError = _.sprintf(gettext("Installing the plugin from \"%(source)s\" failed, please see the log for details."), {source: source});
}
}
}
} else if (action == "uninstall") {
if (data.hasOwnProperty("plugin")) {
name = data.plugin.name;
}
titleSuccess = _.sprintf(gettext("Plugin \"%(name)s\" uninstalled"), {name: name});
textSuccess = gettext("The plugin was uninstalled successfully");
textRestart = gettext("The plugin was uninstalled successfully, however a restart of OctoPrint is needed for that to take effect.");
textReload = gettext("The plugin was uninstalled successfully, however a reload of the page is needed for that to take effect.");
titleError = gettext("Something went wrong");
if (data.hasOwnProperty("reason")) {
textError = _.sprintf(gettext("Uninstalling the plugin failed: %(reason)s"), {reason: data.reason});
} else {
textError = gettext("Uninstalling the plugin failed, please see the log for details.");
}
} else if (action == "enable") {
if (data.hasOwnProperty("plugin")) {
name = data.plugin.name;
}
titleSuccess = _.sprintf(gettext("Plugin \"%(name)s\" enabled"), {name: name});
textSuccess = gettext("The plugin was enabled successfully.");
textRestart = gettext("The plugin was enabled successfully, however a restart of OctoPrint is needed for that to take effect.");
textReload = gettext("The plugin was enabled successfully, however a reload of the page is needed for that to take effect.");
titleError = gettext("Something went wrong");
if (data.hasOwnProperty("reason")) {
textError = _.sprintf(gettext("Toggling the plugin failed: %(reason)s"), {reason: data.reason});
} else {
textError = gettext("Toggling the plugin failed, please see the log for details.");
}
} else if (action == "disable") {
if (data.hasOwnProperty("plugin")) {
name = data.plugin.name;
}
titleSuccess = _.sprintf(gettext("Plugin \"%(name)s\" disabled"), {name: name});
textSuccess = gettext("The plugin was disabled successfully.");
textRestart = gettext("The plugin was disabled successfully, however a restart of OctoPrint is needed for that to take effect.");
textReload = gettext("The plugin was disabled successfully, however a reload of the page is needed for that to take effect.");
titleError = gettext("Something went wrong");
if (data.hasOwnProperty("reason")) {
textError = _.sprintf(gettext("Toggling the plugin failed: %(reason)s"), {reason: data.reason});
} else {
textError = gettext("Toggling the plugin failed, please see the log for details.");
}
} else {
return;
}
self._displayNotification(data, titleSuccess, textSuccess, textRestart, textReload, titleError, textError);
self.requestData();
}
};
self._forcedStdoutLine = /You are using pip version .*?, however version .*? is available\.|You should consider upgrading via the '.*?' command\./;
self._preprocessLine = function(line) {
if (line.stream == "stderr" && line.line.match(self._forcedStdoutLine)) {
line.stream = "stdout";
}
return line;
}
}
// view model class, parameters for constructor, container to bind to
ADDITIONAL_VIEWMODELS.push([
PluginManagerViewModel,
["loginStateViewModel", "settingsViewModel", "printerStateViewModel", "systemViewModel"],
"#settings_plugin_pluginmanager"
]);
});