mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 15:11:31 +08:00 
			
		
		
		
	image sync
This commit is contained in:
		
							parent
							
								
									91cf090820
								
							
						
					
					
						commit
						784cd62df1
					
				
							
								
								
									
										59
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										59
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -4167,6 +4167,34 @@
 | 
				
			|||||||
        "es5-ext": "0.10.35"
 | 
					        "es5-ext": "0.10.35"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "exec-buffer": {
 | 
				
			||||||
 | 
					      "version": "3.2.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/exec-buffer/-/exec-buffer-3.2.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-wsiD+2Tp6BWHoVv3B+5Dcx6E7u5zky+hUwOHjuH2hKSLR3dvRmX8fk8UD8uqQixHs4Wk6eDmiegVrMPjKj7wpA==",
 | 
				
			||||||
 | 
					      "requires": {
 | 
				
			||||||
 | 
					        "execa": "0.7.0",
 | 
				
			||||||
 | 
					        "p-finally": "1.0.0",
 | 
				
			||||||
 | 
					        "pify": "3.0.0",
 | 
				
			||||||
 | 
					        "rimraf": "2.6.2",
 | 
				
			||||||
 | 
					        "tempfile": "2.0.0"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "dependencies": {
 | 
				
			||||||
 | 
					        "pify": {
 | 
				
			||||||
 | 
					          "version": "3.0.0",
 | 
				
			||||||
 | 
					          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
 | 
				
			||||||
 | 
					          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "tempfile": {
 | 
				
			||||||
 | 
					          "version": "2.0.0",
 | 
				
			||||||
 | 
					          "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz",
 | 
				
			||||||
 | 
					          "integrity": "sha1-awRGhWqbERTRhW/8vlCczLCXcmU=",
 | 
				
			||||||
 | 
					          "requires": {
 | 
				
			||||||
 | 
					            "temp-dir": "1.0.0",
 | 
				
			||||||
 | 
					            "uuid": "3.1.0"
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "exec-series": {
 | 
					    "exec-series": {
 | 
				
			||||||
      "version": "1.0.3",
 | 
					      "version": "1.0.3",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/exec-series/-/exec-series-1.0.3.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/exec-series/-/exec-series-1.0.3.tgz",
 | 
				
			||||||
@ -4180,7 +4208,6 @@
 | 
				
			|||||||
      "version": "0.7.0",
 | 
					      "version": "0.7.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
 | 
				
			||||||
      "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
 | 
					      "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
 | 
				
			||||||
      "dev": true,
 | 
					 | 
				
			||||||
      "requires": {
 | 
					      "requires": {
 | 
				
			||||||
        "cross-spawn": "5.1.0",
 | 
					        "cross-spawn": "5.1.0",
 | 
				
			||||||
        "get-stream": "3.0.0",
 | 
					        "get-stream": "3.0.0",
 | 
				
			||||||
@ -5461,6 +5488,16 @@
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "imagemin-pngquant": {
 | 
				
			||||||
 | 
					      "version": "5.0.1",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/imagemin-pngquant/-/imagemin-pngquant-5.0.1.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha1-2KMp2lU6+iJrEc5i3r4Lfje0OeY=",
 | 
				
			||||||
 | 
					      "requires": {
 | 
				
			||||||
 | 
					        "exec-buffer": "3.2.0",
 | 
				
			||||||
 | 
					        "is-png": "1.1.0",
 | 
				
			||||||
 | 
					        "pngquant-bin": "3.1.1"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "import-lazy": {
 | 
					    "import-lazy": {
 | 
				
			||||||
      "version": "2.1.0",
 | 
					      "version": "2.1.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
 | 
				
			||||||
@ -5826,6 +5863,11 @@
 | 
				
			|||||||
      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
 | 
					      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
 | 
				
			||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "is-png": {
 | 
				
			||||||
 | 
					      "version": "1.1.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/is-png/-/is-png-1.1.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha1-1XSxK/J1wDUEVVcLDltXqwYgd84="
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "is-posix-bracket": {
 | 
					    "is-posix-bracket": {
 | 
				
			||||||
      "version": "0.1.1",
 | 
					      "version": "0.1.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz",
 | 
				
			||||||
@ -7826,6 +7868,16 @@
 | 
				
			|||||||
      "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.1.tgz",
 | 
				
			||||||
      "integrity": "sha512-ggXCTsqHRIsGMkHlCEhbHhUmNTA2r1lpkE0NL4Q9S8spkXbm4vE9TVmPso2AGYn90Gltdz8W5CyzhcIGg2Gejg=="
 | 
					      "integrity": "sha512-ggXCTsqHRIsGMkHlCEhbHhUmNTA2r1lpkE0NL4Q9S8spkXbm4vE9TVmPso2AGYn90Gltdz8W5CyzhcIGg2Gejg=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "pngquant-bin": {
 | 
				
			||||||
 | 
					      "version": "3.1.1",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/pngquant-bin/-/pngquant-bin-3.1.1.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha1-0STZinWpSH9AwWQLTb/Lsr1aH9E=",
 | 
				
			||||||
 | 
					      "requires": {
 | 
				
			||||||
 | 
					        "bin-build": "2.2.0",
 | 
				
			||||||
 | 
					        "bin-wrapper": "3.0.2",
 | 
				
			||||||
 | 
					        "logalot": "2.1.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "postcss": {
 | 
					    "postcss": {
 | 
				
			||||||
      "version": "5.2.18",
 | 
					      "version": "5.2.18",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
 | 
				
			||||||
@ -10309,6 +10361,11 @@
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "temp-dir": {
 | 
				
			||||||
 | 
					      "version": "1.0.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0="
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "tempfile": {
 | 
					    "tempfile": {
 | 
				
			||||||
      "version": "1.1.1",
 | 
					      "version": "1.1.1",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-1.1.1.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-1.1.1.tgz",
 | 
				
			||||||
 | 
				
			|||||||
@ -35,6 +35,7 @@
 | 
				
			|||||||
    "html": "^1.0.0",
 | 
					    "html": "^1.0.0",
 | 
				
			||||||
    "imagemin": "^5.3.1",
 | 
					    "imagemin": "^5.3.1",
 | 
				
			||||||
    "imagemin-mozjpeg": "^7.0.0",
 | 
					    "imagemin-mozjpeg": "^7.0.0",
 | 
				
			||||||
 | 
					    "imagemin-pngquant": "^5.0.1",
 | 
				
			||||||
    "ini": "^1.3.4",
 | 
					    "ini": "^1.3.4",
 | 
				
			||||||
    "jimp": "^0.2.28",
 | 
					    "jimp": "^0.2.28",
 | 
				
			||||||
    "multer": "^1.3.0",
 | 
					    "multer": "^1.3.0",
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,7 @@ const router = express.Router();
 | 
				
			|||||||
const sql = require('../../services/sql');
 | 
					const sql = require('../../services/sql');
 | 
				
			||||||
const auth = require('../../services/auth');
 | 
					const auth = require('../../services/auth');
 | 
				
			||||||
const utils = require('../../services/utils');
 | 
					const utils = require('../../services/utils');
 | 
				
			||||||
 | 
					const sync_table = require('../../services/sync_table');
 | 
				
			||||||
const multer = require('multer')();
 | 
					const multer = require('multer')();
 | 
				
			||||||
const imagemin = require('imagemin');
 | 
					const imagemin = require('imagemin');
 | 
				
			||||||
const imageminMozJpeg = require('imagemin-mozjpeg');
 | 
					const imageminMozJpeg = require('imagemin-mozjpeg');
 | 
				
			||||||
@ -24,6 +25,7 @@ router.get('/:imageId/:filename', auth.checkApiAuth, async (req, res, next) => {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.post('/upload', auth.checkApiAuth, multer.single('upload'), async (req, res, next) => {
 | 
					router.post('/upload', auth.checkApiAuth, multer.single('upload'), async (req, res, next) => {
 | 
				
			||||||
 | 
					    const sourceId = req.headers.source_id;
 | 
				
			||||||
    const file = req.file;
 | 
					    const file = req.file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const imageId = utils.newNoteId();
 | 
					    const imageId = utils.newNoteId();
 | 
				
			||||||
@ -37,6 +39,7 @@ router.post('/upload', auth.checkApiAuth, multer.single('upload'), async (req, r
 | 
				
			|||||||
    const resizedImage = await resize(file.buffer);
 | 
					    const resizedImage = await resize(file.buffer);
 | 
				
			||||||
    const optimizedImage = await optimize(resizedImage);
 | 
					    const optimizedImage = await optimize(resizedImage);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await sql.doInTransaction(async () => {
 | 
				
			||||||
        await sql.insert("images", {
 | 
					        await sql.insert("images", {
 | 
				
			||||||
            image_id: imageId,
 | 
					            image_id: imageId,
 | 
				
			||||||
            format: file.mimetype.substr(6),
 | 
					            format: file.mimetype.substr(6),
 | 
				
			||||||
@ -48,6 +51,9 @@ router.post('/upload', auth.checkApiAuth, multer.single('upload'), async (req, r
 | 
				
			|||||||
            date_created: now
 | 
					            date_created: now
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await sync_table.addImageSync(imageId, sourceId);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    res.send({
 | 
					    res.send({
 | 
				
			||||||
        uploaded: true,
 | 
					        uploaded: true,
 | 
				
			||||||
        url: `/api/image/${imageId}/${file.originalname}`
 | 
					        url: `/api/image/${imageId}/${file.originalname}`
 | 
				
			||||||
@ -60,8 +66,6 @@ const MAX_BYTE_SIZE = 200000; // images should have under 100 KBs
 | 
				
			|||||||
async function resize(buffer) {
 | 
					async function resize(buffer) {
 | 
				
			||||||
    const image = await jimp.read(buffer);
 | 
					    const image = await jimp.read(buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    console.log("Size: ", buffer.byteLength);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (image.bitmap.width > image.bitmap.height && image.bitmap.width > MAX_SIZE) {
 | 
					    if (image.bitmap.width > image.bitmap.height && image.bitmap.width > MAX_SIZE) {
 | 
				
			||||||
        image.resize(MAX_SIZE, jimp.AUTO);
 | 
					        image.resize(MAX_SIZE, jimp.AUTO);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -122,6 +122,17 @@ router.get('/recent_notes/:noteTreeId', auth.checkApiAuth, async (req, res, next
 | 
				
			|||||||
    res.send(await sql.getFirst("SELECT * FROM recent_notes WHERE note_tree_id = ?", [noteTreeId]));
 | 
					    res.send(await sql.getFirst("SELECT * FROM recent_notes WHERE note_tree_id = ?", [noteTreeId]));
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					router.get('/images/:imageId', auth.checkApiAuth, async (req, res, next) => {
 | 
				
			||||||
 | 
					    const imageId = req.params.imageId;
 | 
				
			||||||
 | 
					    const entity = await sql.getFirst("SELECT * FROM images WHERE image_id = ?", [imageId]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (entity && entity.data !== null) {
 | 
				
			||||||
 | 
					        entity.data = entity.data.toString('base64');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    res.send(entity);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.put('/notes', auth.checkApiAuth, async (req, res, next) => {
 | 
					router.put('/notes', auth.checkApiAuth, async (req, res, next) => {
 | 
				
			||||||
    await syncUpdate.updateNote(req.body.entity, req.body.sourceId);
 | 
					    await syncUpdate.updateNote(req.body.entity, req.body.sourceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -158,4 +169,10 @@ router.put('/recent_notes', auth.checkApiAuth, async (req, res, next) => {
 | 
				
			|||||||
    res.send({});
 | 
					    res.send({});
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					router.put('/images', auth.checkApiAuth, async (req, res, next) => {
 | 
				
			||||||
 | 
					    await syncUpdate.updateImage(req.body.entity, req.body.sourceId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    res.send({});
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = router;
 | 
					module.exports = router;
 | 
				
			||||||
@ -4,8 +4,11 @@ const sql = require('./sql');
 | 
				
			|||||||
const log = require('./log');
 | 
					const log = require('./log');
 | 
				
			||||||
const messaging = require('./messaging');
 | 
					const messaging = require('./messaging');
 | 
				
			||||||
const sync_mutex = require('./sync_mutex');
 | 
					const sync_mutex = require('./sync_mutex');
 | 
				
			||||||
 | 
					const utils = require('./utils');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function runCheck(query, errorText, errorList) {
 | 
					async function runCheck(query, errorText, errorList) {
 | 
				
			||||||
 | 
					    utils.assertArguments(query, errorText, errorList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const result = await sql.getFirstColumn(query);
 | 
					    const result = await sql.getFirstColumn(query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (result.length > 0) {
 | 
					    if (result.length > 0) {
 | 
				
			||||||
@ -138,7 +141,7 @@ async function runAllChecks() {
 | 
				
			|||||||
          WHERE
 | 
					          WHERE
 | 
				
			||||||
            (SELECT COUNT(*) FROM notes_tree WHERE notes.note_id = notes_tree.note_id AND notes_tree.is_deleted = 0) = 0
 | 
					            (SELECT COUNT(*) FROM notes_tree WHERE notes.note_id = notes_tree.note_id AND notes_tree.is_deleted = 0) = 0
 | 
				
			||||||
            AND notes.is_deleted = 0
 | 
					            AND notes.is_deleted = 0
 | 
				
			||||||
    `,);
 | 
					    `, 'No undeleted note trees for note IDs', errorList);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    await runCheck(`
 | 
					    await runCheck(`
 | 
				
			||||||
          SELECT 
 | 
					          SELECT 
 | 
				
			||||||
 | 
				
			|||||||
@ -19,7 +19,8 @@ async function getHashes() {
 | 
				
			|||||||
    const optionsQuestionMarks = Array(options.SYNCED_OPTIONS.length).fill('?').join(',');
 | 
					    const optionsQuestionMarks = Array(options.SYNCED_OPTIONS.length).fill('?').join(',');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const hashes = {
 | 
					    const hashes = {
 | 
				
			||||||
        notes: getHash(await sql.getAll(`SELECT
 | 
					        notes: getHash(await sql.getAll(`
 | 
				
			||||||
 | 
					            SELECT
 | 
				
			||||||
              note_id,
 | 
					              note_id,
 | 
				
			||||||
              note_title,
 | 
					              note_title,
 | 
				
			||||||
              note_text,
 | 
					              note_text,
 | 
				
			||||||
@ -29,7 +30,8 @@ async function getHashes() {
 | 
				
			|||||||
            FROM notes
 | 
					            FROM notes
 | 
				
			||||||
            ORDER BY note_id`)),
 | 
					            ORDER BY note_id`)),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        notes_tree: getHash(await sql.getAll(`SELECT
 | 
					        notes_tree: getHash(await sql.getAll(`
 | 
				
			||||||
 | 
					            SELECT
 | 
				
			||||||
               note_tree_id,
 | 
					               note_tree_id,
 | 
				
			||||||
               note_id,
 | 
					               note_id,
 | 
				
			||||||
               parent_note_id,
 | 
					               parent_note_id,
 | 
				
			||||||
@ -40,7 +42,8 @@ async function getHashes() {
 | 
				
			|||||||
             FROM notes_tree
 | 
					             FROM notes_tree
 | 
				
			||||||
             ORDER BY note_tree_id`)),
 | 
					             ORDER BY note_tree_id`)),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        notes_history: getHash(await sql.getAll(`SELECT
 | 
					        notes_history: getHash(await sql.getAll(`
 | 
				
			||||||
 | 
					            SELECT
 | 
				
			||||||
              note_history_id,
 | 
					              note_history_id,
 | 
				
			||||||
              note_id,
 | 
					              note_id,
 | 
				
			||||||
              note_title,
 | 
					              note_title,
 | 
				
			||||||
@ -50,7 +53,8 @@ async function getHashes() {
 | 
				
			|||||||
            FROM notes_history
 | 
					            FROM notes_history
 | 
				
			||||||
            ORDER BY note_history_id`)),
 | 
					            ORDER BY note_history_id`)),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        recent_notes: getHash(await sql.getAll(`SELECT
 | 
					        recent_notes: getHash(await sql.getAll(`
 | 
				
			||||||
 | 
					           SELECT
 | 
				
			||||||
             note_tree_id,
 | 
					             note_tree_id,
 | 
				
			||||||
             note_path,
 | 
					             note_path,
 | 
				
			||||||
             date_accessed,
 | 
					             date_accessed,
 | 
				
			||||||
@ -58,12 +62,27 @@ async function getHashes() {
 | 
				
			|||||||
           FROM recent_notes
 | 
					           FROM recent_notes
 | 
				
			||||||
           ORDER BY note_path`)),
 | 
					           ORDER BY note_path`)),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        options: getHash(await sql.getAll(`SELECT 
 | 
					        options: getHash(await sql.getAll(`
 | 
				
			||||||
 | 
					           SELECT 
 | 
				
			||||||
             opt_name,
 | 
					             opt_name,
 | 
				
			||||||
             opt_value 
 | 
					             opt_value 
 | 
				
			||||||
           FROM options 
 | 
					           FROM options 
 | 
				
			||||||
           WHERE opt_name IN (${optionsQuestionMarks}) 
 | 
					           WHERE opt_name IN (${optionsQuestionMarks}) 
 | 
				
			||||||
                                                  ORDER BY opt_name`, options.SYNCED_OPTIONS))
 | 
					           ORDER BY opt_name`, options.SYNCED_OPTIONS)),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // we don't include image data on purpose because they are quite large, checksum is good enough
 | 
				
			||||||
 | 
					        // to represent the data anyway
 | 
				
			||||||
 | 
					        images: getHash(await sql.getAll(`
 | 
				
			||||||
 | 
					          SELECT 
 | 
				
			||||||
 | 
					            image_id,
 | 
				
			||||||
 | 
					            format,
 | 
				
			||||||
 | 
					            checksum,
 | 
				
			||||||
 | 
					            name,
 | 
				
			||||||
 | 
					            is_deleted,
 | 
				
			||||||
 | 
					            date_modified,
 | 
				
			||||||
 | 
					            date_created
 | 
				
			||||||
 | 
					          FROM images  
 | 
				
			||||||
 | 
					          ORDER BY image_id`))
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const elapseTimeMs = new Date().getTime() - startTime.getTime();
 | 
					    const elapseTimeMs = new Date().getTime() - startTime.getTime();
 | 
				
			||||||
 | 
				
			|||||||
@ -143,6 +143,9 @@ async function pullSync(syncContext) {
 | 
				
			|||||||
        else if (sync.entity_name === 'recent_notes') {
 | 
					        else if (sync.entity_name === 'recent_notes') {
 | 
				
			||||||
            await syncUpdate.updateRecentNotes(resp, syncContext.sourceId);
 | 
					            await syncUpdate.updateRecentNotes(resp, syncContext.sourceId);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        else if (sync.entity_name === 'images') {
 | 
				
			||||||
 | 
					            await syncUpdate.updateImage(resp, syncContext.sourceId);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            throw new Error(`Unrecognized entity type ${sync.entity_name} in sync #${sync.id}`);
 | 
					            throw new Error(`Unrecognized entity type ${sync.entity_name} in sync #${sync.id}`);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -214,6 +217,13 @@ async function pushEntity(sync, syncContext) {
 | 
				
			|||||||
    else if (sync.entity_name === 'recent_notes') {
 | 
					    else if (sync.entity_name === 'recent_notes') {
 | 
				
			||||||
        entity = await sql.getFirst('SELECT * FROM recent_notes WHERE note_tree_id = ?', [sync.entity_id]);
 | 
					        entity = await sql.getFirst('SELECT * FROM recent_notes WHERE note_tree_id = ?', [sync.entity_id]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else if (sync.entity_name === 'images') {
 | 
				
			||||||
 | 
					        entity = await sql.getFirst('SELECT * FROM images WHERE image_id = ?', [sync.entity_id]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (entity.data !== null) {
 | 
				
			||||||
 | 
					            entity.data = entity.data.toString('base64');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    else {
 | 
					    else {
 | 
				
			||||||
        throw new Error(`Unrecognized entity type ${sync.entity_name} in sync #${sync.id}`);
 | 
					        throw new Error(`Unrecognized entity type ${sync.entity_name} in sync #${sync.id}`);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -28,6 +28,10 @@ async function addRecentNoteSync(noteTreeId, sourceId) {
 | 
				
			|||||||
    await addEntitySync("recent_notes", noteTreeId, sourceId);
 | 
					    await addEntitySync("recent_notes", noteTreeId, sourceId);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function addImageSync(imageId, sourceId) {
 | 
				
			||||||
 | 
					    await addEntitySync("images", imageId, sourceId);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function addEntitySync(entityName, entityId, sourceId) {
 | 
					async function addEntitySync(entityName, entityId, sourceId) {
 | 
				
			||||||
    await sql.replace("sync", {
 | 
					    await sql.replace("sync", {
 | 
				
			||||||
        entity_name: entityName,
 | 
					        entity_name: entityName,
 | 
				
			||||||
@ -78,6 +82,7 @@ async function fillAllSyncRows() {
 | 
				
			|||||||
    await fillSyncRows("notes_tree", "note_tree_id");
 | 
					    await fillSyncRows("notes_tree", "note_tree_id");
 | 
				
			||||||
    await fillSyncRows("notes_history", "note_history_id");
 | 
					    await fillSyncRows("notes_history", "note_history_id");
 | 
				
			||||||
    await fillSyncRows("recent_notes", "note_tree_id");
 | 
					    await fillSyncRows("recent_notes", "note_tree_id");
 | 
				
			||||||
 | 
					    await fillSyncRows("images", "image_id");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
@ -87,6 +92,7 @@ module.exports = {
 | 
				
			|||||||
    addNoteHistorySync,
 | 
					    addNoteHistorySync,
 | 
				
			||||||
    addOptionsSync,
 | 
					    addOptionsSync,
 | 
				
			||||||
    addRecentNoteSync,
 | 
					    addRecentNoteSync,
 | 
				
			||||||
 | 
					    addImageSync,
 | 
				
			||||||
    cleanupSyncRowsForMissingEntities,
 | 
					    cleanupSyncRowsForMissingEntities,
 | 
				
			||||||
    fillAllSyncRows
 | 
					    fillAllSyncRows
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -92,11 +92,30 @@ async function updateRecentNotes(entity, sourceId) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async function updateImage(entity, sourceId) {
 | 
				
			||||||
 | 
					    if (entity.data !== null) {
 | 
				
			||||||
 | 
					        entity.data = Buffer.from(entity.data, 'base64');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const origImage = await sql.getFirst("SELECT * FROM images WHERE image_id = ?", [entity.image_id]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!origImage || origImage.date_modified <= entity.date_modified) {
 | 
				
			||||||
 | 
					        await sql.doInTransaction(async () => {
 | 
				
			||||||
 | 
					            await sql.replace("images", entity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            await sync_table.addImageSync(entity.image_id, sourceId);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        log.info("Update/sync image " + entity.image_id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
    updateNote,
 | 
					    updateNote,
 | 
				
			||||||
    updateNoteTree,
 | 
					    updateNoteTree,
 | 
				
			||||||
    updateNoteHistory,
 | 
					    updateNoteHistory,
 | 
				
			||||||
    updateNoteReordering,
 | 
					    updateNoteReordering,
 | 
				
			||||||
    updateOptions,
 | 
					    updateOptions,
 | 
				
			||||||
    updateRecentNotes
 | 
					    updateRecentNotes,
 | 
				
			||||||
 | 
					    updateImage
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -79,6 +79,14 @@ function sanitizeSql(str) {
 | 
				
			|||||||
    return str.replace(/'/g, "\\'");
 | 
					    return str.replace(/'/g, "\\'");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function assertArguments() {
 | 
				
			||||||
 | 
					    for (const i in arguments) {
 | 
				
			||||||
 | 
					        if (!arguments[i]) {
 | 
				
			||||||
 | 
					            throw new Error(`Argument idx#${i} should not be falsy: ${arguments[i]}`);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
    randomSecureToken,
 | 
					    randomSecureToken,
 | 
				
			||||||
    randomString,
 | 
					    randomString,
 | 
				
			||||||
@ -95,5 +103,6 @@ module.exports = {
 | 
				
			|||||||
    hash,
 | 
					    hash,
 | 
				
			||||||
    isEmptyOrWhitespace,
 | 
					    isEmptyOrWhitespace,
 | 
				
			||||||
    getDateTimeForFile,
 | 
					    getDateTimeForFile,
 | 
				
			||||||
    sanitizeSql
 | 
					    sanitizeSql,
 | 
				
			||||||
 | 
					    assertArguments
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user