#!/usr/bin/env python3 """ Test the unified metadata client that combines all music services """ import json import logging import sys import os # Add the src directory to the path sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src')) logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) def test_unified_client(): """Test the unified metadata client""" logger.info("šŸ” Testing Unified Metadata Client...") try: from swingmusic.services.unified_metadata_client import get_unified_metadata_client # Initialize without Last.fm (optional service) client = get_unified_metadata_client(enable_lastfm=False) # Test enriched track data logger.info("Testing enriched track data...") track_data = client.get_track_with_enrichment("4iV5W9uYEdYUVa79Axb7Rh") if track_data: logger.info("āœ… Enriched track data retrieved!") logger.info(f"Track: {track_data.get('name', 'Unknown')}") logger.info(f"Duration: {track_data.get('duration_ms', 0)/1000:.1f}s") logger.info(f"Spotify Play Count: {track_data.get('play_count', 0):,}") logger.info(f"Spotify Popularity: {track_data.get('popularity', 0)}/100") logger.info(f"Genres: {track_data.get('genres', [])}") logger.info(f"ISRC: {track_data.get('isrc', 'N/A')}") logger.info(f"Cover Art: {'Available' if track_data.get('cover_art') else 'Not available'}") # Check streaming URLs streaming_urls = track_data.get('streaming_urls', {}) if streaming_urls: available_platforms = [k for k, v in streaming_urls.items() if v] logger.info(f"Streaming platforms: {', '.join(available_platforms)}") # Check Last.fm (should be None since disabled) lastfm_stats = track_data.get('lastfm_stats') if lastfm_stats: logger.info(f"Last.fm play count: {lastfm_stats.get('playcount', 0):,}") else: logger.info("āœ… Last.fm correctly disabled") return True else: logger.error("āŒ Failed to get enriched track data") return False except Exception as e: logger.error(f"āŒ Test failed: {e}") import traceback traceback.print_exc() return False def test_spotify_vs_lastfm_counts(): """Demonstrate Spotify play counts vs Last.fm approach""" logger.info("šŸ” Testing Spotify vs Last.fm play counts...") try: from swingmusic.services.spotify_web_player_client import get_spotify_web_player_client spotify_client = get_spotify_web_player_client() # Get track with Spotify play count track = spotify_client.get_track("4iV5W9uYEdYUVa79Axb7Rh") if track: spotify_count = getattr(track, 'playcount', 0) spotify_popularity = getattr(track, 'popularity', 0) logger.info("šŸ“Š Play Count Comparison:") logger.info(f" Spotify Play Count: {spotify_count:,}") logger.info(f" Spotify Popularity: {spotify_popularity}/100") logger.info(f" Last.fm: DISABLED (optional)") logger.info("\nšŸ’” Recommendation:") logger.info(" āœ… Use Spotify play counts (real-time, accurate)") logger.info(" āœ… Use local tracking for personal play counts") logger.info(" āš ļø Keep Last.fm optional (social features only)") return True else: logger.error("āŒ Failed to get Spotify track data") return False except Exception as e: logger.error(f"āŒ Test failed: {e}") return False def test_service_architecture(): """Test the service architecture and dependencies""" logger.info("šŸ” Testing service architecture...") services = { "Spotify Web Player API": "Core metadata - names, artists, albums, play counts", "MusicBrainz": "Genre enrichment, ISRC codes, cover art", "Song.link": "Cross-platform streaming URLs", "Last.fm": "Optional: social features, scrobbling", } logger.info("šŸ—ļø Music Services Architecture:") for service, purpose in services.items(): required = "āœ… Required" if service != "Last.fm" else "āš ļø Optional" logger.info(f" {required} {service}: {purpose}") logger.info("\nšŸ“‹ Data Flow:") logger.info(" 1. Spotify → Core metadata (track names, play counts)") logger.info(" 2. MusicBrainz → Genre enrichment via ISRC") logger.info(" 3. Song.link → Cross-platform URLs") logger.info(" 4. Last.fm → Optional social features") logger.info("\nšŸŽÆ Listening Count Strategy:") logger.info(" Primary: Spotify play counts (real-time, global)") logger.info(" Backup: Local database (personal plays)") logger.info(" Optional: Last.fm (if user enables)") return True def main(): """Run unified client tests""" print("=" * 80) print("šŸŽµ UNIFIED METADATA CLIENT TEST") print("=" * 80) print("Testing the new unified approach to music metadata") print("āœ… Spotify: Core metadata + play counts") print("āœ… MusicBrainz: Genre enrichment") print("āœ… Song.link: Cross-platform URLs") print("āš ļø Last.fm: Optional social features") print("=" * 80) tests = [ ("Service Architecture", test_service_architecture), ("Spotify vs Last.fm Counts", test_spotify_vs_lastfm_counts), ("Unified Client", test_unified_client), ] results = {} for test_name, test_func in tests: print(f"\n{test_name}") print("-" * 50) try: results[test_name] = test_func() except Exception as e: logger.error(f"Test {test_name} failed: {e}") results[test_name] = False # Summary print("\n" + "=" * 80) print("šŸŽ‰ UNIFIED CLIENT TEST RESULTS") print("=" * 80) for test_name, success in results.items(): status = "āœ… PASS" if success else "āŒ FAIL" print(f"{test_name:.<30} {status}") total_tests = len(results) passed_tests = sum(results.values()) print(f"\nšŸ“Š Overall: {passed_tests}/{total_tests} tests passed") if passed_tests == total_tests: print("\nšŸŽ‰ SUCCESS! Unified metadata client working perfectly!") print("āœ… Spotify provides real play counts - no Last.fm needed!") print("āœ… MusicBrainz enriches with genres and cover art!") print("āœ… Song.link provides cross-platform streaming!") print("āœ… Last.fm is optional for social features only!") print("\nšŸš€ Ready for production with optimized architecture!") else: print("\nāš ļø Some issues remain but core functionality works.") print("=" * 80) if __name__ == "__main__": main()