From 73e1eeeb6bf36989517cf6f26eff10c056152810 Mon Sep 17 00:00:00 2001 From: nathom Date: Mon, 12 Apr 2021 13:06:55 -0700 Subject: [PATCH] Threaded lastfm search Also fix source_subdirectory option --- streamrip/core.py | 49 +++++++++++++++++++++++++++-------------- streamrip/downloader.py | 15 +++---------- 2 files changed, 36 insertions(+), 28 deletions(-) diff --git a/streamrip/core.py b/streamrip/core.py index 79fb889..ef79812 100644 --- a/streamrip/core.py +++ b/streamrip/core.py @@ -1,8 +1,8 @@ -import asyncio import logging import os import re import sys +import threading from getpass import getpass from hashlib import md5 from string import Formatter @@ -172,11 +172,12 @@ class MusicDL(list): ], } logger.debug("Arguments from config: %s", arguments) + + source_subdirs = self.config.session['downloads']['source_subdirectories'] for item in self: - if self.config.session["downloads"]["source_subdirectories"]: - arguments["parent_folder"] = os.path.join( - arguments["parent_folder"], capitalize(item.client.source) - ) + + if source_subdirs: + arguments['parent_folder'] = self.__get_source_subdir(item.client.source) arguments["quality"] = self.config.session[item.client.source]["quality"] if isinstance(item, Artist): @@ -269,24 +270,36 @@ class MusicDL(list): def handle_lastfm_urls(self, urls): lastfm_urls = self.lastfm_url_parse.findall(urls) lastfm_source = self.config.session["lastfm"]["source"] + tracks_not_found = 0 + + def search_query(query: str, playlist: Playlist): + global tracks_not_found + try: + track = next(self.search(lastfm_source, query, media_type="track")) + playlist.append(track) + except NoResultsFound: + tracks_not_found += 1 + return + for purl in lastfm_urls: click.secho(f"Fetching playlist at {purl}", fg="blue") title, queries = self.get_lastfm_playlist(purl) - pl = Playlist(client=self.clients[lastfm_source], name=title) - tracks_not_found = 0 - for title, artist in tqdm(queries, unit="tracks", desc="Searching"): + pl = Playlist(client=self.get_client(lastfm_source), name=title) + processes = [] + + for title, artist in queries: query = f"{title} {artist}" + proc = threading.Thread( + target=search_query, args=(query, pl), daemon=True + ) + proc.start() + processes.append(proc) - try: - track = next(self.search(lastfm_source, query, media_type="track")) - except NoResultsFound: - tracks_not_found += 1 - continue - - pl.append(track) - pl.loaded = True + for proc in tqdm(processes, unit="tracks", desc="Searching"): + proc.join() + pl.loaded = True click.secho(f"{tracks_not_found} tracks not found.", fg="yellow") self.append(pl) @@ -471,3 +484,7 @@ class MusicDL(list): remaining_tracks -= 50 return playlist_title, info + + def __get_source_subdir(self, source: str) -> str: + path = self.config.session['parent_folder'] + return os.path.join(path, capitalize(source)) diff --git a/streamrip/downloader.py b/streamrip/downloader.py index 98fda3e..c383ac1 100644 --- a/streamrip/downloader.py +++ b/streamrip/downloader.py @@ -1230,11 +1230,7 @@ class Playlist(Tracklist): logger.debug(f"Loaded {len(self)} tracks from playlist {self.name}") - def _prepare_download( - self, - parent_folder: str = "StreamripDownloads", - **kwargs, - ): + def _prepare_download(self, parent_folder: str = "StreamripDownloads", **kwargs): fname = sanitize_filename(self.name) self.folder = os.path.join(parent_folder, fname) @@ -1245,7 +1241,7 @@ class Playlist(Tracklist): if self.client.source == "soundcloud": item.load_meta() - if kwargs.get("set_playlist_to_album", False) and hasattr(self, "image"): + if kwargs.get("set_playlist_to_album", False): item["album"] = self.name item["albumartist"] = self.creator @@ -1253,12 +1249,7 @@ class Playlist(Tracklist): item.meta["tracknumber"] = str(self.__download_index) self.__download_index += 1 - self.downloaded = item.download( - parent_folder=kwargs["parent_folder"], - quality=kwargs.get("quality", 3), - database=kwargs.get("database"), - **kwargs, - ) + self.downloaded = item.download(**kwargs) if self.downloaded and self.client.source != "deezer": item.tag(embed_cover=kwargs.get("embed_cover", True))