1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-11-29 22:48:10 +02:00

Allow cancelling sync and fixed resource issue

This commit is contained in:
Laurent Cozic
2017-07-09 16:47:05 +01:00
parent de16573742
commit 297edfa682
11 changed files with 210 additions and 33 deletions

View File

@@ -90,8 +90,8 @@ android {
applicationId "net.cozic.joplin"
minSdkVersion 16
targetSdkVersion 22
versionCode 2
versionName "0.8.0"
versionCode 3
versionName "0.8.1"
ndk {
abiFilters "armeabi-v7a", "x86"
}

View File

@@ -1,6 +1,7 @@
import { shim } from 'lib/shim.js';
import { stringify } from 'query-string';
import { time } from 'lib/time-utils.js';
import { Logger } from 'lib/logger.js'
class OneDriveApi {
@@ -16,6 +17,15 @@ class OneDriveApi {
this.listeners_ = {
'authRefreshed': [],
};
this.logger_ = new Logger();
}
setLogger(l) {
this.logger_ = l;
}
logger() {
return this.logger_;
}
isPublic() {
@@ -161,17 +171,19 @@ class OneDriveApi {
let error = this.oneDriveErrorResponseToError(errorResponse);
if (error.code == 'InvalidAuthenticationToken' || error.code == 'unauthenticated') {
this.logger().info('Token expired: refreshing...');
await this.refreshAccessToken();
continue;
} else if (error && ((error.error && error.error.code == 'generalException') || (error.code == 'generalException'))) {
// Rare error (one Google hit) - I guess the request can be repeated
// { error:
// { code: 'generalException',
// message: 'An error occurred in the data store.',
// innerError:
// { 'request-id': 'b4310552-c18a-45b1-bde1-68e2c2345eef',
// date: '2017-06-29T00:15:50' } } }
this.logger().info('Got error below - retrying...');
this.logger().info(error);
await time.msleep(1000 * i);
continue;
} else if (error.code == 'EAGAIN') {
@@ -181,6 +193,8 @@ class OneDriveApi {
// type: 'system',
// errno: 'EAGAIN',
// code: 'EAGAIN' }
this.logger().info('Got error below - retrying...');
this.logger().info(error);
await time.msleep(1000 * i);
continue;
} else {

View File

@@ -16,12 +16,17 @@ reg.logger = () => {
return reg.logger_;
}
reg.setLogger = (l) => {
reg.logger_ = l;
}
reg.oneDriveApi = () => {
if (reg.oneDriveApi_) return reg.oneDriveApi_;
const isPublic = Setting.value('appType') != 'cli';
reg.oneDriveApi_ = new OneDriveApi(parameters().oneDrive.id, parameters().oneDrive.secret, isPublic);
reg.oneDriveApi_.setLogger(reg.logger());
reg.oneDriveApi_.on('authRefreshed', (a) => {
reg.logger().info('Saving updated OneDrive auth.');

View File

@@ -18,6 +18,7 @@ class Synchronizer {
this.resourceDirName_ = '.resource';
this.logger_ = new Logger();
this.appType_ = appType;
this.cancelling_ = false;
}
state() {
@@ -86,6 +87,17 @@ class Synchronizer {
return false;
}
cancel() {
if (this.cancelling_) return;
this.logger().info('Cancelling synchronization...');
this.cancelling_ = true;
}
cancelling() {
return this.cancelling_;
}
async start(options = null) {
if (!options) options = {};
if (!options.onProgress) options.onProgress = function(o) {};
@@ -96,6 +108,7 @@ class Synchronizer {
}
this.randomFailureChoice_ = Math.floor(Math.random() * 5);
this.cancelling_ = false;
// ------------------------------------------------------------------------
// First, find all the items that have been changed since the
@@ -131,6 +144,8 @@ class Synchronizer {
let donePaths = [];
while (true) {
if (this.cancelling()) break;
let result = await BaseItem.itemsThatNeedSync();
let locals = result.items;
@@ -138,6 +153,8 @@ class Synchronizer {
options.onProgress(report);
for (let i = 0; i < locals.length; i++) {
if (this.cancelling()) break;
let local = locals[i];
let ItemClass = BaseItem.itemClass(local);
let path = BaseItem.systemPath(local);
@@ -249,6 +266,8 @@ class Synchronizer {
report.remotesToDelete = deletedItems.length;
options.onProgress(report);
for (let i = 0; i < deletedItems.length; i++) {
if (this.cancelling()) break;
let item = deletedItems[i];
let path = BaseItem.systemPath(item.item_id)
this.logSyncOperation('deleteRemote', null, { id: item.item_id }, 'local has been deleted');
@@ -272,9 +291,13 @@ class Synchronizer {
let context = null;
while (true) {
if (this.cancelling()) break;
let listResult = await this.api().list('', { context: context });
let remotes = listResult.items;
for (let i = 0; i < remotes.length; i++) {
if (this.cancelling()) break;
let remote = remotes[i];
let path = remote.path;
@@ -319,14 +342,17 @@ class Synchronizer {
if (newContent.type_ == BaseModel.TYPE_RESOURCE && action == 'createLocal') {
let localResourceContentPath = Resource.fullPath(newContent);
let remoteResourceContentPath = this.resourceDirName_ + '/' + newContent.id;
if (this.appType_ == 'cli') {
let remoteResourceContent = await this.api().get(remoteResourceContentPath, { encoding: 'binary' });
await Resource.setContent(newContent, remoteResourceContent);
} else if (this.appType_ == 'mobile') {
await this.api().get(remoteResourceContentPath, { path: localResourceContentPath, target: 'file' });
} else {
throw new Error('Unknown appType: ' + this.appType_);
}
await this.api().get(remoteResourceContentPath, { path: localResourceContentPath, target: 'file' });
// if (this.appType_ == 'cli') {
// let remoteResourceContent = await this.api().get(remoteResourceContentPath, { encoding: 'binary' });
// await Resource.setContent(newContent, remoteResourceContent);
// } else if (this.appType_ == 'mobile') {
// await this.api().get(remoteResourceContentPath, { path: localResourceContentPath, target: 'file' });
// } else {
// throw new Error('Unknown appType: ' + this.appType_);
// }
}
await ItemClass.save(newContent, options);
@@ -352,18 +378,22 @@ class Synchronizer {
if (this.randomFailure(options, 4)) return;
let items = await BaseItem.syncedItems();
for (let i = 0; i < items.length; i++) {
let item = items[i];
if (remoteIds.indexOf(item.id) < 0) {
report.localsToDelete++;
options.onProgress(report);
this.logSyncOperation('deleteLocal', { id: item.id }, null, 'remote has been deleted');
if (!this.cancelling()) {
let items = await BaseItem.syncedItems();
for (let i = 0; i < items.length; i++) {
if (this.cancelling()) break;
let ItemClass = BaseItem.itemClass(item);
await ItemClass.delete(item.id, { trackDeleted: false });
report['deleteLocal']++;
options.onProgress(report);
let item = items[i];
if (remoteIds.indexOf(item.id) < 0) {
report.localsToDelete++;
options.onProgress(report);
this.logSyncOperation('deleteLocal', { id: item.id }, null, 'remote has been deleted');
let ItemClass = BaseItem.itemClass(item);
await ItemClass.delete(item.id, { trackDeleted: false });
report['deleteLocal']++;
options.onProgress(report);
}
}
}
} catch (error) {
@@ -371,6 +401,11 @@ class Synchronizer {
throw error;
}
if (this.cancelling()) {
this.logger().info('Synchronization was cancelled.');
this.cancelling_ = false;
}
this.logger().info('Synchronization complete [' + synchronizationId + ']:');
await this.logSyncSummary(report);

View File

@@ -1,2 +1,3 @@
@echo off
npm start -- --reset-cache
npm start -- --reset-cache
rem "c:\Program Files (x86)\Yarn\bin\yarn.cmd" start -- --reset-cache