#!/usr/bin/python import sys from xml.sax import parse from xml.sax.handler import ContentHandler # http://wxpython.org/ from wxPython.wx import * from wxPython.html import * # http://diveintomark.org/projects/rss_parser/index.html import rssparser # simple SAX parser for Radio, Syndirella, and Aggie dialects of OPML. class opml(ContentHandler): outline={} def __init__(self,file): ContentHandler.__init__(self) parse(file, self) def startElement(self, name, attrs): if name=='outline': values=dict(map(lambda k:(k.lower(),attrs.getValue(k)),attrs.getNames())) if 'title' in values: values['text']=values['title'] self.outline[attrs['title'].lower()]=values # Yet Another 3 Paned Aggregator class wx3pa(wxApp): # model mySubs=None items=None # view tree=None list=None data=None def OnInit(self): # layout frame = wxFrame(NULL, -1, "3 Paned Aggregator Mockup-demo") split1 = wxSplitterWindow(frame,-1) split2 = wxSplitterWindow(split1,-1) # panes self.tree=wxTreeCtrl(split1,-1) self.list=wxListCtrl(split2,-1,style=wxLC_REPORT|wxSUNKEN_BORDER) self.data=wxHtmlWindow(split2,-1) # attach the panes to the frame split1.SplitVertically(self.tree, split2) split2.SplitHorizontally(self.list, self.data) self.SetTopWindow(frame) frame.Show(true) # resize split1.SetMinimumPaneSize(20) split2.SetMinimumPaneSize(20) split1.SetSashPosition(300,true) split2.SetSashPosition(200) # wire up the events EVT_TREE_SEL_CHANGED(self, self.tree.GetId(), self.selectFeed) EVT_LIST_ITEM_SELECTED(self, self.list.GetId(), self.selectItem) return true # load a list of subscriptions from an OPML file def load(self,files): root = self.tree.AddRoot("Feeds") for file in files: self.mySubs = opml(file) names=self.mySubs.outline.keys() names.sort() for name in names: text = self.mySubs.outline[name]['text'] child=self.tree.AppendItem(root,text.encode('iso-8859-1')) self.tree.SetPyData(child,self.mySubs.outline[name]) self.tree.Expand(root) # select a single feed and display titles from each item def selectFeed(self, event): self.list.DeleteAllItems() if not self.list.GetColumn(0): self.list.InsertColumn(0, 'Title') outline = self.tree.GetPyData(event.GetItem()) self.items=rssparser.parse(outline['xmlurl'])['items'] for i in range(0,len(self.items)): if 'title' in self.items[i]: row=self.list.InsertStringItem(i,self.items[i]['title']) self.list.SetItemData(row,i) self.list.SetColumnWidth(0,wxLIST_AUTOSIZE_USEHEADER) # show the html description for a single item def selectItem(self, event): item=self.items[event.GetItem().GetData()] self.data.SetPage(item.get('content_encoded', item.get('description'))) if __name__ == '__main__': app = wx3pa(0) app.load(sys.argv[1:] or [r'http://radio.weblogs.com/0101679/gems/mySubscriptions.opml']) app.MainLoop()