add failed scan items to wishlist.
This commit is contained in:
parent
08e3f6c900
commit
b1391b9466
3 changed files with 74 additions and 8 deletions
|
|
@ -22,7 +22,8 @@ class SyncResult:
|
||||||
failed_tracks: int
|
failed_tracks: int
|
||||||
sync_time: datetime
|
sync_time: datetime
|
||||||
errors: List[str]
|
errors: List[str]
|
||||||
|
wishlist_added_count: int = 0
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def success_rate(self) -> float:
|
def success_rate(self) -> float:
|
||||||
if self.total_tracks == 0:
|
if self.total_tracks == 0:
|
||||||
|
|
@ -252,7 +253,53 @@ class PlaylistSyncService:
|
||||||
total_tracks=total_tracks,
|
total_tracks=total_tracks,
|
||||||
matched_tracks=len(matched_tracks),
|
matched_tracks=len(matched_tracks),
|
||||||
failed_tracks=failed_tracks)
|
failed_tracks=failed_tracks)
|
||||||
|
|
||||||
|
# Auto-add unmatched tracks to wishlist
|
||||||
|
wishlist_added_count = 0
|
||||||
|
if unmatched_tracks:
|
||||||
|
try:
|
||||||
|
from core.wishlist_service import get_wishlist_service
|
||||||
|
wishlist_service = get_wishlist_service()
|
||||||
|
|
||||||
|
logger.info(f"Auto-adding {len(unmatched_tracks)} unmatched tracks to wishlist")
|
||||||
|
|
||||||
|
for match_result in unmatched_tracks:
|
||||||
|
spotify_track = match_result.spotify_track
|
||||||
|
|
||||||
|
# Convert SpotifyTrack to dict format expected by wishlist service
|
||||||
|
spotify_track_data = {
|
||||||
|
'id': spotify_track.id,
|
||||||
|
'name': spotify_track.name,
|
||||||
|
'artists': [{'name': a} if isinstance(a, str) else a for a in spotify_track.artists],
|
||||||
|
'album': {'name': spotify_track.album},
|
||||||
|
'duration_ms': spotify_track.duration_ms,
|
||||||
|
'popularity': getattr(spotify_track, 'popularity', 0),
|
||||||
|
'preview_url': getattr(spotify_track, 'preview_url', None),
|
||||||
|
'external_urls': getattr(spotify_track, 'external_urls', {})
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add to wishlist with source context
|
||||||
|
success = wishlist_service.add_spotify_track_to_wishlist(
|
||||||
|
spotify_track_data=spotify_track_data,
|
||||||
|
failure_reason='Missing from media server after sync',
|
||||||
|
source_type='playlist',
|
||||||
|
source_context={
|
||||||
|
'playlist_name': playlist.name,
|
||||||
|
'playlist_id': playlist.id,
|
||||||
|
'sync_type': 'automatic_sync',
|
||||||
|
'timestamp': datetime.now().isoformat()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
wishlist_added_count += 1
|
||||||
|
|
||||||
|
logger.info(f"Successfully added {wishlist_added_count}/{len(unmatched_tracks)} tracks to wishlist")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"Failed to auto-add tracks to wishlist: {e}")
|
||||||
|
# Don't fail the sync if wishlist add fails
|
||||||
|
|
||||||
result = SyncResult(
|
result = SyncResult(
|
||||||
playlist_name=playlist.name,
|
playlist_name=playlist.name,
|
||||||
total_tracks=len(playlist.tracks),
|
total_tracks=len(playlist.tracks),
|
||||||
|
|
@ -261,9 +308,10 @@ class PlaylistSyncService:
|
||||||
downloaded_tracks=downloaded_tracks,
|
downloaded_tracks=downloaded_tracks,
|
||||||
failed_tracks=failed_tracks,
|
failed_tracks=failed_tracks,
|
||||||
sync_time=datetime.now(),
|
sync_time=datetime.now(),
|
||||||
errors=errors
|
errors=errors,
|
||||||
|
wishlist_added_count=wishlist_added_count
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.info(f"Sync completed: {result.success_rate:.1f}% success rate")
|
logger.info(f"Sync completed: {result.success_rate:.1f}% success rate")
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
@ -437,7 +485,8 @@ class PlaylistSyncService:
|
||||||
downloaded_tracks=0,
|
downloaded_tracks=0,
|
||||||
failed_tracks=0,
|
failed_tracks=0,
|
||||||
sync_time=datetime.now(),
|
sync_time=datetime.now(),
|
||||||
errors=errors
|
errors=errors,
|
||||||
|
wishlist_added_count=0
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_sync_preview(self, playlist_name: str) -> Dict[str, Any]:
|
def get_sync_preview(self, playlist_name: str) -> Dict[str, Any]:
|
||||||
|
|
|
||||||
|
|
@ -3750,10 +3750,18 @@ class SyncPage(QWidget):
|
||||||
|
|
||||||
# Show toast notification for sync completion
|
# Show toast notification for sync completion
|
||||||
if hasattr(self, 'toast_manager') and self.toast_manager:
|
if hasattr(self, 'toast_manager') and self.toast_manager:
|
||||||
|
wishlist_count = getattr(result, 'wishlist_added_count', 0)
|
||||||
|
|
||||||
if result.failed_tracks > 0:
|
if result.failed_tracks > 0:
|
||||||
self.toast_manager.show_toast(f"Sync completed: {result.matched_tracks}/{result.total_tracks} tracks added, {result.failed_tracks} failed", ToastType.WARNING)
|
msg = f"Sync completed: {result.matched_tracks}/{result.total_tracks} tracks added, {result.failed_tracks} failed"
|
||||||
|
if wishlist_count > 0:
|
||||||
|
msg += f". {wishlist_count} track{'s' if wishlist_count > 1 else ''} added to wishlist"
|
||||||
|
self.toast_manager.show_toast(msg, ToastType.WARNING)
|
||||||
else:
|
else:
|
||||||
self.toast_manager.show_toast(f"Sync completed: {result.matched_tracks} tracks added to queue", ToastType.SUCCESS)
|
msg = f"Sync completed: {result.matched_tracks} tracks added to queue"
|
||||||
|
if wishlist_count > 0:
|
||||||
|
msg += f". {wishlist_count} missing track{'s' if wishlist_count > 1 else ''} added to wishlist"
|
||||||
|
self.toast_manager.show_toast(msg, ToastType.SUCCESS)
|
||||||
|
|
||||||
# Continue sequential sync if in progress
|
# Continue sequential sync if in progress
|
||||||
if self.is_sequential_syncing:
|
if self.is_sequential_syncing:
|
||||||
|
|
|
||||||
|
|
@ -6283,7 +6283,16 @@ function updateCardToDefault(playlistId, finalState = null) {
|
||||||
if (finalState.status === 'finished') {
|
if (finalState.status === 'finished') {
|
||||||
statusEl.textContent = `Synced: Just now`;
|
statusEl.textContent = `Synced: Just now`;
|
||||||
statusEl.className = 'playlist-card-status status-synced';
|
statusEl.className = 'playlist-card-status status-synced';
|
||||||
showToast(`Sync complete for "${card.querySelector('.playlist-card-name').textContent}"`, 'success');
|
|
||||||
|
// Check if any tracks were added to wishlist
|
||||||
|
const wishlistCount = finalState.progress?.wishlist_added_count || finalState.result?.wishlist_added_count || 0;
|
||||||
|
const playlistName = card.querySelector('.playlist-card-name').textContent;
|
||||||
|
|
||||||
|
if (wishlistCount > 0) {
|
||||||
|
showToast(`Sync complete for "${playlistName}". Added ${wishlistCount} missing track${wishlistCount > 1 ? 's' : ''} to wishlist.`, 'success');
|
||||||
|
} else {
|
||||||
|
showToast(`Sync complete for "${playlistName}"`, 'success');
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
statusEl.textContent = `Sync Failed`;
|
statusEl.textContent = `Sync Failed`;
|
||||||
statusEl.className = 'playlist-card-status status-needs-sync'; // Or a new error class
|
statusEl.className = 'playlist-card-status status-needs-sync'; // Or a new error class
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue