Merge pull request #16 from RafaelSolVargas/patch1.2

Patch1.2
This commit is contained in:
Rafael Vargas
2022-01-12 11:38:50 -04:00
committed by GitHub
11 changed files with 339 additions and 308 deletions

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
assets/
__pycache__ __pycache__
.env .env
.cache .cache

View File

@@ -1,13 +1,8 @@
from decouple import config from decouple import config
CETUS_API = config('CETUS_API')
CAMBION_API = config('CAMBION_API')
FISSURES_API = config('FISSURES_API')
BOT_TOKEN = config('BOT_TOKEN') BOT_TOKEN = config('BOT_TOKEN')
SPOTIFY_ID = config('SPOTIFY_ID') SPOTIFY_ID = config('SPOTIFY_ID')
SPOTIFY_SECRET = config('SPOTIFY_SECRET') SPOTIFY_SECRET = config('SPOTIFY_SECRET')
SECRET_MESSAGE = config('SECRET_MESSAGE')
PHRASES_API = config('PHRASES_API')
BOT_PREFIX = '!' BOT_PREFIX = '!'
VC_TIMEOUT = 600 VC_TIMEOUT = 600
@@ -16,40 +11,17 @@ STARTUP_MESSAGE = 'Starting Vulkan...'
STARTUP_COMPLETE_MESSAGE = 'Vulkan is now operating.' STARTUP_COMPLETE_MESSAGE = 'Vulkan is now operating.'
MAX_PLAYLIST_LENGTH = 50 MAX_PLAYLIST_LENGTH = 50
MAX_API_PHRASES_TRIES = 10
MAX_API_CETUS_TRIES = 10
MAX_API_CAMBION_TRIES = 10
MAX_API_FISSURES_TRIES = 10
MAX_PRELOAD_SONGS = 10 MAX_PRELOAD_SONGS = 10
MAX_SONGS_HISTORY = 15
INVITE_MESSAGE = 'To invite Vulkan to your own server, click [here]({})'
SONGINFO_UPLOADER = "Uploader: " SONGINFO_UPLOADER = "Uploader: "
SONGINFO_DURATION = "Duration: " SONGINFO_DURATION = "Duration: "
SONGINFO_REQUESTER = 'Requester: ' SONGINFO_REQUESTER = 'Requester: '
HELP_SKIP = 'Skip the current playing song.'
HELP_RESUME = 'Resumes the song player.'
HELP_CLEAR = 'Clear the queue.'
HELP_STOP = 'Stop the song player, removing Vulkan from voice channel.'
HELP_LOOP = '(one/all/off) - Control the loop of songs.'
HELP_NP = 'Show the info of the current song.'
HELP_QUEUE = f'Show the first {MAX_PRELOAD_SONGS} songs in queue.'
HELP_PAUSE = 'Pauses the song player.'
HELP_SHUFFLE = 'Shuffle the songs playing.'
HELP_PLAY = '(title/youtube/spotify) - Plays a song.'
HELP_MOVE = '(x, y) - Moves a song from position x to y in queue.'
HELP_REMOVE = '(x, -1) - Remove a song in the position x or -1 for the last song.'
HELP_RESET = 'Reset the Player of a server.'
HELP_WARFRAME = f'({BOT_PREFIX}warframe help for more).'
HELP_RANDOM = '(x) - Return a random number between 1 and x.'
HELP_ESCOLHA = '(x, y, z...) - Choose randomly one item passed.'
HELP_CARA = 'Return cara or coroa.'
HELP_DROP = '(user_name) - Try to remove the user from the current voice channel.'
HELP_FRASE = "Send a randomly phrase, perhaps you get the secret."
HELP_HELP = 'This command :)'
HELP_LONG_LOOP = 'Loop Command Help\nOne - Start looping the current song\nAll - Start looping all songs in queue\nOff - Disable the song loop'
SONGS_ADDED = 'You added {} songs to the queue' SONGS_ADDED = 'You added {} songs to the queue'
SONG_ADDED = 'You added the song {} to the queue' SONG_ADDED = 'You added the song `{}` to the queue'
SONG_ADDED_TWO = '🎧 Song added to the queue' SONG_ADDED_TWO = '🎧 Song added to the queue'
SONG_PLAYING = '🎧 Song playing now' SONG_PLAYING = '🎧 Song playing now'
SONG_PLAYER = '🎧 Song Player' SONG_PLAYER = '🎧 Song Player'
@@ -58,19 +30,11 @@ ONE_SONG_LOOPING = '🎧 Looping One Song'
ALL_SONGS_LOOPING = '🎧 Looping All Songs' ALL_SONGS_LOOPING = '🎧 Looping All Songs'
SONG_PAUSED = '⏸️ Song paused' SONG_PAUSED = '⏸️ Song paused'
SONG_RESUMED = '▶️ Song playing' SONG_RESUMED = '▶️ Song playing'
EMPTY_QUEUE = f' Song queue is empty, use {BOT_PREFIX}play to add new songs' EMPTY_QUEUE = f'📜 Song queue is empty, use {BOT_PREFIX}play to add new songs'
SONG_DOWNLOADING = '📥 Downloading...' SONG_DOWNLOADING = '📥 Downloading...'
SONGS_SHUFFLED = '🔀 Songs shuffled successfully' HISTORY_TITLE = '🎧 Played Songs'
ERROR_SHUFFLING = '❌ Error while shuffling the songs' HISTORY_EMPTY = '📜 There is no musics in history'
ERROR_MOVING = '❌ Error while moving the songs'
LENGTH_ERROR = '❌ Numbers must be between 1 and queue length, use -1 for the last song'
ERROR_NUMBER = '❌ This command require a number'
ERROR_PLAYING = '❌ Error while playing songs'
COMMAND_NOT_FOUND = f'❌ Command not found, type {BOT_PREFIX}help to see all commands'
UNKNOWN_ERROR = '❌ Unknown Error'
ERROR_MISSING_ARGUMENTS = f'❌ Missing arguments in this function. Type {BOT_PREFIX}help to see all commands'
ERROR_WHILE_REQUESTING = 'O banco de dados dos cara tá off, bando de vagabundo, tenta depois aí bicho'
SONG_MOVED_SUCCESSFULLY = 'Song `{}` in position `{}` moved with `{}` in position `{}` successfully' SONG_MOVED_SUCCESSFULLY = 'Song `{}` in position `{}` moved with `{}` in position `{}` successfully'
SONG_REMOVED_SUCCESSFULLY = 'Song `{}` removed successfully' SONG_REMOVED_SUCCESSFULLY = 'Song `{}` removed successfully'
@@ -83,15 +47,26 @@ LOOP_ALL_ACTIVATE = '🔁 Looping all songs'
LOOP_ONE_ACTIVATE = '🔂 Looping the current song' LOOP_ONE_ACTIVATE = '🔂 Looping the current song'
LOOP_DISABLE = '➡️ Loop disabled' LOOP_DISABLE = '➡️ Loop disabled'
LOOP_ALREADY_DISABLE = '❌ Loop is already disabled' LOOP_ALREADY_DISABLE = '❌ Loop is already disabled'
LOOP_ON = f'❌ This command cannot be invoked with any loop activated. Use {BOT_PREFIX}loop off to disable loop'
SONGS_PLAYING_TITLES = [ONE_SONG_LOOPING, ALL_SONGS_LOOPING, SONG_PLAYING] SONGS_SHUFFLED = '🔀 Songs shuffled successfully'
ERROR_SHUFFLING = '❌ Error while shuffling the songs'
ERROR_MOVING = '❌ Error while moving the songs'
LENGTH_ERROR = '❌ Numbers must be between 1 and queue length, use -1 for the last song'
ERROR_NUMBER = '❌ This command require a number'
ERROR_PLAYING = '❌ Error while playing songs'
COMMAND_NOT_FOUND = f'❌ Command not found, type {BOT_PREFIX}help to see all commands'
UNKNOWN_ERROR = f'❌ Unknown Error, if needed, use {BOT_PREFIX}reset to reset the player of your server'
ERROR_MISSING_ARGUMENTS = f'❌ Missing arguments in this function. Type {BOT_PREFIX}help to see all commands'
NOT_PREVIOUS = '❌ There is none previous song to play'
PLAYER_NOT_PLAYING = f'❌ No song playing. Use {BOT_PREFIX}play to start the player'
IMPOSSIBLE_MOVE = 'That is impossible :('
ERROR_TITLE = 'Error :-(' ERROR_TITLE = 'Error :-('
NO_CHANNEL = 'To play some music, connect to any voice channel first.' NO_CHANNEL = 'To play some music, connect to any voice channel first.'
NO_GUILD = f'This server are not connected to Vulkan, try {BOT_PREFIX}reset' NO_GUILD = f'This server does not has a Player, try {BOT_PREFIX}reset'
INVALID_INPUT = 'This type of input was too strange, try something better' INVALID_INPUT = f'This type of input was too strange, try something better or type {BOT_PREFIX}help play'
DOWNLOADING_ERROR = 'An error occurred while downloading' DOWNLOADING_ERROR = 'An error occurred while downloading'
EXTRACTING_ERROR = 'An error ocurred while searching for the songs' EXTRACTING_ERROR = 'An error ocurred while searching for the songs'
COLOURS = { COLOURS = {
'red': 0xDC143C, 'red': 0xDC143C,

43
config/help.py Normal file
View File

@@ -0,0 +1,43 @@
from config.config import *
HELP_SKIP = 'Skip the current playing song.'
HELP_SKIP_LONG = 'Skip the playing of the current song, does not work if loop one is activated. \n\nArguments: None.'
HELP_RESUME = 'Resumes the song player.'
HELP_RESUME_LONG = 'If the player if paused, return the playing. \n\nArguments: None.'
HELP_CLEAR = 'Clear the queue and songs history.'
HELP_CLEAR_LONG = 'Clear the songs queue and songs history. \n\nArguments: None.'
HELP_STOP = 'Stop the song player.'
HELP_STOP_LONG = 'Stop the song player, clear queue and history and remove Vulkan from voice channel.\n\nArguments: None.'
HELP_LOOP = 'Control the loop of songs.'
HELP_LOOP_LONG = 'Controll the loop of songs.\n\n Require: A song being played.\nArguments:\nOne - Start looping the current song. \
\nAll - Start looping all songs in queue.\nOff - Disable loop.'
HELP_NP = 'Show the info of the current song.'
HELP_NP_LONG = 'Show the information of the song being played.\n\nRequire: A song being played.\nArguments: None.'
HELP_QUEUE = f'Show the first {MAX_PRELOAD_SONGS} songs in queue.'
HELP_QUEUE_LONG = f'Show the first {MAX_PRELOAD_SONGS} song in the queue.\n\nArguments: None.'
HELP_PAUSE = 'Pauses the song player.'
HELP_PAUSE_LONG = 'If playing, pauses the song player.\n\nArguments: None'
HELP_PREV = 'Play the previous song.'
HELP_PREV_LONG = 'Play the previous song. If playing, the current song will return to queue.\n\nRequire: Loop to be disable.\nArguments: None.'
HELP_SHUFFLE = 'Shuffle the songs playing.'
HELP_SHUFFLE_LONG = 'Randomly shuffle the songs in the queue.\n\nArguments: None.'
HELP_PLAY = 'Plays a song.'
HELP_PLAY_LONG = 'Play a song in discord. \n\nRequire: You to be connected to a voice channel.\nArguments: Youtube or Spotify song/playlist link or the title of the song to be searched in Youtube.'
HELP_HISTORY = f'Show the history of played songs.'
HELP_HISTORY_LONG = f'Show the last {MAX_SONGS_HISTORY} played songs'
HELP_MOVE = 'Moves a song from position x to y in queue.'
HELP_MOVE_LONG = 'Moves a song from position x to position y in queue.\n\nRequire: Positions to be both valid numbers.\nArguments: 1º Number => Initial position, 2º Number => Destination position. Both numbers could be -1 to refer to the last song in queue.\nDefault: By default, if the second number is not passed, it will be 1, moving the selected song to 1º position.'
HELP_REMOVE = 'Remove a song in position x.'
HELP_REMOVE_LONG = 'Remove a song from queue in the position passed.\n\nRequire: Position to be a valid number.\nArguments: 1º Number => Position in queue of the song.'
HELP_RESET = 'Reset the Player of the server.'
HELP_RESET_LONG = 'Reset the Player of the server. Recommended if you find any type of error.\n\nArguments: None'
HELP_HELP = f'Use {BOT_PREFIX}help "command" for more info.'
HELP_HELP_LONG = f'Use {BOT_PREFIX}help command for more info about the command selected.'
HELP_INVITE = 'Send the invite URL to call Vulkan to your server.'
HELP_INVITE_LONG = 'Send an message in text channel with a URL to be used to invite Vulkan to your own server.\n\nArguments: None.'
HELP_RANDOM = 'Return a random number between 1 and x.'
HELP_RANDOM_LONG = 'Send a randomly selected number between 1 and the number you pass.\n\nRequired: Number to be a valid number.\nArguments: 1º Any number to be used as range.'
HELP_CHOOSE = 'Choose randomly one item passed.'
HELP_CHOOSE_LONG = 'Choose randomly one item passed in this command.\n\nRequire: Itens to be separated by comma.\nArguments: As much as you want.'
HELP_CARA = 'Return cara or coroa.'
HELP_CARA_LONG = 'Return cara or coroa.'

View File

@@ -3,6 +3,7 @@ from discord import Client
from discord.ext.commands.errors import CommandNotFound, MissingRequiredArgument from discord.ext.commands.errors import CommandNotFound, MissingRequiredArgument
from discord.ext import commands from discord.ext import commands
from config import config from config import config
from config import help
class Control(commands.Cog): class Control(commands.Cog):
@@ -11,11 +12,12 @@ class Control(commands.Cog):
def __init__(self, bot: Client): def __init__(self, bot: Client):
self.__bot = bot self.__bot = bot
self.__comandos = { self.__comandos = {
'MUSIC': ['resume', 'pause', 'loop', 'stop', 'skip', 'play', 'queue', 'clear', 'np', 'shuffle', 'move', 'remove', 'reset'], 'MUSIC': ['resume', 'pause', 'loop', 'stop',
'WARFRAME': ['warframe'], 'skip', 'play', 'queue', 'clear',
'RANDOM': ['escolha', 'cara', 'random'], 'np', 'shuffle', 'move', 'remove',
'HELP': ['help'], 'reset', 'prev', 'history'],
'OTHERS': ['frase'] 'RANDOM': ['choose', 'cara', 'random']
} }
@commands.Cog.listener() @commands.Cog.listener()
@@ -42,6 +44,7 @@ class Control(commands.Cog):
) )
await ctx.send(embed=embed) await ctx.send(embed=embed)
else: else:
print(error)
embed = discord.Embed( embed = discord.Embed(
title=config.ERROR_TITLE, title=config.ERROR_TITLE,
description=config.UNKNOWN_ERROR, description=config.UNKNOWN_ERROR,
@@ -49,37 +52,70 @@ class Control(commands.Cog):
) )
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name="help", help=config.HELP_HELP, aliases=['h', 'ajuda']) @commands.command(name="help", help=help.HELP_HELP, description=help.HELP_HELP_LONG, aliases=['h', 'ajuda'])
async def help_msg(self, ctx): async def help_msg(self, ctx, command_help=''):
helptxt = '' if command_help != '':
help_music = '🎧 `MUSIC`\n' for command in self.__bot.commands:
help_random = '🎲 `RANDOM`\n' if command.name == command_help:
help_warframe = '🎮 `WARFRAME`\n' txt = command.description if command.description else command.help
help_help = '👾 `HELP`\n'
help_others = '🕹️ `OTHERS`\n'
for command in self.__bot.commands: embedhelp = discord.Embed(
if command.name in self.__comandos['MUSIC']: title=f'**Description of {command_help}** command',
help_music += f'**{command}** - {command.help}\n' description=txt,
elif command.name in self.__comandos['HELP']: colour=config.COLOURS['blue']
help_help += f'**{command}** - {command.help}\n' )
elif command.name in self.__comandos['OTHERS']:
help_others += f'**{command}** - {command.help}\n'
elif command.name in self.__comandos['WARFRAME']:
help_warframe += f'**{command}** - {command.help}\n'
else:
help_random += f'**{command}** - {command.help}\n'
helptxt = f'{help_music}\n{help_warframe}\n{help_random}\n{help_others}\n{help_help}' await ctx.send(embed=embedhelp)
return
embedhelp = discord.Embed( embedhelp = discord.Embed(
title=f'**Available Commands of {self.__bot.user.name}**', title='Command Help',
description=helptxt, description=f'Command {command_help} Not Found',
colour=config.COLOURS['red']
)
await ctx.send(embed=embedhelp)
else:
helptxt = ''
help_music = '🎧 `MUSIC`\n'
help_random = '🎲 `RANDOM`\n'
help_help = '👾 `HELP`\n'
for command in self.__bot.commands:
if command.name in self.__comandos['MUSIC']:
help_music += f'**{command}** - {command.help}\n'
elif command.name in self.__comandos['RANDOM']:
help_random += f'**{command}** - {command.help}\n'
else:
help_help += f'**{command}** - {command.help}\n'
helptxt = f'\n{help_music}\n{help_help}\n{help_random}'
embedhelp = discord.Embed(
title=f'**Available Commands of {self.__bot.user.name}**',
description=helptxt,
colour=config.COLOURS['blue']
)
embedhelp.set_thumbnail(url=self.__bot.user.avatar_url)
await ctx.send(embed=embedhelp)
@commands.command(name='invite', help=help.HELP_INVITE, description=help.HELP_INVITE_LONG)
async def invite_bot(self, ctx):
invite_url = 'https://discordapp.com/oauth2/authorize?client_id={}&scope=bot>'.format(
self.__bot.user.id)
txt = config.INVITE_MESSAGE.format(invite_url)
embed = discord.Embed(
title="Invite Vulkan",
description=txt,
colour=config.COLOURS['blue'] colour=config.COLOURS['blue']
) )
embedhelp.set_thumbnail(url=self.__bot.user.avatar_url) await ctx.send(embed=embed)
await ctx.send(embed=embedhelp)
def setup(bot): def setup(bot):

