Adding Reset and Shuffle Controller and some fix

This commit is contained in:
Rafael Vargas 2022-03-25 14:31:37 -04:00
parent d30ff93dc1
commit 8ac80c216f
9 changed files with 128 additions and 191 deletions

View File

@ -1,4 +1,3 @@
from msilib.schema import ControlEvent
from typing import Dict from typing import Dict
from discord import Guild, Client, Embed from discord import Guild, Client, Embed
from discord.ext import commands from discord.ext import commands
@ -10,6 +9,8 @@ from Controllers.MoveController import MoveController
from Controllers.NowPlayingController import NowPlayingController from Controllers.NowPlayingController import NowPlayingController
from Controllers.PlayerController import PlayersController from Controllers.PlayerController import PlayersController
from Controllers.RemoveController import RemoveController from Controllers.RemoveController import RemoveController
from Controllers.ResetController import ResetController
from Controllers.ShuffleController import ShuffleController
from Music.Player import Player from Music.Player import Player
from Utils.Utils import is_connected from Utils.Utils import is_connected
from Controllers.SkipController import SkipController from Controllers.SkipController import SkipController
@ -70,12 +71,11 @@ class Music(commands.Cog):
@commands.command(name="queue", help=helper.HELP_QUEUE, description=helper.HELP_QUEUE_LONG, aliases=['q', 'fila']) @commands.command(name="queue", help=helper.HELP_QUEUE, description=helper.HELP_QUEUE_LONG, aliases=['q', 'fila'])
async def queue(self, ctx: Context) -> None: async def queue(self, ctx: Context) -> None:
player = self.__get_player(ctx) controller = QueueController(ctx, self.__bot)
if player is None:
return
embed = await player.queue() response = await controller.run()
await ctx.send(embed=embed) view2 = EmbedView(response)
await view2.run()
@commands.command(name="skip", help=helper.HELP_SKIP, description=helper.HELP_SKIP_LONG, aliases=['s', 'pular']) @commands.command(name="skip", help=helper.HELP_SKIP, description=helper.HELP_SKIP_LONG, aliases=['s', 'pular'])
async def skip(self, ctx: Context) -> None: async def skip(self, ctx: Context) -> None:
@ -175,12 +175,13 @@ class Music(commands.Cog):
@commands.command(name='shuffle', help=helper.HELP_SHUFFLE, description=helper.HELP_SHUFFLE_LONG, aliases=['aleatorio']) @commands.command(name='shuffle', help=helper.HELP_SHUFFLE, description=helper.HELP_SHUFFLE_LONG, aliases=['aleatorio'])
async def shuffle(self, ctx: Context) -> None: async def shuffle(self, ctx: Context) -> None:
player = self.__get_player(ctx) controller = ShuffleController(ctx, self.__bot)
if player is None:
return response = await controller.run()
else: view1 = EmbedView(response)
description = await player.shuffle() view2 = EmoteView(response)
await self.__send_embed(ctx, self.__config.SONG_PLAYER, description, 'blue') await view1.run()
await view2.run()
@commands.command(name='move', help=helper.HELP_MOVE, description=helper.HELP_MOVE_LONG, aliases=['m', 'mover']) @commands.command(name='move', help=helper.HELP_MOVE, description=helper.HELP_MOVE_LONG, aliases=['m', 'mover'])
async def move(self, ctx: Context, pos1, pos2='1') -> None: async def move(self, ctx: Context, pos1, pos2='1') -> None:
@ -204,19 +205,13 @@ class Music(commands.Cog):
@commands.command(name='reset', help=helper.HELP_RESET, description=helper.HELP_RESET_LONG, aliases=['resetar']) @commands.command(name='reset', help=helper.HELP_RESET, description=helper.HELP_RESET_LONG, aliases=['resetar'])
async def reset(self, ctx: Context) -> None: async def reset(self, ctx: Context) -> None:
player = self.__get_player(ctx) controller = ResetController(ctx, self.__bot)
try:
await player.force_stop()
await player.stop()
self.__guilds[ctx.guild] = Player(self.__bot, ctx.guild)
player = self.__get_player(ctx)
await player.force_stop()
except Exception as e:
print(f'DEVELOPER NOTE -> Reset Error: {e}')
self.__guilds[ctx.guild] = Player(self.__bot, ctx.guild) response = await controller.run()
player = self.__get_player(ctx) view1 = EmbedView(response)
print(f'Player for guild {ctx.guild} created') view2 = EmoteView(response)
await view1.run()
await view2.run()
async def __send_embed(self, ctx: Context, title='', description='', colour='grey') -> None: async def __send_embed(self, ctx: Context, title='', description='', colour='grey') -> None:
try: try:

