Stylish update

This commit is contained in:
Rafael Vargas
2022-01-08 17:07:02 -04:00
parent 13bc51fae7
commit ef2d7bb8fa
10 changed files with 228 additions and 180 deletions

View File

@@ -64,7 +64,6 @@ class Downloader():
except (ExtractorError, DownloadError) as e:
return None
else:
print('Invalid type of playlist URL')
return None
async def preload(self, songs: list) -> None:

View File

@@ -24,10 +24,6 @@ class IPlaylist(ABC):
def next_song(self):
pass
@abstractmethod
def prev_song(self):
pass
@abstractmethod
def add_song(self, identifier: str) -> None:
pass

View File

@@ -1,4 +1,5 @@
import discord
from discord import colour
from discord.ext import commands
from config import config
import datetime
@@ -25,41 +26,53 @@ class Player(commands.Cog):
self.FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5',
'options': '-vn'}
async def connect(self, ctx):
async def connect(self, ctx) -> None:
if not ctx.author.voice:
return {'success': False, 'reason': config.NO_CHANNEL}
return False
if self.__guild.voice_client == None:
await ctx.author.voice.channel.connect(reconnect=True, timeout=None)
return {'success': True, 'reason': ''}
return True
def __play_next(self, error, ctx) -> None:
if error != None:
return
def __play_next(self, error, ctx):
song = self.__playlist.next_song()
if song != None: # If there is not a song for the song
if song != None:
coro = self.__play_music(ctx, song)
self.__bot.loop.create_task(coro)
else:
self.__playing = False
async def __play_music(self, ctx, song):
self.__playing = True
async def __play_music(self, ctx, song) -> None:
try:
self.__playing = True
player = discord.FFmpegPCMAudio(song.source, **self.FFMPEG_OPTIONS)
self.__guild.voice_client.play(
player, after=lambda e: self.__play_next(e, ctx))
player = discord.FFmpegPCMAudio(song.source, **self.FFMPEG_OPTIONS)
self.__guild.voice_client.play(
player, after=lambda e: self.__play_next(e, ctx))
self.__timer.cancel()
self.__timer = Timer(self.__timeout_handler)
self.__timer.cancel()
self.__timer = Timer(self.__timeout_handler)
await ctx.invoke(self.__bot.get_command('np'))
await ctx.invoke(self.__bot.get_command('np'))
songs = self.__playlist.songs_to_preload
await self.__down.preload(songs)
songs = self.__playlist.songs_to_preload
await self.__down.preload(songs)
except:
embed = discord.Embed(
title=config.ERROR_TITLE,
description=config.ERROR_PLAYING,
colour=config.COLOURS['red']
)
await ctx.send(embed=embed)
return
async def play(self, ctx, track, requester) -> str:
async def play(self, ctx, track=str, requester=str) -> str:
try:
songs_names, provider = self.__searcher.search(track)
if provider == Provider.Unknown:
if provider == Provider.Unknown or songs_names == None:
embed = discord.Embed(
title=config.ERROR_TITLE,
description=config.INVALID_INPUT,
@@ -78,7 +91,7 @@ class Player(commands.Cog):
songs_preload = self.__playlist.songs_to_preload
await self.__down.preload(songs_preload)
except:
except Exception as e:
embed = discord.Embed(
title=config.ERROR_TITLE,
description=config.DOWNLOADING_ERROR,
@@ -98,16 +111,16 @@ class Player(commands.Cog):
return
elif not self.__playing:
embed = discord.Embed(
title=config.SONG_QUEUE_TITLE,
title=config.SONG_PLAYER,
description=config.SONG_ADDED.format(song.title),
colour=config.COLOURS['blue'])
await ctx.send(embed=embed)
else:
embed = self.__format_embed(song.info, config.SONG_ADDED)
embed = self.__format_embed(song.info, config.SONG_ADDED_TWO)
await ctx.send(embed=embed)
else:
embed = discord.Embed(
title=config.SONG_QUEUE_TITLE,
title=config.SONG_PLAYER,
description=config.SONGS_ADDED.format(songs_quant),
colour=config.COLOURS['blue'])
await ctx.send(embed=embed)
@@ -115,7 +128,7 @@ class Player(commands.Cog):
if not self.__playing:
try_another = True
while try_another: # This will ensure the first song source to be ready
while try_another: # will ensure the first song source to be ready
first_song = self.__playlist.next_song()
if first_song == None:
embed = discord.Embed(
@@ -139,26 +152,32 @@ class Player(commands.Cog):
async def queue(self) -> discord.Embed:
if self.__playlist.looping_one:
info = self.__playlist.current.info
title = 'Song Looping Now'
title = config.ONE_SONG_LOOPING
return self.__format_embed(info, title)
songs_preload = self.__playlist.songs_to_preload
await self.__down.preload(songs_preload)
total_time = format_time(sum([int(song.duration if song.duration else 0)
for song in songs_preload])) # Sum the duration
total_songs = len(self.__playlist)
text = f'Total musics: {total_songs} | Duration: `{total_time}` downloaded \n\n'
for pos, song in enumerate(songs_preload, start=1):
title = song.title if song.title else 'Downloading...'
text += f"**`{pos}` - ** {title} - `{format_time(song.duration)}`\n"
if len(songs_preload) == 0:
title = config.SONG_PLAYER
text = config.EMPTY_QUEUE
title = 'Songs in Queue'
if len(songs_preload) > 0:
if self.__playlist.looping_all:
title = 'Repeating All'
else:
text = 'There is no musics in queue'
if self.__playlist.looping_all:
title = config.ALL_SONGS_LOOPING
else:
title = 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 config.SONG_DOWNLOADING
text += f"**`{pos}` - ** {song_name} - `{format_time(song.duration)}`\n"
embed = discord.Embed(
title=title,
@@ -202,7 +221,7 @@ class Player(commands.Cog):
self.__guild.voice_client.resume()
return True
async def loop(self, args: str):
async def loop(self, args: str) -> str:
args = args.lower()
if args == 'one':
description = self.__playlist.loop_one()
@@ -211,7 +230,7 @@ class Player(commands.Cog):
elif args == 'off':
description = self.__playlist.loop_off()
else:
description = 'Comando Loop\nOne - Repete a música atual\nAll - Repete as músicas atuais\nOff - Desativa o loop'
description = config.HELP_LONG_LOOP
return description
@@ -220,9 +239,9 @@ class Player(commands.Cog):
async def now_playing(self) -> discord.Embed:
if self.__playlist.looping_one:
title = 'Song Looping Now'
title = config.ONE_SONG_LOOPING
else:
title = 'Song Playing Now'
title = config.SONG_PLAYING
current_song = self.__playlist.current
embed = self.__format_embed(current_song.info, title)
@@ -235,9 +254,9 @@ class Player(commands.Cog):
songs = self.__playlist.songs_to_preload
await self.__down.preload(songs)
return 'Musics shuffled successfully'
return config.SONGS_SHUFFLED
except:
return 'An error ocurred :/'
return config.ERROR_SHUFFLING
async def move(self, pos1, pos2='1') -> str:
try:
@@ -245,7 +264,7 @@ class Player(commands.Cog):
pos2 = int(pos2)
except:
return 'This command require a number'
return config.ERROR_NUMBER
result = self.__playlist.move_songs(pos1, pos2)
@@ -259,12 +278,12 @@ class Player(commands.Cog):
position = int(position)
except:
return 'This command require a number'
return config.ERROR_NUMBER
result = self.__playlist.remove_song(position)
return result
def __format_embed(self, info, title='') -> discord.Embed:
def __format_embed(self, info=dict, title='') -> discord.Embed:
"""Configure the embed to show the song information"""
embedvc = discord.Embed(
title=title,

View File

@@ -41,42 +41,27 @@ class Playlist(IPlaylist):
def next_song(self) -> Song:
"""Return the next song to play"""
if self.__current == None and len(self.__queue) == 0:
# If not playing and nothing to play
return None
# If playing
played_song = self.__current
# Check if need to repeat the played song
if self.__looping_one: # Insert the current song to play again
self.__queue.appendleft(played_song)
if self.__looping_all: # Insert the current song in the end of queue
self.__queue.append(played_song)
while True: # Try to get the source of next song
if len(self.__queue) == 0: # If no more song to play, return None
while True:
if len(self.__queue) == 0:
return None
# Att the current with the first one
self.__current = self.__queue[0]
self.__queue.popleft() # Remove the current from queue
self.__name_history.append(
self.__current.identifier) # Add to name history
self.__songs_history.append(self.__current) # Add to song history
self.__queue.popleft()
self.__name_history.append(self.__current.identifier)
self.__songs_history.append(self.__current)
return self.__current
def prev_song(self) -> Song:
"""Return the source of the last song played
Return None or the source of the prev song
"""
if len(self.__songs_history) == 0:
return None
else:
return self.__songs_history[0].source
def add_song(self, identifier: str, requester: str) -> Song:
"""Create a song object, add to queue and return it"""
song = Song(identifier=identifier, playlist=self, requester=requester)
@@ -102,12 +87,13 @@ class Playlist(IPlaylist):
Return: Embed descrition to show to user
"""
if self.__looping_all == True:
return 'Vulkan already looping one music, disable loop first'
return config.LOOP_ALL_ON
elif self.__looping_one == True:
return "I'm already doing this, you dumb ass"
return config.LOOP_ONE_ALREADY_ON
else:
self.__looping_one = True
return 'Repeating the current song'
return config.LOOP_ONE_ACTIVATE
def loop_all(self) -> str:
"""Try to start the loop of all songs
@@ -115,21 +101,23 @@ class Playlist(IPlaylist):
Return: Embed descrition to show to user
"""
if self.__looping_one == True:
return 'Vulkan already looping one music, disable loop first'
return config.LOOP_ONE_ON
elif self.__looping_all == True:
return "I'm already doing this, you dumb ass"
return config.LOOP_ALL_ALREADY_ON
else:
self.__looping_all = True
return 'Repeating all songs in queue'
return config.LOOP_ALL_ACTIVATE
def loop_off(self) -> str:
"""Disable both types of loop"""
if self.__looping_all == False and self.__looping_one == False:
return "The loop is already off, you fucking dick head"
return config.LOOP_ALREADY_DISABLE
self.__looping_all = False
self.__looping_one = False
return 'Loop disable'
return config.LOOP_DISABLE
def destroy_song(self, song_destroy: Song) -> None:
"""Destroy a song object from the queue"""
@@ -150,7 +138,7 @@ class Playlist(IPlaylist):
pos2 = len(self.__queue)
if pos2 not in range(1, len(self.__queue) + 1) or pos1 not in range(1, len(self.__queue) + 1):
return 'Numbers must be between 1 and queue length, or -1 for the last song'
return config.LENGTH_ERROR
try:
song1 = self.__queue[pos1-1]
@@ -162,18 +150,17 @@ class Playlist(IPlaylist):
song1_name = song1.title if song1.title else song1.identifier
song2_name = song2.title if song2.title else song2.identifier
return f'Song `{song1_name}` in position `{pos1}` moved with `{song2_name}` in position `{pos2}` successfully'
except Exception as e:
print(e)
return 'There was a problem with the moving of songs'
return config.SONG_MOVED_SUCCESSFULLY.format(song1_name, pos1, song2_name, pos2)
except:
return config.ERROR_MOVING
def remove_song(self, position) -> tuple:
def remove_song(self, position) -> str:
if position not in range(1, len(self.__queue) + 1) and position != -1:
return 'Numbers must be between 1 and queue length, or -1 for the last song'
return config.LENGTH_ERROR
else:
song = self.__queue[position-1]
self.__queue.remove(song)
song_name = song.title if song.title else song.identifier
return f'Song `{song_name}` removed successfully'
return config.SONG_REMOVED_SUCCESSFULLY.format(song_name)

View File

@@ -24,7 +24,7 @@ class SpotifySearch():
except:
return False
def search(self, music) -> list:
def search(self, music=str) -> list:
"""Search and return the title of musics on Spotify"""
type = music.split('/')[3].split('?')[0]
code = music.split('/')[4].split('?')[0]
@@ -39,14 +39,13 @@ class SpotifySearch():
return musics
def __get_album(self, code) -> list:
def __get_album(self, code=str) -> list:
"""Get the externals urls of a album
ARG: Spotify Code of the Album
ARG: Spotify Code of the Album
"""
if self.__connected == True:
try:
# Load all music objects
results = self.__api.album_tracks(code)
musics = results['items']
@@ -66,10 +65,10 @@ class SpotifySearch():
except Exception as e:
raise e
def __get_playlist(self, code) -> list:
def __get_playlist(self, code=str) -> list:
"""Get the externals urls of a playlist
Arg: Spotify Code of the Playlist
Arg: Spotify Code of the Playlist
"""
try:
results = self.__api.playlist_items(code)
@@ -96,10 +95,10 @@ class SpotifySearch():
except Exception as e:
raise e
def __get_track(self, code) -> list:
def __get_track(self, code=str) -> list:
"""Convert a external_url track to the title of the music
ARG: Spotify Code of the Music
ARG: Spotify Code of the Music
"""
results = self.__api.track(code)
name = results['name']
@@ -112,7 +111,7 @@ class SpotifySearch():
def __extract_title(self, music: dict) -> str:
"""Receive a spotify music object and return his title
ARG: music dict returned by Spotify
ARG: music dict returned by Spotify
"""
title = f'{music["name"]} '
for artist in music['artists']:

View File

@@ -11,7 +11,7 @@ def is_connected(ctx):
return None
def format_time(duration):
def format_time(duration) -> str:
if not duration:
return "00:00"