diff --git a/tools/tools.py b/tools/tools.py index 1fc8d6c..84f9425 100644 --- a/tools/tools.py +++ b/tools/tools.py @@ -11,9 +11,9 @@ from redbot.core.utils.menus import menu, DEFAULT_CONTROLS from tabulate import tabulate from contextlib import suppress as sps - BaseCog = getattr(commands, "Cog", object) + class Tools(BaseCog): """Mod and Admin tools.""" @@ -359,6 +359,54 @@ class Tools(BaseCog): ) await awaiter.edit(embed=embed) + @commands.command(name="listguilds", aliases=["listservers", "guildlist", "serverlist"]) + @checks.mod_or_permissions() + async def listguilds(self, ctx): + """ + List the guilds|servers the bot is in + """ + asciidoc = lambda m: "```asciidoc\n{}\n```".format(m) + guilds = sorted(self.bot.guilds, key=lambda g: -g.member_count) + header = ("```\n" "The bot is in the following {} server{}:\n" "```").format( + len(guilds), "s" if len(guilds) > 1 else "" + ) + + max_zpadding = max([len(str(g.member_count)) for g in guilds]) + form = "{gid} :: {mems:0{zpadding}} :: {name}" + all_forms = [ + form.format(gid=g.id, mems=g.member_count, name=g.name, zpadding=max_zpadding) + for g in guilds + ] + final = "\n".join(all_forms) + + await ctx.send(header) + for page in cf.pagify(final, delims=["\n"], shorten_by=16): + await ctx.send(asciidoc(page)) + + @commands.guild_only() + @checks.mod_or_permissions(manage_channels=True) + @commands.command(name="listchannels", aliases=["channellist"]) + async def listchannels(self, ctx): + """ + List the channels of the current server + """ + asciidoc = lambda m: "```asciidoc\n{}\n```".format(m) + channels = ctx.guild.channels + top_channels, category_channels = self.sort_channels(ctx.guild.channels) + + topChannels_formed = "\n".join(self.channels_format(top_channels)) + categories_formed = "\n\n".join([self.category_format(tup) for tup in category_channels]) + + await ctx.send( + f"{ctx.guild.name} has {len(channels)} channel{'s' if len(channels) > 1 else ''}." + ) + + for page in cf.pagify(topChannels_formed, delims=["\n"], shorten_by=16): + await ctx.send(asciidoc(page)) + + for page in cf.pagify(categories_formed, delims=["\n\n"], shorten_by=16): + await ctx.send(asciidoc(page)) + @commands.guild_only() @commands.command() @checks.mod_or_permissions(manage_server=True) @@ -742,3 +790,58 @@ class Tools(BaseCog): roles = guild.roles role = discord.utils.find(lambda r: r.name.lower() == str(rolename).lower(), roles) return role + + def sort_channels(self, channels): + temp = dict() + + channels = sorted(channels, key=lambda c: c.position) + + for c in channels[:]: + if isinstance(c, discord.CategoryChannel): + channels.pop(channels.index(c)) + temp[c] = list() + + for c in channels[:]: + if c.category: + channels.pop(channels.index(c)) + temp[c.category].append(c) + + category_channels = sorted( + [(cat, sorted(chans, key=lambda c: c.position)) for cat, chans in temp.items()], + key=lambda t: t[0].position, + ) + return channels, category_channels + + def channels_format(self, channels: list): + + if channels == []: + return [] + + channel_form = "{name} :: {ctype} :: {cid}" + + def type_name(channel): + return channel.__class__.__name__[:-7] + + name_justify = max([len(c.name[:24]) for c in channels]) + type_justify = max([len(type_name(c)) for c in channels]) + + return [ + channel_form.format( + name=c.name[:24].ljust(name_justify), + ctype=type_name(c).ljust(type_justify), + cid=c.id, + ) + for c in channels + ] + + def category_format(self, cat_chan_tuple: tuple): + + cat = cat_chan_tuple[0] + chs = cat_chan_tuple[1] + + chfs = self.channels_format(chs) + if chfs != []: + ch_forms = ["\t" + f for f in chfs] + return "\n".join([f"{cat.name} :: {cat.id}"] + ch_forms) + else: + return "\n".join([f"{cat.name} :: {cat.id}"] + ["\tNo Channels"])