diff options
-rw-r--r-- | src/core.py | 58 | ||||
-rw-r--r-- | src/tabs.py | 49 | ||||
-rw-r--r-- | src/windows.py | 10 | ||||
-rw-r--r-- | src/xhtml.py | 5 |
4 files changed, 82 insertions, 40 deletions
diff --git a/src/core.py b/src/core.py index f5980af1..8e0d56ce 100644 --- a/src/core.py +++ b/src/core.py @@ -128,6 +128,7 @@ class Core(object): 'message': (self.command_message, _('Usage: /message <jid> [optional message]\nMessage: Open a conversation with the specified JID (even if it is not in our roster), and send a message to it, if specified'), None), 'version': (self.command_version, _('Usage: /version <jid>\nVersion: get the software version of the given JID (usually its XMPP client and Operating System)'), None), 'connect': (self.command_reconnect, _('Usage: /connect\nConnect: disconnect from the remote server if you are currently connected and then connect to it again'), None), + 'server_cycle': (self.command_server_cycle, _('Usage: /server_cycle [domain] [message]\nServer Cycle: disconnect and reconnects in all the rooms in domain.'), None), } self.key_func = { @@ -682,7 +683,7 @@ class Core(object): else: self.command_win('%d' % nb) # search for keyboard shortcut - if char in list(self.key_func.keys()): + if char in self.key_func: self.key_func[char]() else: self.do_command(char) @@ -853,7 +854,7 @@ class Core(object): code = error['error']['code'] body = error['error']['text'] if not body: - if code in list(ERROR_AND_STATUS_CODES.keys()): + if code in ERROR_AND_STATUS_CODES: body = ERROR_AND_STATUS_CODES[code] else: body = condition or _('Unknown error') @@ -877,6 +878,11 @@ class Core(object): """ open a new conversation tab and focus it if needed """ + for tab in self.tabs: # if the room exists, focus it and return + if isinstance(tab, tabs.ConversationTab): + if tab.get_name() == jid: + self.command_win('%s' % tab.nb) + return tab new_tab = tabs.ConversationTab(jid) # insert it in the rooms self.add_tab(new_tab, focus) @@ -945,8 +951,6 @@ class Core(object): room_from = message.getMucroom() if message['type'] == 'error': # Check if it's an error return self.room_error(message, from_room) - if nick_from == room_from: - nick_from = None room = self.get_room_by_name(room_from) tab = self.get_tab_by_name(room_from, tabs.MucTab) if tab and tab.get_room() and tab.get_room().get_user_by_name(nick_from) and\ @@ -980,15 +984,15 @@ class Core(object): args = arg.split() if len(args) == 0: msg = _('Available commands are: ') - for command in list(self.commands.keys()): + for command in self.commands: msg += "%s " % command - for command in list(self.current_tab().commands.keys()): + for command in self.current_tab().commands: msg += "%s " % command msg += _("\nType /help <command_name> to know what each command does") if len(args) >= 1: - if args[0] in list(self.commands.keys()): + if args[0] in self.commands: msg = self.commands[args[0]][1] - elif args[0] in list(self.current_tab().commands.keys()): + elif args[0] in self.current_tab().commands: msg = self.current_tab().commands[args[0]][1] else: msg = _('Unknown command: %s') % args[0] @@ -1024,7 +1028,7 @@ class Core(object): self.set_status(show, msg) def completion_status(self, the_input): - return the_input.auto_completion([status for status in list(possible_show.keys())], ' ') + return the_input.auto_completion([status for status in possible_show], ' ') def command_message(self, arg): """ @@ -1322,6 +1326,31 @@ class Core(object): del tab self.refresh_window() + def command_server_cycle(self, arg): + """ + Do a /cycle on each room of the given server. If none, do it on the current tab + """ + args = common.shell_split(arg) + tab = self.current_tab() + message = "" + + if len(args): + domain = args[0] + if len(args) > 1: + message = args[1] + else: + if isinstance(tab, tabs.MucTab): + domain = JID(tab.get_name()).domain + else: + self.information(_("No server specified"), "Error") + return + for tab in self.tabs: + if isinstance(tab, tabs.MucTab) and JID(tab.get_name()).domain == domain: + if tab.get_room().joined: + muc.leave_groupchat(tab.core.xmpp, tab.get_name(), tab.get_room().own_nick, message) + tab.get_room().joined = False + self.command_join(tab.get_name()) + def go_to_room_number(self): """ Read 2 more chars and go to the tab @@ -1358,7 +1387,12 @@ class Core(object): if isinstance(tab, tabs.MucTab): muc.leave_groupchat(self.xmpp, tab.get_room().name, tab.get_room().own_nick, msg) self.save_config() - self.xmpp.disconnect(False) + # Ugly fix thanks to gmail servers + try: + sys.stderr = None + self.xmpp.disconnect(False) + except: + pass def command_quit(self, arg): """ @@ -1430,12 +1464,12 @@ class Core(object): command = line.strip()[:].split()[0][1:] arg = line[2+len(command):] # jump the '/' and the ' ' # example. on "/link 0 open", command = "link" and arg = "0 open" - if command in list(self.commands.keys()): + if command in self.commands: func = self.commands[command][0] func(arg) return else: - self.information(_("unknown command (%s)") % (command), _('Error')) + self.information(_("Unknown command (%s)") % (command), _('Error')) def doupdate(self): if not self.running: diff --git a/src/tabs.py b/src/tabs.py index fa8cc5f8..4a7e26f5 100644 --- a/src/tabs.py +++ b/src/tabs.py @@ -119,8 +119,8 @@ class Tab(object): return command[2](the_input) else: # complete the command's name - words = ['/%s'%(name) for name in list(self.core.commands.keys())] +\ - ['/%s'% (name) for name in list(self.commands.keys())] + words = ['/%s'%(name) for name in self.core.commands] +\ + ['/%s'% (name) for name in self.commands] the_input.auto_completion(words, '') return True return False @@ -282,21 +282,23 @@ class ChatTab(Tab): def on_enter(self): txt = self.input.key_enter() - clean_text = xhtml.clean_text(txt) - if not self.execute_command(clean_text): - if txt.startswith('//'): - txt = txt[1:] - self.command_say(txt) + if txt: + clean_text = xhtml.clean_text(txt) + if not self.execute_command(clean_text): + if txt.startswith('//'): + txt = txt[1:] + self.command_say(txt) self.cancel_paused_delay() def send_chat_state(self, state): """ Send an empty chatstate message """ - msg = self.core.xmpp.make_message(self.get_name()) - msg['type'] = self.message_type - msg['chat_state'] = state - msg.send() + if not isinstance(self, MucTab) or self.get_room().joined: + msg = self.core.xmpp.make_message(self.get_name()) + msg['type'] = self.message_type + msg['chat_state'] = state + msg.send() def send_composing_chat_state(self, empty_before, empty_after): """ @@ -304,11 +306,13 @@ class ChatTab(Tab): on the the current status of the input """ if config.get('send_chat_states', 'true') == 'true' and self.remote_wants_chatstates: - if not empty_before and empty_after: + if empty_after: self.send_chat_state("active") self.cancel_paused_delay() - elif (empty_before or (self.timed_event_paused is not None and not self.timed_event_paused())) and not empty_after: + elif empty_before or (self.timed_event_paused is not None and not self.timed_event_paused()): + self.cancel_paused_delay() self.send_chat_state("composing") + self.set_paused_delay(True) def set_paused_delay(self, composing): """ @@ -593,6 +597,8 @@ class MucTab(ChatTab): msg = arg[len(nick)+1:] muc.send_private_message(self.core.xmpp, r.name, msg) self.core.add_message_to_text_buffer(r, msg, None, r.own_nick) + if not r: + self.core.information(_("Cannot find user: %s" % nick), 'Error') def command_topic(self, arg): """ @@ -719,9 +725,6 @@ class MucTab(ChatTab): self.input.do_command(key) empty_after = self.input.get_text() == '' or (self.input.get_text().startswith('/') and not self.input.get_text().startswith('//')) self.send_composing_chat_state(empty_before, empty_after) - if not empty_before and empty_after: - self.cancel_paused_delay() - self.set_paused_delay(empty_before and not empty_after) return False def completion(self): @@ -730,6 +733,7 @@ class MucTab(ChatTab): """ if self.complete_commands(self.input): return + # If we are not completing a command or a command's argument, complete a nick compare_users = lambda x: x.last_talked word_list = [user.nick for user in sorted(self._room.users, key=compare_users, reverse=True)\ @@ -740,7 +744,11 @@ class MucTab(ChatTab): add_after = after else: add_after = ' ' + + empty_before = self.input.get_text() == '' or (self.input.get_text().startswith('/') and not self.input.get_text().startswith('//')) self.input.auto_completion(word_list, add_after) + empty_after = self.input.get_text() == '' or (self.input.get_text().startswith('/') and not self.input.get_text().startswith('//')) + self.send_composing_chat_state(empty_before, empty_after) def get_color_state(self): return self._room.color_state @@ -1063,9 +1071,6 @@ class PrivateTab(ChatTab): self.input.do_command(key) empty_after = self.input.get_text() == '' or (self.input.get_text().startswith('/') and not self.input.get_text().startswith('//')) self.send_composing_chat_state(empty_before, empty_after) - if not empty_before and empty_after: - self.cancel_paused_delay() - self.set_paused_delay(empty_before and not empty_after) return False def on_lose_focus(self): @@ -1195,6 +1200,7 @@ class RosterInfoTab(Tab): """ jid = JID(args.strip()).bare if not jid: + self.core.information(_('No JID specified'), 'Error') return self.core.xmpp.sendPresence(pto=jid, ptype='subscribe') @@ -1242,7 +1248,7 @@ class RosterInfoTab(Tab): if isinstance(item, Contact) and item.get_ask() == 'asked': jid = item.get_bare_jid() else: - self.core.information('No subscription to deny') + self.core.information('No subscription to accept') return else: jid = args[0] @@ -1506,9 +1512,6 @@ class ConversationTab(ChatTab): self.input.do_command(key) empty_after = self.input.get_text() == '' or (self.input.get_text().startswith('/') and not self.input.get_text().startswith('//')) self.send_composing_chat_state(empty_before, empty_after) - self.set_paused_delay(empty_before and not empty_after) - if not empty_before and empty_after: - self.cancel_paused_delay() return False def on_lose_focus(self): diff --git a/src/windows.py b/src/windows.py index 85584152..df361ed8 100644 --- a/src/windows.py +++ b/src/windows.py @@ -126,7 +126,7 @@ class Win(object): self._win.attron(curses.A_UNDERLINE) elif attr_char == 'b': self._win.attron(curses.A_BOLD) - elif attr_char.isnumeric(): + elif attr_char in string.digits and attr_char != '': self._win.attron(common.curses_color_pair(int(attr_char))) next_attr_char = text.find('\x19') self.addstr(text) @@ -566,7 +566,11 @@ class TextWin(Win): else: txt = txt.replace('\t', ' ') # length of the time - offset = 9+len(theme.CHAR_TIME_LEFT[:1])+len(theme.CHAR_TIME_RIGHT[:1]) + offset = 9 + if theme.CHAR_TIME_RIGHT: + offset += 1 + if theme.CHAR_TIME_RIGHT: + offset += 1 nickname = message.nickname if nickname and len(nickname) >= 25: nick = nickname[:25]+'…' @@ -1125,7 +1129,7 @@ class MessageInput(Input): Read one more char (c) and add \x19c to the string """ attr_char = self.core.read_keyboard() - if attr_char in self.text_attributes or (attr_char.isnumeric() and int(attr_char) < 7): + if attr_char in self.text_attributes or (attr_char in string.digits and int(attr_char) < 7): self.do_command('\x19', False) self.do_command(attr_char) diff --git a/src/xhtml.py b/src/xhtml.py index 237ed444..29017be3 100644 --- a/src/xhtml.py +++ b/src/xhtml.py @@ -28,6 +28,7 @@ import subprocess from sleekxmpp.xmlstream import ET from xml.etree.ElementTree import ElementTree from sys import version_info +from string import digits from config import config import logging @@ -133,7 +134,7 @@ def poezio_colors_to_html(string): if 'strong' not in opened_elements: opened_elements.append('strong') res += '<strong>' - elif attr_char.isnumeric(): + elif attr_char in digits: number = int(attr_char) if number in number_to_color_names: if 'strong' in opened_elements: @@ -215,7 +216,7 @@ def poezio_colors_to_xhtml(string): if 'strong' not in open_elements: res += '<strong>' open_elements.append('strong') - elif attr_char.isnumeric(): + elif attr_char in digits: self._win.attron(common.curses_color_pair(int(attr_char))) next_attr_char = string.find('\x19') |