From a56a010869b357fbf1539f5394ef07fe1d3caaf4 Mon Sep 17 00:00:00 2001
From: Ianardo DiCaprio <43935737+Ianardo-DiCaprio@users.noreply.github.com>
Date: Sat, 10 Aug 2019 14:28:04 +0100
Subject: [PATCH] Add optional bot count and online count

---
 infochannel/infochannel.py | 123 ++++++++++++++++++++++++++++++++-----
 1 file changed, 109 insertions(+), 14 deletions(-)

diff --git a/infochannel/infochannel.py b/infochannel/infochannel.py
index 55e26ca..23e04de 100644
--- a/infochannel/infochannel.py
+++ b/infochannel/infochannel.py
@@ -1,17 +1,17 @@
 from typing import Any
-
 import discord
+
 from redbot.core import Config, commands, checks
 from redbot.core.bot import Red
 
 Cog: Any = getattr(commands, "Cog", object)
-
 listener = getattr(commands.Cog, "listener", None)  # Trusty + Sinbad
 if listener is None:
 
     def listener(name=None):
         return lambda x: x
 
+
 class InfoChannel(Cog):
     """
     Create a channel with updating server info
@@ -27,7 +27,11 @@ class InfoChannel(Cog):
 
         default_guild = {
             "channel_id": None,
+            "botchannel_id": None,
+            "onlinechannel_id": None,
             "member_count": True,
+            "bot_count": False,
+            "online_count": False,
         }
 
         self.config.register_guild(**default_guild)
@@ -58,7 +62,7 @@ class InfoChannel(Cog):
         elif channel_id is None:
             await ctx.send("Enable info channel on this server?")
         else:
-            await ctx.send("Info channel is {}. Delete it?".format(channel.mention))
+            await ctx.send("Do you wish to delete current info channels?")
 
         msg = await self.bot.wait_for("message", check=check)
 
@@ -74,43 +78,127 @@ class InfoChannel(Cog):
         if not await ctx.tick():
             await ctx.send("Done!")
 
+    @commands.group()
+    @checks.admin()
+    async def infochannelset(self, ctx: commands.Context):
+        """
+        Toggle different types of infochannels
+        """
+
+    @infochannelset.command(name="botcount")
+    async def _infochannelset_botcount(self, ctx: commands.Context, enabled: bool = None):
+        """
+        Toggle an infochannel that shows the amount of bots in the server
+        """
+        guild = ctx.guild
+        if enabled is None:
+            enabled = not await self.config.guild(guild).bot_count()
+        await self.config.guild(guild).bot_count.set(enabled)
+        if enabled:
+            await ctx.send("InfoChannel for bot count has been enabled.")
+        else:
+            await ctx.send("InfoChannel for bot count has been disabled.")
+
+    @infochannelset.command(name="onlinecount")
+    async def _infochannelset_onlinecount(self, ctx: commands.Context, enabled: bool = None):
+        """
+        Toggle an infochannel that shows the amount of online users in the server
+        """
+        guild = ctx.guild
+        if enabled is None:
+            enabled = not await self.config.guild(guild).online_count()
+        await self.config.guild(guild).online_count.set(enabled)
+        if enabled:
+            await ctx.send("InfoChannel for online user count has been enabled.")
+        else:
+            await ctx.send("InfoChannel for online user count has been disabled.")
+
     async def make_infochannel(self, guild: discord.Guild):
-        overwrites = {guild.default_role: discord.PermissionOverwrite(connect=False),
-                      guild.me: discord.PermissionOverwrite(manage_channels=True, connect=True)}
+        botcount = await self.config.guild(guild).bot_count()
+        onlinecount = await self.config.guild(guild).online_count()
+        overwrites = {
+            guild.default_role: discord.PermissionOverwrite(connect=False),
+            guild.me: discord.PermissionOverwrite(manage_channels=True, connect=True),
+        }
 
         channel = await guild.create_voice_channel(
             "Placeholder", reason="InfoChannel make", overwrites=overwrites
         )
-
         await self.config.guild(guild).channel_id.set(channel.id)
 
+        if botcount:
+            botchannel = await guild.create_voice_channel(
+                "Placeholder", reason="InfoChannel botcount", overwrites=overwrites
+            )
+            await self.config.guild(guild).botchannel_id.set(botchannel.id)
+        if onlinecount:
+            onlinechannel = await guild.create_voice_channel(
+                "Placeholder", reason="InfoChannel onlinecount", overwrites=overwrites
+            )
+            await self.config.guild(guild).onlinechannel_id.set(onlinechannel.id)
+
         await self.update_infochannel(guild)
 
     async def delete_infochannel(self, guild: discord.Guild, channel: discord.VoiceChannel):
+        guild_data = await self.config.guild(guild).all()
+        botchannel_id = guild_data["botchannel_id"]
+        onlinechannel_id = guild_data["onlinechannel_id"]
+        botchannel: discord.VoiceChannel = guild.get_channel(botchannel_id)
+        onlinechannel: discord.VoiceChannel = guild.get_channel(onlinechannel_id)
+        channel_id = guild_data["channel_id"]
+        channel: discord.VoiceChannel = guild.get_channel(channel_id)
         await channel.delete(reason="InfoChannel delete")
+        if botchannel_id is not None:
+            await botchannel.delete(reason="InfoChannel delete")
+        if onlinechannel_id is not None:
+            await onlinechannel.delete(reason="InfoChannel delete")
         await self.config.guild(guild).clear()
 
     async def update_infochannel(self, guild: discord.Guild):
         guild_data = await self.config.guild(guild).all()
+        botcount = guild_data["bot_count"]
+        onlinecount = guild_data["online_count"]
+
+        # Gets count of bots
+        bots = lambda x: x.bot
+        num = len([m for m in guild.members if bots(m)])
+        bot_msg = f"Bots: {num}"
+
+        # Gets count of online users
+        members = guild.member_count
+        offline = len(list(filter(lambda m: m.status is discord.Status.offline, guild.members)))
+        num = members - offline
+        online_msg = f"Online: {num}"
+
+        # Gets count of actual users
+        total = lambda x: not x.bot
+        num = len([m for m in guild.members if total(m)])
+        human_msg = f"Total Humans: {num}"
 
         channel_id = guild_data["channel_id"]
         if channel_id is None:
             return
 
+        botchannel_id = guild_data["botchannel_id"]
+        onlinechannel_id = guild_data["onlinechannel_id"]
+        channel_id = guild_data["channel_id"]
         channel: discord.VoiceChannel = guild.get_channel(channel_id)
+        botchannel: discord.VoiceChannel = guild.get_channel(botchannel_id)
+        onlinechannel: discord.VoiceChannel = guild.get_channel(onlinechannel_id)
 
-        if channel is None:
-            return
-
-        name = ""
         if guild_data["member_count"]:
-            name += "Members: {} ".format(guild.member_count)
-
-        if name == "":
-            name = "Stats not enabled"
+            name = "{} ".format(human_msg)
 
         await channel.edit(reason="InfoChannel update", name=name)
 
+        if botcount:
+            name = "{} ".format(bot_msg)
+            await botchannel.edit(reason="InfoChannel update", name=name)
+
+        if onlinecount:
+            name = "{} ".format(online_msg)
+            await onlinechannel.edit(reason="InfoChannel update", name=name)
+
     @listener()
     async def on_member_join(self, member: discord.Member):
         await self.update_infochannel(member.guild)
@@ -118,3 +206,10 @@ class InfoChannel(Cog):
     @listener()
     async def on_member_remove(self, member: discord.Member):
         await self.update_infochannel(member.guild)
+
+    @listener()
+    async def on_member_update(self, before: discord.Member, after: discord.Member):
+        onlinecount = await self.config.guild(after.guild).online_count()
+        if onlinecount:
+            if before.status != after.status:
+                await self.update_infochannel(after.guild)