1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-26 18:58:21 +02:00

All: Added concept of sync version and client ID to allow upgrading sync targets

This commit is contained in:
Laurent Cozic 2019-10-10 23:23:11 +02:00
parent f71e7f4fd3
commit 8a097fb79c
7 changed files with 1454 additions and 1394 deletions

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,7 @@ const BaseService = require('lib/services/BaseService.js');
const { FsDriverNode } = require('lib/fs-driver-node.js'); const { FsDriverNode } = require('lib/fs-driver-node.js');
const { time } = require('lib/time-utils.js'); const { time } = require('lib/time-utils.js');
const { shimInit } = require('lib/shim-init-node.js'); const { shimInit } = require('lib/shim-init-node.js');
const { uuid } = require('lib/uuid.js');
const SyncTargetRegistry = require('lib/SyncTargetRegistry.js'); const SyncTargetRegistry = require('lib/SyncTargetRegistry.js');
const SyncTargetMemory = require('lib/SyncTargetMemory.js'); const SyncTargetMemory = require('lib/SyncTargetMemory.js');
const SyncTargetFilesystem = require('lib/SyncTargetFilesystem.js'); const SyncTargetFilesystem = require('lib/SyncTargetFilesystem.js');
@ -137,6 +138,7 @@ async function switchClient(id) {
await Setting.load(); await Setting.load();
if (!Setting.value('clientId')) Setting.setValue('clientId', uuid.create());
Setting.setValue('sync.wipeOutFailSafe', false); // To keep things simple, always disable fail-safe unless explicitely set in the test itself Setting.setValue('sync.wipeOutFailSafe', false); // To keep things simple, always disable fail-safe unless explicitely set in the test itself
} }
@ -180,6 +182,7 @@ async function setupDatabase(id = null) {
if (databases_[id]) { if (databases_[id]) {
await clearDatabase(id); await clearDatabase(id);
await Setting.load(); await Setting.load();
if (!Setting.value('clientId')) Setting.setValue('clientId', uuid.create());
return; return;
} }
@ -197,6 +200,7 @@ async function setupDatabase(id = null) {
BaseModel.db_ = databases_[id]; BaseModel.db_ = databases_[id];
await Setting.load(); await Setting.load();
if (!Setting.value('clientId')) Setting.setValue('clientId', uuid.create());
} }
function resourceDir(id = null) { function resourceDir(id = null) {

View File

@ -569,6 +569,9 @@ class Application extends BaseApplication {
'', '',
'Copyright © 2016-2019 Laurent Cozic', 'Copyright © 2016-2019 Laurent Cozic',
_('%s %s (%s, %s)', p.name, p.version, Setting.value('env'), process.platform), _('%s %s (%s, %s)', p.name, p.version, Setting.value('env'), process.platform),
'',
_('Client ID: %s', Setting.value('clientId')),
_('Sync Version: %s', Setting.value('syncVersion')),
]; ];
if (gitInfo) { if (gitInfo) {
message.push(`\n${gitInfo}`); message.push(`\n${gitInfo}`);

View File

@ -15,6 +15,7 @@ const { reg } = require('lib/registry.js');
const { time } = require('lib/time-utils.js'); const { time } = require('lib/time-utils.js');
const BaseSyncTarget = require('lib/BaseSyncTarget.js'); const BaseSyncTarget = require('lib/BaseSyncTarget.js');
const { shim } = require('lib/shim.js'); const { shim } = require('lib/shim.js');
const { uuid } = require('lib/uuid.js');
const { _, setLocale } = require('lib/locale.js'); const { _, setLocale } = require('lib/locale.js');
const reduxSharedMiddleware = require('lib/components/shared/reduxSharedMiddleware'); const reduxSharedMiddleware = require('lib/components/shared/reduxSharedMiddleware');
const os = require('os'); const os = require('os');
@ -598,6 +599,8 @@ class BaseApplication {
await Setting.load(); await Setting.load();
if (!Setting.value('clientId')) Setting.setValue('clientId', uuid.create());
if (Setting.value('firstStart')) { if (Setting.value('firstStart')) {
const locale = shim.detectAndSetLocale(Setting); const locale = shim.detectAndSetLocale(Setting);
reg.logger().info(`First start: detected locale as ${locale}`); reg.logger().info(`First start: detected locale as ${locale}`);

View File

@ -31,6 +31,12 @@ class Setting extends BaseModel {
// public for the mobile and desktop apps because they are handled separately in menus. // public for the mobile and desktop apps because they are handled separately in menus.
this.metadata_ = { this.metadata_ = {
'clientId': {
value: '',
type: Setting.TYPE_STRING,
public: false,
},
'sync.target': { 'sync.target': {
value: SyncTargetRegistry.nameToId('dropbox'), value: SyncTargetRegistry.nameToId('dropbox'),
type: Setting.TYPE_INT, type: Setting.TYPE_INT,
@ -917,6 +923,7 @@ Setting.constants_ = {
templateDir: '', templateDir: '',
tempDir: '', tempDir: '',
openDevTools: false, openDevTools: false,
syncVersion: 1,
}; };
Setting.autoSaveEnabled = true; Setting.autoSaveEnabled = true;

View File

@ -213,6 +213,9 @@ class Synchronizer {
const syncSteps = options.syncSteps ? options.syncSteps : ['update_remote', 'delete_remote', 'delta']; const syncSteps = options.syncSteps ? options.syncSteps : ['update_remote', 'delete_remote', 'delta'];
// The default is to log errors, but when testing it's convenient to be able to catch and verify errors
const throwOnError = options.throwOnError === true;
const syncTargetId = this.api().syncTargetId(); const syncTargetId = this.api().syncTargetId();
this.cancelling_ = false; this.cancelling_ = false;
@ -237,11 +240,27 @@ class Synchronizer {
return `${this.resourceDirName_}/${resourceId}`; return `${this.resourceDirName_}/${resourceId}`;
}; };
let errorToThrow = null;
try { try {
await this.api().mkdir(this.syncDirName_); await this.api().mkdir(this.syncDirName_);
this.api().setTempDirName(this.syncDirName_); this.api().setTempDirName(this.syncDirName_);
await this.api().mkdir(this.resourceDirName_); await this.api().mkdir(this.resourceDirName_);
const supportedSyncTargetVersion = Setting.value('syncVersion');
const syncTargetVersion = await this.api().get('.sync/version.txt');
if (!syncTargetVersion) {
await this.api().put('.sync/version.txt', `${supportedSyncTargetVersion}`);
} else {
if (Number(syncTargetVersion) > supportedSyncTargetVersion) {
throw new Error(sprintf('Sync version of the target (%d) does not match sync version supported by client (%d). Please upgrade your client.', Number(syncTargetVersion), supportedSyncTargetVersion));
} else {
await this.api().put('.sync/version.txt', `${supportedSyncTargetVersion}`);
// TODO: do upgrade job
}
}
// ======================================================================== // ========================================================================
// 1. UPLOAD // 1. UPLOAD
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -709,7 +728,9 @@ class Synchronizer {
} }
} // DELTA STEP } // DELTA STEP
} catch (error) { } catch (error) {
if (error && ['cannotEncryptEncrypted', 'noActiveMasterKey', 'processingPathTwice', 'failSafe'].indexOf(error.code) >= 0) { if (throwOnError) {
errorToThrow = error;
} else if (error && ['cannotEncryptEncrypted', 'noActiveMasterKey', 'processingPathTwice', 'failSafe'].indexOf(error.code) >= 0) {
// Only log an info statement for this since this is a common condition that is reported // Only log an info statement for this since this is a common condition that is reported
// in the application, and needs to be resolved by the user. // in the application, and needs to be resolved by the user.
// Or it's a temporary issue that will be resolved on next sync. // Or it's a temporary issue that will be resolved on next sync.
@ -752,6 +773,8 @@ class Synchronizer {
this.state_ = 'idle'; this.state_ = 'idle';
if (errorToThrow) throw errorToThrow;
return outputContext; return outputContext;
} }
} }

View File

@ -59,6 +59,7 @@ const ResourceFetcher = require('lib/services/ResourceFetcher');
const SearchEngine = require('lib/services/SearchEngine'); const SearchEngine = require('lib/services/SearchEngine');
const WelcomeUtils = require('lib/WelcomeUtils'); const WelcomeUtils = require('lib/WelcomeUtils');
const { themeStyle } = require('lib/components/global-style.js'); const { themeStyle } = require('lib/components/global-style.js');
const { uuid } = require('lib/uuid.js');
const SyncTargetRegistry = require('lib/SyncTargetRegistry.js'); const SyncTargetRegistry = require('lib/SyncTargetRegistry.js');
const SyncTargetOneDrive = require('lib/SyncTargetOneDrive.js'); const SyncTargetOneDrive = require('lib/SyncTargetOneDrive.js');
@ -440,6 +441,8 @@ async function initialize(dispatch) {
reg.logger().info('Loading settings...'); reg.logger().info('Loading settings...');
await Setting.load(); await Setting.load();
if (!Setting.value('clientId')) Setting.setValue('clientId', uuid.create());
if (Setting.value('firstStart')) { if (Setting.value('firstStart')) {
let locale = NativeModules.I18nManager.localeIdentifier; let locale = NativeModules.I18nManager.localeIdentifier;
if (!locale) locale = defaultLocale(); if (!locale) locale = defaultLocale();