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.

59 lines
1.8 KiB

  1. from asyncio import StreamReader, StreamWriter, Queue
  2. from dataclasses import dataclass, field
  3. from datetime import datetime
  4. from logging import log, INFO
  5. from paircd.reply import RPL_CREATED, RPL_MYINFO, RPL_WELCOME, RPL_YOURHOST
  6. from paircd.message import Message
  7. from typing import Set
  8. @dataclass
  9. class Client:
  10. hostname: str
  11. reader: StreamReader
  12. writer: StreamWriter
  13. msg_queue: Queue = field(default_factory=Queue)
  14. nickname: str = ""
  15. username: str = ""
  16. realname: str = ""
  17. registered: bool = False
  18. away: str = ""
  19. channels: Set[str] = field(default_factory=set)
  20. def id(self) -> str:
  21. nickname = self.nickname or "<unknown>"
  22. username = self.username or "<unknown>"
  23. return f"{nickname}!{username}@{self.hostname}"
  24. def log(self, msg: str, level: int = INFO) -> None:
  25. log(level, f"{self.hostname} ({self.id()}) {msg}")
  26. async def write_forever(self) -> None:
  27. while True:
  28. msg = await self.msg_queue.get()
  29. self.writer.write(msg)
  30. await self.writer.drain()
  31. def write_message(self, message: Message) -> None:
  32. self.msg_queue.put_nowait(message.encode())
  33. def register(self) -> None:
  34. if self.registered:
  35. return
  36. if not (self.nickname and self.username and self.realname):
  37. return
  38. self.registered = True
  39. self.log("registered")
  40. self.write_message(RPL_WELCOME(self.nickname, self.id()))
  41. self.write_message(RPL_YOURHOST(self.nickname, "localhost", "paircd-0.0.1"))
  42. # TODO: Pull timestamp from server instance
  43. self.write_message(RPL_CREATED(self.nickname, datetime.utcnow()))
  44. # TODO: Display list of supported user & channel modes
  45. self.write_message(
  46. RPL_MYINFO(self.nickname, "localhost", "paircd-0.0.1", "", "")
  47. )