summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core.py58
-rw-r--r--src/tabs.py49
-rw-r--r--src/windows.py10
-rw-r--r--src/xhtml.py5
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')