chore: blog post publish cleanup (#7873)

This commit is contained in:
Joshua Chen 2022-08-01 18:00:01 +08:00 committed by GitHub
parent e8a11da805
commit 1a62b41e31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 110 deletions

View file

@ -8,46 +8,95 @@
import fs from 'fs-extra';
import path from 'path';
import {fileURLToPath} from 'url';
import {program} from 'commander';
import logger from '@docusaurus/logger';
import sharp from 'sharp';
import imageSize from 'image-size';
const allImages = (
await fs.readdir(new URL('../../website/src/data/showcase', import.meta.url))
).filter((file) => ['.png', 'jpg', '.jpeg'].includes(path.extname(file)));
// You can use it as:
//
// # Resize all images in showcase (which is most likely)
// node admin/scripts/resizeImage.js
//
// # Resize specified images / all images in a folder
// # This does not read folders recursively as of now
// node admin/scripts/resizeImage.js image1.png some-folder ...
//
// By default, showcase images are resized to 640×320; everything else is
// resized to width 1000. You can explicitly give a width/height as arguments.
// node admin/scripts/resizeImage.js --width 640 --height 320 image1.png
const [, , ...selectedImages] = process.argv;
const images = selectedImages.length > 0 ? selectedImages : allImages;
function maybeParseInt(n) {
const res = Number.parseInt(n, 10);
if (Number.isNaN(res)) {
return undefined;
}
return res;
}
const stats = {
skipped: 0,
resized: 0,
};
const showcasePath = 'website/src/data/showcase';
await Promise.all(
images.map(async (img) => {
const imgPath = fileURLToPath(
new URL(`../../website/src/data/showcase/${img}`, import.meta.url),
);
const {width, height} = imageSize(imgPath);
if (width === 640 && height === 320 && imgPath.endsWith('.png')) {
// Do not emit if not resized. Important because we can't guarantee
// idempotency during resize -> optimization
stats.skipped += 1;
return;
program
.arguments('[imagePaths...]')
.option('-w, --width <width>', 'Image width', maybeParseInt)
.option('-h, --height <height>', 'Image height', maybeParseInt)
.action(async (imagePaths, options) => {
if (imagePaths.length === 0) {
imagePaths.push(showcasePath);
}
logger.info`Resized path=${imgPath}: Before number=${width}×number=${height}`;
const data = await sharp(imgPath)
.resize(640, 320, {fit: 'cover', position: 'top'})
.png()
.toBuffer();
await fs.writeFile(imgPath.replace(/jpe?g/, 'png'), data);
stats.resized += 1;
}),
);
const rootDir = fileURLToPath(new URL('../..', import.meta.url));
const images = (
await Promise.all(
imagePaths.map(async (p) =>
path.extname(p)
? [path.resolve(rootDir, p)]
: (await fs.readdir(p)).map((f) => path.resolve(rootDir, p, f)),
),
)
)
.flat()
.filter((p) => ['.png', 'jpg', '.jpeg'].includes(path.extname(p)));
console.log(`Showcase images resizing complete.
${JSON.stringify(stats, null, 2)}`);
const stats = {
skipped: 0,
resized: 0,
};
await Promise.all(
images.map(async (imgPath) => {
const {width, height} = imageSize(imgPath);
const targetWidth =
options.width ?? (imgPath.includes(showcasePath) ? 640 : 1000);
const targetHeight =
options.height ?? (imgPath.includes(showcasePath) ? 320 : undefined);
if (
width <= targetWidth &&
(!targetHeight || height <= targetHeight) &&
imgPath.endsWith('.png')
) {
// Do not emit if not resized. Important because we can't guarantee
// idempotency during resize -> optimization
stats.skipped += 1;
return;
}
logger.info`Resized path=${imgPath}: before number=${width}×number=${height}; now number=${targetWidth}×number=${
targetHeight ?? Math.floor((height / width) * targetWidth)
}`;
const data = await sharp(imgPath)
.resize(targetWidth, targetHeight, {fit: 'cover', position: 'top'})
.png()
.toBuffer();
await fs.writeFile(imgPath.replace(/jpe?g/, 'png'), data);
stats.resized += 1;
}),
);
logger.info`Images resizing complete.
resized: number=${stats.resized}
skipped: number=${stats.skipped}`;
});
program.parse(process.argv);
// You should also run
// optimizt `find website/src/data/showcase -type f -name '*.png'`.

View file

@ -1,53 +0,0 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import fs from 'fs-extra';
import path from 'path';
import logger from '@docusaurus/logger';
import sharp from 'sharp';
import imageSize from 'image-size';
import globby from 'globby';
// TODO duplicate temporary script: factorize!
const imgDir = 'website/blog/2022-08-01-announcing-docusaurus-2.0/img';
const imgWidth = 1200;
const allImages = (await globby(`${imgDir}/**`)).filter((file) =>
['.png', 'jpg', '.jpeg'].includes(path.extname(file)),
);
const [, , ...selectedImages] = process.argv;
const images = selectedImages.length > 0 ? selectedImages : allImages;
const stats = {
skipped: 0,
resized: 0,
};
await Promise.all(
images.map(async (imgPath) => {
const {width, height} = imageSize(imgPath);
if (width === imgWidth && imgPath.endsWith('.png')) {
// Do not emit if not resized. Important because we can't guarantee
// idempotency during resize -> optimization
stats.skipped += 1;
return;
}
logger.info`Resized path=${imgPath}: Before number=${width}×number=${height}`;
const data = await sharp(imgPath)
.resize(imgWidth)
.png({quality: 100})
.toBuffer();
await fs.writeFile(imgPath.replace(/jpe?g/, 'png'), data);
stats.resized += 1;
}),
);
console.log(`Blog images resizing complete.
${JSON.stringify(stats, null, 2)}`);

View file

@ -1,6 +1,7 @@
abernathyca
adriaan
agan
alexbdebrie
alexey
algoliasearch
anonymized
@ -50,9 +51,12 @@ contravariance
corejs
crawlable
creativecommons
csapo
cssnano
csvg
customizability
dabit
dabit
daishi
datagit
datas
@ -63,6 +67,7 @@ deduplicated
déja
deps
devcontainers
devs
devspace
devto
dmitry
@ -100,6 +105,7 @@ formik
fouc
froms
funboxteam
gabrielcsapo
getopts
gitpod
globbing
@ -109,7 +115,10 @@ goyal
gruntfuggly
gtag
hahaha
hamel
hardcoding
hasura
heavener
héctor
héllô
heuristical
@ -118,6 +127,7 @@ hola
horiz
hostman
hoverable
husain
ianad
idempotency
immer
@ -126,11 +136,13 @@ inlines
intelli
interactiveness
interpolatable
investec
jakepartusch
jamstack
janvier
javadoc
jmarcey
jodyheavener
joshcena
jscodeshift
jssdk
@ -157,6 +169,7 @@ marcey
marocchino
massoud
mathjax
maxlynch
maxresdefault
mdast
mdxa
@ -195,7 +208,7 @@ npmrc
nprogress
ntfs
nuxt
OShannessy
oshannessy
onboarded
openapi
opensearch
@ -204,6 +217,7 @@ opensource
optimizt
optind
orta
outerbounds
overrideable
pageview
palenight
@ -212,6 +226,7 @@ palo
paraiso
pathinfo
pathnames
paularmstrong
pbcopy
pcss
peaceiris
@ -222,6 +237,7 @@ picomatch
playbtn
pluggable
plushie
plushies
pnpm
posthog
preactjs
@ -250,6 +266,7 @@ qovery
quasis
quddus
quddús
quickwit
quotify
rachelnabors
ramón
@ -281,6 +298,8 @@ sensical
serializers
setaf
setext
shiki
shiki
showinfo
sida
simen
@ -288,11 +307,14 @@ slorber
sluggified
sluggifies
sluggify
solana
solana
spâce
stackblitz
stackblitzrc
strikethrough
strikethroughs
styl
stylelint
stylelintrc
subdir
@ -310,11 +332,11 @@ subsubsubfolder
sucipto
supabase
svgr
styl
swizzlable
teik
templating
thanos
therox
toolset
toplevel
transifex
@ -325,6 +347,7 @@ treeify
treosh
triaging
tses
twoslash
typecheck
typechecks
typedoc
@ -348,6 +371,7 @@ vetter
vfile
vicenti
vieira
viet
viewports
vinnik
vjeux
@ -367,27 +391,3 @@ yangshunz
zhou
zoomable
zpao
paularmstrong
devs
Viet
dabit
Dabit
alexbdebrie
Investec
Quickwit
Hamel
Husain
Outerbounds
jodyheavener
Heavener
maxlynch
gabrielcsapo
Csapo
Hasura
Solana
solana
shiki
twoslash
Shiki
Therox
plushies