irc: Parse command args

This commit is contained in:
polyfloyd 2025-06-01 17:36:39 +02:00
parent 24088f3ba8
commit 2c8bda6151

View file

@ -1,5 +1,14 @@
"""
This module implements an IRC bot that aims to be compatible with the discord.py API in order to
facilitate re-use of the commands for that bot.
The supported features are the subset of what is needed for this project and not more than that.
"""
import asyncio import asyncio
import inspect
import os import os
import shlex
import sys import sys
import pydle import pydle
@ -8,6 +17,24 @@ from discord_webhook import DiscordEmbed
import commands as botcommands import commands as botcommands
def command_args(handler, sig):
parse = []
for par in list(sig.parameters.values())[1:]:
if par.annotation in (str, inspect._empty):
parse.append(lambda v: v)
elif par.annotation is bool:
parse.append(lambda v: bool(v))
else:
raise Exception(f"unsuported type {par.annotation}")
async def _proxy(ctx):
args = shlex.split(ctx._message)[1:]
args = [parse[i](v) for i, v in enumerate(args)]
await handler(ctx, *args)
return _proxy
class DiscordAuthor: class DiscordAuthor:
def __init__(self, nick): def __init__(self, nick):
self.nick = nick self.nick = nick
@ -32,7 +59,11 @@ class DiscordContext:
return NilTyping() return NilTyping()
async def reply(self, m): async def reply(self, m, file=None):
if file:
# TODO: Host the file somewhere so it can be downloaded.
m += f" {file.filename}"
lines = m.strip().split("\n") lines = m.strip().split("\n")
lines = [f"{self._source}: {line}" for line in lines] lines = [f"{self._source}: {line}" for line in lines]
await self._bot.message(self._target, "\n".join(lines)) await self._bot.message(self._target, "\n".join(lines))
@ -71,7 +102,8 @@ class DiscordImplBot(pydle.Client):
if not message.startswith(self._cmd_prefix): if not message.startswith(self._cmd_prefix):
return return
cmd_fn = self._cmds.get(message.removeprefix(self._cmd_prefix)) name = message.removeprefix(self._cmd_prefix).split(" ", 1)[0]
cmd_fn = self._cmds.get(name)
if not cmd_fn: if not cmd_fn:
return return
@ -83,7 +115,13 @@ class DiscordImplBot(pydle.Client):
def _reg_cmd(handler): def _reg_cmd(handler):
nonlocal name nonlocal name
name = name or handler.__name__ name = name or handler.__name__
self._cmds[name] = handler
sig = inspect.signature(handler)
if len(sig.parameters) == 1:
# Just the DiscordContext argument.
self._cmds[name] = handler
else:
self._cmds[name] = command_args(handler, sig)
return _reg_cmd return _reg_cmd