From 4fc9da81a944f12007f11e77c2edeaf7a28db2f0 Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 24 Nov 2020 15:03:42 -0500 Subject: [PATCH] refactor: topic thumbs lib to topics.thumbs --- src/posts/edit.js | 2 +- src/topics/create.js | 2 +- src/topics/index.js | 2 +- src/topics/thumb.js | 87 ------------------------------------------- src/topics/thumbs.js | 88 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 90 deletions(-) delete mode 100644 src/topics/thumb.js create mode 100644 src/topics/thumbs.js diff --git a/src/posts/edit.js b/src/posts/edit.js index 667c1b0553..bb651e0dfa 100644 --- a/src/posts/edit.js +++ b/src/posts/edit.js @@ -124,7 +124,7 @@ module.exports = function (Posts) { } if (data.thumb) { - await topics.resizeAndUploadThumb(data); + await topics.thumbs.resizeAndUpload(data); newTopicData.thumb = data.thumb; } diff --git a/src/topics/create.js b/src/topics/create.js index 741447200f..cadee2fa0c 100644 --- a/src/topics/create.js +++ b/src/topics/create.js @@ -20,7 +20,7 @@ module.exports = function (Topics) { Topics.create = async function (data) { // This is an internal method, consider using Topics.post instead const timestamp = data.timestamp || Date.now(); - await Topics.resizeAndUploadThumb(data); + await Topics.thumbs.resizeAndUpload(data); const tid = await db.incrObjectField('global', 'nextTid'); diff --git a/src/topics/index.js b/src/topics/index.js index ff864d19a4..97b341f010 100644 --- a/src/topics/index.js +++ b/src/topics/index.js @@ -29,7 +29,7 @@ require('./tags')(Topics); require('./teaser')(Topics); require('./suggested')(Topics); require('./tools')(Topics); -require('./thumb')(Topics); +Topics.thumbs = require('./thumbs'); require('./bookmarks')(Topics); require('./merge')(Topics); diff --git a/src/topics/thumb.js b/src/topics/thumb.js deleted file mode 100644 index 9afd2ddb6b..0000000000 --- a/src/topics/thumb.js +++ /dev/null @@ -1,87 +0,0 @@ - -'use strict'; - -var nconf = require('nconf'); -var path = require('path'); -var fs = require('fs'); -var request = require('request'); -var mime = require('mime'); -var validator = require('validator'); -var util = require('util'); - -var meta = require('../meta'); -var image = require('../image'); -var file = require('../file'); -var plugins = require('../plugins'); - -module.exports = function (Topics) { - const getHead = util.promisify(request.head); - - function pipeToFile(source, destination, callback) { - request(source).pipe(fs.createWriteStream(destination)).on('close', callback); - } - const pipeToFileAsync = util.promisify(pipeToFile); - - Topics.resizeAndUploadThumb = async function (data) { - const allowedExtensions = file.allowedExtensions(); - - // Handle protocol-relative URLs - if (data.thumb && data.thumb.startsWith('//')) { - data.thumb = `${nconf.get('secure') ? 'https' : 'http'}:${data.thumb}`; - } - - // Only continue if passed in thumbnail exists and is a URL. A system path means an upload is not necessary. - if (!data.thumb || !validator.isURL(data.thumb)) { - return; - } - var pathToUpload; - const res = await getHead(data.thumb); - - try { - const type = res.headers['content-type']; - if (!type.match(/image./)) { - throw new Error('[[error:invalid-file]]'); - } - - var extension = path.extname(data.thumb); - if (!extension) { - extension = '.' + mime.getExtension(type); - } - - if (!allowedExtensions.includes(extension)) { - throw new Error('[[error:invalid-file]]'); - } - - const filename = Date.now() + '-topic-thumb' + extension; - const folder = 'files'; - pathToUpload = path.join(nconf.get('upload_path'), folder, filename); - - await pipeToFileAsync(data.thumb, pathToUpload); - - await image.isFileTypeAllowed(pathToUpload); - - await image.checkDimensions(pathToUpload); - await image.resizeImage({ - path: pathToUpload, - width: meta.config.topicThumbSize, - height: meta.config.topicThumbSize, - }); - - if (!plugins.hooks.hasListeners('filter:uploadImage')) { - data.thumb = '/assets/uploads/' + folder + '/' + filename; - return; - } - - const uploadedFile = await plugins.hooks.fire('filter:uploadImage', { - image: { path: pathToUpload, name: '' }, - uid: data.uid, - folder: folder, - }); - file.delete(pathToUpload); - data.thumb = uploadedFile.url; - } catch (err) { - file.delete(pathToUpload); - throw err; - } - }; -}; diff --git a/src/topics/thumbs.js b/src/topics/thumbs.js new file mode 100644 index 0000000000..63d4a6adee --- /dev/null +++ b/src/topics/thumbs.js @@ -0,0 +1,88 @@ + +'use strict'; + +var nconf = require('nconf'); +var path = require('path'); +var fs = require('fs'); +var request = require('request'); +var mime = require('mime'); +var validator = require('validator'); +var util = require('util'); + +var meta = require('../meta'); +var image = require('../image'); +var file = require('../file'); +var plugins = require('../plugins'); + +const Thumbs = {}; +module.exports = Thumbs; + +const getHead = util.promisify(request.head); + +function pipeToFile(source, destination, callback) { + request(source).pipe(fs.createWriteStream(destination)).on('close', callback); +} +const pipeToFileAsync = util.promisify(pipeToFile); + +Thumbs.resizeAndUpload = async function (data) { + const allowedExtensions = file.allowedExtensions(); + + // Handle protocol-relative URLs + if (data.thumb && data.thumb.startsWith('//')) { + data.thumb = `${nconf.get('secure') ? 'https' : 'http'}:${data.thumb}`; + } + + // Only continue if passed in thumbnail exists and is a URL. A system path means an upload is not necessary. + if (!data.thumb || !validator.isURL(data.thumb)) { + return; + } + var pathToUpload; + const res = await getHead(data.thumb); + + try { + const type = res.headers['content-type']; + if (!type.match(/image./)) { + throw new Error('[[error:invalid-file]]'); + } + + var extension = path.extname(data.thumb); + if (!extension) { + extension = '.' + mime.getExtension(type); + } + + if (!allowedExtensions.includes(extension)) { + throw new Error('[[error:invalid-file]]'); + } + + const filename = Date.now() + '-topic-thumb' + extension; + const folder = 'files'; + pathToUpload = path.join(nconf.get('upload_path'), folder, filename); + + await pipeToFileAsync(data.thumb, pathToUpload); + + await image.isFileTypeAllowed(pathToUpload); + + await image.checkDimensions(pathToUpload); + await image.resizeImage({ + path: pathToUpload, + width: meta.config.topicThumbSize, + height: meta.config.topicThumbSize, + }); + + if (!plugins.hooks.hasListeners('filter:uploadImage')) { + data.thumb = '/assets/uploads/' + folder + '/' + filename; + return; + } + + const uploadedFile = await plugins.hooks.fire('filter:uploadImage', { + image: { path: pathToUpload, name: '' }, + uid: data.uid, + folder: folder, + }); + file.delete(pathToUpload); + data.thumb = uploadedFile.url; + } catch (err) { + file.delete(pathToUpload); + throw err; + } +};