I just rolled something with ElementTree. No idea how it
stacks up against validity checks, but it seems to be
accepted by a couple of standard feed readers.
(sorry; longish code segment)
<code>
import os, sys
from datetime import datetime
try:
from xml.etree import cElementTree as ET
except ImportError:
from elementtree import ElementTree as ET
class Feed (object):
ENCODING = "utf-8"
def __init__ (self, title, link, description=None, author=None, updated_on=None):
self.title = title
self.link = link
self.description = description
self.author = author
self.updated_on = updated_on or datetime.now ()
self.entries = []
def add_entry (self, title, link, content, summary=None, id=None, updated_on=None):
self.entries.append (
dict (
title=title,
link=link,
content=content,
summary=summary,
id=id or link,
updated_on=updated_on or datetime.now ()
)
)
def write_rss (self, ofile=sys.stdout, encoding=ENCODING):
rss = ET.Element ("rss", version="2.0")
channel = ET.SubElement (rss, "channel")
ET.SubElement (channel, "title").text = self.title
ET.SubElement (channel, "link").text = self.link
ET.SubElement (channel, "description").text = self.description
for entry in self.entries:
item = ET.SubElement (channel, "item")
ET.SubElement (item, "title").text = entry['title']
ET.SubElement (item, "link").text = entry['link']
ET.SubElement (item, "guid").text = entry['id']
ET.SubElement (item, "description").text = entry['content']
ET.ElementTree (rss).write (ofile, encoding=encoding)
def write_atom (self, ofile=sys.stdout, encoding=ENCODING):
feed = ET.Element ("feed")
ET.SubElement (feed, "title", type="text").text = self.title
ET.SubElement (feed, "link", rel="self", href=self.link)
if self.description:
ET.SubElement (feed, "subtitle", type="text").text = self.description
if self.author:
name, email = self.author
author = ET.SubElement (feed, "author")
ET.SubElement (author, "name").text = name
ET.SubElement (author, "email").text = email
ET.SubElement (feed, "updated").text = self.updated_on.isoformat ()
for entry in self.entries:
e = ET.SubElement (feed, "entry")
ET.SubElement (e, "title").text = entry['title']
ET.SubElement (e, "link", href=entry['link'])
ET.SubElement (e, "id").text = entry['id']
ET.SubElement (e, "updated").text = entry['updated_on'].isoformat ()
if entry['summary']:
ET.SubElement (e, "summary").text = entry['summary']
ET.SubElement (e, "content", type="html").text = "<![CDATA[%s]]>" % entry['content']
ET.ElementTree (feed).write (ofile, encoding=encoding)
if __name__ == '__main__':
feed = Feed ("Feed for example.org", "
http://example.org", author=("Tim Golden", "(e-mail address removed)"))
for i in range (5):
feed.add_entry ("Entry %d" % i, "
http://example.org/entry/%d" % i, "Contents for entry %d" % i, id="entry#%d" % i)
feed.write_atom (open ("feed.atom.xml", "w"), "iso-8859-1")
feed.write_rss (open ("feed.rss.xml", "w"), "iso-8859-1")
</code>
TJG