mirror of
				https://github.com/THIS-IS-NOT-A-BACKUP/zspotify.git
				synced 2025-11-04 05:20:34 +00:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/main'
This commit is contained in:
		
						commit
						2a45634ea3
					
				@ -77,6 +77,7 @@ Be aware you have to set boolean values in the commandline like this: `--downloa
 | 
				
			|||||||
| PRINT_DOWNLOAD_PROGRESS      | --print-download-progress        | Print the download/playlist progress bars
 | 
					| PRINT_DOWNLOAD_PROGRESS      | --print-download-progress        | Print the download/playlist progress bars
 | 
				
			||||||
| PRINT_ERRORS                 | --print-errors                   | Print errors
 | 
					| PRINT_ERRORS                 | --print-errors                   | Print errors
 | 
				
			||||||
| PRINT_DOWNLOADS              | --print-downloads                | Print messages when a song is finished downloading
 | 
					| PRINT_DOWNLOADS              | --print-downloads                | Print messages when a song is finished downloading
 | 
				
			||||||
 | 
					| TEMP_DOWNLOAD_DIR            | --temp-download-dir              | Download tracks to a temporary directory first
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Output format:
 | 
					### Output format:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -26,18 +26,18 @@ def get_album_tracks(album_id):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def get_album_name(album_id):
 | 
					def get_album_name(album_id):
 | 
				
			||||||
    """ Returns album name """
 | 
					    """ Returns album name """
 | 
				
			||||||
    resp = ZSpotify.invoke_url(f'{ALBUM_URL}/{album_id}')
 | 
					    (raw, resp) = ZSpotify.invoke_url(f'{ALBUM_URL}/{album_id}')
 | 
				
			||||||
    return resp[ARTISTS][0][NAME], fix_filename(resp[NAME])
 | 
					    return resp[ARTISTS][0][NAME], fix_filename(resp[NAME])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_artist_albums(artist_id):
 | 
					def get_artist_albums(artist_id):
 | 
				
			||||||
    """ Returns artist's albums """
 | 
					    """ Returns artist's albums """
 | 
				
			||||||
    resp = ZSpotify.invoke_url(f'{ARTIST_URL}/{artist_id}/albums?include_groups=album%2Csingle')
 | 
					    (raw, resp) = ZSpotify.invoke_url(f'{ARTIST_URL}/{artist_id}/albums?include_groups=album%2Csingle')
 | 
				
			||||||
    # Return a list each album's id
 | 
					    # Return a list each album's id
 | 
				
			||||||
    album_ids = [resp[ITEMS][i][ID] for i in range(len(resp[ITEMS]))]
 | 
					    album_ids = [resp[ITEMS][i][ID] for i in range(len(resp[ITEMS]))]
 | 
				
			||||||
    # Recursive requests to get all albums including singles an EPs
 | 
					    # Recursive requests to get all albums including singles an EPs
 | 
				
			||||||
    while resp['next'] is not None:
 | 
					    while resp['next'] is not None:
 | 
				
			||||||
        resp = ZSpotify.invoke_url(resp['next'])
 | 
					        (raw, resp) = ZSpotify.invoke_url(resp['next'])
 | 
				
			||||||
        album_ids.extend([resp[ITEMS][i][ID] for i in range(len(resp[ITEMS]))])
 | 
					        album_ids.extend([resp[ITEMS][i][ID] for i in range(len(resp[ITEMS]))])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return album_ids
 | 
					    return album_ids
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,7 @@ PRINT_SKIPS = 'PRINT_SKIPS'
 | 
				
			|||||||
PRINT_DOWNLOAD_PROGRESS = 'PRINT_DOWNLOAD_PROGRESS'
 | 
					PRINT_DOWNLOAD_PROGRESS = 'PRINT_DOWNLOAD_PROGRESS'
 | 
				
			||||||
PRINT_ERRORS = 'PRINT_ERRORS'
 | 
					PRINT_ERRORS = 'PRINT_ERRORS'
 | 
				
			||||||
PRINT_DOWNLOADS = 'PRINT_DOWNLOADS'
 | 
					PRINT_DOWNLOADS = 'PRINT_DOWNLOADS'
 | 
				
			||||||
 | 
					TEMP_DOWNLOAD_DIR = 'TEMP_DOWNLOAD_DIR'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CONFIG_VALUES = {
 | 
					CONFIG_VALUES = {
 | 
				
			||||||
    ROOT_PATH:                  { 'default': '../ZSpotify Music/',    'type': str,  'arg': '--root-path'                  },
 | 
					    ROOT_PATH:                  { 'default': '../ZSpotify Music/',    'type': str,  'arg': '--root-path'                  },
 | 
				
			||||||
@ -50,6 +51,7 @@ CONFIG_VALUES = {
 | 
				
			|||||||
    PRINT_DOWNLOAD_PROGRESS:    { 'default': 'True',                  'type': bool, 'arg': '--print-download-progress'    },
 | 
					    PRINT_DOWNLOAD_PROGRESS:    { 'default': 'True',                  'type': bool, 'arg': '--print-download-progress'    },
 | 
				
			||||||
    PRINT_ERRORS:               { 'default': 'True',                  'type': bool, 'arg': '--print-errors'               },
 | 
					    PRINT_ERRORS:               { 'default': 'True',                  'type': bool, 'arg': '--print-errors'               },
 | 
				
			||||||
    PRINT_DOWNLOADS:            { 'default': 'False',                 'type': bool, 'arg': '--print-downloads'            },
 | 
					    PRINT_DOWNLOADS:            { 'default': 'False',                 'type': bool, 'arg': '--print-downloads'            },
 | 
				
			||||||
 | 
					    TEMP_DOWNLOAD_DIR:          { 'default': '',                      'type': str,  'arg': '--temp-download-dir'          },
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
OUTPUT_DEFAULT_PLAYLIST = '{playlist}/{artist} - {song_name}.{ext}'
 | 
					OUTPUT_DEFAULT_PLAYLIST = '{playlist}/{artist} - {song_name}.{ext}'
 | 
				
			||||||
@ -129,11 +131,11 @@ class Config:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_root_path(cls) -> str:
 | 
					    def get_root_path(cls) -> str:
 | 
				
			||||||
        return cls.get(ROOT_PATH)
 | 
					        return os.path.join(os.path.dirname(__file__), cls.get(ROOT_PATH))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_root_podcast_path(cls) -> str:
 | 
					    def get_root_podcast_path(cls) -> str:
 | 
				
			||||||
        return cls.get(ROOT_PODCAST_PATH)
 | 
					        return os.path.join(os.path.dirname(__file__), cls.get(ROOT_PODCAST_PATH))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_skip_existing_files(cls) -> bool:
 | 
					    def get_skip_existing_files(cls) -> bool:
 | 
				
			||||||
@ -181,11 +183,17 @@ class Config:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_song_archive(cls) -> str:
 | 
					    def get_song_archive(cls) -> str:
 | 
				
			||||||
        return cls.get(SONG_ARCHIVE)
 | 
					        return os.path.join(ZSpotify.CONFIG.get_root_path(), cls.get(SONG_ARCHIVE))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_credentials_location(cls) -> str:
 | 
					    def get_credentials_location(cls) -> str:
 | 
				
			||||||
        return cls.get(CREDENTIALS_LOCATION)
 | 
					        return os.path.join(os.getcwd(), cls.get(CREDENTIALS_LOCATION))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def get_temp_download_dir(cls) -> str:
 | 
				
			||||||
 | 
					        if cls.get(TEMP_DOWNLOAD_DIR) == '':
 | 
				
			||||||
 | 
					            return ''
 | 
				
			||||||
 | 
					        return os.path.join(ZSpotify.CONFIG.get_root_path(), cls.get(TEMP_DOWNLOAD_DIR))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def get_output(cls, mode: str) -> str:
 | 
					    def get_output(cls, mode: str) -> str:
 | 
				
			||||||
 | 
				
			|||||||
@ -42,7 +42,7 @@ def get_playlist_songs(playlist_id):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def get_playlist_info(playlist_id):
 | 
					def get_playlist_info(playlist_id):
 | 
				
			||||||
    """ Returns information scraped from playlist """
 | 
					    """ Returns information scraped from playlist """
 | 
				
			||||||
    resp = ZSpotify.invoke_url(f'{PLAYLISTS_URL}/{playlist_id}?fields=name,owner(display_name)&market=from_token')
 | 
					    (raw, resp) = ZSpotify.invoke_url(f'{PLAYLISTS_URL}/{playlist_id}?fields=name,owner(display_name)&market=from_token')
 | 
				
			||||||
    return resp['name'].strip(), resp['owner']['display_name'].strip()
 | 
					    return resp['name'].strip(), resp['owner']['display_name'].strip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -14,7 +14,7 @@ SHOWS_URL = 'https://api.spotify.com/v1/shows'
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_episode_info(episode_id_str) -> Tuple[Optional[str], Optional[str]]:
 | 
					def get_episode_info(episode_id_str) -> Tuple[Optional[str], Optional[str]]:
 | 
				
			||||||
    info = ZSpotify.invoke_url(f'{EPISODE_INFO_URL}/{episode_id_str}')
 | 
					    (raw, info) = ZSpotify.invoke_url(f'{EPISODE_INFO_URL}/{episode_id_str}')
 | 
				
			||||||
    if ERROR in info:
 | 
					    if ERROR in info:
 | 
				
			||||||
        return None, None
 | 
					        return None, None
 | 
				
			||||||
    return fix_filename(info[SHOW][NAME]), fix_filename(info[NAME])
 | 
					    return fix_filename(info[SHOW][NAME]), fix_filename(info[NAME])
 | 
				
			||||||
@ -77,11 +77,7 @@ def download_episode(episode_id) -> None:
 | 
				
			|||||||
        direct_download_url = ZSpotify.invoke_url(
 | 
					        direct_download_url = ZSpotify.invoke_url(
 | 
				
			||||||
            'https://api-partner.spotify.com/pathfinder/v1/query?operationName=getEpisode&variables={"uri":"spotify:episode:' + episode_id + '"}&extensions={"persistedQuery":{"version":1,"sha256Hash":"224ba0fd89fcfdfb3a15fa2d82a6112d3f4e2ac88fba5c6713de04d1b72cf482"}}')["data"]["episode"]["audio"]["items"][-1]["url"]
 | 
					            'https://api-partner.spotify.com/pathfinder/v1/query?operationName=getEpisode&variables={"uri":"spotify:episode:' + episode_id + '"}&extensions={"persistedQuery":{"version":1,"sha256Hash":"224ba0fd89fcfdfb3a15fa2d82a6112d3f4e2ac88fba5c6713de04d1b72cf482"}}')["data"]["episode"]["audio"]["items"][-1]["url"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        download_directory = os.path.join(
 | 
					        download_directory = os.path.join(ZSpotify.CONFIG.get_root_podcast_path(), extra_paths)
 | 
				
			||||||
            os.path.dirname(__file__),
 | 
					 | 
				
			||||||
            ZSpotify.CONFIG.get_root_podcast_path(),
 | 
					 | 
				
			||||||
            extra_paths,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
        download_directory = os.path.realpath(download_directory)
 | 
					        download_directory = os.path.realpath(download_directory)
 | 
				
			||||||
        create_download_directory(download_directory)
 | 
					        create_download_directory(download_directory)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ import math
 | 
				
			|||||||
import os
 | 
					import os
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
import time
 | 
					import time
 | 
				
			||||||
 | 
					import uuid
 | 
				
			||||||
from typing import Any, Tuple, List
 | 
					from typing import Any, Tuple, List
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from librespot.audio.decoders import AudioQuality
 | 
					from librespot.audio.decoders import AudioQuality
 | 
				
			||||||
@ -35,27 +36,34 @@ def get_saved_tracks() -> list:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
def get_song_info(song_id) -> Tuple[List[str], str, str, Any, Any, Any, Any, Any, Any, int]:
 | 
					def get_song_info(song_id) -> Tuple[List[str], str, str, Any, Any, Any, Any, Any, Any, int]:
 | 
				
			||||||
    """ Retrieves metadata for downloaded songs """
 | 
					    """ Retrieves metadata for downloaded songs """
 | 
				
			||||||
    info = ZSpotify.invoke_url(f'{TRACKS_URL}?ids={song_id}&market=from_token')
 | 
					    (raw, info) = ZSpotify.invoke_url(f'{TRACKS_URL}?ids={song_id}&market=from_token')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    artists = []
 | 
					    if not TRACKS in info:
 | 
				
			||||||
    for data in info[TRACKS][0][ARTISTS]:
 | 
					        raise ValueError(f'Invalid response from TRACKS_URL:\n{raw}')
 | 
				
			||||||
        artists.append(data[NAME])
 | 
					
 | 
				
			||||||
    album_name = info[TRACKS][0][ALBUM][NAME]
 | 
					    try:
 | 
				
			||||||
    name = info[TRACKS][0][NAME]
 | 
					        artists = []
 | 
				
			||||||
    image_url = info[TRACKS][0][ALBUM][IMAGES][0][URL]
 | 
					        for data in info[TRACKS][0][ARTISTS]:
 | 
				
			||||||
    release_year = info[TRACKS][0][ALBUM][RELEASE_DATE].split('-')[0]
 | 
					            artists.append(data[NAME])
 | 
				
			||||||
    disc_number = info[TRACKS][0][DISC_NUMBER]
 | 
					        album_name = info[TRACKS][0][ALBUM][NAME]
 | 
				
			||||||
    track_number = info[TRACKS][0][TRACK_NUMBER]
 | 
					        name = info[TRACKS][0][NAME]
 | 
				
			||||||
    scraped_song_id = info[TRACKS][0][ID]
 | 
					        image_url = info[TRACKS][0][ALBUM][IMAGES][0][URL]
 | 
				
			||||||
    is_playable = info[TRACKS][0][IS_PLAYABLE]
 | 
					        release_year = info[TRACKS][0][ALBUM][RELEASE_DATE].split('-')[0]
 | 
				
			||||||
    duration_ms = info[TRACKS][0][DURATION_MS]
 | 
					        disc_number = info[TRACKS][0][DISC_NUMBER]
 | 
				
			||||||
 | 
					        track_number = info[TRACKS][0][TRACK_NUMBER]
 | 
				
			||||||
 | 
					        scraped_song_id = info[TRACKS][0][ID]
 | 
				
			||||||
 | 
					        is_playable = info[TRACKS][0][IS_PLAYABLE]
 | 
				
			||||||
 | 
					        duration_ms = info[TRACKS][0][DURATION_MS]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return artists, album_name, name, image_url, release_year, disc_number, track_number, scraped_song_id, is_playable, duration_ms
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        raise ValueError(f'Failed to parse TRACKS_URL response: {str(e)}\n{raw}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return artists, album_name, name, image_url, release_year, disc_number, track_number, scraped_song_id, is_playable, duration_ms
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_song_duration(song_id: str) -> float:
 | 
					def get_song_duration(song_id: str) -> float:
 | 
				
			||||||
    """ Retrieves duration of song in second as is on spotify """
 | 
					    """ Retrieves duration of song in second as is on spotify """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    resp = ZSpotify.invoke_url(f'{TRACK_STATS_URL}{song_id}')
 | 
					    (raw, resp) = ZSpotify.invoke_url(f'{TRACK_STATS_URL}{song_id}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # get duration in miliseconds
 | 
					    # get duration in miliseconds
 | 
				
			||||||
    ms_duration = resp['duration_ms']
 | 
					    ms_duration = resp['duration_ms']
 | 
				
			||||||
@ -83,6 +91,8 @@ def download_track(mode: str, track_id: str, extra_keys={}, disable_progressbar=
 | 
				
			|||||||
        for k in extra_keys:
 | 
					        for k in extra_keys:
 | 
				
			||||||
            output_template = output_template.replace("{"+k+"}", fix_filename(extra_keys[k]))
 | 
					            output_template = output_template.replace("{"+k+"}", fix_filename(extra_keys[k]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ext = EXT_MAP.get(ZSpotify.CONFIG.get_download_format().lower())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        output_template = output_template.replace("{artist}", fix_filename(artists[0]))
 | 
					        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("{album}", fix_filename(album_name))
 | 
				
			||||||
        output_template = output_template.replace("{song_name}", fix_filename(name))
 | 
					        output_template = output_template.replace("{song_name}", fix_filename(name))
 | 
				
			||||||
@ -91,11 +101,15 @@ def download_track(mode: str, track_id: str, extra_keys={}, disable_progressbar=
 | 
				
			|||||||
        output_template = output_template.replace("{track_number}", fix_filename(track_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("{id}", fix_filename(scraped_song_id))
 | 
				
			||||||
        output_template = output_template.replace("{track_id}", fix_filename(track_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()))
 | 
					        output_template = output_template.replace("{ext}", ext)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        filename = os.path.join(os.path.dirname(__file__), ZSpotify.CONFIG.get_root_path(), output_template)
 | 
					        filename = os.path.join(ZSpotify.CONFIG.get_root_path(), output_template)
 | 
				
			||||||
        filedir = os.path.dirname(filename)
 | 
					        filedir = os.path.dirname(filename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        filename_temp = filename
 | 
				
			||||||
 | 
					        if ZSpotify.CONFIG.get_temp_download_dir() != '':
 | 
				
			||||||
 | 
					            filename_temp = os.path.join(ZSpotify.CONFIG.get_temp_download_dir(), f'zspotify_{str(uuid.uuid4())}_{track_id}.{ext}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        check_name = os.path.isfile(filename) and os.path.getsize(filename)
 | 
					        check_name = os.path.isfile(filename) and os.path.getsize(filename)
 | 
				
			||||||
        check_id = scraped_song_id in get_directory_song_ids(filedir)
 | 
					        check_id = scraped_song_id in get_directory_song_ids(filedir)
 | 
				
			||||||
        check_all_time = scraped_song_id in get_previously_downloaded()
 | 
					        check_all_time = scraped_song_id in get_previously_downloaded()
 | 
				
			||||||
@ -113,6 +127,7 @@ def download_track(mode: str, track_id: str, extra_keys={}, disable_progressbar=
 | 
				
			|||||||
    except Exception as e:
 | 
					    except Exception as e:
 | 
				
			||||||
        Printer.print(PrintChannel.ERRORS, '###   SKIPPING SONG - FAILED TO QUERY METADATA   ###')
 | 
					        Printer.print(PrintChannel.ERRORS, '###   SKIPPING SONG - FAILED TO QUERY METADATA   ###')
 | 
				
			||||||
        Printer.print(PrintChannel.ERRORS, str(e) + "\n")
 | 
					        Printer.print(PrintChannel.ERRORS, str(e) + "\n")
 | 
				
			||||||
 | 
					        Printer.print(PrintChannel.ERRORS, "".join(traceback.TracebackException.from_exception(e).format()) + "\n")
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            if not is_playable:
 | 
					            if not is_playable:
 | 
				
			||||||
@ -128,14 +143,13 @@ def download_track(mode: str, track_id: str, extra_keys={}, disable_progressbar=
 | 
				
			|||||||
                    if track_id != scraped_song_id:
 | 
					                    if track_id != scraped_song_id:
 | 
				
			||||||
                        track_id = scraped_song_id
 | 
					                        track_id = scraped_song_id
 | 
				
			||||||
                    track_id = TrackId.from_base62(track_id)
 | 
					                    track_id = TrackId.from_base62(track_id)
 | 
				
			||||||
                    stream = ZSpotify.get_content_stream(
 | 
					                    stream = ZSpotify.get_content_stream(track_id, ZSpotify.DOWNLOAD_QUALITY)
 | 
				
			||||||
                        track_id, ZSpotify.DOWNLOAD_QUALITY)
 | 
					 | 
				
			||||||
                    create_download_directory(filedir)
 | 
					                    create_download_directory(filedir)
 | 
				
			||||||
                    total_size = stream.input_stream.size
 | 
					                    total_size = stream.input_stream.size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    time_start = time.time()
 | 
					                    time_start = time.time()
 | 
				
			||||||
                    downloaded = 0
 | 
					                    downloaded = 0
 | 
				
			||||||
                    with open(filename, 'wb') as file, Printer.progress(
 | 
					                    with open(filename_temp, 'wb') as file, Printer.progress(
 | 
				
			||||||
                            desc=song_name,
 | 
					                            desc=song_name,
 | 
				
			||||||
                            total=total_size,
 | 
					                            total=total_size,
 | 
				
			||||||
                            unit='B',
 | 
					                            unit='B',
 | 
				
			||||||
@ -155,13 +169,16 @@ def download_track(mode: str, track_id: str, extra_keys={}, disable_progressbar=
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    time_downloaded = time.time()
 | 
					                    time_downloaded = time.time()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    convert_audio_format(filename)
 | 
					                    convert_audio_format(filename_temp)
 | 
				
			||||||
                    set_audio_tags(filename, artists, name, album_name, release_year, disc_number, track_number)
 | 
					                    set_audio_tags(filename_temp, artists, name, album_name, release_year, disc_number, track_number)
 | 
				
			||||||
                    set_music_thumbnail(filename, image_url)
 | 
					                    set_music_thumbnail(filename_temp, image_url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if filename_temp != filename:
 | 
				
			||||||
 | 
					                        os.rename(filename_temp, filename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    time_finished = time.time()
 | 
					                    time_finished = time.time()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    Printer.print(PrintChannel.DOWNLOADS, f'###   Downloaded "{song_name}" to "{os.path.relpath(filename, os.path.dirname(__file__))}" in {fmt_seconds(time_downloaded - time_start)} (plus {fmt_seconds(time_finished - time_downloaded)} converting)   ###' + "\n")
 | 
					                    Printer.print(PrintChannel.DOWNLOADS, f'###   Downloaded "{song_name}" to "{os.path.relpath(filename, ZSpotify.CONFIG.get_root_path())}" in {fmt_seconds(time_downloaded - time_start)} (plus {fmt_seconds(time_finished - time_downloaded)} converting)   ###' + "\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    # add song id to archive file
 | 
					                    # add song id to archive file
 | 
				
			||||||
                    if ZSpotify.CONFIG.get_skip_previously_downloaded():
 | 
					                    if ZSpotify.CONFIG.get_skip_previously_downloaded():
 | 
				
			||||||
@ -176,8 +193,8 @@ def download_track(mode: str, track_id: str, extra_keys={}, disable_progressbar=
 | 
				
			|||||||
            Printer.print(PrintChannel.ERRORS, '###   SKIPPING: ' + song_name + ' (GENERAL DOWNLOAD ERROR)   ###')
 | 
					            Printer.print(PrintChannel.ERRORS, '###   SKIPPING: ' + song_name + ' (GENERAL DOWNLOAD ERROR)   ###')
 | 
				
			||||||
            Printer.print(PrintChannel.ERRORS, str(e) + "\n")
 | 
					            Printer.print(PrintChannel.ERRORS, str(e) + "\n")
 | 
				
			||||||
            Printer.print(PrintChannel.ERRORS, "".join(traceback.TracebackException.from_exception(e).format()) + "\n")
 | 
					            Printer.print(PrintChannel.ERRORS, "".join(traceback.TracebackException.from_exception(e).format()) + "\n")
 | 
				
			||||||
            if os.path.exists(filename):
 | 
					            if os.path.exists(filename_temp):
 | 
				
			||||||
                os.remove(filename)
 | 
					                os.remove(filename_temp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def convert_audio_format(filename) -> None:
 | 
					def convert_audio_format(filename) -> None:
 | 
				
			||||||
 | 
				
			|||||||
@ -36,7 +36,7 @@ def get_previously_downloaded() -> List[str]:
 | 
				
			|||||||
    """ Returns list of all time downloaded songs """
 | 
					    """ Returns list of all time downloaded songs """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ids = []
 | 
					    ids = []
 | 
				
			||||||
    archive_path = os.path.join(os.path.dirname(__file__), ZSpotify.CONFIG.get_root_path(), ZSpotify.CONFIG.get_song_archive())
 | 
					    archive_path = ZSpotify.CONFIG.get_song_archive()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if os.path.exists(archive_path):
 | 
					    if os.path.exists(archive_path):
 | 
				
			||||||
        with open(archive_path, 'r', encoding='utf-8') as f:
 | 
					        with open(archive_path, 'r', encoding='utf-8') as f:
 | 
				
			||||||
@ -48,7 +48,7 @@ def get_previously_downloaded() -> List[str]:
 | 
				
			|||||||
def add_to_archive(song_id: str, filename: str, author_name: str, song_name: str) -> None:
 | 
					def add_to_archive(song_id: str, filename: str, author_name: str, song_name: str) -> None:
 | 
				
			||||||
    """ Adds song id to all time installed songs archive """
 | 
					    """ Adds song id to all time installed songs archive """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    archive_path = os.path.join(os.path.dirname(__file__), ZSpotify.CONFIG.get_root_path(), ZSpotify.CONFIG.get_song_archive())
 | 
					    archive_path = ZSpotify.CONFIG.get_song_archive()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if os.path.exists(archive_path):
 | 
					    if os.path.exists(archive_path):
 | 
				
			||||||
        with open(archive_path, 'a', encoding='utf-8') as file:
 | 
					        with open(archive_path, 'a', encoding='utf-8') as file:
 | 
				
			||||||
 | 
				
			|||||||
@ -35,7 +35,7 @@ class ZSpotify:
 | 
				
			|||||||
    def login(cls):
 | 
					    def login(cls):
 | 
				
			||||||
        """ Authenticates with Spotify and saves credentials to a file """
 | 
					        """ Authenticates with Spotify and saves credentials to a file """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cred_location = os.path.join(os.getcwd(), Config.get_credentials_location())
 | 
					        cred_location = Config.get_credentials_location()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if os.path.isfile(cred_location):
 | 
					        if os.path.isfile(cred_location):
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
@ -86,7 +86,8 @@ class ZSpotify:
 | 
				
			|||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def invoke_url(cls, url):
 | 
					    def invoke_url(cls, url):
 | 
				
			||||||
        headers = cls.get_auth_header()
 | 
					        headers = cls.get_auth_header()
 | 
				
			||||||
        return requests.get(url, headers=headers).json()
 | 
					        response = requests.get(url, headers=headers)
 | 
				
			||||||
 | 
					        return response.text, response.json()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def check_premium(cls) -> bool:
 | 
					    def check_premium(cls) -> bool:
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user