summaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authormathieui <mathieui@mathieui.net>2014-12-18 23:39:13 +0100
committermathieui <mathieui@mathieui.net>2014-12-18 23:39:13 +0100
commit510372cb3968f70057630c8e1e3ec9e0d253e740 (patch)
tree00cb48aa4f78d4394d874b6b0e63d84bfab74cf3 /plugins
parentb720a3f8ca57c9b126dfb0abb88cbc6ee3edf33d (diff)
downloadpoezio-510372cb3968f70057630c8e1e3ec9e0d253e740.tar.gz
poezio-510372cb3968f70057630c8e1e3ec9e0d253e740.tar.bz2
poezio-510372cb3968f70057630c8e1e3ec9e0d253e740.tar.xz
poezio-510372cb3968f70057630c8e1e3ec9e0d253e740.zip
Fix #2543 (irc plugin doesn't authenticate properly)
Join the fake room first, then send the message to nickserv, then join initial rooms. Also add two commands and one option.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/irc.py244
1 files changed, 220 insertions, 24 deletions
diff --git a/plugins/irc.py b/plugins/irc.py
index 6341851e..ae51c297 100644
--- a/plugins/irc.py
+++ b/plugins/irc.py
@@ -4,8 +4,9 @@ Plugin destined to be used together with the Biboumi IRC gateway.
For more information about Biboumi, please see the `official website`_.
This plugin is here as a non-default extension of the poezio configuration
-made to work with IRC rooms and logins. Therefore, it does not define any
-commands or do anything useful except on load.
+made to work with IRC rooms and logins. It also defines commands aimed at
+reducing the amount of effort needed to navigate smoothly between IRC and
+XMPP rooms.
Configuration
-------------
@@ -21,6 +22,14 @@ Global configuration
The JID of the IRC gateway to use. If empty, irc.poez.io will be
used. Please try to run your own, though, it’s painless to setup.
+ initial_connect
+ **Default:** ``true``
+
+ If you want to join all the rooms and try to authenticate with
+ nickserv when the plugin gets loaded. If ``false``, you will have
+ to use the :term:`/irc_login` command to authenticate, and the
+ :term:`/irc_join` command to join preconfigured rooms.
+
.. note:: There is no nickname option because the default from poezio will be used.
Server-specific configuration
@@ -49,14 +58,37 @@ section name, and the following options:
Your nickname on this server. If empty, the default configuration will be used.
- rooms
+ rooms [IRC plugin]
**Default:** ``[empty]``
The list of rooms to join on this server (e.g. ``#room1:#room2``).
.. note:: If no login_command or login_nick is set, the authentication phase
- won’t take place and you will join the rooms after a small delay.
+ won’t take place and you will join the rooms without authentication
+ with nickserv or whatever.
+
+Commands
+~~~~~~~~
+
+.. glossary::
+ :sorted:
+ /irc_login
+ **Usage:** ``/irc_login [server1] [server2]…``
+
+ Authenticate with the specified servers if they are correctly
+ configured. If no servers are provided, the plugin will try
+ them all. (You need to set :term:`login_nick` and
+ :term:`login_command` as well)
+
+ /irc_join
+ **Usage:** ``/irc_join <room or server>``
+
+ Join the specified room on the same server as the current tab (can
+ be a private conversation or a chatroom). If a server that appears
+ in the conversation is specified instead of a room, the plugin
+ will try to join all the rooms configured with autojoin on that
+ server.
Example configuration
~~~~~~~~~~~~~~~~~~~~~
@@ -69,7 +101,7 @@ Example configuration
[irc.freenode.net]
nickname = mynick
login_nick = nickserv
- login_command = identify mynick mypassword
+ login_command = identify mypassword
rooms = #testroom1:#testroom2
[irc.geeknode.org]
@@ -84,38 +116,202 @@ Example configuration
"""
from plugin import BasePlugin
+from decorators import command_args_parser
+import common
+import tabs
class Plugin(BasePlugin):
- def init(self):
-
- def join(server):
- "Join rooms after a small delay"
- nick = self.config.get('nickname', '', server) or self.core.own_nick
- rooms = self.config.get('rooms', '', server).split(':')
- for room in rooms:
- room = '{}%{}@{}/{}'.format(room, server, gateway, nick)
- self.core.command_join(room)
+ def init(self):
+ if self.config.get('initial_connect', True):
+ self.initial_connect()
+
+ self.api.add_command('irc_login', self.command_irc_login,
+ usage='[server] [server]…',
+ help=('Connect to the specified servers if they '
+ 'exist in the configuration and the login '
+ 'options are set. If not is given, the '
+ 'plugin will try all the sections in the '
+ 'configuration.'),
+ short='Login to irc servers with nickserv',
+ completion=self.completion_irc_login)
+
+ self.api.add_command('irc_join', self.command_irc_join,
+ usage='<room or server>',
+ help=('Join <room> in the same server as the '
+ 'current tab (if it is an IRC tab). Or '
+ 'join all the preconfigured rooms in '
+ '<server> '),
+ short='Join irc rooms more easily',
+ completion=self.completion_irc_join)
+
+ def join(self, gateway, server):
+ "Join irc rooms on a server"
+ nick = self.config.get_by_tabname('nickname', server, default='') or self.core.own_nick
+ rooms = self.config.get_by_tabname('rooms', server, default='').split(':')
+ for room in rooms:
+ room = '{}%{}@{}/{}'.format(room, server, gateway, nick)
+ self.core.command_join(room)
+
+ def initial_connect(self):
gateway = self.config.get('gateway', 'irc.poez.io')
sections = self.config.sections()
for section in (s for s in sections if s != 'irc'):
- server_suffix = '%{}@{}'.format(section, gateway)
+
+ room_suffix = '%{}@{}'.format(section, gateway)
already_opened = False
for tab in self.core.tabs:
- if tab.name.endswith(server_suffix):
+ if tab.name.endswith(room_suffix) and tab.joined:
already_opened = True
+ break
- login_command = self.config.get('login_command', '', section)
- login_nick = self.config.get('login_nick', '', section)
- nick = self.config.get('nickname', '', section) or self.core.own_nick
-
+ login_command = self.config.get_by_tabname('login_command', section, default='')
+ login_nick = self.config.get_by_tabname('login_nick', section, default='')
+ nick = self.config.get_by_tabname('nickname', section, default='') or self.core.own_nick
if login_command and login_nick:
- dest = '{}{}/{}'.format(login_nick, server_suffix, nick)
+ def login():
+ dest = '{}!{}'.format(login_nick, room_suffix[1:])
+ self.core.xmpp.send_message(mto=dest, mbody=login_command, mtype='chat')
+ delayed = self.api.create_delayed_event(5, self.join, gateway, section)
+ self.api.add_timed_event(delayed)
+ if not already_opened:
+ self.core.command_join(room_suffix + '/' + nick)
+ delayed = self.api.create_delayed_event(3, login)
+ self.api.add_timed_event(delayed)
+ else:
+ login()
+ elif not already_opened:
+ self.join(gateway, section)
+
+ @command_args_parser.quoted(0, -1)
+ def command_irc_login(self, args):
+ """
+ /irc_login [server] [server]…
+ """
+ gateway = self.config.get('gateway', 'irc.poez.io')
+ if args:
+ not_present = []
+ sections = self.config.sections()
+ for section in args:
+ if section not in sections:
+ not_present.append(section)
+ continue
+ login_command = self.config.get_by_tabname('login_command', section, default='')
+ login_nick = self.config.get_by_tabname('login_nick', section, default='')
+ if not login_command and not login_nick:
+ not_present.append(section)
+ continue
+
+ room_suffix = '%{}@{}'.format(section, gateway)
+ dest = '{}!{}'.format(login_nick, room_suffix[1:])
self.core.xmpp.send_message(mto=dest, mbody=login_command, mtype='chat')
+ if len(not_present) == 1:
+ self.api.information('Section %s does not exist or is not configured' % not_present[0], 'Warning')
+ elif len(not_present) > 1:
+ self.api.information('Sections %s do not exist or are not configured' % ', '.join(not_present), 'Warning')
+ else:
+ sections = self.config.sections()
+
+ for section in (s for s in sections if s != 'irc'):
+ login_command = self.config.get_by_tabname('login_command', section, default='')
+ login_nick = self.config.get_by_tabname('login_nick', section, default='')
+ if not login_nick and not login_command:
+ continue
+
+ room_suffix = '%{}@{}'.format(section, gateway)
+ dest = '{}!{}'.format(login_nick, room_suffix[1:])
+ self.core.xmpp.send_message(mto=dest, mbody=login_command, mtype='chat')
+
+
+ def completion_irc_login(self, the_input):
+ """
+ completion for /irc_login
+ """
+ args = the_input.text.split()
+ if '' in args:
+ args.remove('')
+ pos = the_input.get_argument_position()
+ sections = self.config.sections()
+ if 'irc' in sections:
+ sections.remove('irc')
+ for section in args:
+ try:
+ sections.remove(section)
+ except:
+ pass
+ return the_input.new_completion(sections, pos)
+
+ @command_args_parser.quoted(1, 1)
+ def command_irc_join(self, args):
+ """
+ /irc_join <room or server>
+ """
+ if not args:
+ return self.core.command_help('irc_join')
+ sections = self.config.sections()
+ if 'irc' in sections:
+ sections.remove('irc')
+ if args[0] in sections and self.config.get_by_tabname('rooms', args[0]):
+ self.join_server_rooms(args[0])
+ else:
+ self.join_room(args[0])
+
+ def join_server_rooms(self, section):
+ """
+ Join all the rooms configured for a section
+ (section = irc server)
+ """
+ gateway = self.config.get('gateway', 'irc.poez.io')
+ rooms = self.config.get_by_tabname('rooms', section).split(':')
+ nick = self.config.get_by_tabname('nickname', section)
+ if nick:
+ nick = '/' + nick
+ else:
+ nick = ''
+ suffix = '%{}@{}{}'.format(section, gateway, nick)
+
+ for room in rooms:
+ self.core.command_join(room + suffix)
+
+ def join_room(self, name):
+ """
+ Join a room with only its name and the current tab
+ """
+ gateway = self.config.get('gateway', 'irc.poez.io')
+ current = self.core.current_tab()
+ current_jid = common.safeJID(current.name)
+ if not current_jid.server == gateway:
+ self.api.information('The current tab does not appear to be an IRC one', 'Warning')
+ return
+ if isinstance(current, tabs.OneToOneTab):
+ if not '!' in current_jid.node:
+ server = current_jid.node
+ else:
+ ignored, server = current_jid.node.rsplit('!', 1)
+ elif isinstance(current, tabs.MucTab):
+ if not '%' in current_jid.node:
+ server = current_jid.node
+ else:
+ ignored, server = current_jid.node.rsplit('%', 1)
+ else:
+ self.api.information('The current tab does not appear to be an IRC one', 'Warning')
+ return
+
+ room = '{}%{}@{}'.format(name, server, gateway)
+ if self.config.get_by_tabname('nickname', server):
+ room += '/' + self.config.get_by_tabname('nickname', server)
+
+ self.core.command_join(room)
+
+ def completion_irc_join(self, the_input):
+ """
+ completion for /irc_join
+ """
+ sections = self.config.sections()
+ if 'irc' in sections:
+ sections.remove('irc')
+ return the_input.new_completion(sections, 1)
- if not already_opened:
- delayed = self.api.create_delayed_event(5, join, section)
- self.api.add_timed_event(delayed)