mirror of
https://github.com/nathom/streamrip.git
synced 2025-06-03 08:39:00 -04:00
Add lastfm fallback source; #74
This commit is contained in:
parent
68a73e1905
commit
0a5364abef
3 changed files with 71 additions and 34 deletions
|
@ -637,6 +637,9 @@ class Track:
|
||||||
"""
|
"""
|
||||||
return f"{self['artist']} - {self['title']}"
|
return f"{self['artist']} - {self['title']}"
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Video:
|
class Video:
|
||||||
"""Only for Tidal."""
|
"""Only for Tidal."""
|
||||||
|
@ -736,6 +739,9 @@ class Video:
|
||||||
"""
|
"""
|
||||||
return f"<Video - {self.title}>"
|
return f"<Video - {self.title}>"
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Booklet:
|
class Booklet:
|
||||||
"""Only for Qobuz."""
|
"""Only for Qobuz."""
|
||||||
|
@ -766,6 +772,9 @@ class Booklet:
|
||||||
filepath = os.path.join(parent_folder, f"{self.description}.pdf")
|
filepath = os.path.join(parent_folder, f"{self.description}.pdf")
|
||||||
tqdm_download(self.url, filepath)
|
tqdm_download(self.url, filepath)
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Tracklist(list):
|
class Tracklist(list):
|
||||||
"""A base class for tracklist-like objects.
|
"""A base class for tracklist-like objects.
|
||||||
|
@ -1004,6 +1013,9 @@ class Tracklist(list):
|
||||||
if isinstance(key, int):
|
if isinstance(key, int):
|
||||||
super().__setitem__(key, val)
|
super().__setitem__(key, val)
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class YoutubeVideo:
|
class YoutubeVideo:
|
||||||
"""Dummy class implemented for consistency with the Media API."""
|
"""Dummy class implemented for consistency with the Media API."""
|
||||||
|
@ -1094,3 +1106,6 @@ class YoutubeVideo:
|
||||||
:param kwargs:
|
:param kwargs:
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return True
|
||||||
|
|
|
@ -95,7 +95,7 @@ class Config:
|
||||||
},
|
},
|
||||||
"path_format": {"folder": FOLDER_FORMAT, "track": TRACK_FORMAT},
|
"path_format": {"folder": FOLDER_FORMAT, "track": TRACK_FORMAT},
|
||||||
"check_for_updates": True,
|
"check_for_updates": True,
|
||||||
"lastfm": {"source": "qobuz"},
|
"lastfm": {"source": "qobuz", "fallback_source": "deezer"},
|
||||||
"concurrent_downloads": False,
|
"concurrent_downloads": False,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -200,23 +200,11 @@ class MusicDL(list):
|
||||||
try:
|
try:
|
||||||
arguments = self._get_download_args()
|
arguments = self._get_download_args()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
click.secho(
|
self._config_update_message()
|
||||||
"Updating config file... Some settings may be lost. Please run the "
|
|
||||||
"command again.",
|
|
||||||
fg="magenta",
|
|
||||||
)
|
|
||||||
self.config.update()
|
self.config.update()
|
||||||
exit()
|
exit()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
click.secho(
|
self._config_corrupted_message(err)
|
||||||
"There was a problem with your config file. This happens "
|
|
||||||
"sometimes after updates. Run ",
|
|
||||||
nl=False,
|
|
||||||
fg="red",
|
|
||||||
)
|
|
||||||
click.secho("rip config --reset ", fg="yellow", nl=False)
|
|
||||||
click.secho("to reset it. You will need to log in again.", fg="red")
|
|
||||||
click.secho(err, fg="red")
|
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
logger.debug("Arguments from config: %s", arguments)
|
logger.debug("Arguments from config: %s", arguments)
|
||||||
|
@ -363,9 +351,18 @@ class MusicDL(list):
|
||||||
# https://www.last.fm/user/nathan3895/playlists/12058911
|
# https://www.last.fm/user/nathan3895/playlists/12058911
|
||||||
user_regex = re.compile(r"https://www\.last\.fm/user/([^/]+)/playlists/\d+")
|
user_regex = re.compile(r"https://www\.last\.fm/user/([^/]+)/playlists/\d+")
|
||||||
lastfm_urls = self.lastfm_url_parse.findall(urls)
|
lastfm_urls = self.lastfm_url_parse.findall(urls)
|
||||||
|
try:
|
||||||
lastfm_source = self.config.session["lastfm"]["source"]
|
lastfm_source = self.config.session["lastfm"]["source"]
|
||||||
|
lastfm_fallback_source = self.config.session["lastfm"]["fallback_source"]
|
||||||
|
except KeyError:
|
||||||
|
self._config_updating_message()
|
||||||
|
self.config.update()
|
||||||
|
exit()
|
||||||
|
except Exception as err:
|
||||||
|
self._config_corrupted_message(err)
|
||||||
|
raise click.Abort
|
||||||
|
|
||||||
def search_query(query: str, playlist: Playlist) -> bool:
|
def search_query(title, artist, playlist) -> bool:
|
||||||
"""Search for a query and add the first result to playlist.
|
"""Search for a query and add the first result to playlist.
|
||||||
|
|
||||||
:param query:
|
:param query:
|
||||||
|
@ -374,8 +371,21 @@ class MusicDL(list):
|
||||||
:type playlist: Playlist
|
:type playlist: Playlist
|
||||||
:rtype: bool
|
:rtype: bool
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def try_search(source) -> Optional[Track]:
|
||||||
|
if source == lastfm_fallback_source:
|
||||||
|
click.secho("using fallback", fg="red")
|
||||||
try:
|
try:
|
||||||
track = next(self.search(lastfm_source, query, media_type="track"))
|
query = QUERY_FORMAT[lastfm_source].format(
|
||||||
|
title=title, artist=artist
|
||||||
|
)
|
||||||
|
return next(self.search(source, query, media_type="track"))
|
||||||
|
except (NoResultsFound, StopIteration):
|
||||||
|
return None
|
||||||
|
|
||||||
|
track = try_search(lastfm_source) or try_search(lastfm_fallback_source)
|
||||||
|
if track is None:
|
||||||
|
return False
|
||||||
|
|
||||||
if self.config.session["metadata"]["set_playlist_to_album"]:
|
if self.config.session["metadata"]["set_playlist_to_album"]:
|
||||||
# so that the playlist name (actually the album) isn't
|
# so that the playlist name (actually the album) isn't
|
||||||
|
@ -384,9 +394,6 @@ class MusicDL(list):
|
||||||
|
|
||||||
playlist.append(track)
|
playlist.append(track)
|
||||||
return True
|
return True
|
||||||
except (NoResultsFound, StopIteration) as err:
|
|
||||||
logger.debug("No results found for query=%s. Exception: %s", query, err)
|
|
||||||
return False
|
|
||||||
|
|
||||||
for purl in lastfm_urls:
|
for purl in lastfm_urls:
|
||||||
click.secho(f"Fetching playlist at {purl}", fg="blue")
|
click.secho(f"Fetching playlist at {purl}", fg="blue")
|
||||||
|
@ -397,14 +404,10 @@ class MusicDL(list):
|
||||||
if creator_match is not None:
|
if creator_match is not None:
|
||||||
pl.creator = creator_match.group(1)
|
pl.creator = creator_match.group(1)
|
||||||
|
|
||||||
tracks_not_found: int = 0
|
tracks_not_found = 0
|
||||||
with concurrent.futures.ThreadPoolExecutor(max_workers=15) as executor:
|
with concurrent.futures.ThreadPoolExecutor(max_workers=15) as executor:
|
||||||
futures = [
|
futures = [
|
||||||
executor.submit(
|
executor.submit(search_query, title, artist, pl)
|
||||||
search_query,
|
|
||||||
QUERY_FORMAT[lastfm_source].format(title=title, artist=artist),
|
|
||||||
pl,
|
|
||||||
)
|
|
||||||
for title, artist in queries
|
for title, artist in queries
|
||||||
]
|
]
|
||||||
# only for the progress bar
|
# only for the progress bar
|
||||||
|
@ -418,6 +421,7 @@ class MusicDL(list):
|
||||||
|
|
||||||
pl.loaded = True
|
pl.loaded = True
|
||||||
|
|
||||||
|
if tracks_not_found > 0:
|
||||||
click.secho(f"{tracks_not_found} tracks not found.", fg="yellow")
|
click.secho(f"{tracks_not_found} tracks not found.", fg="yellow")
|
||||||
self.append(pl)
|
self.append(pl)
|
||||||
|
|
||||||
|
@ -719,3 +723,21 @@ class MusicDL(list):
|
||||||
or self.config.file[source]["password"] is None
|
or self.config.file[source]["password"] is None
|
||||||
):
|
):
|
||||||
self.prompt_creds(source)
|
self.prompt_creds(source)
|
||||||
|
|
||||||
|
def _config_updating_message(self):
|
||||||
|
click.secho(
|
||||||
|
"Updating config file... Some settings may be lost. Please run the "
|
||||||
|
"command again.",
|
||||||
|
fg="magenta",
|
||||||
|
)
|
||||||
|
|
||||||
|
def _config_corrupted_message(self, err: Exception):
|
||||||
|
click.secho(
|
||||||
|
"There was a problem with your config file. This happens "
|
||||||
|
"sometimes after updates. Run ",
|
||||||
|
nl=False,
|
||||||
|
fg="red",
|
||||||
|
)
|
||||||
|
click.secho("rip config --reset ", fg="yellow", nl=False)
|
||||||
|
click.secho("to reset it. You will need to log in again.", fg="red")
|
||||||
|
click.secho(str(err), fg="red")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue