mirror of
https://github.com/RafaelSolVargas/Vulkan.git
synced 2025-10-29 16:57:23 +00:00
Code style upgrade
This commit is contained in:
85
Handlers/AbstractHandler.py
Normal file
85
Handlers/AbstractHandler.py
Normal file
@@ -0,0 +1,85 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import List
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client, Guild, ClientUser, Member
|
||||
from Config.Messages import Messages
|
||||
from Handlers.PlayersController import PlayersController
|
||||
from Music.Player import Player
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Config.Configs import Configs
|
||||
from Config.Helper import Helper
|
||||
from Views.Embeds import Embeds
|
||||
|
||||
|
||||
class AbstractHandler(ABC):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
self.__bot: Client = bot
|
||||
self.__controller = PlayersController(self.__bot)
|
||||
self.__player: Player = self.__controller.get_player(ctx.guild)
|
||||
self.__guild: Guild = ctx.guild
|
||||
self.__ctx: Context = ctx
|
||||
self.__bot_user: ClientUser = self.__bot.user
|
||||
self.__id = self.__bot_user.id
|
||||
self.__messages = Messages()
|
||||
self.__config = Configs()
|
||||
self.__helper = Helper()
|
||||
self.__embeds = Embeds()
|
||||
self.__bot_member: Member = self.__get_member()
|
||||
|
||||
@abstractmethod
|
||||
async def run(self) -> HandlerResponse:
|
||||
pass
|
||||
|
||||
@property
|
||||
def id(self) -> int:
|
||||
return self.__id
|
||||
|
||||
@property
|
||||
def bot_member(self) -> Member:
|
||||
return self.__bot_member
|
||||
|
||||
@property
|
||||
def bot_user(self) -> ClientUser:
|
||||
return self.__bot_user
|
||||
|
||||
@property
|
||||
def guild(self) -> Guild:
|
||||
return self.__guild
|
||||
|
||||
@property
|
||||
def player(self) -> Player:
|
||||
return self.__player
|
||||
|
||||
@property
|
||||
def controller(self) -> PlayersController:
|
||||
return self.__controller
|
||||
|
||||
@property
|
||||
def bot(self) -> Client:
|
||||
return self.__bot
|
||||
|
||||
@property
|
||||
def config(self) -> Configs:
|
||||
return self.__config
|
||||
|
||||
@property
|
||||
def messages(self) -> Messages:
|
||||
return self.__messages
|
||||
|
||||
@property
|
||||
def helper(self) -> Helper:
|
||||
return self.__helper
|
||||
|
||||
@property
|
||||
def ctx(self) -> Context:
|
||||
return self.__ctx
|
||||
|
||||
@property
|
||||
def embeds(self) -> Embeds:
|
||||
return self.__embeds
|
||||
|
||||
def __get_member(self) -> Member:
|
||||
guild_members: List[Member] = self.__guild.members
|
||||
for member in guild_members:
|
||||
if member.id == self.__id:
|
||||
return member
|
||||
22
Handlers/ClearHandler.py
Normal file
22
Handlers/ClearHandler.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Parallelism.ProcessManager import ProcessManager
|
||||
|
||||
|
||||
class ClearHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
# Get the current process of the guild
|
||||
processManager = ProcessManager()
|
||||
processContext = processManager.getRunningPlayerContext(self.guild)
|
||||
if processContext:
|
||||
# Clear the playlist
|
||||
playlist = processContext.getPlaylist()
|
||||
with processContext.getLock():
|
||||
playlist.clear()
|
||||
|
||||
return HandlerResponse(self.ctx)
|
||||
27
Handlers/HandlerResponse.py
Normal file
27
Handlers/HandlerResponse.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from typing import Union
|
||||
from discord.ext.commands import Context
|
||||
from Config.Exceptions import VulkanError
|
||||
from discord import Embed
|
||||
|
||||
|
||||
class HandlerResponse:
|
||||
def __init__(self, ctx: Context, embed: Embed = None, error: VulkanError = None) -> None:
|
||||
self.__ctx: Context = ctx
|
||||
self.__error: VulkanError = error
|
||||
self.__embed: Embed = embed
|
||||
self.__success = False if error else True
|
||||
|
||||
@property
|
||||
def ctx(self) -> Context:
|
||||
return self.__ctx
|
||||
|
||||
@property
|
||||
def embed(self) -> Union[Embed, None]:
|
||||
return self.__embed
|
||||
|
||||
def error(self) -> Union[VulkanError, None]:
|
||||
return self.__error
|
||||
|
||||
@property
|
||||
def success(self) -> bool:
|
||||
return self.__success
|
||||
24
Handlers/HistoryHandler.py
Normal file
24
Handlers/HistoryHandler.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Utils.Utils import Utils
|
||||
|
||||
|
||||
class HistoryHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
history = self.player.playlist.getSongsHistory()
|
||||
|
||||
if len(history) == 0:
|
||||
text = self.messages.HISTORY_EMPTY
|
||||
|
||||
else:
|
||||
text = f'\n📜 History Length: {len(history)} | Max: {self.config.MAX_SONGS_HISTORY}\n'
|
||||
for pos, song in enumerate(history, start=1):
|
||||
text += f"**`{pos}` - ** {song.title} - `{Utils.format_time(song.duration)}`\n"
|
||||
|
||||
embed = self.embeds.HISTORY(text)
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
39
Handlers/LoopHandler.py
Normal file
39
Handlers/LoopHandler.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Config.Exceptions import BadCommandUsage
|
||||
|
||||
|
||||
class LoopHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
|
||||
async def run(self, args: str) -> HandlerResponse:
|
||||
if args == '' or args is None:
|
||||
self.player.playlist.loop_all()
|
||||
embed = self.embeds.LOOP_ALL_ACTIVATED()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
args = args.lower()
|
||||
if self.player.playlist.getCurrentSong() is None:
|
||||
embed = self.embeds.NOT_PLAYING()
|
||||
error = BadCommandUsage()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
if args == 'one':
|
||||
self.player.playlist.loop_one()
|
||||
embed = self.embeds.LOOP_ONE_ACTIVATED()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
elif args == 'all':
|
||||
self.player.playlist.loop_all()
|
||||
embed = self.embeds.LOOP_ALL_ACTIVATED()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
elif args == 'off':
|
||||
self.player.playlist.loop_off()
|
||||
embed = self.embeds.LOOP_DISABLE()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
else:
|
||||
error = BadCommandUsage()
|
||||
embed = self.embeds.BAD_LOOP_USE()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
63
Handlers/MoveHandler.py
Normal file
63
Handlers/MoveHandler.py
Normal file
@@ -0,0 +1,63 @@
|
||||
from typing import Union
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Config.Exceptions import BadCommandUsage, VulkanError, InvalidInput, NumberRequired, UnknownError
|
||||
from Music.Playlist import Playlist
|
||||
from Parallelism.ProcessManager import ProcessManager
|
||||
|
||||
|
||||
class MoveHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
|
||||
async def run(self, pos1: str, pos2: str) -> HandlerResponse:
|
||||
processManager = ProcessManager()
|
||||
processContext = processManager.getRunningPlayerContext(self.guild)
|
||||
if not processContext:
|
||||
embed = self.embeds.NOT_PLAYING()
|
||||
error = BadCommandUsage()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
with processContext.getLock():
|
||||
error = self.__validateInput(pos1, pos2)
|
||||
if error:
|
||||
embed = self.embeds.ERROR_EMBED(error.message)
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
playlist = processContext.getPlaylist()
|
||||
pos1, pos2 = self.__sanitizeInput(playlist, pos1, pos2)
|
||||
|
||||
if not playlist.validate_position(pos1) or not playlist.validate_position(pos2):
|
||||
error = InvalidInput()
|
||||
embed = self.embeds.PLAYLIST_RANGE_ERROR()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
try:
|
||||
song = playlist.move_songs(pos1, pos2)
|
||||
|
||||
song_name = song.title if song.title else song.identifier
|
||||
embed = self.embeds.SONG_MOVED(song_name, pos1, pos2)
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
except:
|
||||
embed = self.embeds.ERROR_MOVING()
|
||||
error = UnknownError()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
def __validateInput(self, pos1: str, pos2: str) -> Union[VulkanError, None]:
|
||||
try:
|
||||
pos1 = int(pos1)
|
||||
pos2 = int(pos2)
|
||||
except:
|
||||
return NumberRequired(self.messages.ERROR_NUMBER)
|
||||
|
||||
def __sanitizeInput(self, playlist: Playlist, pos1: int, pos2: int) -> tuple:
|
||||
pos1 = int(pos1)
|
||||
pos2 = int(pos2)
|
||||
|
||||
if pos1 == -1:
|
||||
pos1 = len(playlist.getSongs())
|
||||
if pos2 == -1:
|
||||
pos2 = len(playlist.getSongs())
|
||||
|
||||
return pos1, pos2
|
||||
26
Handlers/NowPlayingHandler.py
Normal file
26
Handlers/NowPlayingHandler.py
Normal file
@@ -0,0 +1,26 @@
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Utils.Cleaner import Cleaner
|
||||
|
||||
|
||||
class NowPlayingHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
self.__cleaner = Cleaner()
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
if not self.player.playing:
|
||||
embed = self.embeds.NOT_PLAYING()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
if self.player.playlist.isLoopingOne():
|
||||
title = self.messages.ONE_SONG_LOOPING
|
||||
else:
|
||||
title = self.messages.SONG_PLAYING
|
||||
await self.__cleaner.clean_messages(self.ctx, self.config.CLEANER_MESSAGES_QUANT)
|
||||
|
||||
info = self.player.playlist.getCurrentSong().info
|
||||
embed = self.embeds.SONG_INFO(info, title)
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
22
Handlers/PauseHandler.py
Normal file
22
Handlers/PauseHandler.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Parallelism.ProcessManager import ProcessManager
|
||||
from Parallelism.Commands import VCommands, VCommandsType
|
||||
|
||||
|
||||
class PauseHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
processManager = ProcessManager()
|
||||
processContext = processManager.getRunningPlayerContext(self.guild)
|
||||
if processContext:
|
||||
# Send Pause command to be execute by player process
|
||||
command = VCommands(VCommandsType.PAUSE, None)
|
||||
queue = processContext.getQueue()
|
||||
queue.put(command)
|
||||
|
||||
return HandlerResponse(self.ctx)
|
||||
96
Handlers/PlayHandler.py
Normal file
96
Handlers/PlayHandler.py
Normal file
@@ -0,0 +1,96 @@
|
||||
from Config.Exceptions import DownloadingError, InvalidInput, VulkanError
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Config.Exceptions import ImpossibleMove, UnknownError
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Music.Downloader import Downloader
|
||||
from Music.Searcher import Searcher
|
||||
from Music.Song import Song
|
||||
from Parallelism.ProcessManager import ProcessManager
|
||||
from Parallelism.Commands import VCommands, VCommandsType
|
||||
|
||||
|
||||
class PlayHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
self.__searcher = Searcher()
|
||||
self.__down = Downloader()
|
||||
|
||||
async def run(self, args: str) -> HandlerResponse:
|
||||
track = " ".join(args)
|
||||
requester = self.ctx.author.name
|
||||
|
||||
if not self.__isUserConnected():
|
||||
error = ImpossibleMove()
|
||||
embed = self.embeds.NO_CHANNEL()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
try:
|
||||
musics = await self.__searcher.search(track)
|
||||
if musics is None or len(musics) == 0:
|
||||
raise InvalidInput(self.messages.INVALID_INPUT, self.messages.ERROR_TITLE)
|
||||
|
||||
for music in musics:
|
||||
song = Song(music, self.player.playlist, requester)
|
||||
self.player.playlist.add_song(song)
|
||||
quant = len(musics)
|
||||
|
||||
songs_preload = self.player.playlist.getSongsToPreload()
|
||||
await self.__down.preload(songs_preload)
|
||||
|
||||
if quant == 1:
|
||||
pos = len(self.player.playlist)
|
||||
song = self.__down.finish_one_song(song)
|
||||
if song.problematic:
|
||||
embed = self.embeds.SONG_PROBLEMATIC()
|
||||
error = DownloadingError()
|
||||
response = HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
elif not self.player.playing:
|
||||
embed = self.embeds.SONG_ADDED(song.title)
|
||||
response = HandlerResponse(self.ctx, embed)
|
||||
else:
|
||||
embed = self.embeds.SONG_ADDED_TWO(song.info, pos)
|
||||
response = HandlerResponse(self.ctx, embed)
|
||||
else:
|
||||
embed = self.embeds.SONGS_ADDED(quant)
|
||||
response = HandlerResponse(self.ctx, embed)
|
||||
|
||||
# Get the process context for the current guild
|
||||
manager = ProcessManager(self.bot)
|
||||
processContext = manager.getPlayerContext(self.guild, self.ctx)
|
||||
# Add the downloaded song to the process playlist
|
||||
# All access to shared memory should be protect by acquire the Lock
|
||||
with processContext.getLock():
|
||||
processContext.getPlaylist().add_song(song)
|
||||
|
||||
# If process already started send a command to the player process by queue
|
||||
process = processContext.getProcess()
|
||||
queue = processContext.getQueue()
|
||||
if process.is_alive():
|
||||
command = VCommands(VCommandsType.PLAY)
|
||||
queue.put(command)
|
||||
else:
|
||||
# Start the process
|
||||
process.start()
|
||||
|
||||
return response
|
||||
|
||||
except Exception as err:
|
||||
if isinstance(err, VulkanError): # If error was already processed
|
||||
print(f'DEVELOPER NOTE -> PlayController Error: {err.message}')
|
||||
error = err
|
||||
embed = self.embeds.CUSTOM_ERROR(error)
|
||||
else:
|
||||
print(f'DEVELOPER NOTE -> PlayController Error: {err}')
|
||||
error = UnknownError()
|
||||
embed = self.embeds.UNKNOWN_ERROR()
|
||||
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
def __isUserConnected(self) -> bool:
|
||||
if self.ctx.author.voice:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
56
Handlers/PlayersController.py
Normal file
56
Handlers/PlayersController.py
Normal file
@@ -0,0 +1,56 @@
|
||||
from typing import Dict, List, Union
|
||||
from Config.Singleton import Singleton
|
||||
from discord import Guild, Client, VoiceClient, Member
|
||||
from Music.Player import Player
|
||||
|
||||
|
||||
class PlayersController(Singleton):
|
||||
def __init__(self, bot: Client = None) -> None:
|
||||
if not super().created:
|
||||
self.__bot: Client = bot
|
||||
if bot is not None:
|
||||
self.__players: Dict[Guild, Player] = self.__create_players()
|
||||
|
||||
def set_bot(self, bot: Client) -> None:
|
||||
self.__bot: Client = bot
|
||||
self.__players: Dict[Guild, Player] = self.__create_players()
|
||||
|
||||
def get_player(self, guild: Guild) -> Player:
|
||||
if guild not in self.__players.keys():
|
||||
player = Player(self.__bot, guild)
|
||||
self.__players[guild] = player
|
||||
|
||||
return self.__players[guild]
|
||||
|
||||
def reset_player(self, guild: Guild) -> None:
|
||||
if isinstance(guild, Guild):
|
||||
player = Player(self.__bot, guild)
|
||||
self.__players[guild] == player
|
||||
|
||||
def get_guild_voice(self, guild: Guild) -> Union[VoiceClient, None]:
|
||||
if guild.voice_client is None:
|
||||
return None
|
||||
else:
|
||||
return guild.voice_client
|
||||
|
||||
def create_player(self, guild: Guild) -> None:
|
||||
player = Player(self.__bot, guild)
|
||||
self.__players[guild] = player
|
||||
print(f'Player for guild {guild.name} created')
|
||||
|
||||
def __create_players(self) -> Dict[Guild, Player]:
|
||||
list_guilds: List[Guild] = self.__bot.guilds
|
||||
players: Dict[Guild, Player] = {}
|
||||
|
||||
for guild in list_guilds:
|
||||
player = Player(self.__bot, guild)
|
||||
players[guild] = player
|
||||
print(f'Player for guild {guild.name} created')
|
||||
|
||||
return players
|
||||
|
||||
def __get_guild_bot_member(self, guild: Guild) -> Member:
|
||||
members: List[Member] = guild.members
|
||||
for member in members:
|
||||
if member.id == self.__bot.user.id:
|
||||
return member
|
||||
60
Handlers/PrevHandler.py
Normal file
60
Handlers/PrevHandler.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Config.Exceptions import BadCommandUsage, ImpossibleMove, UnknownError
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
|
||||
|
||||
class PrevHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
if len(self.player.playlist.history()) == 0:
|
||||
error = ImpossibleMove()
|
||||
embed = self.embeds.NOT_PREVIOUS_SONG()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
if not self.__user_connected():
|
||||
error = ImpossibleMove()
|
||||
embed = self.embeds.NO_CHANNEL()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
if not self.__is_connected():
|
||||
success = await self.__connect()
|
||||
if not success:
|
||||
error = UnknownError()
|
||||
embed = self.embeds.UNKNOWN_ERROR()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
if self.player.playlist.isLoopingAll() or self.player.playlist.isLoopingOne():
|
||||
error = BadCommandUsage()
|
||||
embed = self.embeds.FAIL_DUE_TO_LOOP_ON()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
await self.player.play_prev(self.ctx)
|
||||
|
||||
def __user_connected(self) -> bool:
|
||||
if self.ctx.author.voice:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def __is_connected(self) -> bool:
|
||||
try:
|
||||
voice_channel = self.guild.voice_client.channel
|
||||
|
||||
if not self.guild.voice_client.is_connected():
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
async def __connect(self) -> bool:
|
||||
# if self.guild.voice_client is None:
|
||||
try:
|
||||
await self.ctx.author.voice.channel.connect(reconnect=True, timeout=None)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
56
Handlers/QueueHandler.py
Normal file
56
Handlers/QueueHandler.py
Normal file
@@ -0,0 +1,56 @@
|
||||
import asyncio
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Music.Downloader import Downloader
|
||||
from Utils.Utils import Utils
|
||||
from Parallelism.ProcessManager import ProcessManager
|
||||
|
||||
|
||||
class QueueHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
self.__down = Downloader()
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
# Retrieve the process of the guild
|
||||
process = ProcessManager()
|
||||
processContext = process.getRunningPlayerContext(self.guild)
|
||||
if not processContext: # If no process return empty list
|
||||
embed = self.embeds.EMPTY_QUEUE()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
# Acquire the Lock to manipulate the playlist
|
||||
with processContext.getLock():
|
||||
playlist = processContext.getPlaylist()
|
||||
|
||||
if playlist.isLoopingOne():
|
||||
song = playlist.getCurrentSong()
|
||||
embed = self.embeds.ONE_SONG_LOOPING(song.info)
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
songs_preload = playlist.getSongsToPreload()
|
||||
if len(songs_preload) == 0:
|
||||
embed = self.embeds.EMPTY_QUEUE()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
|
||||
asyncio.create_task(self.__down.preload(songs_preload))
|
||||
|
||||
if playlist.isLoopingAll():
|
||||
title = self.messages.ALL_SONGS_LOOPING
|
||||
else:
|
||||
title = self.messages.QUEUE_TITLE
|
||||
|
||||
total_time = Utils.format_time(sum([int(song.duration if song.duration else 0)
|
||||
for song in songs_preload]))
|
||||
total_songs = len(playlist.getSongs())
|
||||
|
||||
text = f'📜 Queue length: {total_songs} | ⌛ Duration: `{total_time}` downloaded \n\n'
|
||||
|
||||
for pos, song in enumerate(songs_preload, start=1):
|
||||
song_name = song.title if song.title else self.messages.SONG_DOWNLOADING
|
||||
text += f"**`{pos}` - ** {song_name} - `{Utils.format_time(song.duration)}`\n"
|
||||
|
||||
embed = self.embeds.QUEUE(title, text)
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
52
Handlers/RemoveHandler.py
Normal file
52
Handlers/RemoveHandler.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from typing import Union
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Config.Exceptions import BadCommandUsage, VulkanError, ErrorRemoving, InvalidInput, NumberRequired
|
||||
|
||||
|
||||
class RemoveHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
|
||||
async def run(self, position: str) -> HandlerResponse:
|
||||
if not self.player.playlist:
|
||||
embed = self.embeds.NOT_PLAYING()
|
||||
error = BadCommandUsage()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
error = self.__validate_input(position)
|
||||
if error:
|
||||
embed = self.embeds.ERROR_EMBED(error.message)
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
position = self.__sanitize_input(position)
|
||||
if not self.player.playlist.validate_position(position):
|
||||
error = InvalidInput()
|
||||
embed = self.embeds.PLAYLIST_RANGE_ERROR()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
try:
|
||||
song = self.player.playlist.remove_song(position)
|
||||
name = song.title if song.title else song.identifier
|
||||
|
||||
embed = self.embeds.SONG_REMOVED(name)
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
except:
|
||||
error = ErrorRemoving()
|
||||
embed = self.embeds.ERROR_REMOVING()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
def __validate_input(self, position: str) -> Union[VulkanError, None]:
|
||||
try:
|
||||
position = int(position)
|
||||
except:
|
||||
return NumberRequired(self.messages.ERROR_NUMBER)
|
||||
|
||||
def __sanitize_input(self, position: str) -> int:
|
||||
position = int(position)
|
||||
|
||||
if position == -1:
|
||||
position = len(self.player.playlist)
|
||||
return position
|
||||
20
Handlers/ResetHandler.py
Normal file
20
Handlers/ResetHandler.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Handlers.PlayersController import PlayersController
|
||||
|
||||
|
||||
class ResetHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
self.__controller = PlayersController(self.bot)
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
try:
|
||||
await self.player.force_stop()
|
||||
await self.bot_member.move_to(None)
|
||||
self.__controller.reset_player(self.guild)
|
||||
return HandlerResponse(self.ctx)
|
||||
except Exception as e:
|
||||
print(f'DEVELOPER NOTE -> Reset Error: {e}')
|
||||
22
Handlers/ResumeHandler.py
Normal file
22
Handlers/ResumeHandler.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Parallelism.ProcessManager import ProcessManager
|
||||
from Parallelism.Commands import VCommands, VCommandsType
|
||||
|
||||
|
||||
class ResumeHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
processManager = ProcessManager()
|
||||
processContext = processManager.getRunningPlayerContext(self.guild)
|
||||
if processContext:
|
||||
# Send Resume command to be execute by player process
|
||||
command = VCommands(VCommandsType.RESUME, None)
|
||||
queue = processContext.getQueue()
|
||||
queue.put(command)
|
||||
|
||||
return HandlerResponse(self.ctx)
|
||||
27
Handlers/ShuffleHandler.py
Normal file
27
Handlers/ShuffleHandler.py
Normal file
@@ -0,0 +1,27 @@
|
||||
import asyncio
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Config.Exceptions import UnknownError
|
||||
from Music.Downloader import Downloader
|
||||
|
||||
|
||||
class ShuffleHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
self.__down = Downloader()
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
try:
|
||||
self.player.playlist.shuffle()
|
||||
songs = self.player.playlist.getSongsToPreload()
|
||||
|
||||
asyncio.create_task(self.__down.preload(songs))
|
||||
embed = self.embeds.SONGS_SHUFFLED()
|
||||
return HandlerResponse(self.ctx, embed)
|
||||
except Exception as e:
|
||||
print(f'DEVELOPER NOTE -> Error Shuffling: {e}')
|
||||
error = UnknownError()
|
||||
embed = self.embeds.ERROR_SHUFFLING()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
28
Handlers/SkipHandler.py
Normal file
28
Handlers/SkipHandler.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Config.Exceptions import BadCommandUsage
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Parallelism.ProcessManager import ProcessManager
|
||||
from Parallelism.Commands import VCommands, VCommandsType
|
||||
|
||||
|
||||
class SkipHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
processManager = ProcessManager()
|
||||
processContext = processManager.getRunningPlayerContext(self.guild)
|
||||
if processContext: # Verify if there is a running process
|
||||
playlist = processContext.getPlaylist()
|
||||
if playlist.isLoopingOne():
|
||||
embed = self.embeds.ERROR_DUE_LOOP_ONE_ON()
|
||||
error = BadCommandUsage()
|
||||
return HandlerResponse(self.ctx, embed, error)
|
||||
|
||||
# Send a command to the player process to skip the music
|
||||
command = VCommands(VCommandsType.SKIP, None)
|
||||
queue = processContext.getQueue()
|
||||
queue.put(command)
|
||||
return HandlerResponse(self.ctx)
|
||||
22
Handlers/StopHandler.py
Normal file
22
Handlers/StopHandler.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from discord.ext.commands import Context
|
||||
from discord import Client
|
||||
from Handlers.AbstractHandler import AbstractHandler
|
||||
from Handlers.HandlerResponse import HandlerResponse
|
||||
from Parallelism.ProcessManager import ProcessManager
|
||||
from Parallelism.Commands import VCommands, VCommandsType
|
||||
|
||||
|
||||
class StopHandler(AbstractHandler):
|
||||
def __init__(self, ctx: Context, bot: Client) -> None:
|
||||
super().__init__(ctx, bot)
|
||||
|
||||
async def run(self) -> HandlerResponse:
|
||||
processManager = ProcessManager()
|
||||
processContext = processManager.getRunningPlayerContext(self.guild)
|
||||
if processContext:
|
||||
# Send command to player process stop
|
||||
command = VCommands(VCommandsType.STOP, None)
|
||||
queue = processContext.getQueue()
|
||||
queue.put(command)
|
||||
|
||||
return HandlerResponse(self.ctx)
|
||||
Reference in New Issue
Block a user