merge: hotfix into ref/snapshot

This commit is contained in:
alikia2x (寒寒) 2025-03-22 01:48:03 +08:00
commit 9f9ef800d1
Signed by: alikia2x
GPG Key ID: 56209E0CCD8420C6
7 changed files with 60 additions and 51 deletions

View File

@ -3,19 +3,19 @@ import { AllDataType, BiliUserType } from "lib/db/schema.d.ts";
import Akari from "lib/ml/akari.ts"; import Akari from "lib/ml/akari.ts";
export async function videoExistsInAllData(client: Client, aid: number) { export async function videoExistsInAllData(client: Client, aid: number) {
return await client.queryObject<{ exists: boolean }>(`SELECT EXISTS(SELECT 1 FROM all_data WHERE aid = $1)`, [aid]) return await client.queryObject<{ exists: boolean }>(`SELECT EXISTS(SELECT 1 FROM bilibili_metadata WHERE aid = $1)`, [aid])
.then((result) => result.rows[0].exists); .then((result) => result.rows[0].exists);
} }
export async function userExistsInBiliUsers(client: Client, uid: number) { export async function userExistsInBiliUsers(client: Client, uid: number) {
return await client.queryObject<{ exists: boolean }>(`SELECT EXISTS(SELECT 1 FROM bili_user WHERE uid = $1)`, [ return await client.queryObject<{ exists: boolean }>(`SELECT EXISTS(SELECT 1 FROM bilibili_user WHERE uid = $1)`, [
uid, uid,
]); ]);
} }
export async function getUnlabelledVideos(client: Client) { export async function getUnlabelledVideos(client: Client) {
const queryResult = await client.queryObject<{ aid: number }>( const queryResult = await client.queryObject<{ aid: number }>(
`SELECT a.aid FROM all_data a LEFT JOIN labelling_result l ON a.aid = l.aid WHERE l.aid IS NULL`, `SELECT a.aid FROM bilibili_metadata a LEFT JOIN labelling_result l ON a.aid = l.aid WHERE l.aid IS NULL`,
); );
return queryResult.rows.map((row) => row.aid); return queryResult.rows.map((row) => row.aid);
} }
@ -29,14 +29,14 @@ export async function insertVideoLabel(client: Client, aid: number, label: numbe
export async function getVideoInfoFromAllData(client: Client, aid: number) { export async function getVideoInfoFromAllData(client: Client, aid: number) {
const queryResult = await client.queryObject<AllDataType>( const queryResult = await client.queryObject<AllDataType>(
`SELECT * FROM all_data WHERE aid = $1`, `SELECT * FROM bilibili_metadata WHERE aid = $1`,
[aid], [aid],
); );
const row = queryResult.rows[0]; const row = queryResult.rows[0];
let authorInfo = ""; let authorInfo = "";
if (row.uid && await userExistsInBiliUsers(client, row.uid)) { if (row.uid && await userExistsInBiliUsers(client, row.uid)) {
const q = await client.queryObject<BiliUserType>( const q = await client.queryObject<BiliUserType>(
`SELECT * FROM bili_user WHERE uid = $1`, `SELECT * FROM bilibili_user WHERE uid = $1`,
[row.uid], [row.uid],
); );
const userRow = q.rows[0]; const userRow = q.rows[0];
@ -56,8 +56,8 @@ export async function getUnArchivedBiliUsers(client: Client) {
const queryResult = await client.queryObject<{ uid: number }>( const queryResult = await client.queryObject<{ uid: number }>(
` `
SELECT ad.uid SELECT ad.uid
FROM all_data ad FROM bilibili_metadata ad
LEFT JOIN bili_user bu ON ad.uid = bu.uid LEFT JOIN bilibili_user bu ON ad.uid = bu.uid
WHERE bu.uid IS NULL; WHERE bu.uid IS NULL;
`, `,
[], [],

View File

@ -5,41 +5,31 @@ import { parseTimestampFromPsql } from "lib/utils/formatTimestampToPostgre.ts";
export async function getVideosNearMilestone(client: Client) { export async function getVideosNearMilestone(client: Client) {
const queryResult = await client.queryObject<VideoSnapshotType>(` const queryResult = await client.queryObject<VideoSnapshotType>(`
WITH max_views_per_aid AS ( WITH filtered_snapshots AS (
-- aid views aid songs SELECT
SELECT vs.*
vs.aid, FROM
MAX(vs.views) AS max_views
FROM
video_snapshot vs video_snapshot vs
INNER JOIN WHERE
songs s (vs.views >= 90000 AND vs.views < 100000) OR
ON (vs.views >= 900000 AND vs.views < 1000000)
vs.aid = s.aid
GROUP BY
vs.aid
), ),
filtered_max_views AS ( ranked_snapshots AS (
-- views SELECT
SELECT fs.*,
aid, ROW_NUMBER() OVER (PARTITION BY fs.aid ORDER BY fs.created_at DESC) as rn,
max_views MAX(fs.views) OVER (PARTITION BY fs.aid) as max_views_per_aid
FROM FROM
max_views_per_aid filtered_snapshots fs
WHERE INNER JOIN
(max_views >= 90000 AND max_views < 100000) OR songs s ON fs.aid = s.aid
(max_views >= 900000 AND max_views < 1000000) OR
(max_views >= 9900000 AND max_views < 10000000)
) )
-- SELECT
SELECT rs.id, rs.created_at, rs.views, rs.coins, rs.likes, rs.favorites, rs.shares, rs.danmakus, rs.aid, rs.replies
vs.* FROM
FROM ranked_snapshots rs
video_snapshot vs WHERE
INNER JOIN rs.rn = 1;
filtered_max_views fmv
ON
vs.aid = fmv.aid AND vs.views = fmv.max_views
`); `);
return queryResult.rows.map((row) => { return queryResult.rows.map((row) => {
return { return {
@ -72,7 +62,7 @@ export async function getSongSnapshotCount(client: Client, aid: number) {
} }
export async function getShortTermEtaPrediction(client: Client, aid: number) { export async function getShortTermEtaPrediction(client: Client, aid: number) {
const queryResult = await client.queryObject<{eta: number}>( const queryResult = await client.queryObject<{ eta: number }>(
` `
WITH old_snapshot AS ( WITH old_snapshot AS (
SELECT created_at, views SELECT created_at, views
@ -121,6 +111,23 @@ export async function getShortTermEtaPrediction(client: Client, aid: number) {
return queryResult.rows[0].eta; return queryResult.rows[0].eta;
} }
export async function getIntervalFromLastSnapshotToNow(client: Client, aid: number) {
const queryResult = await client.queryObject<{ interval: number }>(
`
SELECT EXTRACT(EPOCH FROM (NOW() - created_at)) AS interval
FROM video_snapshot
WHERE aid = $1
ORDER BY created_at DESC
LIMIT 1;
`,
[aid],
);
if (queryResult.rows.length === 0) {
return null;
}
return queryResult.rows[0].interval;
}
export async function songEligibleForMilestoneSnapshot(client: Client, aid: number) { export async function songEligibleForMilestoneSnapshot(client: Client, aid: number) {
const count = await getSongSnapshotCount(client, aid); const count = await getSongSnapshotCount(client, aid);
if (count < 2) { if (count < 2) {

View File

@ -26,7 +26,7 @@ export const classifyVideoWorker = async (job: Job) => {
await insertVideoLabel(client, aid, label); await insertVideoLabel(client, aid, label);
const exists = await aidExistsInSongs(client, aid); const exists = await aidExistsInSongs(client, aid);
if (!exists) { if (!exists && label !== 0) {
await insertIntoSongs(client, aid); await insertIntoSongs(client, aid);
} }

View File

@ -14,6 +14,8 @@ export const snapshotTickWorker = async (_job: Job) => {
} }
}; };
const log = (a: number, b: number = 10) => Math.log(a) / Math.log(b);
export const closetMilestone = (views: number) => { export const closetMilestone = (views: number) => {
if (views < 100000) return 100000; if (views < 100000) return 100000;
if (views < 1000000) return 1000000; if (views < 1000000) return 1000000;

View File

@ -15,12 +15,11 @@ export async function collectSongs(client: Client) {
export async function insertIntoSongs(client: Client, aid: number) { export async function insertIntoSongs(client: Client, aid: number) {
await client.queryObject( await client.queryObject(
` `
INSERT INTO songs (aid, bvid, published_at, duration) INSERT INTO songs (aid, published_at, duration)
VALUES ( VALUES (
$1, $1,
(SELECT bvid FROM all_data WHERE aid = $1), (SELECT published_at FROM bilibili_metadata WHERE aid = $1),
(SELECT published_at FROM all_data WHERE aid = $1), (SELECT duration FROM bilibili_metadata WHERE aid = $1)
(SELECT duration FROM all_data WHERE aid = $1)
) )
ON CONFLICT DO NOTHING ON CONFLICT DO NOTHING
`, `,

View File

@ -4,6 +4,7 @@ import { formatTimestampToPsql } from "lib/utils/formatTimestampToPostgre.ts";
import logger from "lib/log/logger.ts"; import logger from "lib/log/logger.ts";
import { ClassifyVideoQueue } from "lib/mq/index.ts"; import { ClassifyVideoQueue } from "lib/mq/index.ts";
import { userExistsInBiliUsers, videoExistsInAllData } from "lib/db/allData.ts"; import { userExistsInBiliUsers, videoExistsInAllData } from "lib/db/allData.ts";
import { HOUR, SECOND } from "$std/datetime/constants.ts";
export async function insertVideoInfo(client: Client, aid: number) { export async function insertVideoInfo(client: Client, aid: number) {
const videoExists = await videoExistsInAllData(client, aid); const videoExists = await videoExistsInAllData(client, aid);
@ -18,25 +19,25 @@ export async function insertVideoInfo(client: Client, aid: number) {
const desc = data.View.desc; const desc = data.View.desc;
const uid = data.View.owner.mid; const uid = data.View.owner.mid;
const tags = data.Tags const tags = data.Tags
.filter((tag) => tag.tag_type in ["old_channel", "topic"]) .filter((tag) => !["old_channel", "topic"].indexOf(tag.tag_type))
.map((tag) => tag.tag_name).join(","); .map((tag) => tag.tag_name).join(",");
const title = data.View.title; const title = data.View.title;
const published_at = formatTimestampToPsql(data.View.pubdate); const published_at = formatTimestampToPsql(data.View.pubdate * SECOND + 8 * HOUR);
const duration = data.View.duration; const duration = data.View.duration;
await client.queryObject( await client.queryObject(
`INSERT INTO all_data (aid, bvid, description, uid, tags, title, published_at, duration) `INSERT INTO bilibili_metadata (aid, bvid, description, uid, tags, title, published_at, duration)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
[aid, bvid, desc, uid, tags, title, published_at, duration], [aid, bvid, desc, uid, tags, title, published_at, duration],
); );
const userExists = await userExistsInBiliUsers(client, aid); const userExists = await userExistsInBiliUsers(client, aid);
if (!userExists) { if (!userExists) {
await client.queryObject( await client.queryObject(
`INSERT INTO bili_user (uid, username, "desc", fans) VALUES ($1, $2, $3, $4)`, `INSERT INTO bilibili_user (uid, username, "desc", fans) VALUES ($1, $2, $3, $4)`,
[uid, data.View.owner.name, data.Card.card.sign, data.Card.follower], [uid, data.View.owner.name, data.Card.card.sign, data.Card.follower],
); );
} else { } else {
await client.queryObject( await client.queryObject(
`UPDATE bili_user SET fans = $1 WHERE uid = $2`, `UPDATE bilibili_user SET fans = $1 WHERE uid = $2`,
[data.Card.follower, uid], [data.Card.follower, uid],
); );
} }

View File

@ -3,7 +3,7 @@ export const formatSeconds = (seconds: number) => {
return `${(seconds).toFixed(1)}s`; return `${(seconds).toFixed(1)}s`;
} }
if (seconds < 3600) { if (seconds < 3600) {
return `${Math.floor(seconds / 60)}m${seconds % 60}s`; return `${Math.floor(seconds / 60)}m${(seconds % 60).toFixed(1)}s`;
} }
return `${Math.floor(seconds / 3600)}h ${((seconds % 3600) / 60).toFixed(2)}m`; return `${Math.floor(seconds / 3600)}h ${((seconds % 3600) / 60).toFixed(2)}m`;
}; };