From 9ea0eb2444650e81eb21bf9a5e50244a3f871418 Mon Sep 17 00:00:00 2001 From: solaluset <60041069+solaluset@users.noreply.github.com> Date: Mon, 25 Mar 2024 18:32:52 +0200 Subject: [PATCH 1/2] make get_soup universal --- musicbot/linkutils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/musicbot/linkutils.py b/musicbot/linkutils.py index 33a9adea..22630755 100644 --- a/musicbot/linkutils.py +++ b/musicbot/linkutils.py @@ -102,7 +102,7 @@ class Origins(Enum): async def get_soup(url: str) -> BeautifulSoup: - async with _session.get(spotify_regex.match(url).group()) as response: + async with _session.get(url) as response: response.raise_for_status() page = await response.text() @@ -112,6 +112,8 @@ async def get_soup(url: str) -> BeautifulSoup: async def fetch_spotify(url: str) -> Optional[Union[dict, List[str]]]: """Searches YouTube for Spotify song or loads Spotify playlist""" match = spotify_regex.match(url) + # strip any extra parts + url = match.group() url_type = match.group("type") if url_type != "track": return await fetch_spotify_playlist(url, url_type, match.group("code")) From 4a8e409b628fd956bc6a08e349c68a5129f999c9 Mon Sep 17 00:00:00 2001 From: solaluset <60041069+solaluset@users.noreply.github.com> Date: Mon, 25 Mar 2024 19:11:42 +0200 Subject: [PATCH 2/2] add suno.ai extractor --- musicbot/yt_dlp_plugins/extractor/suno.py | 24 +++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 musicbot/yt_dlp_plugins/extractor/suno.py diff --git a/musicbot/yt_dlp_plugins/extractor/suno.py b/musicbot/yt_dlp_plugins/extractor/suno.py new file mode 100644 index 00000000..c8b9d4ff --- /dev/null +++ b/musicbot/yt_dlp_plugins/extractor/suno.py @@ -0,0 +1,24 @@ +import re + +from yt_dlp import DownloadError +from yt_dlp.extractor.common import InfoExtractor + + +class SunoAIIE(InfoExtractor): + _VALID_URL = r"^https?://app\.suno\.ai/song/(?P\w+)" + + def _real_extract(self, url): + from musicbot.loader import _loop + from musicbot.linkutils import get_soup + + match = re.match(self._VALID_URL, url) + try: + soup = _loop.run_until_complete(get_soup(url)) + return { + "id": match.group("code"), + "url": soup.find(property="og:audio")["content"], + "title": re.sub(r" \| Suno$", "", soup.find("title").string), + "thumbnail": soup.find(property="og:image")["content"], + } + except Exception as e: + raise DownloadError(str(e)) from e