Fixed version of spotify_dl

This commit is contained in:
2023-06-06 11:35:39 +02:00
parent 48f49d59e0
commit 6bc77f3720
7 changed files with 913 additions and 0 deletions
+227
View File
@@ -0,0 +1,227 @@
#!/usr/bin/env python3
import argparse
import time
import json
import os
import sys
from logging import DEBUG, ERROR
from pathlib import Path, PurePath
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials
from spotify_dl.constants import VERSION
from spotify_dl.scaffold import log, setLogLevel, console, get_tokens
from spotify_dl.spotify import (
fetch_tracks,
parse_spotify_url,
validate_spotify_urls,
get_item_name,
)
from spotify_dl.youtube import (
download_songs,
default_filename,
playlist_num_filename,
dump_json,
)
def spotify_dl():
"""Main entry point of the script."""
parser = argparse.ArgumentParser(prog="spotify_dl")
parser.add_argument(
"-l",
"--url",
action="store",
help="Spotify Playlist link URL",
type=str,
nargs="+",
required=False, # this has to be set to false to prevent useless prompt for url when all user wants is the script version
)
parser.add_argument(
"-o",
"--output",
type=str,
action="store",
help="Specify download directory.",
required=False,
default=".",
)
parser.add_argument(
"-d",
"--download",
action="store_true",
help="Download using youtube-dl",
default=True,
)
parser.add_argument(
"-j",
"--dump-json",
action="store_true",
help="Dump info-json using youtube-dl",
default=False,
)
parser.add_argument(
"-f",
"--format_str",
type=str,
action="store",
help="Specify youtube-dl format string.",
default="bestaudio/best",
)
parser.add_argument(
"-k",
"--keep_playlist_order",
default=False,
action="store_true",
help="Whether to keep original playlist ordering or not.",
)
parser.add_argument(
"-m",
"--skip_mp3",
action="store_true",
help="Don't convert downloaded songs to mp3",
)
parser.add_argument(
"-s",
"--use_sponsorblock",
default="no",
action="store",
help="Whether to skip non-music sections using SponsorBlock API. Pass y or yes to skip using SponsorBlock",
)
parser.add_argument(
"-w",
"--no-overwrites",
action="store_true",
help="Whether we should avoid overwriting the target audio file if it already exists",
default=False,
)
parser.add_argument(
"-r",
"--remove-trailing-tracks",
default="no",
action="store",
help="Whether we should delete tracks that were previously downloaded but are not longer in the playlist",
)
parser.add_argument(
"-V",
"--verbose",
action="store_true",
help="Show more information on what" "s happening.",
)
parser.add_argument(
"-v",
"--version",
action="store_true",
help="Shows current version of the program",
)
parser.add_argument(
"-mc",
"--multi_core",
action="store",
type=str,
default=0,
help="Use multiprocessing [-m [int:numcores]",
)
parser.add_argument(
"-p",
"--proxy",
action="store",
type=str,
default="",
help="Download through a proxy. Support HTTP & SOCKS5. Use 'http://username:password@hostname:port' or 'http://hostname:port'",
)
args = parser.parse_args()
num_cores = os.cpu_count()
args.multi_core = int(args.multi_core)
if args.dump_json:
setLogLevel(ERROR)
if args.verbose:
setLogLevel(DEBUG)
log.info("Starting spotify_dl v%s", VERSION)
log.debug("Setting debug mode on spotify_dl")
if args.multi_core > (num_cores - 1):
log.info(
"Requested cores %d exceeds available %d, using %d cores.",
args.multi_core,
num_cores,
num_cores - 1,
)
args.multi_core = num_cores - 1
if args.version:
console.print(f"spotify_dl [bold green]v{VERSION}[/bold green]")
sys.exit(0)
if os.path.isfile(os.path.expanduser("~/.spotify_dl_settings")):
with open(os.path.expanduser("~/.spotify_dl_settings")) as file:
config = json.load(file)
print(config)
for key, value in config.items():
if (isinstance(value, bool) and value) or (
isinstance(value, str) and value and value.lower() in ["true", "t"]
):
setattr(args, key, True)
else:
setattr(args, key, value)
if not args.url:
raise (Exception("No playlist url provided:"))
tokens = get_tokens()
if tokens is None:
sys.exit(1)
client_id, client_secret = tokens
sp = spotipy.Spotify(
auth_manager=SpotifyClientCredentials(
client_id=client_id, client_secret=client_secret
)
)
log.debug("Arguments: %s ", args)
log.info("Sponsorblock enabled?: %s", args.use_sponsorblock)
valid_urls = validate_spotify_urls(args.url)
if not valid_urls:
sys.exit(1)
url_data = {"urls": []}
start_time = time.time()
for url in valid_urls:
url_dict = {}
item_type, item_id = parse_spotify_url(url)
directory_name = get_item_name(sp, item_type, item_id)
url_dict["save_path"] = Path(
PurePath.joinpath(Path(args.output), Path(directory_name))
)
url_dict["save_path"].mkdir(parents=True, exist_ok=True)
log.info("Saving songs to %s directory", directory_name)
url_dict["songs"] = fetch_tracks(sp, item_type, url)
url_data["urls"].append(url_dict.copy())
if args.dump_json is True:
dump_json(url_dict["songs"])
elif args.download is True:
file_name_f = default_filename
if args.keep_playlist_order:
file_name_f = playlist_num_filename
download_songs(
songs=url_data,
output_dir=args.output,
format_str=args.format_str,
skip_mp3=args.skip_mp3,
keep_playlist_order=args.keep_playlist_order,
no_overwrites=args.no_overwrites,
remove_trailing_tracks=(args.remove_trailing_tracks[0].lower()),
use_sponsorblock=args.use_sponsorblock,
file_name_f=file_name_f,
multi_core=args.multi_core,
proxy=args.proxy,
)
log.info("Download completed in %.2f seconds.", time.time() - start_time)
if __name__ == "__main__":
spotify_dl()