From 20de0e8460b92f8f8d32f942dc48ea89d3153ee6 Mon Sep 17 00:00:00 2001 From: strNophix Date: Sat, 12 Nov 2022 20:37:54 +0100 Subject: [PATCH] Converted information cog --- cogs/information/__init__.py | 125 ++------------------ cogs/information/commands.py | 0 cogs/information/interactions.py | 78 ++++++++++++ cogs/music/__init__.py | 62 +--------- cogs/music/{commands.py => interactions.py} | 0 cogs/{settings.py => settings/__init__.py} | 0 6 files changed, 89 insertions(+), 176 deletions(-) delete mode 100644 cogs/information/commands.py create mode 100644 cogs/information/interactions.py rename cogs/music/{commands.py => interactions.py} (100%) rename cogs/{settings.py => settings/__init__.py} (100%) diff --git a/cogs/information/__init__.py b/cogs/information/__init__.py index 6010e85..73a67d3 100644 --- a/cogs/information/__init__.py +++ b/cogs/information/__init__.py @@ -1,125 +1,16 @@ -import datetime -import time -from typing import Optional - -import discord -import humanize -import lavalink -from discord.ext import commands -from discord.ext.commands import Context - -from bot import TuneBot -from context import CustomContext +import typing +from cogs.information.interactions import InfoCommands from utils.classes import BaseCog -from utils.EmbedGenerator import EmbedGenerator -from utils.paginator import HelpPaginator + +if typing.TYPE_CHECKING: + from bot import TuneBot class InformationCog(BaseCog, name="Information"): - @commands.command(name="ping", aliases=["pong"]) - @commands.cooldown(rate=1, per=5, type=commands.BucketType.user) - async def ping(self, ctx: Context): - """Test the latency""" - avatar = ctx.author.avatar.with_static_format("jpeg") - emoji = discord.utils.get(ctx.bot.emojis, name="loading") - start = time.monotonic() - msg = await ctx.send( - embed=discord.Embed(description=f"{emoji} Calculating ping") - ) - millis = (time.monotonic() - start) * 1000 - heartbeat = ctx.bot.latency * 1000 - embed = discord.Embed(color=discord.Color.blue()) - embed.add_field( - name=":heartbeat: Heartbeat", value=f"`{heartbeat:,.2f}ms`", inline=True - ) - embed.add_field( - name=":file_cabinet: ACK", value=f"`{millis:,.2f}ms`", inline=True - ) - embed.set_footer(text=f"Requested by: {ctx.author}", icon_url=f"{avatar}") - await msg.edit(embed=embed) - - @commands.command(name="invite") - @commands.cooldown(rate=1, per=5, type=commands.BucketType.user) - async def invite(self, ctx: Context): - """Gets the invite link""" - await EmbedGenerator.Message( - ctx, "Add our bot to your server:", self.bot.invite_link - ) - - @commands.command(name="wlinfo") - @commands.cooldown(rate=1, per=5, type=commands.BucketType.user) - async def wlinfo(self, ctx: CustomContext): - """Retrieve various node/server/player information""" - player = self.bot.lavalink.player_manager.get(ctx.guild.id) - nodes = self.bot.lavalink.node_manager.available_nodes - - used = humanize.naturalsize(sum([n.stats.memory_used for n in nodes])) - total = humanize.naturalsize(sum([n.stats.memory_allocated for n in nodes])) - free = humanize.naturalsize(sum([n.stats.memory_free for n in nodes])) - cpu = sum([n.stats.cpu_cores for n in nodes]) - - fmt = ( - f"**Lavalink:** `{lavalink.__version__}`\n\n" - f"Connected to `{len(self.bot.lavalink.node_manager.available_nodes)}` nodes.\n" - # f"Best available Node `{self.bot.lavalink.node_manager.find_ideal_node().name.__repr__()}`\n" - f"`{len(self.bot.lavalink.player_manager.players)}` players are distributed on nodes.\n" - f"`{sum([n.stats.players for n in nodes])}` players are distributed on server.\n" - f"`{sum([n.stats.playing_players for n in nodes])}` players are playing on server.\n\n" - f"Server Memory: `{used}/{total}` | `({free} free)`\n" - f"Server CPU: `{cpu}`\n\n" - # f"Server Uptime: `{datetime.timedelta(milliseconds=node.stats.uptime)}`" - ) - await ctx.send(fmt) - - @commands.command(name="help", aliases=["about", "info"]) - @commands.cooldown(1, 1, commands.BucketType.user) - async def about( - self, - ctx: Context, - command: Optional[str] = commands.Option( - description="Show help for a command or category" - ), - ): - """Retrieve a list of possible commands""" - if command: - entity = self.bot.get_cog(command) or self.bot.get_command(command) - - if entity is None: - clean = command.replace("@", "@\u200b") - return await ctx.send(f'Command or category "{clean}" not found.') - elif isinstance(entity, discord.ext.commands.Command): - p = await HelpPaginator.from_command(ctx, entity) - else: - p = await HelpPaginator.from_cog(ctx, entity) - return await p.paginate() - - info = self.bot.config["info"] - title = info["name"] + " Help" - descr = info["description"] - color = self.bot.colors["embed"] - - embed = discord.Embed(color=color, title=title, description=descr) - - display_cogs = { - "Information": ":information_source:", - "Music": ":musical_note:", - "Settings": ":gear:", - } - - for cog_name, cog_icon in display_cogs.items(): - cog = self.bot.cogs.get(cog_name) - if not cog: - continue - cogname_str = f"{cog_icon} {cog_name}" - commands = [f"`{cmd.name}`" for cmd in cog.get_commands() if not cmd.hidden] - commands_str = ", ".join(commands) - embed.add_field(name=cogname_str, value=commands_str, inline=False) - - avatar = ctx.author.avatar.with_static_format("jpeg") - embed.set_footer(text=f"Requested by: {ctx.author}", icon_url=avatar) - await ctx.send(embed=embed) + pass -async def setup(bot: TuneBot): +async def setup(bot: "TuneBot"): bot.remove_command("help") await bot.add_cog(InformationCog(bot)) + bot.tree.add_command(InfoCommands(bot), override=True) diff --git a/cogs/information/commands.py b/cogs/information/commands.py deleted file mode 100644 index e69de29..0000000 diff --git a/cogs/information/interactions.py b/cogs/information/interactions.py new file mode 100644 index 0000000..d910ee0 --- /dev/null +++ b/cogs/information/interactions.py @@ -0,0 +1,78 @@ +import typing + +from discord import app_commands +from discord import Interaction +import humanize +import lavalink + +import cogs.music.helper as music_helper +from utils.embed import create_embed + +if typing.TYPE_CHECKING: + from bot import TuneBot + + +class InfoCommands(app_commands.Group): + def __init__(self, bot: "TuneBot"): + super().__init__(name="bot", description="Some extra info") + self.bot: "TuneBot" = bot + + @app_commands.command(name="invite", description="I'd happily join your server") + async def invite(self, ctx: Interaction): + embed = create_embed(ctx.user) + embed.title = "My invite link" + embed.description = f"[{self.bot.invite_link}]({self.bot.invite_link})" + await ctx.response.send_message(embed=embed) + + @app_commands.command( + name="help", description="In case you cannot find what you want" + ) + async def about(self, ctx: Interaction): + embed = create_embed(ctx.user) + + info = self.bot.config["info"] + embed.title = info["name"] + " help" + embed.description = info["description"] + + display_cogs = { + "Information": ":information_source:", + "Music": ":musical_note:", + "Settings": ":gear:", + } + + for cog_name, cog_icon in display_cogs.items(): + cog = self.bot.cogs.get(cog_name) + if not cog: + continue + cogname_str = f"{cog_icon} {cog_name}" + commands = [f"`{cmd.name}`" for cmd in cog.get_commands() if not cmd.hidden] + commands_str = ", ".join(commands) + embed.add_field(name=cogname_str, value=commands_str, inline=False) + + await ctx.response.send_message(embed=embed) + + @app_commands.command( + name="stats", description="Some node/server/player information" + ) + async def wlinfo(self, ctx: Interaction): + embed = create_embed(ctx.user) + nodes = self.bot.lavalink.node_manager.available_nodes + + used = humanize.naturalsize(sum([n.stats.memory_used for n in nodes])) + total = humanize.naturalsize(sum([n.stats.memory_allocated for n in nodes])) + free = humanize.naturalsize(sum([n.stats.memory_free for n in nodes])) + cpu = sum([n.stats.cpu_cores for n in nodes]) + + info = self.bot.config["info"] + embed.title = info["name"] + " stats" + + embed.description = ( + f"**Lavalink:** `{lavalink.__version__}`\n\n" + f"Connected to `{len(self.bot.lavalink.node_manager.available_nodes)}` nodes.\n" + f"`{len(self.bot.lavalink.player_manager.players)}` players are distributed on nodes.\n" + f"`{sum([n.stats.players for n in nodes])}` players are distributed on server.\n" + f"`{sum([n.stats.playing_players for n in nodes])}` players are playing on server.\n\n" + f"Server Memory: `{used}/{total}` | `({free} free)`\n" + f"Server CPU: `{cpu}`\n\n" + ) + await ctx.response.send_message(embed=embed) diff --git a/cogs/music/__init__.py b/cogs/music/__init__.py index 65a62f5..dee5967 100644 --- a/cogs/music/__init__.py +++ b/cogs/music/__init__.py @@ -1,27 +1,22 @@ import asyncio import typing -from typing import Optional import lavalink from discord.channel import TextChannel from discord.ext import commands -from discord.ext.commands.errors import CommandError -from lavalink.models import DefaultPlayer from bot import TuneBot from cogs.music import helper -from cogs.music.commands import MusicCommands +from cogs.music.interactions import MusicCommands, QUEUE_SIZE from cogs.music.voice_client import LavalinkVoiceClient -from context import CustomContext from utils.classes import BaseCog -from utils.exceptions import EmbeddedCommandException if typing.TYPE_CHECKING: from bot import TuneBot -class MusicCog(BaseCog): +class MusicCog(BaseCog, name="Music"): def __init__(self, bot: TuneBot): super().__init__(bot) if not hasattr(bot, "lavalink"): @@ -41,60 +36,9 @@ class MusicCog(BaseCog): voice_channel = await self.bot.fetch_channel(voicechannel_id) await voice_channel.connect(cls=LavalinkVoiceClient) if not player.is_playing: - await self.fill_player_queue( - player, self.bot.config["queue_buffer_size"] - ) + await helper.fill_player_queue(self.bot, player, QUEUE_SIZE) await player.play() - async def fill_player_queue(self, player: DefaultPlayer, amount: Optional[int] = 1): - await helper.fill_player_queue(self.bot, player, amount) - - def cog_unload(self): - """Cog unload handler. This removes any event hooks that were registered.""" - self.bot.lavalink._event_hooks.clear() - - async def cog_before_invoke(self, ctx: CustomContext): - """Command before-invoke handler.""" - guild_check = ctx.guild is not None - # This is essentially the same as `@commands.guild_only()` - # except it saves us repeating ourselves (and also a few lines). - - if guild_check: - await self.ensure_voice(ctx) - # Ensure that the bot and command author share a mutual voicechannel. - - return guild_check - - async def cog_command_error(self, ctx: CustomContext, error: CommandError): - if isinstance(error, commands.CommandInvokeError): - await ctx.send(error.original) - elif isinstance(error, EmbeddedCommandException): - await error.send(ctx) - - async def ensure_voice(self, ctx: CustomContext): - """This check ensures that the bot and command author are in the same voicechannel.""" - player = self.bot.lavalink.player_manager.create(ctx.guild.id) - # Create returns a player if one exists, otherwise creates. - # This line is important because it ensures that a player always exists for a guild. - - # Most people might consider this a waste of resources for guilds that aren't playing, but this is - # the easiest and simplest way of ensuring players are created. - - # These are commands that require the bot to join a voicechannel (i.e. initiating playback). - # Commands such as volume/skip etc don't require the bot to be in a voicechannel so don't need listing here. - should_connect = ctx.command.name in ("connect",) - if should_connect: - try: - await helper.ensure_voice( - permissions=ctx.me.guild_permissions, - player=player, - author=ctx.author, - voice_client=ctx.guild.voice_client, - channel_id=ctx.channel.id, - ) - except Exception as exc: - raise commands.CommandInvokeError(exc) - async def track_hook(self, event: lavalink.Event): if isinstance(event, lavalink.events.QueueEndEvent): # When this track_hook receives a "QueueEndEvent" from lavalink.py diff --git a/cogs/music/commands.py b/cogs/music/interactions.py similarity index 100% rename from cogs/music/commands.py rename to cogs/music/interactions.py diff --git a/cogs/settings.py b/cogs/settings/__init__.py similarity index 100% rename from cogs/settings.py rename to cogs/settings/__init__.py