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.
This commit is contained in:
Bobby Wibowo 2019-01-06 13:27:17 +07:00
parent 3c49d81b3a
commit e55a04c156
No known key found for this signature in database
GPG Key ID: 51C3A1E1E22D26CF
5 changed files with 78 additions and 27 deletions

View File

@ -187,8 +187,10 @@ utilsController.generateThumbs = (name, force) => {
.toFile(thumbname) .toFile(thumbname)
} }
}) })
.then(() => {
resolve(true)
})
.catch(error => { .catch(error => {
if (!error) return resolve(true)
console.error(`${name}: ${error.toString()}`) console.error(`${name}: ${error.toString()}`)
fs.symlink(thumbUnavailable, thumbname, error => { fs.symlink(thumbUnavailable, thumbname, error => {
if (error) console.error(error) if (error) console.error(error)
@ -304,33 +306,34 @@ utilsController.bulkDeleteFiles = async (field, values, user, set) => {
.catch(console.error) .catch(console.error)
} }
if (config.cloudflare.purgeCache) {
// purgeCloudflareCache() is an async function, but let us not wait for it // purgeCloudflareCache() is an async function, but let us not wait for it
const names = filtered.map(file => file.name) if (config.cloudflare.purgeCache)
utilsController.purgeCloudflareCache(names) utilsController.purgeCloudflareCache(filtered.map(file => file.name), true)
}
return failed return failed
} }
utilsController.purgeCloudflareCache = async names => { utilsController.purgeCloudflareCache = async (names, uploads, verbose) => {
if (!cloudflareAuth) return if (!cloudflareAuth) return false
let domain = config.domain
if (!uploads) domain = config.homeDomain
const thumbs = [] const thumbs = []
names = names.map(name => { names = names.map(name => {
const url = `${config.domain}/${name}` const url = `${domain}/${name}`
const extname = utilsController.extname(name) const extname = utilsController.extname(name)
if (utilsController.mayGenerateThumb(extname)) if (uploads && utilsController.mayGenerateThumb(extname))
thumbs.push(`${config.domain}/thumbs/${name.slice(0, -extname.length)}.png`) thumbs.push(`${domain}/thumbs/${name.slice(0, -extname.length)}.png`)
return url return url
}) })
try { try {
const files = names.concat(thumbs)
const url = `https://api.cloudflare.com/client/v4/zones/${config.cloudflare.zoneId}/purge_cache` const url = `https://api.cloudflare.com/client/v4/zones/${config.cloudflare.zoneId}/purge_cache`
const fetchPurge = await fetch(url, { const fetchPurge = await fetch(url, {
method: 'POST', method: 'POST',
body: JSON.stringify({ files: names.concat(thumbs) }), body: JSON.stringify({ files }),
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'X-Auth-Email': config.cloudflare.email, 'X-Auth-Email': config.cloudflare.email,
@ -338,8 +341,10 @@ utilsController.purgeCloudflareCache = async names => {
} }
}).then(res => res.json()) }).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}`)) 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) { } catch (error) {
console.error(`CF: ${error.toString()}`) console.error(`CF: ${error.toString()}`)
} }

View File

@ -16,10 +16,10 @@
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"start": "node ./lolisafe.js", "start": "node ./lolisafe.js",
"pm2": "pm2 start --name lolisafe ./lolisafe.js", "pm2": "pm2 start --name safe ./lolisafe.js",
"thumbs": "node ./scripts/thumbs.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": { "dependencies": {
"bcrypt": "^2.0.1", "bcrypt": "^2.0.1",

13
scripts/_utils.js Normal file
View File

@ -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
}
}

25
scripts/cfpurge.js Normal file
View File

@ -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()

View File

@ -1,3 +1,4 @@
const { stripIndents } = require('./_utils')
const fs = require('fs') const fs = require('fs')
const path = require('path') const path = require('path')
const utils = require('./../controllers/utilsController') const utils = require('./../controllers/utilsController')
@ -32,19 +33,26 @@ thumbs.getFiles = directory => {
} }
thumbs.do = async () => { thumbs.do = async () => {
const location = process.argv[1].replace(process.cwd() + '/', '')
const args = process.argv.slice(2) const args = process.argv.slice(2)
thumbs.mode = parseInt(args[0]) thumbs.mode = parseInt(args[0])
thumbs.force = parseInt(args[1]) thumbs.force = parseInt(args[1] || 0)
thumbs.verbose = parseInt(args[2]) thumbs.verbose = parseInt(args[2] || 0)
if ((isNaN(thumbs.mode) || ![1, 2, 3].includes(thumbs.mode)) || if (![1, 2, 3].includes(thumbs.mode) ||
(!isNaN(thumbs.force) && ![0, 1].includes(thumbs.force))) { ![0, 1].includes(thumbs.force) ||
console.log('Usage :\nyarn thumbs <mode=1|2|3> [force=0|1] [verbose=0|1]\n') ![0, 1].includes(thumbs.verbose) ||
console.log('mode : 1 = images only, 2 = videos only, 3 = both images and videos') args.includes('--help') ||
console.log('force : 0 = no force (default), 1 = overwrite existing thumbnails') args.includes('-h'))
console.log('verbose: 0 = only print missing thumbs (default), 1 = print all') return console.log(stripIndents(`
return Generate thumbnails.
}
Usage :\nnode ${location} <mode=1|2|3> [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 uploadsDir = path.join(__dirname, '..', 'uploads')
const thumbsDir = path.join(uploadsDir, 'thumbs') const thumbsDir = path.join(uploadsDir, 'thumbs')