131 lines
3.5 KiB
Python
131 lines
3.5 KiB
Python
from functools import wraps
|
||
import logging
|
||
from irc_api.secrets import USER, PASSWORD
|
||
from irc_api.irc import IRC
|
||
from irc_api.v5 import V5
|
||
|
||
|
||
PREFIX = ""
|
||
|
||
def command(name, event=None):
|
||
"""Decorate a function and return a Command instance."""
|
||
def decorator(func):
|
||
desc = name
|
||
if func.__doc__:
|
||
desc = func.__doc__
|
||
return Command(
|
||
name=name,
|
||
desc=desc,
|
||
func=func,
|
||
event=event
|
||
)
|
||
return decorator
|
||
|
||
|
||
class Command:
|
||
def __init__(self, name, desc, func, event=None):
|
||
self.name = name
|
||
self.desc = desc
|
||
self.func = func
|
||
if not event:
|
||
self.event = lambda m: m.text.startswith(PREFIX + name)
|
||
else:
|
||
self.event = event
|
||
|
||
self.cmnd_pack = None
|
||
|
||
def __call__(self, msg):
|
||
return self.func(self.cmnd_pack, msg)
|
||
|
||
|
||
class CommandsPack:
|
||
def __init__(self, bot):
|
||
self.bot = bot
|
||
|
||
|
||
class Bot:
|
||
"""Run the connexion between IRC's server and V5 one.
|
||
|
||
Attributes
|
||
----------
|
||
irc : IRC, public
|
||
IRC wrapper which handle communication with IRC server.
|
||
v5 : V5, public
|
||
V5 wrapper which handle communication with V5 server.
|
||
channels : list, public
|
||
The channels the bot will listen.
|
||
|
||
Methods
|
||
-------
|
||
start : NoneType, public
|
||
Runs the bot and connects it to IRC and V5 servers.
|
||
"""
|
||
def __init__(self, irc_params: tuple, v5_params: tuple, channels: list, prefix: str=""):
|
||
"""Initialize the Bot instance.
|
||
|
||
Parameters
|
||
----------
|
||
irc_params : tuple
|
||
Contains the IRC server informations (host, port)
|
||
v5_params : tuple
|
||
Contains the V5 server informations (host, port)
|
||
channels : list
|
||
Contains the names of the channels on which the bot will connect.
|
||
prefix : str, optionnal
|
||
The prefix on which the bot will react.
|
||
"""
|
||
global PREFIX
|
||
PREFIX = prefix
|
||
|
||
self.irc = IRC(*irc_params)
|
||
self.v5 = V5(v5_params, self.irc)
|
||
self.channels = channels
|
||
|
||
def start(self):
|
||
"""Starts the bot and connect it to the given IRC and V5 servers."""
|
||
# Start IRC
|
||
self.irc.start(USER, PASSWORD)
|
||
|
||
# Join channels
|
||
for channel in self.channels:
|
||
self.irc.join(channel)
|
||
|
||
# Start V5 hadndler
|
||
self.v5.start()
|
||
|
||
# Run IRC
|
||
self.irc.run()
|
||
|
||
def add_help(self):
|
||
help_callback = Command(
|
||
"aide",
|
||
"Affiche la liste des commandes disponibles.",
|
||
help_cmnd
|
||
)
|
||
help_callback.cmnd_pack = self
|
||
self.irc.callbacks.append(help_callback)
|
||
|
||
def add_commands_pack(self, commands_pack):
|
||
"""Add a package of commands to the bot.
|
||
|
||
Parameters
|
||
----------
|
||
commands_pack : CommandsPack
|
||
A commands pack which contains command's instances.
|
||
"""
|
||
cmnd_pack = commands_pack(self)
|
||
|
||
for cmnd_name in dir(commands_pack):
|
||
if not cmnd_name.startswith("__") and not cmnd_name.endswith("__"):
|
||
cmnd = getattr(commands_pack, cmnd_name)
|
||
cmnd.cmnd_pack = cmnd_pack
|
||
|
||
self.irc.callbacks.append(cmnd)
|
||
|
||
|
||
def help_cmnd(bot, msg):
|
||
"""Documentation des fonctions disponibles."""
|
||
bot.irc.send(msg.to, f"Aide des commandes")
|
||
for cmnd in bot.irc.callbacks:
|
||
bot.irc.send(msg.to, f" – {cmnd.name} : {cmnd.desc}")
|