Fix collaborative album artist not applied to single downloads (#215)

Single path template was missing _artists_list and _itunes_artist_id
context keys, so the collab mode first-artist extraction in
_apply_path_template had nothing to work with — $albumartist resolved
to the full multi-artist string. Added both keys matching the exact
pattern used by album and playlist modes, including the iTunes
spotify_album.external_urls fallback. Updated settings UI hints to
show $albumartist as available for single and playlist templates.
This commit is contained in:
Broque Thomas 2026-03-30 11:37:05 -07:00
parent f2e24a36df
commit 525a09c840
3 changed files with 30 additions and 2 deletions

View file

@ -15099,6 +15099,22 @@ def _build_final_path_for_track(context, spotify_artist, album_info, file_ext):
else:
clean_track_name = original_search.get('title', 'Unknown Track')
# Get structured artists list for collab artist handling (same as album/playlist modes)
_artists = original_search.get('artists') or track_info.get('artists') or []
# Extract iTunes artist ID for primary artist resolution (only for iTunes source)
_spotify_album = context.get('spotify_album', {})
_itunes_aid = None
_track_source = original_search.get('_source') or track_info.get('_source', '')
_is_itunes = _track_source == 'itunes' or (isinstance(spotify_artist, dict) and str(spotify_artist.get('id', '')).isdigit() and _track_source != 'deezer')
if _is_itunes and isinstance(spotify_artist, dict):
_aid = spotify_artist.get('id', '')
if str(_aid).isdigit():
_itunes_aid = str(_aid)
if not _itunes_aid and _spotify_album:
_ext = _spotify_album.get('external_urls', {})
if isinstance(_ext, dict) and _ext.get('itunes_artist_id'):
_itunes_aid = _ext['itunes_artist_id']
template_context = {
'artist': spotify_artist["name"] if isinstance(spotify_artist, dict) else spotify_artist.name,
'albumartist': spotify_artist["name"] if isinstance(spotify_artist, dict) else spotify_artist.name,
@ -15109,6 +15125,8 @@ def _build_final_path_for_track(context, spotify_artist, album_info, file_ext):
'year': year,
'quality': context.get('_audio_quality', ''),
'albumtype': album_type_display,
'_artists_list': _artists,
'_itunes_artist_id': _itunes_aid,
}
folder_path, filename_base = _get_file_path_from_template(template_context, 'single_path')
@ -19136,6 +19154,15 @@ def get_version_info():
"title": "What's New in SoulSync",
"subtitle": f"Version {SOULSYNC_VERSION} — Latest Changes",
"sections": [
{
"title": "🔧 Fix Collaborative Album Artist Not Applied to Singles (#215)",
"description": "Single path template now respects the First Listed Artist setting",
"features": [
"• Single downloads now include structured artists list for collab artist extraction",
"• $albumartist variable now works in single and playlist path templates",
"• Settings UI updated to show $albumartist as available for single and playlist templates"
]
},
{
"title": "🔧 Fix Enrichment Overwriting Manual Matches (#221)",
"description": "Enriching an entity that was manually matched no longer reverts the status to not_found",

View file

@ -4536,14 +4536,14 @@
<label>Single Path Template:</label>
<input type="text" id="template-single-path"
placeholder="$artist/$artist - $title/$title">
<small class="settings-hint">Variables: $artist, $artistletter, $title, $album, $albumtype, $year, $quality (filename only)</small>
<small class="settings-hint">Variables: $albumartist, $artist, $artistletter, $title, $album, $albumtype, $year, $quality (filename only)</small>
</div>
<div class="form-group">
<label>Playlist Path Template:</label>
<input type="text" id="template-playlist-path"
placeholder="$playlist/$artist - $title">
<small class="settings-hint">Variables: $playlist, $artist, $artistletter, $title, $year, $quality (filename only)</small>
<small class="settings-hint">Variables: $playlist, $albumartist, $artist, $artistletter, $title, $year, $quality (filename only)</small>
</div>
<div class="form-group">

View file

@ -3403,6 +3403,7 @@ function closeHelperSearch() {
const WHATS_NEW = {
'2.1': [
// Newest features first
{ title: 'Fix Collab Artist on Singles', desc: 'Single/playlist path templates now respect First Listed Artist setting — $albumartist available for all template types' },
{ title: 'Fix Enrichment Breaking Manual Matches', desc: 'Enriching a manually matched artist no longer reverts status to not_found — uses stored ID for direct lookup' },
{ title: 'Fix Spotify OAuth Empty Response', desc: 'OAuth callback server now always sends a response in Docker — added health check and proper logging' },
{ title: 'All Services on Dashboard', desc: 'Dashboard shows all enrichment services as live-status chips — click unconfigured ones to jump to Settings. Spotify card no longer shows "Apple Music"', page: 'dashboard' },