From fa464e4d86185266e1de9fb89d32fa2f35964ce1 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Sun, 10 Jul 2011 18:15:52 +0200 Subject: Pubsub browser can display atom element, etc --- src/atom_parser.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ src/pubsub.py | 49 ++++++++++++++++++++++++++++++++++++++++++++----- src/windows.py | 2 +- 3 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 src/atom_parser.py (limited to 'src') diff --git a/src/atom_parser.py b/src/atom_parser.py new file mode 100644 index 00000000..e676d968 --- /dev/null +++ b/src/atom_parser.py @@ -0,0 +1,48 @@ +# Copyright 2010-2011 Le Coz Florent +# +# This file is part of Poezio. +# +# Poezio is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# Poezio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Poezio. If not, see . + +""" +Defines a function returning a dict containing the values from an +atom entry contained in a pubsub entry +""" + +ATOM_XMLNS = "http://www.w3.org/2005/Atom" + +def parse_atom_entry(pubsub_item): + """ + Takes a pubsub ET.Element item and returns a dict containing + all needed values from the atom entry element. + Returns None if the item does not contain an atom entry. + """ + entry_elem = pubsub_item.find('{%s}entry' % (ATOM_XMLNS,)) + if entry_elem is None: + return None + res = {'author':{}} + author_elem = entry_elem.find('{%s}author' % (ATOM_XMLNS,)) + if author_elem is not None: + for sub in ('name', 'uri'): + sub_elem = author_elem.find('{%s}%s' % (ATOM_XMLNS, sub,)) + if sub_elem is not None: + res['author'][sub] = sub_elem.text + for elem_name in {'title':'text', 'updated':'date', 'published': 'date', + 'summary':'text'}: + elem = entry_elem.find('{%s}%s' % (ATOM_XMLNS, elem_name,)) + if elem is not None: + res[elem_name] = elem.text + link_elem = entry_elem.find('{%s}link' % (ATOM_XMLNS,)) + if link_elem is not None: + res['link_href'] = link_elem.attrib.get('href') or '' + return res diff --git a/src/pubsub.py b/src/pubsub.py index 3e463a3e..5fd0884e 100644 --- a/src/pubsub.py +++ b/src/pubsub.py @@ -19,11 +19,18 @@ log = logging.getLogger(__name__) import curses -import windows import tabs +import windows +import atom_parser from sleekxmpp.xmlstream import ElementBase, ET +try: + import feedparser + has_feedparser = True +except ImportError: + has_feedparser = False + class PubsubNode(object): node_type = None # unknown yet def __init__(self, name, parent=None): @@ -49,6 +56,7 @@ class PubsubItem(object): def __init__(self, idd, content): self.id = idd self.content = content + self.parsed_content = atom_parser.parse_atom_entry(content) def to_dict(self, columns): """ @@ -57,6 +65,9 @@ class PubsubItem(object): ret = {} for col in columns: ret[col] = self.__dict__.get(col) or '' + if self.parsed_content: + ret['title'] = self.parsed_content.get('title') + ret['author'] = self.parsed_content['author'].get('name') return ret class PubsubBrowserTab(tabs.Tab): @@ -85,10 +96,13 @@ class PubsubBrowserTab(tabs.Tab): self.node_listview = windows.ListWin(node_columns) # Item List View - item_columns = ('id',) + item_columns = ('title', 'author', 'id') self.item_list_header = windows.ColumnHeaderWin(item_columns) self.item_listview = windows.ListWin(item_columns) + # Vertical Separator + self.vertical_separator = windows.VerticalSeparator() + # Item viewer self.item_viewer = windows.SimpleTextWin('') self.default_help_message = windows.HelpText("ā€œcā€: create a node.") @@ -121,13 +135,18 @@ class PubsubBrowserTab(tabs.Tab): self.node_listview.resize_columns(column_size) self.node_listview.resize(self.height//2-2, self.width//2, 2, 0) - column_size = {'id': self.width//2,} + w = self.width//2 + column_size = {'id': w//8, + 'title':w//8*5, + 'author':w//8*2} self.item_list_header.resize_columns(column_size) self.item_list_header.resize(self.height//2+1, self.width//2, self.height//2, 0) self.item_listview.resize_columns(column_size) self.item_listview.resize(self.height//2-3, self.width//2, self.height//2+1, 0) - self.item_viewer.resize(self.height-3, self.width//2+1, 1, self.width//2) + self.vertical_separator.resize(self.height-3, 1, 1, self.width//2) + + self.item_viewer.resize(self.height-3, self.width//2+1, 1, self.width//2+1) self.input.resize(1, self.width, self.height-1, 0) def refresh(self): @@ -141,6 +160,7 @@ class PubsubBrowserTab(tabs.Tab): self.item_listview.refresh() self.item_viewer.refresh() self.tab_win.refresh() + self.vertical_separator.refresh() self.input.refresh() def force_refresh(self): @@ -229,6 +249,7 @@ class PubsubBrowserTab(tabs.Tab): self.item_listview.empty() log.debug('display_items_from_node: %s' % node.items) for item in node.items: + line = item.to_dict(columns) self.item_listview.lines.append(item.to_dict(columns)) def add_nodes(self, node_list, parent=None): @@ -320,6 +341,24 @@ class PubsubBrowserTab(tabs.Tab): if not selected_item: return log.debug('Content: %s'%ET.tostring(selected_item.content)) - self.item_viewer._text = str(ET.tostring(selected_item.content)) + if not has_feedparser: + self.item_viewer._text = str(ET.tostring(selected_item.content)) + else: + entry = atom_parser.parse_atom_entry(selected_item.content) + self.item_viewer._text = \ +"""\x193Title:\x19o %(title)s +\x193Author:\x19o %(author_name)s (%(author_uri)s) +%(dates)s\x193Link:\x19o %(link)s + +\x193Summary:\x19o +%(summary)s +""" % {'title': entry.get('title') or '', + 'author_name': entry['author'].get('name') or '', + 'author_uri': entry['author'].get('uri') or '', + 'link': entry.get('link_href') or '', + 'summary': entry.get('summary') or '', + 'dates': '\x193Published:\x19o %(published)s\n%(updated)s' % {'published':entry.get('published') or '', + 'updated': '' if (entry.get('updated') is None) or (entry.get('published') == entry.get('updated')) else '\x193Published:\x19o %s\n' % entry.get('updated')} + } self.item_viewer.rebuild_text() return True diff --git a/src/windows.py b/src/windows.py index d4d9b2a7..6d71e28e 100644 --- a/src/windows.py +++ b/src/windows.py @@ -1661,5 +1661,5 @@ class SimpleTextWin(Win): with g_lock: self._win.erase() for y, line in enumerate(self.built_lines): - self.addstr(y, 0, line) + self.addstr_colored(line, y, 0) self._refresh() -- cgit v1.2.3