Adding prev and history command

This commit is contained in:
Rafael Vargas 2022-01-11 21:46:09 -04:00
parent c41a6a6c8a
commit 5063c45e87
3 changed files with 135 additions and 17 deletions

View File

@ -49,7 +49,7 @@ class Music(commands.Cog):
if player == None: if player == None:
return return
else: else:
await player.skip() await player.skip(ctx)
@commands.command(name='stop', help=config.HELP_STOP, aliases=['parar']) @commands.command(name='stop', help=config.HELP_STOP, aliases=['parar'])
async def stop(self, ctx) -> None: async def stop(self, ctx) -> None:
@ -79,6 +79,29 @@ class Music(commands.Cog):
if success: if success:
await self.__send_embed(ctx, config.SONG_PLAYER, config.SONG_RESUMED, 'blue') await self.__send_embed(ctx, config.SONG_PLAYER, config.SONG_RESUMED, 'blue')
@commands.command(name='prev', help=config.HELP_PREV, aliases=['anterior'])
async def prev(self, ctx) -> None:
player = self.__get_player(ctx)
if player == None:
return
if is_connected(ctx) == None:
success = await player.connect(ctx)
if success == False:
await self.__send_embed(ctx, config.ERROR_TITLE, config.NO_CHANNEL, 'red')
return
await player.play_prev(ctx)
@commands.command(name='history', help=config.HELP_HISTORY, aliases=['historico'])
async def history(self, ctx) -> None:
player = self.__get_player(ctx)
if player == None:
return
else:
embed = player.history()
await ctx.send(embed=embed)
@commands.command(name='loop', help=config.HELP_LOOP, aliases=['l', 'repeat']) @commands.command(name='loop', help=config.HELP_LOOP, aliases=['l', 'repeat'])
async def loop(self, ctx, args: str) -> None: async def loop(self, ctx, args: str) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)

View File

@ -22,11 +22,14 @@ class Player(commands.Cog):
self.__timer = Timer(self.__timeout_handler) self.__timer = Timer(self.__timeout_handler)
self.__playing = False self.__playing = False
# Flag to control if the player should stop totally the playing
self.__force_stop = False
self.YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'} self.YDL_OPTIONS = {'format': 'bestaudio', 'noplaylist': 'True'}
self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
'options': '-vn'} 'options': '-vn'}
async def connect(self, ctx) -> None: async def connect(self, ctx) -> bool:
if not ctx.author.voice: if not ctx.author.voice:
return False return False
@ -35,6 +38,10 @@ class Player(commands.Cog):
return True return True
def __play_next(self, error, ctx) -> None: def __play_next(self, error, ctx) -> None:
if self.__force_stop: # If it's forced to stop player
self.__force_stop = False
return
song = self.__playlist.next_song() song = self.__playlist.next_song()
if song != None: if song != None:
@ -125,6 +132,34 @@ class Player(commands.Cog):
first_song = self.__playlist.next_song() first_song = self.__playlist.next_song()
await self.__play_music(ctx, first_song) await self.__play_music(ctx, first_song)
async def play_prev(self, ctx) -> None:
"""Stop the currently playing cycle, load the previous song and play"""
if self.__playlist.looping_one or self.__playlist.looping_all: # Do not allow play if loop
embed = discord.Embed(
title=config.SONG_PLAYER,
description=config.LOOP_ON,
colour=config.COLOURS['blue']
)
await ctx.send(embed=embed)
return
song = self.__playlist.prev_song() # Prepare the prev song to play again
if song == None:
embed = discord.Embed(
title=config.SONG_PLAYER,
description=config.NOT_PREVIOUS,
colour=config.COLOURS['blue']
)
await ctx.send(embed=embed)
else:
if self.__guild.voice_client.is_playing() or self.__guild.voice_client.is_paused():
# Will forbidden next_song to execute after stopping current player
self.__force_stop = True
self.__guild.voice_client.stop()
self.__playing = False
await self.__play_music(ctx, song)
async def queue(self) -> discord.Embed: async def queue(self) -> discord.Embed:
if self.__playlist.looping_one: if self.__playlist.looping_one:
info = self.__playlist.current.info info = self.__playlist.current.info
@ -163,13 +198,40 @@ class Player(commands.Cog):
return embed return embed
async def skip(self) -> bool: async def skip(self, ctx) -> bool:
if self.__playlist.looping_one:
embed = discord.Embed(
title=config.SONG_PLAYER,
description=config.LOOP_ON,
colour=config.COLOURS['blue']
)
await ctx.send(embed=embed)
return False
if self.__guild.voice_client != None: if self.__guild.voice_client != None:
self.__guild.voice_client.stop() self.__guild.voice_client.stop()
return True return True
else: else:
return False return False
def history(self) -> discord.Embed:
history = self.__playlist.songs_history
if len(history) == 0:
text = config.HISTORY_EMPTY
else:
text = f'\n📜 History Length: {len(history)} | Max: {config.MAX_SONGS_HISTORY}\n'
for pos, song in enumerate(history, start=1):
text += f"**`{pos}` - ** {song.title} - `{format_time(song.duration)}`\n"
embed = discord.Embed(
title=config.HISTORY_TITLE,
description=text,
colour=config.COLOURS['blue']
)
return embed
async def stop(self) -> bool: async def stop(self) -> bool:
if self.__guild.voice_client == None: if self.__guild.voice_client == None:
return False return False
@ -199,6 +261,9 @@ class Player(commands.Cog):
async def loop(self, args: str) -> str: async def loop(self, args: str) -> str:
args = args.lower() args = args.lower()
if self.__playlist.current == None:
return config.PLAYER_NOT_PLAYING
if args == 'one': if args == 'one':
description = self.__playlist.loop_one() description = self.__playlist.loop_one()
elif args == 'all': elif args == 'all':