View File

@@ -2,6 +2,7 @@ import discord
from discord.ext import commands from discord.ext import commands
from config import config from config import config
from config import help
from vulkan.music.Player import Player from vulkan.music.Player import Player
from vulkan.music.utils import * from vulkan.music.utils import *
@@ -13,10 +14,25 @@ class Music(commands.Cog):
@commands.Cog.listener() @commands.Cog.listener()
async def on_ready(self) -> None: async def on_ready(self) -> None:
"""Load a player for each guild that the Bot are"""
for guild in self.__bot.guilds: for guild in self.__bot.guilds:
self.__guilds[guild] = Player(self.__bot, guild) self.__guilds[guild] = Player(self.__bot, guild)
print(f'Player for guild {guild.name} created')
@commands.command(name="play", help=config.HELP_PLAY, aliases=['p', 'tocar']) @commands.Cog.listener()
async def on_guild_join(self, guild) -> None:
"""Load a player when joining a guild"""
self.__guilds[guild] = Player(self.__bot, guild)
print(f'Player for guild {guild.name} created')
@commands.Cog.listener()
async def on_guild_remove(self, guild) -> None:
"""Removes the player of the guild if banned"""
if guild in self.__guilds.keys():
self.__guilds.pop(guild, None)
print(f'Player for guild {guild.name} destroyed')
@commands.command(name="play", help=help.HELP_PLAY, description=help.HELP_PLAY_LONG, aliases=['p', 'tocar'])
async def play(self, ctx, *args) -> None: async def play(self, ctx, *args) -> None:
track = " ".join(args) track = " ".join(args)
requester = ctx.author.name requester = ctx.author.name
@@ -29,12 +45,12 @@ class Music(commands.Cog):
if is_connected(ctx) == None: if is_connected(ctx) == None:
success = await player.connect(ctx) success = await player.connect(ctx)
if success == False: if success == False:
await self.__send_embed(ctx, config.ERROR_TITLE, config.NO_CHANNEL, 'red') await self.__send_embed(ctx, config.IMPOSSIBLE_MOVE, config.NO_CHANNEL, 'red')
return return
await player.play(ctx, track, requester) await player.play(ctx, track, requester)
@commands.command(name="queue", help=config.HELP_QUEUE, aliases=['q', 'fila']) @commands.command(name="queue", help=help.HELP_QUEUE, description=help.HELP_QUEUE_LONG, aliases=['q', 'fila'])
async def queue(self, ctx) -> None: async def queue(self, ctx) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
if player == None: if player == None:
@@ -43,15 +59,15 @@ class Music(commands.Cog):
embed = await player.queue() embed = await player.queue()
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name="skip", help=config.HELP_SKIP, aliases=['s', 'pular']) @commands.command(name="skip", help=help.HELP_SKIP, description=help.HELP_SKIP_LONG, aliases=['s', 'pular'])
async def skip(self, ctx) -> None: async def skip(self, ctx) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
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=help.HELP_STOP, description=help.HELP_STOP_LONG, aliases=['parar'])
async def stop(self, ctx) -> None: async def stop(self, ctx) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
if player == None: if player == None:
@@ -59,7 +75,7 @@ class Music(commands.Cog):
else: else:
await player.stop() await player.stop()
@commands.command(name='pause', help=config.HELP_PAUSE, aliases=['pausar']) @commands.command(name='pause', help=help.HELP_PAUSE, description=help.HELP_PAUSE_LONG, aliases=['pausar'])
async def pause(self, ctx) -> None: async def pause(self, ctx) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
if player == None: if player == None:
@@ -69,7 +85,7 @@ class Music(commands.Cog):
if success: if success:
await self.__send_embed(ctx, config.SONG_PLAYER, config.SONG_PAUSED, 'blue') await self.__send_embed(ctx, config.SONG_PLAYER, config.SONG_PAUSED, 'blue')
@commands.command(name='resume', help=config.HELP_RESUME, aliases=['soltar']) @commands.command(name='resume', help=help.HELP_RESUME, description=help.HELP_RESUME_LONG, aliases=['soltar'])
async def resume(self, ctx) -> None: async def resume(self, ctx) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
if player == None: if player == None:
@@ -79,7 +95,30 @@ 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='loop', help=config.HELP_LOOP, aliases=['l', 'repeat']) @commands.command(name='prev', help=help.HELP_PREV, description=help.HELP_PREV_LONG, 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.IMPOSSIBLE_MOVE, config.NO_CHANNEL, 'red')
return
await player.play_prev(ctx)
@commands.command(name='history', help=help.HELP_HISTORY, description=help.HELP_HISTORY_LONG, 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=help.HELP_LOOP, description=help.HELP_LOOP_LONG, 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)
if player == None: if player == None:
@@ -88,7 +127,7 @@ class Music(commands.Cog):
description = await player.loop(args) description = await player.loop(args)
await self.__send_embed(ctx, config.SONG_PLAYER, description, 'blue') await self.__send_embed(ctx, config.SONG_PLAYER, description, 'blue')
@commands.command(name='clear', help=config.HELP_CLEAR, aliases=['c', 'limpar']) @commands.command(name='clear', help=help.HELP_CLEAR, description=help.HELP_CLEAR_LONG, aliases=['c', 'limpar'])
async def clear(self, ctx) -> None: async def clear(self, ctx) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
if player == None: if player == None:
@@ -96,7 +135,7 @@ class Music(commands.Cog):
else: else:
await player.clear() await player.clear()
@commands.command(name='np', help=config.HELP_NP, aliases=['playing', 'now']) @commands.command(name='np', help=help.HELP_NP, description=help.HELP_NP_LONG, aliases=['playing', 'now'])
async def now_playing(self, ctx) -> None: async def now_playing(self, ctx) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
if player == None: if player == None:
@@ -106,7 +145,7 @@ class Music(commands.Cog):
await self.__clean_messages(ctx) await self.__clean_messages(ctx)
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name='shuffle', help=config.HELP_SHUFFLE, aliases=['aleatorio']) @commands.command(name='shuffle', help=help.HELP_SHUFFLE, description=help.HELP_SHUFFLE_LONG, aliases=['aleatorio'])
async def shuffle(self, ctx) -> None: async def shuffle(self, ctx) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
if player == None: if player == None:
@@ -115,7 +154,7 @@ class Music(commands.Cog):
description = await player.shuffle() description = await player.shuffle()
await self.__send_embed(ctx, config.SONG_PLAYER, description, 'blue') await self.__send_embed(ctx, config.SONG_PLAYER, description, 'blue')
@commands.command(name='move', help=config.HELP_MOVE, aliases=['m', 'mover']) @commands.command(name='move', help=help.HELP_MOVE, description=help.HELP_MOVE_LONG, aliases=['m', 'mover'])
async def move(self, ctx, pos1, pos2='1') -> None: async def move(self, ctx, pos1, pos2='1') -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
if player == None: if player == None:
@@ -124,7 +163,7 @@ class Music(commands.Cog):
description = await player.move(pos1, pos2) description = await player.move(pos1, pos2)
await self.__send_embed(ctx, config.SONG_PLAYER, description, 'blue') await self.__send_embed(ctx, config.SONG_PLAYER, description, 'blue')
@commands.command(name='remove', help=config.HELP_REMOVE, aliases=['remover']) @commands.command(name='remove', help=help.HELP_REMOVE, description=help.HELP_REMOVE_LONG, aliases=['remover'])
async def remove(self, ctx, position) -> None: async def remove(self, ctx, position) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
if player == None: if player == None:
@@ -133,7 +172,7 @@ class Music(commands.Cog):
description = await player.remove(position) description = await player.remove(position)
await self.__send_embed(ctx, config.SONG_PLAYER, description, 'blue') await self.__send_embed(ctx, config.SONG_PLAYER, description, 'blue')
@commands.command(name='reset', help=config.HELP_RESET, aliases=['resetar']) @commands.command(name='reset', help=help.HELP_RESET, description=help.HELP_RESET_LONG, aliases=['resetar'])
async def reset(self, ctx) -> None: async def reset(self, ctx) -> None:
player = self.__get_player(ctx) player = self.__get_player(ctx)
if player != None: if player != None:
@@ -162,8 +201,10 @@ class Music(commands.Cog):
if message.author == self.__bot.user: if message.author == self.__bot.user:
if len(message.embeds) > 0: if len(message.embeds) > 0:
embed = message.embeds[0] embed = message.embeds[0]
if embed.title in config.SONGS_PLAYING_TITLES: if len(embed.fields) > 0:
await message.delete() if embed.fields[0].name == 'Uploader:':
await message.delete()
except: except:
continue continue

