mirror of
https://github.com/keeweb/keeweb.git
synced 2024-06-21 07:06:39 +02:00
storage providers refactoring
This commit is contained in:
parent
9c9abaae80
commit
aa200d3c88
|
@ -1,24 +1,18 @@
|
|||
'use strict';
|
||||
|
||||
var Launcher = require('../comp/launcher'),
|
||||
AppSettingsModel = require('../models/app-settings-model');
|
||||
var Launcher = require('../comp/launcher');
|
||||
|
||||
var Storage = {
|
||||
file: require('./storage-file'),
|
||||
dropbox: require('./storage-dropbox'),
|
||||
webdav: require('./storage-webdav'),
|
||||
gdrive: require('./storage-gdrive'),
|
||||
onedrive: require('./storage-onedrive'),
|
||||
cache: Launcher ? require('./storage-file-cache') : require('./storage-cache')
|
||||
file: new (require('./storage-file'))(),
|
||||
dropbox: new (require('./storage-dropbox'))(),
|
||||
webdav: new (require('./storage-webdav'))(),
|
||||
gdrive: new (require('./storage-gdrive'))(),
|
||||
onedrive: new (require('./storage-onedrive'))(),
|
||||
cache: new (Launcher ? require('./storage-file-cache') : require('./storage-cache'))()
|
||||
};
|
||||
|
||||
_.forEach(Storage, function(prv, name) {
|
||||
if (!prv.system) {
|
||||
var enabled = AppSettingsModel.instance.get(name);
|
||||
if (typeof enabled === 'boolean') {
|
||||
prv.enabled = enabled;
|
||||
}
|
||||
}
|
||||
_.forEach(Storage, function(prv) {
|
||||
prv.init();
|
||||
});
|
||||
|
||||
module.exports = Storage;
|
||||
|
|
37
app/scripts/storage/storage-base.js
Normal file
37
app/scripts/storage/storage-base.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
var Backbone = require('backbone'),
|
||||
Logger = require('../util/logger'),
|
||||
AppSettingsModel = require('../models/app-settings-model');
|
||||
|
||||
var StorageBase = function() {
|
||||
};
|
||||
|
||||
_.extend(StorageBase.prototype, {
|
||||
name: null,
|
||||
icon: null,
|
||||
iconSvg: null,
|
||||
enabled: false,
|
||||
system: false,
|
||||
uipos: null,
|
||||
|
||||
logger: null,
|
||||
appSettings: AppSettingsModel.instance,
|
||||
|
||||
init: function() {
|
||||
if (!this.name) {
|
||||
throw 'Failed to init provider: no name';
|
||||
}
|
||||
if (!this.system) {
|
||||
var enabled = this.appSettings.get(this.name);
|
||||
if (typeof enabled === 'boolean') {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
||||
this.logger = new Logger('storage-' + this.name);
|
||||
}
|
||||
});
|
||||
|
||||
StorageBase.extend = Backbone.Model.extend;
|
||||
|
||||
module.exports = StorageBase;
|
|
@ -1,11 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
var Logger = require('../util/logger');
|
||||
var StorageBase = require('./storage-base');
|
||||
|
||||
var logger = new Logger('storage-cache');
|
||||
var idb = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
||||
|
||||
var StorageCache = {
|
||||
var StorageCache = StorageBase.extend({
|
||||
name: 'cache',
|
||||
enabled: !!idb,
|
||||
system: true,
|
||||
|
@ -13,7 +12,7 @@ var StorageCache = {
|
|||
db: null,
|
||||
errorOpening: null,
|
||||
|
||||
init: function(callback) {
|
||||
initDb: function(callback) {
|
||||
if (this.db) {
|
||||
return callback && callback();
|
||||
}
|
||||
|
@ -21,7 +20,7 @@ var StorageCache = {
|
|||
try {
|
||||
var req = idb.open('FilesCache');
|
||||
req.onerror = function (e) {
|
||||
logger.error('Error opening indexed db', e);
|
||||
that.logger.error('Error opening indexed db', e);
|
||||
that.errorOpening = e;
|
||||
if (callback) { callback(e); }
|
||||
};
|
||||
|
@ -34,82 +33,85 @@ var StorageCache = {
|
|||
db.createObjectStore('files');
|
||||
};
|
||||
} catch (e) {
|
||||
logger.error('Error opening indexed db', e);
|
||||
that.logger.error('Error opening indexed db', e);
|
||||
if (callback) { callback(e); }
|
||||
}
|
||||
},
|
||||
|
||||
save: function(id, opts, data, callback) {
|
||||
logger.debug('Save', id);
|
||||
this.init((function(err) {
|
||||
var that = this;
|
||||
that.logger.debug('Save', id);
|
||||
that.initDb(function(err) {
|
||||
if (err) {
|
||||
return callback && callback(err);
|
||||
}
|
||||
try {
|
||||
var ts = logger.ts();
|
||||
var req = this.db.transaction(['files'], 'readwrite').objectStore('files').put(data, id);
|
||||
var ts = that.logger.ts();
|
||||
var req = that.db.transaction(['files'], 'readwrite').objectStore('files').put(data, id);
|
||||
req.onsuccess = function () {
|
||||
logger.debug('Saved', id, logger.ts(ts));
|
||||
that.logger.debug('Saved', id, that.logger.ts(ts));
|
||||
if (callback) { callback(); }
|
||||
};
|
||||
req.onerror = function () {
|
||||
logger.error('Error saving to cache', id, req.error);
|
||||
that.logger.error('Error saving to cache', id, req.error);
|
||||
if (callback) { callback(req.error); }
|
||||
};
|
||||
} catch (e) {
|
||||
logger.error('Error saving to cache', id, e);
|
||||
that.logger.error('Error saving to cache', id, e);
|
||||
if (callback) { callback(e); }
|
||||
}
|
||||
}).bind(this));
|
||||
});
|
||||
},
|
||||
|
||||
load: function(id, opts, callback) {
|
||||
logger.debug('Load', id);
|
||||
this.init((function(err) {
|
||||
var that = this;
|
||||
that.logger.debug('Load', id);
|
||||
that.initDb(function(err) {
|
||||
if (err) {
|
||||
return callback && callback(err, null);
|
||||
}
|
||||
try {
|
||||
var ts = logger.ts();
|
||||
var req = this.db.transaction(['files'], 'readonly').objectStore('files').get(id);
|
||||
var ts = that.logger.ts();
|
||||
var req = that.db.transaction(['files'], 'readonly').objectStore('files').get(id);
|
||||
req.onsuccess = function () {
|
||||
logger.debug('Loaded', id, logger.ts(ts));
|
||||
that.logger.debug('Loaded', id, that.logger.ts(ts));
|
||||
if (callback) { callback(null, req.result); }
|
||||
};
|
||||
req.onerror = function () {
|
||||
logger.error('Error loading from cache', id, req.error);
|
||||
that.logger.error('Error loading from cache', id, req.error);
|
||||
if (callback) { callback(req.error); }
|
||||
};
|
||||
} catch (e) {
|
||||
logger.error('Error loading from cache', id, e);
|
||||
that.logger.error('Error loading from cache', id, e);
|
||||
if (callback) { callback(e, null); }
|
||||
}
|
||||
}).bind(this));
|
||||
});
|
||||
},
|
||||
|
||||
remove: function(id, opts, callback) {
|
||||
logger.debug('Remove', id);
|
||||
this.init((function(err) {
|
||||
var that = this;
|
||||
that.logger.debug('Remove', id);
|
||||
that.initDb(function(err) {
|
||||
if (err) {
|
||||
return callback && callback(err);
|
||||
}
|
||||
try {
|
||||
var ts = logger.ts();
|
||||
var req = this.db.transaction(['files'], 'readwrite').objectStore('files').delete(id);
|
||||
var ts = that.logger.ts();
|
||||
var req = that.db.transaction(['files'], 'readwrite').objectStore('files').delete(id);
|
||||
req.onsuccess = function () {
|
||||
logger.debug('Removed', id, logger.ts(ts));
|
||||
that.logger.debug('Removed', id, that.logger.ts(ts));
|
||||
if (callback) { callback(); }
|
||||
};
|
||||
req.onerror = function () {
|
||||
logger.error('Error removing from cache', id, req.error);
|
||||
that.logger.error('Error removing from cache', id, req.error);
|
||||
if (callback) { callback(req.error); }
|
||||
};
|
||||
} catch(e) {
|
||||
logger.error('Error removing from cache', id, e);
|
||||
that.logger.error('Error removing from cache', id, e);
|
||||
if (callback) { callback(e); }
|
||||
}
|
||||
}).bind(this));
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = StorageCache;
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
var DropboxLink = require('../comp/dropbox-link'),
|
||||
AppSettingsModel = require('../models/app-settings-model'),
|
||||
var StorageBase = require('./storage-base'),
|
||||
DropboxLink = require('../comp/dropbox-link'),
|
||||
Locale = require('../util/locale'),
|
||||
UrlUtils = require('../util/url-util'),
|
||||
Logger = require('../util/logger');
|
||||
UrlUtils = require('../util/url-util');
|
||||
|
||||
var logger = new Logger('storage-dropbox');
|
||||
|
||||
var StorageDropbox = {
|
||||
var StorageDropbox = StorageBase.extend({
|
||||
name: 'dropbox',
|
||||
icon: 'dropbox',
|
||||
enabled: true,
|
||||
|
@ -28,7 +25,7 @@ var StorageDropbox = {
|
|||
},
|
||||
|
||||
_toFullPath: function(path) {
|
||||
var rootFolder = AppSettingsModel.instance.get('dropboxFolder');
|
||||
var rootFolder = this.appSettings.get('dropboxFolder');
|
||||
if (rootFolder) {
|
||||
path = UrlUtils.fixSlashes('/' + rootFolder + '/' + path);
|
||||
}
|
||||
|
@ -36,7 +33,7 @@ var StorageDropbox = {
|
|||
},
|
||||
|
||||
_toRelPath: function(path) {
|
||||
var rootFolder = AppSettingsModel.instance.get('dropboxFolder');
|
||||
var rootFolder = this.appSettings.get('dropboxFolder');
|
||||
if (rootFolder) {
|
||||
var ix = path.toLowerCase().indexOf(rootFolder.toLowerCase());
|
||||
if (ix === 0) {
|
||||
|
@ -79,7 +76,7 @@ var StorageDropbox = {
|
|||
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',
|
||||
value: AppSettingsModel.instance.get('dropboxFolder') || ''};
|
||||
value: this.appSettings.get('dropboxFolder') || ''};
|
||||
var canUseBuiltInKeys = DropboxLink.canUseBuiltInKeys();
|
||||
if (canUseBuiltInKeys) {
|
||||
fields.push(linkField);
|
||||
|
@ -106,7 +103,7 @@ var StorageDropbox = {
|
|||
if (config.folder) {
|
||||
config.folder = that._fixConfigFolder(config.folder);
|
||||
}
|
||||
AppSettingsModel.instance.set({
|
||||
that.appSettings.set({
|
||||
dropboxAppKey: config.key,
|
||||
dropboxFolder: config.folder
|
||||
});
|
||||
|
@ -145,7 +142,7 @@ var StorageDropbox = {
|
|||
default:
|
||||
return;
|
||||
}
|
||||
AppSettingsModel.instance.set(key, value);
|
||||
this.appSettings.set(key, value);
|
||||
},
|
||||
|
||||
getPathForName: function(fileName) {
|
||||
|
@ -153,39 +150,42 @@ var StorageDropbox = {
|
|||
},
|
||||
|
||||
load: function(path, opts, callback) {
|
||||
logger.debug('Load', path);
|
||||
var ts = logger.ts();
|
||||
path = this._toFullPath(path);
|
||||
var that = this;
|
||||
that.logger.debug('Load', path);
|
||||
var ts = that.logger.ts();
|
||||
path = that._toFullPath(path);
|
||||
DropboxLink.openFile(path, function(err, data, stat) {
|
||||
logger.debug('Loaded', path, stat ? stat.versionTag : null, logger.ts(ts));
|
||||
err = StorageDropbox._convertError(err);
|
||||
that.logger.debug('Loaded', path, stat ? stat.versionTag : null, that.logger.ts(ts));
|
||||
err = that._convertError(err);
|
||||
if (callback) { callback(err, data, stat ? { rev: stat.versionTag } : null); }
|
||||
}, _.noop);
|
||||
},
|
||||
|
||||
stat: function(path, opts, callback) {
|
||||
logger.debug('Stat', path);
|
||||
var ts = logger.ts();
|
||||
path = this._toFullPath(path);
|
||||
var that = this;
|
||||
that.logger.debug('Stat', path);
|
||||
var ts = that.logger.ts();
|
||||
path = that._toFullPath(path);
|
||||
DropboxLink.stat(path, function(err, stat) {
|
||||
if (stat && stat.isRemoved) {
|
||||
err = new Error('File removed');
|
||||
err.notFound = true;
|
||||
}
|
||||
logger.debug('Stated', path, stat ? stat.versionTag : null, logger.ts(ts));
|
||||
err = StorageDropbox._convertError(err);
|
||||
that.logger.debug('Stated', path, stat ? stat.versionTag : null, that.logger.ts(ts));
|
||||
err = that._convertError(err);
|
||||
if (callback) { callback(err, stat ? { rev: stat.versionTag } : null); }
|
||||
}, _.noop);
|
||||
},
|
||||
|
||||
save: function(path, opts, data, callback, rev) {
|
||||
logger.debug('Save', path, rev);
|
||||
var ts = logger.ts();
|
||||
path = this._toFullPath(path);
|
||||
var that = this;
|
||||
that.logger.debug('Save', path, rev);
|
||||
var ts = that.logger.ts();
|
||||
path = that._toFullPath(path);
|
||||
DropboxLink.saveFile(path, data, rev, function(err, stat) {
|
||||
logger.debug('Saved', path, logger.ts(ts));
|
||||
that.logger.debug('Saved', path, that.logger.ts(ts));
|
||||
if (!callback) { return; }
|
||||
err = StorageDropbox._convertError(err);
|
||||
err = that._convertError(err);
|
||||
callback(err, stat ? { rev: stat.versionTag } : null);
|
||||
}, _.noop);
|
||||
},
|
||||
|
@ -211,6 +211,6 @@ var StorageDropbox = {
|
|||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = StorageDropbox;
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
var Launcher = require('../comp/launcher'),
|
||||
Logger = require('../util/logger');
|
||||
var StorageBase = require('./storage-base'),
|
||||
Launcher = require('../comp/launcher');
|
||||
|
||||
var logger = new Logger('storage-file-cache');
|
||||
|
||||
var StorageFileCache = {
|
||||
var StorageFileCache = StorageBase.extend({
|
||||
name: 'cache',
|
||||
enabled: !!Launcher,
|
||||
system: true,
|
||||
|
@ -16,7 +14,7 @@ var StorageFileCache = {
|
|||
return Launcher.req('path').join(this.path, id);
|
||||
},
|
||||
|
||||
init: function(callback) {
|
||||
initFs: function(callback) {
|
||||
if (this.path) {
|
||||
return callback && callback();
|
||||
}
|
||||
|
@ -29,67 +27,70 @@ var StorageFileCache = {
|
|||
this.path = path;
|
||||
callback();
|
||||
} catch (e) {
|
||||
logger.error('Error opening local offline storage', e);
|
||||
this.logger.error('Error opening local offline storage', e);
|
||||
if (callback) { callback(e); }
|
||||
}
|
||||
},
|
||||
|
||||
save: function(id, opts, data, callback) {
|
||||
logger.debug('Save', id);
|
||||
this.init((function(err) {
|
||||
var that = this;
|
||||
that.logger.debug('Save', id);
|
||||
that.initFs(function(err) {
|
||||
if (err) {
|
||||
return callback && callback(err);
|
||||
}
|
||||
var ts = logger.ts();
|
||||
try {
|
||||
Launcher.writeFile(this.getPath(id), data);
|
||||
Launcher.writeFile(that.getPath(id), data);
|
||||
logger.debug('Saved', id, logger.ts(ts));
|
||||
if (callback) { callback(); }
|
||||
} catch (e) {
|
||||
logger.error('Error saving to cache', id, e);
|
||||
if (callback) { callback(e); }
|
||||
}
|
||||
}).bind(this));
|
||||
});
|
||||
},
|
||||
|
||||
load: function(id, opts, callback) {
|
||||
logger.debug('Load', id);
|
||||
this.init((function(err) {
|
||||
var that = this;
|
||||
that.logger.debug('Load', id);
|
||||
that.initFs(function(err) {
|
||||
if (err) {
|
||||
return callback && callback(null, err);
|
||||
}
|
||||
var ts = logger.ts();
|
||||
var ts = that.logger.ts();
|
||||
try {
|
||||
var data = Launcher.readFile(this.getPath(id));
|
||||
logger.debug('Loaded', id, logger.ts(ts));
|
||||
var data = Launcher.readFile(that.getPath(id));
|
||||
that.logger.debug('Loaded', id, that.logger.ts(ts));
|
||||
if (callback) { callback(null, data.buffer); }
|
||||
} catch (e) {
|
||||
logger.error('Error loading from cache', id, e);
|
||||
that.logger.error('Error loading from cache', id, e);
|
||||
if (callback) { callback(e, null); }
|
||||
}
|
||||
}).bind(this));
|
||||
});
|
||||
},
|
||||
|
||||
remove: function(id, opts, callback) {
|
||||
logger.debug('Remove', id);
|
||||
this.init((function(err) {
|
||||
var that = this;
|
||||
that.logger.debug('Remove', id);
|
||||
that.initFs(function(err) {
|
||||
if (err) {
|
||||
return callback && callback(err);
|
||||
}
|
||||
var ts = logger.ts();
|
||||
var ts = that.logger.ts();
|
||||
try {
|
||||
var path = this.getPath(id);
|
||||
var path = that.getPath(id);
|
||||
if (Launcher.fileExists(path)) {
|
||||
Launcher.deleteFile(path);
|
||||
}
|
||||
logger.debug('Removed', id, logger.ts(ts));
|
||||
that.logger.debug('Removed', id, that.logger.ts(ts));
|
||||
if (callback) { callback(); }
|
||||
} catch(e) {
|
||||
logger.error('Error removing from cache', id, e);
|
||||
that.logger.error('Error removing from cache', id, e);
|
||||
if (callback) { callback(e); }
|
||||
}
|
||||
}).bind(this));
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = StorageFileCache;
|
||||
|
|
|
@ -1,41 +1,39 @@
|
|||
'use strict';
|
||||
|
||||
var Launcher = require('../comp/launcher'),
|
||||
Logger = require('../util/logger');
|
||||
|
||||
var logger = new Logger('storage-file');
|
||||
var StorageBase = require('./storage-base'),
|
||||
Launcher = require('../comp/launcher');
|
||||
|
||||
var fileWatchers = {};
|
||||
|
||||
var StorageFile = {
|
||||
var StorageFile = StorageBase.extend({
|
||||
name: 'file',
|
||||
icon: 'hdd-o',
|
||||
enabled: !!Launcher,
|
||||
system: true,
|
||||
|
||||
load: function(path, opts, callback) {
|
||||
logger.debug('Load', path);
|
||||
var ts = logger.ts();
|
||||
this.logger.debug('Load', path);
|
||||
var ts = this.logger.ts();
|
||||
try {
|
||||
var data = Launcher.readFile(path);
|
||||
var rev = Launcher.statFile(path).mtime.getTime().toString();
|
||||
logger.debug('Loaded', path, rev, logger.ts(ts));
|
||||
this.logger.debug('Loaded', path, rev, this.logger.ts(ts));
|
||||
if (callback) { callback(null, data.buffer, { rev: rev }); }
|
||||
} catch (e) {
|
||||
logger.error('Error reading local file', path, e);
|
||||
this.logger.error('Error reading local file', path, e);
|
||||
if (callback) { callback(e, null); }
|
||||
}
|
||||
},
|
||||
|
||||
stat: function(path, opts, callback) {
|
||||
logger.debug('Stat', path);
|
||||
var ts = logger.ts();
|
||||
this.logger.debug('Stat', path);
|
||||
var ts = this.logger.ts();
|
||||
try {
|
||||
var stat = Launcher.statFile(path);
|
||||
logger.debug('Stat done', path, logger.ts(ts));
|
||||
this.logger.debug('Stat done', path, this.logger.ts(ts));
|
||||
if (callback) { callback(null, { rev: stat.mtime.getTime().toString() }); }
|
||||
} catch (e) {
|
||||
logger.error('Error stat local file', path, e);
|
||||
this.logger.error('Error stat local file', path, e);
|
||||
if (e.code === 'ENOENT') {
|
||||
e.notFound = true;
|
||||
}
|
||||
|
@ -44,15 +42,15 @@ var StorageFile = {
|
|||
},
|
||||
|
||||
save: function(path, opts, data, callback, rev) {
|
||||
logger.debug('Save', path, rev);
|
||||
var ts = logger.ts();
|
||||
this.logger.debug('Save', path, rev);
|
||||
var ts = this.logger.ts();
|
||||
try {
|
||||
if (rev) {
|
||||
try {
|
||||
var stat = Launcher.statFile(path);
|
||||
var fileRev = stat.mtime.getTime().toString();
|
||||
if (fileRev !== rev) {
|
||||
logger.debug('Save mtime differs', rev, fileRev);
|
||||
this.logger.debug('Save mtime differs', rev, fileRev);
|
||||
if (callback) { callback({ revConflict: true }, { rev: fileRev }); }
|
||||
return;
|
||||
}
|
||||
|
@ -62,10 +60,10 @@ var StorageFile = {
|
|||
}
|
||||
Launcher.writeFile(path, data);
|
||||
var newRev = Launcher.statFile(path).mtime.getTime().toString();
|
||||
logger.debug('Saved', path, logger.ts(ts));
|
||||
this.logger.debug('Saved', path, this.logger.ts(ts));
|
||||
if (callback) { callback(undefined, { rev: newRev }); }
|
||||
} catch (e) {
|
||||
logger.error('Error writing local file', path, e);
|
||||
this.logger.error('Error writing local file', path, e);
|
||||
if (callback) { callback(e); }
|
||||
}
|
||||
},
|
||||
|
@ -73,7 +71,7 @@ var StorageFile = {
|
|||
watch: function(path, callback) {
|
||||
var names = Launcher.parsePath(path);
|
||||
if (!fileWatchers[names.dir]) {
|
||||
logger.debug('Watch dir', names.dir);
|
||||
this.logger.debug('Watch dir', names.dir);
|
||||
var fsWatcher = Launcher.createFsWatcher(names.dir);
|
||||
fsWatcher.on('change', this.fsWatcherChange.bind(this, names.dir));
|
||||
fileWatchers[names.dir] = { fsWatcher: fsWatcher, callbacks: [] };
|
||||
|
@ -90,7 +88,7 @@ var StorageFile = {
|
|||
watcher.callbacks.splice(ix, 1);
|
||||
}
|
||||
if (!watcher.callbacks.length) {
|
||||
logger.debug('Stop watch dir', names.dir);
|
||||
this.logger.debug('Stop watch dir', names.dir);
|
||||
watcher.fsWatcher.close();
|
||||
delete fileWatchers[names.dir];
|
||||
}
|
||||
|
@ -99,15 +97,16 @@ var StorageFile = {
|
|||
|
||||
fsWatcherChange: function(dirname, evt, fileName) {
|
||||
var watcher = fileWatchers[dirname];
|
||||
var that = this;
|
||||
if (watcher) {
|
||||
watcher.callbacks.forEach(function(cb) {
|
||||
if (cb.file === fileName && typeof cb.callback === 'function') {
|
||||
logger.debug('File changed', dirname, evt, fileName);
|
||||
that.logger.debug('File changed', dirname, evt, fileName);
|
||||
cb.callback();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = StorageFile;
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
var Backbone = require('backbone'),
|
||||
Logger = require('../util/logger'),
|
||||
var StorageBase = require('./storage-base'),
|
||||
Backbone = require('backbone'),
|
||||
Timeouts = require('../const/timeouts');
|
||||
|
||||
var logger = new Logger('storage-gdrive');
|
||||
|
||||
var StorageGDrive = {
|
||||
var StorageGDrive = StorageBase.extend({
|
||||
name: 'gdrive',
|
||||
icon: '',
|
||||
enabled: true,
|
||||
|
@ -23,8 +21,8 @@ var StorageGDrive = {
|
|||
var that = this;
|
||||
that.stat(path, opts, function(err, stat) {
|
||||
if (err) { return callback && callback(err); }
|
||||
logger.debug('Load', path);
|
||||
var ts = logger.ts();
|
||||
that.logger.debug('Load', path);
|
||||
var ts = that.logger.ts();
|
||||
var url = 'https://www.googleapis.com/drive/v3/files/{id}/revisions/{rev}?alt=media'
|
||||
.replace('{id}', path)
|
||||
.replace('{rev}', stat.rev);
|
||||
|
@ -32,14 +30,14 @@ var StorageGDrive = {
|
|||
xhr.responseType = 'arraybuffer';
|
||||
xhr.addEventListener('load', function() {
|
||||
if (xhr.status !== 200) {
|
||||
logger.debug('Load error', path, 'http status ' + xhr.status, logger.ts(ts));
|
||||
that.logger.debug('Load error', path, 'http status ' + xhr.status, that.logger.ts(ts));
|
||||
return callback && callback('load error ' + xhr.status);
|
||||
}
|
||||
logger.debug('Loaded', path, stat.rev, logger.ts(ts));
|
||||
that.logger.debug('Loaded', path, stat.rev, that.logger.ts(ts));
|
||||
return callback && callback(null, xhr.response, { rev: stat.rev });
|
||||
});
|
||||
xhr.addEventListener('error', function() {
|
||||
logger.debug('Load error', path, logger.ts(ts));
|
||||
that.logger.debug('Load error', path, that.logger.ts(ts));
|
||||
return callback && callback('network error');
|
||||
});
|
||||
xhr.open('GET', url);
|
||||
|
@ -54,17 +52,17 @@ var StorageGDrive = {
|
|||
if (err) {
|
||||
return callback && callback(err);
|
||||
}
|
||||
logger.debug('Stat', path);
|
||||
var ts = logger.ts();
|
||||
that.logger.debug('Stat', path);
|
||||
var ts = that.logger.ts();
|
||||
that._gapi.client.drive.files.get({
|
||||
fileId: path,
|
||||
fields: 'headRevisionId'
|
||||
}).then(function (resp) {
|
||||
var rev = resp.result.headRevisionId;
|
||||
logger.debug('Stated', path, rev, logger.ts(ts));
|
||||
that.logger.debug('Stated', path, rev, that.logger.ts(ts));
|
||||
return callback && callback(null, { rev: rev });
|
||||
}, function(resp) {
|
||||
logger.error('Stat error', logger.ts(ts), resp.result.error);
|
||||
that.logger.error('Stat error', that.logger.ts(ts), resp.result.error);
|
||||
return callback && callback(resp.result.error.message || 'stat error');
|
||||
});
|
||||
});
|
||||
|
@ -79,8 +77,8 @@ var StorageGDrive = {
|
|||
return callback && callback({revConflict: true}, stat);
|
||||
}
|
||||
}
|
||||
logger.debug('Save', path);
|
||||
var ts = logger.ts();
|
||||
that.logger.debug('Save', path);
|
||||
var ts = that.logger.ts();
|
||||
var url = 'https://www.googleapis.com/upload/drive/v3/files/{id}?uploadType=media&fields=headRevisionId'
|
||||
.replace('{id}', path)
|
||||
.replace('{rev}', stat.rev);
|
||||
|
@ -88,10 +86,10 @@ var StorageGDrive = {
|
|||
xhr.responseType = 'json';
|
||||
xhr.addEventListener('load', function() {
|
||||
if (xhr.status !== 200) {
|
||||
logger.debug('Save error', path, 'http status ' + xhr.status, logger.ts(ts));
|
||||
that.logger.debug('Save error', path, 'http status ' + xhr.status, that.logger.ts(ts));
|
||||
return callback && callback('load error ' + xhr.status);
|
||||
}
|
||||
logger.debug('Saved', path, logger.ts(ts));
|
||||
that.logger.debug('Saved', path, that.logger.ts(ts));
|
||||
var newRev = xhr.response.headRevisionId;
|
||||
if (!newRev) {
|
||||
return callback && callback('save error: no rev');
|
||||
|
@ -99,7 +97,7 @@ var StorageGDrive = {
|
|||
return callback && callback(null, { rev: newRev });
|
||||
});
|
||||
xhr.addEventListener('error', function() {
|
||||
logger.debug('Save error', path, logger.ts(ts));
|
||||
that.logger.debug('Save error', path, that.logger.ts(ts));
|
||||
return callback && callback('network error');
|
||||
});
|
||||
xhr.open('PATCH', url);
|
||||
|
@ -113,13 +111,13 @@ var StorageGDrive = {
|
|||
var that = this;
|
||||
this._getClient(function(err) {
|
||||
if (err) { return callback && callback(err); }
|
||||
logger.debug('List');
|
||||
var ts = logger.ts();
|
||||
that.logger.debug('List');
|
||||
var ts = that.logger.ts();
|
||||
that._gapi.client.drive.files.list({
|
||||
fields: 'files',
|
||||
q: 'fileExtension="kdbx" and mimeType="application/octet-stream" and trashed=false'
|
||||
}).then(function(resp) {
|
||||
logger.debug('Listed', logger.ts(ts));
|
||||
that.logger.debug('Listed', that.logger.ts(ts));
|
||||
if (!resp.result.files) {
|
||||
return callback && callback('list error');
|
||||
}
|
||||
|
@ -132,7 +130,7 @@ var StorageGDrive = {
|
|||
});
|
||||
return callback && callback(null, fileList);
|
||||
}, function(resp) {
|
||||
logger.error('List error', logger.ts(ts), resp.result.error);
|
||||
that.logger.error('List error', that.logger.ts(ts), resp.result.error);
|
||||
return callback && callback(resp.result.error.message || 'list error');
|
||||
});
|
||||
});
|
||||
|
@ -150,34 +148,34 @@ var StorageGDrive = {
|
|||
if (that._gapi) {
|
||||
that._loadDriveApi(that._authorize.bind(that, callback));
|
||||
} else {
|
||||
logger.debug('Loading gapi client');
|
||||
that.logger.debug('Loading gapi client');
|
||||
window.gApiClientLoaded = function() {
|
||||
if (that._gapiLoadTimeout) {
|
||||
logger.debug('Loaded gapi client');
|
||||
that.logger.debug('Loaded gapi client');
|
||||
delete window.gDriveClientLoaded;
|
||||
that._gapi = window.gapi;
|
||||
that._loadDriveApi(that._authorize.bind(that, callback));
|
||||
}
|
||||
};
|
||||
$.getScript('https://apis.google.com/js/client.js?onload=gApiClientLoaded', function() {
|
||||
logger.debug('Loaded gapi script');
|
||||
that.logger.debug('Loaded gapi script');
|
||||
}).fail(function() {
|
||||
logger.error('Failed to load gapi');
|
||||
that.logger.error('Failed to load gapi');
|
||||
return callback('gapi load failed');
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_loadDriveApi: function(callback) {
|
||||
logger.debug('Loading gdrive api');
|
||||
var that = this;
|
||||
that.logger.debug('Loading gdrive api');
|
||||
this._gapi.client.load('drive', 'v3', function(result) {
|
||||
if (that._gapiLoadTimeout) {
|
||||
clearTimeout(that._gapiLoadTimeout);
|
||||
delete that._gapiLoadTimeout;
|
||||
logger.debug('Loaded gdrive api');
|
||||
that.logger.debug('Loaded gdrive api');
|
||||
if (result && result.error) {
|
||||
logger.error('Error loading gdrive api', result.error);
|
||||
that.logger.error('Error loading gdrive api', result.error);
|
||||
callback(result.error);
|
||||
} else {
|
||||
callback();
|
||||
|
@ -196,25 +194,25 @@ var StorageGDrive = {
|
|||
if (res && !res.error) {
|
||||
callback();
|
||||
} else {
|
||||
logger.debug('Authorizing...');
|
||||
that.logger.debug('Authorizing...');
|
||||
var handlePopupClosed = function() {
|
||||
logger.debug('Auth popup closed');
|
||||
that.logger.debug('Auth popup closed');
|
||||
Backbone.off('popup-closed', handlePopupClosed);
|
||||
callback('popup closed');
|
||||
callback = null;
|
||||
};
|
||||
Backbone.on('popup-closed', handlePopupClosed);
|
||||
var ts = logger.ts();
|
||||
var ts = that.logger.ts();
|
||||
that._gapi.auth.authorize({'client_id': that._clientId, scope: scopes, immediate: false}, function(res) {
|
||||
if (!callback) {
|
||||
return;
|
||||
}
|
||||
Backbone.off('popup-closed', handlePopupClosed);
|
||||
if (res && !res.error) {
|
||||
logger.debug('Authorized', logger.ts(ts));
|
||||
that.logger.debug('Authorized', that.logger.ts(ts));
|
||||
callback();
|
||||
} else {
|
||||
logger.error('Authorize error', logger.ts(ts), res);
|
||||
that.logger.error('Authorize error', that.logger.ts(ts), res);
|
||||
callback(res && res.error || 'authorize error');
|
||||
}
|
||||
});
|
||||
|
@ -227,6 +225,6 @@ var StorageGDrive = {
|
|||
var token = this._gapi.auth.getToken();
|
||||
return token.token_type + ' ' + token.access_token;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = StorageGDrive;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
//var Logger = require('../util/logger');
|
||||
var StorageBase = require('./storage-base');
|
||||
|
||||
//var logger = new Logger('storage-onedrive');
|
||||
|
||||
var StorageOneDrive = {
|
||||
var StorageOneDrive = StorageBase.extend({
|
||||
name: 'onedrive',
|
||||
icon: '',
|
||||
enabled: false,
|
||||
|
@ -33,6 +31,6 @@ var StorageOneDrive = {
|
|||
save: function(path, opts, data, callback/*, rev*/) {
|
||||
if (callback) { callback('not implemented'); }
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = StorageOneDrive;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
'use strict';
|
||||
|
||||
var Logger = require('../util/logger');
|
||||
var StorageBase = require('./storage-base');
|
||||
|
||||
var logger = new Logger('storage-webdav');
|
||||
|
||||
var StorageWebDav = {
|
||||
var StorageWebDav = StorageBase.extend({
|
||||
name: 'webdav',
|
||||
icon: 'server',
|
||||
enabled: true,
|
||||
|
@ -67,7 +65,7 @@ var StorageWebDav = {
|
|||
}, saveOpts), function(err, xhr, stat) {
|
||||
if (err) { return cb(err); }
|
||||
if (stat.rev !== rev) {
|
||||
logger.debug('Save error', path, 'rev conflict', stat.rev, rev);
|
||||
that.logger.debug('Save error', path, 'rev conflict', stat.rev, rev);
|
||||
return cb({ revConflict: true }, xhr, stat);
|
||||
}
|
||||
that._request(_.defaults({
|
||||
|
@ -82,7 +80,7 @@ var StorageWebDav = {
|
|||
return cb(err, xhr, stat);
|
||||
}
|
||||
if (stat.rev !== rev) {
|
||||
logger.debug('Save error', path, 'rev conflict', stat.rev, rev);
|
||||
that.logger.debug('Save error', path, 'rev conflict', stat.rev, rev);
|
||||
that._request(_.defaults({ op: 'Save:delete', method: 'DELETE', path: tmpPath }, saveOpts));
|
||||
return cb({ revConflict: true }, xhr, stat);
|
||||
}
|
||||
|
@ -131,16 +129,17 @@ var StorageWebDav = {
|
|||
},
|
||||
|
||||
_request: function(config, callback) {
|
||||
var that = this;
|
||||
if (config.rev) {
|
||||
logger.debug(config.op, config.path, config.rev);
|
||||
that.logger.debug(config.op, config.path, config.rev);
|
||||
} else {
|
||||
logger.debug(config.op, config.path);
|
||||
that.logger.debug(config.op, config.path);
|
||||
}
|
||||
var ts = logger.ts();
|
||||
var ts = that.logger.ts();
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.addEventListener('load', function() {
|
||||
if ([200, 201, 204].indexOf(xhr.status) < 0) {
|
||||
logger.debug(config.op + ' error', config.path, xhr.status, logger.ts(ts));
|
||||
that.logger.debug(config.op + ' error', config.path, xhr.status, that.logger.ts(ts));
|
||||
var err;
|
||||
switch (xhr.status) {
|
||||
case 404:
|
||||
|
@ -158,20 +157,20 @@ var StorageWebDav = {
|
|||
}
|
||||
var rev = xhr.getResponseHeader('Last-Modified');
|
||||
if (!rev && !config.nostat) {
|
||||
logger.debug(config.op + ' error', config.path, 'no headers', logger.ts(ts));
|
||||
that.logger.debug(config.op + ' error', config.path, 'no headers', that.logger.ts(ts));
|
||||
if (callback) { callback('No Last-Modified header', xhr); callback = null; }
|
||||
return;
|
||||
}
|
||||
var completedOpName = config.op + (config.op.charAt(config.op.length - 1) === 'e' ? 'd' : 'ed');
|
||||
logger.debug(completedOpName, config.path, rev, logger.ts(ts));
|
||||
that.logger.debug(completedOpName, config.path, rev, that.logger.ts(ts));
|
||||
if (callback) { callback(null, xhr, rev ? { rev: rev } : null); callback = null; }
|
||||
});
|
||||
xhr.addEventListener('error', function() {
|
||||
logger.debug(config.op + ' error', config.path, logger.ts(ts));
|
||||
that.logger.debug(config.op + ' error', config.path, that.logger.ts(ts));
|
||||
if (callback) { callback('network error', xhr); callback = null; }
|
||||
});
|
||||
xhr.addEventListener('abort', function() {
|
||||
logger.debug(config.op + ' error', config.path, 'aborted', logger.ts(ts));
|
||||
that.logger.debug(config.op + ' error', config.path, 'aborted', that.logger.ts(ts));
|
||||
if (callback) { callback('aborted', xhr); callback = null; }
|
||||
});
|
||||
xhr.responseType = 'arraybuffer';
|
||||
|
@ -191,6 +190,6 @@ var StorageWebDav = {
|
|||
xhr.send();
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
module.exports = StorageWebDav;
|
||||
|
|
Loading…
Reference in New Issue
Block a user