feat: add id3 tags storage

This commit is contained in:
2024-03-26 06:20:11 +07:00
parent 4f6b140c28
commit 1160b30c3d
6 changed files with 365 additions and 23 deletions
+58 -23
View File
@@ -1,8 +1,27 @@
import type { Context } from "hono";
import { getFilePath } from "./utils";
import { HTTPException } from "hono/http-exception";
import ID3 from "node-id3";
import cache from "../../middlewares/cache";
import { loadDb } from "../../lib/db";
const db = loadDb("id3-tags", (db) => {
db.exec(`CREATE TABLE IF NOT EXISTS tags (
id INTEGER PRIMARY KEY AUTOINCREMENT,
path TEXT NOT NULL,
data TEXT NOT NULL,
image BLOB,
UNIQUE(path)
)`);
});
type ID3Tag = {
id: number;
path: string;
data: string;
image: any;
};
export const getId3Tags = async (c: Context) => {
const url = new URL(c.req.url);
@@ -10,7 +29,7 @@ export const getId3Tags = async (c: Context) => {
const uri = pathname.slice(pathname.indexOf("id3-tags") + 1).join("/");
const { path } = getFilePath("/" + uri);
const cached = cache.key("id3-tags", path);
const cached = cache.key("id3-tags", uri);
if (cached.data != null) {
return c.json(cached.data || {});
}
@@ -18,19 +37,35 @@ export const getId3Tags = async (c: Context) => {
let tags: any = false;
try {
const id3Tags = await ID3.Promise.read(path, { noRaw: true });
const data: any = { ...id3Tags };
const tagsRow = db
.prepare("SELECT * FROM tags WHERE path = ?")
.get(uri) as ID3Tag;
if (data.image) {
const imgUrl = new URL(url);
imgUrl.pathname = imgUrl.pathname.replace("/id3-tags", "/id3-img");
data.image = imgUrl.toString();
if (tagsRow) {
const data = JSON.parse(tagsRow.data);
tags = { ...data, image: tagsRow.image };
} else {
const id3Tags = await ID3.Promise.read(path, { noRaw: true });
const image = (id3Tags.image as any)?.imageBuffer || null;
tags = { ...id3Tags };
db.prepare("INSERT INTO tags (path, data, image) VALUES (?, ?, ?)").run(
uri,
JSON.stringify({ ...id3Tags, image: undefined }),
image
);
}
tags = data;
} catch (err) {}
cached.set(tags);
if (tags.image) {
const imgUrl = new URL(url);
imgUrl.pathname = imgUrl.pathname.replace("/id3-tags", "/id3-img");
tags.image = imgUrl.toString();
}
} catch (err) {
//
} finally {
cached.set(tags);
}
return c.json(tags || {});
};
@@ -39,25 +74,25 @@ export const getId3Image = async (c: Context) => {
const url = new URL(c.req.url);
const pathname = decodeURI(url.pathname).split("/");
const uri = pathname.slice(pathname.indexOf("id3-img") + 1).join("/");
const { path } = getFilePath("/" + uri);
const cached = cache.key("id3-img", path);
const cached = cache.key("id3-img", uri);
if (cached.data) {
c.header("Content-Type", cached.data.mime);
const buffer = Buffer.from(cached.data.imageBuffer);
return c.body(buffer);
c.header("Content-Type", "image/jpeg");
return c.body(Buffer.from(cached.data));
}
try {
const tags = await ID3.Promise.read(path, { noRaw: true });
const image = tags.image;
if (!image || typeof image === "string") {
throw new Error("No image found!");
const tagsRow = db
.prepare("SELECT * FROM tags WHERE path = ?")
.get(uri) as ID3Tag;
if (!tagsRow || !tagsRow.image) {
throw new Error("Not found!");
}
cached.set(image);
c.header("Content-Type", image.mime);
return c.body(image.imageBuffer);
cached.set(tagsRow.image);
c.header("Content-Type", "image/jpeg");
return c.body(tagsRow.image);
} catch (err) {
throw new HTTPException(400, { message: "cannot get tags!" });
}