View File

@@ -1,60 +0,0 @@
from discord.client import Client
import requests
import json
from config import config
from discord.ext import commands
from random import random as rand
class Phrases(commands.Cog):
"""Deal with the generation of motivational phrases"""
def __init__(self, bot: Client):
self.__bot = bot
@commands.command(name='frase', help=config.HELP_FRASE)
async def phrase(self, ctx):
"""Send some phrase to the requester"""
secret = await self.__calculate_rgn()
if secret != None:
await ctx.send(secret)
else:
phrase = await self.__get_phrase()
await ctx.send(phrase)
async def __calculate_rgn(self):
"""Calculate the chance from the phrase function return a secret custom message"""
x = rand()
if x < 0.15:
return config.SECRET_MESSAGE
else:
return None
async def __get_phrase(self):
"""Get the phrase from the server"""
tries = 0
while True:
tries += 1
if tries > config.MAX_API_PHRASES_TRIES:
return config.ERROR_WHILE_REQUEST
return 'O banco de dados dos cara tá off, bando de vagabundo, tenta depois aí bicho'
try:
response = requests.get(config.PHRASES_API)
data = json.loads(response.content)
phrase = data['quoteText']
author = data['quoteAuthor']
if phrase == '' or author == '':
continue
text = f'{phrase} \nBy: {author}'
return text
except:
continue
def setup(bot):
bot.add_cog(Phrases(bot))

