Fix Last.fm radios mirrored under wrong source
Two-part fix for Last.fm Radio playlists showing up in the ListenBrainz group of the Auto-Sync manager + Mirrored tab instead of their own Last.fm group: 1. **Mirror-creation hook** (sync-services.js): the ``_mirrorListenBrainzAfterDiscovery`` helper hardcoded ``source='listenbrainz'`` on every auto-mirror call, even for Last.fm Radio playlists (which share the same MB-track shape + discovery worker but should land under ``source='lastfm'``). ``save_lastfm_radio_playlist`` always prefixes the playlist name with "Last.fm Radio: <seed>", so the helper now keys on that prefix to pick the right mirror source + owner fallback. Going forward, new Last.fm radios mirror correctly the moment discovery completes. 2. **Backfill** (listenbrainz_manager.py): legacy mirror rows created before the fix above are stuck under ``source='listenbrainz'``. Added ``_retag_misrouted_lastfm_radio_mirrors`` to ``_cleanup_old_playlists`` so the next LB refresh re-tags any row whose name starts with "Last.fm Radio:" but is still on ``source='listenbrainz'``. Idempotent — UPDATE only matches misrouted rows.
This commit is contained in:
parent
bbc950d325
commit
e8ee8576a0
2 changed files with 45 additions and 4 deletions
|
|
@ -326,11 +326,43 @@ class ListenBrainzManager:
|
|||
covers_found = sum(1 for t in track_data_list if t.get('album_cover_url'))
|
||||
logger.info(f"Fetched {covers_found}/{len(track_data_list)} cover art URLs")
|
||||
|
||||
def _retag_misrouted_lastfm_radio_mirrors(self, cursor):
|
||||
"""Re-tag mirrored_playlists rows that should be 'lastfm' but
|
||||
were inserted as 'listenbrainz'.
|
||||
|
||||
Backfill for the Phase 1c.1 bug where the auto-mirror helper
|
||||
hardcoded ``source='listenbrainz'`` regardless of playlist
|
||||
origin. Last.fm Radio playlists carry a consistent
|
||||
"Last.fm Radio: <seed>" title prefix from
|
||||
``save_lastfm_radio_playlist``, so any mirror row matching
|
||||
that prefix should sit under the Last.fm group instead of
|
||||
the ListenBrainz one. Idempotent — only updates rows that
|
||||
are still misrouted."""
|
||||
try:
|
||||
cursor.execute(
|
||||
"""
|
||||
UPDATE mirrored_playlists
|
||||
SET source = 'lastfm'
|
||||
WHERE source = 'listenbrainz'
|
||||
AND name LIKE 'Last.fm Radio:%'
|
||||
"""
|
||||
)
|
||||
if cursor.rowcount:
|
||||
logger.info(
|
||||
f"Re-tagged {cursor.rowcount} Last.fm Radio mirror rows "
|
||||
"from source='listenbrainz' to source='lastfm'"
|
||||
)
|
||||
except Exception as exc:
|
||||
logger.debug(f"Last.fm radio mirror retag skipped: {exc}")
|
||||
|
||||
def _cleanup_old_playlists(self):
|
||||
"""Remove old playlists, keeping only the 25 most recent per type"""
|
||||
conn = self._get_db_connection()
|
||||
cursor = conn.cursor()
|
||||
|
||||
# One-shot backfill for legacy misrouting (see method docstring).
|
||||
self._retag_misrouted_lastfm_radio_mirrors(cursor)
|
||||
|
||||
# For each playlist type, keep only the N most recent
|
||||
# lastfm_radio keeps fewer since they're auto-regenerated weekly
|
||||
playlist_type_limits = {
|
||||
|
|
|
|||
|
|
@ -10855,18 +10855,27 @@ function _mirrorListenBrainzAfterDiscovery(playlistMbid) {
|
|||
return;
|
||||
}
|
||||
|
||||
// Last.fm Radio playlists live in the same listenbrainz_playlists
|
||||
// table but are persisted by ``save_lastfm_radio_playlist`` with
|
||||
// a "Last.fm Radio: <seed>" title prefix and ``playlist_type='lastfm_radio'``.
|
||||
// Route them to ``source='lastfm'`` so the Auto-Sync manager
|
||||
// groups them under the Last.fm Radio section + the cascade-
|
||||
// delete hook targets the right mirror source.
|
||||
const title = state.playlist.name || 'ListenBrainz Playlist';
|
||||
const mirrorSource = title.startsWith('Last.fm Radio:') ? 'lastfm' : 'listenbrainz';
|
||||
const ownerFallback = mirrorSource === 'lastfm' ? 'Last.fm' : 'ListenBrainz';
|
||||
mirrorPlaylist(
|
||||
'listenbrainz',
|
||||
mirrorSource,
|
||||
playlistMbid,
|
||||
state.playlist.name || 'ListenBrainz Playlist',
|
||||
title,
|
||||
tracks,
|
||||
{
|
||||
owner: state.playlist.creator || 'ListenBrainz',
|
||||
owner: state.playlist.creator || ownerFallback,
|
||||
description: state.playlist.description || '',
|
||||
image_url: state.playlist.image_url || '',
|
||||
}
|
||||
);
|
||||
console.log(`🪞 [LB Mirror] Mirrored '${state.playlist.name}' with ${tracks.length} matched tracks`);
|
||||
console.log(`🪞 [${mirrorSource} Mirror] Mirrored '${title}' with ${tracks.length} matched tracks`);
|
||||
} catch (err) {
|
||||
console.warn('LB mirror-after-discovery failed:', err);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue