diff options
author | metamuffin <metamuffin@disroot.org> | 2025-06-30 21:36:32 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-06-30 21:36:32 +0200 |
commit | 34a9a343f602375ee8fe5c240d8a466c7b1ca9dc (patch) | |
tree | f6d24014da72badf1569714d75e48b34b6444fc6 | |
parent | f1d857b5ab44b35cf049981a2597b9a9610eae94 (diff) | |
download | isda-34a9a343f602375ee8fe5c240d8a466c7b1ca9dc.tar isda-34a9a343f602375ee8fe5c240d8a466c7b1ca9dc.tar.bz2 isda-34a9a343f602375ee8fe5c240d8a466c7b1ca9dc.tar.zst |
add youtube xml feed flatten worker
-rw-r--r-- | scripts/youtube_xml_feed.ts | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/scripts/youtube_xml_feed.ts b/scripts/youtube_xml_feed.ts new file mode 100644 index 0000000..5d21542 --- /dev/null +++ b/scripts/youtube_xml_feed.ts @@ -0,0 +1,58 @@ +import { Config } from "./config.ts"; + +const ws = new WebSocket(Deno.args[0]) +// deno-lint-ignore no-unused-vars +let config: Config = {} as unknown as Config + +async function flat_feed(cid: string, data: { [key: string]: unknown }) { + const feedurl = `https://www.youtube.com/feeds/videos.xml?channel_id=${cid}` + console.log(`load feed ${feedurl}`); + const res = await fetch(feedurl) + if (!res.ok) throw new Error("feed download error:" + await res.text()); + const feed = await res.text() + + for (const entry of feed.split("<entry>")) { + const id_match = entry.match(/\<yt:videoId\>([0-9A-Za-z-_]{11})\<\/yt:videoId\>/) + const title_match = entry.match(/\<title\>([^\<]*)\<\/title\>/) + const uploader_match = entry.match(/\<name\>([^\<]*)\<\/name\>/) + if (!id_match || !title_match || !uploader_match) continue + const id = id_match[1] + const title = title_match[1] + const uploader = uploader_match[1] + const key = `youtube:${id}`; + ws.send(JSON.stringify({ + t: "metadata", + key, + data: { + ...data, + title: title, + subtitle: `by ${uploader}`, + } + })) + ws.send(JSON.stringify({ t: "enqueue", key })) + } + console.log("done"); +} + +ws.onerror = () => console.error("ws error") +ws.onclose = () => { + console.error("ws closed") + Deno.exit(1) +} +ws.onopen = () => { + console.log("ws open"); + ws.send(JSON.stringify({ t: "register", name: "YouTube XML feed flattener", task_kinds: ["youtube-channel-xmlfeed"] })) + ws.send(JSON.stringify({ t: "accept" })) +} +ws.onmessage = async ev => { + if (typeof ev.data != "string") return + const p = JSON.parse(ev.data) + if (p.t == "config") config = p.config + if (p.t == "error") console.error(`error: ${p.message}`); + if (p.t == "work") { + await flat_feed(p.key.replace("youtube-channel-xmlfeed:", ""), p.data) + ws.send(JSON.stringify({ t: "complete", key: p.key })) + ws.send(JSON.stringify({ t: "save" })) + ws.send(JSON.stringify({ t: "accept" })) + } +} |