From 8d4175704750a24a3e350d4162512e11139ae71b Mon Sep 17 00:00:00 2001 From: danactive Date: Wed, 12 Feb 2020 17:48:29 -0800 Subject: [PATCH 1/4] fix(Resize): Improve error message when GraphicsMagick is missing --- api/server/plugins/resize/lib/index.js | 26 +++++++++++--------- api/server/plugins/resize/lib/resize.js | 8 +++--- api/server/plugins/resize/test/index.spec.js | 23 ++++++++++++++--- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/api/server/plugins/resize/lib/index.js b/api/server/plugins/resize/lib/index.js index d7807878c..0cf9a3dfe 100644 --- a/api/server/plugins/resize/lib/index.js +++ b/api/server/plugins/resize/lib/index.js @@ -1,13 +1,22 @@ +const dotProp = require('dot-prop'); + const resizeMod = require('./resize'); const validation = require('../../../lib/validation'); -const handler = request => new Promise((reply) => { +async function handler(request, h) { const sourcePath = request.payload.source_path; - resizeMod.resize(sourcePath) - .then(() => reply({ resize: true })) - .catch(reply); -}); + try { + const response = await resizeMod.resize(sourcePath); + if (dotProp.get(response, 'meta.error.count', 0) > 0) { + return h.response(response.meta.error).code(500); + } + + return { resize: true }; + } catch (error) { + return error; + } +} const register = (server) => { server.route({ @@ -21,11 +30,6 @@ const register = (server) => { source_path: validation.sourceFolder, }, }, - response: { - schema: { - resize: validation.resize, - }, - }, }, }); }; @@ -33,7 +37,7 @@ const register = (server) => { const plugin = { register, name: 'resize', - version: '0.3.0', + version: '1.0.0', }; module.exports = { plugin }; diff --git a/api/server/plugins/resize/lib/resize.js b/api/server/plugins/resize/lib/resize.js index 5b54ec061..8dcb35519 100644 --- a/api/server/plugins/resize/lib/resize.js +++ b/api/server/plugins/resize/lib/resize.js @@ -28,7 +28,7 @@ function resize(sourcePath) { const thumbPath = originalPath.replace('originals', 'thumbs'); if (errOrient) { - errors.push(`Original orientation write error: ${errOrient}`); + errors.push(`Resize original: ${errOrient.message}`); } function possibleCompletion() { @@ -38,7 +38,7 @@ function resize(sourcePath) { meta: { error: { count: errors.length, - message: errors.join('; '), + message: errors, }, }, payload: { @@ -56,7 +56,7 @@ function resize(sourcePath) { .resize(photoDims.width, photoDims.height) .write(photoPath, (errResize) => { if (errResize) { - errors.push(`Photo resize write error: ${errResize}`); + errors.push(`Resize photo: ${errResize.message}`); } possibleCompletion(); }); @@ -66,7 +66,7 @@ function resize(sourcePath) { .noProfile() .write(thumbPath, (errResize) => { if (errResize) { - errors.push(`Thumbnail resize write error: ${errResize}`); + errors.push(`Resize thumbnail: ${errResize.message}`); } possibleCompletion(); }); diff --git a/api/server/plugins/resize/test/index.spec.js b/api/server/plugins/resize/test/index.spec.js index 0225115fe..42ad30bf0 100644 --- a/api/server/plugins/resize/test/index.spec.js +++ b/api/server/plugins/resize/test/index.spec.js @@ -1,5 +1,7 @@ const tape = require('tape-catch'); +const existsChecker = require('../../exists/lib/exists'); + tape('Verify /resize route', { skip: false }, (describe) => { const calipers = require('calipers')('jpeg'); const hapi = require('@hapi/hapi'); @@ -78,16 +80,31 @@ tape('Verify /resize route', { skip: false }, (describe) => { try { await server.register(plugins); const response = await server.inject(request); - assert.ok(response, 'Has response'); + if (response.statusCode !== 200) { + assert.equal(response.statusCode, 200, JSON.stringify(response.result)); + } + + await existsChecker.pathExists(originalRelativeFile); + assert.ok(originalRelativeFile, `Original image file found at relative ${originalRelativeFile}`); + const originalAbsoluteFile = await utils.file.safePublicPath(originalRelativeFile); + await existsChecker.pathExists(originalAbsoluteFile); + assert.ok(originalAbsoluteFile, `Original image file found at ${originalAbsoluteFile}`); + const photoPath = originalAbsoluteFile.replace(ORIGINAL_FOLDER_NAME, PHOTO_FOLDER_NAME); + await existsChecker.pathExists(photoPath); + assert.ok(originalRelativeFile, `Photo image file found at ${photoPath}`); + const resultsPhoto = await calipers.measure(photoPath); - assert.equal(resultsPhoto.pages[0].width, photoDims.width, 'Photo width measured'); - assert.ok(resultsPhoto.pages[0].height <= photoDims.height, 'Photo height measured'); + assert.equal(resultsPhoto.pages[0].width, photoDims.width, `Photo width measured at ${photoDims.width}`); + assert.ok(resultsPhoto.pages[0].height <= photoDims.height, `Photo height measured at ${photoDims.height}`); const thumbPath = originalAbsoluteFile.replace(ORIGINAL_FOLDER_NAME, THUMB_FOLDER_NAME); + await existsChecker.pathExists(thumbPath); + assert.ok(originalRelativeFile, `Thumb image file found at ${thumbPath}`); + const resultsThumb = await calipers.measure(thumbPath); assert.equal(resultsThumb.pages[0].width, thumbDims.width, 'Thumb width measured'); assert.ok(resultsThumb.pages[0].height <= thumbDims.height, 'Thumb height measured'); From 443f70e965d1f8ea3b2f9207050b4bdfcbb7f942 Mon Sep 17 00:00:00 2001 From: danactive Date: Sun, 23 Feb 2020 16:57:17 -0800 Subject: [PATCH 2/4] chore(Resize): Improve error message when resized images is missing --- api/server/plugins/resize/test/resize.spec.js | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/api/server/plugins/resize/test/resize.spec.js b/api/server/plugins/resize/test/resize.spec.js index 291379cfe..7e6a76d19 100644 --- a/api/server/plugins/resize/test/resize.spec.js +++ b/api/server/plugins/resize/test/resize.spec.js @@ -1,5 +1,6 @@ /* global JSON, require */ const tape = require('tape-catch'); +const existsChecker = require('../../exists/lib/exists'); tape('Verify resize library', { skip: false }, (describe) => { const calipers = require('calipers')('jpeg'); @@ -38,24 +39,48 @@ tape('Verify resize library', { skip: false }, (describe) => { describe.test('* Resize JPEG file to photo and thumb to parent folder', { skip: false }, async (assert) => { const originalRelativeFile = path.join(fixturesPath, 'originals/2016-07-12.jpg'); - await plugin.resize(originalRelativeFile); + const originalAbsoluteFile = await utils.file.safePublicPath(originalRelativeFile); + + try { + await existsChecker.pathExists(originalRelativeFile); + + assert.ok(originalRelativeFile, `Original image file found at relative ${originalRelativeFile}`); + + await plugin.resize(originalRelativeFile); + + await existsChecker.pathExists(originalAbsoluteFile); + assert.ok(originalAbsoluteFile, `Original image file found at ${originalAbsoluteFile}`); + } catch (error) { + assert.fail(`Original resize failed ${error}`); + } try { - const originalAbsoluteFile = await utils.file.safePublicPath(originalRelativeFile); const photoPath = originalAbsoluteFile.replace(ORIGINAL_FOLDER_NAME, PHOTO_FOLDER_NAME); + await existsChecker.pathExists(photoPath); + assert.ok(originalRelativeFile, `Photo image file found at ${photoPath}`); + const resultPhoto = await calipers.measure(photoPath); - assert.equal(resultPhoto.pages[0].width, photoDims.width, 'Photo width measured'); - assert.ok(resultPhoto.pages[0].height <= photoDims.height, 'Photo height measured'); + assert.equal(resultPhoto.pages[0].width, photoDims.width, `Photo width measured at ${photoDims.width}`); + assert.ok(resultPhoto.pages[0].height <= photoDims.height, `Photo height measured at ${photoDims.height}`); + fs.unlink(photoPath, () => assert.pass('Clean up photo')); + } catch (error) { + assert.fail(`Photo resize failed ${error}`); + } + try { const thumbPath = originalAbsoluteFile.replace(ORIGINAL_FOLDER_NAME, THUMB_FOLDER_NAME); + + await existsChecker.pathExists(thumbPath); + assert.ok(originalRelativeFile, `Thumb image file found at ${thumbPath}`); + const resultThumb = await calipers.measure(thumbPath); assert.equal(resultThumb.pages[0].width, thumbDims.width, 'Thumb width measured'); assert.ok(resultThumb.pages[0].height <= thumbDims.height, 'Thumb height measured'); fs.unlink(thumbPath, () => assert.pass('Clean up thumb')); } catch (error) { - assert.fail(`Resize failed ${error}`); + assert.fail(`Thumbnail resize failed ${error}`); } assert.end(); From 0619f64d0b649258cd873d8081ef868ddc0c2189 Mon Sep 17 00:00:00 2001 From: danactive Date: Sun, 23 Feb 2020 20:13:21 -0800 Subject: [PATCH 3/4] feat(Docker): Add Graphicsmagick --- api/Dockerfile | 7 +++++-- docker-compose.yml | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/api/Dockerfile b/api/Dockerfile index ece87023e..827d05a6b 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -1,4 +1,8 @@ -FROM node:10 +FROM node:10-alpine + +RUN apk add --no-cache --virtual build-dependencies make gcc g++ python && \ + apk add --no-cache krb5-dev imagemagick graphicsmagick + WORKDIR /app/api COPY package.json /app/api COPY package-lock.json /app/api @@ -6,4 +10,3 @@ RUN npm ci COPY . /app/api CMD npm start EXPOSE 8000 - diff --git a/docker-compose.yml b/docker-compose.yml index 2325276f6..a335c46ed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,12 @@ version: '3' services: - web: + api: build: api ports: - "8000:8000" volumes: - ./config.json:/app/config.json:ro - - ./public:/app/public:ro + - ./public:/app/public:ro # Unit tests need no readonly mode so remove `:ro` ui: build: ui ports: From e1431473cf8ac76cf063695928b88b3687321c31 Mon Sep 17 00:00:00 2001 From: danactive Date: Sun, 23 Feb 2020 21:21:50 -0800 Subject: [PATCH 4/4] chore(Resize): Correct merge conflict --- api/server/plugins/resize/test/resize.spec.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/api/server/plugins/resize/test/resize.spec.js b/api/server/plugins/resize/test/resize.spec.js index 7a5bb4dd0..7f9e837e7 100644 --- a/api/server/plugins/resize/test/resize.spec.js +++ b/api/server/plugins/resize/test/resize.spec.js @@ -46,7 +46,7 @@ tape('Verify resize library', { skip: false }, (describe) => { assert.ok(originalRelativeFile, `Original image file found at relative ${originalRelativeFile}`); - await plugin.resize(originalRelativeFile); + await plugin.resize(originalRelativeFile); await existsChecker.pathExists(originalAbsoluteFile); assert.ok(originalAbsoluteFile, `Original image file found at ${originalAbsoluteFile}`); @@ -55,7 +55,6 @@ tape('Verify resize library', { skip: false }, (describe) => { } try { - const originalAbsoluteFile = utils.file.safePublicPath(originalRelativeFile); const photoPath = originalAbsoluteFile.replace(ORIGINAL_FOLDER_NAME, PHOTO_FOLDER_NAME); await existsChecker.pathExists(photoPath);