summaryrefslogtreecommitdiff
path: root/src/core.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/core.py')
-rw-r--r--src/core.py86
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):
"""