2015-12-02 21:39:40 +01:00
|
|
|
'use strict';
|
|
|
|
|
2016-03-27 09:06:23 +02:00
|
|
|
var StorageBase = require('./storage-base'),
|
|
|
|
DropboxLink = require('../comp/dropbox-link'),
|
2016-03-14 06:16:33 +01:00
|
|
|
Locale = require('../util/locale'),
|
2016-04-03 14:56:38 +02:00
|
|
|
UrlUtil = require('../util/url-util');
|
2015-12-12 09:53:50 +01:00
|
|
|
|
2016-03-27 09:06:23 +02:00
|
|
|
var StorageDropbox = StorageBase.extend({
|
2015-12-02 21:39:40 +01:00
|
|
|
name: 'dropbox',
|
2016-03-12 12:22:35 +01:00
|
|
|
icon: 'dropbox',
|
2015-12-02 21:39:40 +01:00
|
|
|
enabled: true,
|
2016-03-13 17:08:25 +01:00
|
|
|
uipos: 20,
|
2015-12-02 21:39:40 +01:00
|
|
|
|
2015-12-12 16:43:43 +01:00
|
|
|
_convertError: function(err) {
|
|
|
|
if (!err) {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
if (err.status === DropboxLink.ERROR_NOT_FOUND) {
|
|
|
|
err.notFound = true;
|
|
|
|
}
|
|
|
|
if (err.status === DropboxLink.ERROR_CONFLICT) {
|
|
|
|
err.revConflict = true;
|
|
|
|
}
|
|
|
|
return err;
|
|
|
|
},
|
|
|
|
|
2016-03-14 06:04:55 +01:00
|
|
|
_toFullPath: function(path) {
|
2016-03-27 09:06:23 +02:00
|
|
|
var rootFolder = this.appSettings.get('dropboxFolder');
|
2016-03-14 06:04:55 +01:00
|
|
|
if (rootFolder) {
|
2016-04-03 14:56:38 +02:00
|
|
|
path = UrlUtil.fixSlashes('/' + rootFolder + '/' + path);
|
2016-03-14 06:04:55 +01:00
|
|
|
}
|
|
|
|
return path;
|
|
|
|
},
|
|
|
|
|
|
|
|
_toRelPath: function(path) {
|
2016-03-27 09:06:23 +02:00
|
|
|
var rootFolder = this.appSettings.get('dropboxFolder');
|
2016-03-14 06:04:55 +01:00
|
|
|
if (rootFolder) {
|
|
|
|
var ix = path.toLowerCase().indexOf(rootFolder.toLowerCase());
|
|
|
|
if (ix === 0) {
|
|
|
|
path = path.substr(rootFolder.length);
|
|
|
|
} else if (ix === 1) {
|
|
|
|
path = path.substr(rootFolder.length + 1);
|
|
|
|
}
|
2016-04-03 14:56:38 +02:00
|
|
|
path = UrlUtil.fixSlashes('/' + path);
|
2016-03-14 06:04:55 +01:00
|
|
|
}
|
|
|
|
return path;
|
|
|
|
},
|
|
|
|
|
2016-03-17 22:10:49 +01:00
|
|
|
_fixConfigFolder: function(folder) {
|
|
|
|
folder = folder.replace(/\\/g, '/').trim();
|
|
|
|
if (folder[0] === '/') {
|
|
|
|
folder = folder.substr(1);
|
|
|
|
}
|
|
|
|
return folder;
|
|
|
|
},
|
|
|
|
|
2016-03-13 17:08:25 +01:00
|
|
|
needShowOpenConfig: function() {
|
2016-03-13 17:45:55 +01:00
|
|
|
return !DropboxLink.isValidKey();
|
|
|
|
},
|
|
|
|
|
|
|
|
getOpenConfig: function() {
|
|
|
|
return {
|
|
|
|
desc: 'dropboxSetupDesc',
|
|
|
|
fields: [
|
2016-03-17 22:10:49 +01:00
|
|
|
{id: 'key', title: 'dropboxAppKey', desc: 'dropboxAppKeyDesc', type: 'text', required: true, pattern: '\\w+'},
|
2016-03-14 06:04:55 +01:00
|
|
|
{id: 'folder', title: 'dropboxFolder', desc: 'dropboxFolderDesc', type: 'text', placeholder: 'dropboxFolderPlaceholder'}
|
2016-03-13 17:45:55 +01:00
|
|
|
]
|
|
|
|
};
|
|
|
|
},
|
|
|
|
|
2016-03-17 22:10:49 +01:00
|
|
|
getSettingsConfig: function() {
|
|
|
|
var fields = [];
|
|
|
|
var appKey = DropboxLink.getKey();
|
|
|
|
var linkField = {id: 'link', title: 'dropboxLink', type: 'select', value: 'custom',
|
|
|
|
options: { app: 'dropboxLinkApp', full: 'dropboxLinkFull', custom: 'dropboxLinkCustom' } };
|
|
|
|
var keyField = {id: 'key', title: 'dropboxAppKey', desc: 'dropboxAppKeyDesc', type: 'text', required: true, pattern: '\\w+',
|
|
|
|
value: appKey};
|
|
|
|
var folderField = {id: 'folder', title: 'dropboxFolder', desc: 'dropboxFolderSettingsDesc', type: 'text',
|
2016-03-27 09:06:23 +02:00
|
|
|
value: this.appSettings.get('dropboxFolder') || ''};
|
2016-03-17 22:10:49 +01:00
|
|
|
var canUseBuiltInKeys = DropboxLink.canUseBuiltInKeys();
|
|
|
|
if (canUseBuiltInKeys) {
|
|
|
|
fields.push(linkField);
|
|
|
|
if (appKey === DropboxLink.Keys.AppFolder) {
|
|
|
|
linkField.value = 'app';
|
|
|
|
} else if (appKey === DropboxLink.Keys.FullDropbox) {
|
|
|
|
linkField.value = 'full';
|
|
|
|
fields.push(folderField);
|
|
|
|
} else {
|
|
|
|
fields.push(keyField);
|
|
|
|
fields.push(folderField);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
fields.push(keyField);
|
|
|
|
fields.push(folderField);
|
|
|
|
}
|
|
|
|
return { fields: fields };
|
|
|
|
},
|
|
|
|
|
2016-03-13 17:45:55 +01:00
|
|
|
applyConfig: function(config, callback) {
|
2016-07-17 13:30:38 +02:00
|
|
|
DropboxLink.authenticate(err => {
|
2016-03-14 06:04:55 +01:00
|
|
|
if (!err) {
|
|
|
|
if (config.folder) {
|
2016-07-17 13:30:38 +02:00
|
|
|
config.folder = this._fixConfigFolder(config.folder);
|
2016-03-13 17:45:55 +01:00
|
|
|
}
|
2016-07-17 13:30:38 +02:00
|
|
|
this.appSettings.set({
|
2016-03-14 06:04:55 +01:00
|
|
|
dropboxAppKey: config.key,
|
|
|
|
dropboxFolder: config.folder
|
|
|
|
});
|
2016-03-17 22:49:39 +01:00
|
|
|
DropboxLink.resetClient();
|
2016-03-14 06:04:55 +01:00
|
|
|
}
|
|
|
|
callback(err);
|
|
|
|
}, config.key);
|
2016-03-13 17:08:25 +01:00
|
|
|
},
|
|
|
|
|
2016-03-17 22:10:49 +01:00
|
|
|
applySetting: function(key, value) {
|
|
|
|
switch (key) {
|
|
|
|
case 'link':
|
|
|
|
key = 'dropboxAppKey';
|
|
|
|
switch (value) {
|
|
|
|
case 'app':
|
|
|
|
value = DropboxLink.Keys.AppFolder;
|
|
|
|
break;
|
|
|
|
case 'full':
|
|
|
|
value = DropboxLink.Keys.FullDropbox;
|
|
|
|
break;
|
|
|
|
case 'custom':
|
|
|
|
value = '(your app key)';
|
|
|
|
break;
|
2016-03-17 22:49:39 +01:00
|
|
|
default:
|
|
|
|
return;
|
2016-03-17 22:10:49 +01:00
|
|
|
}
|
2016-03-17 22:49:39 +01:00
|
|
|
DropboxLink.resetClient();
|
2016-03-17 22:10:49 +01:00
|
|
|
break;
|
|
|
|
case 'key':
|
|
|
|
key = 'dropboxAppKey';
|
|
|
|
break;
|
|
|
|
case 'folder':
|
|
|
|
key = 'dropboxFolder';
|
|
|
|
value = this._fixConfigFolder(value);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
2016-03-27 09:06:23 +02:00
|
|
|
this.appSettings.set(key, value);
|
2016-03-17 22:10:49 +01:00
|
|
|
},
|
|
|
|
|
2015-12-12 16:43:43 +01:00
|
|
|
getPathForName: function(fileName) {
|
|
|
|
return '/' + fileName + '.kdbx';
|
|
|
|
},
|
|
|
|
|
2016-03-12 17:49:52 +01:00
|
|
|
load: function(path, opts, callback) {
|
2016-07-17 13:30:38 +02:00
|
|
|
this.logger.debug('Load', path);
|
|
|
|
var ts = this.logger.ts();
|
|
|
|
path = this._toFullPath(path);
|
|
|
|
DropboxLink.openFile(path, (err, data, stat) => {
|
|
|
|
this.logger.debug('Loaded', path, stat ? stat.versionTag : null, this.logger.ts(ts));
|
|
|
|
err = this._convertError(err);
|
2015-12-08 20:18:35 +01:00
|
|
|
if (callback) { callback(err, data, stat ? { rev: stat.versionTag } : null); }
|
2015-12-12 09:53:50 +01:00
|
|
|
}, _.noop);
|
2015-12-08 20:18:35 +01:00
|
|
|
},
|
|
|
|
|
2016-03-12 17:49:52 +01:00
|
|
|
stat: function(path, opts, callback) {
|
2016-07-17 13:30:38 +02:00
|
|
|
this.logger.debug('Stat', path);
|
|
|
|
var ts = this.logger.ts();
|
|
|
|
path = this._toFullPath(path);
|
|
|
|
DropboxLink.stat(path, (err, stat) => {
|
2015-12-13 21:03:29 +01:00
|
|
|
if (stat && stat.isRemoved) {
|
2015-12-12 16:43:43 +01:00
|
|
|
err = new Error('File removed');
|
|
|
|
err.notFound = true;
|
|
|
|
}
|
2016-07-17 13:30:38 +02:00
|
|
|
this.logger.debug('Stated', path, stat ? stat.versionTag : null, this.logger.ts(ts));
|
|
|
|
err = this._convertError(err);
|
2015-12-08 20:18:35 +01:00
|
|
|
if (callback) { callback(err, stat ? { rev: stat.versionTag } : null); }
|
2015-12-12 09:53:50 +01:00
|
|
|
}, _.noop);
|
2015-12-02 21:39:40 +01:00
|
|
|
},
|
|
|
|
|
2016-03-12 17:49:52 +01:00
|
|
|
save: function(path, opts, data, callback, rev) {
|
2016-07-17 13:30:38 +02:00
|
|
|
this.logger.debug('Save', path, rev);
|
|
|
|
var ts = this.logger.ts();
|
|
|
|
path = this._toFullPath(path);
|
|
|
|
DropboxLink.saveFile(path, data, rev, (err, stat) => {
|
|
|
|
this.logger.debug('Saved', path, this.logger.ts(ts));
|
2015-12-11 21:51:16 +01:00
|
|
|
if (!callback) { return; }
|
2016-07-17 13:30:38 +02:00
|
|
|
err = this._convertError(err);
|
2015-12-12 16:43:43 +01:00
|
|
|
callback(err, stat ? { rev: stat.versionTag } : null);
|
2015-12-12 09:53:50 +01:00
|
|
|
}, _.noop);
|
2016-03-13 17:08:25 +01:00
|
|
|
},
|
|
|
|
|
|
|
|
list: function(callback) {
|
2016-07-17 13:30:38 +02:00
|
|
|
DropboxLink.authenticate((err) => {
|
2016-03-13 17:08:25 +01:00
|
|
|
if (err) { return callback(err); }
|
2016-07-17 13:30:38 +02:00
|
|
|
DropboxLink.list(this._toFullPath(''), (err, files, dirStat, filesStat) => {
|
2016-03-13 17:08:25 +01:00
|
|
|
if (err) { return callback(err); }
|
2016-03-14 06:16:33 +01:00
|
|
|
var fileList = filesStat
|
2016-07-17 13:30:38 +02:00
|
|
|
.filter(f => !f.isFolder && !f.isRemoved && UrlUtil.isKdbx(f.name))
|
|
|
|
.map(f => ({
|
|
|
|
name: f.name,
|
|
|
|
path: this._toRelPath(f.path),
|
|
|
|
rev: f.versionTag
|
|
|
|
}));
|
|
|
|
var dir = dirStat.inAppFolder ? Locale.openAppFolder
|
|
|
|
: (UrlUtil.trimStartSlash(dirStat.path) || Locale.openRootFolder);
|
2016-03-14 06:16:33 +01:00
|
|
|
callback(null, fileList, dir);
|
2016-03-13 17:08:25 +01:00
|
|
|
});
|
|
|
|
});
|
2016-03-27 18:38:33 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
remove: function(path, callback) {
|
2016-07-17 13:30:38 +02:00
|
|
|
this.logger.debug('Remove', path);
|
|
|
|
var ts = this.logger.ts();
|
|
|
|
path = this._toFullPath(path);
|
|
|
|
DropboxLink.deleteFile(path, err => {
|
|
|
|
this.logger.debug('Removed', path, this.logger.ts(ts));
|
2016-03-27 18:38:33 +02:00
|
|
|
return callback && callback(err);
|
|
|
|
}, _.noop);
|
2016-06-04 17:08:50 +02:00
|
|
|
},
|
|
|
|
|
2016-08-21 17:43:59 +02:00
|
|
|
mkdir: function(path, callback) {
|
|
|
|
DropboxLink.authenticate((err) => {
|
|
|
|
if (err) { return callback(err); }
|
|
|
|
this.logger.debug('Make dir', path);
|
|
|
|
let ts = this.logger.ts();
|
|
|
|
path = this._toFullPath(path);
|
|
|
|
DropboxLink.mkdir(path, err => {
|
|
|
|
this.logger.debug('Made dir', path, this.logger.ts(ts));
|
|
|
|
return callback && callback(err);
|
|
|
|
}, _.noop);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2016-06-04 17:08:50 +02:00
|
|
|
setEnabled: function(enabled) {
|
|
|
|
if (!enabled) {
|
|
|
|
DropboxLink.logout();
|
|
|
|
}
|
|
|
|
StorageBase.prototype.setEnabled.call(this, enabled);
|
2015-12-02 21:39:40 +01:00
|
|
|
}
|
2016-03-27 09:06:23 +02:00
|
|
|
});
|
2015-12-02 21:39:40 +01:00
|
|
|
|
2016-03-27 09:46:43 +02:00
|
|
|
module.exports = new StorageDropbox();
|