mirror of
https://github.com/RafaelSolVargas/Vulkan.git
synced 2025-10-29 16:57:23 +00:00
Adding support to slash commands
This commit is contained in:
parent
ef66bf8bcb
commit
3b198cf78a
@ -396,6 +396,11 @@ class VEmbeds:
|
||||
)
|
||||
return embed
|
||||
|
||||
def PLAYLIST_CLEAR(self) -> Embed:
|
||||
return Embed(
|
||||
description=self.__messages.PLAYLIST_CLEAR
|
||||
)
|
||||
|
||||
def CARA_COROA(self, result: str) -> Embed:
|
||||
embed = Embed(
|
||||
title='Cara Coroa',
|
||||
|
||||
@ -21,8 +21,8 @@ class Helper(Singleton):
|
||||
Off - Disable loop."""
|
||||
self.HELP_NP = 'Show the info of the current song.'
|
||||
self.HELP_NP_LONG = 'Show the information of the song being played.\n\nRequire: A song being played.\nArguments: None.'
|
||||
self.HELP_QUEUE = f'Show the first {config.MAX_PRELOAD_SONGS} songs in queue.'
|
||||
self.HELP_QUEUE_LONG = f'Show the first {config.MAX_PRELOAD_SONGS} song in the queue.\n\nArguments: None.'
|
||||
self.HELP_QUEUE = f'Show the first {config.MAX_SONGS_IN_PAGE} songs in queue.'
|
||||
self.HELP_QUEUE_LONG = f'Show the first {config.MAX_SONGS_IN_PAGE} song in the queue.\n\nArguments: None.'
|
||||
self.HELP_PAUSE = 'Pauses the song player.'
|
||||
self.HELP_PAUSE_LONG = 'If playing, pauses the song player.\n\nArguments: None'
|
||||
self.HELP_PREV = 'Play the previous song.'
|
||||
@ -33,7 +33,7 @@ class Helper(Singleton):
|
||||
self.HELP_PLAY_LONG = 'Play a song in discord. \n\nRequire: You to be connected to a voice channel.\nArguments: Youtube, Spotify or Deezer song/playlist link or the title of the song to be searched in Youtube.'
|
||||
self.HELP_HISTORY = f'Show the history of played songs.'
|
||||
self.HELP_HISTORY_LONG = f'Show the last {config.MAX_SONGS_HISTORY} played songs'
|
||||
self.HELP_MOVE = 'Moves a song from position x to y in queue.'
|
||||
self.HELP_MOVE = 'Moves a song from position pos1 to pos2 in queue.'
|
||||
self.HELP_MOVE_LONG = 'Moves a song from position x to position y in queue.\n\nRequire: Positions to be both valid numbers.\nArguments: 1º Number => Initial position, 2º Number => Destination position. Both numbers could be -1 to refer to the last song in queue.\nDefault: By default, if the second number is not passed, it will be 1, moving the selected song to 1º position.'
|
||||
self.HELP_REMOVE = 'Remove a song in position x.'
|
||||
self.HELP_REMOVE_LONG = 'Remove a song from queue in the position passed.\n\nRequire: Position to be a valid number.\nArguments: 1º self.Number => Position in queue of the song.'
|
||||
@ -49,3 +49,6 @@ class Helper(Singleton):
|
||||
self.HELP_CHOOSE_LONG = 'Choose randomly one item passed in this command.\n\nRequire: Itens to be separated by comma.\nArguments: As much as you want.'
|
||||
self.HELP_CARA = 'Return cara or coroa.'
|
||||
self.HELP_CARA_LONG = 'Return cara or coroa.'
|
||||
|
||||
self.SLASH_QUEUE_DESCRIPTION = f'Number of queue page, there is only {config.MAX_SONGS_IN_PAGE} musics by page'
|
||||
self.SLASH_MOVE_HELP = 'Moves a song from position pos1 to pos2 in queue.'
|
||||
|
||||
@ -31,6 +31,7 @@ class Messages(Singleton):
|
||||
self.STOPPING = f'{self.__emojis.STOP} Player Stopped'
|
||||
self.EMPTY_QUEUE = f'{self.__emojis.QUEUE} Song queue is empty, use {configs.BOT_PREFIX}play to add new songs'
|
||||
self.SONG_DOWNLOADING = f'{self.__emojis.DOWNLOADING} Downloading...'
|
||||
self.PLAYLIST_CLEAR = f'{self.__emojis.MUSIC} Playlist is now empty'
|
||||
|
||||
self.HISTORY_TITLE = f'{self.__emojis.MUSIC} Played Songs'
|
||||
self.HISTORY_EMPTY = f'{self.__emojis.QUEUE} There is no musics in history'
|
||||
|
||||
@ -45,7 +45,12 @@ class MusicCog(Cog):
|
||||
try:
|
||||
controller = PlayHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run(args)
|
||||
if len(args) > 1:
|
||||
track = " ".join(args)
|
||||
else:
|
||||
track = args
|
||||
|
||||
response = await controller.run(track)
|
||||
if response is not None:
|
||||
cogResponser1 = EmbedCommandResponse(response, MessagesCategory.PLAYER)
|
||||
cogResponser2 = EmoteCommandResponse(response, MessagesCategory.PLAYER)
|
||||
|
||||
271
DiscordCogs/SlashCog.py
Normal file
271
DiscordCogs/SlashCog.py
Normal file
@ -0,0 +1,271 @@
|
||||
from discord.ext.commands import slash_command, Cog
|
||||
from discord import Option, ApplicationContext, OptionChoice
|
||||
from Handlers.ClearHandler import ClearHandler
|
||||
from Handlers.MoveHandler import MoveHandler
|
||||
from Handlers.NowPlayingHandler import NowPlayingHandler
|
||||
from Handlers.PlayHandler import PlayHandler
|
||||
from Handlers.PrevHandler import PrevHandler
|
||||
from Handlers.RemoveHandler import RemoveHandler
|
||||
from Handlers.ResetHandler import ResetHandler
|
||||
from Handlers.ShuffleHandler import ShuffleHandler
|
||||
from Handlers.SkipHandler import SkipHandler
|
||||
from Handlers.PauseHandler import PauseHandler
|
||||
from Handlers.StopHandler import StopHandler
|
||||
from Handlers.ResumeHandler import ResumeHandler
|
||||
from Handlers.HistoryHandler import HistoryHandler
|
||||
from Handlers.QueueHandler import QueueHandler
|
||||
from Handlers.LoopHandler import LoopHandler
|
||||
from Messages.MessagesCategory import MessagesCategory
|
||||
from Messages.Responses.SlashEmbedResponse import SlashEmbedResponse
|
||||
from Music.VulkanBot import VulkanBot
|
||||
from Config.Embeds import VEmbeds
|
||||
from Config.Helper import Helper
|
||||
import traceback
|
||||
|
||||
helper = Helper()
|
||||
|
||||
|
||||
class SlashCommands(Cog):
|
||||
"""
|
||||
Class to listen to Music commands
|
||||
It'll listen for commands from discord, when triggered will create a specific Handler for the command
|
||||
Execute the handler and then create a specific View to be showed in Discord
|
||||
"""
|
||||
|
||||
def __init__(self, bot: VulkanBot) -> None:
|
||||
self.__bot: VulkanBot = bot
|
||||
self.__embeds = VEmbeds()
|
||||
|
||||
@slash_command(name="play", description=helper.HELP_PLAY)
|
||||
async def play(self, ctx: ApplicationContext,
|
||||
music: Option(str, "The music name or URL", required=True)) -> None:
|
||||
# Due to the utilization of multiprocessing module in this Project, we have multiple instances of the Bot, and by using this flag
|
||||
# we can control witch bot instance will listen to the commands that Discord send to our application
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = PlayHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run(music)
|
||||
if response is not None:
|
||||
cogResponser1 = SlashEmbedResponse(response, ctx, MessagesCategory.PLAYER)
|
||||
await cogResponser1.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name="queue", description=helper.HELP_QUEUE)
|
||||
async def queue(self, ctx: ApplicationContext,
|
||||
page_number: Option(int, helper.SLASH_QUEUE_DESCRIPTION, min_value=1, default=1)) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = QueueHandler(ctx, self.__bot)
|
||||
|
||||
# Change index 1 to 0
|
||||
page_number -= 1
|
||||
response = await controller.run(page_number)
|
||||
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.QUEUE)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name="skip", description=helper.HELP_SKIP)
|
||||
async def skip(self, ctx: ApplicationContext) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = SkipHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run()
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.PLAYER)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='stop', description=helper.HELP_STOP)
|
||||
async def stop(self, ctx: ApplicationContext) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = StopHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run()
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.PLAYER)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='pause', description=helper.HELP_PAUSE)
|
||||
async def pause(self, ctx: ApplicationContext) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = PauseHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run()
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.PLAYER)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='resume', description=helper.HELP_RESUME)
|
||||
async def resume(self, ctx: ApplicationContext) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = ResumeHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run()
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.PLAYER)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='previous', description=helper.HELP_PREV)
|
||||
async def previous(self, ctx: ApplicationContext) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = PrevHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run()
|
||||
if response is not None:
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.PLAYER)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='history', description=helper.HELP_HISTORY)
|
||||
async def history(self, ctx: ApplicationContext) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = HistoryHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run()
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.HISTORY)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='loop', description=helper.HELP_LOOP)
|
||||
async def loop(self, ctx: ApplicationContext,
|
||||
loop_type: Option(str, choices=[
|
||||
OptionChoice(name='off', value='off'),
|
||||
OptionChoice(name='one', value='one'),
|
||||
OptionChoice(name='all', value='all')
|
||||
])) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = LoopHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run(loop_type)
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.LOOP)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='clear', description=helper.HELP_CLEAR)
|
||||
async def clear(self, ctx: ApplicationContext) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = ClearHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run()
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.PLAYER)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='now_playing', description=helper.HELP_NP)
|
||||
async def now_playing(self, ctx: ApplicationContext) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = NowPlayingHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run()
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.NOW_PLAYING)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='shuffle_songs', description=helper.HELP_SHUFFLE)
|
||||
async def shuffle(self, ctx: ApplicationContext) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = ShuffleHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run()
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.PLAYER)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='move_song', description=helper.SLASH_MOVE_HELP)
|
||||
async def move(self, ctx: ApplicationContext,
|
||||
from_pos: Option(int, "The position of song to move", min_value=1),
|
||||
to_pos: Option(int, "The position to put the song, default 1", min_value=1, default=1)) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
if from_pos == 0:
|
||||
from_pos = 1
|
||||
|
||||
controller = MoveHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run(from_pos, to_pos)
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.MANAGING_QUEUE)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='remove', description=helper.HELP_REMOVE)
|
||||
async def remove(self, ctx: ApplicationContext,
|
||||
position: Option(int, "The song position to remove", min_value=1)) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = RemoveHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run(position)
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.MANAGING_QUEUE)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
@slash_command(name='reset', description=helper.HELP_RESET)
|
||||
async def reset(self, ctx: ApplicationContext) -> None:
|
||||
if not self.__bot.listingSlash:
|
||||
return
|
||||
try:
|
||||
await ctx.defer()
|
||||
controller = ResetHandler(ctx, self.__bot)
|
||||
|
||||
response = await controller.run()
|
||||
cogResponser = SlashEmbedResponse(response, ctx, MessagesCategory.PLAYER)
|
||||
await cogResponser.run()
|
||||
except Exception:
|
||||
print(f'[ERROR IN SLASH COMMAND] -> {traceback.format_exc()}')
|
||||
|
||||
|
||||
def setup(bot):
|
||||
bot.add_cog(SlashCommands(bot))
|
||||
@ -23,7 +23,8 @@ class ClearHandler(AbstractHandler):
|
||||
if acquired:
|
||||
playlist.clear()
|
||||
processLock.release()
|
||||
return HandlerResponse(self.ctx)
|
||||
embed = self.embeds.PLAYLIST_CLEAR()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
else:
|
||||
processManager.resetProcess(self.guild, self.ctx)
|
||||
embed = self.embeds.PLAYER_RESTARTED()
|
||||
|
||||
@ -21,8 +21,7 @@ class PlayHandler(AbstractHandler):
|
||||
self.__searcher = Searcher()
|
||||
self.__down = Downloader()
|
||||
|
||||
async def run(self, args: str) -> HandlerResponse:
|
||||
track = " ".join(args)
|
||||
async def run(self, track: str) -> HandlerResponse:
|
||||
requester = self.ctx.author.name
|
||||
|
||||
if not self.__isUserConnected():
|
||||
|
||||
@ -47,11 +47,11 @@ class QueueHandler(AbstractHandler):
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
songsPages = playlist.getSongsPages()
|
||||
if pageNumber < 0 or pageNumber >= len(songsPages):
|
||||
embed = self.embeds.INVALID_INDEX()
|
||||
error = InvalidIndex()
|
||||
processLock.release() # Release the Lock
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
# Truncate the pageNumber to the closest value
|
||||
if pageNumber < 0:
|
||||
pageNumber = 0
|
||||
elif pageNumber >= len(songsPages):
|
||||
pageNumber = len(songsPages) - 1
|
||||
|
||||
# Select the page in queue to be printed
|
||||
songs = songsPages[pageNumber]
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
from typing import Union
|
||||
from discord.ext.commands import Context
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Config.Exceptions import BadCommandUsage, VulkanError, ErrorRemoving, InvalidInput, NumberRequired
|
||||
from Music.Playlist import Playlist
|
||||
from Music.VulkanBot import VulkanBot
|
||||
from Parallelism.ProcessInfo import ProcessInfo
|
||||
from typing import Union
|
||||
from discord import Interaction
|
||||
|
||||
@ -16,15 +16,14 @@ class RemoveHandler(AbstractHandler):
|
||||
async def run(self, position: str) -> HandlerResponse:
|
||||
# Get the current process of the guild
|
||||
processManager = self.config.getProcessManager()
|
||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
||||
processInfo: ProcessInfo = processManager.getRunningPlayerInfo(self.guild)
|
||||
if not processInfo:
|
||||
# Clear the playlist
|
||||
embed = self.embeds.NOT_PLAYING()
|
||||
error = BadCommandUsage()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
playlist = processInfo.getPlaylist()
|
||||
if playlist.getCurrentSong() is None:
|
||||
if playlist is None:
|
||||
embed = self.embeds.NOT_PLAYING()
|
||||
error = BadCommandUsage()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
39
Messages/DiscordMessages.py
Normal file
39
Messages/DiscordMessages.py
Normal file
@ -0,0 +1,39 @@
|
||||
from discord import Message, WebhookMessage
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
class VAbstractMessage(ABC):
|
||||
"""
|
||||
Abstract class to allow create a pattern when dealing with multiple Discord
|
||||
messages types, such as Interaction Messages and the standard discord messages
|
||||
that contains two different ways of deletion
|
||||
"""
|
||||
@abstractmethod
|
||||
async def delete(self):
|
||||
pass
|
||||
|
||||
|
||||
class VWebHookMessage(VAbstractMessage):
|
||||
"""
|
||||
Holds a WebhookMessage instance
|
||||
"""
|
||||
|
||||
def __init__(self, message: WebhookMessage) -> None:
|
||||
self.__message = message
|
||||
super().__init__()
|
||||
|
||||
async def delete(self):
|
||||
await self.__message.delete()
|
||||
|
||||
|
||||
class VDefaultMessage(VAbstractMessage):
|
||||
"""
|
||||
Holds a Message instance, the basic Discord message type
|
||||
"""
|
||||
|
||||
def __init__(self, message: Message) -> None:
|
||||
self.__message = message
|
||||
super().__init__()
|
||||
|
||||
async def delete(self):
|
||||
await self.__message.delete()
|
||||
@ -1,19 +1,20 @@
|
||||
from typing import Dict, List
|
||||
from discord import Message
|
||||
from Config.Singleton import Singleton
|
||||
from UI.Views.AbstractView import AbstractView
|
||||
from Messages.MessagesCategory import MessagesCategory
|
||||
from Messages.DiscordMessages import VAbstractMessage
|
||||
import traceback
|
||||
|
||||
|
||||
class MessagesManager(Singleton):
|
||||
def __init__(self) -> None:
|
||||
if not super().created:
|
||||
# For each guild, and for each category, there will be a list of messages
|
||||
self.__guildsMessages: Dict[int, Dict[MessagesCategory, List[Message]]] = {}
|
||||
self.__guildsMessages: Dict[int, Dict[MessagesCategory, List[VAbstractMessage]]] = {}
|
||||
# Will, for each message, store the AbstractView that controls it
|
||||
self.__messagesViews: Dict[Message, AbstractView] = {}
|
||||
self.__messagesViews: Dict[VAbstractMessage, AbstractView] = {}
|
||||
|
||||
def addMessage(self, guildID: int, category: MessagesCategory, message: Message, view: AbstractView = None) -> None:
|
||||
def addMessage(self, guildID: int, category: MessagesCategory, message: VAbstractMessage, view: AbstractView = None) -> None:
|
||||
if message is None:
|
||||
return
|
||||
|
||||
@ -29,7 +30,7 @@ class MessagesManager(Singleton):
|
||||
self.__messagesViews[message] = view
|
||||
sendedMessages.append(message)
|
||||
|
||||
async def addMessageAndClearPrevious(self, guildID: int, category: MessagesCategory, message: Message, view: AbstractView = None) -> None:
|
||||
async def addMessageAndClearPrevious(self, guildID: int, category: MessagesCategory, message: VAbstractMessage, view: AbstractView = None) -> None:
|
||||
if message is None:
|
||||
return
|
||||
|
||||
@ -66,7 +67,7 @@ class MessagesManager(Singleton):
|
||||
for message in categoriesMessages[category]:
|
||||
self.__deleteMessage(message)
|
||||
|
||||
async def __deleteMessage(self, message: Message) -> None:
|
||||
async def __deleteMessage(self, message: VAbstractMessage) -> None:
|
||||
try:
|
||||
# If there is a view for this message delete the key
|
||||
if message in self.__messagesViews.keys():
|
||||
@ -75,6 +76,5 @@ class MessagesManager(Singleton):
|
||||
del messageView
|
||||
|
||||
await message.delete()
|
||||
except Exception as e:
|
||||
print(f'[ERROR DELETING MESSAGE] -> {e}')
|
||||
pass
|
||||
except Exception:
|
||||
print(f'[ERROR DELETING MESSAGE] -> {traceback.format_exc()}')
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
from Messages.Responses.AbstractCogResponse import AbstractCommandResponse
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Messages.MessagesCategory import MessagesCategory
|
||||
from Messages.DiscordMessages import VAbstractMessage, VDefaultMessage
|
||||
|
||||
|
||||
class EmbedCommandResponse(AbstractCommandResponse):
|
||||
@ -9,16 +10,20 @@ class EmbedCommandResponse(AbstractCommandResponse):
|
||||
|
||||
async def run(self, deleteLast: bool = True) -> None:
|
||||
message = None
|
||||
# If the response has both embed and view to be sended
|
||||
if self.response.embed and self.response.view:
|
||||
message = await self.context.send(embed=self.response.embed, view=self.response.view)
|
||||
# Set the view to contain the sended message
|
||||
self.response.view.set_message(message)
|
||||
|
||||
# Or just a embed
|
||||
elif self.response.embed:
|
||||
message = await self.context.send(embed=self.response.embed)
|
||||
|
||||
if message:
|
||||
vMessage: VAbstractMessage = VDefaultMessage(message)
|
||||
# Only delete the previous message if this is not error and not forbidden by method caller
|
||||
if deleteLast and self.response.success:
|
||||
await self.manager.addMessageAndClearPrevious(self.context.guild.id, self.category, message, self.response.view)
|
||||
await self.manager.addMessageAndClearPrevious(self.context.guild.id, self.category, vMessage, self.response.view)
|
||||
else:
|
||||
self.manager.addMessage(self.context.guild.id, self.category, message)
|
||||
self.manager.addMessage(self.context.guild.id, self.category, vMessage)
|
||||
|
||||
@ -11,6 +11,10 @@ class EmoteCommandResponse(AbstractCommandResponse):
|
||||
self.__emojis = VEmojis()
|
||||
|
||||
async def run(self, deleteLast: bool = True) -> None:
|
||||
# Now with Discord Interactions some commands are triggered without message
|
||||
if (self.message is None):
|
||||
return None
|
||||
|
||||
if self.response.success:
|
||||
await self.message.add_reaction(self.__emojis.SUCCESS)
|
||||
else:
|
||||
|
||||
35
Messages/Responses/SlashEmbedResponse.py
Normal file
35
Messages/Responses/SlashEmbedResponse.py
Normal file
@ -0,0 +1,35 @@
|
||||
from Messages.Responses.AbstractCogResponse import AbstractCommandResponse
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Messages.MessagesCategory import MessagesCategory
|
||||
from Messages.DiscordMessages import VAbstractMessage, VWebHookMessage
|
||||
from discord import ApplicationContext
|
||||
|
||||
|
||||
class SlashEmbedResponse(AbstractCommandResponse):
|
||||
def __init__(self, response: HandlerResponse, ctx: ApplicationContext, category: MessagesCategory) -> None:
|
||||
self.__ctx = ctx
|
||||
super().__init__(response, category)
|
||||
|
||||
async def run(self, deleteLast: bool = True) -> None:
|
||||
message = None
|
||||
# If the response has both embed and view to send
|
||||
if self.response.embed and self.response.view:
|
||||
# Respond the Slash command and set the view to contain the sended message
|
||||
message = await self.__ctx.send_followup(embed=self.response.embed, view=self.response.view)
|
||||
self.response.view.set_message(message)
|
||||
|
||||
# If the response only has the embed then send the embed
|
||||
elif self.response.embed:
|
||||
message = await self.__ctx.send_followup(embed=self.response.embed)
|
||||
else:
|
||||
message = await self.__ctx.send_followup('Ok!')
|
||||
|
||||
# If any message was sended
|
||||
if message:
|
||||
# Convert the Discord message type to an Vulkan type
|
||||
vMessage: VAbstractMessage = VWebHookMessage(message)
|
||||
# Only delete the previous message if this is not error and not forbidden by method caller
|
||||
if deleteLast and self.response.success:
|
||||
await self.manager.addMessageAndClearPrevious(self.context.guild.id, self.category, vMessage, self.response.view)
|
||||
else:
|
||||
self.manager.addMessage(self.context.guild.id, self.category, vMessage)
|
||||
@ -8,13 +8,18 @@ from Config.Embeds import VEmbeds
|
||||
|
||||
|
||||
class VulkanBot(Bot):
|
||||
def __init__(self, *args, **kwargs):
|
||||
def __init__(self, listingSlash: bool = False, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.__listingSlash = listingSlash
|
||||
self.__configs = VConfigs()
|
||||
self.__messages = Messages()
|
||||
self.__embeds = VEmbeds()
|
||||
self.remove_command("help")
|
||||
|
||||
@property
|
||||
def listingSlash(self) -> bool:
|
||||
return self.__listingSlash
|
||||
|
||||
def startBot(self) -> None:
|
||||
"""Blocking function that will start the bot"""
|
||||
if self.__configs.BOT_TOKEN == '':
|
||||
|
||||
@ -23,13 +23,18 @@ class VulkanInitializer:
|
||||
def __create_bot(self, willListen: bool) -> VulkanBot:
|
||||
if willListen:
|
||||
prefix = self.__config.BOT_PREFIX
|
||||
bot = VulkanBot(listingSlash=True,
|
||||
command_prefix=prefix,
|
||||
pm_help=True,
|
||||
case_insensitive=True,
|
||||
intents=self.__intents)
|
||||
else:
|
||||
prefix = ''.join(choices(string.ascii_uppercase + string.digits, k=4))
|
||||
|
||||
bot = VulkanBot(command_prefix=prefix,
|
||||
pm_help=True,
|
||||
case_insensitive=True,
|
||||
intents=self.__intents)
|
||||
bot = VulkanBot(listingSlash=False,
|
||||
command_prefix=prefix,
|
||||
pm_help=True,
|
||||
case_insensitive=True,
|
||||
intents=self.__intents)
|
||||
return bot
|
||||
|
||||
def __add_cogs(self, bot: Bot) -> None:
|
||||
|
||||
@ -15,7 +15,8 @@ Vulkan uses multiprocessing and asynchronous Python modules to maximize Music Pl
|
||||
- Play musics from Youtube, Spotify and Deezer links (Albums, Artists, Playlists and Tracks).
|
||||
- Play musics in multiple discord server at the same time.
|
||||
- The player contains buttons to shortcut some commands.
|
||||
- Search for all musics in Queue using buttons
|
||||
- Support for the new Discord Slash commands.
|
||||
- Search for all musics in Queue using buttons.
|
||||
- Shortcut the playing of one song using dropdown menu.
|
||||
- Manage the loop of one or all playing musics.
|
||||
- Manage the order and remove musics from the queue.
|
||||
|
||||
@ -1,16 +1,19 @@
|
||||
from typing import List
|
||||
from discord import Message
|
||||
from discord.ui import View
|
||||
from Config.Emojis import VEmojis
|
||||
from Music.VulkanBot import VulkanBot
|
||||
from UI.Views.AbstractView import AbstractView
|
||||
from UI.Buttons.AbstractItem import AbstractItem
|
||||
from Music.VulkanBot import VulkanBot
|
||||
from Config.Emojis import VEmojis
|
||||
from discord import Message
|
||||
from discord.ui import View
|
||||
from typing import List
|
||||
|
||||
emojis = VEmojis()
|
||||
|
||||
|
||||
class BasicView(View, AbstractView):
|
||||
"""View that receives buttons to hold, in timeout disable buttons"""
|
||||
"""
|
||||
View class that inherits from the Discord View Class, managing a list of Buttons
|
||||
and the message that holds this View.
|
||||
"""
|
||||
|
||||
def __init__(self, bot: VulkanBot, buttons: List[AbstractItem], timeout: float = 6000):
|
||||
super().__init__(timeout=timeout)
|
||||
@ -42,6 +45,7 @@ class BasicView(View, AbstractView):
|
||||
self.__message = message
|
||||
|
||||
async def update(self):
|
||||
"""Edit the message sending the view again"""
|
||||
try:
|
||||
if not self.__working:
|
||||
return
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user