debloating

This commit is contained in:
Xoconoch
2025-06-03 14:39:53 -06:00
parent af7eacde1b
commit 75f619102d
8 changed files with 134 additions and 273 deletions

View File

@@ -33,6 +33,8 @@ from deezspot.libutils.utils import (
trasform_sync_lyric,
create_zip,
sanitize_name,
save_cover_image,
__get_dir as get_album_directory,
)
from mutagen.flac import FLAC
from mutagen.mp3 import MP3
@@ -192,7 +194,6 @@ class EASY_DW:
self.__ids = preferences.ids
self.__link = preferences.link
self.__output_dir = preferences.output_dir
self.__method_save = preferences.method_save
self.__not_interface = preferences.not_interface
self.__quality_download = preferences.quality_download
self.__recursive_quality = preferences.recursive_quality
@@ -277,7 +278,6 @@ class EASY_DW:
self.__output_dir,
self.__song_quality,
self.__file_format,
self.__method_save,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks
@@ -292,7 +292,6 @@ class EASY_DW:
self.__output_dir,
self.__song_quality,
self.__file_format,
self.__method_save,
is_episode=True,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
@@ -915,10 +914,9 @@ class DW_ALBUM:
self.__ids = self.__preferences.ids
self.__make_zip = self.__preferences.make_zip
self.__output_dir = self.__preferences.output_dir
self.__method_save = self.__preferences.method_save
self.__song_metadata = self.__preferences.song_metadata
self.__not_interface = self.__preferences.not_interface
self.__quality_download = self.__preferences.quality_download
self.__recursive_quality = self.__preferences.recursive_quality
self.__song_metadata_items = self.__song_metadata.items()
@@ -966,11 +964,11 @@ class DW_ALBUM:
infos_dw = API_GW.get_album_data(self.__ids)['data']
md5_image = infos_dw[0]['ALB_PICTURE']
image = API.choose_img(md5_image)
self.__song_metadata['image'] = image
image_bytes = API.choose_img(md5_image, size="1400x1400") # Fetch highest quality
self.__song_metadata['image'] = image_bytes # Store for tagging if needed, already bytes
album = Album(self.__ids)
album.image = image
album.image = image_bytes # Store raw image bytes
album.md5_image = md5_image
album.nb_tracks = self.__song_metadata['nb_tracks']
album.album_name = self.__song_metadata['album']
@@ -983,7 +981,13 @@ class DW_ALBUM:
infos_dw, self.__quality_download
)
# The album_artist for tagging individual tracks will be derived_album_artist_from_contributors
# Determine album base directory once
album_base_directory = get_album_directory(
self.__song_metadata, # Album level metadata
self.__output_dir,
custom_dir_format=self.__preferences.custom_dir_format,
pad_tracks=self.__preferences.pad_tracks
)
total_tracks = len(infos_dw)
for a in range(total_tracks):
@@ -1074,6 +1078,10 @@ class DW_ALBUM:
logger.warning(f"Track not found: {song} :( Details: {track.error_message}. URL: {c_preferences.link if c_preferences else 'N/A'}")
tracks.append(track)
# Save album cover image
if album.image and album_base_directory:
save_cover_image(album.image, album_base_directory, "cover.jpg")
if self.__make_zip:
song_quality = tracks[0].quality if tracks else 'Unknown'
# Pass along custom directory format if set
@@ -1083,7 +1091,6 @@ class DW_ALBUM:
output_dir=self.__output_dir,
song_metadata=self.__song_metadata,
song_quality=song_quality,
method_save=self.__method_save,
custom_dir_format=custom_dir_format
)
album.zip_path = zip_name
@@ -1226,7 +1233,6 @@ class DW_EPISODE:
self.__preferences = preferences
self.__ids = preferences.ids
self.__output_dir = preferences.output_dir
self.__method_save = preferences.method_save
self.__not_interface = preferences.not_interface
self.__quality_download = preferences.quality_download
@@ -1335,6 +1341,16 @@ class DW_EPISODE:
}
Download_JOB.report_progress(progress_data)
# Save cover image for the episode
episode_image_md5 = infos_dw.get('EPISODE_IMAGE_MD5', '')
episode_image_data = None
if episode_image_md5:
episode_image_data = API.choose_img(episode_image_md5, size="1200x1200")
if episode_image_data:
episode_directory = os.path.dirname(output_path)
save_cover_image(episode_image_data, episode_directory, "cover.jpg")
return episode
except Exception as e:

