mirror of
https://github.com/THIS-IS-NOT-A-BACKUP/zspotify.git
synced 2024-11-29 19:24:34 +01:00
Added --output argument for output templating
This commit is contained in:
parent
ad43153d4c
commit
543567079b
@ -47,12 +47,9 @@ def get_artist_albums(artist_id):
|
||||
def download_album(album):
|
||||
""" Downloads songs from an album """
|
||||
artist, album_name = get_album_name(album)
|
||||
artist_fixed = fix_filename(artist)
|
||||
album_name_fixed = fix_filename(album_name)
|
||||
tracks = get_album_tracks(album)
|
||||
for n, track in tqdm(enumerate(tracks, start=1), unit_scale=True, unit='Song', total=len(tracks)):
|
||||
download_track(track[ID], f'{artist_fixed}/{album_name_fixed}',
|
||||
prefix=True, prefix_value=str(n), disable_progressbar=True)
|
||||
download_track('album', track[ID], extra_keys={'album_num': str(n).zfill(2), 'artist': artist, 'album': album}, disable_progressbar=True)
|
||||
|
||||
|
||||
def download_artist_albums(artist):
|
||||
|
@ -54,7 +54,7 @@ def client(args) -> None:
|
||||
print(
|
||||
'### SKIPPING: SONG DOES NOT EXIST ON SPOTIFY ANYMORE ###')
|
||||
else:
|
||||
download_track(song[TRACK][ID], 'Liked Songs/')
|
||||
download_track('liked', song[TRACK][ID])
|
||||
print('\n')
|
||||
|
||||
if args.search_spotify:
|
||||
@ -75,7 +75,7 @@ def download_from_urls(urls: list[str]) -> bool:
|
||||
|
||||
if track_id is not None:
|
||||
download = True
|
||||
download_track(track_id)
|
||||
download_track('single', track_id)
|
||||
elif artist_id is not None:
|
||||
download = True
|
||||
download_artist_albums(artist_id)
|
||||
@ -87,8 +87,7 @@ def download_from_urls(urls: list[str]) -> bool:
|
||||
playlist_songs = get_playlist_songs(playlist_id)
|
||||
name, _ = get_playlist_info(playlist_id)
|
||||
for song in playlist_songs:
|
||||
download_track(song[TRACK][ID],
|
||||
fix_filename(name) + '/')
|
||||
download_track('playlist', song[TRACK][ID], extra_keys={'playlist': name})
|
||||
print('\n')
|
||||
elif episode_id is not None:
|
||||
download = True
|
||||
@ -273,7 +272,7 @@ def search(search_term):
|
||||
print_pos = dics.index(dic) + 1
|
||||
if print_pos == position:
|
||||
if dic['type'] == TRACK:
|
||||
download_track(dic[ID])
|
||||
download_track('single', dic[ID])
|
||||
elif dic['type'] == ALBUM:
|
||||
download_album(dic[ID])
|
||||
elif dic['type'] == ARTIST:
|
||||
|
@ -20,6 +20,7 @@ LANGUAGE = 'LANGUAGE'
|
||||
BITRATE = 'BITRATE'
|
||||
SONG_ARCHIVE = 'SONG_ARCHIVE'
|
||||
CREDENTIALS_LOCATION = 'CREDENTIALS_LOCATION'
|
||||
OUTPUT = 'OUTPUT'
|
||||
|
||||
CONFIG_VALUES = {
|
||||
ROOT_PATH: { 'default': '../ZSpotify Music/', 'type': str, 'arg': '--root-path' },
|
||||
@ -37,8 +38,14 @@ CONFIG_VALUES = {
|
||||
BITRATE: { 'default': '', 'type': str, 'arg': '--bitrate' },
|
||||
SONG_ARCHIVE: { 'default': '.song_archive', 'type': str, 'arg': '--song-archive' },
|
||||
CREDENTIALS_LOCATION: { 'default': 'credentials.json', 'type': str, 'arg': '--credentials-location' },
|
||||
OUTPUT: { 'default': '', 'type': str, 'arg': '--output' },
|
||||
}
|
||||
|
||||
OUTPUT_DEFAULT_PLAYLIST = '{playlist}/{artist} - {song_name}.{ext}'
|
||||
OUTPUT_DEFAULT_PLAYLIST_EXT = '{playlist}/{playlist_num} - {artist} - {song_name}.{ext}'
|
||||
OUTPUT_DEFAULT_LIKED_SONGS = 'Liked Songs/{artist} - {song_name}.{ext}'
|
||||
OUTPUT_DEFAULT_SINGLE = '{artist} - {song_name}.{ext}'
|
||||
OUTPUT_DEFAULT_ALBUM = '{artist}/{album}/{album_num} - {artist} - {song_name}.{ext}'
|
||||
|
||||
class Config:
|
||||
Values = {}
|
||||
@ -165,3 +172,20 @@ class Config:
|
||||
@classmethod
|
||||
def get_credentials_location(cls) -> str:
|
||||
return cls.get(CREDENTIALS_LOCATION)
|
||||
|
||||
@classmethod
|
||||
def get_output(cls, mode: str) -> str:
|
||||
v = cls.get(OUTPUT)
|
||||
if v:
|
||||
return v
|
||||
if mode == 'playlist':
|
||||
return OUTPUT_DEFAULT_PLAYLIST
|
||||
if mode == 'extplaylist':
|
||||
return OUTPUT_DEFAULT_PLAYLIST_EXT
|
||||
if mode == 'liked':
|
||||
return OUTPUT_DEFAULT_LIKED_SONGS
|
||||
if mode == 'single':
|
||||
return OUTPUT_DEFAULT_SINGLE
|
||||
if mode == 'album':
|
||||
return OUTPUT_DEFAULT_ALBUM
|
||||
raise ValueError()
|
||||
|
@ -54,8 +54,7 @@ def download_playlist(playlist):
|
||||
p_bar = tqdm(playlist_songs, unit='song', total=len(playlist_songs), unit_scale=True)
|
||||
enum = 1
|
||||
for song in p_bar:
|
||||
download_track(song[TRACK][ID], fix_filename(playlist[NAME].strip()) + '/',
|
||||
prefix=True, prefix_value=str(enum) ,disable_progressbar=True)
|
||||
download_track('extplaylist', song[TRACK][ID], extra_keys={'playlist': playlist, 'playlist_num': str(enum).zfill(2)}, disable_progressbar=True)
|
||||
p_bar.set_description(song[TRACK][NAME])
|
||||
enum += 1
|
||||
|
||||
|
@ -69,39 +69,45 @@ def get_song_duration(song_id: str) -> float:
|
||||
return duration
|
||||
|
||||
# noinspection PyBroadException
|
||||
def download_track(track_id: str, extra_paths='', prefix=False, prefix_value='', disable_progressbar=False) -> None:
|
||||
def download_track(mode: str, track_id: str, extra_keys={}, disable_progressbar=False) -> None:
|
||||
""" Downloads raw song audio from Spotify """
|
||||
|
||||
try:
|
||||
output_template = ZSpotify.CONFIG.get_output(mode)
|
||||
|
||||
(artists, album_name, name, image_url, release_year, disc_number,
|
||||
track_number, scraped_song_id, is_playable, duration_ms) = get_song_info(track_id)
|
||||
|
||||
if ZSpotify.CONFIG.get_split_album_discs():
|
||||
download_directory = os.path.join(os.path.dirname(
|
||||
__file__), ZSpotify.CONFIG.get_root_path(), extra_paths, f'Disc {disc_number}')
|
||||
else:
|
||||
download_directory = os.path.join(os.path.dirname(
|
||||
__file__), ZSpotify.CONFIG.get_root_path(), extra_paths)
|
||||
|
||||
song_name = fix_filename(artists[0]) + ' - ' + fix_filename(name)
|
||||
if prefix:
|
||||
song_name = f'{prefix_value.zfill(2)} - {song_name}' if prefix_value.isdigit(
|
||||
) else f'{prefix_value} - {song_name}'
|
||||
|
||||
filename = os.path.join(
|
||||
download_directory, f'{song_name}.{EXT_MAP.get(ZSpotify.CONFIG.get_download_format().lower())}')
|
||||
for k in extra_keys:
|
||||
output_template = output_template.replace("{"+k+"}", fix_filename(extra_keys[k]))
|
||||
|
||||
output_template = output_template.replace("{artist}", fix_filename(artists[0]))
|
||||
output_template = output_template.replace("{album}", fix_filename(album_name))
|
||||
output_template = output_template.replace("{song_name}", fix_filename(name))
|
||||
output_template = output_template.replace("{release_year}", fix_filename(release_year))
|
||||
output_template = output_template.replace("{disc_number}", fix_filename(disc_number))
|
||||
output_template = output_template.replace("{track_number}", fix_filename(track_number))
|
||||
output_template = output_template.replace("{id}", fix_filename(scraped_song_id))
|
||||
output_template = output_template.replace("{track_id}", fix_filename(track_id))
|
||||
output_template = output_template.replace("{ext}", EXT_MAP.get(ZSpotify.CONFIG.get_download_format().lower()))
|
||||
|
||||
filename = os.path.join(os.path.dirname(__file__), ZSpotify.CONFIG.get_root_path(), output_template)
|
||||
filedir = os.path.dirname(filename)
|
||||
|
||||
check_name = os.path.isfile(filename) and os.path.getsize(filename)
|
||||
check_id = scraped_song_id in get_directory_song_ids(download_directory)
|
||||
check_id = scraped_song_id in get_directory_song_ids(filedir)
|
||||
check_all_time = scraped_song_id in get_previously_downloaded()
|
||||
|
||||
# a song with the same name is installed
|
||||
if not check_id and check_name:
|
||||
c = len([file for file in os.listdir(download_directory)
|
||||
if re.search(f'^{song_name}_', file)]) + 1
|
||||
c = len([file for file in os.listdir(filedir) if re.search(f'^{filename}_', str(file))]) + 1
|
||||
|
||||
filename = os.path.join(
|
||||
download_directory, f'{song_name}_{c}.{EXT_MAP.get(ZSpotify.CONFIG.get_download_format())}')
|
||||
fname = os.path.splitext(os.path.basename(filename))[0]
|
||||
ext = os.path.splitext(os.path.basename(filename))[1]
|
||||
|
||||
filename = os.path.join(filedir, f'{fname}_{c}{ext}')
|
||||
|
||||
|
||||
except Exception as e:
|
||||
@ -127,7 +133,7 @@ def download_track(track_id: str, extra_paths='', prefix=False, prefix_value='',
|
||||
track_id = TrackId.from_base62(track_id)
|
||||
stream = ZSpotify.get_content_stream(
|
||||
track_id, ZSpotify.DOWNLOAD_QUALITY)
|
||||
create_download_directory(download_directory)
|
||||
create_download_directory(filedir)
|
||||
total_size = stream.input_stream.size
|
||||
|
||||
with open(filename, 'wb') as file, tqdm(
|
||||
@ -155,7 +161,7 @@ def download_track(track_id: str, extra_paths='', prefix=False, prefix_value='',
|
||||
add_to_archive(scraped_song_id, artists[0], name)
|
||||
# add song id to download directory's .song_ids file
|
||||
if not check_id:
|
||||
add_to_directory_song_ids(download_directory, scraped_song_id)
|
||||
add_to_directory_song_ids(filedir, scraped_song_id)
|
||||
|
||||
if not ZSpotify.CONFIG.get_anti_ban_wait_time():
|
||||
time.sleep(ZSpotify.CONFIG.get_anti_ban_wait_time())
|
||||
|
@ -256,4 +256,4 @@ def fix_filename(name):
|
||||
>>> all('_' == fix_filename(chr(i)) for i in list(range(32)))
|
||||
True
|
||||
"""
|
||||
return re.sub(r'[/\\:|<>"?*\0-\x1f]|^(AUX|COM[1-9]|CON|LPT[1-9]|NUL|PRN)(?![^.])|^\s|[\s.]$', "_", name, flags=re.IGNORECASE)
|
||||
return re.sub(r'[/\\:|<>"?*\0-\x1f]|^(AUX|COM[1-9]|CON|LPT[1-9]|NUL|PRN)(?![^.])|^\s|[\s.]$', "_", str(name), flags=re.IGNORECASE)
|
||||
|
Loading…
Reference in New Issue
Block a user