#!/usr/bin/env python3 """ Test and validation tool for Karaoke Song Library Cleanup Tool Provides validation and debugging capabilities for the tool. """ import json import os import sys from pathlib import Path def load_json_file(file_path: str) -> dict: """Load JSON file safely.""" try: with open(file_path, 'r', encoding='utf-8') as f: return json.load(f) except Exception as e: print(f"Error loading {file_path}: {e}") return {} def validate_data_files(): """Validate that required data files exist and are properly formatted.""" print("=== Data File Validation ===") # Check for required files required_files = [ 'data/allSongs.json', 'config/config.json' ] for file_path in required_files: if os.path.exists(file_path): print(f"āœ… {file_path} - Found") try: data = load_json_file(file_path) if isinstance(data, (dict, list)): print(f" šŸ“„ Valid JSON format") else: print(f" āŒ Invalid JSON format") except Exception as e: print(f" āŒ Error reading JSON: {e}") else: print(f"āŒ {file_path} - Missing") # Check for optional files optional_files = [ 'data/skipSongs.json', 'data/preferences/priority_preferences.json' ] print("\n=== Optional Files ===") for file_path in optional_files: if os.path.exists(file_path): print(f"āœ… {file_path} - Found") else: print(f"āš ļø {file_path} - Not found (will be created when needed)") def analyze_song_data(): """Analyze the song data structure and provide insights.""" print("\n=== Song Data Analysis ===") all_songs_path = 'data/allSongs.json' if not os.path.exists(all_songs_path): print(f"āŒ {all_songs_path} not found - cannot analyze song data") return try: songs = load_json_file(all_songs_path) if not songs: print("āŒ No songs found in data file") return print(f"šŸ“Š Total songs: {len(songs)}") # Analyze file types file_types = {} artists = set() titles = set() for song in songs: # File type analysis path = song.get('path', '').lower() if path.endswith('.mp4'): file_types['MP4'] = file_types.get('MP4', 0) + 1 elif path.endswith('.mp3'): file_types['MP3'] = file_types.get('MP3', 0) + 1 elif path.endswith('.cdg'): file_types['CDG'] = file_types.get('CDG', 0) + 1 else: file_types['Other'] = file_types.get('Other', 0) + 1 # Artist and title analysis artist = song.get('artist', '').strip() title = song.get('title', '').strip() if artist: artists.add(artist) if title: titles.add(title) print(f"šŸ“ File types: {file_types}") print(f"šŸŽ¤ Unique artists: {len(artists)}") print(f"šŸŽµ Unique titles: {len(titles)}") # Sample data structure if songs: print(f"\nšŸ“‹ Sample song structure:") sample = songs[0] for key, value in sample.items(): if isinstance(value, str) and len(value) > 50: value = value[:50] + "..." print(f" {key}: {value}") except Exception as e: print(f"āŒ Error analyzing song data: {e}") def validate_config(): """Validate the configuration file.""" print("\n=== Configuration Validation ===") config_path = 'config/config.json' if not os.path.exists(config_path): print(f"āŒ {config_path} not found") return try: config = load_json_file(config_path) # Check for required config sections required_sections = ['channel_priorities', 'matching_rules'] for section in required_sections: if section in config: print(f"āœ… {section} - Found") else: print(f"āŒ {section} - Missing") # Display current configuration print(f"\nšŸ“‹ Current configuration:") for key, value in config.items(): if isinstance(value, list): print(f" {key}: {len(value)} items") else: print(f" {key}: {value}") except Exception as e: print(f"āŒ Error validating config: {e}") def main(): """Main test function.""" print("šŸŽµ Karaoke Song Library Cleanup Tool - Test & Validation") print("=" * 60) # Validate data files validate_data_files() # Analyze song data analyze_song_data() # Validate configuration validate_config() print("\n" + "=" * 60) print("āœ… Test completed") if __name__ == "__main__": main()