diff --git a/deezspot/deezloader/__dee_api__.py b/deezspot/deezloader/__dee_api__.py index 1212bab..4a741ee 100644 --- a/deezspot/deezloader/__dee_api__.py +++ b/deezspot/deezloader/__dee_api__.py @@ -1,6 +1,6 @@ #!/usr/bin/python3 -from typing import Optional, List, Dict, Any, Union +from typing import Optional, List, Dict, Any from deezspot.models.callback.common import IDs from deezspot.models.callback.track import ( @@ -23,6 +23,7 @@ from deezspot.models.callback.playlist import ( artistAlbumTrackPlaylistObject, ) from deezspot.models.callback.user import userObject +from deezspot.libutils.logging_utils import logger def _parse_release_date(date_str: Optional[str]) -> Dict[str, Any]: if not date_str: @@ -234,7 +235,15 @@ def tracking_album(album_json: dict) -> Optional[albumObject]: ) album_tracks.append(track) + # Calculate total discs by finding the maximum disc number + total_discs = 1 + if album_tracks: + disc_numbers = [track.disc_number for track in album_tracks if hasattr(track, 'disc_number') and track.disc_number] + total_discs = max(disc_numbers, default=1) + + # Update album object with tracks and total discs album_obj.tracks = album_tracks + album_obj.total_discs = total_discs return album_obj @@ -378,6 +387,21 @@ def create_standardized_track(track_json: dict) -> trackObject: name=track_json["album"]["artist"].get('name', ''), ids=IDs(deezer=track_json["album"]["artist"].get('id')) )) + + # Try to get full album information for accurate total_discs + total_discs = 1 + album_id = track_json["album"].get('id') + if album_id: + try: + # Import here to avoid circular imports + from deezspot.deezloader.dee_api import API + full_album_obj = API.get_album(album_id) + if full_album_obj and hasattr(full_album_obj, 'total_discs'): + total_discs = full_album_obj.total_discs + except Exception as e: + # If album fetching fails, fall back to default + logger.debug(f"Could not fetch full album data for total_discs calculation: {e}") + total_discs = 1 album_data = albumTrackObject( album_type=track_json["album"].get('record_type', ''), @@ -387,6 +411,7 @@ def create_standardized_track(track_json: dict) -> trackObject: release_date=_parse_release_date(track_json["album"].get('release_date')), artists=album_artists, total_tracks=track_json["album"].get('nb_tracks', 0), + total_discs=total_discs, # Set the calculated or fetched total discs genres=[g['name'] for g in track_json["album"].get('genres', {}).get('data', [])] ) diff --git a/deezspot/libutils/metadata_converter.py b/deezspot/libutils/metadata_converter.py index 5a2ebaf..21a691f 100644 --- a/deezspot/libutils/metadata_converter.py +++ b/deezspot/libutils/metadata_converter.py @@ -163,8 +163,11 @@ def track_object_to_dict(track_obj: Any, source_type: Optional[str] = None) -> D tags['nb_tracks'] = getattr(album, 'total_tracks', 0) - # Calculate total discs from all tracks in album for proper metadata - if hasattr(album, 'tracks') and album.tracks: + # Use the album's total_discs field if available, otherwise calculate from tracks + if hasattr(album, 'total_discs') and album.total_discs: + tags['nb_discs'] = album.total_discs + elif hasattr(album, 'tracks') and album.tracks: + # Fallback: Calculate total discs from all tracks in album for proper metadata disc_numbers = [getattr(track, 'disc_number', 1) for track in album.tracks if hasattr(track, 'disc_number')] tags['nb_discs'] = max(disc_numbers, default=1) else: diff --git a/deezspot/models/callback/album.py b/deezspot/models/callback/album.py index 5ae4d31..5fbc11b 100644 --- a/deezspot/models/callback/album.py +++ b/deezspot/models/callback/album.py @@ -43,6 +43,7 @@ class albumObject: title: str = "" release_date: Dict[str, Any] = field(default_factory=dict) total_tracks: int = 0 + total_discs: int = 1 # New field for multi-disc album support genres: List[str] = field(default_factory=list) images: List[Dict[str, Any]] = field(default_factory=list) copyrights: List[Dict[str, str]] = field(default_factory=list) diff --git a/deezspot/models/callback/playlist.py b/deezspot/models/callback/playlist.py index 523f6a8..5256270 100644 --- a/deezspot/models/callback/playlist.py +++ b/deezspot/models/callback/playlist.py @@ -21,6 +21,7 @@ class albumTrackPlaylistObject: title: str = "" release_date: Dict[str, Any] = field(default_factory=dict) # ReleaseDate as dict total_tracks: int = 0 + total_discs: int = 1 # New field for multi-disc album support images: List[Dict[str, Any]] = field(default_factory=list) ids: IDs = field(default_factory=IDs) artists: List[artistAlbumTrackPlaylistObject] = field(default_factory=list) diff --git a/deezspot/models/callback/track.py b/deezspot/models/callback/track.py index 7a40cf3..16bcdce 100644 --- a/deezspot/models/callback/track.py +++ b/deezspot/models/callback/track.py @@ -31,6 +31,7 @@ class albumTrackObject: title: str = "" release_date: Dict[str, Any] = field(default_factory=dict) # ReleaseDate as dict total_tracks: int = 0 + total_discs: int = 1 # New field for multi-disc album support genres: List[str] = field(default_factory=list) images: List[Dict[str, Any]] = field(default_factory=list) ids: IDs = field(default_factory=IDs) diff --git a/deezspot/spotloader/__spo_api__.py b/deezspot/spotloader/__spo_api__.py index 0bfa86c..6370119 100644 --- a/deezspot/spotloader/__spo_api__.py +++ b/deezspot/spotloader/__spo_api__.py @@ -87,17 +87,28 @@ def tracking(ids, album_data_for_track=None, market: list[str] | None = None) -> _check_market_availability(track_name_for_check, "Track", api_track_markets, market) album_to_process = None + full_album_obj = None + if album_data_for_track: album_to_process = album_data_for_track elif json_track.get('album'): album_id = json_track.get('album', {}).get('id') if album_id: - album_to_process = Spo.get_album(album_id) + # Try to get full album data with all tracks for proper disc counting + full_album_data = Spo.get_album(album_id) + if full_album_data: + album_to_process = full_album_data + # Also create a full album object to get total_discs + full_album_obj = tracking_album(full_album_data, market) if not album_to_process: album_to_process = json_track.get('album') album_for_track = _json_to_album_track_object(album_to_process) if album_to_process else albumTrackObject() + # If we have a full album object with total_discs, use that information + if full_album_obj and hasattr(full_album_obj, 'total_discs'): + album_for_track.total_discs = full_album_obj.total_discs + track_obj = trackObject( title=json_track.get('name', ''), disc_number=json_track.get('disc_number', 1), @@ -170,11 +181,18 @@ def tracking_album(album_json, market: list[str] | None = None) -> Optional[albu # Simplified track object from album endpoint is enough for trackAlbumObject album_tracks.append(_json_to_track_album_object(track_item)) + # Calculate total discs by finding the maximum disc number + total_discs = 1 + if album_tracks: + disc_numbers = [track.disc_number for track in album_tracks if hasattr(track, 'disc_number') and track.disc_number] + total_discs = max(disc_numbers, default=1) + album_obj = albumObject( album_type=album_json.get('album_type'), title=album_json.get('name'), release_date=_parse_release_date(album_json.get('release_date'), album_json.get('release_date_precision')), total_tracks=album_json.get('total_tracks'), + total_discs=total_discs, # Set the calculated total discs genres=album_json.get('genres', []), images=album_json.get('images', []), copyrights=album_json.get('copyrights', []),