diff --git a/web/app.py b/web/app.py index 0669f23..107a729 100644 --- a/web/app.py +++ b/web/app.py @@ -58,6 +58,35 @@ def get_duplicate_groups(skip_songs: List[Dict[str, Any]]) -> List[Dict[str, Any return groups_list + +def generate_mp3_song_list(all_songs: List[Dict[str, Any]], skip_songs: List[Dict[str, Any]]) -> Dict[str, Any]: + """Generate a list of MP3 songs that remain after cleanup.""" + # Create a set of paths that are being skipped + skip_paths = {song['path'] for song in skip_songs} + + # Filter for MP3/CDG songs that are NOT being skipped + mp3_songs = [] + for song in all_songs: + path = song.get('path', '') + if path.lower().endswith(('.mp3', '.cdg')) and path not in skip_paths: + mp3_songs.append({ + 'position': len(mp3_songs) + 1, + 'title': song.get('title', 'Unknown'), + 'artist': song.get('artist', 'Unknown') + }) + + # Sort by artist, then by title + mp3_songs.sort(key=lambda x: (x['artist'].lower(), x['title'].lower())) + + # Update positions after sorting + for i, song in enumerate(mp3_songs): + song['position'] = i + 1 + + return { + 'title': 'MP3 Songs need to be found', + 'songs': mp3_songs + } + def get_file_type(path: str) -> str: """Extract file type from path.""" path_lower = path.lower() @@ -359,5 +388,54 @@ def get_artists(): 'total_artists': len(artists_list) }) + +@app.route('/api/mp3-songs') +def get_mp3_songs(): + """API endpoint to get MP3 songs that remain after cleanup.""" + # Load all songs and skip songs + all_songs = load_json_file(os.path.join(DATA_DIR, 'allSongs.json')) + skip_songs = load_json_file(os.path.join(DATA_DIR, 'reports', 'skip_songs_detailed.json')) + + if not all_songs: + return jsonify({'error': 'No all songs data found'}), 404 + + if not skip_songs: + skip_songs = [] + + # Generate MP3 song list + mp3_song_list = generate_mp3_song_list(all_songs, skip_songs) + + return jsonify(mp3_song_list) + + +@app.route('/api/download/mp3-songs') +def download_mp3_songs(): + """Download MP3 songs list as JSON file.""" + # Load all songs and skip songs + all_songs = load_json_file(os.path.join(DATA_DIR, 'allSongs.json')) + skip_songs = load_json_file(os.path.join(DATA_DIR, 'reports', 'skip_songs_detailed.json')) + + if not all_songs: + return jsonify({'error': 'No all songs data found'}), 404 + + if not skip_songs: + skip_songs = [] + + # Generate MP3 song list + mp3_song_list = generate_mp3_song_list(all_songs, skip_songs) + + # Save to file + output_path = os.path.join(DATA_DIR, 'reports', 'mp3SongList.json') + with open(output_path, 'w', encoding='utf-8') as f: + json.dump(mp3_song_list, f, indent=2, ensure_ascii=False) + + # Return the file for download + return send_from_directory( + os.path.join(DATA_DIR, 'reports'), + 'mp3SongList.json', + as_attachment=True, + download_name='mp3SongList.json' + ) + if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5000) \ No newline at end of file diff --git a/web/templates/index.html b/web/templates/index.html index fb6da51..782832b 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -266,6 +266,20 @@ +
+
+ +
+
+ + + Download a JSON file containing all MP3 songs that remain after cleanup, + sorted by artist and title. Use this list to find replacement videos. + +
+
@@ -737,6 +751,48 @@ `; } + + async function downloadMp3Songs() { + try { + // Show loading state + const button = event.target.closest('button'); + const originalText = button.innerHTML; + button.innerHTML = ' Generating...'; + button.disabled = true; + + // Trigger download + const response = await fetch('/api/download/mp3-songs'); + + if (response.ok) { + // Create a blob from the response + const blob = await response.blob(); + + // Create download link + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = 'mp3SongList.json'; + document.body.appendChild(a); + a.click(); + window.URL.revokeObjectURL(url); + document.body.removeChild(a); + + // Show success message + alert('MP3 Song List downloaded successfully!'); + } else { + const errorData = await response.json(); + alert('Error downloading MP3 song list: ' + (errorData.error || 'Unknown error')); + } + } catch (error) { + console.error('Error downloading MP3 songs:', error); + alert('Error downloading MP3 song list: ' + error.message); + } finally { + // Restore button state + const button = event.target.closest('button'); + button.innerHTML = originalText; + button.disabled = false; + } + } \ No newline at end of file