From 3a18807bc1049339b1f97586fda10f4ddd09b3a0 Mon Sep 17 00:00:00 2001 From: Choco <94597336+ChocoMeow@users.noreply.github.com> Date: Thu, 22 Feb 2024 18:14:32 +0800 Subject: [PATCH] Added lyrist platform --- README.md | 2 +- addons/lyrics.py | 55 ++++++++++++++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 00a08db..786e15d 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ MONGODB_NAME = Vocard * For `bot_access_user` you can pass the [discord user id](https://support.discord.com/hc/en-us/articles/206346498-Where-can-I-find-my-User-Server-Message-ID-). Example: `[123456789012345678]` * For `embed_color` you must pass a [Hexadecimal color code](https://htmlcolorcodes.com/) and add `0x` before the color code. Example: `"0xb3b3b3"` * For `default_max_queue` you can set a default maximum number of tracks that can be added to the queue. -* For `lyrics_platform` you can set lyrics search engine (e.g. `A_ZLyrics`, `Genius`)
**NOTE: If you are using Genius as your lyrics search engine, you must install the lyricsgenius module (`pip install lyricsgenius`)** +* For `lyrics_platform` you can set lyrics search engine (e.g. `A_ZLyrics`, `Genius`, `lyrist`)
**NOTE: If you are using Genius as your lyrics search engine, you must install the lyricsgenius module (`pip install lyricsgenius`)** * For `ipc_server` you can set the host, password and enable of the ipc server. * For `emoji_source_raw` you can change the source emoji of the track with discord emoji like `<:EMOJI_NAME:EMOJI_ID>` * For `cooldowns` you can set a custom cooldown in the command. Example: `"command_name": [The total number of tokens available, The length of the cooldown period in seconds]` diff --git a/addons/lyrics.py b/addons/lyrics.py index 6f51c09..4fd3320 100644 --- a/addons/lyrics.py +++ b/addons/lyrics.py @@ -5,6 +5,7 @@ from abc import ABC, abstractmethod from urllib.parse import quote from math import floor from importlib import import_module +from typing import Optional userAgents = '''Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36 Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36 @@ -47,13 +48,15 @@ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-US) AppleWebKit/530.9 (KHTM Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-US) AppleWebKit/530.6 (KHTML, like Gecko) Chrome/ Safari/530.6 Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_6; en-US) AppleWebKit/530.5 (KHTML, like Gecko) Chrome/ Safari/530.5''' +LYRIST_ENDPOINT = "https://lyrist.vercel.app/api/" + class LyricsPlatform(ABC): @abstractmethod - async def getLyrics(): + async def get_lyrics(self, title: str, artist: str) -> Optional[dict[str, str]]: ... class A_ZLyrics(LyricsPlatform): - async def get(self, url): + async def get(self, url) -> str: try: async with aiohttp.ClientSession() as session: resp = await session.get(url=url, headers={'User-Agent': random.choice(userAgents)}) @@ -63,13 +66,12 @@ class A_ZLyrics(LyricsPlatform): except: return "" - async def getLyrics(self, title: str): - link = await self.googleGet(title=title) + async def get_lyrics(self, title: str, artist: str) -> dict[str, str]: + link = await self.googleGet(title=title, artist=artist) if not link: return 0 page = await self.get(link) - metadata = [elm.text for elm in self.htmlFindAll(page)('b')] if not metadata: @@ -85,21 +87,19 @@ class A_ZLyrics(LyricsPlatform): if not lyrics: return print("Lyrics not found") - rr = re.split(r"(\[[\w\S_ ]+\:])", lyrics) - for item in rr: - if item == "": - rr.remove(item) + lyrics_parts = re.split(r"(\[[\w\S_ ]+\:])", lyrics) + lyrics_parts = [item for item in lyrics_parts if item != ""] - count = len(rr) + count = len(lyrics_parts) if count > 1: if (count % 2) != 0: - del rr[count-1] - return {rr[i].replace("[", "").replace(":]", ""): self.clearText(rr[i + 1]) for i in range(0, len(rr), 2)} - return {"default": self.clearText(rr[0])} + del lyrics_parts[count-1] + return {lyrics_parts[i].replace("[", "").replace(":]", ""): self.clearText(lyrics_parts[i + 1]) for i in range(0, len(lyrics_parts), 2)} + return {"default": self.clearText(lyrics_parts[0])} except: return None - async def googleGet(self, acc = 0.6, artist='', title=''): + async def googleGet(self, acc = 0.6, artist='', title='') -> Optional[str]: data = artist + ' ' * (title != '' and artist != '') + title encoded_data = quote(data.replace(' ', '+')) @@ -125,7 +125,7 @@ class A_ZLyrics(LyricsPlatform): return None return None - def jaro_distance(self, s1, s2): + def jaro_distance(self, s1, s2) -> int: if (s1 == s2): return 1.0 @@ -160,11 +160,11 @@ class A_ZLyrics(LyricsPlatform): return (match/ len1 + match / len2 + (match - t + 1) / match)/ 3.0 - def htmlFindAll(self, page): + def htmlFindAll(self, page) -> list: soup = bs4.BeautifulSoup(page, "html.parser") return soup.findAll - def clearText(self, text: str): + def clearText(self, text: str) -> str: if text.startswith("\n\n"): text = text.replace("\n\n", "", 1) @@ -175,14 +175,29 @@ class Genius(LyricsPlatform): self.module = import_module("lyricsgenius") self.genius = self.module.Genius(func.tokens.genius_token) - async def getLyrics(self, name: str): - song = self.genius.search_song(title=name) + async def get_lyrics(self, title: str, artist: str) -> Optional[dict[str, str]]: + song = self.genius.search_song(title=title, artist=artist) if not song: return None return {"default": song.lyrics} +class Lyrist(LyricsPlatform): + async def get_lyrics(self, title: str, artist: str) -> Optional[dict[str, str]]: + try: + request_url = LYRIST_ENDPOINT + title + "/" + artist + async with aiohttp.ClientSession() as session: + resp = await session.get(url=request_url, headers={'User-Agent': random.choice(userAgents)}) + if resp.status != 200: + return None + + data = await resp.json() + return {"default": data["lyrics"]} + except: + return None + lyricsPlatform: dict[str, LyricsPlatform] = { "a_zlyrics": A_ZLyrics, - "genius": Genius + "genius": Genius, + "lyrist": Lyrist } \ No newline at end of file