View File

@@ -2,6 +2,7 @@ from random import randint, random
import discord import discord
from discord.ext import commands from discord.ext import commands
from config import config from config import config
from config import help
class Random(commands.Cog): class Random(commands.Cog):
@@ -10,14 +11,14 @@ class Random(commands.Cog):
def __init__(self, bot): def __init__(self, bot):
self.__bot = bot self.__bot = bot
@commands.command(name='random', help=config.HELP_RANDOM) @commands.command(name='random', help=help.HELP_RANDOM, description=help.HELP_RANDOM_LONG)
async def random(self, ctx, arg: str): async def random(self, ctx, arg: str) -> None:
try: try:
arg = int(arg) arg = int(arg)
except Exception as e: except:
embed = discord.Embed( embed = discord.Embed(
description='Manda um número aí ow animal', description=config.ERROR_NUMBER,
colour=config.COLOURS['red'] colour=config.COLOURS['red']
) )
await ctx.send(embed=embed) await ctx.send(embed=embed)
@@ -32,14 +33,14 @@ class Random(commands.Cog):
x = randint(a, b) x = randint(a, b)
embed = discord.Embed( embed = discord.Embed(
title=f'Número Aleatório entre {a, b}', title=f'Random number between [{a, b}]',
description=x, description=x,
colour=config.COLOURS['green'] colour=config.COLOURS['green']
) )
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name='cara', help=config.HELP_CARA) @commands.command(name='cara', help=help.HELP_CARA, description=help.HELP_CARA_LONG)
async def cara(self, ctx): async def cara(self, ctx) -> None:
x = random() x = random()
if x < 0.5: if x < 0.5:
result = 'cara' result = 'cara'
@@ -48,13 +49,13 @@ class Random(commands.Cog):
embed = discord.Embed( embed = discord.Embed(
title='Cara Cora', title='Cara Cora',
description=f'Resultado: {result}', description=f'Result: {result}',
colour=config.COLOURS['green'] colour=config.COLOURS['green']
) )
await ctx.send(embed=embed) await ctx.send(embed=embed)
@commands.command(name='escolha', help=config.HELP_ESCOLHA) @commands.command(name='choose', help=help.HELP_CHOOSE, description=help.HELP_CHOOSE_LONG)
async def escolher(self, ctx, *args: str): async def choose(self, ctx, *args: str) -> None:
try: try:
user_input = " ".join(args) user_input = " ".join(args)
itens = user_input.split(sep=',') itens = user_input.split(sep=',')
@@ -62,16 +63,16 @@ class Random(commands.Cog):
index = randint(0, len(itens)-1) index = randint(0, len(itens)-1)
embed = discord.Embed( embed = discord.Embed(
title='Escolha de algo', title='Choose something',
description=itens[index], description=itens[index],
colour=config.COLOURS['green'] colour=config.COLOURS['green']
) )
await ctx.send(embed=embed) await ctx.send(embed=embed)
except Exception as e: except:
embed = discord.Embed( embed = discord.Embed(
title='Escolha de algo', title='Choose something.',
description='Erro: Envie várias coisas separadas por vírgula', description=f'Error: Use {config.BOT_PREFIX}help choose to understand this command.',
colour=config.COLOURS['green'] colour=config.COLOURS['red']
) )
await ctx.send(embed=embed) await ctx.send(embed=embed)

