#!/usr/bin/env python3 """ DragonflyDB Setup Script for SwingMusic This script helps set up DragonflyDB for fast Spotify metadata caching. DragonflyDB is a Redis-compatible in-memory database perfect for caching. """ import subprocess import sys import time import logging from pathlib import Path logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) def check_dragonflydb_installed(): """Check if DragonflyDB is installed""" try: result = subprocess.run(['dragonfly', '--version'], capture_output=True, text=True, timeout=5) if result.returncode == 0: logger.info(f"āœ… DragonflyDB found: {result.stdout.strip()}") return True except (subprocess.TimeoutExpired, FileNotFoundError): pass logger.warning("āŒ DragonflyDB not found") return False def install_dragonflydb(): """Install DragonflyDB using Docker (recommended)""" logger.info("🐳 Installing DragonflyDB via Docker...") docker_commands = [ # Pull DragonflyDB image ['docker', 'pull', 'docker.dragonflydb.io/dragonflydb/dragonfly'], # Run DragonflyDB container ['docker', 'run', '-d', '--name', 'swingmusic-dragonfly', '-p', '6379:6379', '--restart', 'unless-stopped', 'docker.dragonflydb.io/dragonflydb/dragonfly'], ] for cmd in docker_commands: try: logger.info(f"Running: {' '.join(cmd)}") result = subprocess.run(cmd, capture_output=True, text=True, timeout=30) if result.returncode != 0: logger.error(f"Command failed: {result.stderr}") return False time.sleep(2) # Wait between commands except subprocess.TimeoutExpired: logger.error("Command timed out") return False except FileNotFoundError: logger.error("Docker not found. Please install Docker first.") return False logger.info("āœ… DragonflyDB container started successfully!") return True def check_dragonflydb_running(): """Check if DragonflyDB is running on localhost:6379""" try: import redis client = redis.Redis(host='localhost', port=6379, socket_connect_timeout=2, socket_timeout=2) client.ping() logger.info("āœ… DragonflyDB is running and accessible!") return True except Exception as e: logger.warning(f"āŒ DragonflyDB not accessible: {e}") return False def start_dragonflydb_binary(): """Start DragonflyDB binary (if installed locally)""" logger.info("šŸš€ Starting DragonflyDB binary...") try: # Start DragonflyDB in background process = subprocess.Popen(['dragonfly', '--port=6379'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) # Wait a moment for startup time.sleep(3) if check_dragonflydb_running(): logger.info("āœ… DragonflyDB binary started successfully!") logger.info(f"Process ID: {process.pid}") return True else: logger.error("āŒ DragonflyDB failed to start") return False except FileNotFoundError: logger.error("āŒ DragonflyDB binary not found") return False def setup_instructions(): """Print setup instructions""" print("\n" + "=" * 60) print("šŸ‰ DRAGONFLYDB SETUP INSTRUCTIONS") print("=" * 60) print("\nDragonflyDB provides ultra-fast caching for Spotify metadata.") print("Without it, SwingMusic will use SQLite (slower but still works).") print("\nšŸ“‹ SETUP OPTIONS:") print("\n1ļøāƒ£ DOCKER (Recommended):") print(" docker run -d --name swingmusic-dragonfly -p 6379:6379 \\") print(" --restart unless-stopped docker.dragonflydb.io/dragonflydb/dragonfly") print("\n2ļøāƒ£ BINARY INSTALLATION:") print(" # Download from: https://www.dragonflydb.io/") print(" # Or use package manager (brew, apt, etc.)") print(" dragonfly --port=6379") print("\n3ļøāƒ£ SKIP (Use SQLite fallback):") print(" # SwingMusic will work without DragonflyDB") print(" # Just slower caching with local SQLite database") print("\nāœ… VERIFICATION:") print(" python3 -c \"import redis; redis.Redis(host='localhost', port=6379).ping()\"") print("=" * 60) def main(): """Main setup function""" print("šŸ‰ DragonflyDB Setup for SwingMusic") print("=" * 50) # Check if already running if check_dragonflydb_running(): logger.info("āœ… DragonflyDB is already running! Setup complete.") return # Check if installed if not check_dragonflydb_installed(): logger.info("DragonflyDB not found. Installing via Docker...") if install_dragonflydb(): # Wait for container to start time.sleep(5) if check_dragonflydb_running(): logger.info("āœ… DragonflyDB setup complete!") return else: logger.error("āŒ Docker installation failed") else: # Try to start binary if start_dragonflydb_binary(): return else: logger.error("āŒ Failed to start DragonflyDB binary") # Show instructions if all else fails setup_instructions() print("\nšŸ“ SUMMARY:") print("āœ… SwingMusic will work with SQLite caching if DragonflyDB unavailable") print("šŸš€ DragonflyDB provides much faster performance when available") print("šŸ”§ Follow the instructions above to set up DragonflyDB manually") if __name__ == "__main__": main()