You've already forked joplin
							
							
				mirror of
				https://github.com/laurent22/joplin.git
				synced 2025-10-31 00:07:48 +02:00 
			
		
		
		
	Fixed OneDrive connection issue
This commit is contained in:
		
							
								
								
									
										37
									
								
								CliClient/app/command-status.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								CliClient/app/command-status.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| import { BaseCommand } from './base-command.js'; | ||||
| import { _ } from 'lib/locale.js'; | ||||
| import { ReportService } from 'lib/services/report.js'; | ||||
|  | ||||
| class Command extends BaseCommand { | ||||
|  | ||||
| 	usage() { | ||||
| 		return 'status'; | ||||
| 	} | ||||
|  | ||||
| 	description() { | ||||
| 		return 'Displays summary about the notes and notebooks.'; | ||||
| 	} | ||||
|  | ||||
| 	async action(args) { | ||||
| 		let service = new ReportService(); | ||||
| 		let report = await service.status(); | ||||
|  | ||||
| 		for (let i = 0; i < report.length; i++) { | ||||
| 			let section = report[i]; | ||||
|  | ||||
| 			if (i > 0) this.log(''); | ||||
|  | ||||
| 			this.log('# ' + section.title); | ||||
| 			this.log(''); | ||||
|  | ||||
| 			for (let n in section.body) { | ||||
| 				if (!section.body.hasOwnProperty(n)) continue; | ||||
| 				let line = section.body[n]; | ||||
| 				this.log(line); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| module.exports = Command; | ||||
| @@ -18,47 +18,36 @@ class Command extends BaseCommand { | ||||
| 	options() { | ||||
| 		return [ | ||||
| 			['--random-failures', 'For debugging purposes. Do not use.'], | ||||
| 			['--stats', 'Displays stats about synchronization.'], | ||||
| 		]; | ||||
| 	} | ||||
|  | ||||
| 	async action(args) { | ||||
| 		if (args.options.stats) { | ||||
| 			const report = await BaseItem.stats(); | ||||
| 			for (let n in report.items) { | ||||
| 				if (!report.items.hasOwnProperty(n)) continue; | ||||
| 				const r = report.items[n]; | ||||
| 				this.log(_('%s: %d/%d', n, r.synced, r.total)) | ||||
| 			} | ||||
| 			this.log(_('Total: %d/%d', report.total.synced, report.total.total)); | ||||
| 		} else { | ||||
| 			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(' ')); | ||||
| 				}, | ||||
| 				onMessage: (msg) => { | ||||
| 					vorpalUtils.redrawDone(); | ||||
| 					this.log(msg); | ||||
| 				}, | ||||
| 				randomFailures: args.options['random-failures'] === true, | ||||
| 			}; | ||||
| 		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(' ')); | ||||
| 			}, | ||||
| 			onMessage: (msg) => { | ||||
| 				vorpalUtils.redrawDone(); | ||||
| 				this.log(msg); | ||||
| 			}, | ||||
| 			randomFailures: args.options['random-failures'] === true, | ||||
| 		}; | ||||
|  | ||||
| 			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.')); | ||||
| 		let sync = await app().synchronizer(Setting.value('sync.target')); | ||||
| 		if (!sync) throw new Error(_('Cannot initialize synchronizer.')); | ||||
|  | ||||
| 			this.log(_('Starting synchronization...')); | ||||
| 		this.log(_('Starting synchronization...')); | ||||
|  | ||||
| 			await sync.start(options); | ||||
| 			vorpalUtils.redrawDone(); | ||||
| 			this.log(_('Done.')); | ||||
| 		} | ||||
| 		await sync.start(options); | ||||
| 		vorpalUtils.redrawDone(); | ||||
| 		this.log(_('Done.')); | ||||
| 	} | ||||
|  | ||||
| 	async cancel() { | ||||
|   | ||||
| @@ -50,8 +50,6 @@ class NotesScreenComponent extends React.Component { | ||||
| 		let folder = Folder.byId(this.props.folders, this.props.selectedFolderId); | ||||
| 		let title = folder ? folder.title : null; | ||||
|  | ||||
| 		console.info('FOLDER', folder); | ||||
|  | ||||
| 		const { navigate } = this.props.navigation; | ||||
| 		return ( | ||||
| 			<View style={{flex: 1}}> | ||||
|   | ||||
| @@ -8,6 +8,7 @@ import { time } from 'lib/time-utils' | ||||
| import { Logger } from 'lib/logger.js'; | ||||
| import { BaseItem } from 'lib/models/base-item.js'; | ||||
| import { Folder } from 'lib/models/folder.js'; | ||||
| import { ReportService } from 'lib/services/report.js'; | ||||
| import { _ } from 'lib/locale.js'; | ||||
|  | ||||
| class StatusScreenComponent extends React.Component { | ||||
| @@ -19,7 +20,7 @@ class StatusScreenComponent extends React.Component { | ||||
| 	constructor() { | ||||
| 		super(); | ||||
| 		this.state = { | ||||
| 			reportLines: [], | ||||
| 			report: [], | ||||
| 		}; | ||||
| 	} | ||||
|  | ||||
| @@ -28,39 +29,47 @@ class StatusScreenComponent extends React.Component { | ||||
| 	} | ||||
|  | ||||
| 	async resfreshScreen() { | ||||
| 		let r = await BaseItem.stats(); | ||||
| 		let reportLines = []; | ||||
|  | ||||
| 		reportLines.push(_('Sync status (sync items / total items):')); | ||||
|  | ||||
| 		for (let n in r.items) { | ||||
| 			if (!r.items.hasOwnProperty(n)) continue; | ||||
| 			reportLines.push(_('%s: %d/%d', n, r.items[n].synced, r.items[n].total)); | ||||
| 		} | ||||
|  | ||||
| 		if (r.total) reportLines.push(_('Total: %d/%d', r.total.synced, r.total.total)); | ||||
| 		if (r.toDelete) reportLines.push(_('To delete: %d', r.toDelete.total)); | ||||
|  | ||||
| 		reportLines.push(''); | ||||
|  | ||||
| 		reportLines.push(_('Folders:')); | ||||
|  | ||||
| 		let folders = await Folder.all(); | ||||
| 		for (let i = 0; i < folders.length; i++) { | ||||
| 			let folder = folders[i]; | ||||
| 			reportLines.push(_('%s: %d notes', folders[i].title, await Folder.noteCount(folders[i].id))); | ||||
| 		} | ||||
|  | ||||
| 		this.setState({ reportLines: reportLines }); | ||||
| 		let service = new ReportService(); | ||||
| 		let report = await service.status(); | ||||
| 		this.setState({ report: report }); | ||||
| 	} | ||||
|  | ||||
| 	render() { | ||||
| 		let report = this.state.reportLines ? this.state.reportLines.join("\n") : ''; | ||||
| 		function renderBody(report) { | ||||
| 			let output = []; | ||||
| 			let baseStyle = { | ||||
| 				paddingLeft: 6, | ||||
| 				paddingRight: 6, | ||||
| 				paddingTop: 0, | ||||
| 				paddingBottom: 0, | ||||
| 				flex: 0, | ||||
| 			}; | ||||
| 			for (let i = 0; i < report.length; i++) { | ||||
| 				let section = report[i]; | ||||
|  | ||||
| 				let style = Object.assign({}, baseStyle); | ||||
| 				style.fontWeight = 'bold'; | ||||
| 				if (i > 0) style.paddingTop = 20; | ||||
| 				output.push(<Text key={'sectiontitle_' + i} style={style}>{section.title}</Text>); | ||||
|  | ||||
| 				for (let n in section.body) { | ||||
| 					if (!section.body.hasOwnProperty(n)) continue; | ||||
| 					style = Object.assign({}, baseStyle); | ||||
| 					output.push(<Text key={'line_' + i + '_' + n} style={style}>{section.body[n]}</Text>); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			return output; | ||||
| 		} | ||||
|  | ||||
| 		let body = renderBody(this.state.report); | ||||
|  | ||||
| 		return ( | ||||
| 			<View style={{flex: 1}}> | ||||
| 				<ScreenHeader navState={this.props.navigation.state} /> | ||||
| 				<Text style={{padding: 6, flex: 1, textAlignVertical: 'top'}} multiline={true}>{report}</Text> | ||||
| 				<View style={{flex: 1}}> | ||||
| 					{ body } | ||||
| 				</View> | ||||
| 				<Button title="Refresh" onPress={() => this.resfreshScreen()}/> | ||||
| 			</View> | ||||
| 		); | ||||
|   | ||||
| @@ -167,9 +167,16 @@ class OneDriveApi { | ||||
| 					response = await shim.fetchBlob(url, options); | ||||
| 				} | ||||
| 			} catch (error) { | ||||
| 				// TEMPORARY: To try to find where uncaught error comes from | ||||
| 				let error = new Error('OneDrive API caught: ' + JSON.stringify(error)); | ||||
| 				throw error; | ||||
| 				if (error.message == 'Network request failed') { | ||||
| 					// Unfortunately the error 'Network request failed' doesn't have a type | ||||
| 					// or error code, so hopefully that message won't change and is not localized | ||||
| 					this.logger().info('Got error below - retrying...'); | ||||
| 					this.logger().info(error); | ||||
| 					await time.sleep((i + 1) * 3); | ||||
| 					continue; | ||||
| 				} else { | ||||
| 					throw error; | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| 			if (!response.ok) { | ||||
| @@ -197,7 +204,7 @@ class OneDriveApi { | ||||
| 					//   code: 'EAGAIN' } | ||||
| 					this.logger().info('Got error below - retrying...'); | ||||
| 					this.logger().info(error); | ||||
| 					await time.msleep(1000 * i); | ||||
| 					await time.sleep((i + 1) * 3); | ||||
| 					continue; | ||||
| 				} else if (error.code == 'itemNotFound' && method == 'DELETE') { | ||||
| 					// Deleting a non-existing item is ok - noop | ||||
|   | ||||
							
								
								
									
										75
									
								
								ReactNativeClient/lib/services/report.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								ReactNativeClient/lib/services/report.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| import { time } from 'lib/time-utils' | ||||
| import { BaseItem } from 'lib/models/base-item.js'; | ||||
| import { Folder } from 'lib/models/folder.js'; | ||||
| import { _ } from 'lib/locale.js'; | ||||
|  | ||||
| class ReportService { | ||||
|  | ||||
| 	async syncStatus() { | ||||
| 		let output = { | ||||
| 			items: {}, | ||||
| 			total: {}, | ||||
| 		}; | ||||
|  | ||||
| 		let itemCount = 0; | ||||
| 		let syncedCount = 0; | ||||
| 		for (let i = 0; i < BaseItem.syncItemDefinitions_.length; i++) { | ||||
| 			let d = BaseItem.syncItemDefinitions_[i]; | ||||
| 			let ItemClass = BaseItem.getClass(d.className); | ||||
| 			let o = { | ||||
| 				total: await ItemClass.count(), | ||||
| 				synced: await ItemClass.syncedCount(), | ||||
| 			}; | ||||
| 			output.items[d.className] = o; | ||||
| 			itemCount += o.total; | ||||
| 			syncedCount += o.synced; | ||||
| 		} | ||||
|  | ||||
| 		output.total = { | ||||
| 			total: itemCount, | ||||
| 			synced: syncedCount, | ||||
| 		}; | ||||
|  | ||||
| 		output.toDelete = { | ||||
| 			total: await BaseItem.deletedItemCount(), | ||||
| 		}; | ||||
|  | ||||
| 		return output; | ||||
| 	} | ||||
|  | ||||
| 	async status() { | ||||
| 		let r = await this.syncStatus(); | ||||
| 		let sections = []; | ||||
| 		let section = {}; | ||||
|  | ||||
| 		section.title = _('Sync status (synced items / total items)'); | ||||
| 		section.body = []; | ||||
|  | ||||
| 		for (let n in r.items) { | ||||
| 			if (!r.items.hasOwnProperty(n)) continue; | ||||
| 			section.body.push(_('%s: %d/%d', n, r.items[n].synced, r.items[n].total)); | ||||
| 		} | ||||
|  | ||||
| 		if (r.total) section.body.push(_('Total: %d/%d', r.total.synced, r.total.total)); | ||||
| 		if (r.toDelete) section.body.push(_('To delete: %d', r.toDelete.total)); | ||||
|  | ||||
| 		sections.push(section); | ||||
|  | ||||
| 		section = {}; | ||||
| 		section.title = _('Folders'); | ||||
| 		section.body = []; | ||||
|  | ||||
| 		let folders = await Folder.all(); | ||||
| 		for (let i = 0; i < folders.length; i++) { | ||||
| 			let folder = folders[i]; | ||||
| 			section.body.push(_('%s: %d notes', folders[i].title, await Folder.noteCount(folders[i].id))); | ||||
| 		} | ||||
|  | ||||
| 		sections.push(section); | ||||
|  | ||||
| 		return sections; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| export { ReportService } | ||||
		Reference in New Issue
	
	Block a user