diff --git a/Duplicati/Library/Backend/Filejump/Filejump.cs b/Duplicati/Library/Backend/Filejump/Filejump.cs index e19cb3872..35c903214 100644 --- a/Duplicati/Library/Backend/Filejump/Filejump.cs +++ b/Duplicati/Library/Backend/Filejump/Filejump.cs @@ -318,7 +318,7 @@ namespace Duplicati.Library.Backend if (string.IsNullOrWhiteSpace(folderPath) || folderPath == "/") return null; - var pathParts = folderPath.Trim('/').Split('/'); + var pathParts = folderPath.Trim('/').Split('/', StringSplitOptions.RemoveEmptyEntries); long? currentParentId = null; foreach (var part in pathParts) @@ -475,7 +475,7 @@ namespace Duplicati.Library.Backend throw new InvalidOperationException("Backend not initialized correctly"); long? currentParentId = null; - var pathParts = m_path.Trim('/').Split('/'); + var pathParts = m_path.Trim('/').Split('/', StringSplitOptions.RemoveEmptyEntries); var newFolder = false; foreach (var part in pathParts) diff --git a/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js b/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js index ba61e296a..ec573c721 100644 --- a/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js +++ b/Duplicati/Server/webroot/ngax/scripts/services/EditUriBuiltins.js @@ -38,6 +38,7 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo, EditUriBackendConfig.templates['smb'] = 'templates/backends/smb.html'; EditUriBackendConfig.templates['cifs'] = 'templates/backends/smb.html'; EditUriBackendConfig.templates['filen'] = 'templates/backends/filen.html'; + EditUriBackendConfig.templates['filejump'] = 'templates/backends/filejump.html'; EditUriBackendConfig.testers['s3'] = function(scope, callback) { @@ -639,7 +640,6 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo, EditUriBackendConfig.parsers['cifs'] = EditUriBackendConfig.parsers['smb']; EditUriBackendConfig.parsers['filen'] = function (scope, module, server, path, port, options) { - console.log("filen parser", scope, module, server, path, port, options); var p1 = server ?? ''; var p2 = path ?? ''; var combined = p1; @@ -648,6 +648,18 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo, scope.Path = combined; }; + EditUriBackendConfig.parsers['filejump'] = function (scope, module, server, path, port, options) { + console.log("filejump parser", scope, module, server, path, port, options); + var p1 = server ?? ''; + var p2 = path ?? ''; + var combined = p1; + if (p1.length > 0 && p2.length > 0) + combined += '/' + p2; + scope.Path = combined; + scope.ApiToken = options['--api-token']; + scope.UsernamePasswordAuth = (scope.ApiToken || '').trim() == ''; + } + // Builders take the scope and produce the uri output EditUriBackendConfig.builders['s3'] = function (scope) { var opts = { @@ -1033,6 +1045,33 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo, ); } + EditUriBackendConfig.builders['filejump'] = function (scope) { + var opts = {}; + EditUriBackendConfig.merge_in_advanced_options(scope, opts, true); + // Remove trailing and leading slashes + if (scope.Path) + scope.Path = scope.Path.replace(/^[/\\]+/, '').replace(/[/\\]+$/, ''); + else + scope.Path = ''; + + if (scope.UsernamePasswordAuth) + { + delete opts['api-token']; + } + else + { + opts['api-token'] = scope.ApiToken; + delete opts['auth-username']; + delete opts['auth-password']; + } + + return AppUtils.format('{0}://{1}{2}', + scope.Backend.Key, + scope.Path, + AppUtils.encodeDictAsUrl(opts) + ); + } + EditUriBackendConfig.validaters['smb'] = function (scope, continuation) { if (EditUriBackendConfig.require_server(scope) && EditUriBackendConfig.require_username(scope) @@ -1047,6 +1086,19 @@ backupApp.service('EditUriBuiltins', function (AppService, AppUtils, SystemInfo, EditUriBackendConfig.recommend_path(scope, continuation); }; + EditUriBackendConfig.validaters['filejump'] = function (scope, continuation) { + if (scope.UsernamePasswordAuth) + { + if (EditUriBackendConfig.require_username_and_password(scope)) + EditUriBackendConfig.recommend_path(scope, continuation); + } + else + { + if (EditUriBackendConfig.require_field(scope, 'ApiToken', gettextCatalog.getString('API Token'))) + EditUriBackendConfig.recommend_path(scope, continuation); + } + }; + EditUriBackendConfig.validaters['file'] = function (scope, continuation) { if (EditUriBackendConfig.require_path(scope)) continuation(); diff --git a/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js b/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js index e96cc6626..fc2771c11 100644 --- a/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js +++ b/Duplicati/Server/webroot/ngax/scripts/services/SystemInfo.js @@ -80,6 +80,7 @@ backupApp.service('SystemInfo', function($rootScope, $timeout, $cookies, AppServ 'aliyunoss': null, 'pcloud': null, 'filen': null, + 'filejump': null } }; diff --git a/Duplicati/Server/webroot/ngax/templates/backends/filejump.html b/Duplicati/Server/webroot/ngax/templates/backends/filejump.html new file mode 100644 index 000000000..9d740614e --- /dev/null +++ b/Duplicati/Server/webroot/ngax/templates/backends/filejump.html @@ -0,0 +1,34 @@ +