import requests import urllib.parse import os.path import os import sys sys.path.append("/yt-dlp") import yt_dlp def lastfm_search(query: str) -> tuple[str, str]: response = requests.get( url="https://ws.audioscrobbler.com/2.0/?method=track.search&format=json", params={"limit": 5, "track": query, "api_key": os.environ["LASTFM_API_KEY"]}, ) assert response.status_code == 200 track_info = response.json()["results"]["trackmatches"]["track"][0] return track_info["name"], track_info["artist"] def lastfm_getinfo(name: str, artist: str) -> tuple[str, str, str, str, list[str]]: # ( id, image_id, tags ) response = requests.get( url="https://ws.audioscrobbler.com/2.0/?method=track.getInfo&format=json", params={ "track": name, "artist": artist, "api_key": os.environ["LASTFM_API_KEY"], }, ) track_info = response.json()["track"] image_url = urllib.parse.urlparse(track_info["album"]["image"][0]["#text"]) return ( track_info["mbid"], [t["name"] for t in track_info["toptags"]["tag"]], os.path.splitext(os.path.basename(image_url.path))[0], ) def download_song_mp3(name: str, artist: str) -> tuple[str, str] | None: # ( id, audio ) ydl_opts = { "format": "bestaudio", "default_search": "ytsearch1", "outtmpl": "%(title)s.%(ext)s", "skip_download": True, } with yt_dlp.YoutubeDL(ydl_opts) as ydl: info = ydl.extract_info(f"{name!r} - {artist!r}", download=False) first_entry = info["entries"][0] video_id = first_entry["id"] for fmt in first_entry["formats"]: if "acodec" in fmt and fmt["acodec"] != "none": return video_id, fmt["url"] return None