View File

@@ -39,7 +39,7 @@ from deezspot.libutils.others_settings import (
stock_recursive_download,
stock_not_interface,
stock_zip,
method_save,
stock_save_cover,
)
from deezspot.libutils.logging_utils import ProgressReporter, logger
@@ -97,7 +97,6 @@ class DeeLogin:
recursive_quality=stock_recursive_quality,
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
method_save=method_save,
custom_dir_format=None,
custom_track_format=None,
pad_tracks=True,
@@ -130,7 +129,6 @@ class DeeLogin:
preferences.recursive_quality = recursive_quality
preferences.recursive_download = recursive_download
preferences.not_interface = not_interface
preferences.method_save = method_save
# New custom formatting preferences:
preferences.custom_dir_format = custom_dir_format
preferences.custom_track_format = custom_track_format
@@ -155,14 +153,14 @@ class DeeLogin:
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
make_zip=stock_zip,
method_save=method_save,
custom_dir_format=None,
custom_track_format=None,
pad_tracks=True,
initial_retry_delay=30,
retry_delay_increase=30,
max_retries=5,
convert_to=None
convert_to=None,
save_cover=stock_save_cover
) -> Album:
link_is_valid(link_album)
@@ -185,7 +183,6 @@ class DeeLogin:
preferences.recursive_quality = recursive_quality
preferences.recursive_download = recursive_download
preferences.not_interface = not_interface
preferences.method_save = method_save
preferences.make_zip = make_zip
# New custom formatting preferences:
preferences.custom_dir_format = custom_dir_format
@@ -198,6 +195,7 @@ class DeeLogin:
preferences.max_retries = max_retries
# Audio conversion parameter
preferences.convert_to = convert_to
preferences.save_cover = save_cover
album = DW_ALBUM(preferences).dw()
@@ -211,7 +209,6 @@ class DeeLogin:
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
make_zip=stock_zip,
method_save=method_save,
custom_dir_format=None,
custom_track_format=None,
pad_tracks=True,
@@ -251,7 +248,6 @@ class DeeLogin:
preferences.recursive_quality = recursive_quality
preferences.recursive_download = recursive_download
preferences.not_interface = not_interface
preferences.method_save = method_save
preferences.make_zip = make_zip
# New custom formatting preferences:
preferences.custom_dir_format = custom_dir_format
@@ -276,7 +272,6 @@ class DeeLogin:
recursive_quality=stock_recursive_quality,
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
method_save=method_save,
custom_dir_format=None,
custom_track_format=None,
pad_tracks=True,
@@ -293,7 +288,6 @@ class DeeLogin:
track['link'], output_dir,
quality_download, recursive_quality,
recursive_download, not_interface,
method_save=method_save,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,
@@ -332,7 +326,6 @@ class DeeLogin:
recursive_quality=stock_recursive_quality,
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
method_save=method_save,
custom_dir_format=None,
custom_track_format=None,
pad_tracks=True,
@@ -351,7 +344,6 @@ class DeeLogin:
recursive_quality=recursive_quality,
recursive_download=recursive_download,
not_interface=not_interface,
method_save=method_save,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,
@@ -450,7 +442,6 @@ class DeeLogin:
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
make_zip=stock_zip,
method_save=method_save,
custom_dir_format=None,
custom_track_format=None,
pad_tracks=True,
@@ -466,7 +457,7 @@ class DeeLogin:
link_dee, output_dir,
quality_download, recursive_quality,
recursive_download, not_interface,
make_zip, method_save,
make_zip,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,
@@ -486,7 +477,6 @@ class DeeLogin:
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
make_zip=stock_zip,
method_save=method_save,
custom_dir_format=None,
custom_track_format=None,
pad_tracks=True,
@@ -563,7 +553,6 @@ class DeeLogin:
recursive_quality=recursive_quality,
recursive_download=recursive_download,
not_interface=not_interface,
method_save=method_save,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,
@@ -618,7 +607,6 @@ class DeeLogin:
recursive_quality=stock_recursive_quality,
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
method_save=method_save,
custom_dir_format=None,
custom_track_format=None,
pad_tracks=True,
@@ -648,7 +636,6 @@ class DeeLogin:
recursive_quality=recursive_quality,
recursive_download=recursive_download,
not_interface=not_interface,
method_save=method_save,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,
@@ -665,14 +652,14 @@ class DeeLogin:
recursive_quality=stock_recursive_quality,
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
method_save=method_save,
custom_dir_format=None,
custom_track_format=None,
pad_tracks=True,
initial_retry_delay=30,
retry_delay_increase=30,
max_retries=5,
convert_to=None
convert_to=None,
save_cover=stock_save_cover
) -> Episode:
link_is_valid(link_episode)
@@ -707,16 +694,8 @@ class DeeLogin:
preferences.recursive_quality = recursive_quality
preferences.recursive_download = recursive_download
preferences.not_interface = not_interface
preferences.method_save = method_save
# New custom formatting preferences:
preferences.custom_dir_format = custom_dir_format
preferences.custom_track_format = custom_track_format
# Track number padding option
preferences.pad_tracks = pad_tracks
# Retry parameters
preferences.initial_retry_delay = initial_retry_delay
preferences.retry_delay_increase = retry_delay_increase
preferences.max_retries = max_retries
# No convert_to for episode download
preferences.save_cover = save_cover
episode = DW_EPISODE(preferences).dw()
@@ -730,7 +709,6 @@ class DeeLogin:
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
make_zip=stock_zip,
method_save=method_save,
custom_dir_format=None,
custom_track_format=None,
pad_tracks=True,
@@ -773,7 +751,6 @@ class DeeLogin:
recursive_quality=recursive_quality,
recursive_download=recursive_download,
not_interface=not_interface,
method_save=method_save,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,
@@ -800,7 +777,6 @@ class DeeLogin:
recursive_download=recursive_download,
not_interface=not_interface,
make_zip=make_zip,
method_save=method_save,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,
@@ -827,7 +803,6 @@ class DeeLogin:
recursive_download=recursive_download,
not_interface=not_interface,
make_zip=make_zip,
method_save=method_save,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,

