sync bugfixes

This commit is contained in:
Antelle 2015-12-11 23:51:16 +03:00
parent 56b7feea9f
commit 5bd6cf88b4
10 changed files with 63 additions and 24 deletions

6
.idea/encodings.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

View File

@ -121,6 +121,7 @@ DropboxChooser.prototype.readFile = function(url) {
}; };
var DropboxLink = { var DropboxLink = {
ERROR_CONFLICT: Dropbox.ApiError.CONFLICT,
_getClient: function(complete) { _getClient: function(complete) {
if (this._dropboxClient && this._dropboxClient.isAuthenticated()) { if (this._dropboxClient && this._dropboxClient.isAuthenticated()) {
complete(null, this._dropboxClient); complete(null, this._dropboxClient);
@ -199,6 +200,8 @@ var DropboxLink = {
body: 'Something went wrong during Dropbox sync. Please, try again later. Error code: ' + err.status body: 'Something went wrong during Dropbox sync. Please, try again later. Error code: ' + err.status
}); });
break; break;
case Dropbox.ApiError.CONFLICT:
break;
default: default:
alertCallback({ alertCallback({
header: 'Dropbox Sync Error', header: 'Dropbox Sync Error',
@ -241,7 +244,7 @@ var DropboxLink = {
saveFile: function(fileName, data, rev, complete) { saveFile: function(fileName, data, rev, complete) {
if (rev) { if (rev) {
var opts = typeof rev === 'string' ? { lastVersionTag: rev } : undefined; var opts = typeof rev === 'string' ? { lastVersionTag: rev, noOverwrite: true, noAutoRename: true } : undefined;
this._callAndHandleError('writeFile', [fileName, data, opts], complete); this._callAndHandleError('writeFile', [fileName, data, opts], complete);
} else { } else {
this.getFileList((function(err, files) { this.getFileList((function(err, files) {

View File

@ -322,7 +322,10 @@ var AppModel = Backbone.Model.extend({
file.setLocalEditState(fileInfo.get('editState')); file.setLocalEditState(fileInfo.get('editState'));
} }
file.set('modified', true); file.set('modified', true);
setTimeout(this.syncFile.bind(this, file), 0); setTimeout(that.syncFile.bind(that, file), 0);
}
if (fileInfo) {
file.set('syncDate', fileInfo.get('syncDate'));
} }
var cacheId = fileInfo && fileInfo.id || IdGenerator.uuid(); var cacheId = fileInfo && fileInfo.id || IdGenerator.uuid();
if (updateCacheOnSuccess && params.storage !== 'file') { if (updateCacheOnSuccess && params.storage !== 'file') {
@ -350,7 +353,7 @@ var AppModel = Backbone.Model.extend({
modified: file.get('modified'), modified: file.get('modified'),
editState: file.getLocalEditState(), editState: file.getLocalEditState(),
rev: rev, rev: rev,
pullDate: dt, syncDate: file.get('syncDate') || dt,
openDate: dt openDate: dt
}); });
this.fileInfos.remove(id); this.fileInfos.remove(id);
@ -365,6 +368,10 @@ var AppModel = Backbone.Model.extend({
}, },
syncFile: function(file, options, callback) { syncFile: function(file, options, callback) {
var that = this;
if (file.get('demo')) {
return callback && callback();
}
if (file.get('syncing')) { if (file.get('syncing')) {
return callback && callback('Sync in progress'); return callback && callback('Sync in progress');
} }
@ -382,12 +389,13 @@ var AppModel = Backbone.Model.extend({
modified: file.get('modified'), modified: file.get('modified'),
editState: null, editState: null,
rev: null, rev: null,
pullDate: dt, syncDate: dt,
openDate: dt openDate: dt
}); });
} }
var storage = Storage[options.storage || file.get('storage')]; var storage = options.storage || file.get('storage');
var path = options.path || file.get('path'); var path = options.path || file.get('path');
file.setSyncProgress();
var complete = function(err, savedToCache) { var complete = function(err, savedToCache) {
if (!err) { savedToCache = true; } if (!err) { savedToCache = true; }
file.setSyncComplete(path, storage, err ? err.toString() : null, savedToCache); file.setSyncComplete(path, storage, err ? err.toString() : null, savedToCache);
@ -395,12 +403,13 @@ var AppModel = Backbone.Model.extend({
storage: storage, storage: storage,
path: path, path: path,
modified: file.get('modified'), modified: file.get('modified'),
editState: file.getLocalEditState() editState: file.getLocalEditState(),
syncDate: file.get('syncDate')
}); });
if (!this.fileInfos.get(id)) { if (!that.fileInfos.get(fileInfo.id)) {
this.fileInfos.unshift(fileInfo); that.fileInfos.unshift(fileInfo);
} }
this.fileInfos.save(); that.fileInfos.save();
if (callback) { callback(err); } if (callback) { callback(err); }
}; };
if (!storage) { if (!storage) {
@ -419,16 +428,22 @@ var AppModel = Backbone.Model.extend({
if (++loadLoops === maxLoadLoops) { if (++loadLoops === maxLoadLoops) {
return complete('Too many load attempts, please try again later'); return complete('Too many load attempts, please try again later');
} }
storage.load(path, function(err, data, stat) { Storage[storage].load(path, function(err, data, stat) {
if (err) { return complete(err); } if (err) { return complete(err); }
file.mergeOrUpdate(data, function(err) { file.mergeOrUpdate(data, function(err) {
if (err) { return complete(err); } if (err) { return complete(err); }
if (stat && stat.rev) { if (stat && stat.rev) {
fileInfo.set('rev', stat.rev); fileInfo.set('rev', stat.rev);
} }
fileInfo.set('pullDate', new Date()); file.set('syncDate', new Date());
if (file.get('modified')) { if (file.get('modified')) {
saveToCacheAndStorage(); saveToCacheAndStorage();
} else if (file.get('dirty') && storage !== 'file') {
Storage.cache.save(fileInfo.id, data, function (err) {
if (err) { return complete(err); }
file.set('dirty', false);
complete();
});
} else { } else {
complete(); complete();
} }
@ -438,7 +453,7 @@ var AppModel = Backbone.Model.extend({
var saveToCacheAndStorage = function() { var saveToCacheAndStorage = function() {
file.getData(function(data, err) { file.getData(function(data, err) {
if (err) { return complete(err); } if (err) { return complete(err); }
if (!file.get('dirty') || storage === Storage.file) { if (!file.get('dirty') || storage === 'file') {
saveToStorage(data); saveToStorage(data);
} else { } else {
Storage.cache.save(fileInfo.id, data, function (err) { Storage.cache.save(fileInfo.id, data, function (err) {
@ -450,31 +465,40 @@ var AppModel = Backbone.Model.extend({
}); });
}; };
var saveToStorage = function(data) { var saveToStorage = function(data) {
storage.save(path, data, function(err) { Storage[storage].save(path, data, function(err) {
if (err && err.revConflict) { if (err && err.revConflict) {
loadFromStorageAndMerge(); loadFromStorageAndMerge();
} else if (err) { } else if (err) {
complete(err); complete(err);
} else { } else {
if (storage === Storage.file) { if (storage === 'file') {
Storage.cache.remove(fileInfo.id); Storage.cache.remove(fileInfo.id);
} }
file.set('syncDate', new Date());
complete(); complete();
} }
}, fileInfo.get('rev')); }, fileInfo.get('rev'));
}; };
if (options.reload) { if (options.reload) {
loadFromStorageAndMerge(); loadFromStorageAndMerge();
} else if (storage === Storage.file) { } else if (storage === 'file') {
if (file.get('modified')) { if (file.get('modified')) {
saveToCacheAndStorage(); saveToCacheAndStorage();
} else { } else {
complete(); complete();
} }
} else { } else {
storage.stat(path, function (err, stat) { Storage[storage].stat(path, function (err, stat) {
if (err) {
// TODO: save to cache if storage save failed
return complete(err);
}
if (stat.rev === fileInfo.get('rev')) { if (stat.rev === fileInfo.get('rev')) {
saveToCacheAndStorage(); if (file.get('modified')) {
saveToCacheAndStorage();
} else {
complete();
}
} else { } else {
loadFromStorageAndMerge(); loadFromStorageAndMerge();
} }

View File

@ -11,7 +11,7 @@ var FileInfoModel = Backbone.Model.extend({
modified: false, modified: false,
editState: null, editState: null,
rev: null, rev: null,
pullDate: null, syncDate: null,
openDate: null openDate: null
}, },

View File

@ -26,7 +26,8 @@ var FileModel = Backbone.Model.extend({
passwordChanged: false, passwordChanged: false,
keyFileChanged: false, keyFileChanged: false,
syncing: false, syncing: false,
syncError: null syncError: null,
syncDate: null
}, },
db: null, db: null,

View File

@ -19,7 +19,13 @@ var StorageDropbox = {
}, },
save: function(path, data, callback, rev) { save: function(path, data, callback, rev) {
DropboxLink.saveFile(path, data, rev, callback || _.noop); DropboxLink.saveFile(path, data, rev, function(err) {
if (!callback) { return; }
if (err && err.status === DropboxLink.ERROR_CONFLICT) {
err = { revConflict: true };
}
callback(err);
});
} }
}; };

View File

@ -323,7 +323,7 @@ var AppView = Backbone.View.extend({
} }
}, },
saveAndLock: function(autoInit) { saveAndLock: function(/*autoInit*/) {
var pendingCallbacks = 0, var pendingCallbacks = 0,
errorFiles = [], errorFiles = [],
that = this; that = this;

View File

@ -183,7 +183,7 @@ var SettingsAboutView = Backbone.View.extend({
that.render(); that.render();
return; return;
} }
this.save({ storage: 'dropbox' }); that.save({ storage: 'dropbox' });
}); });
}, },

View File

@ -26,7 +26,7 @@
"backbone": "~1.2.3", "backbone": "~1.2.3",
"baron": "~1.0.1", "baron": "~1.0.1",
"bourbon": "~4.2.5", "bourbon": "~4.2.5",
"dropbox": "antelle/dropbox-js#0.10.5", "dropbox": "antelle/dropbox-js#0.10.6",
"font-awesome": "~4.4.0", "font-awesome": "~4.4.0",
"install": "~1.0.4", "install": "~1.0.4",
"kdbxweb": "~0.3.1", "kdbxweb": "~0.3.1",

View File

@ -10,6 +10,5 @@
<excludeFolder url="file://$MODULE_DIR$/tmp" /> <excludeFolder url="file://$MODULE_DIR$/tmp" />
</content> </content>
<orderEntry type="sourceFolder" forTests="false" /> <orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="keeweb node_modules" level="project" />
</component> </component>
</module> </module>