View File

@ -1,6 +1,7 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import List
from discord.ext.commands import Context from discord.ext.commands import Context
from discord import Client, Guild from discord import Client, Guild, ClientUser, Member
from Controllers.PlayerController import PlayersController from Controllers.PlayerController import PlayersController
from Music.Player import Player from Music.Player import Player
from Controllers.ControllerResponse import ControllerResponse from Controllers.ControllerResponse import ControllerResponse
@ -16,14 +17,29 @@ class AbstractController(ABC):
self.__player: Player = self.__controller.get_player(ctx.guild) self.__player: Player = self.__controller.get_player(ctx.guild)
self.__guild: Guild = ctx.guild self.__guild: Guild = ctx.guild
self.__ctx: Context = ctx self.__ctx: Context = ctx
self.__bot_user: ClientUser = self.__bot.user
self.__id = self.__bot_user.id
self.__config = Configs() self.__config = Configs()
self.__helper = Helper() self.__helper = Helper()
self.__embeds = Embeds() self.__embeds = Embeds()
self.__bot_member: Member = self.__get_member()
@abstractmethod @abstractmethod
async def run(self) -> ControllerResponse: async def run(self) -> ControllerResponse:
pass 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 @property
def guild(self) -> Guild: def guild(self) -> Guild:
return self.__guild return self.__guild
@ -55,3 +71,9 @@ class AbstractController(ABC):
@property @property
def embeds(self) -> Embeds: def embeds(self) -> Embeds:
return 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

View File

@ -30,11 +30,10 @@ class LoopController(AbstractController):
embed = self.embeds.LOOP_ALL_ACTIVATED() embed = self.embeds.LOOP_ALL_ACTIVATED()
return ControllerResponse(self.ctx, embed) return ControllerResponse(self.ctx, embed)
elif args == 'off': elif args == 'off':
self.player.playlist.loop_all() self.player.playlist.loop_off()
embed = self.embeds.LOOP_DISABLE() embed = self.embeds.LOOP_DISABLE()
return ControllerResponse(self.ctx, embed) return ControllerResponse(self.ctx, embed)
else: else:
self.player.playlist.loop_all()
error = BadCommandUsage() error = BadCommandUsage()
embed = self.embeds.BAD_LOOP_USE() embed = self.embeds.BAD_LOOP_USE()
return ControllerResponse(self.ctx, embed, error) return ControllerResponse(self.ctx, embed, error)

View File

@ -1,6 +1,6 @@
from typing import Dict, List, Union from typing import Dict, List, Union
from Config.Singleton import Singleton from Config.Singleton import Singleton
from discord import Guild, Client, VoiceClient from discord import Guild, Client, VoiceClient, Member
from Music.Player import Player from Music.Player import Player
@ -43,3 +43,9 @@ class PlayersController(Singleton):
print(f'Player for guild {guild.name} created') print(f'Player for guild {guild.name} created')
return players 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

View File

@ -13,23 +13,22 @@ class QueueController(AbstractController):
async def run(self) -> ControllerResponse: async def run(self) -> ControllerResponse:
if self.player.playlist.looping_one: if self.player.playlist.looping_one:
info = self.player.playlist.current song = self.player.playlist.current
embed = self.embeds.ONE_SONG_LOOPING(info) embed = self.embeds.ONE_SONG_LOOPING(song.info)
return ControllerResponse(self.ctx, embed) return ControllerResponse(self.ctx, embed)
songs_preload = self.player.playlist.songs_to_preload songs_preload = self.player.playlist.songs_to_preload
if len(songs_preload) == 0: if len(songs_preload) == 0:
embed = self.embeds.EMPTY_QUEUE embed = self.embeds.EMPTY_QUEUE()
return ControllerResponse(self.ctx, embed) return ControllerResponse(self.ctx, embed)
await self.__down.preload(songs_preload) await self.__down.preload(songs_preload)
if self.player.playlist.looping_all: if self.player.playlist.looping_all:
title = self.__config.ALL_SONGS_LOOPING title = self.config.ALL_SONGS_LOOPING
else: else:
title = self.__config.QUEUE_TITLE title = self.config.QUEUE_TITLE
title = self.config.QUEUE_TITLE
total_time = format_time(sum([int(song.duration if song.duration else 0) total_time = format_time(sum([int(song.duration if song.duration else 0)
for song in songs_preload])) for song in songs_preload]))
total_songs = len(self.player.playlist) total_songs = len(self.player.playlist)

