diff options
Diffstat (limited to 'src/core.py')
-rw-r--r-- | src/core.py | 86 |
1 files changed, 58 insertions, 28 deletions
diff --git a/src/core.py b/src/core.py index 4aa1b2b3..df7f3cad 100644 --- a/src/core.py +++ b/src/core.py @@ -129,17 +129,16 @@ class Core(object): '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), + 'bind': (self.command_bind, _('Usage: /bind <key> <equ>\nBind: bind a key to an other key or to a “command”. For example "/bind ^H KEY_UP" makes Control + h do the same same than the Up key.')), } self.key_func = { "KEY_PPAGE": self.scroll_page_up, "KEY_NPAGE": self.scroll_page_down, "KEY_F(5)": self.rotate_rooms_left, - "M-[1;6D": self.rotate_rooms_left, "^P": self.rotate_rooms_left, 'kLFT3': self.rotate_rooms_left, "KEY_F(6)": self.rotate_rooms_right, - "M-[1;6C": self.rotate_rooms_right, "^N": self.rotate_rooms_right, 'kRIT3': self.rotate_rooms_right, "KEY_F(7)": self.shrink_information_win, @@ -335,6 +334,7 @@ class Core(object): def on_got_offline(self, presence): jid = presence['from'] contact = roster.get_contact_by_jid(jid.bare) + logger.log_roster_change(jid.bare, 'got offline') if not contact: return log.debug('on_got_offline: %s' % presence) @@ -356,6 +356,7 @@ class Core(object): if not contact: # Todo, handle presence comming from contacts not in roster return + logger.log_roster_change(jid.bare, 'got online') resource = contact.get_resource_by_fulljid(jid.full) assert not resource resource = Resource(jid.full) @@ -485,7 +486,7 @@ class Core(object): for tab in self.tabs: if tab.get_name() == jid_from.bare and isinstance(tab, tabs.MucTab): if message['type'] == 'error': - return self.room_error(message, tab.get_room().name) + return self.room_error(message, jid_from) else: return self.on_groupchat_private_message(message) return self.on_normal_message(message) @@ -513,6 +514,8 @@ class Core(object): conversation.remote_wants_chatstates = True else: conversation.remote_wants_chatstates = False + if 'private' in config.get('beep_on', 'highlight private').split(): + curses.beep() logger.log_message(jid.full.replace('/', '\\'), nick_from, body) if conversation is self.current_tab(): self.refresh_window() @@ -550,6 +553,8 @@ class Core(object): jid = message['from'] body = xhtml.get_body_from_message_stanza(message) if not body: + if message['type'] == 'error': + self.information(self.get_error_message_from_error_stanza(message), 'Error') return conversation = self.get_tab_of_conversation_with_jid(jid, create=True) if roster.get_contact_by_jid(jid.bare): @@ -563,6 +568,8 @@ class Core(object): else: conversation.remote_wants_chatstates = False logger.log_message(jid.bare, remote_nick, body) + if 'private' in config.get('beep_on', 'highlight private').split(): + curses.beep() if self.current_tab() is not conversation: conversation.set_color_state(theme.COLOR_TAB_PRIVATE) self.refresh_tab_win() @@ -668,7 +675,8 @@ class Core(object): """ # curses.ungetch(0) # FIXME while self.running: - char_list = self.read_keyboard() + char_list = [common.replace_key_with_bound(key)\ + for key in self.read_keyboard()] # Special case for M-x where x is a number if len(char_list) == 1: char = char_list[0] @@ -767,7 +775,8 @@ class Core(object): def refresh_tab_win(self): self.current_tab().tab_win.refresh() - self.current_tab().input.refresh() + if self.current_tab().input: + self.current_tab().input.refresh() self.doupdate() def add_tab(self, new_tab, focus=False): @@ -850,26 +859,34 @@ class Core(object): self.current_tab().on_scroll_up() self.refresh_window() - def room_error(self, error, room_name): + def get_error_message_from_error_stanza(self, stanza): """ - Display the error on the room window + Takes a stanza of the form <message type='error'><error/></message> + and return a well formed string containing the error informations """ - room = self.get_room_by_name(room_name) - msg = error['error']['type'] - condition = error['error']['condition'] - code = error['error']['code'] - body = error['error']['text'] + msg = stanza['error']['type'] + condition = stanza['error']['condition'] + code = stanza['error']['code'] + body = stanza['error']['text'] if not body: if code in ERROR_AND_STATUS_CODES: body = ERROR_AND_STATUS_CODES[code] else: body = condition or _('Unknown error') if code: - msg = _('Error: %(code)s - %(msg)s: %(body)s') % {'msg':msg, 'body':body, 'code':code} - self.add_message_to_text_buffer(room, msg) + message = _('Error: %(code)s - %(msg)s: %(body)s') % {'msg':msg, 'body':body, 'code':code} else: - msg = _('Error: %(msg)s: %(body)s') % {'msg':msg, 'body':body} - self.add_message_to_text_buffer(room, msg) + message = _('Error: %(msg)s: %(body)s') % {'msg':msg, 'body':body} + return message + + def room_error(self, error, room_name): + """ + Display the error on the room window + """ + room = self.get_room_by_name(room_name) + error_message = self.get_error_message_from_error_stanza(error) + self.add_message_to_text_buffer(room, error_message) + code = error['error']['code'] if code == '401': msg = _('To provide a password in order to join the room, type "/join / password" (replace "password" by the real password)') self.add_message_to_text_buffer(room, msg) @@ -968,13 +985,15 @@ class Core(object): body = xhtml.get_body_from_message_stanza(message) if body: date = date if delayed == True else None - self.add_message_to_text_buffer(room, body, date, nick_from) + self.add_message_to_text_buffer(room, body, date, nick_from, history=True if date else False) if tab is self.current_tab(): tab.text_win.refresh(tab._room) tab.info_header.refresh(tab._room, tab.text_win) self.refresh_tab_win() + if 'message' in config.get('beep_on', 'highlight private').split(): + curses.beep() - def add_message_to_text_buffer(self, room, txt, time=None, nickname=None): + def add_message_to_text_buffer(self, room, txt, time=None, nickname=None, history=None): """ Add the message to the room if possible, else, add it to the Info window (in the Info tab of the info window in the RosterTab) @@ -982,7 +1001,7 @@ class Core(object): if not room: self.information('Trying to add a message in no room: %s' % txt, 'Error') else: - room.add_message(txt, time, nickname) + room.add_message(txt, time, nickname, history=history) def command_help(self, arg): """ @@ -1073,7 +1092,7 @@ class Core(object): """ /reconnect """ - self.disconnect(True) + self.disconnect(reconnect=True) def command_list(self, arg): """ @@ -1221,6 +1240,7 @@ class Core(object): else: # no server could be found, print a message and return self.information(_("You didn't specify a server for the room you want to join"), 'Error') return + room = room.lower() r = self.get_room_by_name(room) if len(args) == 2: # a password is provided password = args[1] @@ -1229,7 +1249,6 @@ class Core(object): return if room.startswith('@'): room = room[1:] - room = room.lower() current_status = self.get_status() if r and not r.joined: muc.join_groupchat(self.xmpp, room, nick, password, @@ -1359,6 +1378,16 @@ class Core(object): tab.get_room().joined = False self.command_join(tab.get_name()) + def command_bind(self, arg): + """ + Bind a key. + """ + args = common.shell_split(arg) + if len(args) != 2: + return self.command_help('bind') + config.set_and_save(args[0], args[1], section='bindings') + self.information('%s is now bound to %s' % (args[0], args[1]), 'Info') + def go_to_room_number(self): """ Read 2 more chars and go to the tab @@ -1378,15 +1407,19 @@ class Core(object): def information(self, msg, typ=''): """ - Displays an informational message in the "Info" room window + Displays an informational message in the "Info" buffer """ nb_lines = self.information_buffer.add_message(msg, nickname=typ) if typ != '' and typ.lower() in config.get('information_buffer_popup_on', 'error roster warning help info').split(): popup_time = config.get('popup_time', 4) + (nb_lines - 1) * 2 self.pop_information_win_up(nb_lines, popup_time) + else: + if self.information_win_size != 0: + self.information_win.refresh(self.information_buffer) + self.current_tab().input.refresh() - def disconnect(self, msg=None): + def disconnect(self, msg=None, reconnect=False): """ Disconnect from remote server and correctly set the states of all parts of the client (for example, set the MucTabs as not joined, etc) @@ -1394,13 +1427,10 @@ class Core(object): for tab in self.tabs: if isinstance(tab, tabs.MucTab): muc.leave_groupchat(self.xmpp, tab.get_room().name, tab.get_room().own_nick, msg) + roster.empty() self.save_config() # Ugly fix thanks to gmail servers - try: - sys.stderr = None - self.xmpp.disconnect(False) - except: - pass + self.xmpp.disconnect(reconnect) def command_quit(self, arg): """ |