mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Simplified sync logging and reporting
This commit is contained in:
parent
18b5453146
commit
f840dd505f
@ -22,14 +22,12 @@ class Command extends BaseCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async action(args) {
|
async action(args) {
|
||||||
|
let sync = await app().synchronizer(Setting.value('sync.target'));
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
onProgress: (report) => {
|
onProgress: (report) => {
|
||||||
let line = [];
|
let lines = sync.reportToLines(report);
|
||||||
if (report.remotesToUpdate) line.push(_('Items to upload: %d/%d.', report.createRemote + report.updateRemote, report.remotesToUpdate));
|
if (lines.length) vorpalUtils.redraw(lines.join(' '));
|
||||||
if (report.remotesToDelete) line.push(_('Remote items to delete: %d/%d.', report.deleteRemote, report.remotesToDelete));
|
|
||||||
if (report.localsToUdpate) line.push(_('Items to download: %d/%d.', report.createLocal + report.updateLocal, report.localsToUdpate));
|
|
||||||
if (report.localsToDelete) line.push(_('Local items to delete: %d/%d.', report.deleteLocal, report.localsToDelete));
|
|
||||||
if (line.length) vorpalUtils.redraw(line.join(' '));
|
|
||||||
},
|
},
|
||||||
onMessage: (msg) => {
|
onMessage: (msg) => {
|
||||||
vorpalUtils.redrawDone();
|
vorpalUtils.redrawDone();
|
||||||
@ -40,7 +38,6 @@ class Command extends BaseCommand {
|
|||||||
|
|
||||||
this.log(_('Synchronization target: %s', Setting.value('sync.target')));
|
this.log(_('Synchronization target: %s', Setting.value('sync.target')));
|
||||||
|
|
||||||
let sync = await app().synchronizer(Setting.value('sync.target'));
|
|
||||||
if (!sync) throw new Error(_('Cannot initialize synchronizer.'));
|
if (!sync) throw new Error(_('Cannot initialize synchronizer.'));
|
||||||
|
|
||||||
this.log(_('Starting synchronization...'));
|
this.log(_('Starting synchronization...'));
|
||||||
|
@ -5,7 +5,7 @@ const vorpalUtils = {};
|
|||||||
|
|
||||||
let vorpal_ = null;
|
let vorpal_ = null;
|
||||||
let redrawStarted_ = false;
|
let redrawStarted_ = false;
|
||||||
let redrawLastUpdateTime_ = time.unixMs();
|
let redrawLastUpdateTime_ = 0;
|
||||||
let redrawLastLog_ = null;
|
let redrawLastLog_ = null;
|
||||||
let redrawEnabled_ = true;
|
let redrawEnabled_ = true;
|
||||||
let errorStackTraceEnabled_ = false;
|
let errorStackTraceEnabled_ = false;
|
||||||
|
@ -53,20 +53,16 @@ class SideMenuContentComponent extends Component {
|
|||||||
|
|
||||||
async synchronize_press() {
|
async synchronize_press() {
|
||||||
if (reg.oneDriveApi().auth()) {
|
if (reg.oneDriveApi().auth()) {
|
||||||
|
const sync = await reg.synchronizer()
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
onProgress: (report) => {
|
onProgress: (report) => {
|
||||||
let line = [];
|
let lines = sync.reportToLines(report);
|
||||||
line.push(_('Items to upload: %d/%d.', report.createRemote + report.updateRemote, report.remotesToUpdate));
|
this.setState({ syncReportText: lines.join("\n") });
|
||||||
line.push(_('Remote items to delete: %d/%d.', report.deleteRemote, report.remotesToDelete));
|
|
||||||
line.push(_('Items to download: %d/%d.', report.createLocal + report.updateLocal, report.localsToUdpate));
|
|
||||||
line.push(_('Local items to delete: %d/%d.', report.deleteLocal, report.localsToDelete));
|
|
||||||
line.push(_('Sync state: %s.', report.state));
|
|
||||||
this.setState({ syncReportText: line.join("\n") });
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const sync = await reg.synchronizer()
|
|
||||||
sync.start(options);
|
sync.start(options);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Log.error(error);
|
Log.error(error);
|
||||||
|
@ -6,6 +6,7 @@ import { BaseModel } from 'lib/base-model.js';
|
|||||||
import { sprintf } from 'sprintf-js';
|
import { sprintf } from 'sprintf-js';
|
||||||
import { time } from 'lib/time-utils.js';
|
import { time } from 'lib/time-utils.js';
|
||||||
import { Logger } from 'lib/logger.js'
|
import { Logger } from 'lib/logger.js'
|
||||||
|
import { _ } from 'lib/locale.js';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
|
||||||
class Synchronizer {
|
class Synchronizer {
|
||||||
@ -19,6 +20,9 @@ class Synchronizer {
|
|||||||
this.logger_ = new Logger();
|
this.logger_ = new Logger();
|
||||||
this.appType_ = appType;
|
this.appType_ = appType;
|
||||||
this.cancelling_ = false;
|
this.cancelling_ = false;
|
||||||
|
|
||||||
|
this.onProgress_ = function(s) {};
|
||||||
|
this.progressReport_ = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
state() {
|
state() {
|
||||||
@ -41,10 +45,22 @@ class Synchronizer {
|
|||||||
return this.logger_;
|
return this.logger_;
|
||||||
}
|
}
|
||||||
|
|
||||||
logSyncOperation(action, local, remote, reason) {
|
reportToLines(report) {
|
||||||
|
let lines = [];
|
||||||
|
if (report.createLocal) lines.push(_('Created local items: %d.', report.createLocal));
|
||||||
|
if (report.updateLocal) lines.push(_('Updated local items: %d.', report.updateLocal));
|
||||||
|
if (report.createRemote) lines.push(_('Created remote items: %d.', report.createRemote));
|
||||||
|
if (report.updatedRemote) lines.push(_('Updated remote items: %d.', report.updatedRemote));
|
||||||
|
if (report.deleteLocal) lines.push(_('Deleted local items: %d.', report.deleteLocal));
|
||||||
|
if (report.deleteRemote) lines.push(_('Deleted remote items: %d.', report.deleteRemote));
|
||||||
|
if (report.state) lines.push(_('State: %s.', report.state));
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
logSyncOperation(action, local = null, remote = null, message = null) {
|
||||||
let line = ['Sync'];
|
let line = ['Sync'];
|
||||||
line.push(action);
|
line.push(action);
|
||||||
line.push(reason);
|
if (message) line.push(message);
|
||||||
|
|
||||||
let type = local && local.type_ ? local.type_ : null;
|
let type = local && local.type_ ? local.type_ : null;
|
||||||
if (!type) type = remote && remote.type_ ? remote.type_ : null;
|
if (!type) type = remote && remote.type_ ? remote.type_ : null;
|
||||||
@ -66,9 +82,15 @@ class Synchronizer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.logger().debug(line.join(': '));
|
this.logger().debug(line.join(': '));
|
||||||
|
|
||||||
|
if (!this.progressReport_[action]) this.progressReport_[action] = 0;
|
||||||
|
this.progressReport_[action]++;
|
||||||
|
this.progressReport_.state = this.state();
|
||||||
|
this.onProgress_(this.progressReport_);
|
||||||
}
|
}
|
||||||
|
|
||||||
async logSyncSummary(report) {
|
async logSyncSummary(report) {
|
||||||
|
this.logger().info('Operations completed: ');
|
||||||
for (let n in report) {
|
for (let n in report) {
|
||||||
if (!report.hasOwnProperty(n)) continue;
|
if (!report.hasOwnProperty(n)) continue;
|
||||||
if (n == 'errors') continue;
|
if (n == 'errors') continue;
|
||||||
@ -81,11 +103,10 @@ class Synchronizer {
|
|||||||
this.logger().info('Total notes: ' + noteCount);
|
this.logger().info('Total notes: ' + noteCount);
|
||||||
this.logger().info('Total resources: ' + resourceCount);
|
this.logger().info('Total resources: ' + resourceCount);
|
||||||
|
|
||||||
if (report.errors.length) {
|
if (report.errors && report.errors.length) {
|
||||||
this.logger().warn('There was some errors:');
|
this.logger().warn('There was some errors:');
|
||||||
for (let i = 0; i < report.errors.length; i++) {
|
for (let i = 0; i < report.errors.length; i++) {
|
||||||
let e = report.errors[i];
|
let e = report.errors[i];
|
||||||
//let msg = JSON.stringify(e); //e && e.message ? e.message : JSON.stringify(e);
|
|
||||||
this.logger().warn(e);
|
this.logger().warn(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +136,8 @@ class Synchronizer {
|
|||||||
|
|
||||||
async start(options = null) {
|
async start(options = null) {
|
||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
if (!options.onProgress) options.onProgress = function(o) {};
|
this.onProgress_ = options.onProgress ? options.onProgress : function(o) {};
|
||||||
|
this.progressReport_ = { errors: [] };
|
||||||
|
|
||||||
if (this.state() != 'idle') {
|
if (this.state() != 'idle') {
|
||||||
this.logger().warn('Synchronization is already in progress. State: ' + this.state());
|
this.logger().warn('Synchronization is already in progress. State: ' + this.state());
|
||||||
@ -131,28 +153,10 @@ class Synchronizer {
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
let synchronizationId = time.unixMs().toString();
|
let synchronizationId = time.unixMs().toString();
|
||||||
this.logger().info('Starting synchronization... [' + synchronizationId + ']');
|
|
||||||
|
|
||||||
this.state_ = 'started';
|
this.state_ = 'started';
|
||||||
|
|
||||||
let report = {
|
this.logSyncOperation('starting', null, null, 'Starting synchronization... [' + synchronizationId + ']');
|
||||||
remotesToUpdate: 0,
|
|
||||||
remotesToDelete: 0,
|
|
||||||
localsToUdpate: 0,
|
|
||||||
localsToDelete: 0,
|
|
||||||
|
|
||||||
createLocal: 0,
|
|
||||||
updateLocal: 0,
|
|
||||||
deleteLocal: 0,
|
|
||||||
createRemote: 0,
|
|
||||||
updateRemote: 0,
|
|
||||||
deleteRemote: 0,
|
|
||||||
itemConflict: 0,
|
|
||||||
noteConflict: 0,
|
|
||||||
|
|
||||||
state: this.state(),
|
|
||||||
errors: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.api().mkdir(this.syncDirName_);
|
await this.api().mkdir(this.syncDirName_);
|
||||||
@ -165,9 +169,6 @@ class Synchronizer {
|
|||||||
let result = await BaseItem.itemsThatNeedSync();
|
let result = await BaseItem.itemsThatNeedSync();
|
||||||
let locals = result.items;
|
let locals = result.items;
|
||||||
|
|
||||||
report.remotesToUpdate += locals.length;
|
|
||||||
options.onProgress(report);
|
|
||||||
|
|
||||||
for (let i = 0; i < locals.length; i++) {
|
for (let i = 0; i < locals.length; i++) {
|
||||||
if (this.cancelling()) break;
|
if (this.cancelling()) break;
|
||||||
|
|
||||||
@ -273,11 +274,7 @@ class Synchronizer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
report[action]++;
|
|
||||||
|
|
||||||
donePaths.push(path);
|
donePaths.push(path);
|
||||||
|
|
||||||
options.onProgress(report);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!result.hasMore) break;
|
if (!result.hasMore) break;
|
||||||
@ -288,8 +285,6 @@ class Synchronizer {
|
|||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
let deletedItems = await BaseItem.deletedItems();
|
let deletedItems = await BaseItem.deletedItems();
|
||||||
report.remotesToDelete = deletedItems.length;
|
|
||||||
options.onProgress(report);
|
|
||||||
for (let i = 0; i < deletedItems.length; i++) {
|
for (let i = 0; i < deletedItems.length; i++) {
|
||||||
if (this.cancelling()) break;
|
if (this.cancelling()) break;
|
||||||
|
|
||||||
@ -299,9 +294,6 @@ class Synchronizer {
|
|||||||
await this.api().delete(path);
|
await this.api().delete(path);
|
||||||
if (this.randomFailure(options, 3)) return;
|
if (this.randomFailure(options, 3)) return;
|
||||||
await BaseItem.remoteDeletedItem(item.item_id);
|
await BaseItem.remoteDeletedItem(item.item_id);
|
||||||
|
|
||||||
report['deleteRemote']++;
|
|
||||||
options.onProgress(report);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
@ -344,9 +336,6 @@ class Synchronizer {
|
|||||||
|
|
||||||
if (!action) continue;
|
if (!action) continue;
|
||||||
|
|
||||||
report.localsToUdpate++;
|
|
||||||
options.onProgress(report);
|
|
||||||
|
|
||||||
if (action == 'createLocal' || action == 'updateLocal') {
|
if (action == 'createLocal' || action == 'updateLocal') {
|
||||||
let content = await this.api().get(path);
|
let content = await this.api().get(path);
|
||||||
if (content === null) {
|
if (content === null) {
|
||||||
@ -367,17 +356,7 @@ class Synchronizer {
|
|||||||
if (newContent.type_ == BaseModel.TYPE_RESOURCE && action == 'createLocal') {
|
if (newContent.type_ == BaseModel.TYPE_RESOURCE && action == 'createLocal') {
|
||||||
let localResourceContentPath = Resource.fullPath(newContent);
|
let localResourceContentPath = Resource.fullPath(newContent);
|
||||||
let remoteResourceContentPath = this.resourceDirName_ + '/' + newContent.id;
|
let remoteResourceContentPath = this.resourceDirName_ + '/' + newContent.id;
|
||||||
|
|
||||||
await this.api().get(remoteResourceContentPath, { path: localResourceContentPath, target: 'file' });
|
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);
|
await ItemClass.save(newContent, options);
|
||||||
@ -386,10 +365,6 @@ class Synchronizer {
|
|||||||
} else {
|
} else {
|
||||||
this.logSyncOperation(action, local, remote, reason);
|
this.logSyncOperation(action, local, remote, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
report[action]++;
|
|
||||||
|
|
||||||
options.onProgress(report);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!listResult.hasMore) break;
|
if (!listResult.hasMore) break;
|
||||||
@ -417,14 +392,10 @@ class Synchronizer {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
report.localsToDelete++;
|
|
||||||
options.onProgress(report);
|
|
||||||
this.logSyncOperation('deleteLocal', { id: item.id }, null, 'remote has been deleted');
|
this.logSyncOperation('deleteLocal', { id: item.id }, null, 'remote has been deleted');
|
||||||
|
|
||||||
let ItemClass = BaseItem.itemClass(item);
|
let ItemClass = BaseItem.itemClass(item);
|
||||||
await ItemClass.delete(item.id, { trackDeleted: false });
|
await ItemClass.delete(item.id, { trackDeleted: false });
|
||||||
report['deleteLocal']++;
|
|
||||||
options.onProgress(report);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -442,8 +413,8 @@ class Synchronizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
report.errors.push(error);
|
|
||||||
this.logger().error(error);
|
this.logger().error(error);
|
||||||
|
this.progressReport_.errors.push(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.cancelling()) {
|
if (this.cancelling()) {
|
||||||
@ -451,13 +422,14 @@ class Synchronizer {
|
|||||||
this.cancelling_ = false;
|
this.cancelling_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger().info('Synchronization complete [' + synchronizationId + ']:');
|
|
||||||
await this.logSyncSummary(report);
|
|
||||||
|
|
||||||
this.state_ = 'idle';
|
this.state_ = 'idle';
|
||||||
|
|
||||||
report.state = this.state();
|
this.logSyncOperation('finished', null, null, 'Synchronization finished [' + synchronizationId + ']');
|
||||||
options.onProgress(report);
|
|
||||||
|
await this.logSyncSummary(this.progressReport_);
|
||||||
|
|
||||||
|
this.onProgress_ = function(s) {};
|
||||||
|
this.progressReport_ = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user