diff --git a/lib/models/note.js b/lib/models/note.js index d7109d44..ad968e7b 100644 --- a/lib/models/note.js +++ b/lib/models/note.js @@ -92,20 +92,22 @@ module.exports = function (sequelize, DataTypes) { return new Promise(function (resolve, reject) { // if no content specified then use default note if (!note.content) { - var body = null - let filePath = null - if (!note.alias) { - filePath = config.defaultNotePath - } else { - filePath = path.join(config.docsPath, note.alias + '.md') + let filePath = config.defaultNotePath + + if (note.alias) { + const notePathInDocPath = path.join(config.docsPath, path.basename(note.alias) + '.md') + if (Note.checkFileExist(notePathInDocPath)) { + filePath = notePathInDocPath + } } + if (Note.checkFileExist(filePath)) { - var fsCreatedTime = moment(fs.statSync(filePath).ctime) - body = fs.readFileSync(filePath, 'utf8') - note.title = Note.parseNoteTitle(body) - note.content = body + const noteInFS = readFileSystemNote(filePath) + note.title = noteInFS.title + note.content = noteInFS.content if (filePath !== config.defaultNotePath) { - note.createdAt = fsCreatedTime + note.createdAt = noteInFS.lastchangeAt + note.lastchangeAt = noteInFS.lastchangeAt } } } @@ -196,6 +198,29 @@ module.exports = function (sequelize, DataTypes) { }) }) } + + async function syncNote (noteInFS, note) { + const contentLength = noteInFS.content.length + + let note2 = await note.update({ + title: noteInFS.title, + content: noteInFS.content, + lastchangeAt: noteInFS.lastchangeAt + }) + const revision = await sequelize.models.Revision.saveNoteRevisionAsync(note2) + // update authorship on after making revision of docs + const patch = dmp.patch_fromText(revision.patch) + const operations = Note.transformPatchToOperations(patch, contentLength) + let authorship = note2.authorship + for (let i = 0; i < operations.length; i++) { + authorship = Note.updateAuthorshipByOperation(operations[i], null, authorship) + } + note2 = await note.update({ + authorship: authorship + }) + return note2.id + } + Note.parseNoteId = function (noteId, callback) { async.series({ parseNoteIdByAlias: function (_callback) { @@ -204,65 +229,35 @@ module.exports = function (sequelize, DataTypes) { where: { alias: noteId } - }).then(function (note) { - if (note) { - const filePath = path.join(config.docsPath, noteId + '.md') - if (Note.checkFileExist(filePath)) { - // if doc in filesystem have newer modified time than last change time - // then will update the doc in db - var fsModifiedTime = moment(fs.statSync(filePath).mtime) - var dbModifiedTime = moment(note.lastchangeAt || note.createdAt) - var body = fs.readFileSync(filePath, 'utf8') - var contentLength = body.length - var title = Note.parseNoteTitle(body) - if (fsModifiedTime.isAfter(dbModifiedTime) && note.content !== body) { - note.update({ - title: title, - content: body, - lastchangeAt: fsModifiedTime - }).then(function (note) { - sequelize.models.Revision.saveNoteRevision(note, function (err, revision) { - if (err) return _callback(err, null) - // update authorship on after making revision of docs - var patch = dmp.patch_fromText(revision.patch) - var operations = Note.transformPatchToOperations(patch, contentLength) - var authorship = note.authorship - for (let i = 0; i < operations.length; i++) { - authorship = Note.updateAuthorshipByOperation(operations[i], null, authorship) - } - note.update({ - authorship: authorship - }).then(function (note) { - return callback(null, note.id) - }).catch(function (err) { - return _callback(err, null) - }) - }) - }).catch(function (err) { - return _callback(err, null) - }) + }).then(async function (note) { + const filePath = path.join(config.docsPath, path.basename(noteId) + '.md') + if (Note.checkFileExist(filePath)) { + try { + if (note) { + // if doc in filesystem have newer modified time than last change time + // then will update the doc in db + const noteInFS = readFileSystemNote(filePath) + if (shouldSyncNote(note, noteInFS)) { + const noteId = await syncNote(noteInFS, note) + return callback(null, noteId) + } } else { + // create new note with alias, and will sync md file in beforeCreateHook + const note = await Note.create({ + alias: noteId, + owner: null, + permission: 'locked' + }) return callback(null, note.id) } - } else { - return callback(null, note.id) - } - } else { - var filePath = path.join(config.docsPath, noteId + '.md') - if (Note.checkFileExist(filePath)) { - Note.create({ - alias: noteId, - owner: null, - permission: 'locked' - }).then(function (note) { - return callback(null, note.id) - }).catch(function (err) { - return _callback(err, null) - }) - } else { - return _callback(null, null) + } catch (err) { + return callback(err, null) } } + if (!note) { + return callback(null, null) + } + return callback(null, note.id) }).catch(function (err) { return _callback(err, null) }) @@ -589,5 +584,21 @@ module.exports = function (sequelize, DataTypes) { return operations } + function readFileSystemNote (filePath) { + const fsModifiedTime = moment(fs.statSync(filePath).mtime) + const content = fs.readFileSync(filePath, 'utf8') + + return { + lastchangeAt: fsModifiedTime, + title: Note.parseNoteTitle(content), + content: content + } + } + + function shouldSyncNote (note, noteInFS) { + const dbModifiedTime = moment(note.lastchangeAt || note.createdAt) + return noteInFS.lastchangeAt.isAfter(dbModifiedTime) && note.content !== noteInFS.content + } + return Note } diff --git a/lib/models/revision.js b/lib/models/revision.js index b628d96d..5f91b7d8 100644 --- a/lib/models/revision.js +++ b/lib/models/revision.js @@ -6,6 +6,7 @@ var moment = require('moment') var childProcess = require('child_process') var shortId = require('shortid') var path = require('path') +var util = require('util') var Op = Sequelize.Op @@ -296,6 +297,7 @@ module.exports = function (sequelize, DataTypes) { return callback(err, null) }) } + Revision.saveNoteRevisionAsync = util.promisify(Revision.saveNoteRevision) Revision.finishSaveNoteRevision = function (note, revision, callback) { note.update({ savedAt: revision.updatedAt