1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
#!/usr/bin/env python3
from datetime import datetime
from typing import List
def _format_date(dt):
"""convert a datetime into an RFC 822 formatted date
Input date must be in GMT.
Stolen from PyRSS2Gen.
"""
# Looks like:
# Sat, 07 Sep 2002 00:00:01 GMT
# Can't use strftime because that's locale dependent
#
# Isn't there a standard way to do this for Python? The
# rfc822 and email.Utils modules assume a timestamp. The
# following is based on the rfc822 module.
weekdays = [
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun",
]
months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
]
return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (
weekdays[dt.weekday()],
dt.day,
months[dt.month - 1],
dt.year,
dt.hour,
dt.minute,
dt.second,
)
class RSSItem:
title: str
url: str
content: str
date: str
enclosures: List[str]
guid: str
class RSSFeed:
title: str
url: str
description: str
content: List[RSSItem]
def escape(str):
str = str.replace("&", "&")
return str
def buildRSS(feed_data: RSSFeed):
"""
feed_data = {
title, url, description,
content = [{
title, url, content, date, [enclosures], guid
}]
}
"""
feed = f"""<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
<channel>
<title>{feed_data['title']}</title>
<link>{feed_data['url']}</link>
<description>{escape(feed_data['description'])}</description>
<lastBuildDate>{_format_date(datetime.now())}</lastBuildDate>"""
for item in feed_data["content"]:
feed += " <item>"
feed += f" <title><![CDATA[{item.get('title', 'N/A')}]]></title>"
feed += f" <link>{item.get('url', 'N/A')}</link>"
feed += (
f" <description><![CDATA[{item.get('content', 'N/A')}]]></description>"
)
if "date" in item:
if type(item["date"]) is str:
feed += f" <pubDate>{item['date']}</pubDate>"
else:
feed += f" <pubDate>{_format_date(item['date'])}</pubDate>"
for enclosure in item.get("enclosures", []):
feed += f' <media:content url="{enclosure}" />'
if "guid" in item:
feed += f" <guid>{item['guid']}</guid>"
feed += " </item>"
feed += " </channel>"
feed += "</rss>"
return feed
|