diff --git a/bot/src/cogs/botinfo.py b/bot/src/cogs/botinfo.py index 491a3f3..8c07df1 100644 --- a/bot/src/cogs/botinfo.py +++ b/bot/src/cogs/botinfo.py @@ -1,4 +1,5 @@ import platform +from collections import Counter from os import environ from os import getpid from os.path import exists @@ -9,6 +10,8 @@ from discord import app_commands from discord.ext import commands from psutil import Process +from cogs.utils import discord_utils + class BotInfo(commands.Cog): """View information about the bot""" @@ -39,30 +42,10 @@ class BotInfo(commands.Cog): memory_usage = round(process.memory_info().rss / 1000000, 1) # Member stats - # - # This is a pretty stupid way of doing things but it's the best I can come up with. - # Using curly brackets for both dicts and sets is retarded becuase - # I have to do this shit in order to create a fucking empty set. - # - # Apparently you can't access user presences, only member presences - # Because of that I have to use sets instead of ints in order to not count duplicate users. - # Fucking hell discord... - total_members = set([]) - online_members = set([]) - idle_members = set([]) - dnd_members = set([]) - offline_members = set([]) - for guild in self.bot.guilds: - for member in guild.members: - total_members.add(member.id) - if str(member.status) == "online": - online_members.add(member.id) - elif str(member.status) == "idle": - idle_members.add(member.id) - elif str(member.status) == "dnd": - dnd_members.add(member.id) - elif str(member.status) == "offline": - offline_members.add(member.id) + # Presences are only available on members, and a user in several servers shows up once per server, + # so key by id to count every user once + statuses = {member.id: member.status for member in self.bot.get_all_members()} + status_counts = Counter(statuses.values()) # Build embed embed = discord.Embed(color=interaction.client.user.color, url=environ["BOT_MISC_WEBSITE"]) @@ -78,11 +61,8 @@ class BotInfo(commands.Cog): if exists("/.dockerenv"): embed.add_field(name="Docker", value="✅") embed.add_field( - name=f"Brukere ({len(total_members)})", - value=f'{self.bot.emoji["online"]}{len(online_members)}\n' - + f'{self.bot.emoji["idle"]}{len(idle_members)}\n' - + f'{self.bot.emoji["dnd"]}{len(dnd_members)}\n' - + f'{self.bot.emoji["offline"]}{len(offline_members)}', + name=f"Brukere ({len(statuses)})", + value=discord_utils.format_status_counts(status_counts, self.bot.emoji, "\n"), ) embed.add_field( name="Lenker", diff --git a/bot/src/cogs/info.py b/bot/src/cogs/info.py index 7af12c9..9179ecb 100644 --- a/bot/src/cogs/info.py +++ b/bot/src/cogs/info.py @@ -1,3 +1,5 @@ +from collections import Counter + import discord from discord import app_commands from discord.ext import commands @@ -108,22 +110,8 @@ class Info(commands.Cog): # Member count and status counts total_members = interaction.guild.member_count - bot_members = 0 - online_members = 0 - idle_members = 0 - dnd_members = 0 - offline_members = 0 - for member in interaction.guild.members: - if member.bot: - bot_members += 1 - if str(member.status) == "online": - online_members += 1 - elif str(member.status) == "idle": - idle_members += 1 - elif str(member.status) == "dnd": - dnd_members += 1 - elif str(member.status) == "offline": - offline_members += 1 + bot_members = sum(member.bot for member in interaction.guild.members) + status_counts = Counter(member.status for member in interaction.guild.members) # Roles roles = self.construct_role_string(interaction.guild.roles) @@ -224,10 +212,7 @@ class Info(commands.Cog): name=f"Medlemmer ({total_members})", value=f"👤 Mennesker: **{int(total_members) - int(bot_members)}**\n" + f"🤖 Båtter: **{bot_members}**\n" - + f'{self.bot.emoji["online"]}{online_members} ' - + f'{self.bot.emoji["idle"]}{idle_members} ' - + f'{self.bot.emoji["dnd"]}{dnd_members} ' - + f'{self.bot.emoji["offline"]}{offline_members}', + + discord_utils.format_status_counts(status_counts, self.bot.emoji, " "), ) embed.add_field(name=f"Roller ({len(interaction.guild.roles) - 1})", value=roles, inline=False) if interaction.guild.premium_tier != 0: diff --git a/bot/src/cogs/utils/discord_utils.py b/bot/src/cogs/utils/discord_utils.py index 38989f8..35156fa 100644 --- a/bot/src/cogs/utils/discord_utils.py +++ b/bot/src/cogs/utils/discord_utils.py @@ -1,10 +1,31 @@ import io +from collections import Counter import discord from discord.ext import commands from cogs.utils import misc_utils +SHOWN_STATUSES = (discord.Status.online, discord.Status.idle, discord.Status.dnd, discord.Status.offline) + + +def format_status_counts(status_counts: Counter[discord.Status], emoji: dict[str, str], separator: str) -> str: + """ + Format how many members have each status, as status emojis followed by the counts + + Parameters + ---------- + status_counts (Counter[discord.Status]): How many members have each status + emoji (dict[str, str]): The bot's emojis, which have an entry for every status + separator (str): What to put between the statuses + + Returns + ---------- + (str): The formatted status counts + """ + + return separator.join(f"{emoji[status.value]}{status_counts[status]}" for status in SHOWN_STATUSES) + async def send_as_txt_file(interaction: discord.Interaction, content: str, filename: str): """