From e55a04c1565d649dde98996549a431a6610b27d5 Mon Sep 17 00:00:00 2001 From: Bobby Wibowo Date: Sun, 6 Jan 2019 13:27:17 +0700 Subject: [PATCH] Updates Added cfpurge.js to scripts directory. This can be used to purge cache of frontend pages and uploads. Do "node scripts/cfpurge.js --help" for usage. Removed "randver" from package.js/scripts. I've installed randomstring globally instead and just simply do: randomstring n Back then I didn't know it could be used that way. --- controllers/utilsController.js | 33 +++++++++++++++++++-------------- package.json | 6 +++--- scripts/_utils.js | 13 +++++++++++++ scripts/cfpurge.js | 25 +++++++++++++++++++++++++ scripts/thumbs.js | 28 ++++++++++++++++++---------- 5 files changed, 78 insertions(+), 27 deletions(-) create mode 100644 scripts/_utils.js create mode 100644 scripts/cfpurge.js diff --git a/controllers/utilsController.js b/controllers/utilsController.js index 03cf145..35a71a3 100644 --- a/controllers/utilsController.js +++ b/controllers/utilsController.js @@ -187,8 +187,10 @@ utilsController.generateThumbs = (name, force) => { .toFile(thumbname) } }) + .then(() => { + resolve(true) + }) .catch(error => { - if (!error) return resolve(true) console.error(`${name}: ${error.toString()}`) fs.symlink(thumbUnavailable, thumbname, error => { if (error) console.error(error) @@ -304,33 +306,34 @@ utilsController.bulkDeleteFiles = async (field, values, user, set) => { .catch(console.error) } - if (config.cloudflare.purgeCache) { - // purgeCloudflareCache() is an async function, but let us not wait for it - const names = filtered.map(file => file.name) - utilsController.purgeCloudflareCache(names) - } + // purgeCloudflareCache() is an async function, but let us not wait for it + if (config.cloudflare.purgeCache) + utilsController.purgeCloudflareCache(filtered.map(file => file.name), true) return failed } -utilsController.purgeCloudflareCache = async names => { - if (!cloudflareAuth) return +utilsController.purgeCloudflareCache = async (names, uploads, verbose) => { + if (!cloudflareAuth) return false + + let domain = config.domain + if (!uploads) domain = config.homeDomain const thumbs = [] names = names.map(name => { - const url = `${config.domain}/${name}` + const url = `${domain}/${name}` const extname = utilsController.extname(name) - if (utilsController.mayGenerateThumb(extname)) - thumbs.push(`${config.domain}/thumbs/${name.slice(0, -extname.length)}.png`) - + if (uploads && utilsController.mayGenerateThumb(extname)) + thumbs.push(`${domain}/thumbs/${name.slice(0, -extname.length)}.png`) return url }) try { + const files = names.concat(thumbs) const url = `https://api.cloudflare.com/client/v4/zones/${config.cloudflare.zoneId}/purge_cache` const fetchPurge = await fetch(url, { method: 'POST', - body: JSON.stringify({ files: names.concat(thumbs) }), + body: JSON.stringify({ files }), headers: { 'Content-Type': 'application/json', 'X-Auth-Email': config.cloudflare.email, @@ -338,8 +341,10 @@ utilsController.purgeCloudflareCache = async names => { } }).then(res => res.json()) - if (fetchPurge.errors) + if (Array.isArray(fetchPurge.errors) && fetchPurge.errors.length) fetchPurge.errors.forEach(error => console.error(`CF: ${error.code}: ${error.message}`)) + else if (verbose) + console.log(`URLs:\n${files.join('\n')}\n\nSuccess: ${fetchPurge.success}`) } catch (error) { console.error(`CF: ${error.toString()}`) } diff --git a/package.json b/package.json index d265a5e..054ae94 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,10 @@ "license": "MIT", "scripts": { "start": "node ./lolisafe.js", - "pm2": "pm2 start --name lolisafe ./lolisafe.js", + "pm2": "pm2 start --name safe ./lolisafe.js", "thumbs": "node ./scripts/thumbs.js", - "randver": "node -e \"console.log(require('randomstring').generate(10))\"", - "pull": "git stash; git pull; yarn; git stash pop" + "pull": "git stash; git pull; yarn; git stash pop", + "pm2restart": "pm2 restart safe" }, "dependencies": { "bcrypt": "^2.0.1", diff --git a/scripts/_utils.js b/scripts/_utils.js new file mode 100644 index 0000000..54569c6 --- /dev/null +++ b/scripts/_utils.js @@ -0,0 +1,13 @@ +module.exports = { + stripIndents (string) { + if (!string) return + const result = string.replace(/^[^\S\n]+/gm, '') + const match = result.match(/^[^\S\n]*(?=\S)/gm) + const indent = match && Math.min(...match.map(el => el.length)) + if (indent) { + const regexp = new RegExp(`^.{${indent}}`, 'gm') + return result.replace(regexp, '') + } + return result + } +} diff --git a/scripts/cfpurge.js b/scripts/cfpurge.js new file mode 100644 index 0000000..828f296 --- /dev/null +++ b/scripts/cfpurge.js @@ -0,0 +1,25 @@ +const { stripIndents } = require('./_utils') +const utils = require('./../controllers/utilsController') +const config = require('./../config') + +const cfpurge = {} + +cfpurge.do = async () => { + const location = process.argv[1].replace(process.cwd() + '/', '') + const args = process.argv.slice(2) + if (args.includes('--help') || args.includes('-h')) + return console.log(stripIndents(` + Purge Cloudflare's cache. + + Usage:\nnode ${location} [...filename] + + filename: + File names (as in uploads) separated by space (will automatically include their thumbs if available). + If not provided, this will default to frontend pages listed in "pages" array in config.js. + `)) + + const filenames = args.length ? args : config.pages + return utils.purgeCloudflareCache(filenames, Boolean(args.length), true) +} + +cfpurge.do() diff --git a/scripts/thumbs.js b/scripts/thumbs.js index 3be88f4..1e82583 100644 --- a/scripts/thumbs.js +++ b/scripts/thumbs.js @@ -1,3 +1,4 @@ +const { stripIndents } = require('./_utils') const fs = require('fs') const path = require('path') const utils = require('./../controllers/utilsController') @@ -32,19 +33,26 @@ thumbs.getFiles = directory => { } thumbs.do = async () => { + const location = process.argv[1].replace(process.cwd() + '/', '') const args = process.argv.slice(2) thumbs.mode = parseInt(args[0]) - thumbs.force = parseInt(args[1]) - thumbs.verbose = parseInt(args[2]) - if ((isNaN(thumbs.mode) || ![1, 2, 3].includes(thumbs.mode)) || - (!isNaN(thumbs.force) && ![0, 1].includes(thumbs.force))) { - console.log('Usage :\nyarn thumbs [force=0|1] [verbose=0|1]\n') - console.log('mode : 1 = images only, 2 = videos only, 3 = both images and videos') - console.log('force : 0 = no force (default), 1 = overwrite existing thumbnails') - console.log('verbose: 0 = only print missing thumbs (default), 1 = print all') - return - } + thumbs.force = parseInt(args[1] || 0) + thumbs.verbose = parseInt(args[2] || 0) + if (![1, 2, 3].includes(thumbs.mode) || + ![0, 1].includes(thumbs.force) || + ![0, 1].includes(thumbs.verbose) || + args.includes('--help') || + args.includes('-h')) + return console.log(stripIndents(` + Generate thumbnails. + + Usage :\nnode ${location} [force=0|1] [verbose=0|1] + + mode : 1 = images only, 2 = videos only, 3 = both images and videos + force : 0 = no force (default), 1 = overwrite existing thumbnails + verbose: 0 = only print missing thumbs (default), 1 = print all + `)) const uploadsDir = path.join(__dirname, '..', 'uploads') const thumbsDir = path.join(uploadsDir, 'thumbs')