View File

@ -0,0 +1,20 @@
from discord.ext.commands import Context
from discord import Client, Member
from Controllers.AbstractController import AbstractController
from Controllers.ControllerResponse import ControllerResponse
from Controllers.PlayerController import PlayersController
class ResetController(AbstractController):
def __init__(self, ctx: Context, bot: Client) -> None:
super().__init__(ctx, bot)
self.__controller = PlayersController(self.bot)
async def run(self) -> ControllerResponse:
try:
await self.player.force_stop()
await self.bot_member.move_to(None)
self.__controller.reset_player(self.guild)
return ControllerResponse(self.ctx)
except Exception as e:
print(f'DEVELOPER NOTE -> Reset Error: {e}')

View File

@ -0,0 +1,26 @@
from discord.ext.commands import Context
from discord import Client
from Controllers.AbstractController import AbstractController
from Controllers.ControllerResponse import ControllerResponse
from Exceptions.Exceptions import UnknownError
from Music.Downloader import Downloader
class ShuffleController(AbstractController):
def __init__(self, ctx: Context, bot: Client) -> None:
super().__init__(ctx, bot)
self.__down = Downloader()
async def run(self) -> ControllerResponse:
try:
self.player.playlist.shuffle()
songs = self.player.playlist.songs_to_preload
await self.__down.preload(songs)
embed = self.embeds.SONGS_SHUFFLED()
return ControllerResponse(self.ctx, embed)
except Exception as e:
print(f'DEVELOPER NOTE -> Error Shuffling: {e}')
error = UnknownError()
embed = self.embeds.ERROR_SHUFFLING()
return ControllerResponse(self.ctx, embed, error)

View File

