2015-05-29 14:31:43 +00:00
$ ( function ( ) {
function PluginManagerViewModel ( parameters ) {
var self = this ;
self . loginState = parameters [ 0 ] ;
self . settingsViewModel = parameters [ 1 ] ;
2015-06-18 09:37:08 +00:00
self . printerState = parameters [ 2 ] ;
2015-05-29 14:31:43 +00:00
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 ( [ ] ) ;
2015-06-10 17:34:33 +00:00
self . followDependencyLinks = ko . observable ( false ) ;
2015-05-29 14:31:43 +00:00
self . working = ko . observable ( false ) ;
self . workingTitle = ko . observable ( ) ;
self . workingDialog = undefined ;
self . workingOutput = undefined ;
2015-06-18 09:37:08 +00:00
self . enableManagement = ko . computed ( function ( ) {
return ! self . printerState . isPrinting ( ) ;
} ) ;
self . enableToggle = function ( data ) {
return self . enableManagement ( ) && data . key != 'pluginmanager' ;
} ;
self . enableUninstall = function ( data ) {
return self . enableManagement ( ) && ! data . bundled && data . key != 'pluginmanager' && ! data . pending _uninstall ;
} ;
self . enableRepoInstall = function ( data ) {
return self . enableManagement ( ) && self . isCompatible ( data ) ;
} ;
2015-05-29 14:31:43 +00:00
self . invalidUrl = ko . computed ( function ( ) {
var url = self . installUrl ( ) ;
return url !== undefined && url . trim ( ) != "" && ! ( _ . startsWith ( url . toLocaleLowerCase ( ) , "http://" ) || _ . startsWith ( url . toLocaleLowerCase ( ) , "https://" ) ) ;
} ) ;
self . enableUrlInstall = ko . computed ( function ( ) {
var url = self . installUrl ( ) ;
2015-06-18 09:37:08 +00:00
return self . enableManagement ( ) && url !== undefined && url . trim ( ) != "" && ! self . invalidUrl ( ) ;
2015-05-29 14:31:43 +00:00
} ) ;
self . invalidArchive = ko . computed ( 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 . computed ( function ( ) {
var name = self . uploadFilename ( ) ;
2015-06-18 09:37:08 +00:00
return self . enableManagement ( ) && name !== undefined && name . trim ( ) != "" && ! self . invalidArchive ( ) ;
2015-05-29 14:31:43 +00:00
} ) ;
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..." ) ) ;
2015-06-10 17:34:33 +00:00
data . formData = {
dependency _links : self . followDependencyLinks ( )
} ;
2015-05-29 14:31:43 +00:00
data . submit ( ) ;
return false ;
} ) ;
} ,
done : function ( e , data ) {
self . _markDone ( ) ;
self . uploadButton . unbind ( "click" ) ;
self . uploadFilename ( "" ) ;
} ,
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 ( ) ;
self . uploadButton . unbind ( "click" ) ;
self . uploadFilename ( "" ) ;
}
} ) ;
self . performRepositorySearch = function ( ) {
var query = self . repositorySearchQuery ( ) ;
if ( query !== undefined && query . trim ( ) != "" ) {
self . repositoryplugins . changeSearchFunction ( function ( entry ) {
return entry && ( entry [ "title" ] . toLocaleLowerCase ( ) . indexOf ( query ) > - 1 || entry [ "description" ] . toLocaleLowerCase ( ) . indexOf ( query ) > - 1 ) ;
} ) ;
} else {
self . repositoryplugins . resetSearch ( ) ;
}
} ;
self . fromResponse = function ( data ) {
self . _fromPluginsResponse ( data . plugins ) ;
self . _fromRepositoryResponse ( data . repository )
} ;
self . _fromPluginsResponse = function ( data ) {
var installedPlugins = [ ] ;
_ . each ( data , function ( plugin ) {
installedPlugins . push ( plugin . key ) ;
} ) ;
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 . requestData = function ( includeRepo ) {
if ( ! self . loginState . isAdmin ( ) ) {
return ;
}
$ . ajax ( {
url : API _BASEURL + "plugin/pluginmanager" + ( ( includeRepo ) ? "?refresh_repository=true" : "" ) ,
type : "GET" ,
dataType : "json" ,
success : self . fromResponse
} ) ;
} ;
self . togglePlugin = function ( data ) {
if ( ! self . loginState . isAdmin ( ) ) {
return ;
}
2015-06-18 09:37:08 +00:00
if ( ! self . enableManagement ( ) ) {
return ;
}
2015-05-29 14:31:43 +00:00
if ( data . key == "pluginmanager" ) return ;
var command = self . _getToggleCommand ( data ) ;
var payload = { plugin : data . key } ;
self . _postCommand ( command , payload , function ( response ) {
self . requestData ( ) ;
} , function ( ) {
new PNotify ( {
title : gettext ( "Something went wrong" ) ,
text : gettext ( "Please consult octoprint.log for details" ) ,
type : "error" ,
hide : false
} )
} ) ;
} ;
self . showRepository = function ( ) {
self . repositoryDialog . modal ( "show" ) ;
} ;
self . pluginDetails = function ( data ) {
window . open ( data . page ) ;
} ;
self . installFromRepository = function ( data ) {
if ( ! self . loginState . isAdmin ( ) ) {
return ;
}
2015-06-18 09:37:08 +00:00
if ( ! self . enableManagement ( ) ) {
return ;
}
2015-05-29 14:31:43 +00:00
if ( self . installed ( data ) ) {
2015-06-10 17:34:33 +00:00
self . installPlugin ( data . archive , data . title , data . id , data . follow _dependency _links || self . followDependencyLinks ( ) ) ;
2015-05-29 14:31:43 +00:00
} else {
2015-06-10 17:34:33 +00:00
self . installPlugin ( data . archive , data . title , undefined , data . follow _dependency _links || self . followDependencyLinks ( ) ) ;
2015-05-29 14:31:43 +00:00
}
} ;
2015-06-10 17:34:33 +00:00
self . installPlugin = function ( url , name , reinstall , followDependencyLinks ) {
2015-05-29 14:31:43 +00:00
if ( ! self . loginState . isAdmin ( ) ) {
return ;
}
2015-06-18 09:37:08 +00:00
if ( ! self . enableManagement ( ) ) {
return ;
}
2015-05-29 14:31:43 +00:00
if ( url === undefined ) {
url = self . installUrl ( ) ;
}
if ( ! url ) return ;
2015-06-10 17:34:33 +00:00
if ( followDependencyLinks === undefined ) {
followDependencyLinks = self . followDependencyLinks ( ) ;
}
2015-05-29 14:31:43 +00:00
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 command = "install" ;
2015-06-10 17:34:33 +00:00
var payload = { url : url , dependency _links : followDependencyLinks } ;
2015-05-29 14:31:43 +00:00
if ( reinstall ) {
payload [ "plugin" ] = reinstall ;
payload [ "force" ] = true ;
}
self . _postCommand ( command , payload , function ( response ) {
self . requestData ( ) ;
self . _markDone ( ) ;
self . installUrl ( "" ) ;
} , function ( ) {
new PNotify ( {
title : gettext ( "Something went wrong" ) ,
text : gettext ( "Please consult octoprint.log for details" ) ,
type : "error" ,
hide : false
} ) ;
self . _markDone ( ) ;
} ) ;
} ;
self . uninstallPlugin = function ( data ) {
if ( ! self . loginState . isAdmin ( ) ) {
return ;
}
2015-06-18 09:37:08 +00:00
if ( ! self . enableManagement ( ) ) {
return ;
}
2015-05-29 14:31:43 +00:00
if ( data . bundled ) return ;
if ( data . key == "pluginmanager" ) return ;
self . _markWorking ( gettext ( "Uninstalling plugin..." ) , _ . sprintf ( gettext ( "Uninstalling plugin \"%(name)s\"" ) , { name : data . name } ) ) ;
var command = "uninstall" ;
var payload = { plugin : data . key } ;
self . _postCommand ( command , payload , function ( response ) {
self . requestData ( ) ;
self . _markDone ( ) ;
} , function ( ) {
new PNotify ( {
title : gettext ( "Something went wrong" ) ,
text : gettext ( "Please consult octoprint.log for details" ) ,
type : "error" ,
hide : false
} ) ;
self . _markDone ( ) ;
} ) ;
} ;
self . refreshRepository = function ( ) {
if ( ! self . loginState . isAdmin ( ) ) {
return ;
}
2015-06-18 09:37:08 +00:00
self . requestData ( true ) ;
2015-05-29 14:31:43 +00:00
} ;
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" ) ) : gettext ( "Incompatible" ) ;
} ;
self . _displayNotification = function ( response , titleSuccess , textSuccess , textRestart , textReload , titleError , textError ) {
if ( response . result ) {
if ( response . needs _restart ) {
new PNotify ( {
title : titleSuccess ,
text : textRestart ,
hide : false
} ) ;
} else if ( response . needs _refresh ) {
new PNotify ( {
title : titleSuccess ,
text : textReload ,
confirm : {
confirm : true ,
buttons : [ {
text : gettext ( "Reload now" ) ,
click : function ( ) {
location . reload ( true ) ;
}
} ]
} ,
buttons : {
closer : false ,
sticker : false
} ,
hide : false
} )
} else {
new PNotify ( {
title : titleSuccess ,
text : textSuccess ,
type : "success" ,
hide : false
} )
}
} else {
new PNotify ( {
title : titleError ,
text : textError ,
type : "error" ,
hide : false
} ) ;
}
} ;
self . _postCommand = function ( command , data , successCallback , failureCallback , alwaysCallback , timeout ) {
var payload = _ . extend ( data , { command : command } ) ;
var params = {
url : API _BASEURL + "plugin/pluginmanager" ,
type : "POST" ,
dataType : "json" ,
data : JSON . stringify ( payload ) ,
contentType : "application/json; charset=UTF-8" ,
success : function ( response ) {
if ( successCallback ) successCallback ( response ) ;
} ,
error : function ( ) {
if ( failureCallback ) failureCallback ( ) ;
} ,
complete : function ( ) {
if ( alwaysCallback ) alwaysCallback ( ) ;
}
} ;
if ( timeout != undefined ) {
params . timeout = timeout ;
}
$ . ajax ( params ) ;
} ;
self . _markWorking = function ( title , line ) {
self . working ( true ) ;
self . workingTitle ( title ) ;
self . loglines . removeAll ( ) ;
self . loglines . push ( { line : line , stream : "message" } ) ;
self . workingDialog . modal ( "show" ) ;
} ;
self . _markDone = function ( ) {
self . working ( false ) ;
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 ) {
return ( ( ! data . enabled || data . pending _disable ) && ! data . pending _enable ) ? "enable" : "disable" ;
} ;
self . toggleButtonCss = function ( data ) {
var icon = self . _getToggleCommand ( data ) == "enable" ? "icon-circle-blank" : "icon-circle" ;
2015-06-18 09:37:08 +00:00
var disabled = ( self . enableToggle ( data ) ) ? "" : " disabled" ;
2015-05-29 14:31:43 +00:00
return icon + disabled ;
} ;
self . toggleButtonTitle = function ( data ) {
return self . _getToggleCommand ( data ) == "enable" ? gettext ( "Enable Plugin" ) : gettext ( "Disable Plugin" ) ;
} ;
self . onBeforeBinding = function ( ) {
self . settings = self . settingsViewModel . settings ;
} ;
self . onUserLoggedIn = function ( user ) {
if ( user . admin ) {
self . requestData ( ) ;
}
} ;
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 ( line ) ;
} ) ;
self . _scrollWorkingOutputToEnd ( ) ;
} else if ( messageType == "result" ) {
var titleSuccess , textSuccess , textRestart , textReload , titleError , textError ;
var action = data . action ;
var name = "Unknown" ;
if ( action == "install" ) {
2015-06-19 22:56:26 +00:00
var unknown = false ;
2015-05-29 14:31:43 +00:00
if ( data . hasOwnProperty ( "plugin" ) ) {
2015-06-19 22:56:26 +00:00
if ( data . plugin == "unknown" ) {
unknown = true ;
} else {
name = data . plugin . name ;
}
2015-05-29 14:31:43 +00:00
}
2015-06-19 22:56:26 +00:00
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 ) {
2015-05-29 14:31:43 +00:00
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 url = "unknown" ;
if ( data . hasOwnProperty ( "url" ) ) {
url = data . url ;
}
if ( data . hasOwnProperty ( "reason" ) ) {
if ( data . was _reinstalled ) {
textError = _ . sprintf ( gettext ( "Reinstalling the plugin from URL \"%(url)s\" failed: %(reason)s" ) , { reason : data . reason , url : url } ) ;
} else {
textError = _ . sprintf ( gettext ( "Installing the plugin from URL \"%(url)s\" failed: %(reason)s" ) , { reason : data . reason , url : url } ) ;
}
} else {
if ( data . was _reinstalled ) {
textError = _ . sprintf ( gettext ( "Reinstalling the plugin from URL \"%(url)s\" failed, please see the log for details." ) , { url : url } ) ;
} else {
textError = _ . sprintf ( gettext ( "Installing the plugin from URL \"%(url)s\" failed, please see the log for details." ) , { url : url } ) ;
}
}
} 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 ( ) ;
}
} ;
}
// view model class, parameters for constructor, container to bind to
2015-06-18 09:37:08 +00:00
ADDITIONAL _VIEWMODELS . push ( [ PluginManagerViewModel , [ "loginStateViewModel" , "settingsViewModel" , "printerStateViewModel" ] , "#settings_plugin_pluginmanager" ] ) ;
2015-05-29 14:31:43 +00:00
} ) ;