# HG changeset patch # User Paul Boddie # Date 1342476215 -7200 # Node ID eee0ea142168d3f341afae6481529f268f8604e3 # Parent 685687ea5d71cb4b845727d77cca8e9cbf906121 Added a macro based on FeedReader to obtain and present shared updates. diff -r 685687ea5d71 -r eee0ea142168 macros/SharedContent.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/macros/SharedContent.py Tue Jul 17 00:03:35 2012 +0200 @@ -0,0 +1,141 @@ +# -*- coding: iso-8859-1 -*- +""" + MoinMoin - SharedContent macro, based on the FeedReader macro + + @copyright: 2008, 2012 by Paul Boddie + @license: GNU GPL (v2 or later), see COPYING.txt for details. +""" + +from MoinMoin.Page import Page +import urllib +import xml.dom.pulldom + +Dependencies = ["time"] + +MAX_ENTRIES = 5 +ATOM_NS = "http://www.w3.org/2005/Atom" + +def text(element): + nodes = [] + for node in element.childNodes: + if node.nodeType == node.TEXT_NODE: + nodes.append(node.nodeValue) + return "".join(nodes) + +def linktext(element, feed_type): + if feed_type == "rss": + return text(element) + else: + return element.getAttribute("href") + +def execute(macro, args): + request = macro.request + fmt = macro.formatter + + max_entries = MAX_ENTRIES + args = args.split(",") + if args: + try: + feed_url = args[0] + max_entries = int(args[1]) + except IndexError: + pass + + # Obtain the feed. + + feed = urllib.urlopen(feed_url) + + try: + # Parse each node from the feed. + + title = link = None + channel_title = channel_link = None + + output = [] + append = output.append + append(fmt.bullet_list(on=1)) + + feed_type = None + in_item = False + nentries = 0 + + events = xml.dom.pulldom.parse(feed) + + for event, value in events: + + if event == xml.dom.pulldom.START_ELEMENT: + tagname = value.localName + + # Detect the feed type and items. + + if tagname == "feed" and value.namespaceURI == ATOM_NS: + feed_type = "atom" + + elif tagname == "rss": + feed_type = "rss" + + # Detect items. + + elif feed_type == "rss" and tagname == "item" or \ + feed_type == "atom" and tagname == "entry": + + in_item = True + + elif tagname == "title": + events.expandNode(value) + if in_item: + title = value + else: + channel_title = value + + elif tagname == "link": + events.expandNode(value) + if in_item: + link = value + else: + channel_link = value + + elif event == xml.dom.pulldom.END_ELEMENT: + tagname = value.localName + + if feed_type == "rss" and tagname == "item" or \ + feed_type == "atom" and tagname == "entry": + + in_item = False + + # Emit title and link information for items. + + if title and link and nentries < max_entries: + link_text = linktext(link, feed_type) + + append(fmt.listitem(on=1)) + append(fmt.url(on=1, href=link_text)) + append(fmt.icon('www')) + append(fmt.text(" " + text(title))) + append(fmt.url(on=0)) + append(fmt.listitem(on=0)) + + title = link = None + nentries += 1 + + append(fmt.bullet_list(on=0)) + + if channel_title and channel_link: + channel_link_text = linktext(channel_link, feed_type) + + append(fmt.paragraph(on=1)) + append(fmt.url(on=1, href=channel_link_text)) + append(fmt.text(text(channel_title))) + append(fmt.url(on=0)) + append(fmt.text(" ")) + append(fmt.url(on=1, href=feed_url)) + append(fmt.icon('rss')) + append(fmt.url(on=0)) + append(fmt.paragraph(on=0)) + + finally: + feed.close() + + return ''.join(output) + +# vim: tabstop=4 expandtab shiftwidth=4