diff --git a/public/javascripts/dialogs/settings.js b/public/javascripts/dialogs/settings.js index b5b18fb3e..c934b4ed7 100644 --- a/public/javascripts/dialogs/settings.js +++ b/public/javascripts/dialogs/settings.js @@ -149,5 +149,17 @@ settings.addModule((async function () { buildRevisionEl.html(appInfo.build_revision); buildRevisionEl.attr('href', 'https://github.com/zadam/trilium/commit/' + appInfo.build_revision); + return {}; +})()); + +settings.addModule((async function () { + const forceFullSyncButton = $("#force-full-sync-button"); + + forceFullSyncButton.click(async () => { + await server.post('sync/force-full-sync'); + + showMessage("Full sync triggered"); + }); + return {}; })()); \ No newline at end of file diff --git a/routes/api/recent_notes.js b/routes/api/recent_notes.js index 07f7acdda..58de6f137 100644 --- a/routes/api/recent_notes.js +++ b/routes/api/recent_notes.js @@ -33,19 +33,7 @@ router.put('/:noteTreeId/:notePath', auth.checkApiAuth, async (req, res, next) = }); async function getRecentNotes() { - await deleteOld(); - return await sql.getResults("SELECT * FROM recent_notes WHERE is_deleted = 0 ORDER BY date_accessed DESC"); } -async function deleteOld() { - const cutoffDateAccessed = utils.dateStr(new Date(Date.now() - 24 * 60 * 60 * 1000)); - - await sql.doInTransaction(async () => { - await sql.execute("DELETE FROM recent_notes WHERE date_accessed < ?", [cutoffDateAccessed]); - - await sql.execute("DELETE FROM sync WHERE entity_name = 'recent_notes' AND sync_date < ?", [cutoffDateAccessed]); - }); -} - module.exports = router; \ No newline at end of file diff --git a/routes/api/sync.js b/routes/api/sync.js index ed9a2e361..91c3cde75 100644 --- a/routes/api/sync.js +++ b/routes/api/sync.js @@ -20,6 +20,18 @@ router.post('/now', auth.checkApiAuth, async (req, res, next) => { res.send(await sync.sync()); }); +router.post('/force-full-sync', auth.checkApiAuth, async (req, res, next) => { + await sql.doInTransaction(async () => { + await options.setOption('last_synced_pull', 0); + await options.setOption('last_synced_push', 0); + }); + + // not awaiting for the job to finish (will probably take a long time) + sync.sync(); + + res.send({}); +}); + router.get('/changed', auth.checkApiAuth, async (req, res, next) => { const lastSyncId = parseInt(req.query.lastSyncId); diff --git a/services/build.js b/services/build.js index e5ca41958..23a9cd9e6 100644 --- a/services/build.js +++ b/services/build.js @@ -1 +1 @@ -module.exports = { build_date:"2017-12-10T23:23:04-05:00", build_revision: "bdeaa2829d4c5436e86d0d943a2a332d0c016804" }; +module.exports = { build_date:"2017-12-12T23:57:58-05:00", build_revision: "2fa57b79fd972b3eda6eb8ef1d26e9915b75fd96" }; diff --git a/services/notes.js b/services/notes.js index 6bd94bbe6..f02fee4d8 100644 --- a/services/notes.js +++ b/services/notes.js @@ -142,6 +142,7 @@ async function updateNote(noteId, newNote, ctx) { } const now = new Date(); + const nowStr = utils.nowDate(); const historySnapshotTimeInterval = parseInt(await options.getOption('history_snapshot_time_interval')); @@ -170,7 +171,7 @@ async function updateNote(noteId, newNote, ctx) { note_text: oldNote.note_text, is_protected: 0, // will be fixed in the protectNoteHistory() call date_modified_from: oldNote.date_modified, - date_modified_to: now + date_modified_to: nowStr }); await sync_table.addNoteHistorySync(newNoteHistoryId); @@ -182,7 +183,7 @@ async function updateNote(noteId, newNote, ctx) { newNote.detail.note_title, newNote.detail.note_text, newNote.detail.is_protected, - now, + nowStr, noteId]); await sync_table.addNoteSync(noteId); diff --git a/services/ping_job.js b/services/ping_job.js index 7e8c1b3b8..a7621e269 100644 --- a/services/ping_job.js +++ b/services/ping_job.js @@ -3,7 +3,7 @@ const source_id = require('./source_id'); const utils = require('./utils'); const messaging = require('./messaging'); const options = require('./options'); -const sync = require('./sync'); +const sync_setup = require('./sync_setup'); let startTime = utils.nowDate(); let sentSyncId = []; @@ -35,7 +35,7 @@ async function sendPing() { messaging.sendMessage({ type: 'sync', data: data, - changesToPushCount: sync.isSyncSetup ? changesToPushCount : 0 + changesToPushCount: sync_setup.isSyncSetup ? changesToPushCount : 0 }); for (const syncId of syncIds) { diff --git a/services/sync.js b/services/sync.js index 73c577b96..a3eb10949 100644 --- a/services/sync.js +++ b/services/sync.js @@ -5,7 +5,6 @@ const rp = require('request-promise'); const sql = require('./sql'); const options = require('./options'); const utils = require('./utils'); -const config = require('./config'); const source_id = require('./source_id'); const notes = require('./notes'); const syncUpdate = require('./sync_update'); @@ -14,11 +13,7 @@ const event_log = require('./event_log'); const fs = require('fs'); const app_info = require('./app_info'); const messaging = require('./messaging'); - -const SYNC_SERVER = config['Sync']['syncServerHost']; -const isSyncSetup = !!SYNC_SERVER; -const SYNC_TIMEOUT = config['Sync']['syncServerTimeout'] || 5000; -const SYNC_PROXY = config['Sync']['syncProxy']; +const sync_setup = require('./sync_setup'); let syncInProgress = false; let proxyToggle = true; @@ -278,7 +273,7 @@ async function checkContentHash(syncContext) { } async function syncRequest(syncContext, method, uri, body) { - const fullUri = SYNC_SERVER + uri; + const fullUri = sync_setup.SYNC_SERVER + uri; try { const options = { @@ -287,15 +282,15 @@ async function syncRequest(syncContext, method, uri, body) { jar: syncContext.cookieJar, json: true, body: body, - timeout: SYNC_TIMEOUT + timeout: sync_setup.SYNC_TIMEOUT }; if (syncServerCertificate) { options.ca = syncServerCertificate; } - if (SYNC_PROXY && proxyToggle) { - options.proxy = SYNC_PROXY; + if (sync_setup.SYNC_PROXY && proxyToggle) { + options.proxy = sync_setup.SYNC_PROXY; } return await rp(options); @@ -306,19 +301,17 @@ async function syncRequest(syncContext, method, uri, body) { } sql.dbReady.then(() => { - if (isSyncSetup) { - log.info("Setting up sync to " + SYNC_SERVER + " with timeout " + SYNC_TIMEOUT); + if (sync_setup.isSyncSetup) { + log.info("Setting up sync to " + sync_setup.SYNC_SERVER + " with timeout " + sync_setup.SYNC_TIMEOUT); - if (SYNC_PROXY) { - log.info("Sync proxy: " + SYNC_PROXY); + if (sync_setup.SYNC_PROXY) { + log.info("Sync proxy: " + sync_setup.SYNC_PROXY); } - const syncCertPath = config['Sync']['syncServerCertificate']; + if (sync_setup.SYNC_CERT_PATH) { + log.info('Sync certificate: ' + sync_setup.SYNC_CERT_PATH); - if (syncCertPath) { - log.info('Sync certificate: ' + syncCertPath); - - syncServerCertificate = fs.readFileSync(syncCertPath); + syncServerCertificate = fs.readFileSync(sync_setup.SYNC_CERT_PATH); } setInterval(sync, 60000); @@ -332,6 +325,5 @@ sql.dbReady.then(() => { }); module.exports = { - sync, - isSyncSetup + sync }; \ No newline at end of file diff --git a/services/sync_setup.js b/services/sync_setup.js new file mode 100644 index 000000000..b51087ed1 --- /dev/null +++ b/services/sync_setup.js @@ -0,0 +1,11 @@ +"use strict"; + +const config = require('./config'); + +module.exports = { + SYNC_SERVER: config['Sync']['syncServerHost'], + isSyncSetup: !!config['Sync']['syncServerHost'], + SYNC_TIMEOUT: config['Sync']['syncServerTimeout'] || 5000, + SYNC_PROXY: config['Sync']['syncProxy'], + SYNC_CERT_PATH: config['Sync']['syncServerCertificate'] +}; \ No newline at end of file diff --git a/services/sync_table.js b/services/sync_table.js index 65348cf1f..f4c038087 100644 --- a/services/sync_table.js +++ b/services/sync_table.js @@ -1,6 +1,7 @@ const sql = require('./sql'); const source_id = require('./source_id'); const utils = require('./utils'); +const sync_setup = require('./sync_setup'); async function addNoteSync(noteId, sourceId) { await addEntitySync("notes", noteId, sourceId) @@ -27,12 +28,14 @@ async function addRecentNoteSync(notePath, sourceId) { } async function addEntitySync(entityName, entityId, sourceId) { - await sql.replace("sync", { - entity_name: entityName, - entity_id: entityId, - sync_date: utils.nowDate(), - source_id: sourceId || source_id.currentSourceId - }); + if (sync_setup.isSyncSetup) { + await sql.replace("sync", { + entity_name: entityName, + entity_id: entityId, + sync_date: utils.nowDate(), + source_id: sourceId || source_id.currentSourceId + }); + } } module.exports = { diff --git a/services/sync_update.js b/services/sync_update.js index f73561445..2c553d4a2 100644 --- a/services/sync_update.js +++ b/services/sync_update.js @@ -1,7 +1,6 @@ const sql = require('./sql'); const log = require('./log'); const options = require('./options'); -const utils = require('./utils'); const eventLog = require('./event_log'); const notes = require('./notes'); const sync_table = require('./sync_table'); @@ -19,9 +18,6 @@ async function updateNote(entity, sourceId) { log.info("Update/sync note " + entity.note_id); } - else { - await eventLog.addNoteEvent(entity.note_id, "Sync conflict in note , " + utils.formatTwoDates(origNote.date_modified, entity.date_modified)); - } } async function updateNoteTree(entity, sourceId) { @@ -37,9 +33,6 @@ async function updateNoteTree(entity, sourceId) { log.info("Update/sync note tree " + entity.note_tree_id); } - else { - await eventLog.addNoteEvent(entity.note_tree_id, "Sync conflict in note tree , " + utils.formatTwoDates(orig.date_modified, entity.date_modified)); - } }); } @@ -54,9 +47,6 @@ async function updateNoteHistory(entity, sourceId) { log.info("Update/sync note history " + entity.note_history_id); } - else { - await eventLog.addNoteEvent(entity.note_id, "Sync conflict in note history for , " + utils.formatTwoDates(orig.date_modified_to, entity.date_modified_to)); - } }); } @@ -85,9 +75,6 @@ async function updateOptions(entity, sourceId) { await eventLog.addEvent("Synced option " + entity.opt_name); } - else { - await eventLog.addEvent("Sync conflict in options for " + entity.opt_name + ", " + utils.formatTwoDates(orig.date_modified, entity.date_modified)); - } }); } diff --git a/services/utils.js b/services/utils.js index 09f5190d2..6f06a52a9 100644 --- a/services/utils.js +++ b/services/utils.js @@ -62,10 +62,6 @@ function isElectron() { return !!process.versions['electron']; } -function formatTwoDates(origDate, newDate) { - return "orig: " + origDate + ", new: " + newDate; -} - function hash(text) { return crypto.createHash('sha1').update(text).digest('base64'); } @@ -88,7 +84,6 @@ module.exports = { fromBase64, hmac, isElectron, - formatTwoDates, hash, isEmptyOrWhitespace }; \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index 902ed134d..262f1be48 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -165,6 +165,7 @@
  • Change password
  • Protected session
  • History snapshots
  • +
  • Sync
  • About Trilium
  • @@ -212,6 +213,9 @@
    +
    + +