From 896f7615d02f24a5e3fb85d641ad5baf1c210d21 Mon Sep 17 00:00:00 2001 From: alikia2x Date: Sun, 9 Nov 2025 23:41:47 +0800 Subject: [PATCH] update: the handling of bilibili id --- bun.lock | 3 ++ .../elysia/lib/{av_bv.ts => bilibiliID.ts} | 35 ++++++++++++++++ packages/elysia/lib/mq.ts | 6 +++ packages/elysia/package.json | 1 + packages/elysia/routes/song/add.ts | 41 +++++++++++++++++++ packages/elysia/routes/song/info.ts | 2 +- packages/elysia/routes/video/metadata.ts | 2 +- packages/elysia/routes/video/snapshots.ts | 2 +- 8 files changed, 89 insertions(+), 3 deletions(-) rename packages/elysia/lib/{av_bv.ts => bilibiliID.ts} (58%) create mode 100644 packages/elysia/lib/mq.ts create mode 100644 packages/elysia/routes/song/add.ts diff --git a/bun.lock b/bun.lock index 280b910..b0cc5a9 100644 --- a/bun.lock +++ b/bun.lock @@ -90,6 +90,7 @@ "@elysiajs/openapi": "^1.4.11", "@elysiajs/server-timing": "^1.4.0", "@rabbit-company/argon2id": "^2.1.0", + "bullmq": "^5.63.0", "chalk": "^5.6.2", "elysia": "catalog:", "elysia-ip": "^1.0.10", @@ -3132,6 +3133,8 @@ "dot-prop/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], + "elysia-api/bullmq": ["bullmq@5.63.0", "", { "dependencies": { "cron-parser": "^4.9.0", "ioredis": "^5.4.1", "msgpackr": "^1.11.2", "node-abort-controller": "^3.1.1", "semver": "^7.5.4", "tslib": "^2.0.0", "uuid": "^11.1.0" } }, "sha512-HT1iM3Jt4bZeg3Ru/MxrOy2iIItxcl1Pz5Ync1Vrot70jBpVguMxFEiSaDU57BwYwR4iwnObDnzct2lirKkX5A=="], + "elysia-api/zod": ["zod@4.1.12", "", {}, "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ=="], "eslint/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], diff --git a/packages/elysia/lib/av_bv.ts b/packages/elysia/lib/bilibiliID.ts similarity index 58% rename from packages/elysia/lib/av_bv.ts rename to packages/elysia/lib/bilibiliID.ts index 10bcfde..be2e980 100644 --- a/packages/elysia/lib/av_bv.ts +++ b/packages/elysia/lib/bilibiliID.ts @@ -1,3 +1,5 @@ +import z from "zod"; + const XOR_CODE = 23442827791579n; const MASK_CODE = 2251799813685247n; const MAX_AID = 1n << 51n; @@ -27,3 +29,36 @@ export function bv2av(bvid: `BV1${string}`) { const tmp = bvidArr.reduce((pre, bvidChar) => pre * BASE + BigInt(data.indexOf(bvidChar)), 0n); return Number((tmp & MASK_CODE) ^ XOR_CODE); } + +const BV_REGEX = /^BV1[1-9A-HJ-NP-Za-km-z]{9}$/; +const bvSchema = z.string().regex(BV_REGEX); +const AV_REGEX = /^av[0-9]+$/; +const avSchema = z.string().regex(AV_REGEX); + +export function detectBiliID(id: string) { + if (bvSchema.safeParse(id).success) { + return { + type: "bv" as const, + id: id as `BV1${string}` + } + } + else if (avSchema.safeParse(id).success) { + return { + type: "av" as const, + id: id as `av${string}` + } + } + return null; +} + +export function biliIDToAID(id: string) { + const detected = detectBiliID(id); + if (!detected) { + return null; + } + if (detected.type === "bv") { + return bv2av(detected.id); + } else { + return Number.parseInt(detected.id.slice(2)); + } +} \ No newline at end of file diff --git a/packages/elysia/lib/mq.ts b/packages/elysia/lib/mq.ts new file mode 100644 index 0000000..02a495c --- /dev/null +++ b/packages/elysia/lib/mq.ts @@ -0,0 +1,6 @@ +import { Queue, ConnectionOptions } from "bullmq"; +import { redis } from "@core/db/redis"; + +export const LatestVideosQueue = new Queue("latestVideos", { + connection: redis as ConnectionOptions +}); diff --git a/packages/elysia/package.json b/packages/elysia/package.json index a514664..07e0e82 100644 --- a/packages/elysia/package.json +++ b/packages/elysia/package.json @@ -13,6 +13,7 @@ "@elysiajs/openapi": "^1.4.11", "@elysiajs/server-timing": "^1.4.0", "@rabbit-company/argon2id": "^2.1.0", + "bullmq": "^5.63.0", "chalk": "^5.6.2", "elysia": "catalog:", "elysia-ip": "^1.0.10", diff --git a/packages/elysia/routes/song/add.ts b/packages/elysia/routes/song/add.ts new file mode 100644 index 0000000..8ee2f42 --- /dev/null +++ b/packages/elysia/routes/song/add.ts @@ -0,0 +1,41 @@ +import { Elysia, t } from "elysia"; +import { dbMain } from "@core/drizzle"; +import { relations, singer, songs } from "@core/drizzle/main/schema"; +import { eq, and } from "drizzle-orm"; +import { biliIDToAID, bv2av } from "@elysia/lib/bilibiliID"; +import { requireAuth } from "@elysia/middlewares/auth"; +import { LatestVideosQueue } from "@elysia/lib/mq"; + +const addSongHandler = new Elysia() + .use(requireAuth) + .post( + "/song/bilibili", + async ({ params, status, body, user }) => { + const id = body.id; + const aid = biliIDToAID(id); + const job = LatestVideosQueue.add("getVideoInfo", { + aid: aid + }) + return { + message: "Successfully updated song info.", + }; + }, + { + response: { + 200: t.Object({ + message: t.String(), + updated: t.Any() + }), + 401: t.Object({ + message: t.String() + }), + 404: t.Object({ + message: t.String(), + code: t.String() + }) + }, + body: t.Object({ + id: t.String() + }) + } + ); diff --git a/packages/elysia/routes/song/info.ts b/packages/elysia/routes/song/info.ts index 8280edc..79f5519 100644 --- a/packages/elysia/routes/song/info.ts +++ b/packages/elysia/routes/song/info.ts @@ -2,7 +2,7 @@ import { Elysia, t } from "elysia"; import { dbMain } from "@core/drizzle"; import { relations, singer, songs } from "@core/drizzle/main/schema"; import { eq, and } from "drizzle-orm"; -import { bv2av } from "@elysia/lib/av_bv"; +import { bv2av } from "@elysia/lib/bilibiliID"; import { requireAuth } from "@elysia/middlewares/auth"; async function getSongIDFromBiliID(id: string) { diff --git a/packages/elysia/routes/video/metadata.ts b/packages/elysia/routes/video/metadata.ts index 15f830f..3b99a20 100644 --- a/packages/elysia/routes/video/metadata.ts +++ b/packages/elysia/routes/video/metadata.ts @@ -1,7 +1,7 @@ import { Elysia, t } from "elysia"; import { dbMain } from "@core/drizzle"; import { videoSnapshot } from "@core/drizzle/main/schema"; -import { bv2av } from "@elysia/lib/av_bv"; +import { bv2av } from "@elysia/lib/bilibiliID"; import { getVideoInfo } from "@core/net/getVideoInfo"; import { redis } from "@core/db/redis"; import { ErrorResponseSchema } from "@elysia/src/schema"; diff --git a/packages/elysia/routes/video/snapshots.ts b/packages/elysia/routes/video/snapshots.ts index 3b5aa68..22c5f9a 100644 --- a/packages/elysia/routes/video/snapshots.ts +++ b/packages/elysia/routes/video/snapshots.ts @@ -1,7 +1,7 @@ import { Elysia } from "elysia"; import { dbMain } from "@core/drizzle"; import { videoSnapshot } from "@core/drizzle/main/schema"; -import { bv2av } from "@elysia/lib/av_bv"; +import { bv2av } from "@elysia/lib/bilibiliID"; import { ErrorResponseSchema } from "@elysia/src/schema"; import { eq, desc } from "drizzle-orm"; import z from "zod";