diff options
Diffstat (limited to 'plugins/irc.py')
-rw-r--r-- | plugins/irc.py | 244 |
1 files changed, 80 insertions, 164 deletions
diff --git a/plugins/irc.py b/plugins/irc.py index 9d981c91..f3aa7b63 100644 --- a/plugins/irc.py +++ b/plugins/irc.py @@ -20,9 +20,9 @@ Global configuration :sorted: gateway - **Default:** ``irc.poez.io`` + **Default:** ``irc.jabberfr.org`` - The JID of the IRC gateway to use. If empty, irc.poez.io will be + The JID of the IRC gateway to use. If empty, irc.jabberfr.org will be used. Please try to run your own, though, it’s painless to setup. initial_connect @@ -46,17 +46,6 @@ section name, and the following options: .. glossary:: :sorted: - - login_command - **Default:** ``[empty]`` - - The command used to identify with the services (e.g. ``IDENTIFY mypassword``). - - login_nick - **Default:** ``[empty]`` - - The nickname to whom the auth command will be sent. - nickname **Default:** ``[empty]`` @@ -77,14 +66,6 @@ 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>`` @@ -109,9 +90,9 @@ Example configuration .. code-block:: ini [irc] - gateway = irc.poez.io + gateway = irc.jabberfr.org - [irc.freenode.net] + [irc.libera.chat] nickname = mynick login_nick = nickserv login_command = identify mypassword @@ -129,30 +110,30 @@ Example configuration """ +import asyncio + +from typing import Optional, Tuple, List, Any +from slixmpp.jid import JID, InvalidJID + from poezio.plugin import BasePlugin from poezio.decorators import command_args_parser from poezio.core.structs import Completion -from poezio import common from poezio import tabs class Plugin(BasePlugin): - 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) - + default_config = { + 'irc': { + "initial_connect": True, + "gateway": "irc.jabberfr.org", + } + } + + def init(self) -> None: + if self.config.getbool('initial_connect'): + asyncio.create_task( + self.initial_connect() + ) self.api.add_command( 'irc_join', self.command_irc_join, @@ -179,22 +160,38 @@ class Plugin(BasePlugin): 'example.com "hi there"`'), short='Open a private conversation with an IRC user') - def join(self, gateway, server): + async def join(self, gateway: str, server: JID) -> None: "Join irc rooms on a server" - nick = self.config.get_by_tabname( + nick: str = self.config.get_by_tabname( 'nickname', server, default='') or self.core.own_nick - rooms = self.config.get_by_tabname( + rooms: List[str] = self.config.get_by_tabname( 'rooms', server, default='').split(':') + joins = [] for room in rooms: room = '{}%{}@{}/{}'.format(room, server, gateway, nick) - self.core.command.join(room) + joins.append(self.core.command.join(room)) - def initial_connect(self): - gateway = self.config.get('gateway', 'irc.poez.io') - sections = self.config.sections() + await asyncio.gather(*joins) - for section in (s for s in sections if s != 'irc'): + async def initial_connect(self) -> None: + gateway: str = self.config.getstr('gateway') + sections: List[str] = self.config.sections() + sections_jid = [] + for sect in sections: + if sect == 'irc': + continue + try: + sect_jid = JID(sect) + if sect_jid != sect_jid.server: + self.api.information(f'Invalid server: {sect}', 'Warning') + continue + except InvalidJID: + self.api.information(f'Invalid server: {sect}', 'Warning') + continue + sections_jid.append(sect_jid) + + for section in sections_jid: room_suffix = '%{}@{}'.format(section, gateway) already_opened = False @@ -203,125 +200,40 @@ class Plugin(BasePlugin): already_opened = True break - 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: - - def login(gw, sect, log_nick, log_cmd, room_suff): - dest = '{}%{}'.format(log_nick, room_suff) - self.core.xmpp.send_message( - mto=dest, mbody=log_cmd, mtype='chat') - delayed = self.api.create_delayed_event( - 5, self.join, gw, sect) - self.api.add_timed_event(delayed) - - if not already_opened: - self.core.command.join(room_suffix + '/' + nick) - delayed = self.api.create_delayed_event( - 5, login, gateway, section, login_nick, login_command, - room_suffix[1:]) - self.api.add_timed_event(delayed) - else: - login(gateway, section, login_nick, login_command, - room_suffix[1:]) - 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 Completion(the_input.new_completion, sections, pos) + if not already_opened: + await self.join(gateway, section) @command_args_parser.quoted(1, 1) - def command_irc_join(self, args): + async def command_irc_join(self, args: Optional[List[str]]) -> None: """ /irc_join <room or server> """ if not args: - return self.core.command.help('irc_join') - sections = self.config.sections() + self.core.command.help('irc_join') + return + sections: List[str] = 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]) + if args[0] in sections: + try: + section_jid = JID(args[0]) + except InvalidJID: + self.api.information(f'Invalid address: {args[0]}', 'Error') + return + #self.config.get_by_tabname('rooms', section_jid) + await self.join_server_rooms(section_jid) else: - self.join_room(args[0]) + await self.join_room(args[0]) @command_args_parser.quoted(1, 1) - def command_irc_query(self, args): + def command_irc_query(self, args: Optional[List[str]]) -> None: """ Open a private conversation with the given nickname, on the current IRC server. """ if args is None: - return self.core.command.help('irc_query') + self.core.command.help('irc_query') + return current_tab_info = self.get_current_tab_irc_info() if not current_tab_info: return @@ -336,14 +248,14 @@ class Plugin(BasePlugin): else: self.core.command.message('{}'.format(jid)) - def join_server_rooms(self, section): + async def join_server_rooms(self, section: JID) -> None: """ 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) + gateway: str = self.config.getstr('gateway') + rooms: List[str] = self.config.get_by_tabname('rooms', section).split(':') + nick: str = self.config.get_by_tabname('nickname', section) if nick: nick = '/' + nick else: @@ -351,9 +263,9 @@ class Plugin(BasePlugin): suffix = '%{}@{}{}'.format(section, gateway, nick) for room in rooms: - self.core.command.join(room + suffix) + await self.core.command.join(room + suffix) - def join_room(self, name): + async def join_room(self, name: str) -> None: """ Join a room with only its name and the current tab """ @@ -361,20 +273,24 @@ class Plugin(BasePlugin): if not current_tab_info: return server, gateway = current_tab_info + try: + server_jid = JID(server) + except InvalidJID: + return room = '{}%{}@{}'.format(name, server, gateway) - if self.config.get_by_tabname('nickname', server): - room += '/' + self.config.get_by_tabname('nickname', server) + if self.config.get_by_tabname('nickname', server_jid.bare): + room += '/' + self.config.get_by_tabname('nickname', server_jid.bare) - self.core.command.join(room) + await self.core.command.join(room) - def get_current_tab_irc_info(self): + def get_current_tab_irc_info(self) -> Optional[Tuple[str, str]]: """ Return a tuple with the irc server and the gateway hostnames of the current tab. If the current tab is not an IRC channel or private conversation, a warning is displayed and None is returned """ - gateway = self.config.get('gateway', 'irc.poez.io') + gateway: str = self.config.getstr('gateway') current = self.api.current_tab() current_jid = current.jid if not current_jid.server == gateway: @@ -397,11 +313,11 @@ class Plugin(BasePlugin): return None return server, gateway - def completion_irc_join(self, the_input): + def completion_irc_join(self, the_input: Any) -> Completion: """ completion for /irc_join """ - sections = self.config.sections() + sections: List[str] = self.config.sections() if 'irc' in sections: sections.remove('irc') return Completion(the_input.new_completion, sections, 1) |