Files
what-to-eat/scripts/check-video-links.ts
T

68 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 巡检 packages/data/recipe.csv 中的 B 站视频是否失效,输出 Markdown 报告
*
* pnpm check:videos # 打印报告
* pnpm check:videos --out report.md # 同时写入文件(供 workflow 更新 issue)
*/
import fs from 'node:fs'
import process from 'node:process'
import { setTimeout as sleep } from 'node:timers/promises'
import { bilibiliViewApi, classifyBilibiliCode } from '../packages/cook/src/utils/bilibili'
import { recipeCsvFile } from '../packages/cook/src/utils/config'
import { parseRecipeCsv } from '../packages/cook/src/utils/csv'
const DELAY_MS = 400
async function check(id: string) {
try {
const res = await fetch(bilibiliViewApi(id), {
headers: { 'User-Agent': 'Mozilla/5.0 (cook recipe link checker; +https://github.com/YunYouJun/cook)' },
signal: AbortSignal.timeout(15_000),
})
const body = await res.json() as { code: number, message?: string }
return { status: classifyBilibiliCode(body.code), detail: `${body.code} ${body.message ?? ''}`.trim() }
}
catch (e) {
return { status: 'unknown' as const, detail: (e as Error).message }
}
}
const recipes = parseRecipeCsv(fs.readFileSync(recipeCsvFile, 'utf-8'))
const byVideo = new Map<string, { line: number, name: string }[]>()
recipes.forEach((recipe, i) => {
if (!recipe.bv)
return
const list = byVideo.get(recipe.bv) ?? []
list.push({ line: i + 2, name: recipe.name })
byVideo.set(recipe.bv, list)
})
const dead: string[] = []
let unknown = 0
for (const [id, uses] of byVideo) {
const result = await check(id)
if (result.status === 'dead') {
for (const use of uses)
dead.push(`| ${use.line} | ${use.name} | [${id}](https://www.bilibili.com/video/${id}) | ${result.detail} |`)
}
else if (result.status === 'unknown') {
unknown++
}
await sleep(DELAY_MS)
}
const report = [
`共检查 ${byVideo.size} 个视频,失效 ${dead.length} 条菜谱,无法确认 ${unknown} 个(接口限流或超时,下次巡检会重试)。`,
'',
...(dead.length
? ['| 行 | 菜名 | 视频 | 接口返回 |', '| --- | --- | --- | --- |', ...dead]
: ['没有发现失效视频。']),
'',
`_由 \`pnpm check:videos\` 生成于 ${new Date().toISOString().slice(0, 10)}。替换视频号或删除菜谱后,下一次巡检会自动更新此列表。_`,
].join('\n')
console.log(report)
const outIndex = process.argv.indexOf('--out')
if (outIndex > -1 && process.argv[outIndex + 1])
fs.writeFileSync(process.argv[outIndex + 1]!, report)