diff --git a/CliClient/app/app.js b/CliClient/app/app.js index 32e1a7b95..aea29eb48 100644 --- a/CliClient/app/app.js +++ b/CliClient/app/app.js @@ -1,8 +1,3 @@ -import { FileApi } from 'lib/file-api.js'; -import { FileApiDriverOneDrive } from 'lib/file-api-driver-onedrive.js'; -import { FileApiDriverMemory } from 'lib/file-api-driver-memory.js'; -import { FileApiDriverLocal } from 'lib/file-api-driver-local.js'; -import { OneDriveApiNodeUtils } from './onedrive-api-node-utils.js'; import { JoplinDatabase } from 'lib/joplin-database.js'; import { Database } from 'lib/database.js'; import { DatabaseDriverNode } from 'lib/database-driver-node.js'; @@ -325,6 +320,11 @@ class Application { let cmd = this.shellArgsToString(argv); await this.vorpal().exec(cmd); } else { + + setInterval(() => { + reg.scheduleSync(1); + }, 1000 * 5);//60 * 5); + this.updatePrompt(); this.vorpal().show(); this.vorpal().history(Setting.value('appId')); // Enables persistent history diff --git a/CliClient/app/command-config.js b/CliClient/app/command-config.js index bcc40d1f1..0cfe7ba1f 100644 --- a/CliClient/app/command-config.js +++ b/CliClient/app/command-config.js @@ -13,6 +13,12 @@ class Command extends BaseCommand { return _("Gets or sets a config value. If [value] is not provided, it will show the value of [name]. If neither [name] nor [value] is provided, it will list the current configuration."); } + options() { + return [ + ['-v, --verbose', _('Also displays hidden config variables.')], + ]; + } + async action(args) { const renderKeyValue = (name) => { @@ -25,7 +31,7 @@ class Command extends BaseCommand { } if (!args.name && !args.value) { - let keys = Setting.publicKeys(); + let keys = args.options.verbose ? Setting.keys() : Setting.publicKeys(); for (let i = 0; i < keys.length; i++) { this.log(renderKeyValue(keys[i])); } diff --git a/CliClient/app/command-mkbook.js b/CliClient/app/command-mkbook.js index e56c26cd6..82f78a043 100644 --- a/CliClient/app/command-mkbook.js +++ b/CliClient/app/command-mkbook.js @@ -2,6 +2,7 @@ import { BaseCommand } from './base-command.js'; import { app } from './app.js'; import { _ } from 'lib/locale.js'; import { Folder } from 'lib/models/folder.js'; +import { reg } from 'lib/registry.js'; class Command extends BaseCommand { @@ -18,8 +19,7 @@ class Command extends BaseCommand { } async action(args) { - let folder = await Folder.save({ title: args['notebook'] }, { userSideValidation: true }); - + let folder = await Folder.save({ title: args['notebook'] }, { userSideValidation: true }); app().switchCurrentFolder(folder); } diff --git a/CliClient/app/command-mknote.js b/CliClient/app/command-mknote.js index 5da58a94a..82842d139 100644 --- a/CliClient/app/command-mknote.js +++ b/CliClient/app/command-mknote.js @@ -2,6 +2,7 @@ import { BaseCommand } from './base-command.js'; import { app } from './app.js'; import { _ } from 'lib/locale.js'; import { Note } from 'lib/models/note.js'; +import { reg } from 'lib/registry.js'; class Command extends BaseCommand { diff --git a/CliClient/app/command-sync.js b/CliClient/app/command-sync.js index 662fccc7b..6d0fa7148 100644 --- a/CliClient/app/command-sync.js +++ b/CliClient/app/command-sync.js @@ -1,6 +1,7 @@ import { BaseCommand } from './base-command.js'; import { app } from './app.js'; import { _ } from 'lib/locale.js'; +import { OneDriveApiNodeUtils } from './onedrive-api-node-utils.js'; import { Setting } from 'lib/models/setting.js'; import { BaseItem } from 'lib/models/base-item.js'; import { vorpalUtils } from './vorpal-utils.js'; @@ -74,6 +75,13 @@ class Command extends BaseCommand { try { this.syncTarget_ = Setting.value('sync.target'); if (args.options.target) this.syncTarget_ = args.options.target; + + if (this.syncTarget_ == Setting.SYNC_TARGET_ONEDRIVE && !reg.oneDriveApi().auth()) { + const oneDriveApiUtils = new OneDriveApiNodeUtils(reg.oneDriveApi()); + const auth = await oneDriveApiUtils.oauthDance(this); + Setting.setValue('sync.3.auth', auth ? JSON.stringify(auth) : null); + if (!auth) return; + } let sync = await reg.synchronizer(this.syncTarget_); @@ -98,8 +106,17 @@ class Command extends BaseCommand { let context = Setting.value('sync.context'); context = context ? JSON.parse(context) : {}; options.context = context; - let newContext = await sync.start(options); - Setting.setValue('sync.context', JSON.stringify(newContext)); + + try { + let newContext = await sync.start(options); + Setting.setValue('sync.context', JSON.stringify(newContext)); + } catch (error) { + if (error.code == 'alreadyStarted') { + this.log(error.message); + } else { + throw error; + } + } vorpalUtils.redrawDone(); diff --git a/CliClient/locales/en_GB.po b/CliClient/locales/en_GB.po index 8537c6daf..3390a1f71 100644 --- a/CliClient/locales/en_GB.po +++ b/CliClient/locales/en_GB.po @@ -70,6 +70,9 @@ msgid "" "current configuration." msgstr "" +msgid "Also displays hidden config variables." +msgstr "" + #, javascript-format msgid "%s = %s (%s)" msgstr "" @@ -324,6 +327,10 @@ msgstr "" msgid "Completed: %s" msgstr "" +#, javascript-format +msgid "Synchronization is already in progress. State: %s" +msgstr "" + msgid "Conflicts" msgstr "" diff --git a/CliClient/locales/fr_FR.po b/CliClient/locales/fr_FR.po index 216d9a4fa..6e38f30c3 100644 --- a/CliClient/locales/fr_FR.po +++ b/CliClient/locales/fr_FR.po @@ -76,6 +76,9 @@ msgstr "" "fournie, la valeur de [nom] est affichée. Si ni le [nom] ni la [valeur] ne " "sont fournies, la configuration complète est affichée." +msgid "Also displays hidden config variables." +msgstr "" + #, fuzzy, javascript-format msgid "%s = %s (%s)" msgstr "%s %s (%s)" @@ -360,6 +363,10 @@ msgstr "Dernière erreur : %s (Plus d'information dans le journal d'erreurs)" msgid "Completed: %s" msgstr "Terminé : %s" +#, fuzzy, javascript-format +msgid "Synchronization is already in progress. State: %s" +msgstr "Synchronisation est déjà en cours." + msgid "Conflicts" msgstr "Conflits" diff --git a/CliClient/locales/joplin.pot b/CliClient/locales/joplin.pot index 8537c6daf..3390a1f71 100644 --- a/CliClient/locales/joplin.pot +++ b/CliClient/locales/joplin.pot @@ -70,6 +70,9 @@ msgid "" "current configuration." msgstr "" +msgid "Also displays hidden config variables." +msgstr "" + #, javascript-format msgid "%s = %s (%s)" msgstr "" @@ -324,6 +327,10 @@ msgstr "" msgid "Completed: %s" msgstr "" +#, javascript-format +msgid "Synchronization is already in progress. State: %s" +msgstr "" + msgid "Conflicts" msgstr "" diff --git a/ReactNativeClient/lib/registry.js b/ReactNativeClient/lib/registry.js index 6f1ca6797..b247ccca4 100644 --- a/ReactNativeClient/lib/registry.js +++ b/ReactNativeClient/lib/registry.js @@ -115,12 +115,20 @@ reg.scheduleSync = async (delay = null) => { return; } - const sync = await reg.synchronizer(); + const sync = await reg.synchronizer(Setting.value('sync.target')); let context = Setting.value('sync.context'); context = context ? JSON.parse(context) : {}; - let newContext = await sync.start({ context: context }); - Setting.setValue('sync.context', JSON.stringify(newContext)); + try { + let newContext = await sync.start({ context: context }); + Setting.setValue('sync.context', JSON.stringify(newContext)); + } catch (error) { + if (error.code == 'alreadyStarted') { + reg.logger.info(error.message); + } else { + throw error; + } + } }, delay); } diff --git a/ReactNativeClient/lib/synchronizer.js b/ReactNativeClient/lib/synchronizer.js index 91ba87f9d..436330920 100644 --- a/ReactNativeClient/lib/synchronizer.js +++ b/ReactNativeClient/lib/synchronizer.js @@ -148,6 +148,15 @@ class Synchronizer { async start(options = null) { if (!options) options = {}; + + if (this.state() != 'idle') { + let error = new Error(_('Synchronization is already in progress. State: %s', this.state())); + error.code = 'alreadyStarted'; + throw error; + //this.logger().info('Synchronization is already in progress. State: ' + this.state()); + return; + } + this.onProgress_ = options.onProgress ? options.onProgress : function(o) {}; this.progressReport_ = { errors: [] }; @@ -155,11 +164,6 @@ class Synchronizer { const syncTargetId = this.api().syncTargetId(); - if (this.state() != 'idle') { - this.logger().info('Synchronization is already in progress. State: ' + this.state()); - return; - } - this.randomFailureChoice_ = Math.floor(Math.random() * 5); this.cancelling_ = false;