mirror of https://github.com/keeweb/keeweb.git
backupFile
This commit is contained in:
parent
26fad0c5fa
commit
24d18cd296
|
@ -317,6 +317,10 @@ var DropboxLink = {
|
|||
this._callAndHandleError('remove', [fileName], complete);
|
||||
},
|
||||
|
||||
mkdir: function(path, complete) {
|
||||
this._callAndHandleError('mkdir', [path], complete);
|
||||
},
|
||||
|
||||
canChooseFile: function() {
|
||||
return !Launcher;
|
||||
},
|
||||
|
|
|
@ -16,6 +16,7 @@ var Backbone = require('backbone'),
|
|||
Logger = require('../util/logger'),
|
||||
FeatureDetector = require('../util/feature-detector'),
|
||||
Format = require('../util/format'),
|
||||
UrlUtil = require('../util/url-util'),
|
||||
AutoType = require('../auto-type');
|
||||
|
||||
require('../mixins/protected-value-ex');
|
||||
|
@ -784,13 +785,47 @@ var AppModel = Backbone.Model.extend({
|
|||
}
|
||||
let path = backup.path.replace('{date}', Format.dtStrFs(new Date()));
|
||||
logger.info('Backup file to', backup.storage, path);
|
||||
Storage[backup.storage].save(path, opts, data, (err) => {
|
||||
if (err) {
|
||||
logger.error('Backup error', err);
|
||||
} else {
|
||||
logger.info('Backup complete');
|
||||
let saveToFolder = () => {
|
||||
if (Storage[backup.storage].getPathForName) {
|
||||
path = Storage[backup.storage].getPathForName(path);
|
||||
}
|
||||
Storage[backup.storage].save(path, opts, data, (err) => {
|
||||
if (err) {
|
||||
logger.error('Backup error', err);
|
||||
} else {
|
||||
logger.info('Backup complete');
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
};
|
||||
let folderPath = UrlUtil.fileToDir(path);
|
||||
if (Storage[backup.storage].getPathForName) {
|
||||
folderPath = Storage[backup.storage].getPathForName(folderPath).replace('.kdbx', '');
|
||||
}
|
||||
Storage[backup.storage].stat(folderPath, opts, (err) => {
|
||||
if (err) {
|
||||
if (err.notFound) {
|
||||
logger.info('Backup folder does not exist');
|
||||
if (!Storage[backup.storage].mkdir) {
|
||||
return callback('Mkdir not supported by ' + backup.storage);
|
||||
}
|
||||
Storage[backup.storage].mkdir(folderPath, (err) => {
|
||||
if (err) {
|
||||
logger.error('Error creating backup folder', err);
|
||||
callback('Error creating backup folder');
|
||||
} else {
|
||||
logger.info('Backup folder created');
|
||||
saveToFolder();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
logger.error('Stat folder error', err);
|
||||
callback('Cannot stat backup folder');
|
||||
}
|
||||
} else {
|
||||
logger.info('Backup folder exists, saving');
|
||||
saveToFolder();
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -215,6 +215,19 @@ var StorageDropbox = StorageBase.extend({
|
|||
}, _.noop);
|
||||
},
|
||||
|
||||
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);
|
||||
});
|
||||
},
|
||||
|
||||
setEnabled: function(enabled) {
|
||||
if (!enabled) {
|
||||
DropboxLink.logout();
|
||||
|
|
|
@ -71,52 +71,59 @@ var StorageGDrive = StorageBase.extend({
|
|||
},
|
||||
|
||||
save: function(path, opts, data, callback, rev) {
|
||||
this.stat(path, opts, (err, stat) => {
|
||||
if (rev) {
|
||||
if (err) { return callback && callback(err); }
|
||||
if (stat.rev !== rev) {
|
||||
return callback && callback({revConflict: true}, stat);
|
||||
}
|
||||
this._oauthAuthorize(err => {
|
||||
if (err) {
|
||||
return callback && callback(err);
|
||||
}
|
||||
this.logger.debug('Save', path);
|
||||
var ts = this.logger.ts();
|
||||
var isNew = path.lastIndexOf(NewFileIdPrefix, 0) === 0;
|
||||
var url;
|
||||
if (isNew) {
|
||||
url = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,headRevisionId';
|
||||
var fileName = path.replace(NewFileIdPrefix, '') + '.kdbx';
|
||||
var boundry = 'b' + Date.now() + 'x' + Math.round(Math.random() * 1000000);
|
||||
data = new Blob([
|
||||
'--', boundry, '\r\n',
|
||||
'Content-Type: application/json; charset=UTF-8', '\r\n\r\n',
|
||||
JSON.stringify({ name: fileName }), '\r\n',
|
||||
'--', boundry, '\r\n',
|
||||
'Content-Type: application/octet-stream', '\r\n\r\n',
|
||||
data, '\r\n',
|
||||
'--', boundry, '--', '\r\n'
|
||||
], {type: 'multipart/related; boundary="' + boundry + '"'});
|
||||
} else {
|
||||
url = 'https://www.googleapis.com/upload/drive/v3/files/{id}?uploadType=media&fields=headRevisionId'
|
||||
.replace('{id}', path);
|
||||
data = new Blob([data], {type: 'application/octet-stream'});
|
||||
}
|
||||
this._xhr({
|
||||
url: url,
|
||||
method: isNew ? 'POST' : 'PATCH',
|
||||
responseType: 'json',
|
||||
data: data,
|
||||
success: (response) => {
|
||||
this.logger.debug('Saved', path, this.logger.ts(ts));
|
||||
var newRev = response.headRevisionId;
|
||||
if (!newRev) {
|
||||
return callback && callback('save error: no rev');
|
||||
this.stat(path, opts, (err, stat) => {
|
||||
if (rev) {
|
||||
if (err) {
|
||||
return callback && callback(err);
|
||||
}
|
||||
if (stat.rev !== rev) {
|
||||
return callback && callback({ revConflict: true }, stat);
|
||||
}
|
||||
return callback && callback(null, { rev: newRev, path: isNew ? response.id : null });
|
||||
},
|
||||
error: (err) => {
|
||||
this.logger.error('Save error', path, err, this.logger.ts(ts));
|
||||
return callback && callback(err);
|
||||
}
|
||||
this.logger.debug('Save', path);
|
||||
var ts = this.logger.ts();
|
||||
var isNew = path.lastIndexOf(NewFileIdPrefix, 0) === 0;
|
||||
var url;
|
||||
if (isNew) {
|
||||
url = 'https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&fields=id,headRevisionId';
|
||||
var fileName = path.replace(NewFileIdPrefix, '') + '.kdbx';
|
||||
var boundry = 'b' + Date.now() + 'x' + Math.round(Math.random() * 1000000);
|
||||
data = new Blob([
|
||||
'--', boundry, '\r\n',
|
||||
'Content-Type: application/json; charset=UTF-8', '\r\n\r\n',
|
||||
JSON.stringify({ name: fileName }), '\r\n',
|
||||
'--', boundry, '\r\n',
|
||||
'Content-Type: application/octet-stream', '\r\n\r\n',
|
||||
data, '\r\n',
|
||||
'--', boundry, '--', '\r\n'
|
||||
], { type: 'multipart/related; boundary="' + boundry + '"' });
|
||||
} else {
|
||||
url = 'https://www.googleapis.com/upload/drive/v3/files/{id}?uploadType=media&fields=headRevisionId'
|
||||
.replace('{id}', path);
|
||||
data = new Blob([data], { type: 'application/octet-stream' });
|
||||
}
|
||||
this._xhr({
|
||||
url: url,
|
||||
method: isNew ? 'POST' : 'PATCH',
|
||||
responseType: 'json',
|
||||
data: data,
|
||||
success: (response) => {
|
||||
this.logger.debug('Saved', path, this.logger.ts(ts));
|
||||
var newRev = response.headRevisionId;
|
||||
if (!newRev) {
|
||||
return callback && callback('save error: no rev');
|
||||
}
|
||||
return callback && callback(null, { rev: newRev, path: isNew ? response.id : null });
|
||||
},
|
||||
error: (err) => {
|
||||
this.logger.error('Save error', path, err, this.logger.ts(ts));
|
||||
return callback && callback(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
|
|
@ -190,6 +190,31 @@ var StorageOneDrive = StorageBase.extend({
|
|||
});
|
||||
},
|
||||
|
||||
mkdir: function(path, callback) {
|
||||
this._oauthAuthorize(err => {
|
||||
if (err) { return callback && callback(err); }
|
||||
this.logger.debug('Make dir', path);
|
||||
var ts = this.logger.ts();
|
||||
var url = this._baseUrl + '/drive/root/children';
|
||||
var data = JSON.stringify({ name: path.replace('/drive/root:/', ''), folder: {} });
|
||||
this._xhr({
|
||||
url: url,
|
||||
method: 'POST',
|
||||
responseType: 'json',
|
||||
statuses: [200, 204],
|
||||
data: new Blob([data], {type: 'application/json'}),
|
||||
success: () => {
|
||||
this.logger.debug('Made dir', path, this.logger.ts(ts));
|
||||
return callback && callback();
|
||||
},
|
||||
error: (err) => {
|
||||
this.logger.error('Make dir error', path, err, this.logger.ts(ts));
|
||||
return callback && callback(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
setEnabled: function(enabled) {
|
||||
if (!enabled) {
|
||||
var url = 'https://login.live.com/oauth20_logout.srf?client_id={client_id}&redirect_uri={url}'
|
||||
|
|
Loading…
Reference in New Issue