View File

@@ -115,45 +115,6 @@ def check_track_md5(infos_dw):
logger.error(f"Failed to check track MD5: {str(e)}")
raise
def set_path(song_metadata, output_dir, method_save):
"""
Set the output path for a track based on metadata and save method.
Args:
song_metadata: Track metadata
output_dir: Base output directory
method_save: Save method (e.g., 'artist/album/track')
Returns:
str: Full output path
"""
try:
# Create base directory if it doesn't exist
os.makedirs(output_dir, exist_ok=True)
# Build path based on method
if method_save == 'artist/album/track':
path = os.path.join(
output_dir,
song_metadata['artist'],
song_metadata['album'],
f"{song_metadata['music']}.mp3"
)
else:
path = os.path.join(
output_dir,
f"{song_metadata['artist']} - {song_metadata['music']}.mp3"
)
# Create parent directories
os.makedirs(os.path.dirname(path), exist_ok=True)
return path
except Exception as e:
logger.error(f"Failed to set path: {str(e)}")
raise
def trasform_sync_lyric(lyrics):
"""
Transform synchronized lyrics into a standard format.

View File

@@ -21,5 +21,5 @@ stock_recursive_quality = False
stock_recursive_download = False
stock_not_interface = False
stock_zip = False
is_thread = False # WARNING FOR TRUE, LOOP ON DEFAULT
stock_real_time_dl = True
stock_save_cover = False # Default for saving cover image

View File

@@ -203,7 +203,6 @@ def set_path(
pad_tracks=True
):
# Determine the directory for the song
# method_save is removed, __get_dir now only relies on custom_dir_format
directory = __get_dir(
song_metadata,
output_dir,
@@ -306,3 +305,27 @@ def trasform_sync_lyric(lyric):
arr = (a['line'], int(a['milliseconds']))
sync_array.append(arr)
return sync_array
def save_cover_image(image_data: bytes, directory_path: str, cover_filename: str = "cover.jpg"):
if not image_data:
logger.warning(f"No image data provided to save cover in {directory_path}.")
return
if not isdir(directory_path):
# This case should ideally be handled by prior directory creation (e.g., __get_dir)
# but as a fallback, we can try to create it or log a warning.
logger.warning(f"Directory {directory_path} does not exist. Attempting to create it for cover image.")
try:
makedirs(directory_path, exist_ok=True)
logger.info(f"Created directory {directory_path} for cover image.")
except OSError as e:
logger.error(f"Failed to create directory {directory_path} for cover: {e}")
return
cover_path = join(directory_path, cover_filename)
try:
with open(cover_path, "wb") as f:
f.write(image_data)
logger.info(f"Successfully saved cover image to {cover_path}")
except OSError as e:
logger.error(f"Failed to save cover image to {cover_path}: {e}")

View File

@@ -19,3 +19,4 @@ class Preferences:
self.initial_retry_delay = 30 # Default initial retry delay in seconds
self.retry_delay_increase = 30 # Default increase in delay between retries in seconds
self.max_retries = 5 # Default maximum number of retries per track
self.save_cover: bool = False # Option to save a cover.jpg image

View File

@@ -32,6 +32,8 @@ from deezspot.libutils.utils import (
create_zip,
request,
sanitize_name,
save_cover_image,
__get_dir as get_album_directory,
)
from mutagen import File
from mutagen.easyid3 import EasyID3
@@ -136,7 +138,6 @@ class EASY_DW:
self.__ids = preferences.ids
self.__link = preferences.link
self.__output_dir = preferences.output_dir
self.__method_save = preferences.method_save
self.__song_metadata = preferences.song_metadata
self.__not_interface = preferences.not_interface
self.__quality_download = preferences.quality_download or "NORMAL"
@@ -169,7 +170,6 @@ class EASY_DW:
self.__output_dir,
self.__song_quality,
self.__file_format,
self.__method_save,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks
@@ -184,7 +184,6 @@ class EASY_DW:
self.__output_dir,
self.__song_quality,
self.__file_format,
self.__method_save,
is_episode=True,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
@@ -1004,29 +1003,37 @@ class EASY_DW:
self.__write_episode()
# Write metadata tags so subsequent skips work
write_tags(self.__c_episode)
# Save episode cover image if download was successful
if self.__c_episode.success and hasattr(self.__c_episode, 'episode_path') and self.__c_episode.episode_path:
episode_directory = dirname(self.__c_episode.episode_path)
image_url = self.__song_metadata.get('image')
image_bytes = None
if image_url:
try:
image_bytes = request(image_url).content
except Exception as e_img:
logger.warning(f"Failed to fetch cover image for episode {self.__c_episode.tags.get('name', '')}: {e_img}")
if image_bytes:
save_cover_image(image_bytes, episode_directory, "cover.jpg")
return self.__c_episode
def download_cli(preferences: Preferences) -> None:
__link = preferences.link
__output_dir = preferences.output_dir
__method_save = preferences.method_save
__not_interface = preferences.not_interface
__quality_download = preferences.quality_download
__recursive_download = preferences.recursive_download
__recursive_quality = preferences.recursive_quality
cmd = f"deez-dw.py -so spo -l \"{__link}\" "
if __output_dir:
cmd += f"-o {__output_dir} "
if __method_save:
cmd += f"-sa {__method_save} "
if __not_interface:
cmd += f"-g "
if __quality_download:
cmd += f"-q {__quality_download} "
if __recursive_download:
cmd += f"-rd "
if __recursive_quality:
cmd += f"-rq"
system(cmd)
class DW_TRACK:
@@ -1042,11 +1049,6 @@ class DW_TRACK:
# it's an intentional skip, not an error
return track
def dw2(self) -> Track:
track = EASY_DW(self.__preferences).get_no_dw_track()
download_cli(self.__preferences)
return track
class DW_ALBUM:
def __init__(
self,
@@ -1056,7 +1058,6 @@ class DW_ALBUM:
self.__ids = self.__preferences.ids
self.__make_zip = self.__preferences.make_zip
self.__output_dir = self.__preferences.output_dir
self.__method_save = self.__preferences.method_save
self.__song_metadata = self.__preferences.song_metadata
self.__not_interface = self.__preferences.not_interface
self.__song_metadata_items = self.__song_metadata.items()
@@ -1098,11 +1099,12 @@ class DW_ALBUM:
"url": f"https://open.spotify.com/album/{album_id}"
})
pic = self.__song_metadata['image']
image = request(pic).content
self.__song_metadata['image'] = image
pic_url = self.__song_metadata['image'] # This is URL for spotify
image_bytes = request(pic_url).content
self.__song_metadata['image'] = image_bytes # Keep bytes for tagging
album = Album(self.__ids)
album.image = image
album.image = image_bytes # Store raw image bytes for cover saving
album.nb_tracks = self.__song_metadata['nb_tracks']
album.album_name = self.__song_metadata['album']
album.upc = self.__song_metadata['upc']
@@ -1110,6 +1112,14 @@ class DW_ALBUM:
album.md5_image = self.__ids
album.tags = self.__song_metadata
# Determine album base directory once
album_base_directory = get_album_directory(
self.__song_metadata, # Album level metadata
self.__output_dir,
custom_dir_format=self.__preferences.custom_dir_format,
pad_tracks=self.__preferences.pad_tracks
)
c_song_metadata = {}
for key, item in self.__song_metadata_items:
if type(item) is not list:
@@ -1147,6 +1157,11 @@ class DW_ALBUM:
track.error_message = f"An unexpected error occurred: {str(e_generic)}"
logger.error(f"Unexpected error downloading track '{song_name}' by '{artist_name}' from album '{album.album_name}'. Reason: {track.error_message}")
tracks.append(track)
# Save album cover image
if album.image and album_base_directory:
save_cover_image(album.image, album_base_directory, "cover.jpg")
if self.__make_zip:
song_quality = tracks[0].quality
custom_dir_format = getattr(self.__preferences, 'custom_dir_format', None)
@@ -1155,7 +1170,6 @@ class DW_ALBUM:
output_dir=self.__output_dir,
song_metadata=self.__song_metadata,
song_quality=song_quality,
method_save=self.__method_save,
custom_dir_format=custom_dir_format
)
album.zip_path = zip_name
@@ -1185,11 +1199,6 @@ class DW_ALBUM:
return album
def dw2(self) -> Album:
track = EASY_DW(self.__preferences).get_no_dw_track()
download_cli(self.__preferences)
return track
class DW_PLAYLIST:
def __init__(
self,
@@ -1284,86 +1293,6 @@ class DW_PLAYLIST:
return playlist
def dw2(self) -> Playlist:
# Extract playlist metadata for reporting
playlist_name = self.__json_data.get('name', 'Unknown Playlist')
playlist_owner = self.__json_data.get('owner', {}).get('display_name', 'Unknown Owner')
total_tracks = self.__json_data.get('tracks', {}).get('total', 'unknown')
playlist_id = self.__ids
# Report playlist initializing status
Download_JOB.report_progress({
"type": "playlist",
"owner": playlist_owner,
"status": "initializing",
"total_tracks": total_tracks,
"name": playlist_name,
"url": f"https://open.spotify.com/playlist/{playlist_id}"
})
playlist = Playlist()
tracks = playlist.tracks
for i, c_song_metadata in enumerate(self.__song_metadata):
if type(c_song_metadata) is str:
logger.warning(f"Track not found {c_song_metadata}")
continue
c_preferences = deepcopy(self.__preferences)
c_preferences.ids = c_song_metadata['ids']
c_preferences.song_metadata = c_song_metadata
c_preferences.json_data = self.__json_data # Pass playlist data for reporting
c_preferences.track_number = i + 1 # Track number in the playlist
# Even though we're not downloading directly, we still need to set up the track object
track = EASY_DW(c_preferences, parent='playlist').get_no_dw_track()
if not track.success:
song = f"{c_song_metadata['music']} - {c_song_metadata['artist']}"
error_detail = getattr(track, 'error_message', 'Download failed for unspecified reason.')
logger.warning(f"Cannot download '{song}' (CLI mode). Reason: {error_detail} (Link: {track.link or c_preferences.link})")
tracks.append(track)
# Track-level progress reporting using the standardized format
progress_data = {
"type": "track",
"song": c_song_metadata.get("music", ""),
"artist": c_song_metadata.get("artist", ""),
"status": "progress",
"current_track": i + 1,
"total_tracks": total_tracks,
"parent": {
"type": "playlist",
"name": playlist_name,
"owner": self.__json_data.get('owner', {}).get('display_name', 'unknown'),
"total_tracks": total_tracks,
"url": f"https://open.spotify.com/playlist/{self.__json_data.get('id', '')}"
},
"url": f"https://open.spotify.com/track/{c_song_metadata['ids']}"
}
Download_JOB.report_progress(progress_data)
download_cli(self.__preferences)
if self.__make_zip:
playlist_title = self.__json_data['name']
zip_name = f"{self.__output_dir}/{playlist_title} [playlist {self.__ids}]"
create_zip(tracks, zip_name=zip_name)
playlist.zip_path = zip_name
# Report playlist done status
playlist_name = self.__json_data.get('name', 'Unknown Playlist')
playlist_owner = self.__json_data.get('owner', {}).get('display_name', 'Unknown Owner')
total_tracks = self.__json_data.get('tracks', {}).get('total', 0)
playlist_id = self.__ids
Download_JOB.report_progress({
"type": "playlist",
"owner": playlist_owner,
"status": "done",
"total_tracks": total_tracks,
"name": playlist_name,
"url": f"https://open.spotify.com/playlist/{playlist_id}"
})
return playlist
class DW_EPISODE:
def __init__(
self,
@@ -1389,41 +1318,18 @@ class DW_EPISODE:
episode = EASY_DW(self.__preferences).download_eps()
# Using standardized episode progress format
progress_data = {
"type": "episode",
"song": self.__preferences.song_metadata.get('name', 'Unknown Episode'),
"artist": self.__preferences.song_metadata.get('show', 'Unknown Show'),
"status": "done"
}
# Set URL if available
episode_id = self.__preferences.ids
if episode_id:
progress_data["url"] = f"https://open.spotify.com/episode/{episode_id}"
Download_JOB.report_progress(progress_data)
return episode
def dw2(self) -> Episode:
# Using standardized episode progress format
progress_data = {
"type": "episode",
"song": self.__preferences.song_metadata.get('name', 'Unknown Episode'),
"artist": self.__preferences.song_metadata.get('show', 'Unknown Show'),
"status": "initializing"
}
# Set URL if available
episode_id = self.__preferences.ids
if episode_id:
progress_data["url"] = f"https://open.spotify.com/episode/{episode_id}"
Download_JOB.report_progress(progress_data)
episode = EASY_DW(self.__preferences).get_no_dw_track()
download_cli(self.__preferences)
# Save episode cover image if download was successful
if episode.success and hasattr(episode, 'episode_path') and episode.episode_path:
episode_directory = dirname(episode.episode_path)
image_url = self.__preferences.song_metadata.get('image')
image_bytes = None
if image_url:
try:
image_bytes = request(image_url).content
except Exception as e_img:
logger.warning(f"Failed to fetch cover image for episode {episode.tags.get('name', '')}: {e_img}")
if image_bytes:
save_cover_image(image_bytes, episode_directory, "cover.jpg")
# Using standardized episode progress format
progress_data = {

View File

@@ -32,8 +32,7 @@ from deezspot.libutils.others_settings import (
stock_recursive_download,
stock_not_interface,
stock_zip,
method_save,
is_thread,
stock_save_cover,
stock_real_time_dl
)
from deezspot.libutils.logging_utils import logger, ProgressReporter
@@ -90,8 +89,6 @@ class SpoLogin:
recursive_quality=stock_recursive_quality,
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
method_save=method_save,
is_thread=is_thread,
real_time_dl=stock_real_time_dl,
custom_dir_format=None,
custom_track_format=None,
@@ -118,7 +115,6 @@ class SpoLogin:
preferences.recursive_quality = recursive_quality
preferences.recursive_download = recursive_download
preferences.not_interface = not_interface
preferences.method_save = method_save
preferences.is_episode = False
preferences.custom_dir_format = custom_dir_format
preferences.custom_track_format = custom_track_format
@@ -128,10 +124,7 @@ class SpoLogin:
preferences.max_retries = max_retries
preferences.convert_to = convert_to
if not is_thread:
track = DW_TRACK(preferences).dw()
else:
track = DW_TRACK(preferences).dw2()
track = DW_TRACK(preferences).dw()
return track
except Exception as e:
@@ -147,8 +140,6 @@ class SpoLogin:
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
make_zip=stock_zip,
method_save=method_save,
is_thread=is_thread,
real_time_dl=stock_real_time_dl,
custom_dir_format=None,
custom_track_format=None,
@@ -156,7 +147,8 @@ class SpoLogin:
initial_retry_delay=30,
retry_delay_increase=30,
max_retries=5,
convert_to=None
convert_to=None,
save_cover=stock_save_cover
) -> Album:
try:
link_is_valid(link_album)
@@ -178,7 +170,6 @@ class SpoLogin:
preferences.recursive_quality = recursive_quality
preferences.recursive_download = recursive_download
preferences.not_interface = not_interface
preferences.method_save = method_save
preferences.make_zip = make_zip
preferences.is_episode = False
preferences.custom_dir_format = custom_dir_format
@@ -188,11 +179,9 @@ class SpoLogin:
preferences.retry_delay_increase = retry_delay_increase
preferences.max_retries = max_retries
preferences.convert_to = convert_to
preferences.save_cover = save_cover
if not is_thread:
album = DW_ALBUM(preferences).dw()
else:
album = DW_ALBUM(preferences).dw2()
album = DW_ALBUM(preferences).dw()
return album
except Exception as e:
@@ -208,8 +197,6 @@ class SpoLogin:
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
make_zip=stock_zip,
method_save=method_save,
is_thread=is_thread,
real_time_dl=stock_real_time_dl,
custom_dir_format=None,
custom_track_format=None,
@@ -217,7 +204,8 @@ class SpoLogin:
initial_retry_delay=30,
retry_delay_increase=30,
max_retries=5,
convert_to=None
convert_to=None,
save_cover=stock_save_cover
) -> Playlist:
try:
link_is_valid(link_playlist)
@@ -253,7 +241,6 @@ class SpoLogin:
preferences.recursive_quality = recursive_quality
preferences.recursive_download = recursive_download
preferences.not_interface = not_interface
preferences.method_save = method_save
preferences.make_zip = make_zip
preferences.is_episode = False
preferences.custom_dir_format = custom_dir_format
@@ -263,11 +250,9 @@ class SpoLogin:
preferences.retry_delay_increase = retry_delay_increase
preferences.max_retries = max_retries
preferences.convert_to = convert_to
preferences.save_cover = save_cover
if not is_thread:
playlist = DW_PLAYLIST(preferences).dw()
else:
playlist = DW_PLAYLIST(preferences).dw2()
playlist = DW_PLAYLIST(preferences).dw()
return playlist
except Exception as e:
@@ -282,8 +267,6 @@ class SpoLogin:
recursive_quality=stock_recursive_quality,
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
method_save=method_save,
is_thread=is_thread,
real_time_dl=stock_real_time_dl,
custom_dir_format=None,
custom_track_format=None,
@@ -291,7 +274,8 @@ class SpoLogin:
initial_retry_delay=30,
retry_delay_increase=30,
max_retries=5,
convert_to=None
convert_to=None,
save_cover=stock_save_cover
) -> Episode:
try:
link_is_valid(link_episode)
@@ -312,7 +296,6 @@ class SpoLogin:
preferences.recursive_quality = recursive_quality
preferences.recursive_download = recursive_download
preferences.not_interface = not_interface
preferences.method_save = method_save
preferences.is_episode = True
preferences.custom_dir_format = custom_dir_format
preferences.custom_track_format = custom_track_format
@@ -321,11 +304,9 @@ class SpoLogin:
preferences.retry_delay_increase = retry_delay_increase
preferences.max_retries = max_retries
preferences.convert_to = convert_to
preferences.save_cover = save_cover
if not is_thread:
episode = DW_EPISODE(preferences).dw()
else:
episode = DW_EPISODE(preferences).dw2()
episode = DW_EPISODE(preferences).dw()
return episode
except Exception as e:
@@ -343,8 +324,6 @@ class SpoLogin:
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
make_zip=stock_zip,
method_save=method_save,
is_thread=is_thread,
real_time_dl=stock_real_time_dl,
custom_dir_format=None,
custom_track_format=None,
@@ -382,8 +361,6 @@ class SpoLogin:
recursive_download=recursive_download,
not_interface=not_interface,
make_zip=make_zip,
method_save=method_save,
is_thread=is_thread,
real_time_dl=real_time_dl,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
@@ -408,7 +385,6 @@ class SpoLogin:
recursive_download=stock_recursive_download,
not_interface=stock_not_interface,
make_zip=stock_zip,
method_save=method_save,
real_time_dl=stock_real_time_dl,
custom_dir_format=None,
custom_track_format=None,
@@ -416,7 +392,8 @@ class SpoLogin:
initial_retry_delay=30,
retry_delay_increase=30,
max_retries=5,
convert_to=None
convert_to=None,
save_cover=stock_save_cover
) -> Smart:
try:
link_is_valid(link)
@@ -439,7 +416,6 @@ class SpoLogin:
recursive_quality=recursive_quality,
recursive_download=recursive_download,
not_interface=not_interface,
method_save=method_save,
real_time_dl=real_time_dl,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
@@ -462,14 +438,15 @@ class SpoLogin:
recursive_download=recursive_download,
not_interface=not_interface,
make_zip=make_zip,
method_save=method_save,
real_time_dl=real_time_dl,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,
initial_retry_delay=initial_retry_delay,
retry_delay_increase=retry_delay_increase,
max_retries=max_retries
max_retries=max_retries,
convert_to=convert_to,
save_cover=save_cover
)
smart.type = "album"
smart.album = album
@@ -485,14 +462,15 @@ class SpoLogin:
recursive_download=recursive_download,
not_interface=not_interface,
make_zip=make_zip,
method_save=method_save,
real_time_dl=real_time_dl,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,
initial_retry_delay=initial_retry_delay,
retry_delay_increase=retry_delay_increase,
max_retries=max_retries
max_retries=max_retries,
convert_to=convert_to,
save_cover=save_cover
)
smart.type = "playlist"
smart.playlist = playlist
@@ -507,14 +485,15 @@ class SpoLogin:
recursive_quality=recursive_quality,
recursive_download=recursive_download,
not_interface=not_interface,
method_save=method_save,
real_time_dl=real_time_dl,
custom_dir_format=custom_dir_format,
custom_track_format=custom_track_format,
pad_tracks=pad_tracks,
initial_retry_delay=initial_retry_delay,
retry_delay_increase=retry_delay_increase,
max_retries=max_retries
max_retries=max_retries,
convert_to=convert_to,
save_cover=save_cover
)
smart.type = "episode"
smart.episode = episode