mirror of
https://github.com/glomatico/votify.git
synced 2026-09-30 04:52:30 +02:00
Fix
Refactor media metadata handling and improve error logging.
This commit is contained in:
+119
-30
@@ -1,5 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import traceback
|
||||
|
||||
import inspect
|
||||
import logging
|
||||
import time
|
||||
@@ -489,7 +491,7 @@ def main(
|
||||
)
|
||||
|
||||
is_premium = (
|
||||
True if force_premium else spotify_api.user_profile["product"] == "premium"
|
||||
True if force_premium else spotify_api.user_profile['data']['me']['account']['product'] == "premium"
|
||||
)
|
||||
if not lrc_only:
|
||||
if download_mode == DownloadMode.ARIA2C and not downloader.aria2c_path_full:
|
||||
@@ -566,11 +568,19 @@ def main(
|
||||
urls = _urls
|
||||
|
||||
error_count = 0
|
||||
|
||||
global_playlist_metadata = None
|
||||
|
||||
for url_index, url in enumerate(urls, start=1):
|
||||
url_progress = color_text(f"URL {url_index}/{len(urls)}", colorama.Style.DIM)
|
||||
logger.info(f'({url_progress}) Checking "{url}"')
|
||||
try:
|
||||
url_info = downloader.get_url_info(url)
|
||||
|
||||
if url_info.type == 'playlist':
|
||||
if hasattr(url_info, 'name') and url_info.name:
|
||||
global_playlist_metadata = {'name': url_info.name, 'owner_name': getattr(url_info, 'owner', 'Unknown')}
|
||||
|
||||
if url_info.type == "artist":
|
||||
download_queue = downloader.get_download_queue_from_artist(url_info.id)
|
||||
else:
|
||||
@@ -582,76 +592,154 @@ def main(
|
||||
error_count += 1
|
||||
logger.error(
|
||||
f'({url_progress}) Failed to check "{url}"',
|
||||
exc_info=no_exceptions,
|
||||
exc_info=not no_exceptions,
|
||||
)
|
||||
continue
|
||||
|
||||
for index, download_queue_item in enumerate(download_queue, start=1):
|
||||
queue_progress = color_text(
|
||||
f"Track {index}/{len(download_queue)} from URL {url_index}/{len(urls)}",
|
||||
colorama.Style.DIM,
|
||||
)
|
||||
media_metadata = download_queue_item.media_metadata
|
||||
|
||||
media_metadata = None
|
||||
if isinstance(download_queue_item, dict):
|
||||
media_metadata = download_queue_item.get("media_metadata", download_queue_item)
|
||||
else:
|
||||
media_metadata = getattr(download_queue_item, "media_metadata", download_queue_item)
|
||||
|
||||
if not isinstance(media_metadata, dict):
|
||||
media_metadata = getattr(media_metadata, "__dict__", {})
|
||||
|
||||
if isinstance(media_metadata, dict) and 'track' in media_metadata and isinstance(media_metadata['track'],dict):
|
||||
clean_track_metadata = media_metadata['track']
|
||||
else:
|
||||
clean_track_metadata = media_metadata
|
||||
|
||||
track_name = "Unknown Track"
|
||||
try:
|
||||
logger.info(
|
||||
f'({queue_progress}) Downloading "{media_metadata["name"]}"'
|
||||
)
|
||||
media_id = downloader.get_media_id(media_metadata)
|
||||
media_type = media_metadata["type"]
|
||||
gid_metadata = downloader.get_gid_metadata(media_id, media_type)
|
||||
track_name = media_metadata["data"]["trackUnion"]["name"]
|
||||
except (KeyError, TypeError):
|
||||
track_name = clean_track_metadata.get("name", "Unknown Track")
|
||||
|
||||
is_playable = True
|
||||
|
||||
if isinstance(clean_track_metadata, dict):
|
||||
|
||||
if clean_track_metadata.get('isPlayable') is False:
|
||||
is_playable = False
|
||||
elif clean_track_metadata.get('is_playable') is False:
|
||||
is_playable = False
|
||||
elif clean_track_metadata.get('playable') is False:
|
||||
is_playable = False
|
||||
|
||||
elif 'data' in clean_track_metadata:
|
||||
try:
|
||||
union = clean_track_metadata['data']['trackUnion']
|
||||
if union.get('isPlayable') is False or union.get('playable') is False:
|
||||
is_playable = False
|
||||
except:
|
||||
pass
|
||||
|
||||
if not is_playable:
|
||||
logger.warning(f'({queue_progress}) Skipping "{track_name}": Track unavailable/unplayable.')
|
||||
continue
|
||||
|
||||
try:
|
||||
logger.info(f'({queue_progress}) Downloading "{track_name}"')
|
||||
|
||||
try:
|
||||
media_id = downloader.get_media_id(clean_track_metadata)
|
||||
except ValueError:
|
||||
if isinstance(download_queue_item, dict) and 'id' in download_queue_item:
|
||||
media_id = download_queue_item['id']
|
||||
else:
|
||||
raise
|
||||
|
||||
media_metadata_for_download = media_metadata
|
||||
|
||||
media_type = "track"
|
||||
try:
|
||||
type_from_meta = media_metadata['data']['trackUnion']['__typename']
|
||||
media_type = type_from_meta.lower()
|
||||
except (KeyError, TypeError, AttributeError):
|
||||
if isinstance(media_metadata, dict) and 'episode' in media_metadata:
|
||||
media_type = "episode"
|
||||
media_metadata_for_download = None
|
||||
else:
|
||||
media_type = "track"
|
||||
media_metadata_for_download = None
|
||||
|
||||
gid_metadata = downloader.get_gid_metadata(media_id, media_type, spotify_api.user_profile)
|
||||
|
||||
def get_meta(item, key):
|
||||
val = getattr(item, key, None)
|
||||
if val is None and isinstance(item, dict):
|
||||
val = item.get(key)
|
||||
return val
|
||||
|
||||
safe_album_metadata = get_meta(download_queue_item, "album_metadata")
|
||||
safe_playlist_metadata = get_meta(download_queue_item, "playlist_metadata")
|
||||
safe_show_metadata = get_meta(download_queue_item, "show_metadata")
|
||||
|
||||
if not safe_playlist_metadata and global_playlist_metadata:
|
||||
safe_playlist_metadata = global_playlist_metadata
|
||||
|
||||
if media_type == "track":
|
||||
if disable_wvd:
|
||||
logger.warning(
|
||||
"Widevine decryption is disabled, "
|
||||
"skipping Widevine protected content"
|
||||
)
|
||||
logger.warning("Widevine decryption is disabled, skipping.")
|
||||
continue
|
||||
if audio_quality in VORBIS_AUDIO_QUALITIES:
|
||||
logger.warning(
|
||||
"Vorbis audio quality is only supported for podcasts, "
|
||||
"skipping"
|
||||
)
|
||||
logger.warning("Vorbis audio quality is only supported for podcasts.")
|
||||
continue
|
||||
|
||||
if download_music_videos:
|
||||
downloader_music_video.download(
|
||||
music_video_id=media_id,
|
||||
music_video_metadata=media_metadata,
|
||||
album_metadata=download_queue_item.album_metadata,
|
||||
music_video_metadata=media_metadata_for_download,
|
||||
album_metadata=safe_album_metadata,
|
||||
gid_metadata=gid_metadata,
|
||||
playlist_metadata=download_queue_item.playlist_metadata,
|
||||
playlist_metadata=safe_playlist_metadata,
|
||||
playlist_track=index,
|
||||
)
|
||||
else:
|
||||
downloader_song.download(
|
||||
track_id=media_id,
|
||||
track_metadata=media_metadata,
|
||||
album_metadata=download_queue_item.album_metadata,
|
||||
track_metadata=media_metadata_for_download,
|
||||
album_metadata=safe_album_metadata,
|
||||
gid_metadata=gid_metadata,
|
||||
playlist_metadata=download_queue_item.playlist_metadata,
|
||||
playlist_metadata=safe_playlist_metadata,
|
||||
product_name=spotify_api.user_profile,
|
||||
playlist_track=index,
|
||||
)
|
||||
|
||||
elif media_type == "episode":
|
||||
if download_podcast_videos:
|
||||
downloader_episode_video.download(
|
||||
episode_id=media_id,
|
||||
episode_metadata=media_metadata,
|
||||
show_metadata=download_queue_item.show_metadata,
|
||||
episode_metadata=media_metadata_for_download,
|
||||
show_metadata=safe_show_metadata,
|
||||
gid_metadata=gid_metadata,
|
||||
playlist_metadata=download_queue_item.playlist_metadata,
|
||||
playlist_metadata=safe_playlist_metadata,
|
||||
playlist_track=index,
|
||||
)
|
||||
else:
|
||||
downloader_episode.download(
|
||||
episode_id=media_id,
|
||||
episode_metadata=media_metadata,
|
||||
show_metadata=download_queue_item.show_metadata,
|
||||
episode_metadata=media_metadata_for_download,
|
||||
show_metadata=safe_show_metadata,
|
||||
gid_metadata=gid_metadata,
|
||||
playlist_metadata=download_queue_item.playlist_metadata,
|
||||
playlist_metadata=safe_playlist_metadata,
|
||||
playlist_track=index,
|
||||
)
|
||||
#except ValueError:
|
||||
# error_count += 1
|
||||
# continue
|
||||
|
||||
except Exception as e:
|
||||
error_count += 1
|
||||
logger.error(
|
||||
f'({queue_progress}) Failed to download "{media_metadata["name"]}"',
|
||||
f'({queue_progress}) Failed to download "{track_name}"',
|
||||
exc_info=not no_exceptions,
|
||||
)
|
||||
finally:
|
||||
@@ -660,4 +748,5 @@ def main(
|
||||
f"Waiting for {wait_interval} second(s) before continuing"
|
||||
)
|
||||
time.sleep(wait_interval)
|
||||
|
||||
logger.info(f"Done ({error_count} error(s))")
|
||||
|
||||
Reference in New Issue
Block a user