aboutsummaryrefslogtreecommitdiff
path: root/rss/rss_feed.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rss/rss_feed.py57
1 files changed, 57 insertions, 0 deletions
diff --git a/rss/rss_feed.py b/rss/rss_feed.py
new file mode 100644
index 00000000..5ed6226d
--- /dev/null
+++ b/rss/rss_feed.py
@@ -0,0 +1,57 @@
+#!/usr/bin/env python3
+
+import lxml.etree as ET
+
+class RssFeed(object):
+ """Class for storing an RSS 2.0 feed.
+
+ https://validator.w3.org/feed/docs/rss2.html.
+
+ """
+
+ # pylint: disable=too-many-instance-attributes
+
+ REQUIRED_ELEMENTS = ["title", "link", "description"]
+ OPTIONAL_ELEMENTS = ["language", "copyright", "managingEditor", "webMaster",
+ "pubDate", "lastBuildDate", "category", "generator",
+ "docs", "cloud", "ttl", "image", "textInput",
+ "skipHours", "skipDays"]
+
+ def __init__(self):
+ """Define available attributes."""
+ self.rssurl = None # the URL of the rss feed
+ self.atomlink = None
+ for element in self.REQUIRED_ELEMENTS:
+ setattr(self, element, None)
+ for element in self.OPTIONAL_ELEMENTS:
+ setattr(self, element, None)
+ self.docs = ET.Element("docs")
+ self.docs.text = "https://validator.w3.org/feed/docs/rss2.html"
+ self.author_text = None
+ self.update_timestamp = None
+ self.items = []
+ self.rss = None
+ self.channel = None
+
+ def assemble_rss(self, FEED_MAX_ENTRIES):
+ """Assemble RSS 2.0 feed."""
+ self.rss = ET.Element("rss", version="2.0", nsmap={"atom": "http://www.w3.org/2005/Atom"})
+ self.channel = ET.SubElement(self.rss, "channel")
+ # https://validator.w3.org/feed/docs/warning/MissingAtomSelfLink.html
+ self.atomlink = ET.SubElement(self.channel, "{http://www.w3.org/2005/Atom}link",
+ href=self.rssurl, rel="self", type="application/rss+xml")
+ for element in self.REQUIRED_ELEMENTS:
+ self.channel.append(getattr(self, element))
+ for element in self.OPTIONAL_ELEMENTS:
+ attr = getattr(self, element)
+ if attr is not None:
+ self.channel.append(attr)
+ # include at most FEED_MAX_ENTRIES items in the RSS feed
+ for item in self.items[:FEED_MAX_ENTRIES]:
+ self.channel.append(item.item)
+
+ def dump_rss(self, FEED_MAX_ENTRIES):
+ """Dump RSS feed XML."""
+ if self.rss is None:
+ self.assemble_rss(FEED_MAX_ENTRIES)
+ return ET.tostring(self.rss).decode("utf-8")