58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import fs from "node:fs";
|
|
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
import path from "node:path";
|
|
import type { Connect, Plugin, ViteDevServer } from "vite";
|
|
|
|
export function mp3DownloaderPlugin(): Plugin {
|
|
return {
|
|
name: "mp3-downloader",
|
|
configureServer(server: ViteDevServer) {
|
|
// Vite dev server middlewares are connect-style: (req, res, next)
|
|
server.middlewares.use(async (req, res, next) => {
|
|
const reqUrl = req.url;
|
|
if (!reqUrl || !reqUrl.startsWith("/uploads/")) return next();
|
|
if (!reqUrl.endsWith(".mp3")) return next();
|
|
|
|
try {
|
|
await mp3Downloader(req, res, next);
|
|
} catch (e) {
|
|
console.error(e, reqUrl);
|
|
next();
|
|
}
|
|
});
|
|
},
|
|
};
|
|
}
|
|
|
|
async function mp3Downloader(
|
|
req: Connect.IncomingMessage,
|
|
res: ServerResponse<IncomingMessage>,
|
|
next: Connect.NextFunction,
|
|
) {
|
|
const url = new URL(`https://www.howtostudykorean.com/wp-content${req.url}`);
|
|
|
|
const segs = req.url!.slice(1).split("/");
|
|
const filename = segs.pop()!;
|
|
const saveroot = "docs/public";
|
|
const saveto = path.join(saveroot, ...segs, filename);
|
|
|
|
if (fs.existsSync(saveto)) {
|
|
return next();
|
|
}
|
|
|
|
fs.mkdirSync(path.join(saveroot, ...segs), { recursive: true });
|
|
|
|
const r = await fetch(url, { redirect: "follow" });
|
|
if (!r.ok) {
|
|
console.error(r);
|
|
return next();
|
|
}
|
|
|
|
fs.writeFileSync(saveto, Buffer.from(await r.arrayBuffer()));
|
|
// console.log(fs.statSync(saveto));
|
|
console.log("saved to", saveto);
|
|
|
|
res.setHeader("Content-Type", "audio/mpeg");
|
|
fs.createReadStream(saveto).pipe(res);
|
|
}
|