View File

@@ -1,118 +0,0 @@
import requests
import json
import discord
from discord.ext import commands
from config import config
from discord import Embed
class Warframe(commands.Cog):
"""Deal with the generation of warframe data"""
def __init__(self, bot: discord.Client):
self.__bot = bot
self.__open_functions = ['cetus', 'cambion', 'fissures']
@commands.command(name='warframe', help=config.HELP_WARFRAME)
async def warframe(self, ctx, arg) -> Embed:
if arg in self.__open_functions:
function = getattr(Warframe, f'_Warframe__{arg}')
embed = await function(self)
await ctx.send(embed=embed)
else:
info = f'Warframe commands: {self.__open_functions}'
embed = Embed(
title='Invalid Command',
description=info,
colour=config.COLOURS['blue']
)
await ctx.send(embed=embed)
async def __cetus(self) -> Embed:
description = await self.__get_cetus()
embed = discord.Embed(
title='Warframe Cetus Timing',
description=description,
colour=config.COLOURS['blue']
)
return embed
async def __get_cetus(self) -> str:
"""Return the information of the Warframe API"""
tries = 0
while True:
tries += 1
if tries > config.MAX_API_CETUS_TRIES:
return 'Os DE baiano não tão com o banco de dados ligado'
try:
response = requests.get(config.CETUS_API)
data = json.loads(response.content)
short = data['shortString']
return short
except Exception as e:
continue
async def __cambion(self) -> Embed:
description = await self.__get_cambion()
embed = discord.Embed(
title='Warframe Cambion Timing',
description=description,
colour=config.COLOURS['blue']
)
return embed
async def __get_cambion(self) -> str:
"""Return the information of the Warframe API"""
tries = 0
while True:
tries += 1
if tries > config.MAX_API_CAMBION_TRIES:
return 'Os DE baiano não tão com o banco de dados ligado'
try:
response = requests.get(config.CAMBION_API)
data = json.loads(response.content)
info = f'**Active:** {data["active"]}\n**Time Left:** {data["timeLeft"]}'
return info
except:
continue
async def __fissures(self) -> Embed:
description = await self.__get_fissures()
embed = discord.Embed(
title='Warframe Fissures Status',
description=description,
colour=config.COLOURS['blue']
)
return embed
async def __get_fissures(self) -> str:
"""Return the information of the Warframe API"""
tries = 0
while True:
tries += 1
if tries > config.MAX_API_FISSURES_TRIES:
return 'Os DE baiano não tão com o banco de dados ligado'
try:
response = requests.get(config.FISSURES_API)
data = json.loads(response.content)
info = ''
for pos, fissure in enumerate(data, start=1):
info += f'`{pos}` - **Mission:** {fissure["missionType"]} | **Type:** {fissure["tier"]} | **Timing:** {fissure["eta"]} | **Storm:** {fissure["isStorm"]}\n'
return info
except Exception as e:
continue
def setup(bot):
bot.add_cog(Warframe(bot))

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':
@@ -206,7 +271,7 @@ class Player(commands.Cog):
elif args == 'off': elif args == 'off':
description = self.__playlist.loop_off() description = self.__playlist.loop_off()
else: else:
description = config.HELP_LONG_LOOP description = help.HELP_LONG_LOOP
return description return description
@@ -214,6 +279,14 @@ class Player(commands.Cog):
self.__playlist.clear() self.__playlist.clear()
async def now_playing(self) -> discord.Embed: async def now_playing(self) -> discord.Embed:
if not self.__playing:
embed = discord.Embed(
title=config.SONG_PLAYER,
description=config.PLAYER_NOT_PLAYING,
colour=config.COLOURS['blue']
)
return embed
if self.__playlist.looping_one: if self.__playlist.looping_one:
title = config.ONE_SONG_LOOPING title = config.ONE_SONG_LOOPING
else: else:
@@ -235,6 +308,9 @@ class Player(commands.Cog):
return config.ERROR_SHUFFLING return config.ERROR_SHUFFLING
async def move(self, pos1, pos2='1') -> str: async def move(self, pos1, pos2='1') -> str:
if not self.__playing:
return config.PLAYER_NOT_PLAYING
try: try:
pos1 = int(pos1) pos1 = int(pos1)
pos2 = int(pos2) pos2 = int(pos2)
@@ -250,6 +326,9 @@ class Player(commands.Cog):
async def remove(self, position) -> str: async def remove(self, position) -> str:
"""Remove a song from the queue in the position""" """Remove a song from the queue in the position"""
if not self.__playing:
return config.PLAYER_NOT_PLAYING
try: try:
position = int(position) position = int(position)

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"""
@@ -79,7 +100,6 @@ class Playlist(IPlaylist):
def clear(self) -> None: def clear(self) -> None:
"""Clear the songs to play song history""" """Clear the songs to play song history"""
self.__queue.clear() self.__queue.clear()
self.__songs_history.clear()
def loop_one(self) -> str: def loop_one(self) -> str:
"""Try to start the loop of the current song """Try to start the loop of the current song
@@ -164,3 +184,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

View File

@@ -6,7 +6,11 @@ from config import config
def is_connected(ctx): def is_connected(ctx):
try: try:
voice_channel = ctx.guild.voice_client.channel voice_channel = ctx.guild.voice_client.channel
return voice_channel
if not ctx.guild.voice_client.is_connected():
return None
else:
return voice_channel
except: except:
return None return None