python ircd using asyncio
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
1.4 KiB

  1. import asyncio
  2. from asyncio.streams import StreamReader, StreamWriter
  3. import logging
  4. import os
  5. from paircd.client import Client
  6. from paircd.handlers import handle_cmd, register_cmd_handlers
  7. from paircd.message import parse_message
  8. from paircd.server import Server
  9. logging.basicConfig(
  10. format="%(asctime)s [%(levelname)s] - %(message)s", level=logging.INFO
  11. )
  12. logger = logging.getLogger()
  13. async def read_forever(server: Server, client: Client) -> None:
  14. while True:
  15. raw_msg = await client.reader.readuntil(b"\r\n")
  16. msg = parse_message(raw_msg)
  17. await handle_cmd(server, client, msg)
  18. async def serve() -> None:
  19. bind_addr = os.getenv("BIND_ADDR") or "0.0.0.0"
  20. port = os.getenv("PORT") or 6667
  21. irc_server = Server()
  22. register_cmd_handlers()
  23. async def register_client(reader: StreamReader, writer: StreamWriter) -> None:
  24. client = Client(
  25. hostname=writer.get_extra_info("peername")[0],
  26. reader=reader,
  27. writer=writer,
  28. )
  29. asyncio.create_task(read_forever(irc_server, client))
  30. asyncio.create_task(client.write_forever())
  31. server = await asyncio.start_server(
  32. register_client,
  33. bind_addr,
  34. port,
  35. reuse_port=True,
  36. )
  37. logger.info(f"Listening on {bind_addr}:{port}")
  38. async with server:
  39. await server.serve_forever()
  40. def main() -> None:
  41. asyncio.run(serve())
  42. if __name__ == "__main__":
  43. main()