aboutsummaryrefslogtreecommitdiff
path: root/scripts/youtube_xml_feed.ts
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-06-30 21:36:32 +0200
committermetamuffin <metamuffin@disroot.org>2025-06-30 21:36:32 +0200
commit34a9a343f602375ee8fe5c240d8a466c7b1ca9dc (patch)
treef6d24014da72badf1569714d75e48b34b6444fc6 /scripts/youtube_xml_feed.ts
parentf1d857b5ab44b35cf049981a2597b9a9610eae94 (diff)
downloadisda-34a9a343f602375ee8fe5c240d8a466c7b1ca9dc.tar
isda-34a9a343f602375ee8fe5c240d8a466c7b1ca9dc.tar.bz2
isda-34a9a343f602375ee8fe5c240d8a466c7b1ca9dc.tar.zst
add youtube xml feed flatten worker
Diffstat (limited to 'scripts/youtube_xml_feed.ts')
-rw-r--r--scripts/youtube_xml_feed.ts58
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" }))
+ }
+}