summaryrefslogtreecommitdiff
path: root/poezio/core
diff options
context:
space:
mode:
authormathieui <mathieui@mathieui.net>2017-11-12 15:03:09 +0100
committermathieui <mathieui@mathieui.net>2017-11-12 15:03:09 +0100
commitd55cc5872503567775f0d7a7731d6f489bf2299b (patch)
tree725f9e7b8144d36054447b3c82edfb45bda8df1d /poezio/core
parent92496db823db34f7f7fb1ab31eaef093a707c3e8 (diff)
downloadpoezio-d55cc5872503567775f0d7a7731d6f489bf2299b.tar.gz
poezio-d55cc5872503567775f0d7a7731d6f489bf2299b.tar.bz2
poezio-d55cc5872503567775f0d7a7731d6f489bf2299b.tar.xz
poezio-d55cc5872503567775f0d7a7731d6f489bf2299b.zip
yapf -ir
Diffstat (limited to 'poezio/core')
-rw-r--r--poezio/core/__init__.py1
-rw-r--r--poezio/core/commands.py202
-rw-r--r--poezio/core/completions.py184
-rw-r--r--poezio/core/core.py816
-rw-r--r--poezio/core/handlers.py659
-rw-r--r--poezio/core/structs.py14
6 files changed, 1116 insertions, 760 deletions
diff --git a/poezio/core/__init__.py b/poezio/core/__init__.py
index 0c6d63d9..cfe4c179 100644
--- a/poezio/core/__init__.py
+++ b/poezio/core/__init__.py
@@ -5,4 +5,3 @@ __all__ = ['Core', 'Command', 'Status']
from poezio.core.core import Core
from poezio.core.structs import Command, Status
-
diff --git a/poezio/core/commands.py b/poezio/core/commands.py
index 5a28182b..ab0ced9a 100644
--- a/poezio/core/commands.py
+++ b/poezio/core/commands.py
@@ -46,10 +46,8 @@ class CommandCore:
buff = ['Global commands:']
for name, command in self.core.commands.items():
if isinstance(command, Command):
- acc.append(' \x19%s}%s\x19o - %s' % (
- color,
- name,
- command.short_desc))
+ acc.append(' \x19%s}%s\x19o - %s' % (color, name,
+ command.short_desc))
else:
acc.append(' \x19%s}%s\x19o' % (color, name))
acc = sorted(acc)
@@ -59,10 +57,8 @@ class CommandCore:
tab_commands = self.core.current_tab().commands
for name, command in tab_commands.items():
if isinstance(command, Command):
- acc.append(' \x19%s}%s\x19o - %s' % (
- color,
- name,
- command.short_desc))
+ acc.append(' \x19%s}%s\x19o - %s' % (color, name,
+ command.short_desc))
else:
acc.append(' \x19%s}%s\x19o' % (color, name))
acc = sorted(acc)
@@ -93,11 +89,13 @@ class CommandCore:
"""
/runkey <key>
"""
+
def replace_line_breaks(key):
"replace ^J with \n"
if key == '^J':
return '\n'
return key
+
if args is None:
return self.help('runkey')
char = args[0]
@@ -135,7 +133,8 @@ class CommandCore:
current.send_chat_state('inactive')
for tab in self.core.tabs:
if isinstance(tab, tabs.MucTab) and tab.joined:
- muc.change_show(self.core.xmpp, tab.name, tab.own_nick, show, msg)
+ muc.change_show(self.core.xmpp, tab.name, tab.own_nick, show,
+ msg)
if hasattr(tab, 'directed_presence'):
del tab.directed_presence
self.core.set_status(show, msg)
@@ -156,12 +155,14 @@ class CommandCore:
if ptype == 'available':
ptype = None
try:
- pres = self.core.xmpp.make_presence(pto=jid, ptype=ptype, pstatus=status)
+ pres = self.core.xmpp.make_presence(
+ pto=jid, ptype=ptype, pstatus=status)
self.core.events.trigger('send_normal_presence', pres)
pres.send()
except (XMPPError, NotConnectedError):
self.core.information('Could not send directed presence', 'Error')
- log.debug('Could not send directed presence to %s', jid, exc_info=True)
+ log.debug(
+ 'Could not send directed presence to %s', jid, exc_info=True)
return
tab = self.core.get_tab_by_name(jid)
if tab:
@@ -184,7 +185,7 @@ class CommandCore:
"""/theme <theme name>"""
if args is None:
return self.help('theme')
- self.set('theme %s' % (args[0],))
+ self.set('theme %s' % (args[0], ))
@command_args_parser.quoted(1)
def win(self, args):
@@ -254,10 +255,12 @@ class CommandCore:
if not old_tab and value == tab.name:
old_tab = tab
if not old_tab:
- self.core.information("Tab %s does not exist" % args[0], "Error")
+ self.core.information("Tab %s does not exist" % args[0],
+ "Error")
return None
ref = old_tab.nb
return ref
+
old = get_nb_from_value(args[0])
new = get_nb_from_value(args[1])
if new is None or old is None:
@@ -281,19 +284,20 @@ class CommandCore:
jid = safeJID(args[0])
else:
if not isinstance(self.core.current_tab(), tabs.MucTab):
- return self.core.information('Please provide a server', 'Error')
+ return self.core.information('Please provide a server',
+ 'Error')
jid = safeJID(self.core.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
- self.core.xmpp.plugin['xep_0030'].get_items(jid=jid,
- callback=cb)
+ self.core.xmpp.plugin['xep_0030'].get_items(jid=jid, callback=cb)
@command_args_parser.quoted(1)
def version(self, args):
"""
/version <jid>
"""
+
def callback(res):
"Callback for /version"
if not res:
@@ -301,10 +305,9 @@ class CommandCore:
' version from %s' % jid,
'Warning')
version = '%s is running %s version %s on %s' % (
- jid,
- res.get('name') or 'an unknown software',
- res.get('version') or 'unknown',
- res.get('os') or 'an unknown platform')
+ jid, res.get('name') or 'an unknown software',
+ res.get('version') or 'unknown',
+ res.get('os') or 'an unknown platform')
self.core.information(version, 'Info')
if args is None:
@@ -315,7 +318,8 @@ class CommandCore:
fixes.get_version(self.core.xmpp, jid, callback=callback)
elif jid in roster:
for resource in roster[jid].resources:
- fixes.get_version(self.core.xmpp, resource.jid, callback=callback)
+ fixes.get_version(
+ self.core.xmpp, resource.jid, callback=callback)
def _empty_join(self):
tab = self.core.current_tab()
@@ -372,7 +376,7 @@ class CommandCore:
else:
room, nick = self._parse_join_jid(args[0])
if not room and not nick:
- return # nothing was parsed
+ return # nothing was parsed
room = room.lower()
if nick == '':
@@ -467,11 +471,13 @@ class CommandCore:
bookmark.nick = nick
if password:
bookmark.password = password
+
def callback(iq):
if iq["type"] != "error":
self.core.information('Bookmark added.', 'Info')
else:
self.core.information("Could not add the bookmarks.", "Info")
+
self.core.bookmarks.save_local()
self.core.bookmarks.save_remote(self.core.xmpp, callback)
@@ -480,8 +486,7 @@ class CommandCore:
for tab in self.core.get_tabs(tabs.MucTab):
bookmark = self.core.bookmarks[tab.name]
if not bookmark:
- bookmark = Bookmark(tab.name, autojoin=True,
- method=method)
+ bookmark = Bookmark(tab.name, autojoin=True, method=method)
new_bookmarks.append(bookmark)
else:
bookmark.method = method
@@ -489,11 +494,14 @@ class CommandCore:
self.core.bookmarks.remove(bookmark)
new_bookmarks.extend(self.core.bookmarks.bookmarks)
self.core.bookmarks.set(new_bookmarks)
+
def _cb(iq):
if iq["type"] != "error":
self.core.information("Bookmarks saved.", "Info")
else:
- self.core.information("Could not save the remote bookmarks.", "Info")
+ self.core.information("Could not save the remote bookmarks.",
+ "Info")
+
self.core.bookmarks.save_local()
self.core.bookmarks.save_remote(self.core.xmpp, _cb)
@@ -520,7 +528,8 @@ class CommandCore:
if success:
self.core.information('Bookmark deleted', 'Info')
else:
- self.core.information('Error while deleting the bookmark', 'Error')
+ self.core.information('Error while deleting the bookmark',
+ 'Error')
if not args:
tab = self.core.current_tab()
@@ -546,15 +555,17 @@ class CommandCore:
lines = []
theme = get_theme()
for section_name, section in config_dict.items():
- lines.append('\x19%(section_col)s}[%(section)s]\x19o' %
- {
- 'section': section_name,
- 'section_col': dump_tuple(theme.COLOR_INFORMATION_TEXT),
- })
+ lines.append(
+ '\x19%(section_col)s}[%(section)s]\x19o' % {
+ 'section': section_name,
+ 'section_col': dump_tuple(
+ 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]
@@ -573,7 +584,8 @@ class CommandCore:
file_name = os.path.join(file_name, plugin_name + '.cfg')
plugin_config = PluginConfig(file_name, plugin_name)
else:
- plugin_config = self.core.plugin_manager.plugins[plugin_name].config
+ plugin_config = self.core.plugin_manager.plugins[
+ plugin_name].config
value = plugin_config.get(option, default='', section=section)
info = ('%s=%s' % (option, value), 'Info')
else:
@@ -600,14 +612,15 @@ class CommandCore:
file_name = os.path.join(file_name, plugin_name + '.cfg')
plugin_config = PluginConfig(file_name, plugin_name)
else:
- plugin_config = self.core.plugin_manager.plugins[plugin_name].config
+ plugin_config = self.core.plugin_manager.plugins[
+ plugin_name].config
info = plugin_config.set_and_save(option, value, section)
else:
if args[0] == '.':
name = safeJID(self.core.current_tab().name).bare
if not name:
- self.core.information('Invalid tab to use the "." argument.',
- 'Error')
+ self.core.information(
+ 'Invalid tab to use the "." argument.', 'Error')
return
section = name
else:
@@ -679,35 +692,35 @@ class CommandCore:
"""
/last_activity <jid>
"""
+
def callback(iq):
"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')
+ 'activity of this contact.', 'Error')
else:
- self.core.information('Error retrieving the activity', 'Error')
+ self.core.information('Error retrieving the activity',
+ 'Error')
return
seconds = iq['last_activity']['seconds']
status = iq['last_activity']['status']
from_ = iq['from']
if not safeJID(from_).user:
msg = 'The uptime of %s is %s.' % (
- from_,
- common.parse_secs_to_str(seconds))
+ from_, common.parse_secs_to_str(seconds))
else:
msg = 'The last activity of %s was %s ago%s' % (
- from_,
- common.parse_secs_to_str(seconds),
- (' and his/her last status was %s' % status) if status else '')
+ from_, common.parse_secs_to_str(seconds),
+ (' and his/her last status was %s' % status)
+ if status else '')
self.core.information(msg, 'Info')
if args is None:
return self.help('last_activity')
jid = safeJID(args[0])
- self.core.xmpp.plugin['xep_0012'].get_last_activity(jid,
- callback=callback)
+ self.core.xmpp.plugin['xep_0012'].get_last_activity(
+ jid, callback=callback)
@command_args_parser.quoted(0, 2)
def mood(self, args):
@@ -719,15 +732,14 @@ class CommandCore:
mood = args[0]
if mood not in pep.MOODS:
- return self.core.information('%s is not a correct value for a mood.'
- % mood,
- 'Error')
+ return self.core.information(
+ '%s is not a correct value for a mood.' % mood, 'Error')
if len(args) == 2:
text = args[1]
else:
text = None
- self.core.xmpp.plugin['xep_0107'].publish_mood(mood, text,
- callback=dumb_callback)
+ self.core.xmpp.plugin['xep_0107'].publish_mood(
+ mood, text, callback=dumb_callback)
@command_args_parser.quoted(0, 3)
def activity(self, args):
@@ -740,9 +752,8 @@ class CommandCore:
general = args[0]
if general not in pep.ACTIVITIES:
- return self.core.information('%s is not a correct value for an activity'
- % general,
- 'Error')
+ return self.core.information(
+ '%s is not a correct value for an activity' % general, 'Error')
specific = None
text = None
if length == 2:
@@ -755,10 +766,9 @@ class CommandCore:
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')
- self.core.xmpp.plugin['xep_0108'].publish_activity(general, specific, text,
- callback=dumb_callback)
+ 'for an activity' % specific, 'Error')
+ self.core.xmpp.plugin['xep_0108'].publish_activity(
+ general, specific, text, callback=dumb_callback)
@command_args_parser.quoted(0, 2)
def gaming(self, args):
@@ -773,9 +783,8 @@ class CommandCore:
address = args[1]
else:
address = None
- return self.core.xmpp.plugin['xep_0196'].publish_gaming(name=name,
- server_address=address,
- callback=dumb_callback)
+ return self.core.xmpp.plugin['xep_0196'].publish_gaming(
+ name=name, server_address=address, callback=dumb_callback)
@command_args_parser.quoted(2, 1, [None])
def invite(self, args):
@@ -800,9 +809,9 @@ class CommandCore:
return
reason = args[1]
del self.core.pending_invites[jid.bare]
- self.core.xmpp.plugin['xep_0045'].decline_invite(jid.bare,
- self.core.pending_invites[jid.bare],
- reason)
+ self.core.xmpp.plugin['xep_0045'].decline_invite(
+ jid.bare, self.core.pending_invites[jid.bare], reason)
+
### Commands without a completion in this class ###
@@ -811,8 +820,8 @@ class CommandCore:
"""/invitations"""
build = ""
for invite in self.core.pending_invites:
- build += "%s by %s" % (invite,
- safeJID(self.core.pending_invites[invite]).bare)
+ build += "%s by %s" % (
+ invite, safeJID(self.core.pending_invites[invite]).bare)
if self.core.pending_invites:
build = "You are invited to the following rooms:\n" + build
else:
@@ -838,7 +847,8 @@ class CommandCore:
self.core.save_config()
self.core.plugin_manager.disable_plugins()
self.core.disconnect(msg)
- self.core.xmpp.add_event_handler("disconnected", self.core.exit, disposable=True)
+ self.core.xmpp.add_event_handler(
+ "disconnected", self.core.exit, disposable=True)
@command_args_parser.quoted(0, 1, [''])
def destroy_room(self, args):
@@ -849,7 +859,8 @@ class CommandCore:
if room:
muc.destroy_room(self.core.xmpp, room)
elif isinstance(self.core.current_tab(), tabs.MucTab) and not args[0]:
- muc.destroy_room(self.core.xmpp, self.core.current_tab().general_jid)
+ muc.destroy_room(self.core.xmpp,
+ self.core.current_tab().general_jid)
else:
self.core.information('Invalid JID: "%s"' % args[0], 'Error')
@@ -862,12 +873,15 @@ class CommandCore:
return self.help('bind')
if not config.silent_set(args[0], args[1], section='bindings'):
- self.core.information('Unable to write in the config file', 'Error')
+ self.core.information('Unable to write in the config file',
+ 'Error')
if args[1]:
- self.core.information('%s is now bound to %s' % (args[0], args[1]), 'Info')
+ self.core.information('%s is now bound to %s' % (args[0], args[1]),
+ 'Info')
else:
- self.core.information('%s is now reset to the default binding' % args[0], 'Info')
+ self.core.information(
+ '%s is now reset to the default binding' % args[0], 'Info')
@command_args_parser.raw
def rawxml(self, args):
@@ -881,7 +895,8 @@ class CommandCore:
stanza = args
try:
stanza = StanzaBase(self.core.xmpp, xml=ET.fromstring(stanza))
- if stanza.xml.tag == 'iq' and stanza.xml.attrib.get('type') in ('get', 'set'):
+ if stanza.xml.tag == 'iq' and stanza.xml.attrib.get('type') in (
+ 'get', 'set'):
iq_id = stanza.xml.attrib.get('id')
if not iq_id:
iq_id = self.core.xmpp.new_id()
@@ -893,18 +908,15 @@ class CommandCore:
self.core.xmpp.remove_handler('Iq %s' % iq_id)
self.core.xmpp.register_handler(
- Callback('Iq %s' % iq_id,
- StanzaPath('iq@id=%s' % iq_id),
- iqfunc
- )
- )
+ Callback('Iq %s' % iq_id,
+ StanzaPath('iq@id=%s' % iq_id), iqfunc))
stanza.send()
except:
self.core.information('Could not send custom stanza', 'Error')
- log.debug('/rawxml: Could not send custom stanza (%s)',
- repr(stanza),
- exc_info=True)
-
+ log.debug(
+ '/rawxml: Could not send custom stanza (%s)',
+ repr(stanza),
+ exc_info=True)
@command_args_parser.quoted(1, 256)
def load(self, args):
@@ -928,9 +940,8 @@ 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):
@@ -942,7 +953,8 @@ class CommandCore:
jid = safeJID(args[0])
if not jid.user and not jid.domain and not jid.resource:
return self.core.information('Invalid JID.', 'Error')
- tab = self.core.get_conversation_by_jid(jid.full, False, fallback_barejid=False)
+ 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)
if not tab and not muc:
tab = self.core.open_conversation_window(jid.full, focus=True)
@@ -977,8 +989,8 @@ class CommandCore:
list_tab = tabs.AdhocCommandsListTab(self.core, jid)
self.core.add_tab(list_tab, True)
cb = list_tab.on_list_received
- self.core.xmpp.plugin['xep_0050'].get_commands(jid=jid, local=False,
- callback=cb)
+ self.core.xmpp.plugin['xep_0050'].get_commands(
+ jid=jid, local=False, callback=cb)
@command_args_parser.ignored
def self_(self):
@@ -990,15 +1002,11 @@ class CommandCore:
nick = self.core.own_nick
jid = self.core.xmpp.boundjid.full
info = ('Your JID is %s\nYour current status is "%s" (%s)'
- '\nYour default nickname is %s\nYou are running poezio %s' % (
- jid,
- message if message else '',
- show if show else 'available',
- nick,
- config_opts.version))
+ '\nYour default nickname is %s\nYou are running poezio %s' %
+ (jid, message if message else '', show
+ if show else 'available', nick, config_opts.version))
self.core.information(info, 'Info')
-
@command_args_parser.ignored
def reload(self):
"""
@@ -1006,6 +1014,6 @@ class CommandCore:
"""
self.core.reload_config()
+
def dumb_callback(*args, **kwargs):
"mock callback"
-
diff --git a/poezio/core/completions.py b/poezio/core/completions.py
index 634ab6b3..5e7e510f 100644
--- a/poezio/core/completions.py
+++ b/poezio/core/completions.py
@@ -17,13 +17,15 @@ from poezio.roster import roster
from poezio.core.structs import POSSIBLE_SHOW, Completion
+
class CompletionCore:
def __init__(self, core):
self.core = core
def help(self, the_input):
"""Completion for /help."""
- commands = sorted(self.core.commands.keys()) + sorted(self.core.current_tab().commands.keys())
+ commands = sorted(self.core.commands.keys()) + sorted(
+ self.core.current_tab().commands.keys())
return Completion(the_input.new_completion, commands, 1, quotify=False)
def status(self, the_input):
@@ -31,8 +33,11 @@ class CompletionCore:
Completion of /status
"""
if the_input.get_argument_position() == 1:
- return Completion(the_input.new_completion, [status for status in POSSIBLE_SHOW], 1, ' ', quotify=False)
-
+ return Completion(
+ the_input.new_completion, [status for status in POSSIBLE_SHOW],
+ 1,
+ ' ',
+ quotify=False)
def presence(self, the_input):
"""
@@ -40,29 +45,38 @@ class CompletionCore:
"""
arg = the_input.get_argument_position()
if arg == 1:
- return Completion(the_input.auto_completion, [jid for jid in roster.jids()], '', quotify=True)
+ return Completion(
+ the_input.auto_completion, [jid for jid in roster.jids()],
+ '',
+ quotify=True)
elif arg == 2:
- return Completion(the_input.auto_completion, [status for status in POSSIBLE_SHOW], '', quotify=True)
-
+ return Completion(
+ the_input.auto_completion,
+ [status for status in POSSIBLE_SHOW],
+ '',
+ quotify=True)
def theme(self, the_input):
""" Completion for /theme"""
themes_dir = config.get('themes_dir')
- themes_dir = (themes_dir or
- os.path.join(os.environ.get('XDG_DATA_HOME') or
- os.path.join(os.environ.get('HOME'), '.local', 'share'),
- 'poezio', 'themes'))
+ themes_dir = (themes_dir or os.path.join(
+ os.environ.get('XDG_DATA_HOME')
+ or os.path.join(os.environ.get('HOME'), '.local', 'share'),
+ 'poezio', 'themes'))
themes_dir = os.path.expanduser(themes_dir)
try:
names = os.listdir(themes_dir)
except OSError:
log.error('Completion for /theme failed', exc_info=True)
return False
- theme_files = [name[:-3] for name in names if name.endswith('.py') and name != '__init__.py']
+ theme_files = [
+ name[:-3] for name in names
+ if name.endswith('.py') and name != '__init__.py'
+ ]
if 'default' not in theme_files:
theme_files.append('default')
- return Completion(the_input.new_completion, theme_files, 1, '', quotify=False)
-
+ return Completion(
+ the_input.new_completion, theme_files, 1, '', quotify=False)
def win(self, the_input):
"""Completion for /win"""
@@ -72,7 +86,6 @@ class CompletionCore:
l = [i[1] for i in l]
return Completion(the_input.new_completion, l, 1, '', quotify=False)
-
def join(self, the_input):
"""
Completion for /join
@@ -97,7 +110,9 @@ class CompletionCore:
relevant_rooms = []
relevant_rooms.extend(sorted(self.core.pending_invites.keys()))
- bookmarks = [(str(elem.jid) if not elem.nick else '%s/%s' % (elem.jid, elem.nick)) for elem in self.core.bookmarks]
+ bookmarks = [(str(elem.jid)
+ if not elem.nick else '%s/%s' % (elem.jid, elem.nick))
+ for elem in self.core.bookmarks]
to_suggest = []
for bookmark in bookmarks:
tab = self.core.get_tab_by_name(bookmark, tabs.MucTab)
@@ -113,31 +128,39 @@ 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)
+ return Completion(
+ the_input.new_completion, serv_list, 1, quotify=True)
elif args[1].startswith('/'):
# we completing only a resource
- return Completion(the_input.new_completion, ['/%s' % self.core.own_nick], 1, quotify=True)
+ return Completion(
+ the_input.new_completion, ['/%s' % self.core.own_nick],
+ 1,
+ quotify=True)
else:
- return Completion(the_input.new_completion, relevant_rooms, 1, quotify=True)
-
+ return Completion(
+ the_input.new_completion, relevant_rooms, 1, quotify=True)
def version(self, the_input):
"""Completion for /version"""
- comp = reduce(lambda x, y: x + [i.jid for i in y], (roster[jid].resources for jid in roster.jids() if len(roster[jid])), [])
- return Completion(the_input.new_completion, sorted(comp), 1, quotify=False)
-
+ comp = reduce(lambda x, y: x + [i.jid for i in y],
+ (roster[jid].resources for jid in roster.jids()
+ if len(roster[jid])), [])
+ return Completion(
+ the_input.new_completion, sorted(comp), 1, quotify=False)
def list(self, the_input):
"""Completion for /list"""
muc_serv_list = []
- for tab in self.core.get_tabs(tabs.MucTab): # TODO, also from an history
+ for tab in self.core.get_tabs(
+ tabs.MucTab): # TODO, also from an history
if tab.name not in muc_serv_list:
muc_serv_list.append(safeJID(tab.name).server)
if muc_serv_list:
- return Completion(the_input.new_completion, muc_serv_list, 1, quotify=False)
-
+ return Completion(
+ the_input.new_completion, muc_serv_list, 1, quotify=False)
def move_tab(self, the_input):
"""Completion for /move_tab"""
@@ -145,8 +168,8 @@ class CompletionCore:
if n == 1:
nodes = [tab.name for tab in self.core.tabs if tab]
nodes.remove('Roster')
- return Completion(the_input.new_completion, nodes, 1, ' ', quotify=True)
-
+ return Completion(
+ the_input.new_completion, nodes, 1, ' ', quotify=True)
def runkey(self, the_input):
"""
@@ -157,14 +180,14 @@ class CompletionCore:
list_.extend(self.core.current_tab().key_func.keys())
return Completion(the_input.new_completion, list_, 1, quotify=False)
-
def bookmark(self, the_input):
"""Completion for /bookmark"""
args = common.shell_split(the_input.text)
n = the_input.get_argument_position(quoted=True)
if n == 2:
- return Completion(the_input.new_completion, ['true', 'false'], 2, quotify=True)
+ return Completion(
+ the_input.new_completion, ['true', 'false'], 2, quotify=True)
if n >= 3:
return False
@@ -175,7 +198,8 @@ class CompletionCore:
if jid.server and (jid.resource or jid.full.endswith('/')):
tab = self.core.get_tab_by_name(jid.bare, tabs.MucTab)
nicks = [tab.own_nick] if tab else []
- default = os.environ.get('USER') if os.environ.get('USER') else 'poezio'
+ default = os.environ.get('USER') if os.environ.get(
+ 'USER') else 'poezio'
nick = config.get('default_nick')
if not nick:
if default not in nicks:
@@ -184,29 +208,37 @@ class CompletionCore:
if nick not in nicks:
nicks.append(nick)
jids_list = ['%s/%s' % (jid.bare, nick) for nick in nicks]
- return Completion(the_input.new_completion, jids_list, 1, quotify=True)
+ return Completion(
+ the_input.new_completion, jids_list, 1, quotify=True)
muc_list = [tab.name for tab in self.core.get_tabs(tabs.MucTab)]
muc_list.sort()
muc_list.append('*')
return Completion(the_input.new_completion, muc_list, 1, quotify=True)
-
def remove_bookmark(self, the_input):
"""Completion for /remove_bookmark"""
- return Completion(the_input.new_completion, [bm.jid for bm in self.core.bookmarks], 1, quotify=False)
-
+ return Completion(
+ the_input.new_completion, [bm.jid for bm in self.core.bookmarks],
+ 1,
+ quotify=False)
def decline(self, the_input):
"""Completion for /decline"""
n = the_input.get_argument_position(quoted=True)
if n == 1:
- return Completion(the_input.auto_completion, sorted(self.core.pending_invites.keys()), 1, '', quotify=True)
-
+ return Completion(
+ the_input.auto_completion,
+ sorted(self.core.pending_invites.keys()),
+ 1,
+ '',
+ quotify=True)
def bind(self, the_input):
n = the_input.get_argument_position()
if n == 1:
- args = [key for key in self.core.key_func if not key.startswith('_')]
+ args = [
+ key for key in self.core.key_func if not key.startswith('_')
+ ]
elif n == 2:
args = [key for key in self.core.key_func]
else:
@@ -214,7 +246,6 @@ class CompletionCore:
return Completion(the_input.new_completion, args, n, '', quotify=False)
-
def message(self, the_input):
"""Completion for /message"""
n = the_input.get_argument_position(quoted=True)
@@ -231,14 +262,17 @@ class CompletionCore:
l.append(jid)
return Completion(the_input.new_completion, l, 1, '', quotify=True)
-
def invite(self, the_input):
"""Completion for /invite"""
n = the_input.get_argument_position(quoted=True)
if n == 1:
- comp = reduce(lambda x, y: x + [i.jid for i in y], (roster[jid].resources for jid in roster.jids() if len(roster[jid])), [])
+ comp = reduce(lambda x, y: x + [i.jid for i in y],
+ (roster[jid].resources for jid in roster.jids()
+ if len(roster[jid])), [])
comp = sorted(comp)
- bares = sorted(roster[contact].bare_jid for contact in roster.jids() if len(roster[contact]))
+ bares = sorted(
+ roster[contact].bare_jid for contact in roster.jids()
+ if len(roster[contact]))
off = sorted(jid for jid in roster.jids() if jid not in bares)
comp = comp + bares + off
return Completion(the_input.new_completion, comp, n, quotify=True)
@@ -248,15 +282,19 @@ class CompletionCore:
if tab.joined:
rooms.append(tab.name)
rooms.sort()
- return Completion(the_input.new_completion, rooms, n, '', quotify=True)
-
+ return Completion(
+ the_input.new_completion, rooms, n, '', quotify=True)
def activity(self, the_input):
"""Completion for /activity"""
n = the_input.get_argument_position(quoted=True)
args = common.shell_split(the_input.text)
if n == 1:
- return Completion(the_input.new_completion, sorted(pep.ACTIVITIES.keys()), n, quotify=True)
+ return Completion(
+ the_input.new_completion,
+ sorted(pep.ACTIVITIES.keys()),
+ n,
+ quotify=True)
elif n == 2:
if args[1] in pep.ACTIVITIES:
l = list(pep.ACTIVITIES[args[1]])
@@ -264,13 +302,15 @@ class CompletionCore:
l.sort()
return Completion(the_input.new_completion, l, n, quotify=True)
-
def mood(self, the_input):
"""Completion for /mood"""
n = the_input.get_argument_position(quoted=True)
if n == 1:
- return Completion(the_input.new_completion, sorted(pep.MOODS.keys()), 1, quotify=True)
-
+ return Completion(
+ the_input.new_completion,
+ sorted(pep.MOODS.keys()),
+ 1,
+ quotify=True)
def last_activity(self, the_input):
"""
@@ -279,9 +319,11 @@ class CompletionCore:
n = the_input.get_argument_position(quoted=False)
if n >= 2:
return False
- comp = reduce(lambda x, y: x + [i.jid for i in y], (roster[jid].resources for jid in roster.jids() if len(roster[jid])), [])
- return Completion(the_input.new_completion, sorted(comp), 1, '', quotify=False)
-
+ comp = reduce(lambda x, y: x + [i.jid for i in y],
+ (roster[jid].resources for jid in roster.jids()
+ if len(roster[jid])), [])
+ return Completion(
+ the_input.new_completion, sorted(comp), 1, '', quotify=False)
def server_cycle(self, the_input):
"""Completion for /server_cycle"""
@@ -291,7 +333,6 @@ class CompletionCore:
serv_list.add(serv)
return Completion(the_input.new_completion, sorted(serv_list), 1, ' ')
-
def set(self, the_input):
"""Completion for /set"""
args = common.shell_split(the_input.text)
@@ -302,9 +343,13 @@ class CompletionCore:
if '|' in args[1]:
plugin_name, section = args[1].split('|')[:2]
if plugin_name not in self.core.plugin_manager.plugins:
- return Completion(the_input.new_completion, [], n, quotify=True)
+ return Completion(
+ the_input.new_completion, [], n, quotify=True)
plugin = self.core.plugin_manager.plugins[plugin_name]
- end_list = ['%s|%s' % (plugin_name, section) for section in plugin.config.sections()]
+ end_list = [
+ '%s|%s' % (plugin_name, section)
+ for section in plugin.config.sections()
+ ]
else:
end_list = set(config.options('Poezio'))
end_list.update(config.default.get('Poezio', {}))
@@ -314,11 +359,13 @@ class CompletionCore:
if '|' in args[1]:
plugin_name, section = args[1].split('|')[:2]
if plugin_name not in self.core.plugin_manager.plugins:
- return Completion(the_input.new_completion, [''], n, quotify=True)
+ return Completion(
+ the_input.new_completion, [''], n, quotify=True)
plugin = self.core.plugin_manager.plugins[plugin_name]
end_list = set(plugin.config.options(section or plugin_name))
if plugin.config.default:
- end_list.update(plugin.config.default.get(section or plugin_name, {}))
+ end_list.update(
+ plugin.config.default.get(section or plugin_name, {}))
end_list = list(end_list)
end_list.sort()
elif not config.has_option('Poezio', args[1]):
@@ -333,9 +380,14 @@ class CompletionCore:
if '|' in args[1]:
plugin_name, section = args[1].split('|')[:2]
if plugin_name not in self.core.plugin_manager.plugins:
- return Completion(the_input.new_completion, [''], n, quotify=True)
+ return Completion(
+ the_input.new_completion, [''], n, quotify=True)
plugin = self.core.plugin_manager.plugins[plugin_name]
- end_list = [str(plugin.config.get(args[2], '', section or plugin_name)), '']
+ end_list = [
+ str(
+ plugin.config.get(args[2], '', section
+ or plugin_name)), ''
+ ]
else:
if not config.has_section(args[1]):
end_list = ['']
@@ -345,7 +397,6 @@ class CompletionCore:
return False
return Completion(the_input.new_completion, end_list, n, quotify=True)
-
def set_default(self, the_input):
""" Completion for /set_default
"""
@@ -357,11 +408,13 @@ class CompletionCore:
return Completion(self.set, the_input)
return False
-
def toggle(self, the_input):
"Completion for /toggle"
- return Completion(the_input.new_completion, config.options('Poezio'), 1, quotify=False)
-
+ return Completion(
+ the_input.new_completion,
+ config.options('Poezio'),
+ 1,
+ quotify=False)
def bookmark_local(self, the_input):
"""Completion for /bookmark_local"""
@@ -377,7 +430,8 @@ class CompletionCore:
if jid.server and (jid.resource or jid.full.endswith('/')):
tab = self.core.get_tab_by_name(jid.bare, tabs.MucTab)
nicks = [tab.own_nick] if tab else []
- default = os.environ.get('USER') if os.environ.get('USER') else 'poezio'
+ default = os.environ.get('USER') if os.environ.get(
+ 'USER') else 'poezio'
nick = config.get('default_nick')
if not nick:
if default not in nicks:
@@ -386,8 +440,8 @@ class CompletionCore:
if nick not in nicks:
nicks.append(nick)
jids_list = ['%s/%s' % (jid.bare, nick) for nick in nicks]
- return Completion(the_input.new_completion, jids_list, 1, quotify=True)
+ return Completion(
+ the_input.new_completion, jids_list, 1, quotify=True)
muc_list = [tab.name for tab in self.core.get_tabs(tabs.MucTab)]
muc_list.append('*')
return Completion(the_input.new_completion, muc_list, 1, quotify=True)
-
diff --git a/poezio/core/core.py b/poezio/core/core.py
index 33bbbc54..7678c747 100644
--- a/poezio/core/core.py
+++ b/poezio/core/core.py
@@ -66,8 +66,7 @@ class Core(object):
self.stdscr = None
status = config.get('status')
status = POSSIBLE_SHOW.get(status, None)
- self.status = Status(show=status,
- message=config.get('status_message'))
+ self.status = Status(show=status, message=config.get('status_message'))
self.running = True
self.xmpp = connection.Connection()
self.xmpp.core = self
@@ -81,7 +80,8 @@ class Core(object):
# that are displayed in almost all tabs, in an
# information window.
self.information_buffer = TextBuffer()
- self.information_win_size = config.get('info_win_height', section='var')
+ self.information_win_size = config.get(
+ 'info_win_height', section='var')
self.information_win = windows.TextWin(300)
self.information_buffer.add_window(self.information_win)
self.left_tab_win = None
@@ -164,7 +164,7 @@ class Core(object):
'M-D': self.scroll_info_up,
'M-C': self.scroll_info_down,
'M-k': self.escape_next_key,
- ######## actions mappings ##########
+ ######## actions mappings ##########
'_noop': lambda *args, **kwargs: None,
'_bookmark': self.command.bookmark,
'_bookmark_local': self.command.bookmark_local,
@@ -188,25 +188,30 @@ class Core(object):
'_show_plugins': self.command.plugins,
'_show_xmltab': self.command.xml_tab,
'_toggle_pane': self.toggle_left_pane,
- ###### status actions ######
+ ###### status actions ######
'_available': lambda: self.command.status('available'),
'_away': lambda: self.command.status('away'),
'_chat': lambda: self.command.status('chat'),
'_dnd': lambda: self.command.status('dnd'),
'_xa': lambda: self.command.status('xa'),
- ##### Custom actions ########
+ ##### Custom actions ########
'_exc_': self.try_execute,
}
self.key_func.update(key_func)
# Add handlers
self.xmpp.add_event_handler('connected', self.handler.on_connected)
- self.xmpp.add_event_handler('connection_failed', self.handler.on_failed_connection)
- self.xmpp.add_event_handler('disconnected', self.handler.on_disconnected)
- self.xmpp.add_event_handler('stream_error', self.handler.on_stream_error)
- self.xmpp.add_event_handler('failed_all_auth', self.handler.on_failed_all_auth)
+ self.xmpp.add_event_handler('connection_failed',
+ self.handler.on_failed_connection)
+ self.xmpp.add_event_handler('disconnected',
+ self.handler.on_disconnected)
+ self.xmpp.add_event_handler('stream_error',
+ self.handler.on_stream_error)
+ self.xmpp.add_event_handler('failed_all_auth',
+ self.handler.on_failed_all_auth)
self.xmpp.add_event_handler('no_auth', self.handler.on_no_auth)
- self.xmpp.add_event_handler("session_start", self.handler.on_session_start)
+ self.xmpp.add_event_handler("session_start",
+ self.handler.on_session_start)
self.xmpp.add_event_handler("session_start",
self.handler.on_session_start_features)
self.xmpp.add_event_handler("groupchat_presence",
@@ -215,8 +220,9 @@ class Core(object):
self.handler.on_groupchat_message)
self.xmpp.add_event_handler("groupchat_invite",
self.handler.on_groupchat_invitation)
- self.xmpp.add_event_handler("groupchat_direct_invite",
- self.handler.on_groupchat_direct_invitation)
+ self.xmpp.add_event_handler(
+ "groupchat_direct_invite",
+ self.handler.on_groupchat_direct_invitation)
self.xmpp.add_event_handler("groupchat_decline",
self.handler.on_groupchat_decline)
self.xmpp.add_event_handler("groupchat_config_status",
@@ -224,13 +230,17 @@ class Core(object):
self.xmpp.add_event_handler("groupchat_subject",
self.handler.on_groupchat_subject)
self.xmpp.add_event_handler("message", self.handler.on_message)
- self.xmpp.add_event_handler("message_error", self.handler.on_error_message)
- self.xmpp.add_event_handler("receipt_received", self.handler.on_receipt)
+ self.xmpp.add_event_handler("message_error",
+ self.handler.on_error_message)
+ self.xmpp.add_event_handler("receipt_received",
+ self.handler.on_receipt)
self.xmpp.add_event_handler("got_online", self.handler.on_got_online)
self.xmpp.add_event_handler("got_offline", self.handler.on_got_offline)
- self.xmpp.add_event_handler("roster_update", self.handler.on_roster_update)
+ self.xmpp.add_event_handler("roster_update",
+ self.handler.on_roster_update)
self.xmpp.add_event_handler("changed_status", self.handler.on_presence)
- self.xmpp.add_event_handler("presence_error", self.handler.on_presence_error)
+ self.xmpp.add_event_handler("presence_error",
+ self.handler.on_presence_error)
self.xmpp.add_event_handler("roster_subscription_request",
self.handler.on_subscription_request)
self.xmpp.add_event_handler("roster_subscription_authorized",
@@ -252,8 +262,10 @@ class Core(object):
self.handler.on_chatstate_inactive)
self.xmpp.add_event_handler("attention", self.handler.on_attention)
self.xmpp.add_event_handler("ssl_cert", self.handler.validate_ssl)
- self.xmpp.add_event_handler("ssl_invalid_chain", self.handler.ssl_invalid_chain)
- self.xmpp.add_event_handler('carbon_received', self.handler.on_carbon_received)
+ self.xmpp.add_event_handler("ssl_invalid_chain",
+ self.handler.ssl_invalid_chain)
+ self.xmpp.add_event_handler('carbon_received',
+ self.handler.on_carbon_received)
self.xmpp.add_event_handler('carbon_sent', self.handler.on_carbon_sent)
self.xmpp.add_event_handler('http_confirm', self.handler.http_confirm)
@@ -315,14 +327,11 @@ class Core(object):
self.xmpp.set_keepalive_values)
self.add_configuration_handler("connection_check_interval",
self.xmpp.set_keepalive_values)
- self.add_configuration_handler("themes_dir",
- theming.update_themes_dir)
- self.add_configuration_handler("theme",
- self.on_theme_config_change)
+ self.add_configuration_handler("themes_dir", theming.update_themes_dir)
+ self.add_configuration_handler("theme", self.on_theme_config_change)
self.add_configuration_handler("use_bookmarks_method",
self.on_bookmarks_method_config_change)
- self.add_configuration_handler("password",
- self.on_password_change)
+ self.add_configuration_handler("password", self.on_password_change)
self.add_configuration_handler("enable_vertical_tab_list",
self.on_vertical_tab_list_config_change)
self.add_configuration_handler("vertical_tab_list_size",
@@ -394,14 +403,15 @@ class Core(object):
"""
Called when the request_message_receipts option changes
"""
- self.xmpp.plugin['xep_0184'].auto_request = config.get(option,
- default=True)
+ self.xmpp.plugin['xep_0184'].auto_request = config.get(
+ option, default=True)
def on_ack_receipts_config_change(self, option, value):
"""
Called when the ack_message_receipts option changes
"""
- self.xmpp.plugin['xep_0184'].auto_ack = config.get(option, default=True)
+ self.xmpp.plugin['xep_0184'].auto_ack = config.get(
+ option, default=True)
def on_plugins_dir_config_change(self, option, value):
"""
@@ -438,7 +448,6 @@ class Core(object):
"""
self.xmpp.password = value
-
def on_nick_determinism_changed(self, option, value):
"""If we change the value to true, we call /recolor on all the MucTabs, to
make the current nick colors reflect their deterministic value.
@@ -501,10 +510,10 @@ class Core(object):
"""
sig = args[0]
signals = {
- 1: 'SIGHUP',
- 13: 'SIGPIPE',
- 15: 'SIGTERM',
- }
+ 1: 'SIGHUP',
+ 13: 'SIGPIPE',
+ 15: 'SIGTERM',
+ }
log.error("%s received. Exiting…", signals[sig])
if config.get('enable_user_mood'):
@@ -547,13 +556,12 @@ class Core(object):
'The online help is here http://doc.poez.io/\n'
'No room is joined by default, but you can join poezio’s'
' room (with /join poezio@muc.poez.io), where you can'
- ' ask for help or tell us how great it is.',
- 'Help')
+ ' ask for help or tell us how great it is.', 'Help')
self.refresh_window()
self.xmpp.plugin['xep_0012'].begin_idle(jid=self.xmpp.boundjid)
def exit(self, event=None):
- log.debug("exit(%s)", event)
+ log.debug("exit(%s)", event)
asyncio.get_event_loop().stop()
def on_exception(self, typ, value, trace):
@@ -592,11 +600,13 @@ class Core(object):
"""
main loop waiting for the user to press a key
"""
+
def replace_line_breaks(key):
"replace ^J with \n"
if key == '^J':
return '\n'
return key
+
def separate_chars_from_bindings(char_list):
"""
returns a list of lists. For example if you give
@@ -638,7 +648,7 @@ class Core(object):
log.debug("Input is readable.")
big_char_list = [replace_key_with_bound(key)\
for key in self.read_keyboard()]
- log.debug("Got from keyboard: %s", (big_char_list,))
+ log.debug("Got from keyboard: %s", (big_char_list, ))
# whether to refresh after ALL keys have been handled
for char_list in separate_chars_from_bindings(big_char_list):
@@ -651,7 +661,8 @@ class Core(object):
except ValueError:
pass
else:
- if self.current_tab().nb == nb and config.get('go_to_previous_tab_on_alt_number'):
+ if self.current_tab().nb == nb and config.get(
+ 'go_to_previous_tab_on_alt_number'):
self.go_to_previous_tab()
else:
self.command.win('%d' % nb)
@@ -673,12 +684,10 @@ class Core(object):
"""
ok = roster.save_to_config_file()
ok = ok and config.silent_set('info_win_height',
- self.information_win_size,
- 'var')
+ self.information_win_size, 'var')
if not ok:
self.information('Unable to save runtime preferences'
- ' in the config file',
- 'Error')
+ ' in the config file', 'Error')
def on_roster_enter_key(self, roster_row):
"""
@@ -690,9 +699,8 @@ class Core(object):
else:
self.focus_tab_named(roster_row.bare_jid)
if isinstance(roster_row, Resource):
- if not self.get_conversation_by_jid(roster_row.jid,
- False,
- fallback_barejid=False):
+ if not self.get_conversation_by_jid(
+ roster_row.jid, False, fallback_barejid=False):
self.open_conversation_window(roster_row.jid)
else:
self.focus_tab_named(roster_row.jid)
@@ -716,7 +724,6 @@ class Core(object):
"""
self.do_command(text, True)
-
##################### Anything related to command execution ###################
def execute(self, line):
@@ -727,15 +734,14 @@ class Core(object):
return
if line.startswith('/'):
command = line.strip().split()[0][1:]
- arg = line[2+len(command):] # jump the '/' and the ' '
+ arg = line[2 + len(command):] # jump the '/' and the ' '
# example. on "/link 0 open", command = "link" and arg = "0 open"
if command in self.commands:
func = self.commands[command].func
func(arg)
return
else:
- self.information("Unknown command (%s)" % (command),
- 'Error')
+ self.information("Unknown command (%s)" % (command), 'Error')
def exec_command(self, command):
"""
@@ -770,16 +776,15 @@ class Core(object):
fifo_path = config.get('remote_fifo_path')
if not self.remote_fifo:
try:
- self.remote_fifo = Fifo(os.path.join(fifo_path,
- 'poezio.fifo'),
- 'w')
+ self.remote_fifo = Fifo(
+ os.path.join(fifo_path, 'poezio.fifo'), 'w')
except (OSError, IOError) as exc:
- log.error('Could not open the fifo for writing (%s)',
- os.path.join(fifo_path, './', 'poezio.fifo'),
- exc_info=True)
+ log.error(
+ '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')
+ 'file for writing: %s' % exc, 'Error')
return
args = (pipes.quote(arg.replace('\n', ' ')) for arg in command)
@@ -787,10 +792,11 @@ class Core(object):
try:
self.remote_fifo.write(command_str)
except (IOError) as exc:
- log.error('Could not write in the fifo (%s): %s',
- os.path.join(fifo_path, './', 'poezio.fifo'),
- repr(command),
- exc_info=True)
+ log.error(
+ 'Could not write in the fifo (%s): %s',
+ os.path.join(fifo_path, './', 'poezio.fifo'),
+ repr(command),
+ exc_info=True)
self.information('Could not execute %s: %s' % (command, exc),
'Error')
self.remote_fifo = None
@@ -799,12 +805,12 @@ class Core(object):
try:
executor.start()
except ValueError as exc:
- log.error('Could not execute command (%s)',
- repr(command),
- exc_info=True)
+ log.error(
+ 'Could not execute command (%s)',
+ repr(command),
+ exc_info=True)
self.information('%s' % exc, 'Error')
-
def do_command(self, key, raw):
"""
Execute the action associated with a key
@@ -824,7 +830,6 @@ class Core(object):
else:
self.current_tab().on_input(key, raw)
-
def try_execute(self, line):
"""
Try to execute a command in the current tab
@@ -835,7 +840,6 @@ class Core(object):
except:
log.error('Execute failed (%s)', line, exc_info=True)
-
########################## TImed Events #######################################
def remove_timed_event(self, event):
@@ -844,9 +848,8 @@ class Core(object):
def add_timed_event(self, event):
"""Add a new timed event"""
- event.handler = asyncio.get_event_loop().call_later(event.delay,
- event.callback,
- *event.args)
+ event.handler = asyncio.get_event_loop().call_later(
+ event.delay, event.callback, *event.args)
####################### XMPP-related actions ##################################
@@ -894,7 +897,10 @@ class Core(object):
if reconnect:
# Add a one-time event to reconnect as soon as we are
# effectively disconnected
- self.xmpp.add_event_handler('disconnected', lambda event: self.xmpp.connect(), disposable=True)
+ self.xmpp.add_event_handler(
+ 'disconnected',
+ lambda event: self.xmpp.connect(),
+ disposable=True)
def send_message(self, msg):
"""
@@ -913,20 +919,19 @@ class Core(object):
or a mediated one if it does not.
TODO: allow passwords
"""
+
def callback(iq):
if not iq:
return
if 'jabber:x:conference' in iq['disco_info'].get_features():
self.xmpp.plugin['xep_0249'].send_invitation(
- jid,
- room,
- reason=reason)
- else: # fallback
- self.xmpp.plugin['xep_0045'].invite(room, jid,
- reason=reason or '')
+ jid, room, reason=reason)
+ else: # fallback
+ self.xmpp.plugin['xep_0045'].invite(
+ room, jid, reason=reason or '')
- self.xmpp.plugin['xep_0030'].get_info(jid=jid, timeout=5,
- callback=callback)
+ self.xmpp.plugin['xep_0030'].get_info(
+ jid=jid, timeout=5, callback=callback)
def get_error_message(self, stanza, deprecated=False):
"""
@@ -951,16 +956,22 @@ class Core(object):
body = condition or 'Unknown error'
if code:
message = '%(from)s: %(code)s - %(msg)s: %(body)s' % {
- 'from': sender, 'msg': msg, 'body': body, 'code': code}
+ 'from': sender,
+ 'msg': msg,
+ 'body': body,
+ 'code': code
+ }
else:
message = '%(from)s: %(msg)s: %(body)s' % {
- 'from': sender, 'msg': msg, 'body': body}
+ 'from': sender,
+ 'msg': msg,
+ 'body': body
+ }
return message
-
####################### Tab logic-related things ##############################
- ### Tab getters ###
+### Tab getters ###
def get_tabs(self, cls=None):
"Get all the tabs of a type"
@@ -1002,8 +1013,8 @@ class Core(object):
# We create a dynamic conversation with the bare Jid if
# nothing was found (and we lock it to the resource
# later)
- conversation = self.open_conversation_window(jid.bare,
- False)
+ conversation = self.open_conversation_window(
+ jid.bare, False)
else:
conversation = None
return conversation
@@ -1062,7 +1073,8 @@ class Core(object):
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)
+ 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)
@@ -1139,6 +1151,7 @@ class Core(object):
Read 2 more chars and go to the tab
with the given number
"""
+
def read_next_digit(digit):
try:
int(digit)
@@ -1156,6 +1169,7 @@ class Core(object):
else:
# We need to read more digits
keyboard.continuation_keys_callback = read_next_digit
+
keyboard.continuation_keys_callback = read_next_digit
def go_to_roster(self):
@@ -1164,7 +1178,7 @@ class Core(object):
def go_to_previous_tab(self):
"Go to the previous tab"
- self.command.win('%s' % (self.previous_tab_nb,))
+ self.command.win('%s' % (self.previous_tab_nb, ))
def go_to_important_room(self):
"""
@@ -1183,15 +1197,14 @@ class Core(object):
else:
tab_refs[tab.state].append(tab)
# sort the state by priority and remove those with negative priority
- states = sorted(tab_refs.keys(),
- key=(lambda x: priority.get(x, 0)),
- reverse=True)
+ states = sorted(
+ tab_refs.keys(), key=(lambda x: priority.get(x, 0)), reverse=True)
states = [state for state in states if priority.get(state, -1) >= 0]
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.current_tab_nb
+ and tab_refs[state][-1].nb > self.current_tab_nb):
continue
self.command.win('%s' % tab.nb)
return
@@ -1202,7 +1215,7 @@ class Core(object):
for tab in self.tabs:
if tab.name == tab_name:
if (type_ and (isinstance(tab, type_))) or not type_:
- self.command.win('%s' % (tab.nb,))
+ self.command.win('%s' % (tab.nb, ))
return True
return False
@@ -1249,7 +1262,7 @@ class Core(object):
"""
Open a Private conversation in a MUC and focus if needed.
"""
- complete_jid = room_name+'/'+user_nick
+ complete_jid = room_name + '/' + user_nick
# if the room exists, focus it and return
for tab in self.get_tabs(tabs.PrivateTab):
if tab.name == complete_jid:
@@ -1301,12 +1314,14 @@ class Core(object):
if tab:
tab.rename_user(old_nick, user)
- def on_user_left_private_conversation(self, room_name, user, status_message):
+ def on_user_left_private_conversation(self, room_name, user,
+ status_message):
"""
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.get_tab_by_name('%s/%s' % (room_name, user.nick),
+ tabs.PrivateTab)
if tab:
tab.user_left(status_message, user)
@@ -1315,7 +1330,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.get_tab_by_name('%s/%s' % (room_name, nick),
+ tabs.PrivateTab)
if tab:
tab.user_rejoined(nick)
@@ -1352,10 +1368,10 @@ class Core(object):
if tab is None:
tab = self.current_tab()
if isinstance(tab, tabs.RosterInfoTab):
- return # The tab 0 should NEVER be closed
+ 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
+ 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:
@@ -1365,7 +1381,7 @@ class Core(object):
if nb >= len(self.tabs) - 1:
self.tabs.remove(tab)
nb -= 1
- while not self.tabs[nb]: # remove the trailing gaps
+ while not self.tabs[nb]: # remove the trailing gaps
self.tabs.pop()
nb -= 1
else:
@@ -1397,7 +1413,6 @@ class Core(object):
if self.current_tab() is tab:
self.refresh_window()
-
####################### Curses and ui-related stuff ###########################
def doupdate(self):
@@ -1412,18 +1427,21 @@ class Core(object):
"""
filter_types = config.get('information_buffer_type_filter').split(':')
if typ.lower() in filter_types:
- log.debug('Did not show the message:\n\t%s> %s \n\tdue to information_popup_type_filter configuration', typ, msg)
+ log.debug(
+ 'Did not show the message:\n\t%s> %s \n\tdue to information_popup_type_filter configuration',
+ typ, msg)
return False
filter_messages = config.get('filter_info_messages').split(':')
for words in filter_messages:
if words and words in msg:
- log.debug('Did not show the message:\n\t%s> %s \n\tdue to filter_info_messages configuration', typ, msg)
+ log.debug(
+ 'Did not show the message:\n\t%s> %s \n\tdue to filter_info_messages configuration',
+ typ, msg)
return False
colors = get_theme().INFO_COLORS
color = colors.get(typ.lower(), colors.get('default', None))
- nb_lines = self.information_buffer.add_message(msg,
- nickname=typ,
- nick_color=color)
+ 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):
self.refresh_window()
@@ -1449,8 +1467,8 @@ class Core(object):
curses.start_color()
curses.use_default_colors()
theming.reload_theme()
- curses.ungetch(" ") # H4X: without this, the screen is
- stdscr.getkey() # erased on the first "getkey()"
+ curses.ungetch(" ") # H4X: without this, the screen is
+ stdscr.getkey() # erased on the first "getkey()"
def reset_curses(self):
"""
@@ -1604,9 +1622,8 @@ class Core(object):
if time <= 0 or size <= 0:
return
result = self.grow_information_win(size)
- timed_event = timed_events.DelayedEvent(time,
- self.shrink_information_win,
- result)
+ timed_event = timed_events.DelayedEvent(
+ time, self.shrink_information_win, result)
self.add_timed_event(timed_event)
self.refresh_window()
@@ -1627,12 +1644,10 @@ class Core(object):
self.information_win_size = tabs.Tab.height - 6
if tabs.Tab.height < 6:
self.information_win_size = 0
- height = (tabs.Tab.height - 1 - self.information_win_size
- - tabs.Tab.tab_win_height())
- self.information_win.resize(self.information_win_size,
- tabs.Tab.width,
- height,
- 0)
+ height = (tabs.Tab.height - 1 - self.information_win_size -
+ tabs.Tab.tab_win_height())
+ self.information_win.resize(self.information_win_size, tabs.Tab.width,
+ height, 0)
def resize_global_info_bar(self):
"""
@@ -1645,16 +1660,15 @@ class Core(object):
return
try:
height, _ = self.stdscr.getmaxyx()
- truncated_win = self.stdscr.subwin(height,
- config.get('vertical_tab_list_size'),
- 0, 0)
+ truncated_win = self.stdscr.subwin(
+ height, config.get('vertical_tab_list_size'), 0, 0)
except:
log.error('Curses error on infobar resize', exc_info=True)
return
- self.left_tab_win = windows.VerticalGlobalInfoBar(self, truncated_win)
+ self.left_tab_win = windows.VerticalGlobalInfoBar(
+ self, truncated_win)
elif not self.size.core_degrade_y:
- self.tab_win.resize(1, tabs.Tab.width,
- tabs.Tab.height - 2, 0)
+ self.tab_win.resize(1, tabs.Tab.width, tabs.Tab.height - 2, 0)
self.left_tab_win = None
def add_message_to_text_buffer(self, buff, txt, nickname=None):
@@ -1663,7 +1677,8 @@ class Core(object):
(in the Info tab of the info window in the RosterTab)
"""
if not buff:
- self.information('Trying to add a message in no room: %s' % txt, 'Error')
+ self.information('Trying to add a message in no room: %s' % txt,
+ 'Error')
return
buff.add_message(txt, nickname=nickname)
@@ -1683,11 +1698,11 @@ class Core(object):
# the screen that they can occupy, and we draw the tab list on the
# remaining space, on the left
height, width = self.stdscr.getmaxyx()
- if (config.get('enable_vertical_tab_list') and
- not self.size.core_degrade_x):
+ if (config.get('enable_vertical_tab_list')
+ and not self.size.core_degrade_x):
try:
scr = self.stdscr.subwin(0,
- config.get('vertical_tab_list_size'))
+ config.get('vertical_tab_list_size'))
except:
log.error('Curses error on resize', exc_info=True)
return
@@ -1739,227 +1754,300 @@ class Core(object):
"""
Register the commands when poezio starts
"""
- self.register_command('help', self.command.help,
- usage='[command]',
- shortdesc='\\_o< KOIN KOIN KOIN',
- completion=self.completion.help)
- self.register_command('join', self.command.join,
- usage="[room_name][@server][/nick] [password]",
- desc="Join the specified room. You can specify a nickname "
- "after a slash (/). If no nickname is specified, you will"
- " use the default_nick in the configuration file. You can"
- " omit the room name: you will then join the room you\'re"
- " looking at (useful if you were kicked). You can also "
- "provide a room_name without specifying a server, the "
- "server of the room you're currently in will be used. You"
- " can also provide a password to join the room.\nExamples"
- ":\n/join room@server.tld\n/join room@server.tld/John\n"
- "/join room2\n/join /me_again\n/join\n/join room@server"
- ".tld/my_nick password\n/join / password",
- shortdesc='Join a room',
- completion=self.completion.join)
- self.register_command('exit', self.command.quit,
- desc='Just disconnect from the server and exit poezio.',
- shortdesc='Exit poezio.')
- self.register_command('quit', self.command.quit,
- desc='Just disconnect from the server and exit poezio.',
- shortdesc='Exit poezio.')
- self.register_command('next', self.rotate_rooms_right,
- shortdesc='Go to the next room.')
- self.register_command('prev', self.rotate_rooms_left,
- shortdesc='Go to the previous room.')
- self.register_command('win', self.command.win,
- usage='<number or name>',
- shortdesc='Go to the specified room',
- completion=self.completion.win)
+ self.register_command(
+ 'help',
+ self.command.help,
+ usage='[command]',
+ shortdesc='\\_o< KOIN KOIN KOIN',
+ completion=self.completion.help)
+ self.register_command(
+ 'join',
+ self.command.join,
+ usage="[room_name][@server][/nick] [password]",
+ desc="Join the specified room. You can specify a nickname "
+ "after a slash (/). If no nickname is specified, you will"
+ " use the default_nick in the configuration file. You can"
+ " omit the room name: you will then join the room you\'re"
+ " looking at (useful if you were kicked). You can also "
+ "provide a room_name without specifying a server, the "
+ "server of the room you're currently in will be used. You"
+ " can also provide a password to join the room.\nExamples"
+ ":\n/join room@server.tld\n/join room@server.tld/John\n"
+ "/join room2\n/join /me_again\n/join\n/join room@server"
+ ".tld/my_nick password\n/join / password",
+ shortdesc='Join a room',
+ completion=self.completion.join)
+ self.register_command(
+ 'exit',
+ self.command.quit,
+ desc='Just disconnect from the server and exit poezio.',
+ shortdesc='Exit poezio.')
+ self.register_command(
+ 'quit',
+ self.command.quit,
+ desc='Just disconnect from the server and exit poezio.',
+ shortdesc='Exit poezio.')
+ self.register_command(
+ 'next', self.rotate_rooms_right, shortdesc='Go to the next room.')
+ self.register_command(
+ 'prev',
+ self.rotate_rooms_left,
+ shortdesc='Go to the previous room.')
+ self.register_command(
+ 'win',
+ self.command.win,
+ usage='<number or name>',
+ shortdesc='Go to the specified room',
+ completion=self.completion.win)
self.commands['w'] = self.commands['win']
- self.register_command('move_tab', self.command.move_tab,
- usage='<source> <destination>',
- desc="Insert the <source> tab at the position of "
- "<destination>. This will make the following tabs shift in"
- " some cases (refer to the documentation). A tab can be "
- "designated by its number or by the beginning of its "
- "address. You can use \".\" as a shortcut for the current "
- "tab.",
- shortdesc='Move a tab.',
- completion=self.completion.move_tab)
- self.register_command('destroy_room', self.command.destroy_room,
- usage='[room JID]',
- desc='Try to destroy the room [room JID], or the current'
- ' tab if it is a multi-user chat and [room JID] is '
- 'not given.',
- shortdesc='Destroy a room.',
- completion=None)
- self.register_command('show', self.command.status,
- usage='<availability> [status message]',
- desc="Sets your availability and (optionally) your status "
- "message. The <availability> argument is one of \"available"
- ", chat, away, afk, dnd, busy, xa\" and the optional "
- "[status message] argument will be your status message.",
- shortdesc='Change your availability.',
- completion=self.completion.status)
+ self.register_command(
+ 'move_tab',
+ self.command.move_tab,
+ usage='<source> <destination>',
+ desc="Insert the <source> tab at the position of "
+ "<destination>. This will make the following tabs shift in"
+ " some cases (refer to the documentation). A tab can be "
+ "designated by its number or by the beginning of its "
+ "address. You can use \".\" as a shortcut for the current "
+ "tab.",
+ shortdesc='Move a tab.',
+ completion=self.completion.move_tab)
+ self.register_command(
+ 'destroy_room',
+ self.command.destroy_room,
+ usage='[room JID]',
+ desc='Try to destroy the room [room JID], or the current'
+ ' tab if it is a multi-user chat and [room JID] is '
+ 'not given.',
+ shortdesc='Destroy a room.',
+ completion=None)
+ self.register_command(
+ 'show',
+ self.command.status,
+ usage='<availability> [status message]',
+ desc="Sets your availability and (optionally) your status "
+ "message. The <availability> argument is one of \"available"
+ ", chat, away, afk, dnd, busy, xa\" and the optional "
+ "[status message] argument will be your status message.",
+ shortdesc='Change your availability.',
+ completion=self.completion.status)
self.commands['status'] = self.commands['show']
- self.register_command('bookmark_local', self.command.bookmark_local,
- usage="[roomname][/nick] [password]",
- desc="Bookmark Local: Bookmark locally the specified room "
- "(you will then auto-join it on each poezio start). This"
- " commands uses almost the same syntaxe as /join. Type "
- "/help join for syntax examples. Note that when typing "
- "\"/bookmark\" on its own, the room will be bookmarked "
- "with the nickname you\'re currently using in this room "
- "(instead of default_nick)",
- shortdesc='Bookmark a room locally.',
- completion=self.completion.bookmark_local)
- self.register_command('bookmark', self.command.bookmark,
- usage="[roomname][/nick] [autojoin] [password]",
- desc="Bookmark: Bookmark online the specified room (you "
- "will then auto-join it on each poezio start if autojoin"
- " is specified and is 'true'). This commands uses almost"
- " the same syntax as /join. Type /help join for syntax "
- "examples. Note that when typing \"/bookmark\" alone, the"
- " room will be bookmarked with the nickname you\'re "
- "currently using in this room (instead of default_nick).",
- shortdesc="Bookmark a room online.",
- completion=self.completion.bookmark)
- self.register_command('set', self.command.set,
- usage="[plugin|][section] <option> [value]",
- desc="Set the value of an option in your configuration file."
- " You can, for example, change your default nickname by "
- "doing `/set default_nick toto` or your resource with `/set"
- " resource blabla`. You can also set options in specific "
- "sections with `/set bindings M-i ^i` or in specific plugin"
- " with `/set mpd_client| host 127.0.0.1`. `toggle` can be "
- "used as a special value to toggle a boolean option.",
- shortdesc="Set the value of an option",
- completion=self.completion.set)
- self.register_command('set_default', self.command.set_default,
- usage="[section] <option>",
- desc="Set the default value of an option. For example, "
- "`/set_default resource` will reset the resource "
- "option. You can also reset options in specific "
- "sections by doing `/set_default section option`.",
- shortdesc="Set the default value of an option",
- completion=self.completion.set_default)
- self.register_command('toggle', self.command.toggle,
- usage='<option>',
- desc='Shortcut for /set <option> toggle',
- shortdesc='Toggle an option',
- completion=self.completion.toggle)
- self.register_command('theme', self.command.theme,
- usage='[theme name]',
- desc="Reload the theme defined in the config file. If theme"
- "_name is provided, set that theme before reloading it.",
- shortdesc='Load a theme',
- completion=self.completion.theme)
- self.register_command('list', self.command.list,
- usage='[server]',
- desc="Get the list of public rooms"
- " on the specified server.",
- shortdesc='List the rooms.',
- completion=self.completion.list)
- self.register_command('message', self.command.message,
- usage='<jid> [optional message]',
- desc="Open a conversation with the specified JID (even if it"
- " is not in our roster), and send a message to it, if the "
- "message is specified.",
- shortdesc='Send a message',
- completion=self.completion.message)
- self.register_command('version', self.command.version,
- usage='<jid>',
- desc="Get the software version of the given JID (usually its"
- " XMPP client and Operating System).",
- shortdesc='Get the software version of a JID.',
- completion=self.completion.version)
- self.register_command('server_cycle', self.command.server_cycle,
- usage='[domain] [message]',
- desc='Disconnect and reconnect in all the rooms in domain.',
- shortdesc='Cycle a range of rooms',
- completion=self.completion.server_cycle)
- self.register_command('bind', self.command.bind,
- usage='<key> <equ>',
- desc="Bind a key to another key or to a “command”. For "
- "example \"/bind ^H KEY_UP\" makes Control + h do the"
- " same same as the Up key.",
- completion=self.completion.bind,
- shortdesc='Bind a key to another key.')
- self.register_command('load', self.command.load,
- usage='<plugin> [<otherplugin> …]',
- shortdesc='Load the specified plugin(s)',
- completion=self.plugin_manager.completion_load)
- self.register_command('unload', self.command.unload,
- usage='<plugin> [<otherplugin> …]',
- shortdesc='Unload the specified plugin(s)',
- completion=self.plugin_manager.completion_unload)
- self.register_command('plugins', self.command.plugins,
- shortdesc='Show the plugins in use.')
- self.register_command('presence', self.command.presence,
- usage='<JID> [type] [status]',
- desc="Send a directed presence to <JID> and using"
- " [type] and [status] if provided.",
- shortdesc='Send a directed presence.',
- completion=self.completion.presence)
- self.register_command('rawxml', self.command.rawxml,
- usage='<xml>',
- shortdesc='Send a custom xml stanza.')
- self.register_command('invite', self.command.invite,
- usage='<jid> <room> [reason]',
- desc='Invite jid in room with reason.',
- shortdesc='Invite someone in a room.',
- completion=self.completion.invite)
- self.register_command('invitations', self.command.invitations,
- shortdesc='Show the pending invitations.')
- self.register_command('bookmarks', self.command.bookmarks,
- shortdesc='Show the current bookmarks.')
- self.register_command('remove_bookmark', self.command.remove_bookmark,
- usage='[jid]',
- desc="Remove the specified bookmark, or the "
- "bookmark on the current tab, if any.",
- shortdesc='Remove a bookmark',
- completion=self.completion.remove_bookmark)
- self.register_command('xml_tab', self.command.xml_tab,
- shortdesc='Open an XML tab.')
- self.register_command('runkey', self.command.runkey,
- usage='<key>',
- shortdesc='Execute the action defined for <key>.',
- completion=self.completion.runkey)
- self.register_command('self', self.command.self_,
- shortdesc='Remind you of who you are.')
- self.register_command('last_activity', self.command.last_activity,
- usage='<jid>',
- desc='Informs you of the last activity of a JID.',
- shortdesc='Get the activity of someone.',
- completion=self.completion.last_activity)
- self.register_command('ad-hoc', self.command.adhoc,
- usage='<jid>',
- shortdesc='List available ad-hoc commands on the given jid')
- self.register_command('reload', self.command.reload,
- shortdesc='Reload the config. You can achieve the same by '
- 'sending SIGUSR1 to poezio.')
+ self.register_command(
+ 'bookmark_local',
+ self.command.bookmark_local,
+ usage="[roomname][/nick] [password]",
+ desc="Bookmark Local: Bookmark locally the specified room "
+ "(you will then auto-join it on each poezio start). This"
+ " commands uses almost the same syntaxe as /join. Type "
+ "/help join for syntax examples. Note that when typing "
+ "\"/bookmark\" on its own, the room will be bookmarked "
+ "with the nickname you\'re currently using in this room "
+ "(instead of default_nick)",
+ shortdesc='Bookmark a room locally.',
+ completion=self.completion.bookmark_local)
+ self.register_command(
+ 'bookmark',
+ self.command.bookmark,
+ usage="[roomname][/nick] [autojoin] [password]",
+ desc="Bookmark: Bookmark online the specified room (you "
+ "will then auto-join it on each poezio start if autojoin"
+ " is specified and is 'true'). This commands uses almost"
+ " the same syntax as /join. Type /help join for syntax "
+ "examples. Note that when typing \"/bookmark\" alone, the"
+ " room will be bookmarked with the nickname you\'re "
+ "currently using in this room (instead of default_nick).",
+ shortdesc="Bookmark a room online.",
+ completion=self.completion.bookmark)
+ self.register_command(
+ 'set',
+ self.command.set,
+ usage="[plugin|][section] <option> [value]",
+ desc="Set the value of an option in your configuration file."
+ " You can, for example, change your default nickname by "
+ "doing `/set default_nick toto` or your resource with `/set"
+ " resource blabla`. You can also set options in specific "
+ "sections with `/set bindings M-i ^i` or in specific plugin"
+ " with `/set mpd_client| host 127.0.0.1`. `toggle` can be "
+ "used as a special value to toggle a boolean option.",
+ shortdesc="Set the value of an option",
+ completion=self.completion.set)
+ self.register_command(
+ 'set_default',
+ self.command.set_default,
+ usage="[section] <option>",
+ desc="Set the default value of an option. For example, "
+ "`/set_default resource` will reset the resource "
+ "option. You can also reset options in specific "
+ "sections by doing `/set_default section option`.",
+ shortdesc="Set the default value of an option",
+ completion=self.completion.set_default)
+ self.register_command(
+ 'toggle',
+ self.command.toggle,
+ usage='<option>',
+ desc='Shortcut for /set <option> toggle',
+ shortdesc='Toggle an option',
+ completion=self.completion.toggle)
+ self.register_command(
+ 'theme',
+ self.command.theme,
+ usage='[theme name]',
+ desc="Reload the theme defined in the config file. If theme"
+ "_name is provided, set that theme before reloading it.",
+ shortdesc='Load a theme',
+ completion=self.completion.theme)
+ self.register_command(
+ 'list',
+ self.command.list,
+ usage='[server]',
+ desc="Get the list of public rooms"
+ " on the specified server.",
+ shortdesc='List the rooms.',
+ completion=self.completion.list)
+ self.register_command(
+ 'message',
+ self.command.message,
+ usage='<jid> [optional message]',
+ desc="Open a conversation with the specified JID (even if it"
+ " is not in our roster), and send a message to it, if the "
+ "message is specified.",
+ shortdesc='Send a message',
+ completion=self.completion.message)
+ self.register_command(
+ 'version',
+ self.command.version,
+ usage='<jid>',
+ desc="Get the software version of the given JID (usually its"
+ " XMPP client and Operating System).",
+ shortdesc='Get the software version of a JID.',
+ completion=self.completion.version)
+ self.register_command(
+ 'server_cycle',
+ self.command.server_cycle,
+ usage='[domain] [message]',
+ desc='Disconnect and reconnect in all the rooms in domain.',
+ shortdesc='Cycle a range of rooms',
+ completion=self.completion.server_cycle)
+ self.register_command(
+ 'bind',
+ self.command.bind,
+ usage='<key> <equ>',
+ desc="Bind a key to another key or to a “command”. For "
+ "example \"/bind ^H KEY_UP\" makes Control + h do the"
+ " same same as the Up key.",
+ completion=self.completion.bind,
+ shortdesc='Bind a key to another key.')
+ self.register_command(
+ 'load',
+ self.command.load,
+ usage='<plugin> [<otherplugin> …]',
+ shortdesc='Load the specified plugin(s)',
+ completion=self.plugin_manager.completion_load)
+ self.register_command(
+ 'unload',
+ self.command.unload,
+ usage='<plugin> [<otherplugin> …]',
+ shortdesc='Unload the specified plugin(s)',
+ completion=self.plugin_manager.completion_unload)
+ self.register_command(
+ 'plugins',
+ self.command.plugins,
+ shortdesc='Show the plugins in use.')
+ self.register_command(
+ 'presence',
+ self.command.presence,
+ usage='<JID> [type] [status]',
+ desc="Send a directed presence to <JID> and using"
+ " [type] and [status] if provided.",
+ shortdesc='Send a directed presence.',
+ completion=self.completion.presence)
+ self.register_command(
+ 'rawxml',
+ self.command.rawxml,
+ usage='<xml>',
+ shortdesc='Send a custom xml stanza.')
+ self.register_command(
+ 'invite',
+ self.command.invite,
+ usage='<jid> <room> [reason]',
+ desc='Invite jid in room with reason.',
+ shortdesc='Invite someone in a room.',
+ completion=self.completion.invite)
+ self.register_command(
+ 'invitations',
+ self.command.invitations,
+ shortdesc='Show the pending invitations.')
+ self.register_command(
+ 'bookmarks',
+ self.command.bookmarks,
+ shortdesc='Show the current bookmarks.')
+ self.register_command(
+ 'remove_bookmark',
+ self.command.remove_bookmark,
+ usage='[jid]',
+ desc="Remove the specified bookmark, or the "
+ "bookmark on the current tab, if any.",
+ shortdesc='Remove a bookmark',
+ completion=self.completion.remove_bookmark)
+ self.register_command(
+ 'xml_tab', self.command.xml_tab, shortdesc='Open an XML tab.')
+ self.register_command(
+ 'runkey',
+ self.command.runkey,
+ usage='<key>',
+ shortdesc='Execute the action defined for <key>.',
+ completion=self.completion.runkey)
+ self.register_command(
+ 'self', self.command.self_, shortdesc='Remind you of who you are.')
+ self.register_command(
+ 'last_activity',
+ self.command.last_activity,
+ usage='<jid>',
+ desc='Informs you of the last activity of a JID.',
+ shortdesc='Get the activity of someone.',
+ completion=self.completion.last_activity)
+ self.register_command(
+ 'ad-hoc',
+ self.command.adhoc,
+ usage='<jid>',
+ shortdesc='List available ad-hoc commands on the given jid')
+ self.register_command(
+ 'reload',
+ self.command.reload,
+ shortdesc='Reload the config. You can achieve the same by '
+ 'sending SIGUSR1 to poezio.')
if config.get('enable_user_activity'):
- self.register_command('activity', self.command.activity,
- usage='[<general> [specific] [text]]',
- desc='Send your current activity to your contacts '
- '(use the completion). Nothing means '
- '"stop broadcasting an activity".',
- shortdesc='Send your activity.',
- completion=self.completion.activity)
+ self.register_command(
+ 'activity',
+ self.command.activity,
+ usage='[<general> [specific] [text]]',
+ desc='Send your current activity to your contacts '
+ '(use the completion). Nothing means '
+ '"stop broadcasting an activity".',
+ shortdesc='Send your activity.',
+ completion=self.completion.activity)
if config.get('enable_user_mood'):
- self.register_command('mood', self.command.mood,
- usage='[<mood> [text]]',
- desc='Send your current mood to your contacts '
- '(use the completion). Nothing means '
- '"stop broadcasting a mood".',
- shortdesc='Send your mood.',
- completion=self.completion.mood)
+ self.register_command(
+ 'mood',
+ self.command.mood,
+ usage='[<mood> [text]]',
+ desc='Send your current mood to your contacts '
+ '(use the completion). Nothing means '
+ '"stop broadcasting a mood".',
+ shortdesc='Send your mood.',
+ completion=self.completion.mood)
if config.get('enable_user_gaming'):
- self.register_command('gaming', self.command.gaming,
- usage='[<game name> [server address]]',
- desc='Send your current gaming activity to '
- 'your contacts. Nothing means "stop '
- 'broadcasting a gaming activity".',
- shortdesc='Send your gaming activity.',
- completion=None)
+ self.register_command(
+ 'gaming',
+ self.command.gaming,
+ usage='[<game name> [server address]]',
+ desc='Send your current gaming activity to '
+ 'your contacts. Nothing means "stop '
+ 'broadcasting a gaming activity".',
+ shortdesc='Send your gaming activity.',
+ completion=None)
+
####################### Random things to move #################################
@@ -1971,22 +2059,26 @@ class Core(object):
tab = self.get_tab_by_name(bm.jid, tabs.MucTab)
nick = bm.nick if bm.nick else self.own_nick
if not tab:
- self.open_new_room(bm.jid, nick, focus=False,
- password=bm.password)
+ self.open_new_room(
+ bm.jid, nick, focus=False, password=bm.password)
self.initial_joins.append(bm.jid)
# do not join rooms that do not have autojoin
# but display them anyway
if bm.autojoin:
- muc.join_groupchat(self, bm.jid, nick,
- passwd=bm.password,
- status=self.status.message,
- show=self.status.show)
+ muc.join_groupchat(
+ self,
+ bm.jid,
+ nick,
+ passwd=bm.password,
+ status=self.status.message,
+ show=self.status.show)
def check_bookmark_storage(self, features):
private = 'jabber:iq:private' in features
pep_ = 'http://jabber.org/protocol/pubsub#publish' in features
self.bookmarks.available_storage['private'] = private
self.bookmarks.available_storage['pep'] = pep_
+
def _join_remote_only(iq):
if iq['type'] == 'error':
type_ = iq['error']['type']
@@ -1998,8 +2090,10 @@ class Core(object):
return
remote_bookmarks = self.bookmarks.remote()
self.join_initial_rooms(remote_bookmarks)
+
if not self.xmpp.anon and config.get('use_remote_bookmarks'):
- self.bookmarks.get_remote(self.xmpp, self.information, _join_remote_only)
+ self.bookmarks.get_remote(self.xmpp, self.information,
+ _join_remote_only)
def room_error(self, error, room_name):
"""
@@ -2009,32 +2103,42 @@ class Core(object):
if not tab:
return
error_message = self.get_error_message(error)
- tab.add_message(error_message, highlight=True, nickname='Error',
- nick_color=get_theme().COLOR_ERROR_MSG, typ=2)
+ tab.add_message(
+ error_message,
+ highlight=True,
+ nickname='Error',
+ nick_color=get_theme().COLOR_ERROR_MSG,
+ typ=2)
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)'
tab.add_message(msg, typ=2)
if code == '409':
if config.get('alternative_nickname') != '':
- self.command.join('%s/%s'% (tab.name, tab.own_nick+config.get('alternative_nickname')))
+ self.command.join(
+ '%s/%s' %
+ (tab.name,
+ tab.own_nick + config.get('alternative_nickname')))
else:
if not tab.joined:
- tab.add_message('You can join the room with an other nick, by typing "/join /other_nick"', typ=2)
+ tab.add_message(
+ 'You can join the room with an other nick, by typing "/join /other_nick"',
+ typ=2)
self.refresh_window()
-
class KeyDict(dict):
"""
A dict, with a wrapper for get() that will return a custom value
if the key starts with _exc_
"""
+
def get(self, k, d=None):
if isinstance(k, str) and k.startswith('_exc_') and len(k) > 5:
return lambda: dict.get(self, '_exc_')(k[5:])
return dict.get(self, k, d)
+
def replace_key_with_bound(key):
"""
Replace an inputted key with the one defined as its replacement
@@ -2044,5 +2148,3 @@ def replace_key_with_bound(key):
if not bind:
bind = key
return bind
-
-
diff --git a/poezio/core/handlers.py b/poezio/core/handlers.py
index e6d54558..ac6ae573 100644
--- a/poezio/core/handlers.py
+++ b/poezio/core/handlers.py
@@ -80,6 +80,7 @@ class HandlerCore:
"""
Enable carbons & blocking on session start if wanted and possible
"""
+
def callback(iq):
if not iq:
return
@@ -87,21 +88,23 @@ class HandlerCore:
rostertab = self.core.get_tab_by_name('Roster', tabs.RosterInfoTab)
rostertab.check_blocking(features)
rostertab.check_saslexternal(features)
- if (config.get('enable_carbons') and
- 'urn:xmpp:carbons:2' in features):
+ if (config.get('enable_carbons')
+ and 'urn:xmpp:carbons:2' in features):
self.core.xmpp.plugin['xep_0280'].enable()
self.core.check_bookmark_storage(features)
- self.core.xmpp.plugin['xep_0030'].get_info(jid=self.core.xmpp.boundjid.domain,
- callback=callback)
+ self.core.xmpp.plugin['xep_0030'].get_info(
+ jid=self.core.xmpp.boundjid.domain, callback=callback)
def on_carbon_received(self, message):
"""
Carbon <received/> received
"""
+
def ignore_message(recv):
log.debug('%s has category conference, ignoring carbon',
recv['from'].server)
+
def receive_message(recv):
recv['to'] = self.core.xmpp.boundjid.full
if recv['receipt']:
@@ -109,12 +112,14 @@ class HandlerCore:
self.on_normal_message(recv)
recv = message['carbon_received']
- if (recv['from'].bare not in roster or
- roster[recv['from'].bare].subscription == 'none'):
- fixes.has_identity(self.core.xmpp, recv['from'].server,
- identity='conference',
- on_true=functools.partial(ignore_message, recv),
- on_false=functools.partial(receive_message, recv))
+ if (recv['from'].bare not in roster
+ or roster[recv['from'].bare].subscription == 'none'):
+ fixes.has_identity(
+ self.core.xmpp,
+ recv['from'].server,
+ identity='conference',
+ on_true=functools.partial(ignore_message, recv),
+ on_false=functools.partial(receive_message, recv))
return
else:
receive_message(recv)
@@ -123,20 +128,24 @@ class HandlerCore:
"""
Carbon <sent/> received
"""
+
def ignore_message(sent):
log.debug('%s has category conference, ignoring carbon',
sent['to'].server)
+
def send_message(sent):
sent['from'] = self.core.xmpp.boundjid.full
self.on_normal_message(sent)
sent = message['carbon_sent']
- if (sent['to'].bare not in roster or
- roster[sent['to'].bare].subscription == 'none'):
- fixes.has_identity(self.core.xmpp, sent['to'].server,
- identity='conference',
- on_true=functools.partial(ignore_message, sent),
- on_false=functools.partial(send_message, sent))
+ if (sent['to'].bare not in roster
+ or roster[sent['to'].bare].subscription == 'none'):
+ fixes.has_identity(
+ self.core.xmpp,
+ sent['to'].server,
+ identity='conference',
+ on_true=functools.partial(ignore_message, sent),
+ on_false=functools.partial(send_message, sent))
else:
send_message(sent)
@@ -150,7 +159,11 @@ class HandlerCore:
if jid.bare in self.core.pending_invites:
return
# there are 2 'x' tags in the messages, making message['x'] useless
- invite = StanzaBase(self.core.xmpp, xml=message.xml.find('{http://jabber.org/protocol/muc#user}x/{http://jabber.org/protocol/muc#user}invite'))
+ invite = StanzaBase(
+ self.core.xmpp,
+ xml=message.xml.find(
+ '{http://jabber.org/protocol/muc#user}x/{http://jabber.org/protocol/muc#user}invite'
+ ))
inviter = invite['from']
reason = invite['reason']
password = invite['password']
@@ -204,7 +217,9 @@ class HandlerCore:
When receiving private message from a muc OR a normal message
(from one of our contacts)
"""
- if message.xml.find('{http://jabber.org/protocol/muc#user}x/{http://jabber.org/protocol/muc#user}invite') is not None:
+ if message.xml.find(
+ '{http://jabber.org/protocol/muc#user}x/{http://jabber.org/protocol/muc#user}invite'
+ ) is not None:
return
if message['type'] == 'groupchat':
return
@@ -228,7 +243,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.get_tab_by_name(jid_from.full,
+ tabs.PrivateTab)
if p_tab:
p_tab.add_error(text)
else:
@@ -240,12 +256,11 @@ class HandlerCore:
self.core.information(error_msg, 'Error')
return
error = '\x19%s}%s\x19o' % (dump_tuple(get_theme().COLOR_CHAR_NACK),
- error_msg)
+ error_msg)
if not tab.nack_message('\n' + error, message['id'], message['to']):
tab.add_message(error, typ=0)
self.core.refresh_window()
-
def on_normal_message(self, message):
"""
When receiving "normal" messages (not a private message from a
@@ -254,14 +269,18 @@ class HandlerCore:
if message['type'] == 'error':
return
elif message['type'] == 'headline' and message['body']:
- return self.core.information('%s says: %s' % (message['from'], message['body']), 'Headline')
+ return self.core.information(
+ '%s says: %s' % (message['from'], message['body']), 'Headline')
- use_xhtml = config.get_by_tabname('enable_xhtml_im', message['from'].bare)
+ use_xhtml = config.get_by_tabname('enable_xhtml_im',
+ message['from'].bare)
tmp_dir = config.get('tmp_image_dir') or path.join(CACHE_DIR, 'images')
extract_images = config.get('extract_inline_images')
- body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml,
- tmp_dir=tmp_dir,
- extract_images=extract_images)
+ body = xhtml.get_body_from_message_stanza(
+ message,
+ use_xhtml=use_xhtml,
+ tmp_dir=tmp_dir,
+ extract_images=extract_images)
if not body:
if not self.core.xmpp.plugin['xep_0380'].has_eme(message):
return
@@ -279,7 +298,8 @@ class HandlerCore:
remote_nick = roster[conv_jid.bare].name
# check for a received nick
if not remote_nick and config.get('enable_user_nick'):
- if message.xml.find('{http://jabber.org/protocol/nick}nick') is not None:
+ if message.xml.find(
+ '{http://jabber.org/protocol/nick}nick') is not None:
remote_nick = message['nick']['nick']
if not remote_nick:
remote_nick = conv_jid.user
@@ -298,7 +318,8 @@ class HandlerCore:
return
conversation = self.core.get_conversation_by_jid(conv_jid, create=True)
- if isinstance(conversation, tabs.DynamicConversationTab) and conv_jid.resource:
+ if isinstance(conversation,
+ tabs.DynamicConversationTab) and conv_jid.resource:
conversation.lock(conv_jid.resource)
if not own and not conversation.nick:
@@ -312,9 +333,11 @@ class HandlerCore:
self.core.events.trigger('conversation_msg', message, conversation)
if not message['body']:
return
- body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml,
- tmp_dir=tmp_dir,
- extract_images=extract_images)
+ body = xhtml.get_body_from_message_stanza(
+ message,
+ use_xhtml=use_xhtml,
+ tmp_dir=tmp_dir,
+ extract_images=extract_images)
delayed, date = common.find_delayed_tag(message)
def try_modify():
@@ -324,21 +347,27 @@ class HandlerCore:
if replaced_id and config.get_by_tabname('group_corrections',
conv_jid.bare):
try:
- conversation.modify_message(body, replaced_id, message['id'], jid=jid,
- nickname=remote_nick)
+ conversation.modify_message(
+ body,
+ replaced_id,
+ message['id'],
+ jid=jid,
+ nickname=remote_nick)
return True
except CorrectionError:
log.debug('Unable to correct a message', exc_info=True)
return False
if not try_modify():
- conversation.add_message(body, date,
- nickname=remote_nick,
- nick_color=color,
- history=delayed,
- identifier=message['id'],
- jid=jid,
- typ=1)
+ conversation.add_message(
+ body,
+ date,
+ nickname=remote_nick,
+ nick_color=color,
+ history=delayed,
+ identifier=message['id'],
+ jid=jid,
+ typ=1)
if conversation.remote_wants_chatstates is None and not delayed:
if message['chat_state']:
@@ -366,7 +395,8 @@ class HandlerCore:
return
log.debug('Received 0084 avatar update from %s', jid)
try:
- metadata = msg['pubsub_event']['items']['item']['avatar_metadata']['items']
+ metadata = msg['pubsub_event']['items']['item']['avatar_metadata'][
+ 'items']
except Exception:
log.debug('Failed getting metadata from 0084:', exc_info=True)
return
@@ -387,12 +417,16 @@ class HandlerCore:
# If we didn’t have any, query the data instead.
if not info['url']:
try:
- result = yield from self.core.xmpp['xep_0084'].retrieve_avatar(jid,
- avatar_hash,
- timeout=60)
- contact.avatar = result['pubsub']['items']['item']['avatar_data']['value']
+ result = yield from self.core.xmpp[
+ 'xep_0084'].retrieve_avatar(
+ jid, avatar_hash, timeout=60)
+ contact.avatar = result['pubsub']['items']['item'][
+ 'avatar_data']['value']
except Exception:
- log.debug('Failed retrieving 0084 data from %s:', jid, exc_info=True)
+ log.debug(
+ 'Failed retrieving 0084 data from %s:',
+ jid,
+ exc_info=True)
continue
log.debug('Received %s avatar: %s', jid, info['type'])
@@ -427,9 +461,8 @@ class HandlerCore:
# If we didn’t have any, query the vCard instead.
try:
- result = yield from self.core.xmpp['xep_0054'].get_vcard(jid,
- cached=True,
- timeout=60)
+ result = yield from self.core.xmpp['xep_0054'].get_vcard(
+ jid, cached=True, timeout=60)
avatar = result['vcard_temp']['PHOTO']
contact.avatar = avatar['BINVAL']
except Exception:
@@ -473,25 +506,32 @@ class HandlerCore:
item = item['gaming']
# only name and server_address are used for now
contact.gaming = {
- 'character_name': item['character_name'],
- 'character_profile': item['character_profile'],
- 'name': item['name'],
- 'level': item['level'],
- 'uri': item['uri'],
- 'server_name': item['server_name'],
- 'server_address': item['server_address'],
- }
+ 'character_name': item['character_name'],
+ 'character_profile': item['character_profile'],
+ 'name': item['name'],
+ 'level': item['level'],
+ 'uri': item['uri'],
+ 'server_name': item['server_name'],
+ 'server_address': item['server_address'],
+ }
else:
contact.gaming = {}
if contact.gaming:
- logger.log_roster_change(contact.bare_jid, 'is playing %s' % (common.format_gaming_string(contact.gaming)))
+ logger.log_roster_change(
+ contact.bare_jid, 'is playing %s' %
+ (common.format_gaming_string(contact.gaming)))
- if old_gaming != contact.gaming and config.get_by_tabname('display_gaming_notifications', contact.bare_jid):
+ if old_gaming != contact.gaming and config.get_by_tabname(
+ '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')
+ self.core.information(
+ '%s is playing %s' %
+ (contact.bare_jid,
+ common.format_gaming_string(contact.gaming)), 'Gaming')
else:
- self.core.information(contact.bare_jid + ' stopped playing.', 'Gaming')
+ self.core.information(contact.bare_jid + ' stopped playing.',
+ 'Gaming')
def on_mood_event(self, message):
"""
@@ -518,13 +558,18 @@ class HandlerCore:
contact.mood = ''
if contact.mood:
- logger.log_roster_change(contact.bare_jid, 'has now the mood: %s' % contact.mood)
+ logger.log_roster_change(contact.bare_jid,
+ 'has now the mood: %s' % contact.mood)
- if old_mood != contact.mood and config.get_by_tabname('display_mood_notifications', contact.bare_jid):
+ if old_mood != contact.mood and config.get_by_tabname(
+ 'display_mood_notifications', contact.bare_jid):
if contact.mood:
- self.core.information('Mood from '+ contact.bare_jid + ': ' + contact.mood, 'Mood')
+ self.core.information(
+ 'Mood from ' + contact.bare_jid + ': ' + contact.mood,
+ 'Mood')
else:
- self.core.information(contact.bare_jid + ' stopped having his/her mood.', 'Mood')
+ self.core.information(
+ contact.bare_jid + ' stopped having his/her mood.', 'Mood')
def on_activity_event(self, message):
"""
@@ -537,7 +582,8 @@ class HandlerCore:
roster.modified()
item = message['pubsub_event']['items']['item']
old_activity = contact.activity
- if item.xml.find('{http://jabber.org/protocol/activity}activity') is not None:
+ if item.xml.find(
+ '{http://jabber.org/protocol/activity}activity') is not None:
try:
activity = item['activity']['value']
except ValueError:
@@ -557,13 +603,18 @@ class HandlerCore:
contact.activity = ''
if contact.activity:
- logger.log_roster_change(contact.bare_jid, 'has now the activity %s' % contact.activity)
+ logger.log_roster_change(
+ contact.bare_jid, 'has now the activity %s' % contact.activity)
- if old_activity != contact.activity and config.get_by_tabname('display_activity_notifications', contact.bare_jid):
+ 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.', 'Activity')
+ self.core.information(
+ contact.bare_jid + ' stopped doing his/her activity.',
+ 'Activity')
def on_tune_event(self, message):
"""
@@ -579,27 +630,31 @@ class HandlerCore:
if item.xml.find('{http://jabber.org/protocol/tune}tune') is not None:
item = item['tune']
contact.tune = {
- 'artist': item['artist'],
- 'length': item['length'],
- 'rating': item['rating'],
- 'source': item['source'],
- 'title': item['title'],
- 'track': item['track'],
- 'uri': item['uri']
- }
+ 'artist': item['artist'],
+ 'length': item['length'],
+ 'rating': item['rating'],
+ 'source': item['source'],
+ 'title': item['title'],
+ 'track': item['track'],
+ 'uri': item['uri']
+ }
else:
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):
+ if old_tune != contact.tune and config.get_by_tabname(
+ 'display_tune_notifications', contact.bare_jid):
if contact.tune:
self.core.information(
- 'Tune from '+ message['from'].bare + ': ' + common.format_tune_string(contact.tune),
- 'Tune')
+ 'Tune from ' + message['from'].bare + ': ' +
+ common.format_tune_string(contact.tune), 'Tune')
else:
- self.core.information(contact.bare_jid + ' stopped listening to music.', 'Tune')
+ self.core.information(
+ contact.bare_jid + ' stopped listening to music.', 'Tune')
def on_groupchat_message(self, message):
"""
@@ -609,14 +664,16 @@ class HandlerCore:
return
room_from = message['from'].bare
- if message['type'] == 'error': # Check if it's an error
+ if message['type'] == 'error': # Check if it's an error
self.core.room_error(message, room_from)
return
tab = self.core.get_tab_by_name(room_from, tabs.MucTab)
if not tab:
- self.core.information("message received for a non-existing room: %s" % (room_from))
- muc.leave_groupchat(self.core.xmpp, room_from, self.core.own_nick, msg='')
+ self.core.information(
+ "message received for a non-existing room: %s" % (room_from))
+ muc.leave_groupchat(
+ self.core.xmpp, room_from, self.core.own_nick, msg='')
return
nick_from = message['mucnick']
@@ -628,9 +685,11 @@ class HandlerCore:
use_xhtml = config.get_by_tabname('enable_xhtml_im', room_from)
tmp_dir = config.get('tmp_image_dir') or path.join(CACHE_DIR, 'images')
extract_images = config.get('extract_inline_images')
- body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml,
- tmp_dir=tmp_dir,
- extract_images=extract_images)
+ body = xhtml.get_body_from_message_stanza(
+ message,
+ use_xhtml=use_xhtml,
+ tmp_dir=tmp_dir,
+ extract_images=extract_images)
if not body:
return
@@ -639,18 +698,29 @@ class HandlerCore:
replaced = False
if message.xml.find('{urn:xmpp:message-correct:0}replace') is not None:
replaced_id = message['replace']['id']
- if replaced_id is not '' and config.get_by_tabname('group_corrections',
- message['from'].bare):
+ if replaced_id is not '' and config.get_by_tabname(
+ 'group_corrections', message['from'].bare):
try:
delayed_date = date or datetime.now()
- if tab.modify_message(body, replaced_id, message['id'],
+ if tab.modify_message(
+ body,
+ replaced_id,
+ message['id'],
time=delayed_date,
- nickname=nick_from, user=user):
+ nickname=nick_from,
+ user=user):
self.core.events.trigger('highlight', message, tab)
replaced = True
except CorrectionError:
log.debug('Unable to correct a message', exc_info=True)
- if not replaced and tab.add_message(body, date, nick_from, history=delayed, identifier=message['id'], jid=message['from'], typ=1):
+ if not replaced and tab.add_message(
+ body,
+ date,
+ nick_from,
+ history=delayed,
+ identifier=message['id'],
+ jid=message['from'],
+ typ=1):
self.core.events.trigger('highlight', message, tab)
if message['from'].resource == tab.own_nick:
@@ -693,45 +763,61 @@ class HandlerCore:
use_xhtml = config.get_by_tabname('enable_xhtml_im', jid.bare)
tmp_dir = config.get('tmp_image_dir') or path.join(CACHE_DIR, 'images')
extract_images = config.get('extract_inline_images')
- body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml,
- tmp_dir=tmp_dir,
- extract_images=extract_images)
- tab = self.core.get_tab_by_name(jid.full, tabs.PrivateTab) # get the tab with the private conversation
+ body = xhtml.get_body_from_message_stanza(
+ message,
+ use_xhtml=use_xhtml,
+ tmp_dir=tmp_dir,
+ extract_images=extract_images)
+ tab = self.core.get_tab_by_name(
+ jid.full,
+ tabs.PrivateTab) # get the tab with the private conversation
ignore = config.get_by_tabname('ignore_private', room_from)
- if not tab: # It's the first message we receive: create the tab
+ if not tab: # It's the first message we receive: create the tab
if body and not ignore:
- tab = self.core.open_private_window(room_from, nick_from, False)
+ tab = self.core.open_private_window(room_from, nick_from,
+ False)
if ignore:
self.core.events.trigger('ignored_private', message, tab)
msg = config.get_by_tabname('private_auto_response', room_from)
if msg and body:
- self.core.xmpp.send_message(mto=jid.full, mbody=msg, mtype='chat')
+ self.core.xmpp.send_message(
+ mto=jid.full, mbody=msg, mtype='chat')
return
tab.last_remote_message = datetime.now()
self.core.events.trigger('private_msg', message, tab)
- body = xhtml.get_body_from_message_stanza(message, use_xhtml=use_xhtml,
- tmp_dir=tmp_dir,
- extract_images=extract_images)
+ body = xhtml.get_body_from_message_stanza(
+ message,
+ use_xhtml=use_xhtml,
+ tmp_dir=tmp_dir,
+ extract_images=extract_images)
if not body or not tab:
return
replaced = False
user = tab.parent_muc.get_user_by_name(nick_from)
if message.xml.find('{urn:xmpp:message-correct:0}replace') is not None:
replaced_id = message['replace']['id']
- if replaced_id is not '' and config.get_by_tabname('group_corrections',
- room_from):
+ if replaced_id is not '' and config.get_by_tabname(
+ 'group_corrections', room_from):
try:
- tab.modify_message(body, replaced_id, message['id'], user=user, jid=message['from'],
- nickname=nick_from)
+ tab.modify_message(
+ body,
+ replaced_id,
+ message['id'],
+ user=user,
+ jid=message['from'],
+ nickname=nick_from)
replaced = True
except CorrectionError:
log.debug('Unable to correct a message', exc_info=True)
if not replaced:
- tab.add_message(body, time=None, nickname=nick_from,
- forced_user=user,
- identifier=message['id'],
- jid=message['from'],
- typ=1)
+ tab.add_message(
+ body,
+ time=None,
+ nickname=nick_from,
+ forced_user=user,
+ identifier=message['id'],
+ jid=message['from'],
+ typ=1)
if tab.remote_wants_chatstates is None:
if message['chat_state']:
@@ -767,7 +853,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.get_tab_by_name(message['from'].full,
+ tabs.PrivateTab)
if not tab:
return
self._on_chatstate_private_conversation(message, state)
@@ -862,10 +949,10 @@ class HandlerCore:
contact = roster.get_and_set(jid)
roster.update_contact_groups(contact)
contact.pending_in = True
- self.core.information('%s wants to subscribe to your presence, use '
- '/accept <jid> or /deny <jid> in the roster '
- 'tab to accept or reject the query.' % jid,
- 'Roster')
+ self.core.information(
+ '%s wants to subscribe to your presence, use '
+ '/accept <jid> or /deny <jid> in the roster '
+ '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):
@@ -876,7 +963,8 @@ class HandlerCore:
jid = presence['from'].bare
contact = roster[jid]
if contact.subscription not in ('both', 'from'):
- self.core.information('%s accepted your contact proposal' % jid, 'Roster')
+ self.core.information('%s accepted your contact proposal' % jid,
+ 'Roster')
if contact.pending_out:
contact.pending_out = False
@@ -892,7 +980,8 @@ class HandlerCore:
if not contact:
return
roster.modified()
- self.core.information('%s does not want to receive your status anymore.' % jid, 'Roster')
+ 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):
self.core.refresh_window()
@@ -905,10 +994,13 @@ class HandlerCore:
return
roster.modified()
if contact.pending_out:
- self.core.information('%s rejected your contact proposal' % jid, 'Roster')
+ self.core.information('%s rejected your contact proposal' % jid,
+ 'Roster')
contact.pending_out = False
else:
- self.core.information('%s does not want you to receive his/her/its status anymore.'%jid, 'Roster')
+ self.core.information(
+ '%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):
self.core.refresh_window()
@@ -916,7 +1008,8 @@ class HandlerCore:
### Presence-related handlers ###
def on_presence(self, presence):
- if presence.match('presence/muc') or presence.xml.find('{http://jabber.org/protocol/muc#user}x') is not None:
+ if presence.match('presence/muc') or presence.xml.find(
+ '{http://jabber.org/protocol/muc#user}x') is not None:
return
jid = presence['from']
contact = roster[jid.bare]
@@ -930,10 +1023,12 @@ class HandlerCore:
return
roster.modified()
contact.error = None
- self.core.events.trigger('normal_presence', presence, contact[jid.full])
+ self.core.events.trigger('normal_presence', presence,
+ contact[jid.full])
tab = self.core.get_conversation_by_jid(jid, create=False)
if tab:
- tab.update_status(Status(show=presence['show'], message=presence['status']))
+ tab.update_status(
+ Status(show=presence['show'], message=presence['status']))
if isinstance(self.core.current_tab(), tabs.RosterInfoTab):
self.core.refresh_window()
elif self.core.current_tab() == tab:
@@ -956,7 +1051,8 @@ class HandlerCore:
"""
A JID got offline
"""
- if presence.match('presence/muc') or presence.xml.find('{http://jabber.org/protocol/muc#user}x') is not None:
+ if presence.match('presence/muc') or presence.xml.find(
+ '{http://jabber.org/protocol/muc#user}x') is not None:
return
jid = presence['from']
if not logger.log_roster_change(jid.bare, 'got offline'):
@@ -970,9 +1066,12 @@ class HandlerCore:
if contact.name:
name = contact.name
if jid.resource:
- self.core.add_information_message_to_conversation_tab(jid.full, '\x195}%s is \x191}offline' % name)
- self.core.add_information_message_to_conversation_tab(jid.bare, '\x195}%s is \x191}offline' % name)
- self.core.information('\x193}%s \x195}is \x191}offline' % name, 'Roster')
+ self.core.add_information_message_to_conversation_tab(
+ jid.full, '\x195}%s is \x191}offline' % name)
+ self.core.add_information_message_to_conversation_tab(
+ jid.bare, '\x195}%s is \x191}offline' % name)
+ self.core.information('\x193}%s \x195}is \x191}offline' % name,
+ 'Roster')
roster.modified()
if isinstance(self.core.current_tab(), tabs.RosterInfoTab):
self.core.refresh_window()
@@ -981,7 +1080,8 @@ class HandlerCore:
"""
A JID got online
"""
- if presence.match('presence/muc') or presence.xml.find('{http://jabber.org/protocol/muc#user}x') is not None:
+ if presence.match('presence/muc') or presence.xml.find(
+ '{http://jabber.org/protocol/muc#user}x') is not None:
return
jid = presence['from']
contact = roster[jid.bare]
@@ -996,17 +1096,22 @@ class HandlerCore:
'priority': presence.get_priority() or 0,
'status': presence['status'],
'show': presence['show'],
- })
+ })
self.core.events.trigger('normal_presence', presence, resource)
name = contact.name if contact.name else jid.bare
- self.core.add_information_message_to_conversation_tab(jid.full, '\x195}%s is \x194}online' % name)
+ self.core.add_information_message_to_conversation_tab(
+ jid.full, '\x195}%s is \x194}online' % name)
if time.time() - self.core.connection_time > 10:
# We do not display messages if we recently logged in
if presence['status']:
- self.core.information("\x193}%s \x195}is \x194}online\x195} (\x19o%s\x195})" % (name, presence['status']), "Roster")
+ self.core.information(
+ "\x193}%s \x195}is \x194}online\x195} (\x19o%s\x195})" %
+ (name, presence['status']), "Roster")
else:
- self.core.information("\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)
+ self.core.information(
+ "\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):
self.core.refresh_window()
@@ -1022,14 +1127,14 @@ class HandlerCore:
self.core.events.trigger('muc_presence', presence, tab)
tab.handle_presence(presence)
-
### Connection-related handlers ###
def on_failed_connection(self, error):
"""
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):
@@ -1046,10 +1151,12 @@ class HandlerCore:
tab.disconnect()
msg_typ = 'Error' if not self.core.legitimate_disconnect else 'Info'
self.core.information("Disconnected from server.", msg_typ)
- if self.core.legitimate_disconnect or not config.get('auto_reconnect', True):
+ if self.core.legitimate_disconnect or not config.get(
+ 'auto_reconnect', True):
return
- if (self.core.last_stream_error and
- self.core.last_stream_error[1]['condition'] in ('conflict', 'host-unknown')):
+ if (self.core.last_stream_error
+ and self.core.last_stream_error[1]['condition'] in (
+ 'conflict', 'host-unknown')):
return
yield from asyncio.sleep(1)
self.core.information("Auto-reconnecting.", 'Info')
@@ -1076,8 +1183,8 @@ class HandlerCore:
"""
Authentication failed (no mech)
"""
- self.core.information("Authentication failed, no login method available.",
- 'Error')
+ self.core.information(
+ "Authentication failed, no login method available.", 'Error')
self.core.legitimate_disconnect = True
def on_connected(self, event):
@@ -1092,10 +1199,11 @@ class HandlerCore:
Called when we are connected and authenticated
"""
self.core.connection_time = time.time()
- if not self.core.plugins_autoloaded: # Do not reload plugins on reconnection
+ if not self.core.plugins_autoloaded: # Do not reload plugins on reconnection
self.core.autoload_plugins()
self.core.information("Authentication success.", 'Info')
- self.core.information("Your JID is %s" % self.core.xmpp.boundjid.full, 'Info')
+ self.core.information("Your JID is %s" % self.core.xmpp.boundjid.full,
+ 'Info')
if not self.core.xmpp.anon:
# request the roster
self.core.xmpp.get_roster()
@@ -1112,7 +1220,8 @@ class HandlerCore:
self.core.join_initial_rooms(self.core.bookmarks)
if config.get('enable_user_nick'):
- self.core.xmpp.plugin['xep_0172'].publish_nick(nick=self.core.own_nick, callback=dumb_callback)
+ self.core.xmpp.plugin['xep_0172'].publish_nick(
+ nick=self.core.own_nick, callback=dumb_callback)
asyncio.ensure_future(self.core.xmpp.plugin['xep_0115'].update_caps())
# Start the ping's plugin regular event
self.core.xmpp.set_keepalive_values()
@@ -1126,9 +1235,14 @@ class HandlerCore:
"""
room_from = message['from']
tab = self.core.get_tab_by_name(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))}
+ status_codes = {
+ s.attrib['code']
+ 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('Your affiliation in the room %s changed' % room_from, 'Info')
+ self.core.information(
+ 'Your affiliation in the room %s changed' % room_from, 'Info')
elif tab and status_codes:
show_unavailable = '102' in status_codes
hide_unavailable = '103' in status_codes
@@ -1141,38 +1255,70 @@ class HandlerCore:
modif = False
if show_unavailable or hide_unavailable or non_priv or logging_off\
or non_anon or semi_anon or full_anon:
- tab.add_message('\x19%(info_col)s}Info: A configuration change not privacy-related occured.' %
- {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
- typ=2)
+ tab.add_message(
+ '\x19%(info_col)s}Info: A configuration change not privacy-related occured.'
+ % {
+ 'info_col': dump_tuple(
+ get_theme().COLOR_INFORMATION_TEXT)
+ },
+ typ=2)
modif = True
if show_unavailable:
- tab.add_message('\x19%(info_col)s}Info: The unavailable members are now shown.' %
- {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
- typ=2)
+ tab.add_message(
+ '\x19%(info_col)s}Info: The unavailable members are now shown.'
+ % {
+ 'info_col': dump_tuple(
+ get_theme().COLOR_INFORMATION_TEXT)
+ },
+ typ=2)
elif hide_unavailable:
- tab.add_message('\x19%(info_col)s}Info: The unavailable members are now hidden.' %
- {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
- typ=2)
+ tab.add_message(
+ '\x19%(info_col)s}Info: The unavailable members are now hidden.'
+ % {
+ 'info_col': dump_tuple(
+ get_theme().COLOR_INFORMATION_TEXT)
+ },
+ typ=2)
if non_anon:
- tab.add_message('\x191}Warning:\x19%(info_col)s} The room is now not anonymous. (public JID)' %
- {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
- typ=2)
+ tab.add_message(
+ '\x191}Warning:\x19%(info_col)s} The room is now not anonymous. (public JID)'
+ % {
+ 'info_col': dump_tuple(
+ get_theme().COLOR_INFORMATION_TEXT)
+ },
+ typ=2)
elif semi_anon:
- tab.add_message('\x19%(info_col)s}Info: The room is now semi-anonymous. (moderators-only JID)' %
- {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
- typ=2)
+ tab.add_message(
+ '\x19%(info_col)s}Info: The room is now semi-anonymous. (moderators-only JID)'
+ % {
+ 'info_col': dump_tuple(
+ get_theme().COLOR_INFORMATION_TEXT)
+ },
+ typ=2)
elif full_anon:
- tab.add_message('\x19%(info_col)s}Info: The room is now fully anonymous.' %
- {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
- typ=2)
+ tab.add_message(
+ '\x19%(info_col)s}Info: The room is now fully anonymous.' %
+ {
+ 'info_col': dump_tuple(
+ get_theme().COLOR_INFORMATION_TEXT)
+ },
+ typ=2)
if logging_on:
- tab.add_message('\x191}Warning: \x19%(info_col)s}This room is publicly logged' %
- {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
- typ=2)
+ tab.add_message(
+ '\x191}Warning: \x19%(info_col)s}This room is publicly logged'
+ % {
+ 'info_col': dump_tuple(
+ get_theme().COLOR_INFORMATION_TEXT)
+ },
+ typ=2)
elif logging_off:
- tab.add_message('\x19%(info_col)s}Info: This room is not logged anymore.' %
- {'info_col': dump_tuple(get_theme().COLOR_INFORMATION_TEXT)},
- typ=2)
+ tab.add_message(
+ '\x19%(info_col)s}Info: This room is not logged anymore.' %
+ {
+ 'info_col': dump_tuple(
+ get_theme().COLOR_INFORMATION_TEXT)
+ },
+ typ=2)
if modif:
self.core.refresh_window()
@@ -1203,22 +1349,30 @@ 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)
+ user_string = '\x19%s}%s%s' % (fmt['info_col'], nick_from,
+ after)
fmt['user'] = user_string
if nick_from:
- tab.add_message("%(user)s set the subject to: \x19%(text_col)s}%(subject)s" % fmt,
- time=None,
- typ=2)
+ tab.add_message(
+ "%(user)s set the subject to: \x19%(text_col)s}%(subject)s"
+ % fmt,
+ time=None,
+ typ=2)
else:
- tab.add_message("\x19%(info_col)s}The subject is: \x19%(text_col)s}%(subject)s" % fmt,
- time=None,
- typ=2)
+ tab.add_message(
+ "\x19%(info_col)s}The subject is: \x19%(text_col)s}%(subject)s"
+ % fmt,
+ time=None,
+ 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.get_tab_by_name(room_from,
+ tabs.MucTab) is self.core.current_tab():
self.core.refresh_window()
def on_receipt(self, message):
@@ -1231,7 +1385,8 @@ class HandlerCore:
return
conversation = self.core.get_tab_by_name(jid.full, tabs.OneToOneTab)
- conversation = conversation or self.core.get_tab_by_name(jid.bare, tabs.OneToOneTab)
+ conversation = conversation or self.core.get_tab_by_name(
+ jid.bare, tabs.OneToOneTab)
if not conversation:
log.error("Received ack from non-existing chat tab: %s", jid)
return
@@ -1272,15 +1427,21 @@ class HandlerCore:
if self.core.xml_tab:
if PYGMENTS:
xhtml_text = highlight('%s' % stanza, LEXER, FORMATTER)
- poezio_colored = xhtml.xhtml_to_poezio_colors(xhtml_text, force=True).rstrip('\x19o').strip()
+ poezio_colored = xhtml.xhtml_to_poezio_colors(
+ xhtml_text, force=True).rstrip('\x19o').strip()
else:
poezio_colored = '%s' % stanza
- self.core.add_message_to_text_buffer(self.core.xml_buffer, poezio_colored,
- nickname=get_theme().CHAR_XML_OUT)
+ self.core.add_message_to_text_buffer(
+ self.core.xml_buffer,
+ poezio_colored,
+ nickname=get_theme().CHAR_XML_OUT)
try:
- if self.core.xml_tab.match_stanza(ElementBase(ET.fromstring(stanza))):
- self.core.add_message_to_text_buffer(self.core.xml_tab.filtered_buffer, poezio_colored,
- nickname=get_theme().CHAR_XML_OUT)
+ if self.core.xml_tab.match_stanza(
+ ElementBase(ET.fromstring(stanza))):
+ self.core.add_message_to_text_buffer(
+ self.core.xml_tab.filtered_buffer,
+ poezio_colored,
+ nickname=get_theme().CHAR_XML_OUT)
except:
log.debug('', exc_info=True)
@@ -1295,15 +1456,20 @@ class HandlerCore:
if self.core.xml_tab:
if PYGMENTS:
xhtml_text = highlight('%s' % stanza, LEXER, FORMATTER)
- poezio_colored = xhtml.xhtml_to_poezio_colors(xhtml_text, force=True).rstrip('\x19o').strip()
+ poezio_colored = xhtml.xhtml_to_poezio_colors(
+ xhtml_text, force=True).rstrip('\x19o').strip()
else:
poezio_colored = '%s' % stanza
- self.core.add_message_to_text_buffer(self.core.xml_buffer, poezio_colored,
- nickname=get_theme().CHAR_XML_IN)
+ self.core.add_message_to_text_buffer(
+ self.core.xml_buffer,
+ poezio_colored,
+ nickname=get_theme().CHAR_XML_IN)
try:
if self.core.xml_tab.match_stanza(stanza):
- self.core.add_message_to_text_buffer(self.core.xml_tab.filtered_buffer, poezio_colored,
- nickname=get_theme().CHAR_XML_IN)
+ self.core.add_message_to_text_buffer(
+ self.core.xml_tab.filtered_buffer,
+ poezio_colored,
+ nickname=get_theme().CHAR_XML_IN)
except:
log.debug('', exc_info=True)
if isinstance(self.core.current_tab(), tabs.XMLTab):
@@ -1311,33 +1477,34 @@ class HandlerCore:
self.core.doupdate()
def ssl_invalid_chain(self, tb):
- self.core.information('The certificate sent by the server is invalid.', 'Error')
+ self.core.information('The certificate sent by the server is invalid.',
+ 'Error')
self.core.disconnect()
def _ssl_pop_tab(self, old_cert, new_cert):
def cb(result):
if result:
self.core.information(
- 'New certificate accepted:\nnew: %s\nold: %s' % (
- old_cert, new_cert),
- 'Info')
+ 'New certificate accepted:\nnew: %s\nold: %s' %
+ (old_cert, new_cert), 'Info')
log.debug('Setting certificate to %s', new_cert)
if not config.silent_set('certificate', new_cert):
- self.core.information(
- 'Unable to write in the config file',
- 'Error')
+ self.core.information('Unable to write in the config file',
+ 'Error')
else:
- self.core.information('You refused to validate the certificate.'
- ' You are now disconnected.', 'Info')
+ self.core.information(
+ 'You refused to validate the certificate.'
+ ' You are now disconnected.', 'Info')
self.core.disconnect()
- confirm_tab = tabs.ConfirmTab(self.core,
- 'Certificate check required',
- CERT_WARNING_TEXT % (self.core.xmpp.boundjid.domain, old_cert, new_cert),
- 'You need to accept or reject the certificate',
- cb,
- critical=True)
-
+ confirm_tab = tabs.ConfirmTab(
+ self.core,
+ 'Certificate check required',
+ CERT_WARNING_TEXT % (self.core.xmpp.boundjid.domain, old_cert,
+ new_cert),
+ 'You need to accept or reject the certificate',
+ cb,
+ critical=True)
self.core.add_tab(confirm_tab, True)
self.core.doupdate()
@@ -1356,21 +1523,28 @@ class HandlerCore:
cert = config.get('certificate')
# update the cert representation when it uses the old one
if cert and ':' not in cert:
- cert = ':'.join(i + j for i, j in zip(cert[::2], cert[1::2])).upper()
+ cert = ':'.join(
+ i + j for i, j in zip(cert[::2], cert[1::2])).upper()
config.set_and_save('certificate', cert)
der = ssl.PEM_cert_to_DER_cert(pem)
- asn1 = pyasn1.codec.der.decoder.decode(der, asn1Spec=pyasn1_modules.rfc2459.Certificate())[0]
- spki = asn1.getComponentByName("tbsCertificate").getComponentByName("subjectPublicKeyInfo")
- spki_digest = sha256(pyasn1.codec.der.encoder.encode(spki)).hexdigest().upper()
- spki_found_cert = ':'.join(i + j for i, j in zip(spki_digest[::2], spki_digest[1::2]))
+ asn1 = pyasn1.codec.der.decoder.decode(
+ der, asn1Spec=pyasn1_modules.rfc2459.Certificate())[0]
+ spki = asn1.getComponentByName("tbsCertificate").getComponentByName(
+ "subjectPublicKeyInfo")
+ spki_digest = sha256(
+ pyasn1.codec.der.encoder.encode(spki)).hexdigest().upper()
+ spki_found_cert = ':'.join(
+ i + j for i, j in zip(spki_digest[::2], spki_digest[1::2]))
sha2_digest = sha512(der).hexdigest().upper()
- sha2_found_cert = ':'.join(i + j for i, j in zip(sha2_digest[::2], sha2_digest[1::2]))
+ sha2_found_cert = ':'.join(
+ i + j for i, j in zip(sha2_digest[::2], sha2_digest[1::2]))
if cert:
if sha2_found_cert == cert:
- log.debug('Current hash is cert hash, moving to SPKI hash (%s)',
- spki_found_cert)
+ log.debug(
+ 'Current hash is cert hash, moving to SPKI hash (%s)',
+ spki_found_cert)
config.set_and_save('certificate', spki_found_cert)
return
elif spki_found_cert == cert:
@@ -1380,10 +1554,12 @@ class HandlerCore:
else:
log.debug('First time. Setting certificate to %s', spki_found_cert)
if not config.silent_set('certificate', spki_found_cert):
- self.core.information('Unable to write in the config file', 'Error')
+ self.core.information('Unable to write in the config file',
+ 'Error')
def http_confirm(self, stanza):
confirm = stanza['confirm']
+
def cb(result):
if result:
reply = stanza.reply()
@@ -1396,13 +1572,15 @@ class HandlerCore:
reply.append(stanza['confirm'])
reply.send()
- c_id, c_url, c_method = confirm['id'], confirm['url'], confirm['method']
- confirm_tab = tabs.ConfirmTab(self.core,
- 'HTTP Verification',
- HTTP_VERIF_TEXT % (c_method, c_url, c_id, stanza['from'].full),
- 'An HTTP verification was requested',
- cb,
- critical=False)
+ c_id, c_url, c_method = confirm['id'], confirm['url'], confirm[
+ 'method']
+ confirm_tab = tabs.ConfirmTab(
+ self.core,
+ 'HTTP Verification',
+ HTTP_VERIF_TEXT % (c_method, c_url, c_id, stanza['from'].full),
+ 'An HTTP verification was requested',
+ cb,
+ critical=False)
self.core.add_tab(confirm_tab, False)
self.core.refresh_window()
self.core.doupdate()
@@ -1411,19 +1589,24 @@ class HandlerCore:
def next_adhoc_step(self, iq, adhoc_session):
status = iq['command']['status']
- xform = iq.xml.find('{http://jabber.org/protocol/commands}command/{jabber:x:data}x')
+ xform = iq.xml.find(
+ '{http://jabber.org/protocol/commands}command/{jabber:x:data}x')
if xform is not None:
form = self.core.xmpp.plugin['xep_0004'].build_form(xform)
else:
form = None
if status == 'error':
- return self.core.information("An error occured while executing the command")
+ return self.core.information(
+ "An error occured while executing the command")
if status == 'executing':
if not form:
- self.core.information("Adhoc command step does not contain a data-form. Aborting the execution.", "Error")
- return self.core.xmpp.plugin['xep_0050'].cancel_command(adhoc_session)
+ self.core.information(
+ "Adhoc command step does not contain a data-form. Aborting the execution.",
+ "Error")
+ return self.core.xmpp.plugin['xep_0050'].cancel_command(
+ adhoc_session)
on_validate = self._validate_adhoc_step
on_cancel = self._cancel_adhoc_command
if status == 'completed':
@@ -1435,18 +1618,20 @@ class HandlerCore:
if form:
for note in iq['command']['notes']:
form.add_field(type='fixed', label=note[1])
- self.core.open_new_form(form, on_cancel, on_validate,
- session=adhoc_session)
- else: # otherwise, just display an information
- # message
+ self.core.open_new_form(
+ form, on_cancel, on_validate, session=adhoc_session)
+ else: # otherwise, just display an information
+ # message
notes = '\n'.join([note[1] for note in iq['command']['notes']])
- self.core.information("Adhoc command %s: %s" % (status, notes), "Info")
+ self.core.information("Adhoc command %s: %s" % (status, notes),
+ "Info")
def adhoc_error(self, iq, adhoc_session):
self.core.xmpp.plugin['xep_0050'].terminate_command(adhoc_session)
error_message = self.core.get_error_message(iq)
- self.core.information("An error occured while executing the command: %s" % (error_message),
- 'Error')
+ self.core.information(
+ "An error occured while executing the command: %s" %
+ (error_message), 'Error')
def _cancel_adhoc_command(self, form, session):
self.core.xmpp.plugin['xep_0050'].cancel_command(session)
@@ -1461,6 +1646,7 @@ class HandlerCore:
self.core.xmpp.plugin['xep_0050'].terminate_command(session)
self.core.close_tab()
+
def _composing_tab_state(tab, state):
"""
Set a tab state to or from the "composing" state
@@ -1473,7 +1659,7 @@ def _composing_tab_state(tab, state):
elif isinstance(tab, tabs.ConversationTab):
values = ('true', 'direct', 'conversation')
else:
- return # should not happen
+ return # should not happen
show = config.get('show_composing_tabs')
show = show in values
@@ -1486,4 +1672,3 @@ def _composing_tab_state(tab, state):
tab.state = 'composing'
elif tab.state == 'composing' and state != 'composing':
tab.restore_state()
-
diff --git a/poezio/core/structs.py b/poezio/core/structs.py
index 7d568f04..72c9628a 100644
--- a/poezio/core/structs.py
+++ b/poezio/core/structs.py
@@ -2,8 +2,10 @@
Module defining structures useful to the core class and related methods
"""
-__all__ = ['ERROR_AND_STATUS_CODES', 'DEPRECATED_ERRORS', 'POSSIBLE_SHOW',
- 'Status', 'Command', 'Completion']
+__all__ = [
+ 'ERROR_AND_STATUS_CODES', 'DEPRECATED_ERRORS', 'POSSIBLE_SHOW', 'Status',
+ 'Command', 'Completion'
+]
# http://xmpp.org/extensions/xep-0045.html#errorstatus
ERROR_AND_STATUS_CODES = {
@@ -15,7 +17,7 @@ ERROR_AND_STATUS_CODES = {
'407': 'You are not in the member list',
'409': 'This nickname is already in use or has been reserved',
'503': 'The maximum number of users has been reached',
- }
+}
# http://xmpp.org/extensions/xep-0086.html
DEPRECATED_ERRORS = {
@@ -48,14 +50,18 @@ POSSIBLE_SHOW = {
'xa': 'xa'
}
+
class Status:
__slots__ = ('show', 'message')
+
def __init__(self, show, message):
self.show = show
self.message = message
+
class Command:
__slots__ = ('func', 'desc', 'comp', 'short_desc', 'usage')
+
def __init__(self, func, desc, comp, short_desc, usage):
self.func = func
self.desc = desc
@@ -63,11 +69,13 @@ class Command:
self.short_desc = short_desc
self.usage = usage
+
class Completion:
"""
A completion result essentially currying the input completion call.
"""
__slots__ = ['func', 'args', 'kwargs', 'comp_list']
+
def __init__(self, func, comp_list, *args, **kwargs):
self.func = func
self.comp_list = comp_list