mirror of
https://github.com/migatu/conjurer.git
synced 2026-07-14 21:38:38 +00:00
228 lines
6.5 KiB
Python
228 lines
6.5 KiB
Python
#!/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()
|