1 | import * as wmill from "https://deno.land/x/windmill@v1.85.0/mod.ts"; |
2 | import { parse } from "https://deno.land/x/xml/mod.ts"; |
3 |
|
4 | type Rss = { |
5 | url: string; |
6 | }; |
7 | export async function main(rss_feed: Rss) { |
8 | const rss_feed_url = rss_feed.url; |
9 | let feedStates = (await wmill.getInternalState()) || {}; |
10 | const newestItem: Date = new Date(feedStates[rss_feed_url] || 0); |
11 |
|
12 | const items = await fetch(rss_feed_url) |
13 | .then((response) => response.text()) |
14 | .then((str) => parse(str)) |
15 | .then((feed) => { |
16 | let items = []; |
17 | if (feed["rss"]) { |
18 | items = rss2_items(feed); |
19 | } else if (feed["feed"]) { |
20 | items = atom_items(feed); |
21 | } |
22 | const new_items = items.filter((item) => item.pubDate > newestItem); |
23 | return new_items; |
24 | }); |
25 |
|
26 | if (items.length > 0) { |
27 | let newState = (await wmill.getInternalState()) || {}; |
28 | const dates = items.map((item) => item.pubDate); |
29 | newState[rss_feed_url] = new Date(Math.max(...dates)); |
30 | await wmill.setInternalState(newState); |
31 | } |
32 |
|
33 | return items.reverse(); |
34 | } |
35 |
|
36 | function rss2_items(feed) { |
37 | var items = feed["rss"]["channel"]["item"] || []; |
38 | if (items.length === "undefined") { |
39 | |
40 | items = [items]; |
41 | } |
42 | return items.map((item) => ({ |
43 | title: item.title, |
44 | link: item.link, |
45 | pubDate: new Date(item.pubDate), |
46 | })); |
47 | } |
48 |
|
49 | function atom_items(feed) { |
50 | var items = feed["feed"]["entry"] || []; |
51 | if (items.length === "undefined") { |
52 | |
53 | items = [items]; |
54 | } |
55 | return items.map((item) => ({ |
56 | title: typeof item.title === "string" ? item.title : item.title["#text"], |
57 | link: |
58 | item.link instanceof Array ? item.link[0]["@href"] : item.link["@href"], |
59 | pubDate: new Date(item.updated), |
60 | })); |
61 | } |
62 |
|