aboutsummaryrefslogtreecommitdiff
path: root/scripts/youtube_atom_compare.ts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/youtube_atom_compare.ts')
-rw-r--r--scripts/youtube_atom_compare.ts61
1 files changed, 61 insertions, 0 deletions
diff --git a/scripts/youtube_atom_compare.ts b/scripts/youtube_atom_compare.ts
new file mode 100644
index 0000000..353be14
--- /dev/null
+++ b/scripts/youtube_atom_compare.ts
@@ -0,0 +1,61 @@
+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()
+
+ let last_seen_ids = ""
+ for (const entry of feed.split("<entry>")) {
+ const id_match = entry.match(/\<yt:videoId\>([0-9A-Za-z-_]{11})\<\/yt:videoId\>/)
+ if (!id_match) continue
+ last_seen_ids += id_match[1] + "|"
+ }
+
+ if (data.last_seen_ids && data.last_seen_ids == last_seen_ids) {
+ console.log("feed identical");
+ return
+ } else {
+ console.log("feed changed");
+ ws.send(JSON.stringify({
+ t: "metadata",
+ key: `youtube-channel-atom-compare:${cid}`,
+ data: { last_seen_ids }
+ }))
+ ws.send(JSON.stringify({
+ t: "metadata",
+ key: `youtube-channel:${cid}`,
+ data: { ...data, last_seen_ids: undefined }
+ }))
+ ws.send(JSON.stringify({ t: "enqueue", key: `youtube-channel:${cid}`, ignore_complete: true }))
+ }
+ 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 Atom feed checker", task_kinds: ["youtube-channel-atom-compare"] }))
+ 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-atom-compare:", ""), p.data)
+ ws.send(JSON.stringify({ t: "complete", key: p.key }))
+ ws.send(JSON.stringify({ t: "accept" }))
+ }
+}