__author__ = "Blake Winton and Will Guaraldi"
__version__ = "1.8 (April 11, 2005)"
__url__ = "http://www.bluesock.org/~willg/pyblosxom/"
__description__ = "RSS2 renderer."
from Pyblosxom.renderers.base import RendererBase
from Pyblosxom.tools import Stripper
from xml.dom.minidom import Document
import urlparse
class RSS2Renderer(RendererBase):
desc_length = 20
create_entry = 1
entry_type = 'CDATA'
namespaces = {
'admin': "http://webns.net/mvcb/",
'content': "http://purl.org/rss/1.0/modules/content/",
'creativeCommons': "http://backend.userland.com/creativeCommonsRssModule",
'dc': "http://purl.org/dc/elements/1.1/",
'rdf': "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
'html': "http://www.w3.org/1999/html",
'slash': "http://purl.org/rss/1.0/modules/slash/",
}
def _addText(self, element, text, baseElement):
e = self._doc.createElement(element)
e.appendChild(self._doc.createTextNode(text))
baseElement.appendChild(e)
return e
def _addCDATA(self, element, text, baseElement):
e = self._doc.createElement(element)
e.appendChild(self._doc.createCDATASection(text))
baseElement.appendChild(e)
return e
def _addElemAttr(self, element, attr, content, baseElement, text = None):
e = self._doc.createElement(element)
e.setAttribute(attr, content)
if text:
e.appendChild(self._doc.createTextNode(text))
baseElement.appendChild(e)
return e
def _addAttr(self, element, attr, content):
element.setAttribute(attr, content)
def _addNameSpaces(self, element, namespace_dict):
for attr in namespace_dict:
self._addAttr(element, 'xmlns:' + attr, namespace_dict[attr])
def _urlEncode(self, txt):
txt = txt.replace(" ", "%20")
return txt
def _createChannel(self):
self._doc = Document()
d = self._doc
rss = d.createElement('rss')
rss.setAttribute('version', '2.0')
self._addNameSpaces(rss, self.namespaces)
d.appendChild(rss)
self._channel = d.createElement('channel')
channel = self._channel
rss.appendChild(channel)
self._addText('title', self._config['blog_title'], channel)
self._addText('link', self._urlEncode(self._config['base_url']), channel)
self._addText('description', self._config['blog_description'], channel)
self._addText('language', self._config['blog_language'], channel)
self._addText('ttl', '60', channel)
self._addText('dc:creator', self._config['blog_author'], channel)
self._addElemAttr('admin:generatorAgent', \
'rdf:resource', \
'http://pyblosxom.sourceforge.net/', \
channel)
self._addElemAttr('admin:errorReportsTo', \
'rdf:resource', \
"mailto:" + self._config.get("blog_email", "none"), \
channel)
def _generateDesc(self, html):
s = Stripper()
s.feed(html)
str = s.gettext()
frag = str.split()
if len(frag) > self.desc_length:
frag = frag[:self.desc_length]
frag.append('...')
return ' '.join(frag)
def _createItem(self, entry):
burl = self._config['base_url']
d = urlparse.urlsplit(self._config['base_url'])
domain = '%s://%s' % (d[0], d[1])
item = self._doc.createElement('item')
self._channel.appendChild(item)
self._addText('title', entry['title'], item)
self._addElemAttr('guid', 'isPermaLink', 'false', item, entry['file_path'])
url = urlparse.urljoin(burl + "/", entry["file_path"])
self._addText('link', self._urlEncode(url), item)
self._addText('description', self._generateDesc(entry['body']), item)
if self.create_entry:
if self.entry_type == 'CDATA':
self._addCDATA('content:encoded', entry['body'], item)
else:
self._addText('content:encoded', entry['body'], item)
if entry['path'].strip():
self._addElemAttr('category', 'domain', domain, item, entry['path'])
self._addText('dc:date', entry['w3cdate'], item)
def render(self, header = 1):
if self.rendered == 1:
return
self._data = self._request.getData()
self._config = self._request.getConfiguration()
self.addHeader('Content-Type', 'application/xml')
self.showHeaders()
self._createChannel()
if self._config.get("num_entries", 0):
max_entries = self._config["num_entries"]
else:
max_entries = 20
if self._content:
if max_entries > len(self._content):
num_entries = len(self._content)
else:
num_entries = max_entries
for count in xrange(num_entries):
self._createItem(self._content[count])
text = self._doc.toxml()
if self._config.has_key("blog_encoding"):
text = "<?xml version=\"1.0\" encoding=\"%s\" ?>" % self._config["blog_encoding"] + text[text.find("\n"):]
self.write(text)
self.rendered = 1
def cb_renderer(args):
import sys
req = args['request']
http = req.getHttp()
conf = req.getConfiguration()
ext = conf.get("rss2_extension", "/index.rss2")
if http['PATH_INFO'].endswith( ext ):
http['PATH_INFO'] = http['PATH_INFO'][:-len(ext)]
return RSS2Renderer(req, conf.get('stdoutput', sys.stdout))