48 lines
1.6 KiB
Python
48 lines
1.6 KiB
Python
# openai_rss_reader_stdlib.py
|
|
# pip install feedparser
|
|
|
|
import feedparser
|
|
from email.utils import parsedate_to_datetime
|
|
|
|
FEEDS = [
|
|
"https://platform.openai.com/docs/release-notes.rss", # リリースノート
|
|
"https://openai.com/blog/rss.xml", # ブログ
|
|
]
|
|
|
|
def to_ts(entry: feedparser.FeedParserDict):
|
|
# published_parsed / updated_parsed があれば直接datetime化
|
|
if entry.get("published_parsed"):
|
|
return parsedate_to_datetime(entry.published)
|
|
if entry.get("updated_parsed"):
|
|
return parsedate_to_datetime(entry.updated)
|
|
return None
|
|
|
|
def uniq_key(entry: feedparser.FeedParserDict):
|
|
return entry.get("id") or entry.get("guid") or entry.get("link")
|
|
|
|
def fetch_all(feeds):
|
|
items = []
|
|
seen = set()
|
|
for url in feeds:
|
|
d: feedparser.FeedParserDict = feedparser.parse(url)
|
|
for e in d.entries:
|
|
k = uniq_key(e)
|
|
if not k or k in seen:
|
|
continue
|
|
seen.add(k)
|
|
ts = to_ts(e)
|
|
items.append({
|
|
"title": e.get("title", "(no title)"),
|
|
"link": e.get("link"),
|
|
"published": e.get("published") or e.get("updated"),
|
|
"ts": ts,
|
|
"source": url,
|
|
})
|
|
# ts が None のものは末尾に回す
|
|
items.sort(key=lambda x: (x["ts"] is not None, x["ts"]), reverse=True)
|
|
return items
|
|
|
|
if __name__ == "__main__":
|
|
for i, it in enumerate(fetch_all(FEEDS), 1):
|
|
print(f"{i:02d}. {it['title']}\n {it['link']}\n {it['published']} [{it['source']}]\n")
|