2014-03-27 23:03:20 +00:00
|
|
|
|
"""
|
|
|
|
|
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
|
2014-12-18 22:39:13 +00:00
|
|
|
|
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.
|
2014-03-27 23:03:20 +00:00
|
|
|
|
|
|
|
|
|
Configuration
|
|
|
|
|
-------------
|
|
|
|
|
|
2015-07-22 22:37:19 +00:00
|
|
|
|
Every feature of this plugin is centered around its :ref:`configuration file <plugin-configuration>`,
|
|
|
|
|
so you have to make sure it is filled properly.
|
|
|
|
|
|
2014-03-27 23:03:20 +00:00
|
|
|
|
Global configuration
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
.. glossary::
|
|
|
|
|
:sorted:
|
|
|
|
|
|
|
|
|
|
gateway
|
2022-04-07 17:35:19 +00:00
|
|
|
|
**Default:** ``irc.jabberfr.org``
|
2014-03-27 23:03:20 +00:00
|
|
|
|
|
2022-04-07 17:35:19 +00:00
|
|
|
|
The JID of the IRC gateway to use. If empty, irc.jabberfr.org will be
|
2014-03-27 23:03:20 +00:00
|
|
|
|
used. Please try to run your own, though, it’s painless to setup.
|
|
|
|
|
|
2014-12-18 22:39:13 +00:00
|
|
|
|
initial_connect
|
|
|
|
|
**Default:** ``true``
|
|
|
|
|
|
2015-07-21 16:49:26 +00:00
|
|
|
|
Set to ``true`` if you want to join all the rooms and try to
|
|
|
|
|
authenticate with nickserv when the plugin gets loaded. If it set to
|
|
|
|
|
``false``, you will have to use the :term:`/irc_login` command to
|
|
|
|
|
authenticate, and the :term:`/irc_join` command to join
|
|
|
|
|
preconfigured rooms.
|
2014-12-18 22:39:13 +00:00
|
|
|
|
|
2014-03-27 23:03:20 +00:00
|
|
|
|
.. note:: There is no nickname option because the default from poezio will be used.
|
|
|
|
|
|
|
|
|
|
Server-specific configuration
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
Write a configuration section for each server, with the server address as the
|
|
|
|
|
section name, and the following options:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. glossary::
|
|
|
|
|
:sorted:
|
|
|
|
|
|
|
|
|
|
nickname
|
|
|
|
|
**Default:** ``[empty]``
|
|
|
|
|
|
|
|
|
|
Your nickname on this server. If empty, the default configuration will be used.
|
|
|
|
|
|
2014-12-18 22:39:13 +00:00
|
|
|
|
rooms [IRC plugin]
|
2014-03-27 23:03:20 +00:00
|
|
|
|
**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
|
2014-12-18 22:39:13 +00:00
|
|
|
|
won’t take place and you will join the rooms without authentication
|
|
|
|
|
with nickserv or whatever.
|
|
|
|
|
|
|
|
|
|
Commands
|
|
|
|
|
~~~~~~~~
|
|
|
|
|
|
|
|
|
|
.. glossary::
|
|
|
|
|
:sorted:
|
2014-03-27 23:03:20 +00:00
|
|
|
|
|
2014-12-18 22:39:13 +00:00
|
|
|
|
/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.
|
2014-03-27 23:03:20 +00:00
|
|
|
|
|
2015-01-13 19:02:10 +00:00
|
|
|
|
/irc_query
|
|
|
|
|
**Usage:** ``/irc_query <nickname> [message]``
|
|
|
|
|
|
|
|
|
|
Open a private conversation with the given nickname, on the same IRC
|
|
|
|
|
server as the current tab (can be a private conversation or a
|
|
|
|
|
chatroom). Doing `/irc_query foo "hello there"` when the current
|
|
|
|
|
tab is #foo%irc.example.com@biboumi.example.com is equivalent to
|
2016-09-20 17:20:57 +00:00
|
|
|
|
``/message foo%irc.example.com@biboumi.example.com "hello there"``
|
2015-01-13 19:02:10 +00:00
|
|
|
|
|
2014-03-27 23:03:20 +00:00
|
|
|
|
Example configuration
|
|
|
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
|
|
|
|
.. code-block:: ini
|
|
|
|
|
|
|
|
|
|
[irc]
|
2022-04-07 17:35:19 +00:00
|
|
|
|
gateway = irc.jabberfr.org
|
2014-03-27 23:03:20 +00:00
|
|
|
|
|
2022-04-07 17:35:19 +00:00
|
|
|
|
[irc.libera.chat]
|
2014-03-27 23:03:20 +00:00
|
|
|
|
nickname = mynick
|
|
|
|
|
login_nick = nickserv
|
2014-12-18 22:39:13 +00:00
|
|
|
|
login_command = identify mypassword
|
2014-03-27 23:03:20 +00:00
|
|
|
|
rooms = #testroom1:#testroom2
|
|
|
|
|
|
|
|
|
|
[irc.geeknode.org]
|
|
|
|
|
nickname = anothernick
|
|
|
|
|
login_nick = C
|
|
|
|
|
login_command = nick identify mypassword
|
|
|
|
|
rooms = #testvroum
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. _official website: http://biboumi.louiz.org/
|
2015-01-13 19:02:10 +00:00
|
|
|
|
|
2014-03-27 23:03:20 +00:00
|
|
|
|
"""
|
|
|
|
|
|
2021-02-16 21:03:10 +00:00
|
|
|
|
import asyncio
|
|
|
|
|
|
2022-04-07 17:35:19 +00:00
|
|
|
|
from typing import Optional, Tuple, List, Any
|
2021-09-26 18:21:33 +00:00
|
|
|
|
from slixmpp.jid import JID, InvalidJID
|
|
|
|
|
|
2016-06-27 23:10:52 +00:00
|
|
|
|
from poezio.plugin import BasePlugin
|
|
|
|
|
from poezio.decorators import command_args_parser
|
2016-08-21 13:27:53 +00:00
|
|
|
|
from poezio.core.structs import Completion
|
2016-06-27 23:10:52 +00:00
|
|
|
|
from poezio import tabs
|
2014-03-27 23:03:20 +00:00
|
|
|
|
|
|
|
|
|
|
2018-08-15 11:13:17 +00:00
|
|
|
|
class Plugin(BasePlugin):
|
2022-04-08 17:22:41 +00:00
|
|
|
|
default_config = {
|
|
|
|
|
'irc': {
|
|
|
|
|
"initial_connect": True,
|
|
|
|
|
"gateway": "irc.jabberfr.org",
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-07 17:35:19 +00:00
|
|
|
|
def init(self) -> None:
|
|
|
|
|
if self.config.getbool('initial_connect'):
|
2021-11-18 14:23:46 +00:00
|
|
|
|
asyncio.create_task(
|
2021-02-16 21:03:10 +00:00
|
|
|
|
self.initial_connect()
|
|
|
|
|
)
|
2018-08-15 11:13:17 +00:00
|
|
|
|
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)
|
|
|
|
|
|
|
|
|
|
self.api.add_command(
|
|
|
|
|
'irc_query',
|
|
|
|
|
self.command_irc_query,
|
|
|
|
|
usage='<nickname> [message]',
|
|
|
|
|
help=('Open a private conversation with the '
|
|
|
|
|
'given <nickname>, on the current IRC '
|
|
|
|
|
'server. Optionally immediately send '
|
|
|
|
|
'the given message. For example, if the '
|
|
|
|
|
'current tab is #foo%irc.example.com@'
|
|
|
|
|
'biboumi.example.com, doing `/irc_query '
|
|
|
|
|
'nick "hi there"` is equivalent to '
|
|
|
|
|
'`/message nick%irc.example.com@biboumi.'
|
|
|
|
|
'example.com "hi there"`'),
|
|
|
|
|
short='Open a private conversation with an IRC user')
|
2015-01-13 19:02:10 +00:00
|
|
|
|
|
2022-04-07 17:35:19 +00:00
|
|
|
|
async def join(self, gateway: str, server: JID) -> None:
|
2014-12-18 22:39:13 +00:00
|
|
|
|
"Join irc rooms on a server"
|
2022-04-07 17:35:19 +00:00
|
|
|
|
nick: str = self.config.get_by_tabname(
|
2018-08-15 11:13:17 +00:00
|
|
|
|
'nickname', server, default='') or self.core.own_nick
|
2022-04-07 17:35:19 +00:00
|
|
|
|
rooms: List[str] = self.config.get_by_tabname(
|
2018-08-15 11:13:17 +00:00
|
|
|
|
'rooms', server, default='').split(':')
|
2021-02-16 21:03:10 +00:00
|
|
|
|
joins = []
|
2014-12-18 22:39:13 +00:00
|
|
|
|
for room in rooms:
|
|
|
|
|
room = '{}%{}@{}/{}'.format(room, server, gateway, nick)
|
2021-02-16 21:03:10 +00:00
|
|
|
|
joins.append(self.core.command.join(room))
|
|
|
|
|
|
|
|
|
|
await asyncio.gather(*joins)
|
2014-12-18 22:39:13 +00:00
|
|
|
|
|
2022-04-07 17:35:19 +00:00
|
|
|
|
async def initial_connect(self) -> None:
|
2022-04-08 17:22:41 +00:00
|
|
|
|
gateway: str = self.config.getstr('gateway')
|
2022-04-07 17:35:19 +00:00
|
|
|
|
sections: List[str] = self.config.sections()
|
2014-03-27 23:03:20 +00:00
|
|
|
|
|
2021-09-26 18:21:33 +00:00
|
|
|
|
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)
|
2014-12-18 22:39:13 +00:00
|
|
|
|
|
2021-09-26 18:21:33 +00:00
|
|
|
|
for section in sections_jid:
|
2014-12-18 22:39:13 +00:00
|
|
|
|
room_suffix = '%{}@{}'.format(section, gateway)
|
2014-03-27 23:03:20 +00:00
|
|
|
|
|
|
|
|
|
already_opened = False
|
|
|
|
|
for tab in self.core.tabs:
|
2019-04-08 12:49:57 +00:00
|
|
|
|
if tab.name.endswith(room_suffix) and tab.joined:
|
2014-03-27 23:03:20 +00:00
|
|
|
|
already_opened = True
|
2014-12-18 22:39:13 +00:00
|
|
|
|
break
|
2014-03-27 23:03:20 +00:00
|
|
|
|
|
2021-09-26 18:21:33 +00:00
|
|
|
|
if not already_opened:
|
2021-02-16 21:03:10 +00:00
|
|
|
|
await self.join(gateway, section)
|
2014-12-18 22:39:13 +00:00
|
|
|
|
|
|
|
|
|
@command_args_parser.quoted(1, 1)
|
2022-04-07 17:35:19 +00:00
|
|
|
|
async def command_irc_join(self, args: Optional[List[str]]) -> None:
|
2014-12-18 22:39:13 +00:00
|
|
|
|
"""
|
|
|
|
|
/irc_join <room or server>
|
|
|
|
|
"""
|
|
|
|
|
if not args:
|
2022-04-07 17:35:19 +00:00
|
|
|
|
self.core.command.help('irc_join')
|
|
|
|
|
return
|
|
|
|
|
sections: List[str] = self.config.sections()
|
2014-12-18 22:39:13 +00:00
|
|
|
|
if 'irc' in sections:
|
|
|
|
|
sections.remove('irc')
|
2021-09-26 18:21:33 +00:00
|
|
|
|
if args[0] in sections:
|
|
|
|
|
try:
|
|
|
|
|
section_jid = JID(args[0])
|
|
|
|
|
except InvalidJID:
|
2022-04-07 17:35:19 +00:00
|
|
|
|
self.api.information(f'Invalid address: {args[0]}', 'Error')
|
2021-09-26 18:21:33 +00:00
|
|
|
|
return
|
2022-04-07 17:35:19 +00:00
|
|
|
|
#self.config.get_by_tabname('rooms', section_jid)
|
2021-09-26 18:21:33 +00:00
|
|
|
|
await self.join_server_rooms(section_jid)
|
2014-12-18 22:39:13 +00:00
|
|
|
|
else:
|
2021-02-16 21:03:10 +00:00
|
|
|
|
await self.join_room(args[0])
|
2014-12-18 22:39:13 +00:00
|
|
|
|
|
2015-01-13 19:02:10 +00:00
|
|
|
|
@command_args_parser.quoted(1, 1)
|
2022-04-07 17:35:19 +00:00
|
|
|
|
def command_irc_query(self, args: Optional[List[str]]) -> None:
|
2015-01-13 19:02:10 +00:00
|
|
|
|
"""
|
|
|
|
|
Open a private conversation with the given nickname, on the current IRC
|
|
|
|
|
server.
|
|
|
|
|
"""
|
|
|
|
|
if args is None:
|
2022-04-07 17:35:19 +00:00
|
|
|
|
self.core.command.help('irc_query')
|
|
|
|
|
return
|
2015-01-13 19:02:10 +00:00
|
|
|
|
current_tab_info = self.get_current_tab_irc_info()
|
|
|
|
|
if not current_tab_info:
|
|
|
|
|
return
|
|
|
|
|
server, gateway = current_tab_info
|
|
|
|
|
nickname = args[0]
|
|
|
|
|
message = None
|
|
|
|
|
if len(args) == 2:
|
|
|
|
|
message = args[1]
|
2016-09-20 17:20:57 +00:00
|
|
|
|
jid = '{}%{}@{}'.format(nickname, server, gateway)
|
2015-01-13 19:02:10 +00:00
|
|
|
|
if message:
|
2016-03-31 22:24:58 +00:00
|
|
|
|
self.core.command.message('{} "{}"'.format(jid, message))
|
2015-01-13 19:02:10 +00:00
|
|
|
|
else:
|
2016-03-31 22:24:58 +00:00
|
|
|
|
self.core.command.message('{}'.format(jid))
|
2015-01-13 19:02:10 +00:00
|
|
|
|
|
2022-04-07 17:35:19 +00:00
|
|
|
|
async def join_server_rooms(self, section: JID) -> None:
|
2014-12-18 22:39:13 +00:00
|
|
|
|
"""
|
|
|
|
|
Join all the rooms configured for a section
|
|
|
|
|
(section = irc server)
|
|
|
|
|
"""
|
2022-04-08 17:22:41 +00:00
|
|
|
|
gateway: str = self.config.getstr('gateway')
|
2022-04-07 17:35:19 +00:00
|
|
|
|
rooms: List[str] = self.config.get_by_tabname('rooms', section).split(':')
|
|
|
|
|
nick: str = self.config.get_by_tabname('nickname', section)
|
2014-12-18 22:39:13 +00:00
|
|
|
|
if nick:
|
|
|
|
|
nick = '/' + nick
|
|
|
|
|
else:
|
|
|
|
|
nick = ''
|
|
|
|
|
suffix = '%{}@{}{}'.format(section, gateway, nick)
|
|
|
|
|
|
|
|
|
|
for room in rooms:
|
2021-02-16 21:03:10 +00:00
|
|
|
|
await self.core.command.join(room + suffix)
|
2014-12-18 22:39:13 +00:00
|
|
|
|
|
2022-04-07 17:35:19 +00:00
|
|
|
|
async def join_room(self, name: str) -> None:
|
2014-12-18 22:39:13 +00:00
|
|
|
|
"""
|
|
|
|
|
Join a room with only its name and the current tab
|
|
|
|
|
"""
|
2015-01-13 19:02:10 +00:00
|
|
|
|
current_tab_info = self.get_current_tab_irc_info()
|
|
|
|
|
if not current_tab_info:
|
|
|
|
|
return
|
|
|
|
|
server, gateway = current_tab_info
|
2021-09-26 18:21:33 +00:00
|
|
|
|
try:
|
|
|
|
|
server_jid = JID(server)
|
|
|
|
|
except InvalidJID:
|
|
|
|
|
return
|
2015-01-13 19:02:10 +00:00
|
|
|
|
|
|
|
|
|
room = '{}%{}@{}'.format(name, server, gateway)
|
2022-04-07 17:35:19 +00:00
|
|
|
|
if self.config.get_by_tabname('nickname', server_jid.bare):
|
|
|
|
|
room += '/' + self.config.get_by_tabname('nickname', server_jid.bare)
|
2015-01-13 19:02:10 +00:00
|
|
|
|
|
2021-02-16 21:03:10 +00:00
|
|
|
|
await self.core.command.join(room)
|
2015-01-13 19:02:10 +00:00
|
|
|
|
|
2022-04-07 17:35:19 +00:00
|
|
|
|
def get_current_tab_irc_info(self) -> Optional[Tuple[str, str]]:
|
2015-01-13 19:02:10 +00:00
|
|
|
|
"""
|
|
|
|
|
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
|
|
|
|
|
"""
|
2022-04-08 17:22:41 +00:00
|
|
|
|
gateway: str = self.config.getstr('gateway')
|
2018-08-23 19:35:28 +00:00
|
|
|
|
current = self.api.current_tab()
|
2019-04-28 00:02:49 +00:00
|
|
|
|
current_jid = current.jid
|
2014-12-18 22:39:13 +00:00
|
|
|
|
if not current_jid.server == gateway:
|
2018-08-15 11:13:17 +00:00
|
|
|
|
self.api.information(
|
|
|
|
|
'The current tab does not appear to be an IRC one', 'Warning')
|
2015-01-13 19:02:10 +00:00
|
|
|
|
return None
|
2014-12-18 22:39:13 +00:00
|
|
|
|
if isinstance(current, tabs.OneToOneTab):
|
2017-10-08 14:36:10 +00:00
|
|
|
|
if '%' not in current_jid.node:
|
2014-12-18 22:39:13 +00:00
|
|
|
|
server = current_jid.node
|
|
|
|
|
else:
|
2016-09-20 17:20:57 +00:00
|
|
|
|
ignored, server = current_jid.node.rsplit('%', 1)
|
2014-12-18 22:39:13 +00:00
|
|
|
|
elif isinstance(current, tabs.MucTab):
|
2017-10-08 14:36:10 +00:00
|
|
|
|
if '%' not in current_jid.node:
|
2014-12-18 22:39:13 +00:00
|
|
|
|
server = current_jid.node
|
|
|
|
|
else:
|
|
|
|
|
ignored, server = current_jid.node.rsplit('%', 1)
|
|
|
|
|
else:
|
2018-08-15 11:13:17 +00:00
|
|
|
|
self.api.information(
|
|
|
|
|
'The current tab does not appear to be an IRC one', 'Warning')
|
2015-01-13 19:02:10 +00:00
|
|
|
|
return None
|
|
|
|
|
return server, gateway
|
2014-12-18 22:39:13 +00:00
|
|
|
|
|
2022-04-07 17:35:19 +00:00
|
|
|
|
def completion_irc_join(self, the_input: Any) -> Completion:
|
2014-12-18 22:39:13 +00:00
|
|
|
|
"""
|
|
|
|
|
completion for /irc_join
|
|
|
|
|
"""
|
2022-04-07 17:35:19 +00:00
|
|
|
|
sections: List[str] = self.config.sections()
|
2014-12-18 22:39:13 +00:00
|
|
|
|
if 'irc' in sections:
|
|
|
|
|
sections.remove('irc')
|
2016-08-21 13:27:53 +00:00
|
|
|
|
return Completion(the_input.new_completion, sections, 1)
|