diff --git a/test.py b/test.py index 5af2d7b..92e75e4 100644 --- a/test.py +++ b/test.py @@ -4,7 +4,7 @@ import asyncio import logging -from yaboli import Room +import yaboli FORMAT = "{asctime} [{levelname:<7}] <{name}> {funcName}(): {message}" DATE_FORMAT = "%F %T" @@ -19,37 +19,17 @@ logger = logging.getLogger('yaboli') logger.setLevel(logging.DEBUG) logger.addHandler(handler) -class TestClient: - def __init__(self): - self.room = Room("test", target_nick="testbot") - self.room.register_event("join", self.on_join) - self.room.register_event("part", self.on_part) - self.room.register_event("send", self.on_send) +class TestClient(yaboli.Client): + DEFAULT_NICK = "testbot" - self.stop = asyncio.Event() + async def started(self): + await self.join("test") - async def run(self): - await self.room.connect() - await self.stop.wait() - - async def on_join(self, user): - print() - print(f"{user.nick} ({user.atmention}) joined.") - if user.is_person: - print("They're a person!") - elif user.is_bot: - print("They're just a bot") - else: - print("This should never happen") - print() - - async def on_part(self, user): - print(f"{user.nick} left") - - async def on_send(self, message): - await message.reply(f"You said {message.content!r}.") - msg1 = await message.room.send(f"{message.sender.atmention} said something.") - await msg1.reply("Yes, they really did.") + async def on_send(self, room, message): + if message.content == "!test": + await message.reply(f"You said {message.content!r}.") + msg1 = await room.send(f"{message.sender.atmention} said something.") + await msg1.reply("Yes, they really did.") async def main(): tc = TestClient() diff --git a/yaboli/client.py b/yaboli/client.py index c405884..3641e8b 100644 --- a/yaboli/client.py +++ b/yaboli/client.py @@ -1,21 +1,139 @@ -from typing import List, Optional +import asyncio +import functools +from typing import Dict, List, Optional +import logging +from .message import LiveMessage from .room import Room +from .session import LiveSession + +logger = logging.getLogger(__name__) __all__ = ["Client"] class Client: + DEFAULT_NICK = "" - # Joining and leaving rooms + def __init__(self) -> None: + self._rooms: Dict[str, List[Room]] = {} + self._stop = asyncio.Event() + + async def run(self) -> None: + await self.started() + await self._stop.wait() + + async def stop(self) -> None: + await self.stopping() + + tasks = [] + for rooms in self._rooms.values(): + for room in rooms: + tasks.append(asyncio.create_task(self.part(room))) + for task in tasks: + await task + + self._stop.set() + + # Managing rooms + + def get(self, room_name: str) -> Optional[Room]: + rooms = self._rooms.get(room_name) + if rooms: # None or [] are False-y + return rooms[0] + else: + return None + + def get_all(self, room_name: str) -> List[Room]: + return self._rooms.get(room_name, []) async def join(self, room_name: str, password: Optional[str] = None, - nick: str = "") -> Room: + nick: Optional[str] = None + ) -> Optional[Room]: + logger.info(f"Joining &{room_name}") + + if nick is None: + nick = self.DEFAULT_NICK + room = Room(room_name, password=password, target_nick=nick) + + room.register_event("snapshot", + functools.partial(self.on_snapshot, room)) + room.register_event("send", + functools.partial(self.on_send, room)) + room.register_event("join", + functools.partial(self.on_join, room)) + room.register_event("part", + functools.partial(self.on_part, room)) + room.register_event("nick", + functools.partial(self.on_nick, room)) + room.register_event("edit", + functools.partial(self.on_edit, room)) + room.register_event("pm", + functools.partial(self.on_pm, room)) + room.register_event("disconnect", + functools.partial(self.on_disconnect, room)) + + if await room.connect(): + rooms = self._rooms.get(room_name, []) + rooms.append(room) + self._rooms[room_name] = rooms + + return room + else: + logger.warn(f"Could not join &{room.name}") + return None + + async def part(self, room: Room) -> None: + logger.info(f"Leaving &{room.name}") + + rooms = self._rooms.get(room.name, []) + rooms = [r for r in rooms if r is not room] + self._rooms[room.name] = rooms + + await room.disconnect() + + # Management stuff - overwrite these functions + + async def started(self) -> None: pass - async def get(self, room_name: str) -> Optional[Room]: + async def stopping(self) -> None: pass - async def get_all(self, room_name: str) -> List[Room]: + # Event stuff - overwrite these functions + + async def on_snapshot(self, room: Room, messages: List[LiveMessage]) -> None: + pass + + async def on_send(self, room: Room, message: LiveMessage) -> None: + pass + + async def on_join(self, room: Room, user: LiveSession) -> None: + pass + + async def on_part(self, room: Room, user: LiveSession) -> None: + pass + + async def on_nick(self, + room: Room, + user: LiveSession, + from_nick: str, + to_nick: str + ) -> None: + pass + + async def on_edit(self, message: LiveMessage) -> None: + pass + + async def on_pm(self, + room: Room, + from_id: str, + from_nick: str, + from_room: str, + pm_id: str + ) -> None: + pass + + async def on_disconnect(self, room: Room, reason: str) -> None: pass diff --git a/yaboli/room.py b/yaboli/room.py index f984b28..48d5af3 100644 --- a/yaboli/room.py +++ b/yaboli/room.py @@ -16,7 +16,6 @@ __all__ = ["Room"] T = TypeVar("T") - class Room: """ Events and parameters: @@ -28,13 +27,13 @@ class Room: message: LiveMessage "join" - somebody has joined the room - user: LiveUser + user: LiveSession "part" - somebody has left the room - user: LiveUser + user: LiveSession "nick" - another room member has changed their nick - user: LiveUser + user: LiveSession from: str to: str