@ -176,62 +176,6 @@ class Player(commands.Cog):
await self.__play_music(ctx, song) await self.__play_music(ctx, song)
async def queue(self) -> Embed:
if self.__playlist.looping_one:
info = self.__playlist.current.info
title = self.__config.ONE_SONG_LOOPING
return self.__format_embed(info, title)
songs_preload = self.__playlist.songs_to_preload
if len(songs_preload) == 0:
title = self.__config.SONG_PLAYER
text = self.__config.EMPTY_QUEUE
else:
if self.__playlist.looping_all:
title = self.__config.ALL_SONGS_LOOPING
else:
title = self.__config.QUEUE_TITLE
await self.__down.preload(songs_preload)
total_time = format_time(sum([int(song.duration if song.duration else 0)
for song in songs_preload]))
total_songs = len(self.__playlist)
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.__config.SONG_DOWNLOADING
text += f"**`{pos}` - ** {song_name} - `{format_time(song.duration)}`\n"
embed = Embed(
title=title,
description=text,
colour=self.__config.COLOURS['blue']
)
return embed
def history(self) -> Embed:
history = self.__playlist.songs_history
if len(history) == 0:
text = self.__config.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} - `{format_time(song.duration)}`\n"
embed = Embed(
title=self.__config.HISTORY_TITLE,
description=text,
colour=self.__config.COLOURS['blue']
)
return embed
async def stop(self) -> bool: async def stop(self) -> bool:
if self.__guild.voice_client is None: if self.__guild.voice_client is None:
return False return False
@ -255,101 +199,6 @@ class Player(commands.Cog):
except Exception as e: except Exception as e:
print(f'DEVELOPER NOTE -> Force Stop Error: {e}') print(f'DEVELOPER NOTE -> Force Stop Error: {e}')
async def pause(self) -> bool:
if self.__guild.voice_client == None:
return False
if self.__guild.voice_client.is_playing():
self.__guild.voice_client.pause()
return True
async def resume(self) -> bool:
if self.__guild.voice_client == None:
return False
if self.__guild.voice_client.is_paused():
self.__guild.voice_client.resume()
return True
async def loop(self, args: str) -> str:
args = args.lower()
if self.__playlist.current == None:
return self.__config.PLAYER_NOT_PLAYING
if args == 'one':
description = self.__playlist.loop_one()
elif args == 'all':
description = self.__playlist.loop_all()
elif args == 'off':
description = self.__playlist.loop_off()
else:
raise commands.UserInputError(self.__config.MY_ERROR_BAD_COMMAND)
return description
async def clear(self) -> None:
self.__playlist.clear()
async def now_playing(self) -> Embed:
if not self.__playing:
embed = Embed(
title=self.__config.SONG_PLAYER,
description=self.__config.PLAYER_NOT_PLAYING,
colour=self.__config.COLOURS['blue']
)
return embed
if self.__playlist.looping_one:
title = self.__config.ONE_SONG_LOOPING
else:
title = self.__config.SONG_PLAYING
current_song = self.__playlist.current
embed = self.__format_embed(current_song.info, title)
return embed
async def shuffle(self) -> str:
try:
self.__playlist.shuffle()
songs = self.__playlist.songs_to_preload
await self.__down.preload(songs)
return self.__config.SONGS_SHUFFLED
except:
return self.__config.ERROR_SHUFFLING
async def move(self, pos1, pos2='1') -> str:
if not self.__playing:
return self.__config.PLAYER_NOT_PLAYING
try:
pos1 = int(pos1)
pos2 = int(pos2)
except:
return self.__config.ERROR_NUMBER
result = self.__playlist.move_songs(pos1, pos2)
songs = self.__playlist.songs_to_preload
await self.__down.preload(songs)
return result
async def remove(self, position) -> str:
"""Remove a song from the queue in the position"""
if not self.__playing:
return self.__config.PLAYER_NOT_PLAYING
try:
position = int(position)
except:
return self.__config.ERROR_NUMBER
result = self.__playlist.remove_song(position)
return result
def __format_embed(self, info: dict, title='', position='Playing Now') -> Embed: def __format_embed(self, info: dict, title='', position='Playing Now') -> Embed:
"""Configure the embed to show the song information""" """Configure the embed to show the song information"""
embedvc = Embed( embedvc = Embed(

View File

@ -171,26 +171,47 @@ class Embeds:
) )
return embed return embed
def LOOP_ONE_ACTIVATED(self) -> Embed: def ERROR_SHUFFLING(self) -> Embed:
embed = Embed( embed = Embed(
title=self.__config.SONG_PLAYER, title=self.__config.SONG_PLAYER,
description=self.__config.LOOP_ONE_ACTIVATE, description=self.__config.ERROR_SHUFFLING,
colour=self.__colors.BLACK
)
return embed
def SONGS_SHUFFLED(self) -> Embed:
embed = Embed(
title=self.__config.SONG_PLAYER,
description=self.__config.SONGS_SHUFFLED,
colour=self.__colors.BLUE
)
return embed
def LOOP_ONE_ACTIVATED(self) -> Embed:
embed = Embed(
title=self.__config.LOOP_ONE_ACTIVATE,
colour=self.__colors.BLUE colour=self.__colors.BLUE
) )
return embed return embed
def LOOP_ALL_ACTIVATED(self) -> Embed: def LOOP_ALL_ACTIVATED(self) -> Embed:
embed = Embed( embed = Embed(
title=self.__config.SONG_PLAYER, title=self.__config.LOOP_ALL_ACTIVATE,
description=self.__config.LOOP_ALL_ACTIVATE,
colour=self.__colors.BLUE colour=self.__colors.BLUE
) )
return embed return embed
def ERROR_DUE_LOOP_ONE_ON(self) -> Embed:
embed = Embed(
title=self.__config.BAD_COMMAND_TITLE,
description=self.__config.ERROR_DUE_LOOP_ONE_ON,
colour=self.__colors.BLACK
)
return embed
def LOOP_DISABLE(self) -> Embed: def LOOP_DISABLE(self) -> Embed:
embed = Embed( embed = Embed(
title=self.__config.SONG_PLAYER, title=self.__config.LOOP_DISABLE,
description=self.__config.LOOP_DISABLE,
colour=self.__colors.BLUE colour=self.__colors.BLUE
) )
return embed return embed