feat: compress EVERYTHING!
This commit is contained in:
106
bin/compress_s3.js
Normal file
106
bin/compress_s3.js
Normal file
@ -0,0 +1,106 @@
|
||||
import { Client } from "minio";
|
||||
import sharp from "sharp"
|
||||
import {config} from "dotenv"
|
||||
config()
|
||||
|
||||
// Retrieve MinIO details from environment variables
|
||||
const minioEndpoint = process.env["S3_ENDPOINT_URL"] || "your-minio-endpoint";
|
||||
const minioAccessKey = process.env["S3_ACCESS_KEY"] || "your-access-key";
|
||||
const minioSecretKey = process.env["S3_SECRET_ACCESS_KEY"] || "your-secret-key";
|
||||
const minioBucketName = "silvester23";
|
||||
|
||||
const minioClient = new Client({
|
||||
endPoint: minioEndpoint,
|
||||
accessKey: minioAccessKey,
|
||||
secretKey: minioSecretKey,
|
||||
});
|
||||
|
||||
|
||||
const objects = [];
|
||||
|
||||
const objectStream = minioClient.listObjects(minioBucketName);
|
||||
|
||||
for await (const obj of objectStream) {
|
||||
objects.push(obj);
|
||||
}
|
||||
|
||||
async function compressObject(pngBuffer, fileName, format) {
|
||||
|
||||
const newFilePath = `${fileName.slice(0, -4)}.${format}`;
|
||||
|
||||
let buffer;
|
||||
switch (format) {
|
||||
case "webp":
|
||||
buffer = await sharp(pngBuffer).webp({ quality: 80 }).toBuffer();
|
||||
break;
|
||||
case "jpg":
|
||||
buffer = await sharp(pngBuffer).jpeg({ quality: 80 }).toBuffer();
|
||||
break;
|
||||
case "avif":
|
||||
buffer = await sharp(pngBuffer).avif({ quality: 80 }).toBuffer();
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown format ${format}`);
|
||||
}
|
||||
|
||||
// Upload the JPG buffer back to the same MinIO bucket
|
||||
await minioClient.putObject(minioBucketName, newFilePath, buffer, {
|
||||
'Content-Type': 'image/' + format,
|
||||
});
|
||||
|
||||
console.log(`Uploaded ${newFilePath} to MinIO`);
|
||||
}
|
||||
|
||||
async function fetchBuffer(objectName) {
|
||||
const chunks = [];
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
minioClient.getObject(minioBucketName,objectName, function (err, dataStream) {
|
||||
if (err) {
|
||||
return console.log(err)
|
||||
}
|
||||
dataStream.on('data', function (chunk) {
|
||||
chunks.push(chunk);
|
||||
})
|
||||
dataStream.on('end', function () {
|
||||
res(Buffer.concat(chunks))
|
||||
})
|
||||
dataStream.on('error', function (err) {
|
||||
console.log(err)
|
||||
rej(err)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const pngs = objects.filter((o) => o.name.endsWith(".png"));
|
||||
console.log(`Found ${pngs.length} PNGs`);
|
||||
|
||||
for (const obj of pngs) {
|
||||
const pngFilePath = obj.name;
|
||||
const jpgFilePath = pngFilePath.slice(0, -4) + ".jpg";
|
||||
const avifFilePath = pngFilePath.slice(0, -4) + ".avif";
|
||||
const webpFilePath = pngFilePath.slice(0, -4) + ".webp";
|
||||
|
||||
const hasJpg = objects.some((o) => o.name === jpgFilePath);
|
||||
const hasAvif = objects.some((o) => o.name === avifFilePath);
|
||||
const hasWebp = objects.some((o) => o.name === webpFilePath);
|
||||
|
||||
if(hasAvif && hasJpg && hasWebp) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const pngBuffer = await fetchBuffer(pngFilePath);
|
||||
|
||||
if(!hasJpg) {
|
||||
await compressObject(pngBuffer, pngFilePath, "jpg");
|
||||
}
|
||||
|
||||
if(!hasAvif) {
|
||||
await compressObject(pngBuffer, pngFilePath, "avif");
|
||||
}
|
||||
if(!hasWebp) {
|
||||
await compressObject(pngBuffer, pngFilePath, "webp");
|
||||
}
|
||||
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
import { Client } from "npm:minio";
|
||||
import Jimp from 'npm:jimp';
|
||||
import { config } from "https://deno.land/x/dotenv/mod.ts";
|
||||
config({ export: true });
|
||||
|
||||
interface MinioObject {
|
||||
name: string;
|
||||
}
|
||||
|
||||
// Retrieve MinIO details from environment variables
|
||||
const minioEndpoint = Deno.env.get("S3_ENDPOINT_URL") || "your-minio-endpoint";
|
||||
const minioAccessKey = Deno.env.get("S3_ACCESS_KEY") || "your-access-key";
|
||||
const minioSecretKey = Deno.env.get("S3_SECRET_ACCESS_KEY") || "your-secret-key";
|
||||
const minioBucketName = "silvester23";
|
||||
|
||||
const minioClient = new Client({
|
||||
endPoint: minioEndpoint,
|
||||
accessKey: minioAccessKey,
|
||||
secretKey: minioSecretKey,
|
||||
});
|
||||
|
||||
|
||||
const objects: MinioObject[] = [];
|
||||
|
||||
const objectStream = minioClient.listObjects(minioBucketName);
|
||||
|
||||
for await (const obj of objectStream) {
|
||||
objects.push({
|
||||
name: obj.name,
|
||||
});
|
||||
}
|
||||
|
||||
// Process and upload images
|
||||
for (const obj of objects) {
|
||||
const pngFilePath = obj.name;
|
||||
const jpgFilePath = `${pngFilePath.slice(0, -4)}.jpg`;
|
||||
|
||||
// Check if the PNG file exists and there is no corresponding JPG file
|
||||
if (!objects.some((o) => o.name === jpgFilePath)) {
|
||||
// Download the PNG file from MinIO
|
||||
const pngBuffer = await minioClient.getObject(minioBucketName, pngFilePath);
|
||||
console.log(`Downloaded ${pngFilePath} from MinIO`);
|
||||
|
||||
// Use Jimp to compress and convert the PNG to JPG
|
||||
const image = await Jimp.read(`http://s3-api.app.max-richter.dev/silvester23/${pngFilePath}`);
|
||||
const jpgBuffer = await image.quality(80).getBufferAsync(Jimp.MIME_JPEG);
|
||||
|
||||
// Upload the JPG buffer back to the same MinIO bucket
|
||||
await minioClient.putObject(minioBucketName, jpgFilePath, jpgBuffer, {
|
||||
'Content-Type': 'image/jpeg',
|
||||
});
|
||||
|
||||
console.log(`Uploaded ${jpgFilePath} to MinIO`);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user