diff --git a/royalpack/commands/cv.py b/royalpack/commands/cv.py index 270a1bcf..b602b329 100644 --- a/royalpack/commands/cv.py +++ b/royalpack/commands/cv.py @@ -1,3 +1,4 @@ +from typing import * from royalnet.commands import * @@ -112,6 +113,136 @@ class CvCommand(Command): def __init__(self, interface: CommandInterface): super().__init__(interface) + def _render_member(self, + member, + display_nick: bool, + display_discrim: bool): + member: Dict[str, Any] + status: str = "" + if member["bot"]: + status = "🤖" + elif member["status"]["main"] == "online": + status = "đŸ”ĩ" + elif member["status"]["main"] == "idle": + status = "âšĢī¸" + elif member["status"]["main"] == "dnd": + status = "🔴" + elif member["status"]["main"] == "offline": + status = "âšĒī¸" + + mvoice: Dict[str, Any] = member["voice"] + voice: str = "" + if mvoice is not None: + if mvoice["server_mute"] or mvoice["server_deaf"]: + voice = "đŸŽĩ" + elif mvoice["video"]: + voice = "đŸ–Ĩ" + elif mvoice["afk"]: + voice = "💤" + elif mvoice["self_deaf"]: + voice = "🔇" + elif mvoice["self_mute"]: + voice = "🔈" + else: + voice = "🔊" + + if display_nick and member["nick"] is not None: + name = f"[i]{member['nick']}[/i]" + elif display_discrim: + name = f"{member['name']}#{member['discriminator']}" + else: + name = member['name'] + + activity = "" + if len(member["activities"]) >= 1: + # TODO: how to render activities now? + ... + + return f"{status}{voice} {name}{activity}\n" + async def run(self, args: CommandArgs, data: CommandData) -> None: - response = await self.interface.call_herald_event("discord", "discord_cv") - breakpoint() + response: Dict[str, Any] = await self.interface.call_herald_event("discord", "discord_cv") + + flags = args.optional(0, default="") + display_nicks = "n" in flags + display_discrim = "d" in flags + display_only_role = "a" not in flags + display_only_online = "o" not in flags + + # Find all categories + categories = [] + for member in response["guild"]["members"]: + if member["voice"] is None: + continue + category = member["voice"]["channel"]["category"] + if category not in categories: + categories.append(category) + categories.sort(key=lambda c: c["position"]) + + # Find all channels, grouped by category id + channels = {} + for member in response["guild"]["members"]: + if member["voice"] is None: + continue + category: Optional[int] = member["voice"]["channel"]["category"]["id"] + if category not in channels: + channels[category] = [] + channel = member["voice"]["channel"] + if member["voice"]["channel"] not in channels[category]: + channels[category].append(channel) + for l in channels.values(): + l.sort(key=lambda c: c["position"]) + + # Find all members, grouped by channel id + members = {} + not_connected_members = [] + for member in response["guild"]["members"]: + if member["voice"] is None: + not_connected_members.append(member) + continue + channel = member["voice"]["channel"]["id"] + if channel not in members: + members[channel] = [] + members[channel].append(member) + for l in members.values(): + l.sort(key=lambda m: m["name"]) + + # Construct the chat message + message = f"ℹī¸ Membri di [i]{response['guild']['name']}[/i]:\n\n" + + for category in categories: + category: Dict[str, Any] + if category['id'] is None: + message += f"[b][Nessuna categoria][/b]\n" + else: + message += f"[b][{category['name']}][/b]\n" + + for channel in channels[category["id"]]: + channel: Dict[str, Any] + message += f"[b]#{channel['name']}[/b]\n" + + for member in members[channel["id"]]: + message += self._render_member(member, display_nicks, display_discrim) + + message += "\n" + + if len(not_connected_members) >= 0: + message += "[b][Non in chat vocale][/b]\n" + for member in not_connected_members: + + draw = True + + for role in member["roles"]: + if role["id"] == self.interface.cfg["Cv"]["displayed_role_id"]: + break + else: + if display_only_role: + draw = False + + if display_only_online and member["status"]["main"] == "offline": + draw = False + + if draw: + message += self._render_member(member, display_nicks, display_discrim) + + await data.reply(message) diff --git a/royalpack/events/discord_cv.py b/royalpack/events/discord_cv.py index 59b87609..6ccfa829 100644 --- a/royalpack/events/discord_cv.py +++ b/royalpack/events/discord_cv.py @@ -7,7 +7,7 @@ from royalnet.commands import * class DiscordCvEvent(Event): name = "discord_cv" - async def run(self, guild_id: Optional[int] = None, **kwargs): + async def run(self, guild_id: Optional[int] = None, **kwargs) -> dict: if not self.interface.name == "discord": raise UnsupportedError() @@ -47,6 +47,11 @@ class DiscordCvEvent(Event): "category": { "id": member.voice.channel.category_id, "name": member.voice.channel.category.name, + "position": member.voice.channel.category.position, + } if member.voice.channel.category is not None else { + "id": None, + "name": None, + "position": -1, }, "bitrate": member.voice.channel.bitrate, "user_limit": member.voice.channel.user_limit, @@ -60,12 +65,12 @@ class DiscordCvEvent(Event): "afk": member.voice.afk, } if member.voice is not None else None, "status": { - "main": member.status, - "desktop": member.desktop_status, - "mobile": member.mobile_status, - "web": member.web_status, + "main": member.status.value, + "desktop": member.desktop_status.value, + "mobile": member.mobile_status.value, + "web": member.web_status.value, }, - "activities": [activity.to_dict() for activity in member.activities if activity is not None], + "activities": [], "roles": [{ "id": role.id, "name": role.name, @@ -76,6 +81,15 @@ class DiscordCvEvent(Event): } for role in member.roles] } + for activity in member.activities: + ... + results.append(data) - return results + return { + "guild": { + "id": guild.id, + "name": guild.name, + "members": results, + } + }