Skip to content

Commit

Permalink
Group music commands together (#173)
Browse files Browse the repository at this point in the history
* Group music commands together

* Add invoke_without_command to command groups so they show up in the help command

* Rename music_channel group to music_channel_group for better verbosity

* Remove invoke_without_command

* Note command changes in README
  • Loading branch information
Laura Demkowicz-Duffy authored Aug 24, 2021
1 parent cbf5baf commit 8b4b5b8
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 116 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,29 +404,29 @@ For this cog to work, the `GOOGLE_API` env var must also be set, and instruction
6. Click on `Create Credentials` and then `API key`.
7. Copy the key given. For security, it is recommended that you "restrict key" and only enable `YouTube Data API v3`.

#### !setmusicchannel \<channel mention> [optional: [args]]
#### !music channel set \<channel mention> [optional: [args]]
* This sets the channel mentioned to be used as the music channel. All messages into this channel will be considered music requests, and any music commands must be sent in this channel.
* Optional args:
* Using `-c` will clear the entire channel before setting it up as the music channel.
* *Requires `administrator` permission in Discord*

#### !getmusicchannel
#### !music channel get
* Sends the currently set music channel for the server.
* *Requires `administrator` permission in Discord*

#### !resetmusicchannel
#### !music channel reset
* This clears the current music channel and resets the preview and queue messages.
* *Requires `administrator` permission in Discord*

#### !removemusicchannel
#### !music channel remove
* Unlinks the currently linked music channel from being the music channel. This will not delete the channel or its contents.
* *Requires `administrator` permission in Discord*

#### !fixmusic
#### !music fix
* If the bot has broken and thinks it is still in a Voice Channel, use this command to force it to reset.
* *Requires `administrator` permission in Discord*

#### !musicqueue
#### !music queue
* Aliases: `songqueue, songs, songlist, songslist`
* Gets the current list of songs in the queue.

Expand Down
227 changes: 117 additions & 110 deletions src/esportsbot/cogs/MusicCog.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,12 @@

import googleapiclient.discovery
import youtube_dl
from discord import ClientException, Colour, Embed, FFmpegPCMAudio, PCMVolumeTransformer, TextChannel
from discord import (ClientException, Colour, Embed, FFmpegPCMAudio, PCMVolumeTransformer, TextChannel)
from discord.ext import commands, tasks
from youtubesearchpython import VideosSearch

from esportsbot.db_gateway import DBGatewayActions
from esportsbot.lib.discordUtil import send_timed_message
from esportsbot.models import Music_channels
from youtubesearchpython import VideosSearch


# A discord command check that the command is in the music channel:
Expand Down Expand Up @@ -827,116 +826,10 @@ async def join_member(member):
except AttributeError:
return False

@commands.command(
name="setmusicchannel",
usage="<channel mention> [optional args]",
help="Sets the music channel to the channel mentioned. To see possible optional args, "
"go to https://github.com/FragSoc/esports-bot#setmusicchannel-channel-mention-optional-args"
)
@commands.has_permissions(administrator=True)
async def set_music_channel_command(self, context: commands.Context, text_channel: TextChannel):
"""
Sets the music channel for a given guild to the channel channel mentioned in the command. Extra args can be given to
indicate some extra process to perform while setting up the channel.
:param context: The context of the command.
:param text_channel: The text channel to set the music channel to.
"""
# Using the text channel as the last official arg in the command, find any extras that occur after with a `-`
text_channel_str = str(text_channel.mention)
end_index = context.message.content.index(text_channel_str) + len(text_channel_str)
args = context.message.content[end_index:].strip().split("-")
args.pop(0)
args = [arg.lower() for arg in args]
if "c" in args:
# Use -c to clear the channel.
await self.clear_music_channel(text_channel)

await self.setup_music_channel(text_channel)
await context.send(self.user_strings["music_channel_set"].format(channel=text_channel.mention))

@commands.command(name="getmusicchannel", help="Gets the current channel that is set as the music channel.")
@commands.has_permissions(administrator=True)
async def get_music_channel_command(self, context: commands.Context):
"""
Gets the current channel that is set as the music channel.
If there is no channel set it will return a message saying so.
:param context: The context of the command.
"""
channel = await self.find_music_channel_instance(context.guild)
if channel:
await context.send(self.user_strings["music_channel_get"].format(channel=channel.mention))
else:
await context.send(self.user_strings["music_channel_missing"])

@commands.command(name="resetmusicchannel", help="Clears the music channel and sends the preview and queue messages.")
@commands.has_permissions(administrator=True)
async def reset_music_channel_command(self, context: commands.Context):
"""
Resets the music channel to clear all the text and re-send the preview and queue messages.
:param context: The context of the command.
"""
await self.reset_music_channel(context)

@commands.command(
name="fixmusic",
help="Kicks the bot from the current Voice Channel, clears the current queue and resets the music channel."
)
@commands.has_permissions(administrator=True)
async def guild_bot_reset_command(self, context: commands.Context):
"""
Resets the music channel as well as attempts to disconnect the bot. This is to be used in-case there was an error
and the bot was not able to reset itself.
:param context: The context of the command.
"""
await self.remove_active_guild(context.guild)
await self.disconnect_from_guild(context.guild)
await self.reset_music_channel(context)

@commands.command(
name="removemusicchannel",
help="Unlinks the currently set music channel from being the music channel. Does not delete the actual channel"
)
@commands.has_permissions(administrator=True)
async def unlink_music_channel_command(self, context: commands.Context):
if not self.music_channels.get(context.guild.id):
await context.send(self.user_strings["music_channel_missing"])
return

music_channel_instance = await self.find_music_channel_instance(context.guild)
self.music_channels.pop(context.guild.id)
db_item = self.db.get(Music_channels, guild_id=context.guild.id)
self.db.delete(db_item)
await context.send(self.user_strings["music_channel_removed"].format(channel=music_channel_instance.mention))

@commands.command(
name="musicqueue",
aliases=["songqueue",
"songs",
"songlist",
"songslist"],
help="Gets the current list of songs in the queue"
)
@delete_after()
async def get_current_queue(self, context: commands.Context):
"""
Get the current queue as a string.
:param context: The context of the command.
"""
if context.guild.id not in self.active_guilds:
await send_timed_message(channel=context.channel, content=self.user_strings["bot_inactive"], timer=20)
return

if not self.active_guilds.get(context.guild.id).get("queue"):
await send_timed_message(channel=context.channel, content=self.user_strings["bot_inactive"], timer=20)
return

queue_string = self.get_updated_queue_message(context.guild.id, complete_list=True)
await send_timed_message(channel=context.channel, content=queue_string, timer=60)

@commands.group(
name="music",
help="These are commands used to control the music bot. For more detailed command explanations, "
"go to https://github.com/FragSoc/esports-bot#music-bot"
"go to https://github.com/FragSoc/esports-bot#music-bot",
)
@commands.check(check_music_channel)
@delete_after()
Expand Down Expand Up @@ -968,6 +861,31 @@ async def check_failed_error(self, context: commands.Context, error: commands.Ch
await context.send(self.unhandled_error_string)
raise error

@command_group.command(
name="queue",
aliases=["songqueue",
"songs",
"songlist",
"songslist"],
help="Gets the current list of songs in the queue"
)
@delete_after()
async def get_current_queue(self, context: commands.Context):
"""
Get the current queue as a string.
:param context: The context of the command.
"""
if context.guild.id not in self.active_guilds:
await send_timed_message(channel=context.channel, content=self.user_strings["bot_inactive"], timer=20)
return

if not self.active_guilds.get(context.guild.id).get("queue"):
await send_timed_message(channel=context.channel, content=self.user_strings["bot_inactive"], timer=20)
return

queue_string = self.get_updated_queue_message(context.guild.id, complete_list=True)
await send_timed_message(channel=context.channel, content=queue_string, timer=60)

@command_group.command(
name="join",
aliases=["connect"],
Expand Down Expand Up @@ -1344,6 +1262,95 @@ async def __move_song(self, guild_id, from_pos, to_pos):
await self.update_messages(guild_id)
return True

@command_group.command(
name="fix",
help="Kicks the bot from the current Voice Channel, clears the current queue and resets the music channel."
)
@commands.has_permissions(administrator=True)
async def guild_bot_reset_command(self, context: commands.Context):
"""
Resets the music channel as well as attempts to disconnect the bot. This is to be used in-case there was an error
and the bot was not able to reset itself.
:param context: The context of the command.
"""
await self.remove_active_guild(context.guild)
await self.disconnect_from_guild(context.guild)
await self.reset_music_channel(context)

@command_group.group(name="channel", help="Manage music channel")
async def music_channel_group(self, context: commands.Context):
"""
The command group for the music channel management.
:param context: The context of the command.
"""
pass

@music_channel_group.command(
name="set",
usage="<channel mention> [optional args]",
help="Sets the music channel to the channel mentioned. To see possible optional args, "
"go to https://github.com/FragSoc/esports-bot#setmusicchannel-channel-mention-optional-args"
)
@commands.has_permissions(administrator=True)
async def set_music_channel_command(self, context: commands.Context, text_channel: TextChannel):
"""
Sets the music channel for a given guild to the channel channel mentioned in the command. Extra args can be given to
indicate some extra process to perform while setting up the channel.
:param context: The context of the command.
:param text_channel: The text channel to set the music channel to.
"""
# Using the text channel as the last official arg in the command, find any extras that occur after with a `-`
text_channel_str = str(text_channel.mention)
end_index = context.message.content.index(text_channel_str) + len(text_channel_str)
args = context.message.content[end_index:].strip().split("-")
args.pop(0)
args = [arg.lower() for arg in args]
if "c" in args:
# Use -c to clear the channel.
await self.clear_music_channel(text_channel)

await self.setup_music_channel(text_channel)
await context.send(self.user_strings["music_channel_set"].format(channel=text_channel.mention))

@music_channel_group.command(name="get", help="Gets the current channel that is set as the music channel.")
@commands.has_permissions(administrator=True)
async def get_music_channel_command(self, context: commands.Context):
"""
Gets the current channel that is set as the music channel.
If there is no channel set it will return a message saying so.
:param context: The context of the command.
"""
channel = await self.find_music_channel_instance(context.guild)
if channel:
await context.send(self.user_strings["music_channel_get"].format(channel=channel.mention))
else:
await context.send(self.user_strings["music_channel_missing"])

@music_channel_group.command(name="reset", help="Clears the music channel and sends the preview and queue messages.")
@commands.has_permissions(administrator=True)
async def reset_music_channel_command(self, context: commands.Context):
"""
Resets the music channel to clear all the text and re-send the preview and queue messages.
:param context: The context of the command.
"""
await self.reset_music_channel(context)

@music_channel_group.command(
name="remove",
help="Unlinks the currently set music channel from being the music channel. Does not delete the actual channel"
)
@commands.has_permissions(administrator=True)
async def unlink_music_channel_command(self, context: commands.Context):
if not self.music_channels.get(context.guild.id):
await context.send(self.user_strings["music_channel_missing"])
return

music_channel_instance = await self.find_music_channel_instance(context.guild)
self.music_channels.pop(context.guild.id)
db_item = self.db.get(Music_channels, guild_id=context.guild.id)
self.db.delete(db_item)
await context.send(self.user_strings["music_channel_removed"].format(channel=music_channel_instance.mention))

async def song_index_str_to_int(self, context, song_index):
"""
Convert a 1-indexed song index as a string to a 0-indexed index as an int.
Expand Down

0 comments on commit 8b4b5b8

Please sign in to comment.