From 64b04abbe9980a25e105acb41c50f778e76491f9 Mon Sep 17 00:00:00 2001 From: Bobby Wibowo Date: Fri, 27 Apr 2018 10:27:34 +0700 Subject: [PATCH] Updates (a small breaking change with config file) "generateZips" is no longer merely accepting boolean value, it's now an object with 2 properties: "enabled" and "maxTotalSize". The former is of course to enable/disable zip generation, while the latter is to limit the total size of all the files in an album. If the total size exceeds the set limit, it will not generate a zip file. It'll probably be useful when used alongside Cloudflare's Cache Everything (since Cloudflare will only cache files with a maximum size of 512MB). --- config.sample.js | 13 ++++++++++--- controllers/albumsController.js | 21 ++++++++++++++++++--- routes/album.js | 2 +- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/config.sample.js b/config.sample.js index a46c411..593b073 100644 --- a/config.sample.js +++ b/config.sample.js @@ -121,11 +121,18 @@ module.exports = { }, /* - Allows users to download a .zip file of all files in an album. + Allows users to download a ZIP file of all files in an album. The file is generated when the user clicks the download button in the view - and is re-used if the album has not changed between download requests + and is re-used if the album has not changed between download requests. + If "maxTotalSize" is set (needs to be in MB), generating ZIP file will be disabled + if the total size of all the files in the album exceeds the set limit. + If you have CloudFlare properly caching the zipping API route, it's recommended to + set this to '512MB' as CloudFlare will not cache files bigger than that. */ - generateZips: true + generateZips: { + enabled: true, + maxTotalSize: null + } }, // Folder where to store logs diff --git a/controllers/albumsController.js b/controllers/albumsController.js index a74a323..42d535e 100644 --- a/controllers/albumsController.js +++ b/controllers/albumsController.js @@ -209,7 +209,7 @@ albumsController.generateZip = async (req, res, next) => { }) } - if (!config.uploads.generateZips) { + if (!config.uploads.generateZips || !config.uploads.generateZips.enabled) { return res.status(401).json({ success: false, description: 'Zip generation disabled.' @@ -238,7 +238,7 @@ albumsController.generateZip = async (req, res, next) => { } else { console.log(`Generating zip for album identifier: ${identifier}`) const files = await db.table('files') - .select('name') + .select('name', 'size') .where('albumid', album.id) if (files.length === 0) { return res.json({ @@ -247,6 +247,17 @@ albumsController.generateZip = async (req, res, next) => { }) } + if (config.uploads.generateZips.maxTotalSize) { + const maxTotalSizeBytes = parseInt(config.uploads.generateZips.maxTotalSize) * 1000000 + const totalSizeBytes = files.reduce((accumulator, file) => accumulator + parseInt(file.size), 0) + if (totalSizeBytes > maxTotalSizeBytes) { + return res.json({ + success: false, + description: `Total size of all the files in the album exceeds the limit set by the administrator (${config.uploads.generateZips.maxTotalSize}).` + }) + } + } + const zipPath = path.join(__dirname, '..', config.uploads.folder, 'zips', `${album.identifier}.zip`) const archive = new Zip() @@ -262,7 +273,11 @@ albumsController.generateZip = async (req, res, next) => { archive .generateNodeStream({ type: 'nodebuffer', - streamFiles: true + streamFiles: true, + compression: 'DEFLATE', + compressionOptions: { + level: 1 + } }) .pipe(fs.createWriteStream(zipPath)) .on('finish', async () => { diff --git a/routes/album.js b/routes/album.js index 3197c82..76de1df 100644 --- a/routes/album.js +++ b/routes/album.js @@ -61,7 +61,7 @@ routes.get('/a/:identifier', async (req, res, next) => { thumb, files, identifier, - enableDownload: Boolean(config.uploads.generateZips), + enableDownload: Boolean(config.uploads.generateZips && config.uploads.generateZips.enabled), editedAt: album.editedAt, url: `${homeDomain}/a/${album.identifier}` })