|
|
- from asyncio import create_task, run, start_server, IncompleteReadError
- from asyncio.streams import StreamReader, StreamWriter
- from logging import basicConfig, info, INFO
- import logging
- from os import getenv
- from sys import exc_info
-
- from dotenv import load_dotenv
-
- load_dotenv("../.env")
-
- from paircd.client import Client # noqa: E402
- from paircd.handlers import handle_cmd, register_cmd_handlers # noqa: E402
- from paircd.message import parse_message # noqa: E402
- from paircd.server import Server # noqa: E402
-
- basicConfig(format="%(asctime)s [%(levelname)s] - %(message)s", level=INFO)
-
-
- async def read_forever(server: Server, client: Client) -> None:
- while not client.closed:
- try:
- raw_msg = await client.reader.readuntil(b"\r\n")
- except IncompleteReadError:
- logging.warning("client connection closed", exc_info=exc_info())
- await server.disconnect_client(client.nickname, "Connection reset by peer")
- break
-
- msg = parse_message(raw_msg)
- await handle_cmd(server, client, msg)
-
-
- async def serve() -> None:
- bind_addr = getenv("BIND_ADDR") or "0.0.0.0"
- port = getenv("PORT") or 6667
-
- irc_server = Server()
- register_cmd_handlers()
-
- async def register_client(reader: StreamReader, writer: StreamWriter) -> None:
- client = Client(
- hostname=writer.get_extra_info("peername")[0],
- reader=reader,
- writer=writer,
- )
- create_task(read_forever(irc_server, client))
- create_task(client.write_until_closed(irc_server))
-
- server = await start_server(
- register_client,
- bind_addr,
- port,
- reuse_port=True,
- )
-
- info(f"Listening on {bind_addr}:{port}")
- async with server:
- await server.serve_forever()
-
-
- def main() -> None:
- run(serve())
-
-
- if __name__ == "__main__":
- main()
|