diff --git a/bot.py b/bot.py index c126857..c8bc39e 100644 --- a/bot.py +++ b/bot.py @@ -77,6 +77,9 @@ class Bot(commands.Bot): elif isinstance(err, commands.NoPrivateMessage): await ctx.send('That command is not available in DMs') + + elif isinstance(err, commands.CommandOnCooldown): + await ctx.send(f"{ctx.message.author.mention} Command is on cooldown. Try again in `{err.retry_after:.1f}` seconds.") elif isinstance(err, commands.CheckFailure): print('check failure') diff --git a/cogs/music.py b/cogs/music.py index 4dba0b9..929b610 100644 --- a/cogs/music.py +++ b/cogs/music.py @@ -13,9 +13,13 @@ import discord from discord.ext import commands from typing import Optional +import urllib +import json +from bs4 import BeautifulSoup + from .utils import checks, RoxUtils, timeformatter from .utils.mixplayer import MixPlayer -from .utils.paginator import QueuePaginator, Scroller +from .utils.paginator import QueuePaginator, TextPaginator, Scroller time_rx = re.compile('[0-9]+') @@ -552,6 +556,71 @@ class Music(commands.Cog): embed.set_thumbnail(url=thumb_url) await ctx.send(embed=embed) + + @commands.cooldown(1, 5, commands.BucketType.guild) + @commands.command(name='lyrics') + async def _lyrics(self, ctx, *query: str): + + player = self.bot.lavalink.players.get(ctx.guild.id) + + genius_access_token = self.bot.APIkeys.get('genius', None) + + if genius_access_token is None: + return await ctx.send('Missing API key') + + excluded_words = ["music", "video", "version", "original", "lyrics", + "official", "live","instrumental", "audio", "hd"] + + query = ' '.join(query) + + if not query and player.is_playing: + query = player.current.title + query = re.sub('[-()_]', '', query) + filtered_words = [word for word in query.split() if word.lower() not in excluded_words] + query = ' '.join(filtered_words) + + async def get_site_content(url): + async with self.bot.session.get(url) as resp: + response = await resp.read() + return response.decode('utf-8') + + embed = discord.Embed(description=":mag_right:") + status_msg = await ctx.send(embed=embed) + + try: + url = "https://api.genius.com/search?" + urllib.parse.urlencode({"access_token": genius_access_token, "q": query}) + result = await get_site_content(url) + response = json.loads(result) + song_id = response["response"]["hits"][0]["result"]["id"] + except: + embed = discord.Embed(description=":x:", color=0xFF0000) + return await status_msg.edit(embed=embed) + + result = await get_site_content(f"https://api.genius.com/songs/{song_id}?access_token={genius_access_token}") + song = json.loads(result)["response"]["song"] + + response = await get_site_content(song["url"]) + scraped_data = BeautifulSoup(response, 'html.parser') + lyrics = scraped_data.find(class_='lyrics').get_text() + + paginator = TextPaginator(max_size=2000, max_lines=50, color=0xFFFF64) + for line in lyrics.split('\n'): + paginator.add_line(line) + + await status_msg.delete() + + paginator.pages[0].url=song["url"] + paginator.pages[0].title=song["full_title"] + paginator.pages[0].set_thumbnail(url=song["header_image_thumbnail_url"]) + paginator.pages[0].set_author(name='Genius', icon_url='https://i.imgur.com/NmCTsoF.png') + + if len(paginator.pages) < 4: + for page in paginator.pages: + await ctx.send(embed=page) + else: + paginator.add_page_indicator(ctx.localizer) + scroller = Scroller(ctx, paginator) + await scroller.start_scrolling() @commands.command(name='scrub') @checks.DJ_or(alone=True) @@ -635,7 +704,7 @@ class Music(commands.Cog): # Create returns a player if one exists, otherwise creates. should_connect = ctx.command.callback.__name__ in ('_play', '_find', '_search') # Add commands that require joining voice to work. - without_connect = ctx.command.callback.__name__ in ('_queue', '_history', '_now') # Add commands that don't require the you being in voice. + without_connect = ctx.command.callback.__name__ in ('_queue', '_history', '_now', '_lyrics') # Add commands that don't require the you being in voice. if without_connect: return