From abdc5f45088a39468744b92ee112d8a96b47bd3d Mon Sep 17 00:00:00 2001 From: Forest Belton <65484+forestbelton@users.noreply.github.com> Date: Mon, 21 Jun 2021 23:56:57 -0400 Subject: [PATCH] Simplify handler registration --- .flake8 | 2 ++ paircd/command_handler.py | 18 ++++++++++++++++++ paircd/handle.py | 27 --------------------------- paircd/handler/join.py | 6 ++++-- paircd/handler/nick.py | 4 ++++ paircd/handler/privmsg.py | 6 +++++- paircd/handler/user.py | 4 ++++ paircd/handlers.py | 34 ++++++++++++++++++++++++++++++++++ paircd/main.py | 12 ++---------- 9 files changed, 73 insertions(+), 40 deletions(-) create mode 100644 .flake8 create mode 100644 paircd/command_handler.py delete mode 100644 paircd/handle.py create mode 100644 paircd/handlers.py diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..7da1f96 --- /dev/null +++ b/.flake8 @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 100 diff --git a/paircd/command_handler.py b/paircd/command_handler.py new file mode 100644 index 0000000..e25912d --- /dev/null +++ b/paircd/command_handler.py @@ -0,0 +1,18 @@ +from dataclasses import dataclass +from typing import Awaitable, Callable + +from paircd.client import Client +from paircd.message import Message +from paircd.server import Server + +HandlerFunc = Callable[ + [Server, Client, Message], + Awaitable[None], +] + + +@dataclass +class CommandHandler: + cmd: str + argc: int + handler: HandlerFunc diff --git a/paircd/handle.py b/paircd/handle.py deleted file mode 100644 index f2a08f1..0000000 --- a/paircd/handle.py +++ /dev/null @@ -1,27 +0,0 @@ -import logging -from typing import Any, Awaitable, Callable, Dict - -from paircd.client import Client -from paircd.log import log_client -from paircd.message import Message -from paircd.server import Server - -CMD_HANDLERS: Dict[str, Any] = {} -CMD_EXPECTED_ARGC: Dict[str, int] = {} - -CmdHandler = Callable[ - [Server, Client, Message], - Awaitable[None], -] - - -def register_cmd_handler(cmd: str, argc: int, handler: CmdHandler) -> None: - CMD_EXPECTED_ARGC[cmd] = argc - CMD_HANDLERS[cmd] = handler - - -async def handle_cmd(server: Server, client: Client, msg: Message) -> None: - if msg.cmd not in CMD_HANDLERS: - log_client(client, f"used unknown command {msg.cmd}", level=logging.WARN) - return - await CMD_HANDLERS[msg.cmd](server, client, msg) diff --git a/paircd/handler/join.py b/paircd/handler/join.py index 51386ee..283cef3 100644 --- a/paircd/handler/join.py +++ b/paircd/handler/join.py @@ -1,8 +1,7 @@ -from asyncio import create_task import logging -from paircd.channel import Channel from paircd.client import Client +from paircd.command_handler import CommandHandler from paircd.log import log_client from paircd.message import Message from paircd.server import Server @@ -27,3 +26,6 @@ async def handle_join(server: Server, client: Client, msg: Message) -> None: await channel.msg_queue.put( Message(cmd="JOIN", args=[channel_name], prefix=client.id()).encode() ) + + +JOIN = CommandHandler("JOIN", 1, handle_join) diff --git a/paircd/handler/nick.py b/paircd/handler/nick.py index cfd4ed1..0a6dba9 100644 --- a/paircd/handler/nick.py +++ b/paircd/handler/nick.py @@ -1,4 +1,5 @@ from paircd.client import Client +from paircd.command_handler import CommandHandler from paircd.log import log_client from paircd.message import Message from paircd.server import Server @@ -17,3 +18,6 @@ async def handle_nick(server: Server, client: Client, msg: Message) -> None: if client.username and client.realname: client.registered = True log_client(client, "registered") + + +NICK = CommandHandler("NICK", 1, handle_nick) diff --git a/paircd/handler/privmsg.py b/paircd/handler/privmsg.py index 21cc144..2818576 100644 --- a/paircd/handler/privmsg.py +++ b/paircd/handler/privmsg.py @@ -1,7 +1,8 @@ import logging -from paircd.log import log_client from paircd.client import Client +from paircd.command_handler import CommandHandler +from paircd.log import log_client from paircd.message import Message from paircd.server import Server @@ -23,3 +24,6 @@ async def handle_privmsg(server: Server, client: Client, msg: Message) -> None: return log_client(client, "unknown recipient", level=logging.WARN) + + +PRIVMSG = CommandHandler("PRIVMSG", 2, handle_privmsg) diff --git a/paircd/handler/user.py b/paircd/handler/user.py index 3080e6a..482b883 100644 --- a/paircd/handler/user.py +++ b/paircd/handler/user.py @@ -1,6 +1,7 @@ import logging from paircd.client import Client +from paircd.command_handler import CommandHandler from paircd.log import log_client from paircd.message import Message from paircd.server import Server @@ -17,3 +18,6 @@ async def handle_user(server: Server, client: Client, msg: Message) -> None: if client.nickname: client.registered = True log_client(client, "registered") + + +USER = CommandHandler("USER", 4, handle_user) diff --git a/paircd/handlers.py b/paircd/handlers.py new file mode 100644 index 0000000..29a7340 --- /dev/null +++ b/paircd/handlers.py @@ -0,0 +1,34 @@ +from logging import WARN +from typing import Dict + +from paircd.client import Client +from paircd.command_handler import CommandHandler +from paircd.log import log_client +from paircd.message import Message +from paircd.server import Server + +from paircd.handler.join import JOIN +from paircd.handler.nick import NICK +from paircd.handler.privmsg import PRIVMSG +from paircd.handler.user import USER + +ALL_HANDLERS = [ + JOIN, + NICK, + PRIVMSG, + USER, +] + +CMD_HANDLERS: Dict[str, CommandHandler] = {} + + +def register_cmd_handlers() -> None: + for handler in ALL_HANDLERS: + CMD_HANDLERS[handler.cmd] = handler + + +async def handle_cmd(server: Server, client: Client, msg: Message) -> None: + if msg.cmd not in CMD_HANDLERS: + log_client(client, f"used unknown command {msg.cmd}", level=WARN) + return + await CMD_HANDLERS[msg.cmd].handler(server, client, msg) diff --git a/paircd/main.py b/paircd/main.py index f8f0f60..6f157a8 100644 --- a/paircd/main.py +++ b/paircd/main.py @@ -4,11 +4,7 @@ import logging import os from paircd.client import Client -from paircd.handle import handle_cmd, register_cmd_handler -from paircd.handler.join import handle_join -from paircd.handler.nick import handle_nick -from paircd.handler.privmsg import handle_privmsg -from paircd.handler.user import handle_user +from paircd.handlers import handle_cmd, register_cmd_handlers from paircd.message import parse_message from paircd.server import Server @@ -30,12 +26,8 @@ async def main() -> None: bind_addr = os.getenv("BIND_ADDR") or "0.0.0.0" port = os.getenv("PORT") or 6667 - register_cmd_handler("JOIN", 1, handle_join) - register_cmd_handler("NICK", 1, handle_nick) - register_cmd_handler("PRIVMSG", 2, handle_privmsg) - register_cmd_handler("USER", 4, handle_user) - irc_server = Server() + register_cmd_handlers() async def register_client(reader: StreamReader, writer: StreamWriter) -> None: client = Client(