From 7b446d9b4d9b41deda280596cb0a01a0c7d01700 Mon Sep 17 00:00:00 2001 From: mathieui Date: Sun, 6 Apr 2014 00:15:01 +0200 Subject: [PATCH] Improve drastically the performance of the MucListTab - avoid doing stringprep on every item, avoid at least one full copy - add the number of items to the infowin --- src/tabs/muclisttab.py | 36 ++++++++++++++++++++++++------------ src/windows.py | 31 ++++++++++++++++++++++++------- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/src/tabs/muclisttab.py b/src/tabs/muclisttab.py index c5b2a205..cefe0460 100644 --- a/src/tabs/muclisttab.py +++ b/src/tabs/muclisttab.py @@ -10,13 +10,18 @@ import logging log = logging.getLogger(__name__) import curses +import collections +from datetime import datetime -from . import Tab +from sleekxmpp.plugins.xep_0030.stanza.items import DiscoItem import windows from common import safeJID from decorators import refresh_wrapper +from . import Tab + + class MucListTab(Tab): """ A tab listing rooms from a specific server, displaying various information, @@ -29,8 +34,11 @@ class MucListTab(Tab): Tab.__init__(self) self.state = 'normal' self.name = server - columns = ('node-part', 'name', 'users') - self.list_header = windows.ColumnHeaderWin(columns) + columns = collections.OrderedDict() + columns['node-part'] = 0 + columns['name'] = 2 + columns['users'] = 3 + self.list_header = windows.ColumnHeaderWin(list(columns)) self.listview = windows.ListWin(columns) self.info_header = windows.MucListInfoWin(_('Chatroom list on server %s (Loading)') % self.name) self.default_help_message = windows.HelpText("ā€œjā€: join room.") @@ -55,7 +63,7 @@ class MucListTab(Tab): if self.need_resize: self.resize() log.debug(' TAB Refresh: %s', self.__class__.__name__) - self.info_header.refresh() + self.info_header.refresh(window=self.listview) self.info_win.refresh() self.refresh_tab_win() self.list_header.refresh() @@ -110,18 +118,22 @@ class MucListTab(Tab): if iq['type'] == 'error': self.set_error(iq['error']['type'], iq['error']['code'], iq['error']['text']) return - items = [{'node-part': safeJID(item[0]).user if safeJID(item[0]).server == self.name else safeJID(item[0]).bare, - 'jid': item[0], - 'name': item[2] or '', 'users': ''} for item in iq['disco_items'].get_items()] - self.listview.add_lines(items) + def get_items(): + substanza = iq['disco_items'] + for item in substanza['substanzas']: + if isinstance(item, DiscoItem): + yield (item['jid'], item['node'], item['name']) + items = [ (item[0].split('@')[0], + item[0], + item[2] or '', '') for item in get_items()] + self.listview.set_lines(items) self.info_header.message = _('Chatroom list on server %s') % self.name if self.core.current_tab() is self: - self.listview.refresh() - self.info_header.refresh() + self.refresh() else: self.state = 'highlight' self.refresh_tab_win() - curses.doupdate() + self.core.doupdate() def sort_by(self): if self.list_header.get_order(): @@ -136,7 +148,7 @@ class MucListTab(Tab): asc=True) self.list_header.set_order(True) self.list_header.refresh() - curses.doupdate() + self.core.doupdate() def join_selected(self): row = self.listview.get_selected_row() diff --git a/src/windows.py b/src/windows.py index 60871821..e572a0a5 100644 --- a/src/windows.py +++ b/src/windows.py @@ -491,7 +491,7 @@ class MucListInfoWin(InfoWin): InfoWin.__init__(self) self.message = message - def refresh(self, name=None): + def refresh(self, name=None, window=None): log.debug('Refresh: %s',self.__class__.__name__) with g_lock: self._win.erase() @@ -499,6 +499,8 @@ class MucListInfoWin(InfoWin): self.addstr(name, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) else: self.addstr(self.message, to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + if window: + self.print_scroll_position(window) self.finish_line(get_theme().COLOR_INFORMATION_BAR) self._refresh() @@ -2248,13 +2250,20 @@ class ListWin(Win): """ def __init__(self, columns, with_headers=True): Win.__init__(self) - self._columns = columns # a tuple with the name of the columns + self._columns = columns # a dict {'column_name': tuple_index} self._columns_sizes = {} # a dict {'column_name': size} self.sorted_by = (None, None) # for example: ('name', 'ā†‘') self.lines = [] # a list of dicts self._selected_row = 0 self._starting_pos = 0 # The column number from which we start the refresh + @property + def pos(self): + if len(self.lines) > self.height: + return len(self.lines) + else: + return 0 + def empty(self): """ emtpy the list and reset some important values as well @@ -2288,7 +2297,15 @@ class ListWin(Win): """ if not lines: return - self.lines += lines + self.lines.extend(lines) + + def set_lines(self, lines): + """ + Set the lines to another list + """ + if not lines: + return + self.lines = lines def get_selected_row(self): """ @@ -2305,12 +2322,12 @@ class ListWin(Win): lines = self.lines[self._starting_pos:self._starting_pos+self.height] for y, line in enumerate(lines): x = 0 - for col in self._columns: + for col in self._columns.items(): try: - txt = line[col] or '' - except (KeyError): + txt = line[col[1]] or '' + except KeyError: txt = '' - size = self._columns_sizes[col] + size = self._columns_sizes[col[0]] txt += ' ' * (size-len(txt)) if not txt: continue