Fix Unknown Artist fallback during Spotify rate-limiting and update CI to use GHCR
- Add fallback chain in spotify_artist_context construction to use track.artists when explicit_artist_context has placeholder names like 'Unknown Artist' - Add fallback in _extract_spotify_metadata to use original_search['artists'] when album_artist resolution fails due to Spotify rate-limiting - This fixes downloads being saved to 'Unknown Artist' folders when Spotify API is rate-limited but actual artist data is available from download sources - Update GitHub Actions workflow to push Docker images only to GitHub Container Registry (ghcr.io) instead of Docker Hub
This commit is contained in:
parent
37d325ee10
commit
74bdb1c84b
2 changed files with 41 additions and 16 deletions
25
.github/workflows/docker-publish.yml
vendored
25
.github/workflows/docker-publish.yml
vendored
|
|
@ -7,6 +7,10 @@ on:
|
|||
description: 'Version tag (e.g. 1.6, 1.7)'
|
||||
required: true
|
||||
default: '2.2'
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
|
|
@ -22,11 +26,12 @@ jobs:
|
|||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to Docker Hub
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
|
|
@ -39,15 +44,5 @@ jobs:
|
|||
build-args: |
|
||||
COMMIT_SHA=${{ github.sha }}
|
||||
tags: |
|
||||
boulderbadgedad/soulsync:latest
|
||||
boulderbadgedad/soulsync:${{ inputs.version_tag }}
|
||||
|
||||
- name: Announce release to Discord
|
||||
if: success()
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_ANNOUNCEMENTS_WEBHOOK }}
|
||||
run: |
|
||||
if [ -z "$DISCORD_WEBHOOK" ]; then echo "No webhook configured, skipping"; exit 0; fi
|
||||
curl -s -H "Content-Type: application/json" \
|
||||
-d "{\"embeds\": [{\"title\": \"SoulSync v${{ inputs.version_tag }} Released\", \"description\": \"A new version of SoulSync is available! Pull the latest Docker image to update.\n\n\`\`\`\ndocker pull boulderbadgedad/soulsync:${{ inputs.version_tag }}\n\`\`\`\", \"color\": 5025616, \"footer\": {\"text\": \"SoulSync Auto-Release\"}, \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}]}" \
|
||||
"$DISCORD_WEBHOOK"
|
||||
ghcr.io/${{ github.repository_owner }}/soulsync:latest
|
||||
ghcr.io/${{ github.repository_owner }}/soulsync:${{ inputs.version_tag || 'dev' }}
|
||||
|
|
|
|||
|
|
@ -17733,6 +17733,21 @@ def _extract_spotify_metadata(context: dict, artist: dict, album_info: dict) ->
|
|||
_raw_album_artist = _first_aa
|
||||
_album_artists_for_collab = _sa_aa
|
||||
|
||||
# SPOTIFY RATE LIMIT FIX: When Spotify is rate-limited, explicit_artist_context and spotify_album
|
||||
# may have placeholder/incomplete artist data. Use actual track artist data from original_search
|
||||
# which comes from the download source (HiFi, Tidal, etc.) and contains real artist names.
|
||||
if not _raw_album_artist or _raw_album_artist in ['Unknown Artist', 'Unknown', '']:
|
||||
if 'artists' in original_search and isinstance(original_search['artists'], list) and len(original_search['artists']) > 0:
|
||||
first_artist = original_search['artists'][0]
|
||||
if isinstance(first_artist, dict) and first_artist.get('name'):
|
||||
_raw_album_artist = first_artist['name']
|
||||
if not _album_artists_for_collab:
|
||||
_album_artists_for_collab = [first_artist]
|
||||
elif isinstance(first_artist, str):
|
||||
_raw_album_artist = first_artist
|
||||
if not _album_artists_for_collab:
|
||||
_album_artists_for_collab = [{'name': first_artist}]
|
||||
|
||||
collab_mode = config_manager.get('file_organization.collab_artist_mode', 'first')
|
||||
if collab_mode == 'first' and _raw_album_artist:
|
||||
original_search = context.get("original_search_result", {})
|
||||
|
|
@ -27778,9 +27793,24 @@ def _attempt_download_with_candidates(task_id, candidates, track, batch_id=None)
|
|||
if isinstance(explicit_artist, str):
|
||||
explicit_artist = {'name': explicit_artist}
|
||||
|
||||
# Determine artist name with proper fallback chain:
|
||||
# 1. explicit_artist.name (if not a placeholder like 'Unknown Artist')
|
||||
# 2. track.artists[0] (actual track artist data from download source)
|
||||
# 3. 'Unknown Artist' as last resort
|
||||
explicit_artist_name = explicit_artist.get('name', '')
|
||||
is_placeholder_name = explicit_artist_name in ['Unknown Artist', 'Unknown', '', 'Various Artists']
|
||||
|
||||
if is_placeholder_name and track.artists:
|
||||
# Use actual track artist data instead of placeholder from rate-limited context
|
||||
spotify_artist_name = track.artists[0]
|
||||
elif explicit_artist_name:
|
||||
spotify_artist_name = explicit_artist_name
|
||||
else:
|
||||
spotify_artist_name = track.artists[0] if track.artists else 'Unknown Artist'
|
||||
|
||||
spotify_artist_context = {
|
||||
'id': explicit_artist.get('id', 'explicit_artist'),
|
||||
'name': explicit_artist.get('name', track.artists[0] if track.artists else 'Unknown'),
|
||||
'name': spotify_artist_name,
|
||||
'genres': explicit_artist.get('genres', [])
|
||||
}
|
||||
# Handle both image_url formats (direct string or images array)
|
||||
|
|
|
|||
Loading…
Reference in a new issue