From 28ce49dcaaa1f7e958e09aff2af7d1e956796ad9 Mon Sep 17 00:00:00 2001 From: mathieui Date: Fri, 29 Jun 2018 21:18:09 +0200 Subject: Update poezio for the new tabs module --- poezio/config.py | 17 ++- poezio/connection.py | 25 ++- poezio/core/commands.py | 123 ++++++++------- poezio/core/completions.py | 17 ++- poezio/core/core.py | 302 +++++++++++-------------------------- poezio/core/handlers.py | 144 ++++++++++-------- poezio/logger.py | 4 +- poezio/plugin.py | 4 +- poezio/plugin_manager.py | 8 +- poezio/tabs/adhoc_commands_list.py | 2 +- poezio/tabs/basetabs.py | 17 +-- poezio/tabs/bookmarkstab.py | 8 +- poezio/tabs/confirmtab.py | 5 +- poezio/tabs/conversationtab.py | 5 +- poezio/tabs/listtab.py | 5 +- poezio/tabs/muclisttab.py | 2 +- poezio/tabs/muctab.py | 75 ++++----- poezio/tabs/privatetab.py | 20 +-- poezio/tabs/rostertab.py | 20 +-- poezio/tabs/xmltab.py | 12 +- poezio/text_buffer.py | 11 +- poezio/windows/base_wins.py | 4 +- poezio/windows/bookmark_forms.py | 53 ++++--- poezio/windows/data_forms.py | 4 +- poezio/windows/info_bar.py | 8 +- poezio/windows/info_wins.py | 6 +- poezio/windows/inputs.py | 5 +- poezio/windows/list.py | 12 +- poezio/windows/roster_win.py | 18 ++- poezio/xhtml.py | 4 +- 30 files changed, 415 insertions(+), 525 deletions(-) diff --git a/poezio/config.py b/poezio/config.py index ed295c92..92e3c573 100644 --- a/poezio/config.py +++ b/poezio/config.py @@ -316,16 +316,18 @@ class Config(RawConfigParser): sections, result_lines = result if section not in sections: - log.error('Tried to remove the option %s from a non-' - 'existing section (%s)', option, section) + log.error( + 'Tried to remove the option %s from a non-' + 'existing section (%s)', option, section) return True else: begin, end = sections[section] pos = find_line(result_lines, begin, end, option) if pos is -1: - log.error('Tried to remove a non-existing option %s' - ' from section %s', option, section) + log.error( + 'Tried to remove a non-existing option %s' + ' from section %s', option, section) return True else: del result_lines[pos] @@ -426,9 +428,10 @@ class Config(RawConfigParser): elif current.lower() == "true": value = "false" else: - return ('Could not toggle option: %s.' - ' Current value is %s.' % - (option, current or "empty"), 'Warning') + return ( + 'Could not toggle option: %s.' + ' Current value is %s.' % (option, current or "empty"), + 'Warning') if self.has_section(section): RawConfigParser.set(self, section, option, value) else: diff --git a/poezio/connection.py b/poezio/connection.py index c97365f8..2d6ec2a6 100644 --- a/poezio/connection.py +++ b/poezio/connection.py @@ -81,7 +81,9 @@ class Connection(slixmpp.ClientXMPP): jid = config.get('server') password = None jid = safeJID(jid) - jid.resource = '%s-%s' % (jid.resource, device_id) if jid.resource else 'poezio-%s' % device_id + jid.resource = '%s-%s' % ( + jid.resource, + device_id) if jid.resource else 'poezio-%s' % device_id # TODO: use the system language slixmpp.ClientXMPP.__init__( self, jid, password, lang=config.get('lang')) @@ -107,8 +109,9 @@ class Connection(slixmpp.ClientXMPP): self.auto_authorize = None # prosody defaults, lowest is AES128-SHA, it should be a minimum # for anything that came out after 2002 - self.ciphers = config.get('ciphers', 'HIGH+kEDH:HIGH+kEECDH:HIGH:!PSK' - ':!SRP:!3DES:!aNULL') + self.ciphers = config.get( + 'ciphers', 'HIGH+kEDH:HIGH+kEECDH:HIGH:!PSK' + ':!SRP:!3DES:!aNULL') self.ca_certs = config.get('ca_cert_path') or None interval = config.get('whitespace_interval') if int(interval) > 0: @@ -118,11 +121,17 @@ class Connection(slixmpp.ClientXMPP): self.register_plugin('xep_0004') self.register_plugin('xep_0012') # Must be loaded before 0030. - self.register_plugin('xep_0115', { - 'caps_node': 'https://poez.io', - 'cache': FileSystemCache(CACHE_DIR, 'caps', encode=str, - decode=lambda x: DiscoInfo(ET.fromstring(x))), - }) + self.register_plugin( + 'xep_0115', { + 'caps_node': + 'https://poez.io', + 'cache': + FileSystemCache( + CACHE_DIR, + 'caps', + encode=str, + decode=lambda x: DiscoInfo(ET.fromstring(x))), + }) self.register_plugin('xep_0030') self.register_plugin('xep_0045') self.register_plugin('xep_0048') diff --git a/poezio/core/commands.py b/poezio/core/commands.py index 7d503fff..6e17c32c 100644 --- a/poezio/core/commands.py +++ b/poezio/core/commands.py @@ -53,7 +53,7 @@ class CommandCore: buff.extend(acc) acc = [] buff.append('Tab-specific commands:') - tab_commands = self.core.current_tab().commands + tab_commands = self.core.tabs.current_tab.commands for name, command in tab_commands.items(): if isinstance(command, Command): acc.append(' \x19%s}%s\x19o - %s' % (color, name, @@ -68,7 +68,7 @@ class CommandCore: else: command = args[0].lstrip('/').strip() - tab_commands = self.core.current_tab().commands + tab_commands = self.core.tabs.current_tab.commands if command in tab_commands: tup = tab_commands[command] elif command in self.core.commands: @@ -126,7 +126,7 @@ class CommandCore: pres['type'] = show self.core.events.trigger('send_normal_presence', pres) pres.send() - current = self.core.current_tab() + current = self.core.tabs.current_tab is_muctab = isinstance(current, tabs.MucTab) if is_muctab and current.joined and show in ('away', 'xa'): current.send_chat_state('inactive') @@ -149,8 +149,8 @@ class CommandCore: return self.help('presence') jid, ptype, status = args[0], args[1], args[2] - if jid == '.' and isinstance(self.core.current_tab(), tabs.ChatTab): - jid = self.core.current_tab().name + if jid == '.' and isinstance(self.core.tabs.current_tab, tabs.ChatTab): + jid = self.core.tabs.current_tab.name if ptype == 'available': ptype = None try: @@ -163,7 +163,7 @@ class CommandCore: log.debug( 'Could not send directed presence to %s', jid, exc_info=True) return - tab = self.core.get_tab_by_name(jid) + tab = self.core.tabs.by_name_and_class(jid) if tab: if ptype in ('xa', 'away'): tab.directed_presence = False @@ -171,13 +171,13 @@ class CommandCore: else: tab.directed_presence = True chatstate = 'active' - if tab == self.core.current_tab(): + if tab == self.core.tabs.current_tab: tab.send_chat_state(chatstate, True) if isinstance(tab, tabs.MucTab): for private in tab.privates: private.directed_presence = tab.directed_presence - if self.core.current_tab() in tab.privates: - self.core.current_tab().send_chat_state(chatstate, True) + if self.core.tabs.current_tab in tab.privates: + self.core.tabs.current_tab.send_chat_state(chatstate, True) @command_args_parser.quoted(1) def theme(self, args=None): @@ -200,33 +200,23 @@ class CommandCore: except ValueError: number = -1 name = name.lower() - if number != -1 and self.core.current_tab_nb == number: + if number != -1 and self.core.tabs.current_tab == number: return prev_nb = self.core.previous_tab_nb - self.core.previous_tab_nb = self.core.current_tab_nb - old_tab = self.core.current_tab() + self.core.previous_tab_nb = self.core.tabs.current_tab + old_tab = self.core.tabs.current_tab if 0 <= number < len(self.core.tabs): if not self.core.tabs[number]: self.core.previous_tab_nb = prev_nb return - self.core.current_tab_nb = number + self.core.tabs.set_current_index(number) else: - match = None - target_tabs = self.core.tabs[self.core.current_tab_nb+1:] \ - + self.core.tabs[:self.core.current_tab_nb] - for tab in target_tabs: - for tab_name in tab.matching_names(): - if tab_name[1] and name in tab_name[1].lower(): - match = tab - break - if match: - break + match = self.core.tabs.find_match(name) if match is None: - self.core.previous_tab_nb = prev_nb return - self.core.current_tab_nb = match.nb + self.core.tabs.set_current_tab(match) old_tab.on_lose_focus() - self.core.current_tab().on_gain_focus() + self.core.tabs.current_tab.on_gain_focus() self.core.refresh_window() @command_args_parser.quoted(2) @@ -237,7 +227,7 @@ class CommandCore: if args is None: return self.help('move_tab') - current_tab = self.core.current_tab() + current_tab = self.core.tabs.current_tab if args[0] == '.': args[0] = current_tab.nb if args[1] == '.': @@ -267,8 +257,6 @@ class CommandCore: result = self.core.insert_tab(old, new) if not result: self.core.information('Unable to move the tab.', 'Info') - else: - self.core.current_tab_nb = self.core.tabs.index(current_tab) self.core.refresh_window() @command_args_parser.quoted(0, 1) @@ -282,10 +270,10 @@ class CommandCore: elif args: jid = safeJID(args[0]) else: - if not isinstance(self.core.current_tab(), tabs.MucTab): + if not isinstance(self.core.tabs.current_tab, tabs.MucTab): return self.core.information('Please provide a server', 'Error') - jid = safeJID(self.core.current_tab().name) + jid = safeJID(self.core.tabs.current_tab.name) list_tab = tabs.MucListTab(self.core, jid) self.core.add_tab(list_tab, True) cb = list_tab.on_muc_list_item_received @@ -308,7 +296,7 @@ class CommandCore: resource.jid, callback=self.core.handler.on_version_result) def _empty_join(self): - tab = self.core.current_tab() + tab = self.core.tabs.current_tab if not isinstance(tab, (tabs.MucTab, tabs.PrivateTab)): return (None, None) room = safeJID(tab.name).bare @@ -332,7 +320,7 @@ class CommandCore: # happens with /join /nickname, which is OK if info.bare == '': - tab = self.core.current_tab() + tab = self.core.tabs.current_tab if not isinstance(tab, tabs.MucTab): room, set_nick = (None, None) else: @@ -345,7 +333,7 @@ class CommandCore: # use the server of the current room if available # check if the current room's name has a server if room.find('@') == -1 and not server_root: - tab = self.core.current_tab() + tab = self.core.tabs.current_tab if isinstance(tab, tabs.MucTab): if tab.name.find('@') != -1: domain = safeJID(tab.name).domain @@ -377,13 +365,13 @@ class CommandCore: if room in self.core.pending_invites: del self.core.pending_invites[room] - tab = self.core.get_tab_by_name(room, tabs.MucTab) + tab = self.core.tabs.by_name_and_class(room, tabs.MucTab) # New tab if tab is None: tab = self.core.open_new_room(room, nick, password=password) tab.join() else: - self.core.focus_tab_named(tab.name) + self.core.focus_tab(tab) if tab.own_nick == nick and tab.joined: self.core.information('/join: Nothing to do.', 'Info') else: @@ -397,7 +385,7 @@ class CommandCore: 'use_remote_bookmarks') else 'local' self._add_bookmark('%s/%s' % (room, nick), True, password, method) - if tab == self.core.current_tab(): + if tab == self.core.tabs.current_tab: tab.refresh() self.core.doupdate() @@ -406,7 +394,8 @@ class CommandCore: """ /bookmark_local [room][/nick] [password] """ - if not args and not isinstance(self.core.current_tab(), tabs.MucTab): + if not args and not isinstance(self.core.tabs.current_tab, + tabs.MucTab): return password = args[1] if len(args) > 1 else None jid = args[0] if args else None @@ -418,7 +407,8 @@ class CommandCore: """ /bookmark [room][/nick] [autojoin] [password] """ - if not args and not isinstance(self.core.current_tab(), tabs.MucTab): + if not args and not isinstance(self.core.tabs.current_tab, + tabs.MucTab): return jid = args[0] if args else '' password = args[2] if len(args) > 2 else None @@ -436,7 +426,7 @@ class CommandCore: def _add_bookmark(self, jid, autojoin, password, method): nick = None if not jid: - tab = self.core.current_tab() + tab = self.core.tabs.current_tab roomname = tab.name if tab.joined and tab.own_nick != self.core.own_nick: nick = tab.own_nick @@ -448,7 +438,7 @@ class CommandCore: info = safeJID(jid) roomname, nick = info.bare, info.resource if roomname == '': - tab = self.core.current_tab() + tab = self.core.tabs.current_tab if not isinstance(tab, tabs.MucTab): return roomname = tab.name @@ -499,14 +489,14 @@ class CommandCore: @command_args_parser.ignored def bookmarks(self): """/bookmarks""" - tab = self.core.get_tab_by_name('Bookmarks', tabs.BookmarksTab) - old_tab = self.core.current_tab() + tab = self.core.tabs.by_name_and_class('Bookmarks', tabs.BookmarksTab) + old_tab = self.core.tabs.current_tab if tab: - self.core.current_tab_nb = tab.nb + self.core.tabs.set_current_tab(tab) else: tab = tabs.BookmarksTab(self.core, self.core.bookmarks) self.core.tabs.append(tab) - self.core.current_tab_nb = tab.nb + self.core.tabs.set_current_tab(tab) old_tab.on_lose_focus() tab.on_gain_focus() self.core.refresh_window() @@ -523,7 +513,7 @@ class CommandCore: 'Error') if not args: - tab = self.core.current_tab() + tab = self.core.tabs.current_tab if isinstance(tab, tabs.MucTab) and self.core.bookmarks[tab.name]: self.core.bookmarks.remove(tab.name) self.core.bookmarks.save(self.core.xmpp, callback=cb) @@ -553,10 +543,10 @@ class CommandCore: theme.COLOR_INFORMATION_TEXT), }) for option_name, option_value in section.items(): - lines.append('%s\x19%s}=\x19o%s' % - (option_name, - dump_tuple(theme.COLOR_REVISIONS_MESSAGE), - option_value)) + lines.append( + '%s\x19%s}=\x19o%s' % + (option_name, dump_tuple( + theme.COLOR_REVISIONS_MESSAGE), option_value)) info = ('Current options:\n%s' % '\n'.join(lines), 'Info') elif len(args) == 1: option = args[0] @@ -608,7 +598,7 @@ class CommandCore: info = plugin_config.set_and_save(option, value, section) else: if args[0] == '.': - name = safeJID(self.core.current_tab().name).bare + name = safeJID(self.core.tabs.current_tab.name).bare if not name: self.core.information( 'Invalid tab to use the "." argument.', 'Error') @@ -662,7 +652,7 @@ class CommandCore: Do a /cycle on each room of the given server. If none, do it on the current tab """ - tab = self.core.current_tab() + tab = self.core.tabs.current_tab message = "" if args: domain = args[0] @@ -688,8 +678,9 @@ class CommandCore: "Callback for the last activity" if iq['type'] != 'result': if iq['error']['type'] == 'auth': - self.core.information('You are not allowed to see the ' - 'activity of this contact.', 'Error') + self.core.information( + 'You are not allowed to see the ' + 'activity of this contact.', 'Error') else: self.core.information('Error retrieving the activity', 'Error') @@ -756,8 +747,9 @@ class CommandCore: specific = args[1] text = args[2] if specific and specific not in pep.ACTIVITIES[general]: - return self.core.information('%s is not a correct value ' - 'for an activity' % specific, 'Error') + return self.core.information( + '%s is not a correct value ' + 'for an activity' % specific, 'Error') self.core.xmpp.plugin['xep_0108'].publish_activity( general, specific, text, callback=dumb_callback) @@ -849,9 +841,10 @@ class CommandCore: room = safeJID(args[0]).bare if room: muc.destroy_room(self.core.xmpp, room) - elif isinstance(self.core.current_tab(), tabs.MucTab) and not args[0]: + elif isinstance(self.core.tabs.current_tab, + tabs.MucTab) and not args[0]: muc.destroy_room(self.core.xmpp, - self.core.current_tab().general_jid) + self.core.tabs.current_tab.general_jid) else: self.core.information('Invalid JID: "%s"' % args[0], 'Error') @@ -931,8 +924,9 @@ class CommandCore: """ /plugins """ - self.core.information("Plugins currently in use: %s" % repr( - list(self.core.plugin_manager.plugins.keys())), 'Info') + self.core.information( + "Plugins currently in use: %s" % repr( + list(self.core.plugin_manager.plugins.keys())), 'Info') @command_args_parser.quoted(1, 1) def message(self, args): @@ -946,20 +940,21 @@ class CommandCore: return self.core.information('Invalid JID.', 'Error') tab = self.core.get_conversation_by_jid( jid.full, False, fallback_barejid=False) - muc = self.core.get_tab_by_name(jid.bare, typ=tabs.MucTab) + muc = self.core.tabs.by_name_and_class(jid.bare, typ=tabs.MucTab) if not tab and not muc: tab = self.core.open_conversation_window(jid.full, focus=True) elif muc: if jid.resource: - tab = self.core.get_tab_by_name(jid.full, typ=tabs.PrivateTab) + tab = self.core.tabs.by_name_and_class( + jid.full, typ=tabs.PrivateTab) if tab: - self.core.focus_tab_named(tab.name) + self.core.focus_tab(tab) else: tab = self.core.open_private_window(jid.bare, jid.resource) else: tab = muc else: - self.core.focus_tab_named(tab.name) + self.core.focus_tab(tab) if len(args) == 2: tab.command_say(args[1]) diff --git a/poezio/core/completions.py b/poezio/core/completions.py index c86e3514..331ab553 100644 --- a/poezio/core/completions.py +++ b/poezio/core/completions.py @@ -25,7 +25,7 @@ class CompletionCore: def help(self, the_input): """Completion for /help.""" commands = sorted(self.core.commands.keys()) + sorted( - self.core.current_tab().commands.keys()) + self.core.tabs.current_tab.commands.keys()) return Completion(the_input.new_completion, commands, 1, quotify=False) def status(self, the_input): @@ -47,7 +47,8 @@ class CompletionCore: if arg == 1: to_suggest = [] for bookmark in self.core.bookmarks: - tab = self.core.get_tab_by_name(bookmark.jid, tabs.MucTab) + tab = self.core.tabs.by_name_and_class(bookmark.jid, + tabs.MucTab) if tab is not None and tab.joined: to_suggest.append(bookmark.jid) return Completion( @@ -121,7 +122,7 @@ class CompletionCore: for elem in self.core.bookmarks] to_suggest = [] for bookmark in bookmarks: - tab = self.core.get_tab_by_name(bookmark, tabs.MucTab) + tab = self.core.tabs.by_name_and_class(bookmark, tabs.MucTab) if not tab or (tab and not tab.joined): to_suggest.append(bookmark) relevant_rooms.extend(sorted(to_suggest)) @@ -134,8 +135,8 @@ class CompletionCore: serv_list = [] for tab in self.core.get_tabs(tabs.MucTab): if tab.joined: - serv_list.append('%s@%s' % (jid.user, - safeJID(tab.name).host)) + serv_list.append( + '%s@%s' % (jid.user, safeJID(tab.name).host)) serv_list.extend(relevant_rooms) return Completion( the_input.new_completion, serv_list, 1, quotify=True) @@ -183,7 +184,7 @@ class CompletionCore: """ list_ = [] list_.extend(self.core.key_func.keys()) - list_.extend(self.core.current_tab().key_func.keys()) + list_.extend(self.core.tabs.current_tab.key_func.keys()) return Completion(the_input.new_completion, list_, 1, quotify=False) def bookmark(self, the_input): @@ -202,7 +203,7 @@ class CompletionCore: jid = safeJID(args[1]) if jid.server and (jid.resource or jid.full.endswith('/')): - tab = self.core.get_tab_by_name(jid.bare, tabs.MucTab) + tab = self.core.tabs.by_name_and_class(jid.bare, tabs.MucTab) nicks = [tab.own_nick] if tab else [] default = os.environ.get('USER') if os.environ.get( 'USER') else 'poezio' @@ -434,7 +435,7 @@ class CompletionCore: jid = safeJID(args[1]) if jid.server and (jid.resource or jid.full.endswith('/')): - tab = self.core.get_tab_by_name(jid.bare, tabs.MucTab) + tab = self.core.tabs.by_name_and_class(jid.bare, tabs.MucTab) nicks = [tab.own_nick] if tab else [] default = os.environ.get('USER') if os.environ.get( 'USER') else 'poezio' diff --git a/poezio/core/core.py b/poezio/core/core.py index b708e2cf..814f7813 100644 --- a/poezio/core/core.py +++ b/poezio/core/core.py @@ -44,6 +44,7 @@ from poezio.theming import get_theme from poezio import keyboard from poezio.core.completions import CompletionCore +from poezio.core.tabs import Tabs from poezio.core.commands import CommandCore from poezio.core.handlers import HandlerCore from poezio.core.structs import POSSIBLE_SHOW, DEPRECATED_ERRORS, \ @@ -77,7 +78,8 @@ class Core(object): self.bookmarks = BookmarkList() self.debug = False self.remote_fifo = None - self.avatar_cache = FileSystemPerJidCache(CACHE_DIR, 'avatars', binary=True) + self.avatar_cache = FileSystemPerJidCache( + CACHE_DIR, 'avatars', binary=True) # a unique buffer used to store global information # that are displayed in almost all tabs, in an # information window. @@ -93,8 +95,7 @@ class Core(object): self.xml_tab = None self.xml_buffer = TextBuffer() - self.tabs = [] - self._current_tab_nb = 0 + self.tabs = Tabs() self.previous_tab_nb = 0 own_nick = config.get('default_nick') @@ -397,8 +398,7 @@ class Core(object): Called when the option create_gaps is changed. Remove all gaptabs if switching from gaps to nogaps. """ - if value.lower() == "false": - self.tabs = [tab for tab in self.tabs if tab] + self.tabs.update_gaps(value.lower() == "false") def on_request_receipts_config_change(self, option, value): """ @@ -662,7 +662,7 @@ class Core(object): except ValueError: pass else: - if self.current_tab().nb == nb and config.get( + if self.tabs.current_tab.nb == nb and config.get( 'go_to_previous_tab_on_alt_number'): self.go_to_previous_tab() else: @@ -687,8 +687,9 @@ class Core(object): ok = ok and config.silent_set('info_win_height', self.information_win_size, 'var') if not ok: - self.information('Unable to save runtime preferences' - ' in the config file', 'Error') + self.information( + 'Unable to save runtime preferences' + ' in the config file', 'Error') def on_roster_enter_key(self, roster_row): """ @@ -715,9 +716,9 @@ class Core(object): Messages are namedtuples of the form ('txt nick_color time str_time nickname user') """ - if not isinstance(self.current_tab(), tabs.ChatTab): + if not isinstance(self.tabs.current_tab, tabs.ChatTab): return None - return self.current_tab().get_conversation_messages() + return self.tabs.current_tab.get_conversation_messages() def insert_input_text(self, text): """ @@ -784,8 +785,9 @@ class Core(object): 'Could not open the fifo for writing (%s)', os.path.join(fifo_path, './', 'poezio.fifo'), exc_info=True) - self.information('Could not open the fifo ' - 'file for writing: %s' % exc, 'Error') + self.information( + 'Could not open the fifo ' + 'file for writing: %s' % exc, 'Error') return args = (pipes.quote(arg.replace('\n', ' ')) for arg in command) @@ -829,7 +831,7 @@ class Core(object): keyboard.continuation_keys_callback = None cb(key) else: - self.current_tab().on_input(key, raw) + self.tabs.current_tab.on_input(key, raw) def try_execute(self, line): """ @@ -837,7 +839,7 @@ class Core(object): """ line = '/' + line try: - self.current_tab().execute_command(line) + self.tabs.current_tab.execute_command(line) except: log.error('Execute failed (%s)', line, exc_info=True) @@ -872,8 +874,9 @@ class Core(object): msg = msg.replace('\n', '|') if msg else '' ok = ok and config.silent_set('status_message', msg) if not ok: - self.information('Unable to save the status in ' - 'the config file', 'Error') + self.information( + 'Unable to save the status in ' + 'the config file', 'Error') def get_bookmark_nickname(self, room_name): """ @@ -909,9 +912,9 @@ class Core(object): conversation. Returns False if the current tab is not a conversation tab """ - if not isinstance(self.current_tab(), tabs.ChatTab): + if not isinstance(self.tabs.current_tab, tabs.ChatTab): return False - self.current_tab().command_say(msg) + self.tabs.current_tab.command_say(msg) return True def invite(self, jid, room, reason=None): @@ -977,15 +980,8 @@ class Core(object): def get_tabs(self, cls=None): "Get all the tabs of a type" if cls is None: - cls = tabs.Tab - return [tab for tab in self.tabs if isinstance(tab, cls)] - - def current_tab(self): - """ - returns the current room, the one we are viewing - """ - self.current_tab_nb = self.current_tab_nb - return self.tabs[self.current_tab_nb] + return self.tabs.get_tabs() + return self.tabs.by_class(cls) def get_conversation_by_jid(self, jid, create=True, fallback_barejid=True): """ @@ -999,16 +995,16 @@ class Core(object): jid = safeJID(jid) # We first check if we have a static conversation opened # with this precise resource - conversation = self.get_tab_by_name(jid.full, - tabs.StaticConversationTab) + conversation = self.tabs.by_name_and_class(jid.full, + tabs.StaticConversationTab) if jid.bare == jid.full and not conversation: - conversation = self.get_tab_by_name(jid.full, - tabs.DynamicConversationTab) + conversation = self.tabs.by_name_and_class( + jid.full, tabs.DynamicConversationTab) if not conversation and fallback_barejid: # If not, we search for a conversation with the bare jid - conversation = self.get_tab_by_name(jid.bare, - tabs.DynamicConversationTab) + conversation = self.tabs.by_name_and_class( + jid.bare, tabs.DynamicConversationTab) if not conversation: if create: # We create a dynamic conversation with the bare Jid if @@ -1020,23 +1016,6 @@ class Core(object): conversation = None return conversation - def get_tab_by_name(self, name, typ=None): - """ - Get the tab with the given name. - If typ is provided, return a tab of this type only - """ - for tab in self.tabs: - if tab.name == name: - if (typ and isinstance(tab, typ)) or\ - not typ: - return tab - return None - - def get_tab_by_number(self, number): - if 0 <= number < len(self.tabs): - return self.tabs[number] - return None - def add_tab(self, new_tab, focus=False): """ Appends the new_tab in the tab list and @@ -1046,82 +1025,12 @@ class Core(object): if focus: self.command.win("%s" % new_tab.nb) - def insert_tab_nogaps(self, old_pos, new_pos): - """ - Move tabs without creating gaps - old_pos: old position of the tab - new_pos: desired position of the tab - """ - tab = self.tabs[old_pos] - if new_pos < old_pos: - self.tabs.pop(old_pos) - self.tabs.insert(new_pos, tab) - elif new_pos > old_pos: - self.tabs.insert(new_pos, tab) - self.tabs.remove(tab) - else: - return False - return True - - def insert_tab_gaps(self, old_pos, new_pos): - """ - Move tabs and create gaps in the eventual remaining space - old_pos: old position of the tab - new_pos: desired position of the tab - """ - tab = self.tabs[old_pos] - target = None if new_pos >= len(self.tabs) else self.tabs[new_pos] - if not target: - if new_pos < len(self.tabs): - old_tab = self.tabs[old_pos] - self.tabs[new_pos], self.tabs[old_pos] = old_tab, tabs.GapTab( - self) - else: - self.tabs.append(self.tabs[old_pos]) - self.tabs[old_pos] = tabs.GapTab(self) - else: - if new_pos > old_pos: - self.tabs.insert(new_pos, tab) - self.tabs[old_pos] = tabs.GapTab(self) - elif new_pos < old_pos: - self.tabs[old_pos] = tabs.GapTab(self) - self.tabs.insert(new_pos, tab) - else: - return False - i = self.tabs.index(tab) - done = False - # Remove the first Gap on the right in the list - # in order to prevent global shifts when there is empty space - while not done: - i += 1 - if i >= len(self.tabs): - done = True - elif not self.tabs[i]: - self.tabs.pop(i) - done = True - # Remove the trailing gaps - i = len(self.tabs) - 1 - while isinstance(self.tabs[i], tabs.GapTab): - self.tabs.pop() - i -= 1 - return True - def insert_tab(self, old_pos, new_pos=99999): """ Insert a tab at a position, changing the number of the following tabs returns False if it could not move the tab, True otherwise """ - if old_pos <= 0 or old_pos >= len(self.tabs): - return False - elif new_pos <= 0: - return False - elif new_pos == old_pos: - return False - elif not self.tabs[old_pos]: - return False - if config.get('create_gaps'): - return self.insert_tab_gaps(old_pos, new_pos) - return self.insert_tab_nogaps(old_pos, new_pos) + self.tabs.insert_tab(old_pos, new_pos, config.get('create_gaps')) ### Move actions (e.g. go to next room) ### @@ -1129,22 +1038,18 @@ class Core(object): """ rotate the rooms list to the right """ - self.current_tab().on_lose_focus() - self.current_tab_nb += 1 - while not self.tabs[self.current_tab_nb]: - self.current_tab_nb += 1 - self.current_tab().on_gain_focus() + self.tabs.current_tab.on_lose_focus() + self.tabs.next() + self.tabs.current_tab.on_gain_focus() self.refresh_window() def rotate_rooms_left(self, args=None): """ rotate the rooms list to the right """ - self.current_tab().on_lose_focus() - self.current_tab_nb -= 1 - while not self.tabs[self.current_tab_nb]: - self.current_tab_nb -= 1 - self.current_tab().on_gain_focus() + self.tabs.current_tab.on_lose_focus() + self.tabs.prev() + self.tabs.current_tab.on_gain_focus() self.refresh_window() def go_to_room_number(self): @@ -1190,7 +1095,7 @@ class Core(object): priority = tabs.STATE_PRIORITY tab_refs = {} # put all the active tabs in a dict of lists by state - for tab in self.tabs: + for tab in self.tabs.get_tabs(): if not tab: continue if tab.state not in tab_refs: @@ -1204,8 +1109,8 @@ class Core(object): for state in states: for tab in tab_refs[state]: - if (tab.nb < self.current_tab_nb - and tab_refs[state][-1].nb > self.current_tab_nb): + if (tab.nb < self.tabs.current_tab_intex and + tab_refs[state][-1].nb > self.tabs.current_tab_index): continue self.command.win(str(tab.nb)) return @@ -1213,33 +1118,14 @@ class Core(object): def focus_tab_named(self, tab_name, type_=None): """Returns True if it found a tab to focus on""" - for tab in self.tabs: - if tab.name == tab_name: - if (type_ and (isinstance(tab, type_))) or not type_: - self.command.win(str(tab.nb)) - return True - return False - - @property - def current_tab_nb(self): - """Wrapper for the current tab number""" - return self._current_tab_nb - - @current_tab_nb.setter - def current_tab_nb(self, value): - """ - Prevents the tab number from going over the total number of opened - tabs, or under 0 - """ - old = self._current_tab_nb - if value >= len(self.tabs): - self._current_tab_nb = 0 - elif value < 0: - self._current_tab_nb = len(self.tabs) - 1 + if type_ is None: + tab = self.tabs.by_name(tab_name) else: - self._current_tab_nb = value - if old != self._current_tab_nb and self.tabs[self._current_tab_nb]: - self.events.trigger('tab_change', old, self._current_tab_nb) + tab = self.tabs.by_name_and_class(tab_name, type_) + if tab: + self.command_win(str(tab.nb)) + return True + return False ### Opening actions ### @@ -1270,7 +1156,7 @@ class Core(object): self.command.win(str(tab.nb)) return tab # create the new tab - tab = self.get_tab_by_name(room_name, tabs.MucTab) + tab = self.tabs.by_name_and_class(room_name, tabs.MucTab) if not tab: return None new_tab = tabs.PrivateTab(self, complete_jid, tab.own_nick) @@ -1310,8 +1196,8 @@ class Core(object): this updates the name of all the opened private conversations with him/her """ - tab = self.get_tab_by_name('%s/%s' % (room_name, old_nick), - tabs.PrivateTab) + tab = self.tabs.by_name_and_class('%s/%s' % (room_name, old_nick), + tabs.PrivateTab) if tab: tab.rename_user(old_nick, user) @@ -1321,8 +1207,8 @@ class Core(object): The user left the MUC: add a message in the associated private conversation """ - tab = self.get_tab_by_name('%s/%s' % (room_name, user.nick), - tabs.PrivateTab) + tab = self.tabs.by_name_and_class('%s/%s' % (room_name, user.nick), + tabs.PrivateTab) if tab: tab.user_left(status_message, user) @@ -1331,8 +1217,8 @@ class Core(object): The user joined a MUC: add a message in the associated private conversation """ - tab = self.get_tab_by_name('%s/%s' % (room_name, nick), - tabs.PrivateTab) + tab = self.tabs.by_name_and_class('%s/%s' % (room_name, nick), + tabs.PrivateTab) if tab: tab.user_rejoined(nick) @@ -1357,7 +1243,7 @@ class Core(object): tab.activate(reason=reason) def on_user_changed_status_in_private(self, jid, status): - tab = self.get_tab_by_name(jid, tabs.ChatTab) + tab = self.tabs.by_name_and_class(jid, tabs.ChatTab) if tab is not None: # display the message in private tab.update_status(status) @@ -1367,35 +1253,16 @@ class Core(object): """ was_current = tab is None if tab is None: - tab = self.current_tab() + tab = self.tabs.current_tab if isinstance(tab, tabs.RosterInfoTab): return # The tab 0 should NEVER be closed tab.on_close() del tab.key_func # Remove self references del tab.commands # and make the object collectable - nb = tab.nb - if was_current: - if self.previous_tab_nb != nb: - self.current_tab_nb = self.previous_tab_nb - self.previous_tab_nb = 0 - if config.get('create_gaps'): - if nb >= len(self.tabs) - 1: - self.tabs.remove(tab) - nb -= 1 - while not self.tabs[nb]: # remove the trailing gaps - self.tabs.pop() - nb -= 1 - else: - self.tabs[nb] = tabs.GapTab(self) - else: - self.tabs.remove(tab) + self.tabs.delete(tab, gap=config.get('create_gaps')) logger.close(tab.name) - if self.current_tab_nb >= len(self.tabs): - self.current_tab_nb = len(self.tabs) - 1 - while not self.tabs[self.current_tab_nb]: - self.current_tab_nb -= 1 if was_current: - self.current_tab().on_gain_focus() + self.tabs.current_tab.on_gain_focus() self.refresh_window() import gc gc.collect() @@ -1408,10 +1275,10 @@ class Core(object): Search for a ConversationTab with the given jid (full or bare), if yes, add the given message to it """ - tab = self.get_tab_by_name(jid, tabs.ConversationTab) + tab = self.tabs.by_name_and_class(jid, tabs.ConversationTab) if tab is not None: tab.add_message(msg, typ=2) - if self.current_tab() is tab: + if self.tabs.current_tab is tab: self.refresh_window() ####################### Curses and ui-related stuff ########################### @@ -1444,7 +1311,7 @@ class Core(object): nb_lines = self.information_buffer.add_message( msg, nickname=typ, nick_color=color) popup_on = config.get('information_buffer_popup_on').split() - if isinstance(self.current_tab(), tabs.RosterInfoTab): + if isinstance(self.tabs.current_tab, tabs.RosterInfoTab): self.refresh_window() elif typ != '' and typ.lower() in popup_on: popup_time = config.get('popup_time') + (nb_lines - 1) * 2 @@ -1452,7 +1319,7 @@ class Core(object): else: if self.information_win_size != 0: self.information_win.refresh() - self.current_tab().refresh_input() + self.tabs.current_tab.refresh_input() return True def _init_curses(self, stdscr): @@ -1486,8 +1353,8 @@ class Core(object): Refresh everything """ nocursor = curses.curs_set(0) - self.current_tab().state = 'current' - self.current_tab().refresh() + self.tabs.current_tab.state = 'current' + self.tabs.current_tab.refresh() self.doupdate() curses.curs_set(nocursor) @@ -1495,7 +1362,7 @@ class Core(object): """ Refresh the window containing the tab list """ - self.current_tab().refresh_tab_win() + self.tabs.current_tab.refresh_tab_win() self.refresh_input() self.doupdate() @@ -1503,8 +1370,8 @@ class Core(object): """ Refresh the input if it exists """ - if self.current_tab().input: - self.current_tab().input.refresh() + if self.tabs.current_tab.input: + self.tabs.current_tab.input.refresh() self.doupdate() def scroll_page_down(self): @@ -1512,7 +1379,7 @@ class Core(object): Scroll a page down, if possible. Returns True on success, None on failure. """ - if self.current_tab().on_scroll_down(): + if self.tabs.current_tab.on_scroll_down(): self.refresh_window() return True @@ -1521,7 +1388,7 @@ class Core(object): Scroll a page up, if possible. Returns True on success, None on failure. """ - if self.current_tab().on_scroll_up(): + if self.tabs.current_tab.on_scroll_up(): self.refresh_window() return True @@ -1530,7 +1397,7 @@ class Core(object): Scroll a line up, if possible. Returns True on success, None on failure. """ - if self.current_tab().on_line_up(): + if self.tabs.current_tab.on_line_up(): self.refresh_window() return True @@ -1539,7 +1406,7 @@ class Core(object): Scroll a line down, if possible. Returns True on success, None on failure. """ - if self.current_tab().on_line_down(): + if self.tabs.current_tab.on_line_down(): self.refresh_window() return True @@ -1548,7 +1415,7 @@ class Core(object): Scroll half a screen down, if possible. Returns True on success, None on failure. """ - if self.current_tab().on_half_scroll_up(): + if self.tabs.current_tab.on_half_scroll_up(): self.refresh_window() return True @@ -1557,7 +1424,7 @@ class Core(object): Scroll half a screen down, if possible. Returns True on success, None on failure. """ - if self.current_tab().on_half_scroll_down(): + if self.tabs.current_tab.on_half_scroll_down(): self.refresh_window() return True @@ -1565,8 +1432,8 @@ class Core(object): """ Expand the information win a number of lines """ - if self.information_win_size >= self.current_tab().height -5 or \ - self.information_win_size+nb >= self.current_tab().height-4 or\ + if self.information_win_size >= self.tabs.current_tab.height -5 or \ + self.information_win_size+nb >= self.tabs.current_tab.height-4 or\ self.size.core_degrade_y: return 0 self.information_win_size += nb @@ -1595,10 +1462,10 @@ class Core(object): Scroll the information buffer up """ self.information_win.scroll_up(self.information_win.height) - if not isinstance(self.current_tab(), tabs.RosterInfoTab): + if not isinstance(self.tabs.current_tab, tabs.RosterInfoTab): self.information_win.refresh() else: - info = self.current_tab().information_win + info = self.tabs.current_tab.information_win info.scroll_up(info.height) self.refresh_window() @@ -1607,10 +1474,10 @@ class Core(object): Scroll the information buffer down """ self.information_win.scroll_down(self.information_win.height) - if not isinstance(self.current_tab(), tabs.RosterInfoTab): + if not isinstance(self.tabs.current_tab, tabs.RosterInfoTab): self.information_win.refresh() else: - info = self.current_tab().information_win + info = self.tabs.current_tab.information_win info.scroll_down(info.height) self.refresh_window() @@ -1717,7 +1584,8 @@ class Core(object): tab.need_resize = True else: tab.resize() - if self.tabs: + + if len(self.tabs): self.full_screen_redraw() def read_keyboard(self): @@ -2057,7 +1925,7 @@ class Core(object): for bm in bookmarks: if not (bm.autojoin or config.get('open_all_bookmarks')): continue - tab = self.get_tab_by_name(bm.jid, tabs.MucTab) + tab = self.tabs.by_name_and_class(bm.jid, tabs.MucTab) nick = bm.nick if bm.nick else self.own_nick if not tab: self.open_new_room( @@ -2085,9 +1953,9 @@ class Core(object): type_ = iq['error']['type'] condition = iq['error']['condition'] if not (type_ == 'cancel' and condition == 'item-not-found'): - self.information('Unable to fetch the remote' - ' bookmarks; %s: %s' % (type_, condition), - 'Error') + self.information( + 'Unable to fetch the remote' + ' bookmarks; %s: %s' % (type_, condition), 'Error') return remote_bookmarks = self.bookmarks.remote() self.join_initial_rooms(remote_bookmarks) @@ -2100,7 +1968,7 @@ class Core(object): """ Display the error in the tab """ - tab = self.get_tab_by_name(room_name, tabs.MucTab) + tab = self.tabs.by_name_and_class(room_name, tabs.MucTab) if not tab: return error_message = self.get_error_message(error) diff --git a/poezio/core/handlers.py b/poezio/core/handlers.py index d34534d0..0f84e69c 100644 --- a/poezio/core/handlers.py +++ b/poezio/core/handlers.py @@ -85,7 +85,8 @@ class HandlerCore: if not iq: return features = iq['disco_info']['features'] - rostertab = self.core.get_tab_by_name('Roster', tabs.RosterInfoTab) + rostertab = self.core.tabs.by_name_and_class( + 'Roster', tabs.RosterInfoTab) rostertab.check_blocking(features) rostertab.check_saslexternal(features) if (config.get('enable_carbons') @@ -138,8 +139,9 @@ class HandlerCore: sent = message['carbon_sent'] # todo: implement proper MUC detection logic - if (sent['to'].resource and (sent['to'].bare not in roster - or roster[sent['to'].bare].subscription == 'none')): + if (sent['to'].resource + and (sent['to'].bare not in roster + or roster[sent['to'].bare].subscription == 'none')): fixes.has_identity( self.core.xmpp, sent['to'].server, @@ -243,8 +245,8 @@ class HandlerCore: self.core.room_error(message, jid_from.bare) else: text = self.core.get_error_message(message) - p_tab = self.core.get_tab_by_name(jid_from.full, - tabs.PrivateTab) + p_tab = self.core.tabs.by_name_and_class( + jid_from.full, tabs.PrivateTab) if p_tab: p_tab.add_error(text) else: @@ -372,7 +374,7 @@ class HandlerCore: if not own and 'private' in config.get('beep_on').split(): if not config.get_by_tabname('disable_beep', conv_jid.bare): curses.beep() - if self.core.current_tab() is not conversation: + if self.core.tabs.current_tab is not conversation: if not own: conversation.state = 'private' self.core.refresh_tab_win() @@ -399,7 +401,8 @@ class HandlerCore: avatar_hash = info['id'] # First check whether we have it in cache. - cached_avatar = self.core.avatar_cache.retrieve_by_jid(jid, avatar_hash) + cached_avatar = self.core.avatar_cache.retrieve_by_jid( + jid, avatar_hash) if cached_avatar: contact.avatar = cached_avatar log.debug('Using cached avatar for %s', jid) @@ -425,7 +428,8 @@ class HandlerCore: log.debug('Received %s avatar: %s', jid, info['type']) # Now we save the data on the file system to not have to request it again. - if not self.core.avatar_cache.store_by_jid(jid, avatar_hash, contact.avatar): + if not self.core.avatar_cache.store_by_jid( + jid, avatar_hash, contact.avatar): log.debug( 'Failed writing %s’s avatar to cache:', jid, @@ -442,7 +446,8 @@ class HandlerCore: log.debug('Received vCard avatar update from %s: %s', jid, avatar_hash) # First check whether we have it in cache. - cached_avatar = self.core.avatar_cache.retrieve_by_jid(jid, avatar_hash) + cached_avatar = self.core.avatar_cache.retrieve_by_jid( + jid, avatar_hash) if cached_avatar: contact.avatar = cached_avatar log.debug('Using cached avatar for %s', jid) @@ -463,8 +468,10 @@ class HandlerCore: log.debug('Received %s avatar: %s', jid, avatar['TYPE']) # Now we save the data on the file system to not have to request it again. - if not self.core.avatar_cache.store_by_jid(jid, avatar_hash, contact.avatar): - log.debug('Failed writing %s’s avatar to cache:', jid, exc_info=True) + if not self.core.avatar_cache.store_by_jid(jid, avatar_hash, + contact.avatar): + log.debug( + 'Failed writing %s’s avatar to cache:', jid, exc_info=True) def on_nick_received(self, message): """ @@ -514,9 +521,9 @@ class HandlerCore: 'display_gaming_notifications', contact.bare_jid): if contact.gaming: self.core.information( - '%s is playing %s' % - (contact.bare_jid, - common.format_gaming_string(contact.gaming)), 'Gaming') + '%s is playing %s' % (contact.bare_jid, + common.format_gaming_string( + contact.gaming)), 'Gaming') else: self.core.information(contact.bare_jid + ' stopped playing.', 'Gaming') @@ -597,8 +604,9 @@ class HandlerCore: if old_activity != contact.activity and config.get_by_tabname( 'display_activity_notifications', contact.bare_jid): if contact.activity: - self.core.information('Activity from ' + contact.bare_jid + - ': ' + contact.activity, 'Activity') + self.core.information( + 'Activity from ' + contact.bare_jid + ': ' + + contact.activity, 'Activity') else: self.core.information( contact.bare_jid + ' stopped doing his/her activity.', @@ -630,9 +638,9 @@ class HandlerCore: contact.tune = {} if contact.tune: - logger.log_roster_change(message['from'].bare, - 'is now listening to %s' % - common.format_tune_string(contact.tune)) + logger.log_roster_change( + message['from'].bare, 'is now listening to %s' % + common.format_tune_string(contact.tune)) if old_tune != contact.tune and config.get_by_tabname( 'display_tune_notifications', contact.bare_jid): @@ -656,7 +664,7 @@ class HandlerCore: self.core.room_error(message, room_from) return - tab = self.core.get_tab_by_name(room_from, tabs.MucTab) + tab = self.core.tabs.by_name_and_class(room_from, tabs.MucTab) if not tab: self.core.information( "message received for a non-existing room: %s" % (room_from)) @@ -714,14 +722,14 @@ class HandlerCore: if message['from'].resource == tab.own_nick: tab.last_sent_message = message - if tab is self.core.current_tab(): + if tab is self.core.tabs.current_tab: tab.text_win.refresh() tab.info_header.refresh(tab, tab.text_win, user=tab.own_user) tab.input.refresh() self.core.doupdate() elif tab.state != old_state: self.core.refresh_tab_win() - current = self.core.current_tab() + current = self.core.tabs.current_tab if hasattr(current, 'input') and current.input: current.input.refresh() self.core.doupdate() @@ -756,7 +764,7 @@ class HandlerCore: use_xhtml=use_xhtml, tmp_dir=tmp_dir, extract_images=extract_images) - tab = self.core.get_tab_by_name( + tab = self.core.tabs.by_name_and_class( jid.full, tabs.PrivateTab) # get the tab with the private conversation ignore = config.get_by_tabname('ignore_private', room_from) @@ -764,7 +772,8 @@ class HandlerCore: if body and not ignore: tab = self.core.open_private_window(room_from, with_nick, False) - sender_nick = (tab.own_nick or self.core.own_nick) if sent else with_nick + sender_nick = (tab.own_nick + or self.core.own_nick) if sent else with_nick if ignore and not sent: self.core.events.trigger('ignored_private', message, tab) msg = config.get_by_tabname('private_auto_response', room_from) @@ -815,7 +824,7 @@ class HandlerCore: if not sent and 'private' in config.get('beep_on').split(): if not config.get_by_tabname('disable_beep', jid.full): curses.beep() - if tab is self.core.current_tab(): + if tab is self.core.tabs.current_tab: self.core.refresh_window() else: tab.state = 'normal' if sent else 'private' @@ -841,8 +850,8 @@ class HandlerCore: def _on_chatstate(self, message, state): if message['type'] == 'chat': if not self._on_chatstate_normal_conversation(message, state): - tab = self.core.get_tab_by_name(message['from'].full, - tabs.PrivateTab) + tab = self.core.tabs.by_name_and_class(message['from'].full, + tabs.PrivateTab) if not tab: return self._on_chatstate_private_conversation(message, state) @@ -857,7 +866,7 @@ class HandlerCore: tab.chatstate = state if state == 'gone' and isinstance(tab, tabs.DynamicConversationTab): tab.unlock() - if tab == self.core.current_tab(): + if tab == self.core.tabs.current_tab: tab.refresh_info_header() self.core.doupdate() else: @@ -869,12 +878,13 @@ class HandlerCore: """ Chatstate received in a private conversation from a MUC """ - tab = self.core.get_tab_by_name(message['from'].full, tabs.PrivateTab) + tab = self.core.tabs.by_name_and_class(message['from'].full, + tabs.PrivateTab) if not tab: return self.core.events.trigger('private_chatstate', message, tab) tab.chatstate = state - if tab == self.core.current_tab(): + if tab == self.core.tabs.current_tab: tab.refresh_info_header() self.core.doupdate() else: @@ -887,11 +897,11 @@ class HandlerCore: """ nick = message['mucnick'] room_from = message.get_mucroom() - tab = self.core.get_tab_by_name(room_from, tabs.MucTab) + tab = self.core.tabs.by_name_and_class(room_from, tabs.MucTab) if tab and tab.get_user_by_name(nick): self.core.events.trigger('muc_chatstate', message, tab) tab.get_user_by_name(nick).chatstate = state - if tab == self.core.current_tab(): + if tab == self.core.tabs.current_tab: if not self.core.size.tab_degrade_x: tab.user_win.refresh(tab.users) tab.input.refresh() @@ -908,15 +918,16 @@ class HandlerCore: if iq['type'] == 'error': error_condition = iq['error']['condition'] error_text = iq['error']['text'] - reply = '%s: %s' % (error_condition, error_text) if error_text else error_condition - return self.core.information('Could not get the software ' - 'version from %s: %s' % (jid, reply), - 'Warning') + reply = '%s: %s' % (error_condition, + error_text) if error_text else error_condition + return self.core.information( + 'Could not get the software ' + 'version from %s: %s' % (jid, reply), 'Warning') res = iq['software_version'] version = '%s is running %s version %s on %s' % ( jid, res.get('name', 'an unknown software'), - res.get('version', 'unknown'), - res.get('os', 'an unknown platform')) + res.get('version', 'unknown'), res.get('os', + 'an unknown platform')) self.core.information(version, 'Info') ### subscription-related handlers ### @@ -937,7 +948,7 @@ class HandlerCore: else: roster.update_contact_groups(jid) roster.update_size() - if isinstance(self.core.current_tab(), tabs.RosterInfoTab): + if isinstance(self.core.tabs.current_tab, tabs.RosterInfoTab): self.core.refresh_window() def on_subscription_request(self, presence): @@ -960,7 +971,7 @@ class HandlerCore: 'tab to accept or reject the query.' % jid, 'Roster') self.core.get_tab_by_number(0).state = 'highlight' roster.modified() - if isinstance(self.core.current_tab(), tabs.RosterInfoTab): + if isinstance(self.core.tabs.current_tab, tabs.RosterInfoTab): self.core.refresh_window() def on_subscription_authorized(self, presence): @@ -975,7 +986,7 @@ class HandlerCore: roster.modified() - if isinstance(self.core.current_tab(), tabs.RosterInfoTab): + if isinstance(self.core.tabs.current_tab, tabs.RosterInfoTab): self.core.refresh_window() def on_subscription_remove(self, presence): @@ -988,7 +999,7 @@ class HandlerCore: self.core.information( '%s does not want to receive your status anymore.' % jid, 'Roster') self.core.get_tab_by_number(0).state = 'highlight' - if isinstance(self.core.current_tab(), tabs.RosterInfoTab): + if isinstance(self.core.tabs.current_tab, tabs.RosterInfoTab): self.core.refresh_window() def on_subscription_removed(self, presence): @@ -1007,7 +1018,7 @@ class HandlerCore: '%s does not want you to receive his/her/its status anymore.' % jid, 'Roster') self.core.get_tab_by_number(0).state = 'highlight' - if isinstance(self.core.current_tab(), tabs.RosterInfoTab): + if isinstance(self.core.tabs.current_tab, tabs.RosterInfoTab): self.core.refresh_window() ### Presence-related handlers ### @@ -1034,9 +1045,9 @@ class HandlerCore: if tab: tab.update_status( Status(show=presence['show'], message=presence['status'])) - if isinstance(self.core.current_tab(), tabs.RosterInfoTab): + if isinstance(self.core.tabs.current_tab, tabs.RosterInfoTab): self.core.refresh_window() - elif self.core.current_tab() == tab: + elif self.core.tabs.current_tab == tab: tab.refresh() self.core.doupdate() @@ -1047,8 +1058,7 @@ class HandlerCore: return roster.modified() contact.error = presence['error']['type'] + ': ' + presence['error']['condition'] - # reset chat states status on presence error - tab = self.core.get_tab_by_name(jid.full, tabs.ConversationTab) + # TODO: reset chat states status on presence error def on_got_offline(self, presence): """ @@ -1076,7 +1086,7 @@ class HandlerCore: self.core.information('\x193}%s \x195}is \x191}offline' % name, 'Roster') roster.modified() - if isinstance(self.core.current_tab(), tabs.RosterInfoTab): + if isinstance(self.core.tabs.current_tab, tabs.RosterInfoTab): self.core.refresh_window() def on_got_online(self, presence): @@ -1116,7 +1126,7 @@ class HandlerCore: "\x193}%s \x195}is \x194}online\x195}" % name, "Roster") self.core.add_information_message_to_conversation_tab( jid.bare, '\x195}%s is \x194}online' % name) - if isinstance(self.core.current_tab(), tabs.RosterInfoTab): + if isinstance(self.core.tabs.current_tab, tabs.RosterInfoTab): self.core.refresh_window() def on_groupchat_presence(self, presence): @@ -1126,7 +1136,7 @@ class HandlerCore: presence information of the concerned user """ from_room = presence['from'].bare - tab = self.core.get_tab_by_name(from_room, tabs.MucTab) + tab = self.core.tabs.by_name_and_class(from_room, tabs.MucTab) if tab: self.core.events.trigger('muc_presence', presence, tab) tab.handle_presence(presence) @@ -1137,8 +1147,8 @@ class HandlerCore: """ We cannot contact the remote server """ - self.core.information("Connection to remote server failed: %s" % - (error, ), 'Error') + self.core.information( + "Connection to remote server failed: %s" % (error, ), 'Error') @asyncio.coroutine def on_disconnected(self, event): @@ -1238,11 +1248,11 @@ class HandlerCore: Those are received when a room configuration change occurs. """ room_from = message['from'] - tab = self.core.get_tab_by_name(room_from, tabs.MucTab) + tab = self.core.tabs.by_name_and_class(room_from, tabs.MucTab) status_codes = { s.attrib['code'] - for s in message.xml.findall('{%s}x/{%s}status' % ( - tabs.NS_MUC_USER, tabs.NS_MUC_USER)) + for s in message.xml.findall('{%s}x/{%s}status' % + (tabs.NS_MUC_USER, tabs.NS_MUC_USER)) } if '101' in status_codes: self.core.information( @@ -1332,7 +1342,7 @@ class HandlerCore: """ nick_from = message['mucnick'] room_from = message.get_mucroom() - tab = self.core.get_tab_by_name(room_from, tabs.MucTab) + tab = self.core.tabs.by_name_and_class(room_from, tabs.MucTab) subject = message['subject'] if subject is None or not tab: return @@ -1353,9 +1363,8 @@ class HandlerCore: after = '' if user: user_col = dump_tuple(user.color) - user_string = '\x19%s}%s\x19%s}%s' % (user_col, nick_from, - fmt['info_col'], - after) + user_string = '\x19%s}%s\x19%s}%s' % ( + user_col, nick_from, fmt['info_col'], after) else: user_string = '\x19%s}%s%s' % (fmt['info_col'], nick_from, after) @@ -1375,8 +1384,8 @@ class HandlerCore: typ=2) tab.topic = subject tab.topic_from = nick_from - if self.core.get_tab_by_name(room_from, - tabs.MucTab) is self.core.current_tab(): + if self.core.tabs.by_name_and_class( + room_from, tabs.MucTab) is self.core.tabs.current_tab: self.core.refresh_window() def on_receipt(self, message): @@ -1388,8 +1397,9 @@ class HandlerCore: if not msg_id: return - conversation = self.core.get_tab_by_name(jid.full, tabs.OneToOneTab) - conversation = conversation or self.core.get_tab_by_name( + conversation = self.core.tabs.by_name_and_class( + jid.full, tabs.OneToOneTab) + conversation = conversation or self.core.tabs.by_name_and_class( jid.bare, tabs.OneToOneTab) if not conversation: log.error("Received ack from non-existing chat tab: %s", jid) @@ -1449,8 +1459,8 @@ class HandlerCore: except: log.debug('', exc_info=True) - if isinstance(self.core.current_tab(), tabs.XMLTab): - self.core.current_tab().refresh() + if isinstance(self.core.tabs.current_tab, tabs.XMLTab): + self.core.tabs.current_tab.refresh() self.core.doupdate() def incoming_stanza(self, stanza): @@ -1476,8 +1486,8 @@ class HandlerCore: nickname=get_theme().CHAR_XML_IN) except: log.debug('', exc_info=True) - if isinstance(self.core.current_tab(), tabs.XMLTab): - self.core.current_tab().refresh() + if isinstance(self.core.tabs.current_tab, tabs.XMLTab): + self.core.tabs.current_tab.refresh() self.core.doupdate() def ssl_invalid_chain(self, tb): diff --git a/poezio/logger.py b/poezio/logger.py index 207af0c3..ebf15f5f 100644 --- a/poezio/logger.py +++ b/poezio/logger.py @@ -241,8 +241,8 @@ class Logger(object): lines = message.split('\n') first_line = lines.pop(0) nb_lines = str(len(lines)).zfill(3) - self._roster_logfile.write('MI %s %s %s %s\n' % - (str_time, nb_lines, jid, first_line)) + self._roster_logfile.write( + 'MI %s %s %s %s\n' % (str_time, nb_lines, jid, first_line)) for line in lines: self._roster_logfile.write(' %s\n' % line) self._roster_logfile.flush() diff --git a/poezio/plugin.py b/poezio/plugin.py index 359f1148..016d3199 100644 --- a/poezio/plugin.py +++ b/poezio/plugin.py @@ -204,7 +204,7 @@ class PluginAPI(object): :returns: The current tab. """ - return self.core.current_tab() + return self.core.tabs.current_tab def get_status(self, _): """ @@ -221,7 +221,7 @@ class PluginAPI(object): :param str line: The command to run. """ - return self.core.current_tab().execute_command(*args, **kwargs) + return self.core.tabs.current_tab.execute_command(*args, **kwargs) def all_tabs(self, _): """ diff --git a/poezio/plugin_manager.py b/poezio/plugin_manager.py index cd13e6d8..242132e6 100644 --- a/poezio/plugin_manager.py +++ b/poezio/plugin_manager.py @@ -92,8 +92,8 @@ class PluginManager(object): except Exception as e: log.error('Error while loading the plugin %s', name, exc_info=True) if notify: - self.core.information('Unable to load the plugin %s: %s' % - (name, e), 'Error') + self.core.information( + 'Unable to load the plugin %s: %s' % (name, e), 'Error') self.unload(name, notify=False) else: if notify: @@ -129,8 +129,8 @@ class PluginManager(object): self.core.information('Plugin %s unloaded' % name, 'Info') except Exception as e: log.debug("Could not unload plugin %s", name, exc_info=True) - self.core.information("Could not unload plugin %s: %s" % - (name, e), 'Error') + self.core.information( + "Could not unload plugin %s: %s" % (name, e), 'Error') def add_command(self, module_name, diff --git a/poezio/tabs/adhoc_commands_list.py b/poezio/tabs/adhoc_commands_list.py index a1b186be..fecfc9e2 100644 --- a/poezio/tabs/adhoc_commands_list.py +++ b/poezio/tabs/adhoc_commands_list.py @@ -58,7 +58,7 @@ class AdhocCommandsListTab(ListTab): for item in get_items()] self.listview.set_lines(items) self.info_header.message = 'Ad-hoc commands of JID %s' % self.name - if self.core.current_tab() is self: + if self.core.tabs.current_tab is self: self.refresh() else: self.state = 'highlight' diff --git a/poezio/tabs/basetabs.py b/poezio/tabs/basetabs.py index 13c54c27..8cca8606 100644 --- a/poezio/tabs/basetabs.py +++ b/poezio/tabs/basetabs.py @@ -92,6 +92,7 @@ class Tab(object): def __init__(self, core): self.core = core + self.nb = 0 if not hasattr(self, 'name'): self.name = self.__class__.__name__ self.input = None @@ -108,13 +109,6 @@ class Tab(object): def size(self): return self.core.size - @property - def nb(self): - for index, tab in enumerate(self.core.tabs): - if tab == self: - return index - return len(self.core.tabs) - @staticmethod def tab_win_height(): """ @@ -293,8 +287,8 @@ class Tab(object): if self.missing_command_callback is not None: error_handled = self.missing_command_callback(low) if not error_handled: - self.core.information("Unknown command (%s)" % - (command), 'Error') + self.core.information( + "Unknown command (%s)" % (command), 'Error') if command in ('correct', 'say'): # hack arg = xhtml.convert_simple_to_full_colors(arg) else: @@ -685,8 +679,9 @@ class ChatTab(Tab): 'paused') self.core.add_timed_event(new_event) self.timed_event_paused = new_event - new_event = timed_events.DelayedEvent(30, self.send_chat_state, - 'inactive' if self.inactive else 'active') + new_event = timed_events.DelayedEvent( + 30, self.send_chat_state, 'inactive' + if self.inactive else 'active') self.core.add_timed_event(new_event) self.timed_event_not_paused = new_event diff --git a/poezio/tabs/bookmarkstab.py b/poezio/tabs/bookmarkstab.py index ceccc99d..1ee623c5 100644 --- a/poezio/tabs/bookmarkstab.py +++ b/poezio/tabs/bookmarkstab.py @@ -25,7 +25,8 @@ class BookmarksTab(Tab): self.new_bookmarks = [] self.removed_bookmarks = [] self.header_win = windows.ColumnHeaderWin( - ('name', 'room@server/nickname', 'password', 'autojoin', 'storage')) + ('name', 'room@server/nickname', 'password', 'autojoin', + 'storage')) self.bookmarks_win = windows.BookmarksWin( self.bookmarks, self.height - 4, self.width, 1, 0) self.help_win = windows.HelpText('Ctrl+Y: save, Ctrl+G: cancel, ' @@ -77,8 +78,9 @@ class BookmarksTab(Tab): if not self.bookmarks[bm.jid]: self.bookmarks.append(bm) else: - self.core.information('Invalid JID for bookmark: %s/%s' % - (bm.jid, bm.nick), 'Error') + self.core.information( + 'Invalid JID for bookmark: %s/%s' % (bm.jid, bm.nick), + 'Error') return for bm in self.removed_bookmarks: diff --git a/poezio/tabs/confirmtab.py b/poezio/tabs/confirmtab.py index 28c26122..545bb761 100644 --- a/poezio/tabs/confirmtab.py +++ b/poezio/tabs/confirmtab.py @@ -106,8 +106,9 @@ class ConfirmTab(Tab): def on_info_win_size_changed(self): if self.core.information_win_size >= self.height - 3: return - self.dialog.resize(self.height - 3 - self.core.information_win_size - - Tab.tab_win_height(), self.width, 1, 0) + self.dialog.resize( + self.height - 3 - self.core.information_win_size - + Tab.tab_win_height(), self.width, 1, 0) self.infowin_bottom.resize( 1, self.width, self.height - 2 - self.core.information_win_size - Tab.tab_win_height(), 0) diff --git a/poezio/tabs/conversationtab.py b/poezio/tabs/conversationtab.py index a8a22b4a..e93fe1e3 100644 --- a/poezio/tabs/conversationtab.py +++ b/poezio/tabs/conversationtab.py @@ -376,8 +376,9 @@ class ConversationTab(OneToOneTab): def on_info_win_size_changed(self): if self.core.information_win_size >= self.height - 3: return - self.text_win.resize(self.height - 3 - self.core.information_win_size - - Tab.tab_win_height(), self.width, 1, 0) + self.text_win.resize( + self.height - 3 - self.core.information_win_size - + Tab.tab_win_height(), self.width, 1, 0) self.get_info_header().resize( 1, self.width, self.height - 2 - self.core.information_win_size - Tab.tab_win_height(), 0) diff --git a/poezio/tabs/listtab.py b/poezio/tabs/listtab.py index 84dcc38b..1c96f778 100644 --- a/poezio/tabs/listtab.py +++ b/poezio/tabs/listtab.py @@ -173,8 +173,9 @@ class ListTab(Tab): self.info_header.resize( 1, self.width, self.height - 2 - self.core.information_win_size - Tab.tab_win_height(), 0) - self.listview.resize(self.height - 3 - self.core.information_win_size - - Tab.tab_win_height(), self.width, 1, 0) + self.listview.resize( + self.height - 3 - self.core.information_win_size - + Tab.tab_win_height(), self.width, 1, 0) def on_lose_focus(self): self.state = 'normal' diff --git a/poezio/tabs/muclisttab.py b/poezio/tabs/muclisttab.py index e12d24ee..6ba7816d 100644 --- a/poezio/tabs/muclisttab.py +++ b/poezio/tabs/muclisttab.py @@ -59,7 +59,7 @@ class MucListTab(ListTab): 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: + if self.core.tabs.current_tab is self: self.refresh() else: self.state = 'highlight' diff --git a/poezio/tabs/muctab.py b/poezio/tabs/muctab.py index 70d66ffb..246606e3 100644 --- a/poezio/tabs/muctab.py +++ b/poezio/tabs/muctab.py @@ -193,9 +193,9 @@ class MucTab(ChatTab): valid_affiliations = ('outcast', 'none', 'member', 'admin', 'owner') if affiliation not in valid_affiliations: - return self.core.information('The affiliation must be one of ' + - ', '.join(valid_affiliations), - 'Error') + return self.core.information( + 'The affiliation must be one of ' + + ', '.join(valid_affiliations), 'Error') if nick_or_jid in [user.nick for user in self.users]: muc.set_user_affiliation( self.core.xmpp, @@ -220,8 +220,9 @@ class MucTab(ChatTab): def callback(iq): if iq['type'] == 'error': - self.core.information("Could not set role '%s' for '%s'." % - (role, nick), "Warning") + self.core.information( + "Could not set role '%s' for '%s'." % (role, nick), + "Warning") valid_roles = ('none', 'visitor', 'participant', 'moderator') @@ -281,10 +282,8 @@ class MucTab(ChatTab): user = self.get_user_by_name(self.topic_from) if user: user_text = dump_tuple(user.color) - user_string = '\x19%s}(set by \x19%s}%s\x19%s})' % (info_text, - user_text, - user.nick, - info_text) + user_string = '\x19%s}(set by \x19%s}%s\x19%s})' % ( + info_text, user_text, user.nick, info_text) else: user_string = self.topic_from else: @@ -430,7 +429,7 @@ class MucTab(ChatTab): self.handle_presence_joined(presence, status_codes) except PresenceError: self.core.room_error(presence, presence['from'].bare) - if self.core.current_tab() is self: + if self.core.tabs.current_tab is self: self.text_win.refresh() self.user_win.refresh_if_changed(self.users) self.info_header.refresh(self, self.text_win, user=self.own_user) @@ -454,9 +453,9 @@ class MucTab(ChatTab): # Enable the self ping event, to regularly check if we # are still in the room. self.enable_self_ping_event() - if self.core.current_tab() is not self: + if self.core.tabs.current_tab is not self: self.refresh_tab_win() - self.core.current_tab().refresh_input() + self.core.tabs.current_tab.refresh_input() self.core.doupdate() def handle_presence_unjoined(self, presence, deterministic, own=False): @@ -488,9 +487,9 @@ class MucTab(ChatTab): if self.name in self.core.initial_joins: self.core.initial_joins.remove(self.name) self._state = 'normal' - elif self != self.core.current_tab(): + elif self != self.core.tabs.current_tab: self._state = 'joined' - if (self.core.current_tab() is self + if (self.core.tabs.current_tab is self and self.core.status.show not in ('xa', 'away')): self.send_chat_state('active') new_user.color = get_theme().COLOR_OWN_NICK @@ -650,8 +649,8 @@ class MucTab(ChatTab): self.core.on_user_rejoined_private_conversation(self.name, from_nick) def on_user_nick_change(self, presence, user, from_nick, from_room): - new_nick = presence.xml.find('{%s}x/{%s}item' % - (NS_MUC_USER, NS_MUC_USER)).attrib['nick'] + new_nick = presence.xml.find( + '{%s}x/{%s}item' % (NS_MUC_USER, NS_MUC_USER)).attrib['nick'] old_color = user.color if user.nick == self.own_nick: self.own_nick = new_nick @@ -722,7 +721,7 @@ class MucTab(ChatTab): self.core.disable_private_tabs(self.name, reason=kick_msg) self.disconnect() self.refresh_tab_win() - self.core.current_tab().refresh_input() + self.core.tabs.current_tab.refresh_input() if config.get_by_tabname('autorejoin', self.general_jid): delay = config.get_by_tabname('autorejoin_delay', self.general_jid) @@ -800,7 +799,7 @@ class MucTab(ChatTab): self.core.disable_private_tabs(self.name, reason=kick_msg) self.disconnect() self.refresh_tab_win() - self.core.current_tab().refresh_input() + self.core.tabs.current_tab.refresh_input() # try to auto-rejoin if config.get_by_tabname('autorejoin', self.general_jid): delay = config.get_by_tabname('autorejoin_delay', @@ -959,9 +958,8 @@ class MucTab(ChatTab): role != user.role): # display the message in the room self._text_buffer.add_message(msg) - self.core.on_user_changed_status_in_private('%s/%s' % (from_room, - from_nick), - Status(show, status)) + self.core.on_user_changed_status_in_private( + '%s/%s' % (from_room, from_nick), Status(show, status)) self.users.remove(user) # finally, effectively change the user status user.update(affiliation, show, status, role) @@ -974,7 +972,7 @@ class MucTab(ChatTab): """ self.presence_buffer = [] self.users = [] - if self is not self.core.current_tab(): + if self is not self.core.tabs.current_tab: self.state = 'disconnected' self.joined = False self.disable_self_ping_event() @@ -1178,8 +1176,9 @@ class MucTab(ChatTab): info_win_height = self.core.information_win_size self.user_win.resize( - self.height - 3 - info_win_height - tab_win_height, self.width - - (self.width // 10) * 9 - 1, 1, (self.width // 10) * 9 + 1) + self.height - 3 - info_win_height - tab_win_height, + self.width - (self.width // 10) * 9 - 1, 1, + (self.width // 10) * 9 + 1) self.v_separator.resize( self.height - 3 - info_win_height - tab_win_height, 1, 1, 9 * (self.width // 10)) @@ -1223,15 +1222,16 @@ class MucTab(ChatTab): text_width = self.width else: text_width = (self.width // 10) * 9 - self.user_win.resize(self.height - 3 - self.core.information_win_size - - Tab.tab_win_height(), - self.width - (self.width // 10) * 9 - 1, 1, - (self.width // 10) * 9 + 1) + self.user_win.resize( + self.height - 3 - self.core.information_win_size - + Tab.tab_win_height(), self.width - (self.width // 10) * 9 - 1, 1, + (self.width // 10) * 9 + 1) self.v_separator.resize( self.height - 3 - self.core.information_win_size - Tab.tab_win_height(), 1, 1, 9 * (self.width // 10)) - self.text_win.resize(self.height - 3 - self.core.information_win_size - - Tab.tab_win_height(), text_width, 1, 0) + self.text_win.resize( + self.height - 3 - self.core.information_win_size - + Tab.tab_win_height(), text_width, 1, 0) self.info_header.resize( 1, self.width, self.height - 2 - self.core.information_win_size - Tab.tab_win_height(), 0) @@ -1329,8 +1329,9 @@ class MucTab(ChatTab): nick = args[0] color = args[1].lower() if nick == self.own_nick: - return self.core.information("You cannot change the color of your" - " own nick.", 'Error') + return self.core.information( + "You cannot change the color of your" + " own nick.", 'Error') elif color not in xhtml.colors and color not in ('unset', 'random'): return self.core.information("Unknown color: %s" % color, 'Error') self.set_nick_color(nick, color) @@ -1375,7 +1376,7 @@ class MucTab(ChatTab): """ message = args[0] self.leave_room(message) - if self == self.core.current_tab(): + if self == self.core.tabs.current_tab: self.refresh() self.core.doupdate() @@ -1405,7 +1406,7 @@ class MucTab(ChatTab): r = self.core.open_private_window(self.name, user.nick) if r and len(args) == 2: msg = args[1] - self.core.current_tab().command_say( + self.core.tabs.current_tab.command_say( xhtml.convert_simple_to_full_colors(msg)) if not r: self.core.information("Cannot find user: %s" % nick, 'Error') @@ -1446,9 +1447,9 @@ class MucTab(ChatTab): affiliation = aff.get(user.affiliation, get_theme().CHAR_AFFILIATION_NONE) color = colors.get(user.role, color_other) - buff.append('\x19%s}%s\x19o\x19%s}%s\x19o' % - (color, affiliation, dump_tuple(user.color), - user.nick)) + buff.append( + '\x19%s}%s\x19o\x19%s}%s\x19o' % + (color, affiliation, dump_tuple(user.color), user.nick)) buff.append('\n') message = ' '.join(buff) diff --git a/poezio/tabs/privatetab.py b/poezio/tabs/privatetab.py index d0a12232..bc7f31c7 100644 --- a/poezio/tabs/privatetab.py +++ b/poezio/tabs/privatetab.py @@ -60,7 +60,8 @@ class PrivateTab(OneToOneTab): 'Get the software version of the current interlocutor (usually its XMPP client and Operating System).', shortdesc='Get the software version of a jid.') self.resize() - self.parent_muc = self.core.get_tab_by_name(safeJID(name).bare, MucTab) + self.parent_muc = self.core.tabs.by_name_and_class( + safeJID(name).bare, MucTab) self.on = True self.update_commands() self.update_keys() @@ -275,7 +276,7 @@ class PrivateTab(OneToOneTab): empty_after = self.input.get_text() == '' or ( self.input.get_text().startswith('/') and not self.input.get_text().startswith('//')) - tab = self.core.get_tab_by_name(safeJID(self.name).bare, MucTab) + tab = self.core.tabs.by_name_and_class(safeJID(self.name).bare, MucTab) if tab and tab.joined: self.send_composing_chat_state(empty_after) return False @@ -288,7 +289,7 @@ class PrivateTab(OneToOneTab): self.text_win.remove_line_separator() self.text_win.add_line_separator(self._text_buffer) - tab = self.core.get_tab_by_name(safeJID(self.name).bare, MucTab) + tab = self.core.tabs.by_name_and_class(safeJID(self.name).bare, MucTab) if tab and tab.joined and config.get_by_tabname( 'send_chat_states', self.general_jid) and self.on: self.send_chat_state('inactive') @@ -297,7 +298,7 @@ class PrivateTab(OneToOneTab): def on_gain_focus(self): self.state = 'current' curses.curs_set(1) - tab = self.core.get_tab_by_name(safeJID(self.name).bare, MucTab) + tab = self.core.tabs.by_name_and_class(safeJID(self.name).bare, MucTab) if tab and tab.joined and config.get_by_tabname( 'send_chat_states', self.general_jid, @@ -307,8 +308,9 @@ class PrivateTab(OneToOneTab): def on_info_win_size_changed(self): if self.core.information_win_size >= self.height - 3: return - self.text_win.resize(self.height - 2 - self.core.information_win_size - - Tab.tab_win_height(), self.width, 0, 0) + self.text_win.resize( + self.height - 2 - self.core.information_win_size - + Tab.tab_win_height(), self.width, 0, 0) self.info_header.resize( 1, self.width, self.height - 2 - self.core.information_win_size - Tab.tab_win_height(), 0) @@ -333,7 +335,7 @@ class PrivateTab(OneToOneTab): typ=2) new_jid = safeJID(self.name).bare + '/' + user.nick self.name = new_jid - return self.core.current_tab() is self + return self.core.tabs.current_tab is self @refresh_wrapper.conditional def user_left(self, status_message, user): @@ -371,7 +373,7 @@ class PrivateTab(OneToOneTab): 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT) }, typ=2) - return self.core.current_tab() is self + return self.core.tabs.current_tab is self @refresh_wrapper.conditional def user_rejoined(self, nick): @@ -397,7 +399,7 @@ class PrivateTab(OneToOneTab): 'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT) }, typ=2) - return self.core.current_tab() is self + return self.core.tabs.current_tab is self def activate(self, reason=None): self.on = True diff --git a/poezio/tabs/rostertab.py b/poezio/tabs/rostertab.py index c079d550..5e10cb52 100644 --- a/poezio/tabs/rostertab.py +++ b/poezio/tabs/rostertab.py @@ -271,8 +271,9 @@ class RosterInfoTab(Tab): if not certs: return self.core.information('No certificates found', 'Info') msg = 'Certificates:\n' - msg += '\n'.join(((' %s%s' % (item[0] + (': ' if item[1] else ''), - item[1])) for item in certs)) + msg += '\n'.join( + ((' %s%s' % (item[0] + (': ' if item[1] else ''), item[1])) + for item in certs)) self.core.information(msg, 'Info') self.core.xmpp.plugin['xep_0257'].get_certs(callback=cb, timeout=3) @@ -702,8 +703,8 @@ class RosterInfoTab(Tab): return jid = safeJID(safeJID(args[0]).bare) if not str(jid): - self.core.information('The provided JID (%s) is not valid' % - (args[0], ), 'Error') + self.core.information( + 'The provided JID (%s) is not valid' % (args[0], ), 'Error') return if jid in roster and roster[jid].subscription in ('to', 'both'): return self.core.information('Already subscribed.', 'Roster') @@ -1146,7 +1147,7 @@ class RosterInfoTab(Tab): def reset_help_message(self, _=None): self.input = self.default_help_message - if self.core.current_tab() is self: + if self.core.tabs.current_tab is self: curses.curs_set(0) self.input.refresh() self.core.doupdate() @@ -1266,8 +1267,9 @@ class RosterInfoTab(Tab): acc.append('Contact: %s (%s)' % (cont.bare_jid, res.presence if res else 'unavailable')) if res: - acc.append('%s connected resource%s' % - (len(cont), '' if len(cont) == 1 else 's')) + acc.append( + '%s connected resource%s' % (len(cont), '' + if len(cont) == 1 else 's')) acc.append('Current status: %s' % res.status) if cont.tune: acc.append('Tune: %s' % common.format_tune_string(cont.tune)) @@ -1276,8 +1278,8 @@ class RosterInfoTab(Tab): if cont.activity: acc.append('Activity: %s' % cont.activity) if cont.gaming: - acc.append('Game: %s' % - (common.format_gaming_string(cont.gaming))) + acc.append( + 'Game: %s' % (common.format_gaming_string(cont.gaming))) msg = '\n'.join(acc) elif isinstance(selected_row, Resource): res = selected_row diff --git a/poezio/tabs/xmltab.py b/poezio/tabs/xmltab.py index 223b6667..af091f68 100644 --- a/poezio/tabs/xmltab.py +++ b/poezio/tabs/xmltab.py @@ -261,8 +261,9 @@ class XMLTab(Tab): xml = self.filtered_buffer.messages[:] else: xml = self.core_buffer.messages[:] - text = '\n'.join(('%s %s %s' % (msg.str_time, msg.nickname, - clean_text(msg.txt)) for msg in xml)) + text = '\n'.join( + ('%s %s %s' % (msg.str_time, msg.nickname, clean_text(msg.txt)) + for msg in xml)) filename = os.path.expandvars(os.path.expanduser(args[0])) try: with open(filename, 'w') as fd: @@ -285,7 +286,7 @@ class XMLTab(Tab): def reset_help_message(self, _=None): if self.closed: return True - if self.core.current_tab() is self: + if self.core.tabs.current_tab is self: curses.curs_set(0) self.input = self.default_help_message return True @@ -375,8 +376,9 @@ class XMLTab(Tab): def on_info_win_size_changed(self): if self.core.information_win_size >= self.height - 3: return - self.text_win.resize(self.height - 2 - self.core.information_win_size - - Tab.tab_win_height(), self.width, 0, 0) + self.text_win.resize( + self.height - 2 - self.core.information_win_size - + Tab.tab_win_height(), self.width, 0, 0) self.info_header.resize( 1, self.width, self.height - 2 - self.core.information_win_size - Tab.tab_win_height(), 0) diff --git a/poezio/text_buffer.py b/poezio/text_buffer.py index 4e0f4b90..f835b38e 100644 --- a/poezio/text_buffer.py +++ b/poezio/text_buffer.py @@ -214,9 +214,8 @@ class TextBuffer(object): if msg.ack == 1: # Message was already acked return False if msg.jid != jid: - raise AckError( - 'Wrong JID for message id %s (was %s, expected %s)' % - (old_id, msg.jid, jid)) + raise AckError('Wrong JID for message id %s (was %s, expected %s)' + % (old_id, msg.jid, jid)) msg.ack = value if append: @@ -253,9 +252,9 @@ class TextBuffer(object): raise CorrectionError('Could not check the ' 'identity of the sender') elif not msg.user and msg.jid != jid: - raise CorrectionError('Messages %s and %s have not been ' - 'sent by the same fullJID' % (old_id, - new_id)) + raise CorrectionError( + 'Messages %s and %s have not been ' + 'sent by the same fullJID' % (old_id, new_id)) if not time: time = msg.time diff --git a/poezio/windows/base_wins.py b/poezio/windows/base_wins.py index b54a7b37..52b6c249 100644 --- a/poezio/windows/base_wins.py +++ b/poezio/windows/base_wins.py @@ -120,8 +120,8 @@ class Win(object): self._win.attron(attr_italic) if (attr_char in string.digits or attr_char == '-') and attr_char != '': - color_str = text[next_attr_char + 1:text.find( - '}', next_attr_char)] + color_str = text[next_attr_char + + 1:text.find('}', next_attr_char)] if ',' in color_str: tup, char = read_tuple(color_str) self._win.attron(to_curses_attr(tup)) diff --git a/poezio/windows/bookmark_forms.py b/poezio/windows/bookmark_forms.py index 25d4055d..5a319c27 100644 --- a/poezio/windows/bookmark_forms.py +++ b/poezio/windows/bookmark_forms.py @@ -184,8 +184,8 @@ class BookmarksWin(Win): BookmarkPasswordInput(bookmark), BookmarkAutojoinWin(bookmark), BookmarkMethodInput(bookmark))) - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_NORMAL_TEXT) self.current_horizontal_input = 0 self.current_input = len(self.lines) - 1 @@ -218,8 +218,8 @@ class BookmarksWin(Win): return if self.current_input == len(self.lines) - 1: return - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_NORMAL_TEXT) # Adjust the scroll position if the current_input would be outside # of the visible area @@ -238,8 +238,8 @@ class BookmarksWin(Win): return if self.current_input == 0: return - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_NORMAL_TEXT) self.current_input -= 1 # Adjust the scroll position if the current_input would be outside @@ -247,21 +247,21 @@ class BookmarksWin(Win): if self.current_input < self.scroll_pos: self.scroll_pos = self.current_input self.refresh() - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_SELECTED_ROW) def go_to_next_horizontal_input(self): if not self.lines: return - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_NORMAL_TEXT) self.current_horizontal_input += 1 if self.current_horizontal_input > 3: self.current_horizontal_input = 0 - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_SELECTED_ROW) def go_to_next_page(self): @@ -271,8 +271,8 @@ class BookmarksWin(Win): if self.current_input == len(self.lines) - 1: return - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_NORMAL_TEXT) inc = min(self.height, len(self.lines) - self.current_input - 1) @@ -294,8 +294,8 @@ class BookmarksWin(Win): if self.current_input == 0: return - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_NORMAL_TEXT) dec = min(self.height, self.current_input) @@ -305,8 +305,8 @@ class BookmarksWin(Win): if self.current_input < self.scroll_pos: self.scroll_pos = self.current_input self.refresh() - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_SELECTED_ROW) return True @@ -315,12 +315,12 @@ class BookmarksWin(Win): return if self.current_horizontal_input == 0: return - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_NORMAL_TEXT) self.current_horizontal_input -= 1 - self.lines[ - self.current_input][self.current_horizontal_input].set_color( + self.lines[self.current_input][ + self.current_horizontal_input].set_color( get_theme().COLOR_SELECTED_ROW) def on_input(self, key): @@ -336,9 +336,12 @@ class BookmarksWin(Win): for i in range(len(self.lines)): self.lines[i][0].resize(1, self.width // 4, y + 1, 0) self.lines[i][1].resize(1, self.width // 4, y + 1, self.width // 4) - self.lines[i][2].resize(1, self.width // 6, y + 1, 3 * self.width // 6) - self.lines[i][3].resize(1, self.width // 6, y + 1, 4 * self.width // 6) - self.lines[i][4].resize(1, self.width // 6, y + 1, 5 * self.width // 6) + self.lines[i][2].resize(1, self.width // 6, y + 1, + 3 * self.width // 6) + self.lines[i][3].resize(1, self.width // 6, y + 1, + 4 * self.width // 6) + self.lines[i][4].resize(1, self.width // 6, y + 1, + 5 * self.width // 6) y += 1 self._refresh() for i, inp in enumerate(self.lines): diff --git a/poezio/windows/data_forms.py b/poezio/windows/data_forms.py index c600273e..a9dc3695 100644 --- a/poezio/windows/data_forms.py +++ b/poezio/windows/data_forms.py @@ -422,8 +422,8 @@ class FormWin(object): self.current_input += 1 jump = 0 while self.current_input + jump != len( - self.inputs) - 1 and self.inputs[self.current_input - + jump]['input'].is_dummy(): + self.inputs) - 1 and self.inputs[self.current_input + + jump]['input'].is_dummy(): jump += 1 if self.inputs[self.current_input + jump]['input'].is_dummy(): return diff --git a/poezio/windows/info_bar.py b/poezio/windows/info_bar.py index 950813f1..6e338a78 100644 --- a/poezio/windows/info_bar.py +++ b/poezio/windows/info_bar.py @@ -26,18 +26,12 @@ class GlobalInfoBar(Win): self.addstr(0, 0, "[", to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) - create_gaps = config.get('create_gaps') show_names = config.get('show_tab_names') show_nums = config.get('show_tab_numbers') use_nicks = config.get('use_tab_nicks') show_inactive = config.get('show_inactive_tabs') - # ignore any remaining gap tabs if the feature is not enabled - if create_gaps: - sorted_tabs = self.core.tabs[:] - else: - sorted_tabs = [tab for tab in self.core.tabs if tab] - for nb, tab in enumerate(sorted_tabs): + for nb, tab in enumerate(self.core.tabs): if not tab: continue color = tab.color if not show_inactive and color is get_theme().COLOR_TAB_NORMAL: diff --git a/poezio/windows/info_wins.py b/poezio/windows/info_wins.py index 2d4d1e01..27f9e1cf 100644 --- a/poezio/windows/info_wins.py +++ b/poezio/windows/info_wins.py @@ -228,9 +228,9 @@ class DynamicConversationInfoWin(ConversationInfoWin): self.addstr(jid.bare, to_curses_attr(get_theme().COLOR_CONVERSATION_NAME)) if jid.resource: - self.addstr("/%s" % (jid.resource, ), - to_curses_attr( - get_theme().COLOR_CONVERSATION_RESOURCE)) + self.addstr( + "/%s" % (jid.resource, ), + to_curses_attr(get_theme().COLOR_CONVERSATION_RESOURCE)) self.addstr('] ', to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) diff --git a/poezio/windows/inputs.py b/poezio/windows/inputs.py index 6956f4f6..6453205c 100644 --- a/poezio/windows/inputs.py +++ b/poezio/windows/inputs.py @@ -522,9 +522,8 @@ class Input(Win): self._win.erase() if self.color: self._win.attron(to_curses_attr(self.color)) - displayed_text = text[self.view_pos: - self.view_pos + self.width - 1].replace( - '\t', '\x18') + displayed_text = text[self.view_pos:self.view_pos + self.width - + 1].replace('\t', '\x18') self._win.attrset(0) self._addstr_colored_lite(displayed_text) # Fill the rest of the line with the input color diff --git a/poezio/windows/list.py b/poezio/windows/list.py index 1f51e88f..26cb1e5f 100644 --- a/poezio/windows/list.py +++ b/poezio/windows/list.py @@ -101,9 +101,9 @@ class ListWin(Win): if not txt: continue if line is self.lines[self._selected_row]: - self.addstr(y, x, txt[:size], - to_curses_attr( - get_theme().COLOR_INFORMATION_BAR)) + self.addstr( + y, x, txt[:size], + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) else: self.addstr(y, x, txt[:size]) x += size @@ -192,9 +192,9 @@ class ColumnHeaderWin(Win): size = self._columns_sizes[col] txt += ' ' * (size - len(txt)) if col in self._column_sel: - self.addstr(0, x, txt, - to_curses_attr( - get_theme().COLOR_COLUMN_HEADER_SEL)) + self.addstr( + 0, x, txt, + to_curses_attr(get_theme().COLOR_COLUMN_HEADER_SEL)) else: self.addstr(0, x, txt, to_curses_attr(get_theme().COLOR_COLUMN_HEADER)) diff --git a/poezio/windows/roster_win.py b/poezio/windows/roster_win.py index 36c41ae6..f1490709 100644 --- a/poezio/windows/roster_win.py +++ b/poezio/windows/roster_win.py @@ -146,8 +146,8 @@ class RosterWin(Win): self.scroll_down(self.pos - self.start_pos - self.height + (self.height // 2)) # draw the roster from the cache - roster_view = self.roster_cache[self.start_pos - 1: - self.start_pos + self.height] + roster_view = self.roster_cache[self.start_pos - 1:self.start_pos + + self.height] options = { 'show_roster_sub': config.get('show_roster_subscriptions'), @@ -190,9 +190,10 @@ class RosterWin(Win): """ The header at the top """ - self.addstr('Roster: %s/%s contacts' % - (roster.get_nb_connected_contacts(), len(roster)), - to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) + self.addstr( + 'Roster: %s/%s contacts' % (roster.get_nb_connected_contacts(), + len(roster)), + to_curses_attr(get_theme().COLOR_INFORMATION_BAR)) self.finish_line(get_theme().COLOR_INFORMATION_BAR) def draw_group(self, y, group, colored): @@ -206,9 +207,10 @@ class RosterWin(Win): else: self.addstr(y, 0, '[-] ') contacts = " (%s/%s)" % (group.get_nb_connected_contacts(), len(group)) - self.addstr(y, 4, - self.truncate_name(group.name, - len(contacts) + 4) + contacts) + self.addstr( + y, 4, + self.truncate_name(group.name, + len(contacts) + 4) + contacts) if colored: self._win.attroff(to_curses_attr(get_theme().COLOR_SELECTED_ROW)) self.finish_line() diff --git a/poezio/xhtml.py b/poezio/xhtml.py index df11d005..c03b206e 100644 --- a/poezio/xhtml.py +++ b/poezio/xhtml.py @@ -562,8 +562,8 @@ def poezio_colors_to_html(string): check_property('font-style', 'italic') if attr_char in digits: - number_str = string[next_attr_char + 1:string.find( - '}', next_attr_char)] + number_str = string[next_attr_char + + 1:string.find('}', next_attr_char)] number = int(number_str) if number in number_to_color_names: check_property('color', -- cgit v1.2.3