mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-12 23:45:18 +00:00
69 lines
2.7 KiB
TypeScript
69 lines
2.7 KiB
TypeScript
import path from "path";
|
|
import isUrl from "is-url";
|
|
import * as fs from "fs"
|
|
import axios from "axios";
|
|
import { Stream } from "stream";
|
|
import { streamToBuffer } from "./streamToBuffer";
|
|
import Jimp from "jimp";
|
|
import du from "du";
|
|
import { cacheDir } from "../conf";
|
|
|
|
|
|
interface ImageDimensions {
|
|
height: number;
|
|
width: number;
|
|
}
|
|
|
|
const fsm = fs.promises;
|
|
|
|
export async function getCachedImageBuffer(name: string, dims?: ImageDimensions): Promise<Buffer> {
|
|
try {
|
|
const MB_5 = 5000000; //5 Megabytes
|
|
const cacheImgFolder = path.join(cacheDir, "images");
|
|
// for clearing up the cache if it reaches out of the size
|
|
const cacheName = `${isUrl(name) ? name.split("/").slice(-1)[0] : name}.cnim`;
|
|
const cachePath = path.join(cacheImgFolder, cacheName);
|
|
// checking if the cached image already exists or not
|
|
if (fs.existsSync(cachePath)) {
|
|
// automatically removing cache after a certain 50 MB oversize
|
|
if ((await du(cacheImgFolder)) > MB_5) {
|
|
fs.rmSync(cacheImgFolder, { recursive: true, force: true });
|
|
}
|
|
const cachedImg = await fsm.readFile(cachePath);
|
|
const cachedImgMeta = (await Jimp.read(cachedImg)).bitmap;
|
|
|
|
// if the dimensions are changed then the previously cached
|
|
// images are removed and replaced with a new one
|
|
if (dims && (cachedImgMeta.height !== dims.height || cachedImgMeta.width !== dims?.width)) {
|
|
fs.rmSync(cachePath);
|
|
return await imageResizeAndWrite(cachedImg, { cacheFolder: cacheImgFolder, cacheName, dims });
|
|
}
|
|
return cachedImg;
|
|
} else {
|
|
// finding no cache image fetching it through axios
|
|
const { data: imgData } = await axios.get<Stream>(name, { responseType: "stream" });
|
|
// converting axios stream to buffer
|
|
const resImgBuf = await streamToBuffer(imgData);
|
|
// creating cache_dir
|
|
await fsm.mkdir(cacheImgFolder, { recursive: true });
|
|
if (dims) {
|
|
return await imageResizeAndWrite(resImgBuf, { cacheFolder: cacheImgFolder, cacheName, dims });
|
|
}
|
|
await fsm.writeFile(path.join(cacheImgFolder, cacheName), resImgBuf);
|
|
return resImgBuf;
|
|
}
|
|
} catch (error) {
|
|
console.error("[Error in Image Cache]: ", error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
async function imageResizeAndWrite(img: Buffer, { cacheFolder, cacheName, dims }: { dims: ImageDimensions; cacheFolder: string; cacheName: string }): Promise<Buffer> {
|
|
// caching the images by resizing if the max/fixed (Width/Height)
|
|
// is available in the args
|
|
const resizedImg = (await Jimp.read(img)).resize(dims.width, dims.height)
|
|
const resizedImgBuffer = await resizedImg.getBufferAsync(resizedImg._originalMime);
|
|
await fsm.writeFile(path.join(cacheFolder, cacheName), resizedImgBuffer);
|
|
return resizedImgBuffer;
|
|
}
|