mirror of
https://github.com/nathom/streamrip.git
synced 2025-05-27 21:44:27 -04:00
Begin move to cleo
This commit is contained in:
parent
54f4ab99af
commit
9970ac548f
13 changed files with 528 additions and 150 deletions
75
rip/cli.py
75
rip/cli.py
|
@ -9,15 +9,31 @@ logging.basicConfig(level="WARNING")
|
|||
logger = logging.getLogger("streamrip")
|
||||
|
||||
|
||||
@click.group(invoke_without_command=True)
|
||||
class SkipArg(click.Group):
|
||||
def parse_args(self, ctx, args):
|
||||
if len(args) == 0:
|
||||
click.echo(self.get_help(ctx))
|
||||
exit()
|
||||
|
||||
if args[0] in self.commands:
|
||||
print('command found')
|
||||
args.insert(0, "")
|
||||
# if args[0] in self.commands:
|
||||
# if len(args) == 1 or args[1] not in self.commands:
|
||||
# # This condition needs updating for multiple positional arguments
|
||||
# args.insert(0, "")
|
||||
super(SkipArg, self).parse_args(ctx, args)
|
||||
|
||||
|
||||
# @click.option(
|
||||
# "-u",
|
||||
# "--urls",
|
||||
# metavar="URLS",
|
||||
# help="Url from Qobuz, Tidal, SoundCloud, or Deezer",
|
||||
# multiple=True,
|
||||
# )
|
||||
@click.group(cls=SkipArg, invoke_without_command=True)
|
||||
@click.option("-c", "--convert", metavar="CODEC", help="alac, mp3, flac, or ogg")
|
||||
@click.option(
|
||||
"-u",
|
||||
"--urls",
|
||||
metavar="URLS",
|
||||
help="Url from Qobuz, Tidal, SoundCloud, or Deezer",
|
||||
multiple=True,
|
||||
)
|
||||
@click.option(
|
||||
"-q",
|
||||
"--quality",
|
||||
|
@ -27,6 +43,7 @@ logger = logging.getLogger("streamrip")
|
|||
@click.option("-t", "--text", metavar="PATH", help="Download urls from a text file.")
|
||||
@click.option("-nd", "--no-db", is_flag=True, help="Ignore the database.")
|
||||
@click.option("--debug", is_flag=True, help="Show debugging logs.")
|
||||
@click.argument("URLS", nargs=1)
|
||||
@click.version_option(prog_name="rip", version=__version__)
|
||||
@click.pass_context
|
||||
def cli(ctx, **kwargs):
|
||||
|
@ -54,9 +71,7 @@ def cli(ctx, **kwargs):
|
|||
from .constants import CONFIG_DIR
|
||||
from .core import RipCore
|
||||
|
||||
logging.basicConfig(level="WARNING")
|
||||
logger = logging.getLogger("streamrip")
|
||||
|
||||
print(kwargs)
|
||||
if not os.path.isdir(CONFIG_DIR):
|
||||
os.makedirs(CONFIG_DIR, exist_ok=True)
|
||||
|
||||
|
@ -68,7 +83,8 @@ def cli(ctx, **kwargs):
|
|||
logger.debug("Starting debug log")
|
||||
|
||||
if ctx.invoked_subcommand is None and not ctx.params["urls"]:
|
||||
echo(cli.get_help(ctx))
|
||||
print(dir(cli))
|
||||
click.echo(cli.get_help(ctx))
|
||||
|
||||
if ctx.invoked_subcommand not in {
|
||||
None,
|
||||
|
@ -90,13 +106,13 @@ def cli(ctx, **kwargs):
|
|||
r = requests.get("https://pypi.org/pypi/streamrip/json").json()
|
||||
newest = r["info"]["version"]
|
||||
if __version__ != newest:
|
||||
secho(
|
||||
click.secho(
|
||||
"A new version of streamrip is available! "
|
||||
"Run `pip3 install streamrip --upgrade` to update.",
|
||||
fg="yellow",
|
||||
)
|
||||
else:
|
||||
secho("streamrip is up-to-date!", fg="green")
|
||||
click.secho("streamrip is up-to-date!", fg="green")
|
||||
|
||||
if kwargs["no_db"]:
|
||||
config.session["database"]["enabled"] = False
|
||||
|
@ -108,7 +124,7 @@ def cli(ctx, **kwargs):
|
|||
if kwargs["quality"] is not None:
|
||||
quality = int(kwargs["quality"])
|
||||
if quality not in range(5):
|
||||
secho("Invalid quality", fg="red")
|
||||
click.secho("Invalid quality", fg="red")
|
||||
return
|
||||
|
||||
config.session["qobuz"]["quality"] = quality
|
||||
|
@ -126,7 +142,7 @@ def cli(ctx, **kwargs):
|
|||
logger.debug(f"Handling {kwargs['text']}")
|
||||
core.handle_txt(kwargs["text"])
|
||||
else:
|
||||
secho(f"Text file {kwargs['text']} does not exist.")
|
||||
click.secho(f"Text file {kwargs['text']} does not exist.")
|
||||
|
||||
if ctx.invoked_subcommand is None:
|
||||
core.download()
|
||||
|
@ -150,6 +166,7 @@ def filter_discography(ctx, **kwargs):
|
|||
|
||||
For basic filtering, use the `--repeats` and `--features` filters.
|
||||
"""
|
||||
raise Exception
|
||||
filters = kwargs.copy()
|
||||
filters.pop("urls")
|
||||
config.session["filters"] = filters
|
||||
|
@ -206,7 +223,7 @@ def search(ctx, **kwargs):
|
|||
if core.interactive_search(query, kwargs["source"], kwargs["type"]):
|
||||
core.download()
|
||||
else:
|
||||
secho("No items chosen, exiting.", fg="bright_red")
|
||||
click.secho("No items chosen, exiting.", fg="bright_red")
|
||||
|
||||
|
||||
@cli.command()
|
||||
|
@ -333,10 +350,10 @@ def config(ctx, **kwargs):
|
|||
config.update()
|
||||
|
||||
if kwargs["path"]:
|
||||
echo(CONFIG_PATH)
|
||||
click.echo(CONFIG_PATH)
|
||||
|
||||
if kwargs["open"]:
|
||||
secho(f"Opening {CONFIG_PATH}", fg="green")
|
||||
click.secho(f"Opening {CONFIG_PATH}", fg="green")
|
||||
click.launch(CONFIG_PATH)
|
||||
|
||||
if kwargs["open_vim"]:
|
||||
|
@ -347,41 +364,41 @@ def config(ctx, **kwargs):
|
|||
|
||||
if kwargs["directory"]:
|
||||
config_dir = os.path.dirname(CONFIG_PATH)
|
||||
secho(f"Opening {config_dir}", fg="green")
|
||||
click.secho(f"Opening {config_dir}", fg="green")
|
||||
click.launch(config_dir)
|
||||
|
||||
if kwargs["qobuz"]:
|
||||
config.file["qobuz"]["email"] = input(style("Qobuz email: ", fg="blue"))
|
||||
config.file["qobuz"]["email"] = input(click.style("Qobuz email: ", fg="blue"))
|
||||
|
||||
secho("Qobuz password (will not show on screen):", fg="blue")
|
||||
click.secho("Qobuz password (will not show on screen):", fg="blue")
|
||||
config.file["qobuz"]["password"] = md5(
|
||||
getpass(prompt="").encode("utf-8")
|
||||
).hexdigest()
|
||||
|
||||
config.save()
|
||||
secho("Qobuz credentials hashed and saved to config.", fg="green")
|
||||
click.secho("Qobuz credentials hashed and saved to config.", fg="green")
|
||||
|
||||
if kwargs["tidal"]:
|
||||
client = TidalClient()
|
||||
client.login()
|
||||
config.file["tidal"].update(client.get_tokens())
|
||||
config.save()
|
||||
secho("Credentials saved to config.", fg="green")
|
||||
click.secho("Credentials saved to config.", fg="green")
|
||||
|
||||
if kwargs["deezer"]:
|
||||
secho(
|
||||
click.secho(
|
||||
"If you're not sure how to find the ARL cookie, see the instructions at ",
|
||||
italic=True,
|
||||
nl=False,
|
||||
dim=True,
|
||||
)
|
||||
secho(
|
||||
click.secho(
|
||||
"https://github.com/nathom/streamrip/wiki/Finding-your-Deezer-ARL-Cookie",
|
||||
underline=True,
|
||||
italic=True,
|
||||
fg="blue",
|
||||
)
|
||||
config.file["deezer"]["arl"] = input(style("ARL: ", fg="green"))
|
||||
config.file["deezer"]["arl"] = input(click.style("ARL: ", fg="green"))
|
||||
config.save()
|
||||
|
||||
|
||||
|
@ -481,7 +498,7 @@ def convert(ctx, **kwargs):
|
|||
elif os.path.isfile(kwargs["path"]):
|
||||
codec_map[codec](filename=kwargs["path"], **converter_args).convert()
|
||||
else:
|
||||
secho(f"File {kwargs['path']} does not exist.", fg="red")
|
||||
click.secho(f"File {kwargs['path']} does not exist.", fg="red")
|
||||
|
||||
|
||||
@cli.command()
|
||||
|
@ -503,7 +520,7 @@ def repair(ctx, **kwargs):
|
|||
|
||||
def none_chosen():
|
||||
"""Print message if nothing was chosen."""
|
||||
secho("No items chosen, exiting.", fg="bright_red")
|
||||
click.secho("No items chosen, exiting.", fg="bright_red")
|
||||
|
||||
|
||||
def main():
|
||||
|
|
214
rip/cli_cleo.py
Normal file
214
rip/cli_cleo.py
Normal file
|
@ -0,0 +1,214 @@
|
|||
import logging
|
||||
import os
|
||||
|
||||
from cleo.application import Application as BaseApplication
|
||||
from cleo.commands.command import Command
|
||||
|
||||
from streamrip import __version__
|
||||
|
||||
from .config import Config
|
||||
from .core import RipCore
|
||||
|
||||
logging.basicConfig(level="WARNING")
|
||||
logger = logging.getLogger("streamrip")
|
||||
|
||||
|
||||
class DownloadCommand(Command):
|
||||
"""
|
||||
Download items from a url
|
||||
|
||||
url
|
||||
{--f|file=None : Path to a text file containing urls}
|
||||
{urls?* : One or more Qobuz, Tidal, Deezer, or SoundCloud urls}
|
||||
"""
|
||||
|
||||
help = (
|
||||
'\nDownload "Dreams" by Fleetwood Mac:\n'
|
||||
"$ <fg=magenta>rip url https://www.deezer.com/en/track/63480987</>\n\n"
|
||||
"Batch download urls from a text file named urls.txt:\n"
|
||||
"$ <fg=magenta>rip --file urls.txt</>\n"
|
||||
)
|
||||
|
||||
def handle(self):
|
||||
config = Config()
|
||||
core = RipCore(config)
|
||||
|
||||
urls = self.argument("urls")
|
||||
path = self.option("file")
|
||||
if path != "None":
|
||||
if os.path.isfile(path):
|
||||
core.handle_txt(path)
|
||||
else:
|
||||
self.line(
|
||||
f"<error>File <comment>{path}</comment> does not exist.</error>"
|
||||
)
|
||||
return 1
|
||||
|
||||
if urls:
|
||||
core.handle_urls(";".join(urls))
|
||||
|
||||
if len(core) > 0:
|
||||
core.download()
|
||||
elif not urls and path == "None":
|
||||
self.line("<error>Must pass arguments. See </><info>rip url -h</info>.")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
class SearchCommand(Command):
|
||||
"""
|
||||
Search for and download items in interactive mode.
|
||||
|
||||
search
|
||||
{query : The name to search for}
|
||||
{--s|source=qobuz : Qobuz, Tidal, Soundcloud, Deezer, or Deezloader}
|
||||
{--t|type=album : Album, Playlist, Track, or Artist}
|
||||
"""
|
||||
|
||||
def handle(self):
|
||||
query = self.argument("query")
|
||||
source, type = clean_options(self.option("source"), self.option("type"))
|
||||
|
||||
config = Config()
|
||||
core = RipCore(config)
|
||||
|
||||
if core.interactive_search(query, source, type):
|
||||
core.download()
|
||||
else:
|
||||
self.line("<error>No items chosen, exiting.</error>")
|
||||
|
||||
|
||||
class DiscoverCommand(Command):
|
||||
"""
|
||||
Browse and download items in interactive mode.
|
||||
|
||||
discover
|
||||
{--s|scrape : Download all of the items in the list}
|
||||
{--m|max-items=50 : The number of items to fetch}
|
||||
{list=ideal-discography : The list to fetch}
|
||||
"""
|
||||
|
||||
help = (
|
||||
"\nAvailable options for <info>list</info>:\n\n"
|
||||
" • most-streamed\n"
|
||||
" • recent-releases\n"
|
||||
" • best-sellers\n"
|
||||
" • press-awards\n"
|
||||
" • ideal-discography\n"
|
||||
" • editor-picks\n"
|
||||
" • most-featured\n"
|
||||
" • qobuzissims\n"
|
||||
" • new-releases\n"
|
||||
" • new-releases-full\n"
|
||||
" • harmonia-mundi\n"
|
||||
" • universal-classic\n"
|
||||
" • universal-jazz\n"
|
||||
" • universal-jeunesse\n"
|
||||
" • universal-chanson\n"
|
||||
)
|
||||
|
||||
def handle(self):
|
||||
from streamrip.constants import QOBUZ_FEATURED_KEYS
|
||||
|
||||
chosen_list = self.argument("list")
|
||||
scrape = self.option("scrape")
|
||||
max_items = self.option("max-items")
|
||||
|
||||
if chosen_list not in QOBUZ_FEATURED_KEYS:
|
||||
self.line(f'<error>Error: list "{chosen_list}" not available</error>')
|
||||
self.line(self.help)
|
||||
return 1
|
||||
|
||||
config = Config()
|
||||
core = RipCore(config)
|
||||
|
||||
if scrape:
|
||||
core.scrape(chosen_list, max_items)
|
||||
core.download()
|
||||
return 0
|
||||
|
||||
if core.interactive_search(
|
||||
chosen_list, "qobuz", "featured", limit=int(max_items)
|
||||
):
|
||||
core.download()
|
||||
else:
|
||||
self.line("<error>No items chosen, exiting.</error>")
|
||||
|
||||
|
||||
class LastfmCommand(Command):
|
||||
"""
|
||||
Search for tracks from a list.fm playlist and download them.
|
||||
|
||||
lastfm
|
||||
{--s|source=qobuz : The source to search for items on}
|
||||
{urls* : Last.fm playlist urls}
|
||||
"""
|
||||
|
||||
def handle(self):
|
||||
source = self.option("source")
|
||||
urls = self.argument("urls")
|
||||
|
||||
config = Config()
|
||||
core = RipCore(config)
|
||||
config.session["lastfm"]["source"] = source
|
||||
core.handle_lastfm_urls(";".join(urls))
|
||||
core.download()
|
||||
|
||||
|
||||
class ConfigCommand(Command):
|
||||
"""
|
||||
Manage the configuration file
|
||||
|
||||
{--o|open : Open the config file in the default application}
|
||||
{--ov|open-vim : Open the config file in (neo)vim}
|
||||
{--d|directory : Open the directory that the config file is located in}
|
||||
{--p|path : Show the config file's path}
|
||||
{--q|qobuz : Set the credentials for Qobuz}
|
||||
{--t|tidal : Log into Tidal}
|
||||
{--dz|deezer : Set the Deezer ARL}
|
||||
{--reset : Reset the config file}
|
||||
{--update : Reset the config file, keeping the credentials}
|
||||
"""
|
||||
|
||||
|
||||
class Application(BaseApplication):
|
||||
def __init__(self):
|
||||
super().__init__("rip", __version__)
|
||||
|
||||
def _run(self, io):
|
||||
if io.is_debug():
|
||||
logger.setLevel(logging.DEBUG)
|
||||
|
||||
super()._run(io)
|
||||
|
||||
# @property
|
||||
# def _default_definition(self):
|
||||
# default_globals = super()._default_definition
|
||||
# default_globals.add_option(Option("convert", shortcut="c", flag=False))
|
||||
# return default_globals
|
||||
|
||||
|
||||
# class ConvertCommand(Command):
|
||||
# pass
|
||||
|
||||
|
||||
# class RepairCommand(Command):
|
||||
# pass
|
||||
|
||||
|
||||
def clean_options(*opts):
|
||||
return tuple(o.replace("=", "").strip() for o in opts)
|
||||
|
||||
|
||||
def main():
|
||||
application = Application()
|
||||
application.add(DownloadCommand())
|
||||
application.add(SearchCommand())
|
||||
application.add(DiscoverCommand())
|
||||
application.add(LastfmCommand())
|
||||
# application.add(ConfigCommand())
|
||||
application.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -7,7 +7,7 @@ import shutil
|
|||
from pprint import pformat
|
||||
from typing import Any, Dict
|
||||
|
||||
import click
|
||||
from click import style, secho
|
||||
import tomlkit
|
||||
|
||||
from streamrip.exceptions import InvalidSourceError
|
||||
|
|
|
@ -4,7 +4,7 @@ import os
|
|||
import re
|
||||
from pathlib import Path
|
||||
|
||||
import click
|
||||
from click import style, secho
|
||||
|
||||
APPNAME = "streamrip"
|
||||
APP_DIR = click.get_app_dir(APPNAME)
|
||||
|
|
76
rip/core.py
76
rip/core.py
|
@ -10,7 +10,7 @@ from hashlib import md5
|
|||
from string import Formatter
|
||||
from typing import Dict, Generator, List, Optional, Tuple, Type, Union
|
||||
|
||||
import click
|
||||
from click import style, secho
|
||||
import requests
|
||||
from tqdm import tqdm
|
||||
|
||||
|
@ -162,8 +162,8 @@ class RipCore(list):
|
|||
if not parsed and len(self) == 0:
|
||||
if "last.fm" in url:
|
||||
message = (
|
||||
f"For last.fm urls, use the {style('lastfm', fg='yellow')} "
|
||||
f"command. See {style('rip lastfm --help', fg='yellow')}."
|
||||
f"For last.fm urls, use the {click.style('lastfm', fg='yellow')} "
|
||||
f"command. See {click.style('rip lastfm --help', fg='yellow')}."
|
||||
)
|
||||
else:
|
||||
message = f"Cannot find urls in text: {url}"
|
||||
|
@ -175,7 +175,7 @@ class RipCore(list):
|
|||
logger.info(
|
||||
f"ID {item_id} already downloaded, use --no-db to override."
|
||||
)
|
||||
secho(
|
||||
click.secho(
|
||||
f"ID {item_id} already downloaded, use --no-db to override.",
|
||||
fg="magenta",
|
||||
)
|
||||
|
@ -248,12 +248,12 @@ class RipCore(list):
|
|||
max_items = float("inf")
|
||||
|
||||
if self.failed_db.is_dummy:
|
||||
secho(
|
||||
click.secho(
|
||||
"Failed downloads database must be enabled in the config file "
|
||||
"to repair!",
|
||||
fg="red",
|
||||
)
|
||||
raise click.Abort
|
||||
exit()
|
||||
|
||||
for counter, (source, media_type, item_id) in enumerate(self.failed_db):
|
||||
if counter >= max_items:
|
||||
|
@ -304,7 +304,7 @@ class RipCore(list):
|
|||
item.load_meta(**arguments)
|
||||
except NonStreamable:
|
||||
self.failed_db.add((item.client.source, item.type, item.id))
|
||||
secho(f"{item!s} is not available, skipping.", fg="red")
|
||||
click.secho(f"{item!s} is not available, skipping.", fg="red")
|
||||
continue
|
||||
|
||||
try:
|
||||
|
@ -321,7 +321,7 @@ class RipCore(list):
|
|||
self.failed_db.add(failed_item_info)
|
||||
continue
|
||||
except ItemExists as e:
|
||||
secho(f'"{e!s}" already exists. Skipping.', fg="yellow")
|
||||
click.secho(f'"{e!s}" already exists. Skipping.', fg="yellow")
|
||||
continue
|
||||
|
||||
if hasattr(item, "id"):
|
||||
|
@ -366,13 +366,13 @@ class RipCore(list):
|
|||
creds = self.config.creds(client.source)
|
||||
if client.source == "deezer" and creds["arl"] == "":
|
||||
if self.config.session["deezer"]["deezloader_warnings"]:
|
||||
secho(
|
||||
click.secho(
|
||||
"Falling back to Deezloader (max 320kbps MP3). If you have a subscription, run ",
|
||||
nl=False,
|
||||
fg="yellow",
|
||||
)
|
||||
secho("rip config --deezer ", nl=False, bold=True)
|
||||
secho("to download FLAC files.\n\n", fg="yellow")
|
||||
click.secho("rip config --deezer ", nl=False, bold=True)
|
||||
click.secho("to download FLAC files.\n\n", fg="yellow")
|
||||
raise DeezloaderFallback
|
||||
|
||||
while True:
|
||||
|
@ -380,7 +380,7 @@ class RipCore(list):
|
|||
client.login(**creds)
|
||||
break
|
||||
except AuthenticationError:
|
||||
secho("Invalid credentials, try again.", fg="yellow")
|
||||
click.secho("Invalid credentials, try again.", fg="yellow")
|
||||
self.prompt_creds(client.source)
|
||||
creds = self.config.creds(client.source)
|
||||
except MissingCredentials:
|
||||
|
@ -419,7 +419,7 @@ class RipCore(list):
|
|||
|
||||
interpreter_urls = QOBUZ_INTERPRETER_URL_REGEX.findall(url)
|
||||
if interpreter_urls:
|
||||
secho(
|
||||
click.secho(
|
||||
"Extracting IDs from Qobuz interpreter urls. Use urls "
|
||||
"that include the artist ID for faster preprocessing.",
|
||||
fg="yellow",
|
||||
|
@ -432,7 +432,7 @@ class RipCore(list):
|
|||
|
||||
dynamic_urls = DEEZER_DYNAMIC_LINK_REGEX.findall(url)
|
||||
if dynamic_urls:
|
||||
secho(
|
||||
click.secho(
|
||||
"Extracting IDs from Deezer dynamic link. Use urls "
|
||||
"of the form https://www.deezer.com/{country}/{type}/{id} for "
|
||||
"faster processing.",
|
||||
|
@ -486,7 +486,7 @@ class RipCore(list):
|
|||
exit()
|
||||
except Exception as err:
|
||||
self._config_corrupted_message(err)
|
||||
raise click.Abort
|
||||
exit()
|
||||
|
||||
def search_query(title, artist, playlist) -> bool:
|
||||
"""Search for a query and add the first result to playlist.
|
||||
|
@ -523,8 +523,10 @@ class RipCore(list):
|
|||
playlist.append(track)
|
||||
return True
|
||||
|
||||
from streamrip.utils import TQDM_BAR_FORMAT
|
||||
|
||||
for purl in lastfm_urls:
|
||||
secho(f"Fetching playlist at {purl}", fg="blue")
|
||||
click.secho(f"Fetching playlist at {purl}", fg="blue")
|
||||
title, queries = self.get_lastfm_playlist(purl)
|
||||
|
||||
pl = Playlist(client=self.get_client(lastfm_source), name=title)
|
||||
|
@ -541,8 +543,11 @@ class RipCore(list):
|
|||
# only for the progress bar
|
||||
for search_attempt in tqdm(
|
||||
concurrent.futures.as_completed(futures),
|
||||
unit="Tracks",
|
||||
dynamic_ncols=True,
|
||||
total=len(futures),
|
||||
desc="Searching",
|
||||
desc="Searching...",
|
||||
bar_format=TQDM_BAR_FORMAT,
|
||||
):
|
||||
if not search_attempt.result():
|
||||
tracks_not_found += 1
|
||||
|
@ -550,7 +555,8 @@ class RipCore(list):
|
|||
pl.loaded = True
|
||||
|
||||
if tracks_not_found > 0:
|
||||
secho(f"{tracks_not_found} tracks not found.", fg="yellow")
|
||||
click.secho(f"{tracks_not_found} tracks not found.", fg="yellow")
|
||||
|
||||
self.append(pl)
|
||||
|
||||
def handle_txt(self, filepath: Union[str, os.PathLike]):
|
||||
|
@ -602,7 +608,7 @@ class RipCore(list):
|
|||
media_type if media_type != "featured" else "album"
|
||||
].from_api(item, client)
|
||||
|
||||
if i > limit:
|
||||
if i >= limit - 1:
|
||||
return
|
||||
else:
|
||||
logger.debug("Not generator")
|
||||
|
@ -616,7 +622,7 @@ class RipCore(list):
|
|||
for i, item in enumerate(items):
|
||||
logger.debug(item["title"])
|
||||
yield MEDIA_CLASS[media_type].from_api(item, client) # type: ignore
|
||||
if i > limit:
|
||||
if i >= limit - 1:
|
||||
return
|
||||
|
||||
def preview_media(self, media) -> str:
|
||||
|
@ -795,11 +801,7 @@ class RipCore(list):
|
|||
for page in range(1, last_page + 1)
|
||||
]
|
||||
|
||||
for future in tqdm(
|
||||
concurrent.futures.as_completed(futures),
|
||||
total=len(futures),
|
||||
desc="Scraping playlist",
|
||||
):
|
||||
for future in concurrent.futures.as_completed(futures):
|
||||
get_titles(future.result().text)
|
||||
|
||||
return playlist_title, info
|
||||
|
@ -815,9 +817,9 @@ class RipCore(list):
|
|||
:type source: str
|
||||
"""
|
||||
if source == "qobuz":
|
||||
secho("Enter Qobuz email:", fg="green")
|
||||
click.secho("Enter Qobuz email:", fg="green")
|
||||
self.config.file[source]["email"] = input()
|
||||
secho(
|
||||
click.secho(
|
||||
"Enter Qobuz password (will not show on screen):",
|
||||
fg="green",
|
||||
)
|
||||
|
@ -826,27 +828,27 @@ class RipCore(list):
|
|||
).hexdigest()
|
||||
|
||||
self.config.save()
|
||||
secho(
|
||||
click.secho(
|
||||
f'Credentials saved to config file at "{self.config._path}"',
|
||||
fg="green",
|
||||
)
|
||||
elif source == "deezer":
|
||||
secho(
|
||||
click.secho(
|
||||
"If you're not sure how to find the ARL cookie, see the instructions at ",
|
||||
italic=True,
|
||||
nl=False,
|
||||
dim=True,
|
||||
)
|
||||
secho(
|
||||
click.secho(
|
||||
"https://github.com/nathom/streamrip/wiki/Finding-your-Deezer-ARL-Cookie",
|
||||
underline=True,
|
||||
italic=True,
|
||||
fg="blue",
|
||||
)
|
||||
|
||||
self.config.file["deezer"]["arl"] = input(style("ARL: ", fg="green"))
|
||||
self.config.file["deezer"]["arl"] = input(click.style("ARL: ", fg="green"))
|
||||
self.config.save()
|
||||
secho(
|
||||
click.secho(
|
||||
f'Credentials saved to config file at "{self.config._path}"',
|
||||
fg="green",
|
||||
)
|
||||
|
@ -854,19 +856,19 @@ class RipCore(list):
|
|||
raise Exception
|
||||
|
||||
def _config_updating_message(self):
|
||||
secho(
|
||||
click.secho(
|
||||
"Updating config file... Some settings may be lost. Please run the "
|
||||
"command again.",
|
||||
fg="magenta",
|
||||
)
|
||||
|
||||
def _config_corrupted_message(self, err: Exception):
|
||||
secho(
|
||||
click.secho(
|
||||
"There was a problem with your config file. This happens "
|
||||
"sometimes after updates. Run ",
|
||||
nl=False,
|
||||
fg="red",
|
||||
)
|
||||
secho("rip config --reset ", fg="yellow", nl=False)
|
||||
secho("to reset it. You will need to log in again.", fg="red")
|
||||
secho(str(err), 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