View File

@ -12,13 +12,16 @@ class Playlist(IPlaylist):
def __init__(self) -> None: def __init__(self) -> None:
self.__queue = deque() # Store the musics to play self.__queue = deque() # Store the musics to play
self.__songs_history = deque() # Store the musics played self.__songs_history = deque() # Store the musics played
self.__name_history = deque() # Store the name of musics played
self.__looping_one = False self.__looping_one = False
self.__looping_all = False self.__looping_all = False
self.__current: Song = None self.__current: Song = None
@property
def songs_history(self) -> deque:
return self.__songs_history
@property @property
def looping_one(self) -> bool: def looping_one(self) -> bool:
return self.__looping_one return self.__looping_one
@ -39,28 +42,46 @@ class Playlist(IPlaylist):
return len(self.__queue) return len(self.__queue)
def next_song(self) -> Song: def next_song(self) -> Song:
"""Return the next song to play""" """Return the next song to play in a normal playlist flow"""
if self.__current == None and len(self.__queue) == 0: if self.__current == None and len(self.__queue) == 0:
return None return None
played_song = self.__current played_song = self.__current
if self.__looping_one: # Insert the current song to play again # Att played song info
self.__queue.appendleft(played_song) if played_song != None:
if not self.__looping_one and not self.__looping_all:
if played_song.problematic == False:
self.__songs_history.appendleft(played_song)
if self.__looping_all: # Insert the current song in the end of queue if len(self.__songs_history) > config.MAX_SONGS_HISTORY:
self.__queue.append(played_song) self.__songs_history.pop() # Remove the older
while True: elif self.__looping_one: # Insert the current song to play again
if len(self.__queue) == 0: self.__queue.appendleft(played_song)
return None
self.__current = self.__queue[0] elif self.__looping_all: # Insert the current song in the end of queue
self.__queue.popleft() self.__queue.append(played_song)
self.__name_history.append(self.__current.identifier)
self.__songs_history.append(self.__current)
return self.__current # Get the new song
if len(self.__queue) == 0:
return None
self.__current = self.__queue.popleft()
return self.__current
def prev_song(self) -> Song:
"""If playing return it to queue and return the previous song to play"""
if len(self.__songs_history) == 0:
return None
else:
if self.__current != None:
self.__queue.appendleft(self.__current)
last_song = self.__songs_history.popleft() # Get the last song
self.__current = last_song
return self.__current # return the song
def add_song(self, identifier: str, requester: str) -> Song: def add_song(self, identifier: str, requester: str) -> Song:
"""Create a song object, add to queue and return it""" """Create a song object, add to queue and return it"""
@ -164,3 +185,12 @@ class Playlist(IPlaylist):
song_name = song.title if song.title else song.identifier song_name = song.title if song.title else song.identifier
return config.SONG_REMOVED_SUCCESSFULLY.format(song_name) return config.SONG_REMOVED_SUCCESSFULLY.format(song_name)
def history(self) -> list:
"""Return a list with the song title of all played songs"""
titles = []
for song in self.__songs_history:
title = song.title if song.title else 'Unknown'
titles.append(title)
return titles