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