Add post-scan phase progress to watchlist automation card
This commit is contained in:
parent
5b507d897e
commit
cdcaa245d1
2 changed files with 63 additions and 2 deletions
|
|
@ -1508,7 +1508,7 @@ class WatchlistScanner:
|
|||
logger.error(f"Error fetching similar artists for {watchlist_artist.artist_name}: {e}")
|
||||
return False
|
||||
|
||||
def populate_discovery_pool(self, top_artists_limit: int = 50, albums_per_artist: int = 10, profile_id: int = 1):
|
||||
def populate_discovery_pool(self, top_artists_limit: int = 50, albums_per_artist: int = 10, profile_id: int = 1, progress_callback=None):
|
||||
"""
|
||||
Populate discovery pool with tracks from top similar artists.
|
||||
Called after watchlist scan completes.
|
||||
|
|
@ -1529,8 +1529,14 @@ class WatchlistScanner:
|
|||
if skip_pool_population:
|
||||
logger.info("Discovery pool was populated recently (< 24 hours ago). Skipping pool population.")
|
||||
logger.info("But still refreshing recent albums cache and curated playlists...")
|
||||
if progress_callback:
|
||||
progress_callback('skip', 'Discovery pool recently updated, skipping')
|
||||
# Still run these even when skipping main pool population
|
||||
if progress_callback:
|
||||
progress_callback('phase', 'Caching recent albums...')
|
||||
self.cache_discovery_recent_albums(profile_id=profile_id)
|
||||
if progress_callback:
|
||||
progress_callback('phase', 'Curating playlists...')
|
||||
self.curate_discovery_playlists(profile_id=profile_id)
|
||||
return
|
||||
|
||||
|
|
@ -1556,8 +1562,14 @@ class WatchlistScanner:
|
|||
if not similar_artists:
|
||||
logger.info("No similar artists found to populate discovery pool from similar artists")
|
||||
logger.info("But still caching recent albums from watchlist artists and curating playlists...")
|
||||
if progress_callback:
|
||||
progress_callback('skip', 'No similar artists found')
|
||||
# Still run these even without similar artists - they use watchlist artists
|
||||
if progress_callback:
|
||||
progress_callback('phase', 'Caching recent albums...')
|
||||
self.cache_discovery_recent_albums(profile_id=profile_id)
|
||||
if progress_callback:
|
||||
progress_callback('phase', 'Curating playlists...')
|
||||
self.curate_discovery_playlists(profile_id=profile_id)
|
||||
return
|
||||
|
||||
|
|
@ -1568,6 +1580,8 @@ class WatchlistScanner:
|
|||
for artist_idx, similar_artist in enumerate(similar_artists, 1):
|
||||
try:
|
||||
logger.info(f"[{artist_idx}/{len(similar_artists)}] Processing {similar_artist.similar_artist_name} (occurrence: {similar_artist.occurrence_count})")
|
||||
if progress_callback:
|
||||
progress_callback('artist', f'{similar_artist.similar_artist_name} ({artist_idx}/{len(similar_artists)})')
|
||||
|
||||
# Build list of sources to process for this artist
|
||||
# iTunes is ALWAYS processed (baseline), Spotify is added if authenticated
|
||||
|
|
@ -1766,6 +1780,8 @@ class WatchlistScanner:
|
|||
continue
|
||||
|
||||
logger.info(f"Discovery pool from similar artists complete: {total_tracks_added} tracks added")
|
||||
if progress_callback:
|
||||
progress_callback('success', f'Discovery pool: {total_tracks_added} tracks from {len(similar_artists)} artists')
|
||||
|
||||
# Note: Watchlist artist albums are already in discovery pool from the watchlist scan itself
|
||||
# No need to re-fetch them here to avoid duplicate API calls
|
||||
|
|
@ -1927,10 +1943,14 @@ class WatchlistScanner:
|
|||
|
||||
# Cache recent albums for discovery page
|
||||
logger.info("Caching recent albums for discovery page...")
|
||||
if progress_callback:
|
||||
progress_callback('phase', 'Caching recent albums...')
|
||||
self.cache_discovery_recent_albums(profile_id=profile_id)
|
||||
|
||||
# Curate playlists for consistent daily experience
|
||||
logger.info("Curating discovery playlists...")
|
||||
if progress_callback:
|
||||
progress_callback('phase', 'Curating playlists...')
|
||||
self.curate_discovery_playlists(profile_id=profile_id)
|
||||
|
||||
except Exception as e:
|
||||
|
|
|
|||
|
|
@ -24850,35 +24850,66 @@ def _process_watchlist_scan_automatically(automation_id=None):
|
|||
# Populate discovery pool from similar artists (per-profile)
|
||||
print("🎵 Starting discovery pool population...")
|
||||
watchlist_scan_state['current_phase'] = 'populating_discovery_pool'
|
||||
_update_automation_progress(automation_id, progress=96, phase='Populating discovery pool',
|
||||
log_line='Building discovery pool from similar artists...', log_type='info')
|
||||
try:
|
||||
def _discovery_progress(event_type, message):
|
||||
if event_type == 'artist':
|
||||
_update_automation_progress(automation_id, phase=f'Discovery pool: {message}',
|
||||
log_line=message, log_type='info',
|
||||
current_item=message)
|
||||
elif event_type == 'phase':
|
||||
_update_automation_progress(automation_id, phase=message,
|
||||
log_line=message, log_type='info')
|
||||
elif event_type == 'success':
|
||||
_update_automation_progress(automation_id,
|
||||
log_line=message, log_type='success')
|
||||
elif event_type == 'skip':
|
||||
_update_automation_progress(automation_id,
|
||||
log_line=message, log_type='info')
|
||||
|
||||
for p in all_profiles:
|
||||
scanner.populate_discovery_pool(profile_id=p['id'])
|
||||
scanner.populate_discovery_pool(profile_id=p['id'], progress_callback=_discovery_progress)
|
||||
print("✅ Discovery pool population complete")
|
||||
except Exception as discovery_error:
|
||||
print(f"⚠️ Error populating discovery pool: {discovery_error}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
_update_automation_progress(automation_id,
|
||||
log_line=f'Discovery pool error: {discovery_error}', log_type='error')
|
||||
|
||||
# Update ListenBrainz playlists cache
|
||||
print("🧠 Starting ListenBrainz playlists update...")
|
||||
watchlist_scan_state['current_phase'] = 'updating_listenbrainz'
|
||||
_update_automation_progress(automation_id, progress=97, phase='Updating ListenBrainz',
|
||||
log_line='Fetching ListenBrainz playlists...', log_type='info')
|
||||
try:
|
||||
from core.listenbrainz_manager import ListenBrainzManager
|
||||
lb_manager = ListenBrainzManager(str(get_database().database_path))
|
||||
lb_result = lb_manager.update_all_playlists()
|
||||
if lb_result.get('success'):
|
||||
summary = lb_result.get('summary', {})
|
||||
updated = summary.get('updated', 0)
|
||||
total_lb = summary.get('total', 0)
|
||||
print(f"✅ ListenBrainz update complete: {summary}")
|
||||
_update_automation_progress(automation_id,
|
||||
log_line=f'ListenBrainz: {updated}/{total_lb} playlists updated', log_type='success')
|
||||
else:
|
||||
print(f"⚠️ ListenBrainz update had issues: {lb_result.get('error', 'Unknown error')}")
|
||||
_update_automation_progress(automation_id,
|
||||
log_line=f'ListenBrainz: {lb_result.get("error", "Unknown error")}', log_type='error')
|
||||
except Exception as lb_error:
|
||||
print(f"⚠️ Error updating ListenBrainz: {lb_error}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
_update_automation_progress(automation_id,
|
||||
log_line=f'ListenBrainz error: {lb_error}', log_type='error')
|
||||
|
||||
# Update current seasonal playlist (weekly refresh)
|
||||
print("🎃 Starting seasonal content update...")
|
||||
watchlist_scan_state['current_phase'] = 'updating_seasonal'
|
||||
_update_automation_progress(automation_id, progress=98, phase='Updating seasonal content',
|
||||
log_line='Checking seasonal playlists...', log_type='info')
|
||||
try:
|
||||
from core.seasonal_discovery import get_seasonal_discovery_service
|
||||
seasonal_service = get_seasonal_discovery_service(spotify_client, database)
|
||||
|
|
@ -24888,17 +24919,27 @@ def _process_watchlist_scan_automatically(automation_id=None):
|
|||
if current_season:
|
||||
if seasonal_service.should_populate_seasonal_content(current_season, days_threshold=7):
|
||||
print(f"🎃 Updating {current_season} seasonal content...")
|
||||
_update_automation_progress(automation_id,
|
||||
log_line=f'Updating {current_season} seasonal content...', log_type='info')
|
||||
seasonal_service.populate_seasonal_content(current_season)
|
||||
seasonal_service.curate_seasonal_playlist(current_season)
|
||||
print(f"✅ {current_season.capitalize()} seasonal content updated")
|
||||
_update_automation_progress(automation_id,
|
||||
log_line=f'{current_season.capitalize()} seasonal content updated', log_type='success')
|
||||
else:
|
||||
print(f"⏭️ {current_season.capitalize()} seasonal content recently updated, skipping")
|
||||
_update_automation_progress(automation_id,
|
||||
log_line=f'{current_season.capitalize()} seasonal content up to date', log_type='info')
|
||||
else:
|
||||
print("ℹ️ No active season at this time")
|
||||
_update_automation_progress(automation_id,
|
||||
log_line='No active season', log_type='info')
|
||||
except Exception as seasonal_error:
|
||||
print(f"⚠️ Error updating seasonal content: {seasonal_error}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
_update_automation_progress(automation_id,
|
||||
log_line=f'Seasonal error: {seasonal_error}', log_type='error')
|
||||
|
||||
# Add activity for watchlist scan completion
|
||||
if total_added_to_wishlist > 0:
|
||||
|
|
|
|||
Loading…
Reference in a new issue