diff --git a/zspotify/config.py b/zspotify/config.py index 0ba7d6d..0c4e9cf 100644 --- a/zspotify/config.py +++ b/zspotify/config.py @@ -26,6 +26,8 @@ PRINT_DOWNLOAD_PROGRESS = 'PRINT_DOWNLOAD_PROGRESS' PRINT_ERRORS = 'PRINT_ERRORS' PRINT_DOWNLOADS = 'PRINT_DOWNLOADS' TEMP_DOWNLOAD_DIR = 'TEMP_DOWNLOAD_DIR' +MD_ALLGENRES = 'MD_ALLGENRES' +MD_GENREDELIMITER = 'MD_GENREDELIMITER' CONFIG_VALUES = { ROOT_PATH: { 'default': '../ZSpotify Music/', 'type': str, 'arg': '--root-path' }, @@ -49,7 +51,9 @@ CONFIG_VALUES = { PRINT_DOWNLOAD_PROGRESS: { 'default': 'True', 'type': bool, 'arg': '--print-download-progress' }, PRINT_ERRORS: { 'default': 'True', 'type': bool, 'arg': '--print-errors' }, PRINT_DOWNLOADS: { 'default': 'False', 'type': bool, 'arg': '--print-downloads' }, - TEMP_DOWNLOAD_DIR: { 'default': '', 'type': str, 'arg': '--temp-download-dir' }, + MD_ALLGENRES: { 'default': 'False', 'type': bool, 'arg': '--md-allgenres' }, + MD_GENREDELIMITER: { 'default': ';', 'type': str, 'arg': '--md-genredelimiter' }, + TEMP_DOWNLOAD_DIR: { 'default': '', 'type': str, 'arg': '--temp-download-dir' } } OUTPUT_DEFAULT_PLAYLIST = '{playlist}/{artist} - {song_name}.{ext}' @@ -192,7 +196,15 @@ class Config: if cls.get(TEMP_DOWNLOAD_DIR) == '': return '' return os.path.join(cls.get_root_path(), cls.get(TEMP_DOWNLOAD_DIR)) + + @classmethod + def get_allGenres(cls) -> bool: + return cls.get(MD_ALLGENRES) + @classmethod + def get_allGenresDelimiter(cls) -> bool: + return cls.get(MD_GENREDELIMITER) + @classmethod def get_output(cls, mode: str) -> str: v = cls.get(OUTPUT) diff --git a/zspotify/const.py b/zspotify/const.py index 057921c..3e76f8a 100644 --- a/zspotify/const.py +++ b/zspotify/const.py @@ -20,6 +20,10 @@ ARTISTS = 'artists' ALBUMARTIST = 'albumartist' +GENRES = 'genres' + +GENRE = 'genre' + ARTWORK = 'artwork' TRACKS = 'tracks' diff --git a/zspotify/track.py b/zspotify/track.py index 1278412..faa630b 100644 --- a/zspotify/track.py +++ b/zspotify/track.py @@ -8,7 +8,7 @@ from librespot.audio.decoders import AudioQuality from librespot.metadata import TrackId from ffmpy import FFmpeg -from const import TRACKS, ALBUM, NAME, ITEMS, DISC_NUMBER, TRACK_NUMBER, IS_PLAYABLE, ARTISTS, IMAGES, URL, \ +from const import TRACKS, ALBUM, GENRES, GENRE, NAME, ITEMS, DISC_NUMBER, TRACK_NUMBER, IS_PLAYABLE, ARTISTS, IMAGES, URL, \ RELEASE_DATE, ID, TRACKS_URL, SAVED_TRACKS_URL, TRACK_STATS_URL, CODEC_MAP, EXT_MAP, DURATION_MS from termoutput import Printer, PrintChannel from utils import fix_filename, set_audio_tags, set_music_thumbnail, create_download_directory, \ @@ -33,7 +33,7 @@ def get_saved_tracks() -> list: return songs -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], List[str], str, str, Any, Any, Any, Any, Any, Any, int]: """ Retrieves metadata for downloaded songs """ (raw, info) = ZSpotify.invoke_url(f'{TRACKS_URL}?ids={song_id}&market=from_token') @@ -42,8 +42,18 @@ def get_song_info(song_id) -> Tuple[List[str], str, str, Any, Any, Any, Any, Any try: artists = [] + genres = [] for data in info[TRACKS][0][ARTISTS]: artists.append(data[NAME]) + # query artist genres via href, which will be the api url + (raw, artistInfo) = ZSpotify.invoke_url(f'{data["href"]}') + if ZSpotify.CONFIG.get_allGenres() and len(artistInfo[GENRES]) > 0: + for genre in artistInfo[GENRES]: + genres.append(genre) + elif len(artistInfo[GENRES]) > 0: + genres.append(artistInfo[GENRES][0]) + else: + genres.append('') album_name = info[TRACKS][0][ALBUM][NAME] name = info[TRACKS][0][NAME] image_url = info[TRACKS][0][ALBUM][IMAGES][0][URL] @@ -54,7 +64,7 @@ def get_song_info(song_id) -> Tuple[List[str], str, str, Any, Any, Any, Any, Any 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 + return artists, genres, 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}') @@ -82,7 +92,7 @@ def download_track(mode: str, track_id: str, extra_keys={}, disable_progressbar= try: output_template = ZSpotify.CONFIG.get_output(mode) - (artists, album_name, name, image_url, release_year, disc_number, + (artists, genres, album_name, name, image_url, release_year, disc_number, track_number, scraped_song_id, is_playable, duration_ms) = get_song_info(track_id) song_name = fix_filename(artists[0]) + ' - ' + fix_filename(name) @@ -170,7 +180,7 @@ def download_track(mode: str, track_id: str, extra_keys={}, disable_progressbar= time_downloaded = time.time() convert_audio_format(filename_temp) - set_audio_tags(filename_temp, artists, name, album_name, release_year, disc_number, track_number) + set_audio_tags(filename_temp, artists, genres, name, album_name, release_year, disc_number, track_number) set_music_thumbnail(filename_temp, image_url) if filename_temp != filename: diff --git a/zspotify/utils.py b/zspotify/utils.py index 3656145..f56ce5d 100644 --- a/zspotify/utils.py +++ b/zspotify/utils.py @@ -10,7 +10,7 @@ from typing import List, Tuple import music_tag import requests -from const import ARTIST, TRACKTITLE, ALBUM, YEAR, DISCNUMBER, TRACKNUMBER, ARTWORK, \ +from const import ARTIST, GENRE, TRACKTITLE, ALBUM, YEAR, DISCNUMBER, TRACKNUMBER, ARTWORK, \ WINDOWS_SYSTEM, ALBUMARTIST from zspotify import ZSpotify @@ -124,11 +124,12 @@ def clear() -> None: os.system('clear') -def set_audio_tags(filename, artists, name, album_name, release_year, disc_number, track_number) -> None: +def set_audio_tags(filename, artists, genres, name, album_name, release_year, disc_number, track_number) -> None: """ sets music_tag metadata """ tags = music_tag.load_file(filename) tags[ALBUMARTIST] = artists[0] tags[ARTIST] = conv_artist_format(artists) + tags[GENRE] = genres[0] if not ZSpotify.CONFIG.get_allGenres() else ZSpotify.CONFIG.get_allGenresDelimiter().join(genres) tags[TRACKTITLE] = name tags[ALBUM] = album_name tags[YEAR] = release_year