diff --git a/melisa/client.py b/melisa/client.py index f6c7547..c77165e 100644 --- a/melisa/client.py +++ b/melisa/client.py @@ -4,6 +4,8 @@ import logging import asyncio import signal +import sys +import traceback from typing import Dict, List, Union, Any, Iterable, Optional @@ -59,15 +61,15 @@ class Client: """ def __init__( - self, - token: str, - *, - asyncio_debug: bool = False, - intents: Union[Intents, Iterable[Intents]] = None, - activity: Optional[Activity] = None, - status: str = None, - mobile: bool = False, - logs: Union[None, int, str, Dict[str, Any]] = "INFO", + self, + token: str, + *, + asyncio_debug: bool = False, + intents: Union[Intents, Iterable[Intents]] = None, + activity: Optional[Activity] = None, + status: str = None, + mobile: bool = False, + logs: Union[None, int, str, Dict[str, Any]] = "INFO", ): self.shards: Dict[int, Shard] = {} self.http: HTTPClient = HTTPClient(token) @@ -85,7 +87,7 @@ class Client: self.intents = sum(intents) elif intents is None: self.intents = ( - Intents.all() - Intents.GUILD_PRESENCES - Intents.GUILD_MEMBERS + Intents.all() - Intents.GUILD_PRESENCES - Intents.GUILD_MEMBERS ) else: self.intents = intents @@ -135,6 +137,33 @@ class Client: _logger.debug(f"Listener {callback.__qualname__} added successfully!") return self + async def dispatch( + self, + name: str, + *args + ): + """ + Dispatches an event + + Parameters + ---------- + name: :class:`str` + Name of the event to dispatch. + """ + coro = self._events.get(name) + + if coro is not None: + try: + await coro(*args) + except Exception as exc: + custom_error = self._events.get("on_error") + + if custom_error is not None: + asyncio.ensure_future(custom_error(exc)) + else: + print(f"Ignoring exception in {name}", file=sys.stderr) + traceback.print_exc() + def run(self) -> None: """ Run Bot without shards (only 0 shard) @@ -227,7 +256,7 @@ class Client: return Guild.from_dict(data) async def fetch_channel( - self, channel_id: Union[Snowflake, str, int] + self, channel_id: Union[Snowflake, str, int] ) -> Union[Channel, Any]: """ Fetch Channel from the Discord API (by id). diff --git a/melisa/listeners/channel_create.py b/melisa/listeners/channel_create.py index bffe13f..14e6739 100644 --- a/melisa/listeners/channel_create.py +++ b/melisa/listeners/channel_create.py @@ -3,8 +3,6 @@ from __future__ import annotations -import asyncio - from ..utils.types import Coro from ..models.guild import Channel, ChannelType, channel_types_for_converting @@ -18,10 +16,7 @@ async def channel_create_listener(self, gateway, payload: dict): channel = channel_cls.from_dict(payload) - custom_listener = self._events.get("on_channel_create") - - if custom_listener is not None: - asyncio.ensure_future(custom_listener(channel)) + await self.dispatch("on_channel_create", channel) return diff --git a/melisa/listeners/channel_delete.py b/melisa/listeners/channel_delete.py index 7ddab35..7627604 100644 --- a/melisa/listeners/channel_delete.py +++ b/melisa/listeners/channel_delete.py @@ -3,8 +3,6 @@ from __future__ import annotations -import asyncio - from ..utils.types import Coro from ..models.guild import Channel, ChannelType, channel_types_for_converting @@ -18,10 +16,7 @@ async def channel_delete_listener(self, gateway, payload: dict): channel = channel_cls.from_dict(payload) - custom_listener = self._events.get("on_channel_delete") - - if custom_listener is not None: - asyncio.ensure_future(custom_listener(channel)) + await self.dispatch("on_channel_delete", channel) return diff --git a/melisa/listeners/channel_update.py b/melisa/listeners/channel_update.py index 9c2e930..6994264 100644 --- a/melisa/listeners/channel_update.py +++ b/melisa/listeners/channel_update.py @@ -3,8 +3,6 @@ from __future__ import annotations -import asyncio - from ..utils.types import Coro from ..models.guild import Channel, ChannelType, channel_types_for_converting @@ -19,10 +17,7 @@ async def channel_update_listener(self, gateway, payload: dict): channel = channel_cls.from_dict(payload) - custom_listener = self._events.get("on_channel_update") - - if custom_listener is not None: - asyncio.ensure_future(custom_listener(None, channel)) + await self.dispatch("on_channel_update", None, channel) return diff --git a/melisa/listeners/guild_create.py b/melisa/listeners/guild_create.py index 3363a38..9755486 100644 --- a/melisa/listeners/guild_create.py +++ b/melisa/listeners/guild_create.py @@ -3,8 +3,6 @@ from __future__ import annotations -import asyncio - from ..utils.types import Coro from ..models.guild import Guild @@ -21,10 +19,8 @@ async def guild_create_listener(self, gateway, payload: dict): self.guilds[str(guild.id)] = guild - custom_listener = self._events.get("on_guild_create") - - if custom_listener is not None and guild_was_cached_as_none is False: - asyncio.ensure_future(custom_listener(guild)) + if guild_was_cached_as_none is False: + await self.dispatch("on_guild_create", guild) return diff --git a/melisa/listeners/guild_remove.py b/melisa/listeners/guild_remove.py index 5570cd2..7d50b2a 100644 --- a/melisa/listeners/guild_remove.py +++ b/melisa/listeners/guild_remove.py @@ -3,8 +3,6 @@ from __future__ import annotations -import asyncio - from ..utils.types import Coro from ..models.guild import UnavailableGuild @@ -16,10 +14,7 @@ async def guild_delete_listener(self, gateway, payload: dict): self.guilds.pop(guild.id, None) - custom_listener = self._events.get("on_guild_remove") - - if custom_listener is not None: - asyncio.ensure_future(custom_listener(guild)) + await self.dispatch("on_guild_remove", guild) return diff --git a/melisa/listeners/guild_update.py b/melisa/listeners/guild_update.py index d1f89aa..c07e6ae 100644 --- a/melisa/listeners/guild_update.py +++ b/melisa/listeners/guild_update.py @@ -3,8 +3,6 @@ from __future__ import annotations -import asyncio - from ..utils.types import Coro from ..models.guild import Guild @@ -17,10 +15,7 @@ async def guild_update_listener(self, gateway, payload: dict): self.guilds[new_guild.id] = new_guild - custom_listener = self._events.get("on_guild_update") - - if custom_listener is not None: - asyncio.ensure_future(custom_listener(old_guild, new_guild)) + await self.dispatch("on_channel_create", old_guild, new_guild) return diff --git a/melisa/listeners/ready.py b/melisa/listeners/ready.py index 7398e3b..b5b40b2 100644 --- a/melisa/listeners/ready.py +++ b/melisa/listeners/ready.py @@ -3,8 +3,6 @@ from __future__ import annotations -import asyncio - from ..utils.types import Coro from ..models.user import User @@ -20,10 +18,7 @@ async def on_ready_listener(self, gateway, payload: dict): self.user = User.from_dict(payload.get("user")) - custom_listener = self._events.get("on_shard_ready") - - if custom_listener is not None: - asyncio.ensure_future(custom_listener(gateway.shard_id)) + await self.dispatch("on_shard_ready", gateway.shard_id) return