mirror of
https://github.com/RafaelSolVargas/Vulkan.git
synced 2025-10-29 16:57:23 +00:00
Continuing the refactoring
This commit is contained in:
parent
7a5d76ffd3
commit
72043c4475
@ -23,7 +23,7 @@ from Messages.Responses.EmbedCogResponse import EmbedCommandResponse
|
|||||||
from Music.VulkanBot import VulkanBot
|
from Music.VulkanBot import VulkanBot
|
||||||
from Config.Configs import VConfigs
|
from Config.Configs import VConfigs
|
||||||
from Config.Embeds import VEmbeds
|
from Config.Embeds import VEmbeds
|
||||||
from Parallelism.ProcessManager import ProcessManager
|
from Parallelism.ProcessManager import ProcessPlayerManager
|
||||||
|
|
||||||
helper = Helper()
|
helper = Helper()
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ class MusicCog(Cog):
|
|||||||
def __init__(self, bot: VulkanBot) -> None:
|
def __init__(self, bot: VulkanBot) -> None:
|
||||||
self.__bot: VulkanBot = bot
|
self.__bot: VulkanBot = bot
|
||||||
self.__embeds = VEmbeds()
|
self.__embeds = VEmbeds()
|
||||||
VConfigs().setPlayersManager(ProcessManager(bot))
|
VConfigs().setPlayersManager(ProcessPlayerManager(bot))
|
||||||
|
|
||||||
@command(name="play", help=helper.HELP_PLAY, description=helper.HELP_PLAY_LONG, aliases=['p', 'tocar'])
|
@command(name="play", help=helper.HELP_PLAY, description=helper.HELP_PLAY_LONG, aliases=['p', 'tocar'])
|
||||||
async def play(self, ctx: Context, *args) -> None:
|
async def play(self, ctx: Context, *args) -> None:
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from Parallelism.Commands import VCommands
|
|
||||||
from multiprocessing import Queue
|
|
||||||
from typing import List, Union
|
from typing import List, Union
|
||||||
from discord.ext.commands import Context
|
from discord.ext.commands import Context
|
||||||
from discord import Client, Guild, ClientUser, Interaction, Member, User
|
from discord import Client, Guild, ClientUser, Interaction, Member, User
|
||||||
@ -29,12 +27,6 @@ class AbstractHandler(ABC):
|
|||||||
else:
|
else:
|
||||||
self.__author = ctx.user
|
self.__author = ctx.user
|
||||||
|
|
||||||
def putCommandInQueue(self, queue: Queue, command: VCommands) -> None:
|
|
||||||
try:
|
|
||||||
queue.put(command)
|
|
||||||
except Exception as e:
|
|
||||||
print(f'[ERROR PUTTING COMMAND IN QUEUE] -> {e}')
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def run(self) -> HandlerResponse:
|
async def run(self) -> HandlerResponse:
|
||||||
pass
|
pass
|
||||||
|
|||||||
@ -5,7 +5,6 @@ from Music.VulkanBot import VulkanBot
|
|||||||
from Handlers.AbstractHandler import AbstractHandler
|
from Handlers.AbstractHandler import AbstractHandler
|
||||||
from Handlers.HandlerResponse import HandlerResponse
|
from Handlers.HandlerResponse import HandlerResponse
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
from Parallelism.ProcessInfo import PlayerInfo
|
|
||||||
|
|
||||||
|
|
||||||
class ClearHandler(AbstractHandler):
|
class ClearHandler(AbstractHandler):
|
||||||
@ -14,19 +13,18 @@ class ClearHandler(AbstractHandler):
|
|||||||
|
|
||||||
async def run(self) -> HandlerResponse:
|
async def run(self) -> HandlerResponse:
|
||||||
# Get the current process of the guild
|
# Get the current process of the guild
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
if playersManager.verifyIfPlayerExists(self.guild):
|
||||||
if processInfo:
|
|
||||||
# Clear the playlist
|
# Clear the playlist
|
||||||
playlist = processInfo.getPlaylist()
|
playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
processLock = processInfo.getLock()
|
playerLock = playersManager.getPlayerLock(self.guild)
|
||||||
acquired = processLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
||||||
if acquired:
|
if acquired:
|
||||||
playlist.clear()
|
playlist.clear()
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
embed = self.embeds.PLAYLIST_CLEAR()
|
embed = self.embeds.PLAYLIST_CLEAR()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
else:
|
else:
|
||||||
processManager.resetProcess(self.guild, self.ctx)
|
playersManager.resetPlayer(self.guild, self.ctx)
|
||||||
embed = self.embeds.PLAYER_RESTARTED()
|
embed = self.embeds.PLAYER_RESTARTED()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|||||||
@ -14,18 +14,16 @@ class HistoryHandler(AbstractHandler):
|
|||||||
|
|
||||||
async def run(self) -> HandlerResponse:
|
async def run(self) -> HandlerResponse:
|
||||||
# Get the current process of the guild
|
# Get the current process of the guild
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
if playersManager.verifyIfPlayerExists(self.guild):
|
||||||
if processInfo:
|
playerLock = playersManager.getPlayerLock(self.guild)
|
||||||
processLock = processInfo.getLock()
|
acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
||||||
acquired = processLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
|
||||||
if acquired:
|
if acquired:
|
||||||
playlist = processInfo.getPlaylist()
|
history = playersManager.getPlayerPlaylist(self.guild).getSongsHistory()
|
||||||
history = playlist.getSongsHistory()
|
playerLock.release()
|
||||||
processLock.release()
|
|
||||||
else:
|
else:
|
||||||
# If the player doesn't respond in time we restart it
|
# If the player doesn't respond in time we restart it
|
||||||
processManager.resetProcess(self.guild, self.ctx)
|
playersManager.resetPlayer(self.guild, self.ctx)
|
||||||
embed = self.embeds.PLAYER_RESTARTED()
|
embed = self.embeds.PLAYER_RESTARTED()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -17,32 +17,31 @@ class JumpMusicHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self, musicPos: str) -> HandlerResponse:
|
async def run(self, musicPos: str) -> HandlerResponse:
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
if not playersManager.verifyIfPlayerExists(self.guild):
|
||||||
if not processInfo:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
embed = self.embeds.NOT_PLAYING()
|
||||||
error = BadCommandUsage()
|
error = BadCommandUsage()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
|
||||||
processLock = processInfo.getLock()
|
playerLock = playersManager.getPlayerLock(self.guild)
|
||||||
acquired = processLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
||||||
if acquired:
|
if acquired:
|
||||||
# Try to convert input to int
|
# Try to convert input to int
|
||||||
error = self.__validateInput(musicPos)
|
error = self.__validateInput(musicPos)
|
||||||
if error:
|
if error:
|
||||||
embed = self.embeds.ERROR_EMBED(error.message)
|
embed = self.embeds.ERROR_EMBED(error.message)
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
|
||||||
# Sanitize the input
|
# Sanitize the input
|
||||||
playlist: Playlist = processInfo.getPlaylist()
|
playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
musicPos = self.__sanitizeInput(playlist, musicPos)
|
musicPos = self.__sanitizeInput(playlist, musicPos)
|
||||||
|
|
||||||
# Validate the position
|
# Validate the position
|
||||||
if not playlist.validate_position(musicPos):
|
if not playlist.validate_position(musicPos):
|
||||||
error = InvalidInput()
|
error = InvalidInput()
|
||||||
embed = self.embeds.PLAYLIST_RANGE_ERROR()
|
embed = self.embeds.PLAYLIST_RANGE_ERROR()
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
try:
|
try:
|
||||||
# Move the selected song
|
# Move the selected song
|
||||||
@ -50,19 +49,17 @@ class JumpMusicHandler(AbstractHandler):
|
|||||||
|
|
||||||
# Send a command to the player to skip the music
|
# Send a command to the player to skip the music
|
||||||
command = VCommands(VCommandsType.SKIP, None)
|
command = VCommands(VCommandsType.SKIP, None)
|
||||||
queue = processInfo.getQueueToPlayer()
|
playersManager.sendCommandToPlayer(command, self.guild)
|
||||||
self.putCommandInQueue(queue, command)
|
|
||||||
|
|
||||||
processLock.release()
|
|
||||||
return HandlerResponse(self.ctx)
|
return HandlerResponse(self.ctx)
|
||||||
except:
|
except:
|
||||||
# Release the acquired Lock
|
|
||||||
processLock.release()
|
|
||||||
embed = self.embeds.ERROR_MOVING()
|
embed = self.embeds.ERROR_MOVING()
|
||||||
error = UnknownError()
|
error = UnknownError()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
finally:
|
||||||
|
playerLock.release()
|
||||||
else:
|
else:
|
||||||
processManager.resetProcess(self.guild, self.ctx)
|
playersManager.resetPlayer(self.guild, self.ctx)
|
||||||
embed = self.embeds.PLAYER_RESTARTED()
|
embed = self.embeds.PLAYER_RESTARTED()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@ from Handlers.HandlerResponse import HandlerResponse
|
|||||||
from Config.Exceptions import BadCommandUsage
|
from Config.Exceptions import BadCommandUsage
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from discord import Interaction
|
from discord import Interaction
|
||||||
|
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
|
|
||||||
|
|
||||||
@ -14,23 +13,20 @@ class LoopHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self, args: str) -> HandlerResponse:
|
async def run(self, args: str) -> HandlerResponse:
|
||||||
# Get the current process of the guild
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
if not playersManager.verifyIfPlayerExists(self.guild):
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
|
||||||
if not processInfo:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
embed = self.embeds.NOT_PLAYING()
|
||||||
error = BadCommandUsage()
|
error = BadCommandUsage()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
|
||||||
playlist = processInfo.getPlaylist()
|
playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
|
playerLock = playersManager.getPlayerLock(self.guild)
|
||||||
processLock = processInfo.getLock()
|
acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
||||||
acquired = processLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
|
||||||
if acquired:
|
if acquired:
|
||||||
if args == '' or args is None:
|
if args == '' or args is None:
|
||||||
playlist.loop_all()
|
playlist.loop_all()
|
||||||
embed = self.embeds.LOOP_ALL_ACTIVATED()
|
embed = self.embeds.LOOP_ALL_ACTIVATED()
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
args = args.lower()
|
args = args.lower()
|
||||||
@ -53,9 +49,9 @@ class LoopHandler(AbstractHandler):
|
|||||||
error = BadCommandUsage()
|
error = BadCommandUsage()
|
||||||
embed = self.embeds.BAD_LOOP_USE()
|
embed = self.embeds.BAD_LOOP_USE()
|
||||||
|
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
else:
|
else:
|
||||||
processManager.resetProcess(self.guild, self.ctx)
|
playersManager.resetPlayer(self.guild, self.ctx)
|
||||||
embed = self.embeds.PLAYER_RESTARTED()
|
embed = self.embeds.PLAYER_RESTARTED()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|||||||
@ -15,45 +15,44 @@ class MoveHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self, pos1: str, pos2: str) -> HandlerResponse:
|
async def run(self, pos1: str, pos2: str) -> HandlerResponse:
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
if not playersManager.verifyIfPlayerExists(self.guild):
|
||||||
if not processInfo:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
embed = self.embeds.NOT_PLAYING()
|
||||||
error = BadCommandUsage()
|
error = BadCommandUsage()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
|
||||||
processLock = processInfo.getLock()
|
playerLock = playersManager.getPlayerLock(self.guild)
|
||||||
acquired = processLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
||||||
if acquired:
|
if acquired:
|
||||||
error = self.__validateInput(pos1, pos2)
|
error = self.__validateInput(pos1, pos2)
|
||||||
if error:
|
if error:
|
||||||
embed = self.embeds.ERROR_EMBED(error.message)
|
embed = self.embeds.ERROR_EMBED(error.message)
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
|
||||||
playlist = processInfo.getPlaylist()
|
playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
pos1, pos2 = self.__sanitizeInput(playlist, pos1, pos2)
|
pos1, pos2 = self.__sanitizeInput(playlist, pos1, pos2)
|
||||||
|
|
||||||
if not playlist.validate_position(pos1) or not playlist.validate_position(pos2):
|
if not playlist.validate_position(pos1) or not playlist.validate_position(pos2):
|
||||||
error = InvalidInput()
|
error = InvalidInput()
|
||||||
embed = self.embeds.PLAYLIST_RANGE_ERROR()
|
embed = self.embeds.PLAYLIST_RANGE_ERROR()
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
try:
|
try:
|
||||||
song = playlist.move_songs(pos1, pos2)
|
song = playlist.move_songs(pos1, pos2)
|
||||||
|
|
||||||
song_name = song.title if song.title else song.identifier
|
song_name = song.title if song.title else song.identifier
|
||||||
embed = self.embeds.SONG_MOVED(song_name, pos1, pos2)
|
embed = self.embeds.SONG_MOVED(song_name, pos1, pos2)
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
except:
|
except:
|
||||||
# Release the acquired Lock
|
# Release the acquired Lock
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
embed = self.embeds.ERROR_MOVING()
|
embed = self.embeds.ERROR_MOVING()
|
||||||
error = UnknownError()
|
error = UnknownError()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
else:
|
else:
|
||||||
processManager.resetProcess(self.guild, self.ctx)
|
playersManager.resetPlayer(self.guild, self.ctx)
|
||||||
embed = self.embeds.PLAYER_RESTARTED()
|
embed = self.embeds.PLAYER_RESTARTED()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
|
|||||||
@ -14,14 +14,12 @@ class NowPlayingHandler(AbstractHandler):
|
|||||||
self.__cleaner = Cleaner()
|
self.__cleaner = Cleaner()
|
||||||
|
|
||||||
async def run(self) -> HandlerResponse:
|
async def run(self) -> HandlerResponse:
|
||||||
# Get the current process of the guild
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
if not playersManager.verifyIfPlayerExists(self.guild):
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
|
||||||
if not processInfo:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
embed = self.embeds.NOT_PLAYING()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
playlist = processInfo.getPlaylist()
|
playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
if playlist.getCurrentSong() is None:
|
if playlist.getCurrentSong() is None:
|
||||||
embed = self.embeds.NOT_PLAYING()
|
embed = self.embeds.NOT_PLAYING()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|||||||
@ -3,7 +3,6 @@ from Handlers.AbstractHandler import AbstractHandler
|
|||||||
from Handlers.HandlerResponse import HandlerResponse
|
from Handlers.HandlerResponse import HandlerResponse
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
from Parallelism.Commands import VCommands, VCommandsType
|
from Parallelism.Commands import VCommands, VCommandsType
|
||||||
from Parallelism.ProcessInfo import PlayerInfo, ProcessStatus
|
|
||||||
from Music.VulkanBot import VulkanBot
|
from Music.VulkanBot import VulkanBot
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from discord import Interaction
|
from discord import Interaction
|
||||||
@ -14,17 +13,10 @@ class PauseHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self) -> HandlerResponse:
|
async def run(self) -> HandlerResponse:
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
if playersManager.verifyIfPlayerExists(self.guild):
|
||||||
if processInfo:
|
|
||||||
if processInfo.getStatus() == ProcessStatus.SLEEPING:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
|
||||||
return HandlerResponse(self.ctx, embed)
|
|
||||||
|
|
||||||
# Send Pause command to be execute by player process
|
|
||||||
command = VCommands(VCommandsType.PAUSE, None)
|
command = VCommands(VCommandsType.PAUSE, None)
|
||||||
queue = processInfo.getQueueToPlayer()
|
playersManager.sendCommandToPlayer(command, self.guild)
|
||||||
self.putCommandInQueue(queue, command)
|
|
||||||
|
|
||||||
embed = self.embeds.PLAYER_PAUSED()
|
embed = self.embeds.PLAYER_PAUSED()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import traceback
|
import traceback
|
||||||
from typing import List
|
from typing import List, Union
|
||||||
from Config.Exceptions import DownloadingError, InvalidInput, VulkanError
|
from Config.Exceptions import DownloadingError, InvalidInput, VulkanError
|
||||||
from discord.ext.commands import Context
|
from discord.ext.commands import Context
|
||||||
from Handlers.AbstractHandler import AbstractHandler
|
from Handlers.AbstractHandler import AbstractHandler
|
||||||
@ -10,12 +10,9 @@ from Music.Downloader import Downloader
|
|||||||
from Music.Searcher import Searcher
|
from Music.Searcher import Searcher
|
||||||
from Music.Song import Song
|
from Music.Song import Song
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
from Parallelism.ProcessInfo import PlayerInfo
|
|
||||||
from Parallelism.Commands import VCommands, VCommandsType
|
from Parallelism.Commands import VCommands, VCommandsType
|
||||||
from Music.VulkanBot import VulkanBot
|
from Music.VulkanBot import VulkanBot
|
||||||
from typing import Union
|
|
||||||
from discord import Interaction
|
from discord import Interaction
|
||||||
from Music.Playlist import Playlist
|
|
||||||
|
|
||||||
|
|
||||||
class PlayHandler(AbstractHandler):
|
class PlayHandler(AbstractHandler):
|
||||||
@ -37,13 +34,12 @@ class PlayHandler(AbstractHandler):
|
|||||||
if musicsInfo is None or len(musicsInfo) == 0:
|
if musicsInfo is None or len(musicsInfo) == 0:
|
||||||
raise InvalidInput(self.messages.INVALID_INPUT, self.messages.ERROR_TITLE)
|
raise InvalidInput(self.messages.INVALID_INPUT, self.messages.ERROR_TITLE)
|
||||||
|
|
||||||
# Get the process context for the current guild
|
# If there is no executing player for the guild then we create the player
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processInfo = processManager.getOrCreatePlayerInfo(self.guild, self.ctx)
|
if not playersManager.verifyIfPlayerExists(self.guild):
|
||||||
playlist: Playlist = processInfo.getPlaylist()
|
playersManager.createPlayerForGuild(self.guild, self.ctx)
|
||||||
process = processInfo.getProcess()
|
|
||||||
if not process.is_alive(): # If process has not yet started, start
|
playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
process.start()
|
|
||||||
|
|
||||||
# Create the Songs objects
|
# Create the Songs objects
|
||||||
songs: List[Song] = []
|
songs: List[Song] = []
|
||||||
@ -67,19 +63,17 @@ class PlayHandler(AbstractHandler):
|
|||||||
embed = self.embeds.SONG_ADDED_TWO(song.info, pos)
|
embed = self.embeds.SONG_ADDED_TWO(song.info, pos)
|
||||||
response = HandlerResponse(self.ctx, embed)
|
response = HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
# Add the unique song to the playlist and send a command to player process
|
# Add the unique song to the playlist and send a command to player
|
||||||
processLock = processInfo.getLock()
|
playerLock = playersManager.getPlayerLock(self.guild)
|
||||||
acquired = processLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
||||||
if acquired:
|
if acquired:
|
||||||
playlist.add_song(song)
|
playlist.add_song(song)
|
||||||
# Release the acquired Lock
|
# Release the acquired Lock
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
queue = processInfo.getQueueToPlayer()
|
|
||||||
playCommand = VCommands(VCommandsType.PLAY, None)
|
playCommand = VCommands(VCommandsType.PLAY, None)
|
||||||
self.putCommandInQueue(queue, playCommand)
|
playersManager.sendCommandToPlayer(playCommand, self.guild)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
processManager.resetProcess(self.guild, self.ctx)
|
playersManager.resetPlayer(self.guild, self.ctx)
|
||||||
embed = self.embeds.PLAYER_RESTARTED()
|
embed = self.embeds.PLAYER_RESTARTED()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
@ -89,10 +83,10 @@ class PlayHandler(AbstractHandler):
|
|||||||
if len(songs) > 10:
|
if len(songs) > 10:
|
||||||
fiveFirstSongs = songs[0:5]
|
fiveFirstSongs = songs[0:5]
|
||||||
songs = songs[5:]
|
songs = songs[5:]
|
||||||
await self.__downloadSongsAndStore(fiveFirstSongs, processInfo)
|
await self.__downloadSongsAndStore(fiveFirstSongs, playersManager)
|
||||||
|
|
||||||
# Trigger a task to download all songs and then store them in the process playlist
|
# Trigger a task to download all songs and then store them in the playlist
|
||||||
asyncio.create_task(self.__downloadSongsAndStore(songs, processInfo))
|
asyncio.create_task(self.__downloadSongsAndStore(songs, playersManager))
|
||||||
|
|
||||||
embed = self.embeds.SONGS_ADDED(len(songs))
|
embed = self.embeds.SONGS_ADDED(len(songs))
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
@ -102,7 +96,7 @@ class PlayHandler(AbstractHandler):
|
|||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
print(f'ERROR IN PLAYHANDLER -> {traceback.format_exc()}', {type(error)})
|
print(f'ERROR IN PLAYHANDLER -> {traceback.format_exc()}', {type(error)})
|
||||||
if isinstance(error, VulkanError): # If error was already processed
|
if isinstance(error, VulkanError):
|
||||||
embed = self.embeds.CUSTOM_ERROR(error)
|
embed = self.embeds.CUSTOM_ERROR(error)
|
||||||
else:
|
else:
|
||||||
error = UnknownError()
|
error = UnknownError()
|
||||||
@ -110,9 +104,8 @@ class PlayHandler(AbstractHandler):
|
|||||||
|
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
|
||||||
async def __downloadSongsAndStore(self, songs: List[Song], processInfo: PlayerInfo) -> None:
|
async def __downloadSongsAndStore(self, songs: List[Song], playersManager: AbstractPlayersManager) -> None:
|
||||||
playlist = processInfo.getPlaylist()
|
playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
queue = processInfo.getQueueToPlayer()
|
|
||||||
playCommand = VCommands(VCommandsType.PLAY, None)
|
playCommand = VCommands(VCommandsType.PLAY, None)
|
||||||
tooManySongs = len(songs) > 100
|
tooManySongs = len(songs) > 100
|
||||||
|
|
||||||
@ -126,21 +119,18 @@ class PlayHandler(AbstractHandler):
|
|||||||
task = asyncio.create_task(self.__down.download_song(song))
|
task = asyncio.create_task(self.__down.download_song(song))
|
||||||
tasks.append(task)
|
tasks.append(task)
|
||||||
|
|
||||||
# In the original order, await for the task and then, if successfully downloaded, add to the playlist
|
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
|
||||||
for index, task in enumerate(tasks):
|
for index, task in enumerate(tasks):
|
||||||
await task
|
await task
|
||||||
song = songs[index]
|
song = songs[index]
|
||||||
if not song.problematic: # If downloaded add to the playlist and send play command
|
if not song.problematic: # If downloaded add to the playlist and send play command
|
||||||
processInfo = processManager.getOrCreatePlayerInfo(self.guild, self.ctx)
|
playerLock = playersManager.getPlayerLock(self.guild)
|
||||||
processLock = processInfo.getLock()
|
acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
||||||
acquired = processLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
|
||||||
if acquired:
|
if acquired:
|
||||||
playlist.add_song(song)
|
playlist.add_song(song)
|
||||||
self.putCommandInQueue(queue, playCommand)
|
playersManager.sendCommandToPlayer(playCommand, self.guild)
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
else:
|
else:
|
||||||
processManager.resetProcess(self.guild, self.ctx)
|
playersManager.resetPlayer(self.guild, self.ctx)
|
||||||
|
|
||||||
def __isUserConnected(self) -> bool:
|
def __isUserConnected(self) -> bool:
|
||||||
if self.ctx.author.voice:
|
if self.ctx.author.voice:
|
||||||
|
|||||||
@ -19,14 +19,13 @@ class PrevHandler(AbstractHandler):
|
|||||||
embed = self.embeds.NO_CHANNEL()
|
embed = self.embeds.NO_CHANNEL()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processInfo = processManager.getOrCreatePlayerInfo(self.guild, self.ctx)
|
if not playersManager.verifyIfPlayerExists(self.guild):
|
||||||
if not processInfo:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
embed = self.embeds.NOT_PLAYING()
|
||||||
error = BadCommandUsage()
|
error = BadCommandUsage()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
|
||||||
playlist = processInfo.getPlaylist()
|
playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
if len(playlist.getHistory()) == 0:
|
if len(playlist.getHistory()) == 0:
|
||||||
error = ImpossibleMove()
|
error = ImpossibleMove()
|
||||||
embed = self.embeds.NOT_PREVIOUS_SONG()
|
embed = self.embeds.NOT_PREVIOUS_SONG()
|
||||||
@ -37,15 +36,9 @@ class PrevHandler(AbstractHandler):
|
|||||||
embed = self.embeds.FAIL_DUE_TO_LOOP_ON()
|
embed = self.embeds.FAIL_DUE_TO_LOOP_ON()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
|
||||||
# If not started, start the player process
|
|
||||||
process = processInfo.getProcess()
|
|
||||||
if not process.is_alive():
|
|
||||||
process.start()
|
|
||||||
|
|
||||||
# Send a prev command, together with the user voice channel
|
# Send a prev command, together with the user voice channel
|
||||||
prevCommand = VCommands(VCommandsType.PREV, self.author.voice.channel.id)
|
prevCommand = VCommands(VCommandsType.PREV, self.author.voice.channel.id)
|
||||||
queue = processInfo.getQueueToPlayer()
|
playersManager.sendCommandToPlayer(prevCommand, self.guild)
|
||||||
self.putCommandInQueue(queue, prevCommand)
|
|
||||||
|
|
||||||
embed = self.embeds.RETURNING_SONG()
|
embed = self.embeds.RETURNING_SONG()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|||||||
@ -22,29 +22,27 @@ class QueueHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self, pageNumber=0) -> HandlerResponse:
|
async def run(self, pageNumber=0) -> HandlerResponse:
|
||||||
# Retrieve the process of the guild
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
if not playersManager.verifyIfPlayerExists(self.guild):
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
|
||||||
if not processInfo: # If no process return empty list
|
|
||||||
embed = self.embeds.EMPTY_QUEUE()
|
embed = self.embeds.EMPTY_QUEUE()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
# Acquire the Lock to manipulate the playlist
|
# Acquire the Lock to manipulate the playlist
|
||||||
processLock = processInfo.getLock()
|
playerLock = playersManager.getPlayerLock(self.guild)
|
||||||
acquired = processLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
||||||
if acquired:
|
if acquired:
|
||||||
playlist: Playlist = processInfo.getPlaylist()
|
playlist: Playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
|
|
||||||
if playlist.isLoopingOne():
|
if playlist.isLoopingOne():
|
||||||
song = playlist.getCurrentSong()
|
song = playlist.getCurrentSong()
|
||||||
embed = self.embeds.ONE_SONG_LOOPING(song.info)
|
embed = self.embeds.ONE_SONG_LOOPING(song.info)
|
||||||
processLock.release() # Release the Lock
|
playerLock.release() # Release the Lock
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
allSongs = playlist.getSongs()
|
allSongs = playlist.getSongs()
|
||||||
if len(allSongs) == 0:
|
if len(allSongs) == 0:
|
||||||
embed = self.embeds.EMPTY_QUEUE()
|
embed = self.embeds.EMPTY_QUEUE()
|
||||||
processLock.release() # Release the Lock
|
playerLock.release() # Release the Lock
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
songsPages = playlist.getSongsPages()
|
songsPages = playlist.getSongsPages()
|
||||||
@ -93,10 +91,10 @@ class QueueHandler(AbstractHandler):
|
|||||||
|
|
||||||
embed = self.embeds.QUEUE(title, text)
|
embed = self.embeds.QUEUE(title, text)
|
||||||
# Release the acquired Lock
|
# Release the acquired Lock
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
return HandlerResponse(self.ctx, embed, view=queueView)
|
return HandlerResponse(self.ctx, embed, view=queueView)
|
||||||
else:
|
else:
|
||||||
processManager.resetProcess(self.guild, self.ctx)
|
playersManager.resetPlayer(self.guild, self.ctx)
|
||||||
embed = self.embeds.PLAYER_RESTARTED()
|
embed = self.embeds.PLAYER_RESTARTED()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@ from Config.Exceptions import BadCommandUsage, VulkanError, ErrorRemoving, Inval
|
|||||||
from Music.Playlist import Playlist
|
from Music.Playlist import Playlist
|
||||||
from Music.VulkanBot import VulkanBot
|
from Music.VulkanBot import VulkanBot
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
from Parallelism.ProcessInfo import PlayerInfo
|
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from discord import Interaction
|
from discord import Interaction
|
||||||
|
|
||||||
@ -15,15 +14,13 @@ class RemoveHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self, position: str) -> HandlerResponse:
|
async def run(self, position: str) -> HandlerResponse:
|
||||||
# Get the current process of the guild
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
if not playersManager.verifyIfPlayerExists(self.guild):
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
|
||||||
if not processInfo:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
embed = self.embeds.NOT_PLAYING()
|
||||||
error = BadCommandUsage()
|
error = BadCommandUsage()
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
return HandlerResponse(self.ctx, embed, error)
|
||||||
|
|
||||||
playlist = processInfo.getPlaylist()
|
playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
if playlist is None:
|
if playlist is None:
|
||||||
embed = self.embeds.NOT_PLAYING()
|
embed = self.embeds.NOT_PLAYING()
|
||||||
error = BadCommandUsage()
|
error = BadCommandUsage()
|
||||||
|
|||||||
@ -2,7 +2,6 @@ from discord.ext.commands import Context
|
|||||||
from Handlers.AbstractHandler import AbstractHandler
|
from Handlers.AbstractHandler import AbstractHandler
|
||||||
from Handlers.HandlerResponse import HandlerResponse
|
from Handlers.HandlerResponse import HandlerResponse
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
from Parallelism.ProcessInfo import PlayerInfo, ProcessStatus
|
|
||||||
from Parallelism.Commands import VCommands, VCommandsType
|
from Parallelism.Commands import VCommands, VCommandsType
|
||||||
from Music.VulkanBot import VulkanBot
|
from Music.VulkanBot import VulkanBot
|
||||||
from typing import Union
|
from typing import Union
|
||||||
@ -14,18 +13,10 @@ class ResetHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self) -> HandlerResponse:
|
async def run(self) -> HandlerResponse:
|
||||||
# Get the current process of the guild
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
if playersManager.verifyIfPlayerExists(self.guild):
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
|
||||||
if processInfo:
|
|
||||||
if processInfo.getStatus() == ProcessStatus.SLEEPING:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
|
||||||
return HandlerResponse(self.ctx, embed)
|
|
||||||
|
|
||||||
command = VCommands(VCommandsType.RESET, None)
|
command = VCommands(VCommandsType.RESET, None)
|
||||||
queue = processInfo.getQueueToPlayer()
|
playersManager.sendCommandToPlayer(command, self.guild)
|
||||||
self.putCommandInQueue(queue, command)
|
|
||||||
|
|
||||||
return HandlerResponse(self.ctx)
|
return HandlerResponse(self.ctx)
|
||||||
else:
|
else:
|
||||||
embed = self.embeds.NOT_PLAYING()
|
embed = self.embeds.NOT_PLAYING()
|
||||||
|
|||||||
@ -2,7 +2,6 @@ from discord.ext.commands import Context
|
|||||||
from Handlers.AbstractHandler import AbstractHandler
|
from Handlers.AbstractHandler import AbstractHandler
|
||||||
from Handlers.HandlerResponse import HandlerResponse
|
from Handlers.HandlerResponse import HandlerResponse
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
from Parallelism.ProcessInfo import PlayerInfo, ProcessStatus
|
|
||||||
from Parallelism.Commands import VCommands, VCommandsType
|
from Parallelism.Commands import VCommands, VCommandsType
|
||||||
from Music.VulkanBot import VulkanBot
|
from Music.VulkanBot import VulkanBot
|
||||||
from typing import Union
|
from typing import Union
|
||||||
@ -14,18 +13,10 @@ class ResumeHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self) -> HandlerResponse:
|
async def run(self) -> HandlerResponse:
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
if playersManager.verifyIfPlayerExists(self.guild):
|
||||||
if processInfo:
|
|
||||||
if processInfo.getStatus() == ProcessStatus.SLEEPING:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
|
||||||
return HandlerResponse(self.ctx, embed)
|
|
||||||
|
|
||||||
# Send Resume command to be execute by player process
|
|
||||||
command = VCommands(VCommandsType.RESUME, None)
|
command = VCommands(VCommandsType.RESUME, None)
|
||||||
queue = processInfo.getQueueToPlayer()
|
playersManager.sendCommandToPlayer(command, self.guild)
|
||||||
self.putCommandInQueue(queue, command)
|
|
||||||
|
|
||||||
embed = self.embeds.PLAYER_RESUMED()
|
embed = self.embeds.PLAYER_RESUMED()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -14,19 +14,18 @@ class ShuffleHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self) -> HandlerResponse:
|
async def run(self) -> HandlerResponse:
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
if playersManager.verifyIfPlayerExists(self.guild):
|
||||||
if processInfo:
|
|
||||||
try:
|
try:
|
||||||
processLock = processInfo.getLock()
|
playerLock = playersManager.getPlayerLock(self.guild)
|
||||||
acquired = processLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
acquired = playerLock.acquire(timeout=self.config.ACQUIRE_LOCK_TIMEOUT)
|
||||||
if acquired:
|
if acquired:
|
||||||
playlist = processInfo.getPlaylist()
|
playlist = playersManager.getPlayerPlaylist(self.guild)
|
||||||
playlist.shuffle()
|
playlist.shuffle()
|
||||||
# Release the acquired Lock
|
# Release the acquired Lock
|
||||||
processLock.release()
|
playerLock.release()
|
||||||
else:
|
else:
|
||||||
processManager.resetProcess(self.guild, self.ctx)
|
playersManager.resetPlayer(self.guild, self.ctx)
|
||||||
embed = self.embeds.PLAYER_RESTARTED()
|
embed = self.embeds.PLAYER_RESTARTED()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
from discord.ext.commands import Context
|
from discord.ext.commands import Context
|
||||||
from Handlers.AbstractHandler import AbstractHandler
|
from Handlers.AbstractHandler import AbstractHandler
|
||||||
from Config.Exceptions import BadCommandUsage, ImpossibleMove
|
|
||||||
from Handlers.HandlerResponse import HandlerResponse
|
from Handlers.HandlerResponse import HandlerResponse
|
||||||
from Music.VulkanBot import VulkanBot
|
from Music.VulkanBot import VulkanBot
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
from Parallelism.ProcessInfo import PlayerInfo, ProcessStatus
|
|
||||||
from Parallelism.Commands import VCommands, VCommandsType
|
from Parallelism.Commands import VCommands, VCommandsType
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from discord import Interaction
|
from discord import Interaction
|
||||||
@ -15,31 +13,12 @@ class SkipHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self) -> HandlerResponse:
|
async def run(self) -> HandlerResponse:
|
||||||
if not self.__user_connected():
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
error = ImpossibleMove()
|
if playersManager.verifyIfPlayerExists(self.guild):
|
||||||
embed = self.embeds.NO_CHANNEL()
|
|
||||||
return HandlerResponse(self.ctx, embed, error)
|
|
||||||
|
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
|
||||||
if processInfo: # Verify if there is a running process
|
|
||||||
if processInfo.getStatus() == ProcessStatus.SLEEPING:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
|
||||||
return HandlerResponse(self.ctx, embed)
|
|
||||||
|
|
||||||
# Send a command to the player process to skip the music
|
|
||||||
command = VCommands(VCommandsType.SKIP, None)
|
command = VCommands(VCommandsType.SKIP, None)
|
||||||
queue = processInfo.getQueueToPlayer()
|
playersManager.sendCommandToPlayer(command, self.guild)
|
||||||
self.putCommandInQueue(queue, command)
|
|
||||||
|
|
||||||
embed = self.embeds.SKIPPING_SONG()
|
embed = self.embeds.SKIPPING_SONG()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
else:
|
else:
|
||||||
embed = self.embeds.NOT_PLAYING()
|
embed = self.embeds.NOT_PLAYING()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
|
|
||||||
def __user_connected(self) -> bool:
|
|
||||||
if self.author.voice:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|||||||
@ -3,7 +3,6 @@ from Handlers.AbstractHandler import AbstractHandler
|
|||||||
from Handlers.HandlerResponse import HandlerResponse
|
from Handlers.HandlerResponse import HandlerResponse
|
||||||
from Music.VulkanBot import VulkanBot
|
from Music.VulkanBot import VulkanBot
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
from Parallelism.ProcessInfo import PlayerInfo, ProcessStatus
|
|
||||||
from Parallelism.Commands import VCommands, VCommandsType
|
from Parallelism.Commands import VCommands, VCommandsType
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from discord import Interaction
|
from discord import Interaction
|
||||||
@ -14,18 +13,10 @@ class StopHandler(AbstractHandler):
|
|||||||
super().__init__(ctx, bot)
|
super().__init__(ctx, bot)
|
||||||
|
|
||||||
async def run(self) -> HandlerResponse:
|
async def run(self) -> HandlerResponse:
|
||||||
processManager: AbstractPlayersManager = self.config.getPlayersManager()
|
playersManager: AbstractPlayersManager = self.config.getPlayersManager()
|
||||||
processInfo = processManager.getRunningPlayerInfo(self.guild)
|
if playersManager.verifyIfPlayerExists(self.guild):
|
||||||
if processInfo:
|
|
||||||
if processInfo.getStatus() == ProcessStatus.SLEEPING:
|
|
||||||
embed = self.embeds.NOT_PLAYING()
|
|
||||||
return HandlerResponse(self.ctx, embed)
|
|
||||||
|
|
||||||
# Send command to player process stop
|
|
||||||
command = VCommands(VCommandsType.STOP, None)
|
command = VCommands(VCommandsType.STOP, None)
|
||||||
queue = processInfo.getQueueToPlayer()
|
playersManager.sendCommandToPlayer(command, self.guild)
|
||||||
self.putCommandInQueue(queue, command)
|
|
||||||
|
|
||||||
embed = self.embeds.STOPPING_PLAYER()
|
embed = self.embeds.STOPPING_PLAYER()
|
||||||
return HandlerResponse(self.ctx, embed)
|
return HandlerResponse(self.ctx, embed)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
from threading import Lock
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from discord.ext.commands import Context
|
from discord.ext.commands import Context
|
||||||
from discord import Guild, Interaction
|
from discord import Guild, Interaction
|
||||||
|
from Music.Playlist import Playlist
|
||||||
from Music.Song import Song
|
from Music.Song import Song
|
||||||
from Parallelism.ProcessInfo import PlayerInfo
|
from Parallelism.Commands import VCommands
|
||||||
|
|
||||||
|
|
||||||
class AbstractPlayersManager(ABC):
|
class AbstractPlayersManager(ABC):
|
||||||
@ -11,19 +13,33 @@ class AbstractPlayersManager(ABC):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def setPlayerInfo(self, guild: Guild, info: PlayerInfo):
|
def sendCommandToPlayer(self, command: VCommands, guild: Guild, forceCreation: bool = False, context: Union[Context, Interaction] = None):
|
||||||
|
"""If the forceCreation boolean is True, then the context must be provided for the Player to be created"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def getOrCreatePlayerInfo(self, guild: Guild, context: Union[Context, Interaction]) -> PlayerInfo:
|
def getPlayerPlaylist(self, guild: Guild) -> Playlist:
|
||||||
|
"""If there is a player process for the guild, then return the playlist of the guild"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def resetProcess(self, guild: Guild, context: Context) -> None:
|
def getPlayerLock(self, guild: Guild) -> Lock:
|
||||||
|
"""If there is a player process for the guild, then return the lock of the guild"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def getRunningPlayerInfo(self, guild: Guild) -> PlayerInfo:
|
def verifyIfPlayerExists(self, guild: Guild) -> bool:
|
||||||
|
"""Returns if a player for the guild exists"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def createPlayerForGuild(self, guild: Guild, context: Union[Context, Interaction]) -> None:
|
||||||
|
"""With the context information of a guild create a internal player for the guild"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def resetPlayer(self, guild: Guild, context: Context) -> None:
|
||||||
|
"""Tries to reset the player of the guild"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
|
|||||||
@ -32,7 +32,7 @@ class TimeoutClock:
|
|||||||
class PlayerProcess(Process):
|
class PlayerProcess(Process):
|
||||||
"""Process that will play songs, receive commands from the main process by a Queue"""
|
"""Process that will play songs, receive commands from the main process by a Queue"""
|
||||||
|
|
||||||
def __init__(self, name: str, playlist: Playlist, lock: Lock, queueToReceive: Queue, queueToSend: Queue, guildID: int, textID: int, voiceID: int, authorID: int) -> None:
|
def __init__(self, name: str, playlist: Playlist, lock: Lock, queueToReceive: Queue, queueToSend: Queue, guildID: int, voiceID: int) -> None:
|
||||||
"""
|
"""
|
||||||
Start a new process that will have his own bot instance
|
Start a new process that will have his own bot instance
|
||||||
Due to pickle serialization, no objects are stored, the values initialization are being made in the run method
|
Due to pickle serialization, no objects are stored, the values initialization are being made in the run method
|
||||||
@ -46,10 +46,8 @@ class PlayerProcess(Process):
|
|||||||
self.__semStopPlaying: Semaphore = None
|
self.__semStopPlaying: Semaphore = None
|
||||||
self.__loop: AbstractEventLoop = None
|
self.__loop: AbstractEventLoop = None
|
||||||
# Discord context ID
|
# Discord context ID
|
||||||
self.__textChannelID = textID
|
|
||||||
self.__guildID = guildID
|
self.__guildID = guildID
|
||||||
self.__voiceChannelID = voiceID
|
self.__voiceChannelID = voiceID
|
||||||
self.__authorID = authorID
|
|
||||||
# All information of discord context will be retrieved directly with discord API
|
# All information of discord context will be retrieved directly with discord API
|
||||||
self.__guild: Guild = None
|
self.__guild: Guild = None
|
||||||
self.__bot: VulkanBot = None
|
self.__bot: VulkanBot = None
|
||||||
@ -81,9 +79,6 @@ class PlayerProcess(Process):
|
|||||||
self.__bot = await self.__createBotInstance()
|
self.__bot = await self.__createBotInstance()
|
||||||
self.__guild = self.__bot.get_guild(self.__guildID)
|
self.__guild = self.__bot.get_guild(self.__guildID)
|
||||||
self.__voiceChannel = self.__bot.get_channel(self.__voiceChannelID)
|
self.__voiceChannel = self.__bot.get_channel(self.__voiceChannelID)
|
||||||
self.__textChannel = self.__bot.get_channel(self.__textChannelID)
|
|
||||||
self.__author = self.__bot.get_channel(self.__authorID)
|
|
||||||
self.__botMember = self.__getBotMember()
|
|
||||||
# Connect to voice Channel
|
# Connect to voice Channel
|
||||||
await self.__connectToVoiceChannel()
|
await self.__connectToVoiceChannel()
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,11 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from time import sleep, time
|
from time import time
|
||||||
from urllib.parse import parse_qs, urlparse
|
from urllib.parse import parse_qs, urlparse
|
||||||
from Music.VulkanInitializer import VulkanInitializer
|
from discord import VoiceClient
|
||||||
from discord import Member, VoiceClient
|
from asyncio import AbstractEventLoop
|
||||||
from asyncio import AbstractEventLoop, Semaphore
|
|
||||||
from threading import RLock, Thread
|
from threading import RLock, Thread
|
||||||
from multiprocessing import Lock
|
from multiprocessing import Lock
|
||||||
from typing import Callable, List
|
from typing import Callable
|
||||||
from discord import Guild, FFmpegPCMAudio, VoiceChannel
|
from discord import Guild, FFmpegPCMAudio, VoiceChannel
|
||||||
from Music.Playlist import Playlist
|
from Music.Playlist import Playlist
|
||||||
from Music.Song import Song
|
from Music.Song import Song
|
||||||
@ -32,7 +31,7 @@ class TimeoutClock:
|
|||||||
class PlayerThread(Thread):
|
class PlayerThread(Thread):
|
||||||
"""Player Thread to control the song playback in the same Process of the Main Process"""
|
"""Player Thread to control the song playback in the same Process of the Main Process"""
|
||||||
|
|
||||||
def __init__(self, bot: VulkanBot, guild: Guild, name: str, voiceChannel: VoiceChannel, playlist: Playlist, lock: Lock, guildID: int, textID: int, voiceID: int, authorID: int) -> None:
|
def __init__(self, bot: VulkanBot, guild: Guild, name: str, voiceChannel: VoiceChannel, playlist: Playlist, lock: Lock, guildID: int, voiceID: int) -> None:
|
||||||
Thread.__init__(self, name=name, group=None, target=None, args=(), kwargs={})
|
Thread.__init__(self, name=name, group=None, target=None, args=(), kwargs={})
|
||||||
# Synchronization objects
|
# Synchronization objects
|
||||||
self.__playlist: Playlist = playlist
|
self.__playlist: Playlist = playlist
|
||||||
|
|||||||
@ -3,8 +3,8 @@ from discord import Button, TextChannel
|
|||||||
from discord.ui import View
|
from discord.ui import View
|
||||||
from Config.Emojis import VEmojis
|
from Config.Emojis import VEmojis
|
||||||
from Messages.MessagesCategory import MessagesCategory
|
from Messages.MessagesCategory import MessagesCategory
|
||||||
|
from Music.Playlist import Playlist
|
||||||
from Music.VulkanBot import VulkanBot
|
from Music.VulkanBot import VulkanBot
|
||||||
from Parallelism.ProcessInfo import PlayerInfo
|
|
||||||
from Config.Messages import Messages
|
from Config.Messages import Messages
|
||||||
from Music.Song import Song
|
from Music.Song import Song
|
||||||
from Config.Embeds import VEmbeds
|
from Config.Embeds import VEmbeds
|
||||||
@ -29,9 +29,9 @@ class ProcessCommandsExecutor:
|
|||||||
self.__embeds = VEmbeds()
|
self.__embeds = VEmbeds()
|
||||||
self.__emojis = VEmojis()
|
self.__emojis = VEmojis()
|
||||||
|
|
||||||
async def sendNowPlaying(self, processInfo: PlayerInfo, song: Song) -> None:
|
async def sendNowPlaying(self, playlist: Playlist, channel: TextChannel, song: Song) -> None:
|
||||||
|
print('B')
|
||||||
# Get the lock of the playlist
|
# Get the lock of the playlist
|
||||||
playlist = processInfo.getPlaylist()
|
|
||||||
if playlist.isLoopingOne():
|
if playlist.isLoopingOne():
|
||||||
title = self.__messages.ONE_SONG_LOOPING
|
title = self.__messages.ONE_SONG_LOOPING
|
||||||
else:
|
else:
|
||||||
@ -39,7 +39,6 @@ class ProcessCommandsExecutor:
|
|||||||
|
|
||||||
# Create View and Embed
|
# Create View and Embed
|
||||||
embed = self.__embeds.SONG_INFO(song.info, title)
|
embed = self.__embeds.SONG_INFO(song.info, title)
|
||||||
channel = processInfo.getTextChannel()
|
|
||||||
view = self.__getPlayerView(channel)
|
view = self.__getPlayerView(channel)
|
||||||
# Send Message and add to the MessagesManager
|
# Send Message and add to the MessagesManager
|
||||||
message = await channel.send(embed=embed, view=view)
|
message = await channel.send(embed=embed, view=view)
|
||||||
|
|||||||
@ -1,51 +0,0 @@
|
|||||||
from enum import Enum
|
|
||||||
from multiprocessing import Process, Queue, Lock
|
|
||||||
from discord import TextChannel
|
|
||||||
from Music.Playlist import Playlist
|
|
||||||
|
|
||||||
|
|
||||||
class ProcessStatus(Enum):
|
|
||||||
RUNNING = 'Running'
|
|
||||||
SLEEPING = 'Sleeping'
|
|
||||||
|
|
||||||
|
|
||||||
class PlayerInfo:
|
|
||||||
"""
|
|
||||||
Class to store the reference to all structures to maintain a song player
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, process: Process, queueToPlayer: Queue, queueToMain: Queue, playlist: Playlist, lock: Lock, textChannel: TextChannel) -> None:
|
|
||||||
self.__process = process
|
|
||||||
self.__queueToPlayer = queueToPlayer
|
|
||||||
self.__queueToMain = queueToMain
|
|
||||||
self.__playlist = playlist
|
|
||||||
self.__lock = lock
|
|
||||||
self.__textChannel = textChannel
|
|
||||||
self.__status = ProcessStatus.RUNNING
|
|
||||||
|
|
||||||
def setProcess(self, newProcess: Process) -> None:
|
|
||||||
self.__process = newProcess
|
|
||||||
|
|
||||||
def getStatus(self) -> ProcessStatus:
|
|
||||||
return self.__status
|
|
||||||
|
|
||||||
def setStatus(self, status: ProcessStatus) -> None:
|
|
||||||
self.__status = status
|
|
||||||
|
|
||||||
def getProcess(self) -> Process:
|
|
||||||
return self.__process
|
|
||||||
|
|
||||||
def getQueueToPlayer(self) -> Queue:
|
|
||||||
return self.__queueToPlayer
|
|
||||||
|
|
||||||
def getQueueToMain(self) -> Queue:
|
|
||||||
return self.__queueToMain
|
|
||||||
|
|
||||||
def getPlaylist(self) -> Playlist:
|
|
||||||
return self.__playlist
|
|
||||||
|
|
||||||
def getLock(self) -> Lock:
|
|
||||||
return self.__lock
|
|
||||||
|
|
||||||
def getTextChannel(self) -> TextChannel:
|
|
||||||
return self.__textChannel
|
|
||||||
@ -1,23 +1,70 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from multiprocessing import Lock, Queue
|
from enum import Enum
|
||||||
|
from multiprocessing import Lock, Process, Queue
|
||||||
from multiprocessing.managers import BaseManager, NamespaceProxy
|
from multiprocessing.managers import BaseManager, NamespaceProxy
|
||||||
from queue import Empty
|
from queue import Empty
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from typing import Dict, Tuple, Union
|
from typing import Dict, Tuple, Union
|
||||||
from Config.Singleton import Singleton
|
from Config.Singleton import Singleton
|
||||||
from discord import Guild, Interaction
|
from discord import Guild, Interaction, TextChannel
|
||||||
from discord.ext.commands import Context
|
from discord.ext.commands import Context
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
from Parallelism.ProcessExecutor import ProcessCommandsExecutor
|
from Parallelism.ProcessExecutor import ProcessCommandsExecutor
|
||||||
from Music.Song import Song
|
from Music.Song import Song
|
||||||
from Parallelism.PlayerProcess import PlayerProcess
|
from Parallelism.PlayerProcess import PlayerProcess
|
||||||
from Music.Playlist import Playlist
|
from Music.Playlist import Playlist
|
||||||
from Parallelism.ProcessInfo import PlayerInfo, ProcessStatus
|
|
||||||
from Parallelism.Commands import VCommands, VCommandsType
|
from Parallelism.Commands import VCommands, VCommandsType
|
||||||
from Music.VulkanBot import VulkanBot
|
from Music.VulkanBot import VulkanBot
|
||||||
|
|
||||||
|
|
||||||
class ProcessManager(Singleton, AbstractPlayersManager):
|
class ProcessStatus(Enum):
|
||||||
|
RUNNING = 'Running'
|
||||||
|
SLEEPING = 'Sleeping'
|
||||||
|
|
||||||
|
|
||||||
|
class PlayerProcessInfo:
|
||||||
|
"""
|
||||||
|
Class to store the reference to all structures to maintain a process player
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, process: Process, queueToPlayer: Queue, queueToMain: Queue, playlist: Playlist, lock: Lock, textChannel: TextChannel) -> None:
|
||||||
|
self.__process = process
|
||||||
|
self.__queueToPlayer = queueToPlayer
|
||||||
|
self.__queueToMain = queueToMain
|
||||||
|
self.__playlist = playlist
|
||||||
|
self.__lock = lock
|
||||||
|
self.__textChannel = textChannel
|
||||||
|
self.__status = ProcessStatus.RUNNING
|
||||||
|
|
||||||
|
def setProcess(self, newProcess: Process) -> None:
|
||||||
|
self.__process = newProcess
|
||||||
|
|
||||||
|
def getStatus(self) -> ProcessStatus:
|
||||||
|
return self.__status
|
||||||
|
|
||||||
|
def setStatus(self, status: ProcessStatus) -> None:
|
||||||
|
self.__status = status
|
||||||
|
|
||||||
|
def getProcess(self) -> Process:
|
||||||
|
return self.__process
|
||||||
|
|
||||||
|
def getQueueToPlayer(self) -> Queue:
|
||||||
|
return self.__queueToPlayer
|
||||||
|
|
||||||
|
def getQueueToMain(self) -> Queue:
|
||||||
|
return self.__queueToMain
|
||||||
|
|
||||||
|
def getPlaylist(self) -> Playlist:
|
||||||
|
return self.__playlist
|
||||||
|
|
||||||
|
def getLock(self) -> Lock:
|
||||||
|
return self.__lock
|
||||||
|
|
||||||
|
def getTextChannel(self) -> TextChannel:
|
||||||
|
return self.__textChannel
|
||||||
|
|
||||||
|
|
||||||
|
class ProcessPlayerManager(Singleton, AbstractPlayersManager):
|
||||||
"""
|
"""
|
||||||
Manage all running player process, creating and storing them for future calls
|
Manage all running player process, creating and storing them for future calls
|
||||||
Deals with the creation of shared memory
|
Deals with the creation of shared memory
|
||||||
@ -29,28 +76,51 @@ class ProcessManager(Singleton, AbstractPlayersManager):
|
|||||||
VManager.register('Playlist', Playlist)
|
VManager.register('Playlist', Playlist)
|
||||||
self.__manager = VManager()
|
self.__manager = VManager()
|
||||||
self.__manager.start()
|
self.__manager.start()
|
||||||
self.__playersProcess: Dict[int, PlayerInfo] = {}
|
self.__playersProcess: Dict[int, PlayerProcessInfo] = {}
|
||||||
self.__playersListeners: Dict[int, Tuple[Thread, bool]] = {}
|
self.__playersListeners: Dict[int, Tuple[Thread, bool]] = {}
|
||||||
self.__playersCommandsExecutor: Dict[int, ProcessCommandsExecutor] = {}
|
self.__playersCommandsExecutor: Dict[int, ProcessCommandsExecutor] = {}
|
||||||
|
|
||||||
def setPlayerInfo(self, guild: Guild, info: PlayerInfo):
|
def sendCommandToPlayer(self, command: VCommands, guild: Guild, forceCreation: bool = False, context: Union[Context, Interaction] = None):
|
||||||
self.__playersProcess[guild.id] = info
|
if forceCreation:
|
||||||
|
processInfo = self.createPlayerForGuild(guild, context)
|
||||||
|
else:
|
||||||
|
processInfo = self.__getRunningPlayerInfo(guild)
|
||||||
|
|
||||||
def getOrCreatePlayerInfo(self, guild: Guild, context: Union[Context, Interaction]) -> PlayerInfo:
|
if processInfo == None:
|
||||||
"""Return the process info for the guild, the user in context must be connected to a voice_channel"""
|
return
|
||||||
|
|
||||||
|
queue = processInfo.getQueueToPlayer()
|
||||||
|
self.__putCommandInQueue(queue, command)
|
||||||
|
|
||||||
|
def getPlayerPlaylist(self, guild: Guild) -> Playlist:
|
||||||
|
playerInfo = self.__getRunningPlayerInfo(guild)
|
||||||
|
if playerInfo:
|
||||||
|
return playerInfo.getPlaylist()
|
||||||
|
|
||||||
|
def getPlayerLock(self, guild: Guild) -> Lock:
|
||||||
|
playerInfo = self.__getRunningPlayerInfo(guild)
|
||||||
|
if playerInfo:
|
||||||
|
return playerInfo.getLock()
|
||||||
|
|
||||||
|
def verifyIfPlayerExists(self, guild: Guild) -> bool:
|
||||||
|
return guild.id in self.__playersProcess.keys()
|
||||||
|
|
||||||
|
def createPlayerForGuild(self, guild: Guild, context: Union[Context, Interaction]) -> None:
|
||||||
try:
|
try:
|
||||||
if guild.id not in self.__playersProcess.keys():
|
if guild.id not in self.__playersProcess.keys():
|
||||||
self.__playersProcess[guild.id] = self.__createProcessInfo(guild, context)
|
self.__playersProcess[guild.id] = self.__createProcessPlayerInfo(guild, context)
|
||||||
else:
|
else:
|
||||||
# If the process has ended create a new one
|
# If the process has ended create a new one
|
||||||
if not self.__playersProcess[guild.id].getProcess().is_alive():
|
if not self.__playersProcess[guild.id].getProcess().is_alive():
|
||||||
self.__playersProcess[guild.id] = self.__recreateProcess(guild, context)
|
self.__playersProcess[guild.id] = self.__recreateProcess(guild, context)
|
||||||
|
|
||||||
|
# Start the process
|
||||||
|
self.__playersProcess[guild.id].getProcess().start()
|
||||||
return self.__playersProcess[guild.id]
|
return self.__playersProcess[guild.id]
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'[Error In GetPlayerContext] -> {e}')
|
print(f'[Error In GetPlayerContext] -> {e}')
|
||||||
|
|
||||||
def resetProcess(self, guild: Guild, context: Context) -> None:
|
def resetPlayer(self, guild: Guild, context: Context) -> None:
|
||||||
"""Restart a running process, already start it to return to play"""
|
"""Restart a running process, already start it to return to play"""
|
||||||
if guild.id not in self.__playersProcess.keys():
|
if guild.id not in self.__playersProcess.keys():
|
||||||
return None
|
return None
|
||||||
@ -60,10 +130,10 @@ class ProcessManager(Singleton, AbstractPlayersManager):
|
|||||||
newProcessInfo.getProcess().start() # Start the process
|
newProcessInfo.getProcess().start() # Start the process
|
||||||
# Send a command to start the play again
|
# Send a command to start the play again
|
||||||
playCommand = VCommands(VCommandsType.PLAY)
|
playCommand = VCommands(VCommandsType.PLAY)
|
||||||
newProcessInfo.getQueueToPlayer().put(playCommand)
|
self.__putCommandInQueue(newProcessInfo.getQueueToPlayer(), playCommand)
|
||||||
self.__playersProcess[guild.id] = newProcessInfo
|
self.__playersProcess[guild.id] = newProcessInfo
|
||||||
|
|
||||||
def getRunningPlayerInfo(self, guild: Guild) -> PlayerInfo:
|
def __getRunningPlayerInfo(self, guild: Guild) -> PlayerProcessInfo:
|
||||||
"""Return the process info for the guild, if not, return None"""
|
"""Return the process info for the guild, if not, return None"""
|
||||||
if guild.id not in self.__playersProcess.keys():
|
if guild.id not in self.__playersProcess.keys():
|
||||||
print('Process Info not found')
|
print('Process Info not found')
|
||||||
@ -71,7 +141,7 @@ class ProcessManager(Singleton, AbstractPlayersManager):
|
|||||||
|
|
||||||
return self.__playersProcess[guild.id]
|
return self.__playersProcess[guild.id]
|
||||||
|
|
||||||
def __createProcessInfo(self, guild: Guild, context: Context) -> PlayerInfo:
|
def __createProcessPlayerInfo(self, guild: Guild, context: Context) -> PlayerProcessInfo:
|
||||||
guildID: int = context.guild.id
|
guildID: int = context.guild.id
|
||||||
textID: int = context.channel.id
|
textID: int = context.channel.id
|
||||||
voiceID: int = context.author.voice.channel.id
|
voiceID: int = context.author.voice.channel.id
|
||||||
@ -82,8 +152,8 @@ class ProcessManager(Singleton, AbstractPlayersManager):
|
|||||||
queueToListen = Queue()
|
queueToListen = Queue()
|
||||||
queueToSend = Queue()
|
queueToSend = Queue()
|
||||||
process = PlayerProcess(context.guild.name, playlist, lock, queueToSend,
|
process = PlayerProcess(context.guild.name, playlist, lock, queueToSend,
|
||||||
queueToListen, guildID, textID, voiceID, authorID)
|
queueToListen, guildID, voiceID)
|
||||||
processInfo = PlayerInfo(process, queueToSend, queueToListen,
|
processInfo = PlayerProcessInfo(process, queueToSend, queueToListen,
|
||||||
playlist, lock, context.channel)
|
playlist, lock, context.channel)
|
||||||
|
|
||||||
# Create a Thread to listen for the queue coming from the Player Process, this will redirect the Queue to a async
|
# Create a Thread to listen for the queue coming from the Player Process, this will redirect the Queue to a async
|
||||||
@ -111,7 +181,7 @@ class ProcessManager(Singleton, AbstractPlayersManager):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'[ERROR STOPPING PROCESS] -> {e}')
|
print(f'[ERROR STOPPING PROCESS] -> {e}')
|
||||||
|
|
||||||
def __recreateProcess(self, guild: Guild, context: Union[Context, Interaction]) -> PlayerInfo:
|
def __recreateProcess(self, guild: Guild, context: Union[Context, Interaction]) -> PlayerProcessInfo:
|
||||||
"""Create a new process info using previous playlist"""
|
"""Create a new process info using previous playlist"""
|
||||||
self.__stopPossiblyRunningProcess(guild)
|
self.__stopPossiblyRunningProcess(guild)
|
||||||
|
|
||||||
@ -130,7 +200,7 @@ class ProcessManager(Singleton, AbstractPlayersManager):
|
|||||||
queueToSend = Queue()
|
queueToSend = Queue()
|
||||||
process = PlayerProcess(context.guild.name, playlist, lock, queueToSend,
|
process = PlayerProcess(context.guild.name, playlist, lock, queueToSend,
|
||||||
queueToListen, guildID, textID, voiceID, authorID)
|
queueToListen, guildID, textID, voiceID, authorID)
|
||||||
processInfo = PlayerInfo(process, queueToSend, queueToListen,
|
processInfo = PlayerProcessInfo(process, queueToSend, queueToListen,
|
||||||
playlist, lock, context.channel)
|
playlist, lock, context.channel)
|
||||||
|
|
||||||
# Create a Thread to listen for the queue coming from the Player Process, this will redirect the Queue to a async
|
# Create a Thread to listen for the queue coming from the Player Process, this will redirect the Queue to a async
|
||||||
@ -191,10 +261,18 @@ class ProcessManager(Singleton, AbstractPlayersManager):
|
|||||||
# Set the status of this process as sleeping, only the playlist object remains
|
# Set the status of this process as sleeping, only the playlist object remains
|
||||||
self.__playersProcess[guildID].setStatus(ProcessStatus.SLEEPING)
|
self.__playersProcess[guildID].setStatus(ProcessStatus.SLEEPING)
|
||||||
|
|
||||||
|
def __putCommandInQueue(self, queue: Queue, command: VCommands) -> None:
|
||||||
|
try:
|
||||||
|
queue.put(command)
|
||||||
|
except Exception as e:
|
||||||
|
print(f'[ERROR PUTTING COMMAND IN QUEUE] -> {e}')
|
||||||
|
|
||||||
async def showNowPlaying(self, guildID: int, song: Song) -> None:
|
async def showNowPlaying(self, guildID: int, song: Song) -> None:
|
||||||
commandExecutor = self.__playersCommandsExecutor[guildID]
|
commandExecutor = self.__playersCommandsExecutor[guildID]
|
||||||
processInfo = self.__playersProcess[guildID]
|
processInfo = self.__playersProcess[guildID]
|
||||||
|
print('A')
|
||||||
await commandExecutor.sendNowPlaying(processInfo, song)
|
await commandExecutor.sendNowPlaying(processInfo, song)
|
||||||
|
print('C')
|
||||||
|
|
||||||
|
|
||||||
class VManager(BaseManager):
|
class VManager(BaseManager):
|
||||||
|
|||||||
@ -1,199 +0,0 @@
|
|||||||
import asyncio
|
|
||||||
from multiprocessing import Lock, Queue
|
|
||||||
from multiprocessing.managers import BaseManager, NamespaceProxy
|
|
||||||
from queue import Empty
|
|
||||||
from threading import Thread
|
|
||||||
from typing import Dict, Tuple, Union
|
|
||||||
from Config.Singleton import Singleton
|
|
||||||
from discord import Guild, Interaction
|
|
||||||
from discord.ext.commands import Context
|
|
||||||
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
|
||||||
from Parallelism.ProcessExecutor import ProcessCommandsExecutor
|
|
||||||
from Music.Song import Song
|
|
||||||
from Parallelism.PlayerProcess import PlayerProcess
|
|
||||||
from Music.Playlist import Playlist
|
|
||||||
from Parallelism.ProcessInfo import PlayerInfo, ProcessStatus
|
|
||||||
from Parallelism.Commands import VCommands, VCommandsType
|
|
||||||
from Music.VulkanBot import VulkanBot
|
|
||||||
|
|
||||||
|
|
||||||
class ThreadManager(Singleton, AbstractPlayersManager):
|
|
||||||
"""
|
|
||||||
Manage all running player threads, creating and storing them for future calls
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, bot: VulkanBot = None) -> None:
|
|
||||||
if not super().created:
|
|
||||||
self.__bot = bot
|
|
||||||
self.__playersProcess: Dict[int, Thread] = {}
|
|
||||||
|
|
||||||
def setPlayerInfo(self, guild: Guild, info: PlayerInfo):
|
|
||||||
self.__playersProcess[guild.id] = info
|
|
||||||
|
|
||||||
def getOrCreatePlayerInfo(self, guild: Guild, context: Union[Context, Interaction]) -> PlayerInfo:
|
|
||||||
"""Return the process info for the guild, the user in context must be connected to a voice_channel"""
|
|
||||||
try:
|
|
||||||
if guild.id not in self.__playersProcess.keys():
|
|
||||||
self.__playersProcess[guild.id] = self.__createProcessInfo(guild, context)
|
|
||||||
else:
|
|
||||||
# If the process has ended create a new one
|
|
||||||
if not self.__playersProcess[guild.id].getProcess().is_alive():
|
|
||||||
self.__playersProcess[guild.id] = self.__recreateProcess(guild, context)
|
|
||||||
|
|
||||||
return self.__playersProcess[guild.id]
|
|
||||||
except Exception as e:
|
|
||||||
print(f'[Error In GetPlayerContext] -> {e}')
|
|
||||||
|
|
||||||
def resetProcess(self, guild: Guild, context: Context) -> None:
|
|
||||||
"""Restart a running process, already start it to return to play"""
|
|
||||||
if guild.id not in self.__playersProcess.keys():
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Recreate the process keeping the playlist
|
|
||||||
newProcessInfo = self.__recreateProcess(guild, context)
|
|
||||||
newProcessInfo.getProcess().start() # Start the process
|
|
||||||
# Send a command to start the play again
|
|
||||||
playCommand = VCommands(VCommandsType.PLAY)
|
|
||||||
newProcessInfo.getQueueToPlayer().put(playCommand)
|
|
||||||
self.__playersProcess[guild.id] = newProcessInfo
|
|
||||||
|
|
||||||
def getRunningPlayerInfo(self, guild: Guild) -> PlayerInfo:
|
|
||||||
"""Return the process info for the guild, if not, return None"""
|
|
||||||
if guild.id not in self.__playersProcess.keys():
|
|
||||||
print('Process Info not found')
|
|
||||||
return None
|
|
||||||
|
|
||||||
return self.__playersProcess[guild.id]
|
|
||||||
|
|
||||||
def __createProcessInfo(self, guild: Guild, context: Context) -> PlayerInfo:
|
|
||||||
guildID: int = context.guild.id
|
|
||||||
textID: int = context.channel.id
|
|
||||||
voiceID: int = context.author.voice.channel.id
|
|
||||||
authorID: int = context.author.id
|
|
||||||
|
|
||||||
playlist: Playlist = self.__manager.Playlist()
|
|
||||||
lock = Lock()
|
|
||||||
queueToListen = Queue()
|
|
||||||
queueToSend = Queue()
|
|
||||||
process = PlayerProcess(context.guild.name, playlist, lock, queueToSend,
|
|
||||||
queueToListen, guildID, textID, voiceID, authorID)
|
|
||||||
processInfo = PlayerInfo(process, queueToSend, queueToListen,
|
|
||||||
playlist, lock, context.channel)
|
|
||||||
|
|
||||||
# Create a Thread to listen for the queue coming from the Player Process, this will redirect the Queue to a async
|
|
||||||
thread = Thread(target=self.__listenToCommands,
|
|
||||||
args=(queueToListen, guild), daemon=True)
|
|
||||||
self.__playersListeners[guildID] = (thread, False)
|
|
||||||
thread.start()
|
|
||||||
|
|
||||||
# Create a Message Controller for this player
|
|
||||||
self.__playersCommandsExecutor[guildID] = ProcessCommandsExecutor(self.__bot, guildID)
|
|
||||||
|
|
||||||
return processInfo
|
|
||||||
|
|
||||||
def __stopPossiblyRunningProcess(self, guild: Guild):
|
|
||||||
try:
|
|
||||||
if guild.id in self.__playersProcess.keys():
|
|
||||||
playerProcess = self.__playersProcess[guild.id]
|
|
||||||
process = playerProcess.getProcess()
|
|
||||||
process.close()
|
|
||||||
process.kill()
|
|
||||||
playerProcess.getQueueToMain().close()
|
|
||||||
playerProcess.getQueueToMain().join_thread()
|
|
||||||
playerProcess.getQueueToPlayer().close()
|
|
||||||
playerProcess.getQueueToPlayer().join_thread()
|
|
||||||
except Exception as e:
|
|
||||||
print(f'[ERROR STOPPING PROCESS] -> {e}')
|
|
||||||
|
|
||||||
def __recreateProcess(self, guild: Guild, context: Union[Context, Interaction]) -> PlayerInfo:
|
|
||||||
"""Create a new process info using previous playlist"""
|
|
||||||
self.__stopPossiblyRunningProcess(guild)
|
|
||||||
|
|
||||||
guildID: int = context.guild.id
|
|
||||||
textID: int = context.channel.id
|
|
||||||
if isinstance(context, Interaction):
|
|
||||||
authorID: int = context.user.id
|
|
||||||
voiceID: int = context.user.voice.channel.id
|
|
||||||
else:
|
|
||||||
authorID: int = context.author.id
|
|
||||||
voiceID: int = context.author.voice.channel.id
|
|
||||||
|
|
||||||
playlist: Playlist = self.__playersProcess[guildID].getPlaylist()
|
|
||||||
lock = Lock()
|
|
||||||
queueToListen = Queue()
|
|
||||||
queueToSend = Queue()
|
|
||||||
process = PlayerProcess(context.guild.name, playlist, lock, queueToSend,
|
|
||||||
queueToListen, guildID, textID, voiceID, authorID)
|
|
||||||
processInfo = PlayerInfo(process, queueToSend, queueToListen,
|
|
||||||
playlist, lock, context.channel)
|
|
||||||
|
|
||||||
# Create a Thread to listen for the queue coming from the Player Process, this will redirect the Queue to a async
|
|
||||||
thread = Thread(target=self.__listenToCommands,
|
|
||||||
args=(queueToListen, guild), daemon=True)
|
|
||||||
self.__playersListeners[guildID] = (thread, False)
|
|
||||||
thread.start()
|
|
||||||
|
|
||||||
return processInfo
|
|
||||||
|
|
||||||
def __listenToCommands(self, queue: Queue, guild: Guild) -> None:
|
|
||||||
guildID = guild.id
|
|
||||||
while True:
|
|
||||||
shouldEnd = self.__playersListeners[guildID][1]
|
|
||||||
if shouldEnd:
|
|
||||||
break
|
|
||||||
|
|
||||||
try:
|
|
||||||
command: VCommands = queue.get(timeout=5)
|
|
||||||
commandType = command.getType()
|
|
||||||
args = command.getArgs()
|
|
||||||
|
|
||||||
print(f'Process {guild.name} sended command {commandType}')
|
|
||||||
if commandType == VCommandsType.NOW_PLAYING:
|
|
||||||
asyncio.run_coroutine_threadsafe(self.showNowPlaying(
|
|
||||||
guild.id, args), self.__bot.loop)
|
|
||||||
elif commandType == VCommandsType.TERMINATE:
|
|
||||||
# Delete the process elements and return, to finish task
|
|
||||||
self.__terminateProcess(guildID)
|
|
||||||
return
|
|
||||||
elif commandType == VCommandsType.SLEEPING:
|
|
||||||
# The process might be used again
|
|
||||||
self.__sleepingProcess(guildID)
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
print(f'[ERROR] -> Unknown Command Received from Process: {commandType}')
|
|
||||||
except Empty:
|
|
||||||
continue
|
|
||||||
except Exception as e:
|
|
||||||
print(f'[ERROR IN LISTENING PROCESS] -> {guild.name} - {e}')
|
|
||||||
|
|
||||||
def __terminateProcess(self, guildID: int) -> None:
|
|
||||||
# Delete all structures associated with the Player
|
|
||||||
del self.__playersProcess[guildID]
|
|
||||||
del self.__playersCommandsExecutor[guildID]
|
|
||||||
threadListening = self.__playersListeners[guildID]
|
|
||||||
threadListening._stop()
|
|
||||||
del self.__playersListeners[guildID]
|
|
||||||
|
|
||||||
def __sleepingProcess(self, guildID: int) -> None:
|
|
||||||
# Disable all process structures, except Playlist
|
|
||||||
queue1 = self.__playersProcess[guildID].getQueueToMain()
|
|
||||||
queue2 = self.__playersProcess[guildID].getQueueToPlayer()
|
|
||||||
queue1.close()
|
|
||||||
queue1.join_thread()
|
|
||||||
queue2.close()
|
|
||||||
queue2.join_thread()
|
|
||||||
# Set the status of this process as sleeping, only the playlist object remains
|
|
||||||
self.__playersProcess[guildID].setStatus(ProcessStatus.SLEEPING)
|
|
||||||
|
|
||||||
async def showNowPlaying(self, guildID: int, song: Song) -> None:
|
|
||||||
commandExecutor = self.__playersCommandsExecutor[guildID]
|
|
||||||
processInfo = self.__playersProcess[guildID]
|
|
||||||
await commandExecutor.sendNowPlaying(processInfo, song)
|
|
||||||
|
|
||||||
|
|
||||||
class VManager(BaseManager):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class VProxy(NamespaceProxy):
|
|
||||||
_exposed_ = ('__getattribute__', '__setattr__', '__delattr__')
|
|
||||||
131
Parallelism/ThreadPlayerManager.py
Normal file
131
Parallelism/ThreadPlayerManager.py
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
from multiprocessing import Lock
|
||||||
|
from typing import Dict, Union
|
||||||
|
from Config.Singleton import Singleton
|
||||||
|
from discord import Guild, Interaction, TextChannel
|
||||||
|
from discord.ext.commands import Context
|
||||||
|
from Parallelism.AbstractProcessManager import AbstractPlayersManager
|
||||||
|
from Music.Song import Song
|
||||||
|
from Music.Playlist import Playlist
|
||||||
|
from Parallelism.Commands import VCommands, VCommandsType
|
||||||
|
from Music.VulkanBot import VulkanBot
|
||||||
|
from Parallelism.PlayerThread import PlayerThread
|
||||||
|
|
||||||
|
|
||||||
|
class PlayerThreadInfo:
|
||||||
|
"""
|
||||||
|
Class to store the reference to all structures to maintain a player thread
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, thread: PlayerThread, playlist: Playlist, lock: Lock, textChannel: TextChannel) -> None:
|
||||||
|
self.__thread = thread
|
||||||
|
self.__playlist = playlist
|
||||||
|
self.__lock = lock
|
||||||
|
self.__textChannel = textChannel
|
||||||
|
|
||||||
|
def getThread(self) -> PlayerThread:
|
||||||
|
return self.__thread
|
||||||
|
|
||||||
|
def getPlaylist(self) -> Playlist:
|
||||||
|
return self.__playlist
|
||||||
|
|
||||||
|
def getLock(self) -> Lock:
|
||||||
|
return self.__lock
|
||||||
|
|
||||||
|
def getTextChannel(self) -> TextChannel:
|
||||||
|
return self.__textChannel
|
||||||
|
|
||||||
|
|
||||||
|
class ThreadPlayerManager(Singleton, AbstractPlayersManager):
|
||||||
|
"""
|
||||||
|
Manage all running player threads, creating and storing them for future calls
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, bot: VulkanBot = None) -> None:
|
||||||
|
if not super().created:
|
||||||
|
self.__bot = bot
|
||||||
|
self.__playersThreads: Dict[int, PlayerThreadInfo] = {}
|
||||||
|
|
||||||
|
def sendCommandToPlayer(self, command: VCommands, guild: Guild, forceCreation: bool = False, context: Union[Context, Interaction] = None):
|
||||||
|
return super().sendCommandToPlayer(command, guild, forceCreation, context)
|
||||||
|
|
||||||
|
def getPlayerPlaylist(self, guild: Guild) -> Playlist:
|
||||||
|
playerInfo = self.__getRunningPlayerInfo(guild)
|
||||||
|
if playerInfo:
|
||||||
|
return playerInfo.getPlaylist()
|
||||||
|
|
||||||
|
def getPlayerLock(self, guild: Guild) -> Lock:
|
||||||
|
playerInfo = self.__getRunningPlayerInfo(guild)
|
||||||
|
if playerInfo:
|
||||||
|
return playerInfo.getLock()
|
||||||
|
|
||||||
|
def verifyIfPlayerExists(self, guild: Guild) -> bool:
|
||||||
|
return guild.id in self.__playersThreads.keys()
|
||||||
|
|
||||||
|
def createPlayerForGuild(self, guild: Guild, context: Union[Context, Interaction]):
|
||||||
|
try:
|
||||||
|
if guild.id not in self.__playersThreads.keys():
|
||||||
|
self.__playersThreads[guild.id] = self.__createPlayerThreadInfo(context)
|
||||||
|
else:
|
||||||
|
# If the thread has ended create a new one
|
||||||
|
if not self.__playersThreads[guild.id].getThread().is_alive():
|
||||||
|
self.__playersThreads[guild.id] = self.__recreateThread(guild, context)
|
||||||
|
|
||||||
|
return self.__playersThreads[guild.id]
|
||||||
|
except Exception as e:
|
||||||
|
print(f'[Error In GetPlayerContext] -> {e}')
|
||||||
|
|
||||||
|
def resetPlayer(self, guild: Guild, context: Context) -> None:
|
||||||
|
if guild.id not in self.__playersThreads.keys():
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Recreate the thread keeping the playlist
|
||||||
|
newPlayerInfo = self.__recreateThread(guild, context)
|
||||||
|
newPlayerInfo.getThread().start()
|
||||||
|
# Send a command to start the play again
|
||||||
|
playCommand = VCommands(VCommandsType.PLAY)
|
||||||
|
newPlayerInfo.getQueueToPlayer().put(playCommand)
|
||||||
|
self.__playersThreads[guild.id] = newPlayerInfo
|
||||||
|
|
||||||
|
def __getRunningPlayerInfo(self, guild: Guild) -> PlayerThreadInfo:
|
||||||
|
if guild.id not in self.__playersThreads.keys():
|
||||||
|
print('Process Info not found')
|
||||||
|
return None
|
||||||
|
|
||||||
|
return self.__playersThreads[guild.id]
|
||||||
|
|
||||||
|
def __createPlayerThreadInfo(self, context: Union[Context, Interaction]) -> PlayerThreadInfo:
|
||||||
|
guildID: int = context.guild.id
|
||||||
|
if isinstance(context, Interaction):
|
||||||
|
voiceID: int = context.user.voice.channel.id
|
||||||
|
else:
|
||||||
|
voiceID: int = context.author.voice.channel.id
|
||||||
|
|
||||||
|
playlist = Playlist()
|
||||||
|
lock = Lock()
|
||||||
|
player = PlayerThread(context.guild.name, playlist, lock, guildID, voiceID)
|
||||||
|
playerInfo = PlayerThreadInfo(player, playlist, lock, context.channel)
|
||||||
|
player.start()
|
||||||
|
|
||||||
|
return playerInfo
|
||||||
|
|
||||||
|
def __recreateThread(self, guild: Guild, context: Union[Context, Interaction]) -> PlayerThreadInfo:
|
||||||
|
self.__stopPossiblyRunningProcess(guild)
|
||||||
|
|
||||||
|
guildID: int = context.guild.id
|
||||||
|
if isinstance(context, Interaction):
|
||||||
|
voiceID: int = context.user.voice.channel.id
|
||||||
|
else:
|
||||||
|
voiceID: int = context.author.voice.channel.id
|
||||||
|
|
||||||
|
playlist = self.__playersThreads[guildID].getPlaylist()
|
||||||
|
lock = Lock()
|
||||||
|
player = PlayerThread(context.guild.name, playlist, lock, guildID, voiceID)
|
||||||
|
playerInfo = PlayerThreadInfo(player, playlist, lock, context.channel)
|
||||||
|
player.start()
|
||||||
|
|
||||||
|
return playerInfo
|
||||||
|
|
||||||
|
async def showNowPlaying(self, guildID: int, song: Song) -> None:
|
||||||
|
commandExecutor = self.__playersCommandsExecutor[guildID]
|
||||||
|
processInfo = self.__playersThreads[guildID]
|
||||||
|
await commandExecutor.sendNowPlaying(processInfo, song)
|
||||||
Loading…
x
Reference in New Issue
Block a user