From c864af7794bcf34cbcc34a341b8ee3a4d13af8ba Mon Sep 17 00:00:00 2001 From: mbrucedogs Date: Mon, 28 Jul 2025 08:09:47 -0500 Subject: [PATCH] Signed-off-by: mbrucedogs --- CHANGELOG.md | 81 --- data/server_duplicates_tracking.json | 928 +++++++++++++++++++++++++++ karaoke_downloader/cli.py | 53 +- 3 files changed, 967 insertions(+), 95 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index a28b224..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,81 +0,0 @@ -# Changelog - -## [v3.4.1] - 2025-01-27 - -### ๐Ÿ› Bug Fixes -- **Fixed --limit parameter behavior**: The `--limit` parameter now correctly applies to the scanning phase, not just the download execution. When using `--limit N`, only the first N songs are scanned against channels, significantly reducing processing time for large songlists. -- **Fixed --limit logging accuracy**: The logging messages now accurately reflect the number of songs that will actually be processed when using `--limit`, rather than showing counts for all songs in the songlist. -- **Resolved import conflicts**: Fixed inconsistencies between different `extract_artist_title` implementations across modules. - -### โœจ Enhancements -- **Enhanced fuzzy matching**: Improved `extract_artist_title` function in `fuzzy_matcher.py` to handle multiple video title formats: - - `"Artist - Title"` format: "38 Special - Hold On Loosely" - - `"Title Karaoke | Artist Karaoke Version"` format: "Hold On Loosely Karaoke | 38 Special Karaoke Version" - - `"Title Artist KARAOKE"` format: "Hold On Loosely 38 Special KARAOKE" -- **Consolidated parsing logic**: Removed duplicate `extract_artist_title` implementations and centralized all parsing logic in `fuzzy_matcher.py` -- **Better matching accuracy**: Reduced false negatives for songs with non-standard title formats commonly found on YouTube karaoke channels - -### ๐Ÿ”ง Code Quality -- **Eliminated code duplication**: Removed duplicate `extract_artist_title` functions from `id3_utils.py` and `download_planner.py` -- **Single source of truth**: All modules now import `extract_artist_title` from `fuzzy_matcher.py` for consistent behavior -- **Enhanced documentation**: Added comprehensive docstrings and examples to the `extract_artist_title` function -- **Improved maintainability**: Changes to parsing logic now only need to be made in one place - -### ๐Ÿ“š Documentation -- **Updated PRD.md**: Added section documenting recent bug fixes and improvements -- **Updated README.md**: Enhanced feature descriptions and added recent improvements section -- **Enhanced code comments**: Added explanatory comments for the --limit fix and import changes - -### ๐Ÿงช Testing -- **Verified functionality**: Successfully tested the enhanced fuzzy matching with real-world examples -- **Confirmed performance improvements**: Validated that the --limit parameter now works as expected - ---- - -## [v3.4.0] - 2025-01-XX - -### โœจ New Features -- **Parallel downloads**: Enable concurrent downloads with `--parallel --workers N` for significantly faster batch downloads (3-5x speedup) -- **Thread-safe operations**: All tracking, caching, and progress operations are thread-safe -- **Automatic retry mechanism**: Failed downloads are automatically retried with reduced concurrency - -### ๐Ÿ”ง Improvements -- **New parallel downloader module**: `parallel_downloader.py` provides thread-safe concurrent download management -- **Configurable concurrency**: Use `--parallel` to enable parallel downloads with 3 workers by default, or `--parallel --workers N` for custom worker count (1-10) -- **Real-time progress tracking**: Shows active downloads, completion status, and overall progress -- **Backward compatibility**: Sequential downloads remain the default when `--parallel` is not used -- **Integrated with all modes**: Works with both songlist-across-channels and latest-per-channel download modes - ---- - -## [v3.3.0] - 2025-01-XX - -### โœจ New Features -- **Centralized file operations**: `file_utils.py` provides single source of truth for filename handling and file validation -- **Centralized song validation**: `song_validator.py` provides unified logic for checking if songs should be downloaded -- **Enhanced configuration management**: Structured configuration with dataclasses, type safety, and validation - -### ๐Ÿ”ง Improvements -- **Eliminated code duplication**: ~150 lines of duplicate code removed across modules -- **Enhanced type safety**: Comprehensive type hints across all new modules -- **Better error handling**: Consistent patterns via centralized utilities -- **Improved maintainability**: Changes to file operations or song validation only require updates in one place - ---- - -## [v3.2.0] - 2025-01-XX - -### โœจ New Features -- **Download plan pre-scan**: Before downloading, the tool scans all channels for songlist matches, builds a download plan, and prints stats -- **Latest-per-channel plan**: Download the latest N videos from each channel, with a per-channel plan and robust resume -- **Fast mode with early exit**: When a limit is set, scans channels and songs in order, downloads immediately when a match is found -- **Deduplication across channels**: Tracks unique song keys to ensure the same song is not downloaded from multiple channels -- **Fuzzy matching**: Uses string similarity algorithms to find approximate matches between songlist entries and video titles -- **Default channel file**: Automatically uses data/channels.txt as the default channel list for songlist modes - -### ๐Ÿ”ง Improvements -- **Centralized yt-dlp command generation**: Standardized command building and execution across all download operations -- **Enhanced error handling**: Structured exception hierarchy with consistent error messages and formatting -- **Abstracted download pipeline**: Reusable download โ†’ verify โ†’ tag โ†’ track process for consistent processing -- **Optimized scanning algorithm**: High-performance channel scanning with O(nร—m) complexity and pre-processed lookups -- **Robust interruption handling**: Progress is saved after each download, preventing re-downloads if the process is interrupted \ No newline at end of file diff --git a/data/server_duplicates_tracking.json b/data/server_duplicates_tracking.json index 22fec9d..ca0d4bd 100644 --- a/data/server_duplicates_tracking.json +++ b/data/server_duplicates_tracking.json @@ -7038,5 +7038,933 @@ "channel": "songlist", "marked_at": "2025-07-27T08:04:45.697565", "reason": "already_on_server" + }, + "papa roach_last resort": { + "artist": "Papa Roach", + "title": "Last Resort (Karaoke Version)", + "video_title": "Papa Roach - Last Resort (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.702616", + "reason": "already_on_server" + }, + "lewis capaldi_survive": { + "artist": "Lewis Capaldi", + "title": "Survive (Karaoke Version)", + "video_title": "Lewis Capaldi - Survive (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.739703", + "reason": "already_on_server" + }, + "the janedear girls_good girls gone bad": { + "artist": "the JaneDear girls", + "title": "Good Girls Gone Bad (Karaoke Version)", + "video_title": "the JaneDear girls - Good Girls Gone Bad (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.759014", + "reason": "already_on_server" + }, + "justin bieber_flatline": { + "artist": "Justin Bieber", + "title": "Flatline (Karaoke Version)", + "video_title": "Justin Bieber - Flatline (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.772249", + "reason": "already_on_server" + }, + "one direction_another world": { + "artist": "One Direction", + "title": "Another World (Karaoke Version)", + "video_title": "One Direction - Another World (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.792544", + "reason": "already_on_server" + }, + "spin the wheel_your song requests week 8": { + "artist": "Spin The Wheel", + "title": "Your Song Requests Week 8", + "video_title": "Spin The Wheel - Your Song Requests Week 8", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.811032", + "reason": "already_on_server" + }, + "d4vd, hyunjin_always love": { + "artist": "d4vd, Hyunjin", + "title": "Always Love (Karaoke Version)", + "video_title": "d4vd, Hyunjin - Always Love (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.848225", + "reason": "already_on_server" + }, + "adrianne lenker_forwards beckon rebound": { + "artist": "Adrianne Lenker", + "title": "forwards beckon rebound (Karaoke Version)", + "video_title": "Adrianne Lenker - forwards beckon rebound (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.860582", + "reason": "already_on_server" + }, + "bailey zimmerman, luke combs_backup plan": { + "artist": "Bailey Zimmerman, Luke Combs", + "title": "Backup Plan (Karaoke Version)", + "video_title": "Bailey Zimmerman, Luke Combs - Backup Plan (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.881985", + "reason": "already_on_server" + }, + "bryson tiller_let em' know": { + "artist": "Bryson Tiller", + "title": "Let Em' Know (Karaoke Version)", + "video_title": "Bryson Tiller - Let Em' Know (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.898955", + "reason": "already_on_server" + }, + "benson boone_mr electric blue": { + "artist": "Benson Boone", + "title": "Mr Electric Blue (Karaoke Version)", + "video_title": "Benson Boone - Mr Electric Blue (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.917870", + "reason": "already_on_server" + }, + "glorilla_typa": { + "artist": "GloRilla", + "title": "Typa (Karaoke Version)", + "video_title": "GloRilla - Typa (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.937983", + "reason": "already_on_server" + }, + "cardi b_outside": { + "artist": "Cardi B", + "title": "Outside (Karaoke Version)", + "video_title": "Cardi B - Outside (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.956697", + "reason": "already_on_server" + }, + "morgan wallen_skoal, chevy, and browning": { + "artist": "Morgan Wallen", + "title": "Skoal, Chevy, and Browning (Karaoke Version)", + "video_title": "Morgan Wallen - Skoal, Chevy, and Browning (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.972016", + "reason": "already_on_server" + }, + "jade_angel of my dreams": { + "artist": "JADE", + "title": "Angel Of My Dreams (Karaoke Version)", + "video_title": "JADE - Angel Of My Dreams (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:55.987385", + "reason": "already_on_server" + }, + "karol g_latina foreva": { + "artist": "KAROL G", + "title": "LATINA FOREVA (Karaoke Version)", + "video_title": "KAROL G - LATINA FOREVA (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.001183", + "reason": "already_on_server" + }, + "morgan wallen_i got better": { + "artist": "Morgan Wallen", + "title": "I Got Better (Karaoke Version)", + "video_title": "Morgan Wallen - I Got Better (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.018973", + "reason": "already_on_server" + }, + "ella langley_weren't for the wind": { + "artist": "Ella Langley", + "title": "weren't for the wind (Karaoke Version)", + "video_title": "Ella Langley - weren't for the wind (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.036665", + "reason": "already_on_server" + }, + "shabrina leanor_pendampingmu #tahtahatiku": { + "artist": "Shabrina Leanor", + "title": "Pendampingmu #TahtaHatiku (Karaoke Version)", + "video_title": "Shabrina Leanor - Pendampingmu #TahtaHatiku (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.050522", + "reason": "already_on_server" + }, + "elle king_before you met me": { + "artist": "Elle King", + "title": "Before You Met Me (Karaoke Version)", + "video_title": "Elle King - Before You Met Me (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.070722", + "reason": "already_on_server" + }, + "lorde_hammer": { + "artist": "Lorde", + "title": "Hammer (Karaoke Version)", + "video_title": "Lorde - Hammer (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.084734", + "reason": "already_on_server" + }, + "sean paul_temperature": { + "artist": "Sean Paul", + "title": "Temperature (Karaoke Version)", + "video_title": "Sean Paul - Temperature (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.101490", + "reason": "already_on_server" + }, + "karol g_papasito": { + "artist": "KAROL G", + "title": "Papasito (Karaoke Version)", + "video_title": "KAROL G - Papasito (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.118929", + "reason": "already_on_server" + }, + "benson boone_before you": { + "artist": "Benson Boone", + "title": "Before You (Karaoke Version)", + "video_title": "Benson Boone - Before You (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.134488", + "reason": "already_on_server" + }, + "forrest frank_your way's better": { + "artist": "Forrest Frank", + "title": "YOUR WAY'S BETTER (Karaoke Version)", + "video_title": "Forrest Frank - YOUR WAY'S BETTER (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.150270", + "reason": "already_on_server" + }, + "morgan wallen_superman": { + "artist": "Morgan Wallen", + "title": "Superman (Karaoke Version)", + "video_title": "Morgan Wallen - Superman (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.169331", + "reason": "already_on_server" + }, + "earl agustin_tibok": { + "artist": "Earl Agustin", + "title": "Tibok (Karaoke Version)", + "video_title": "Earl Agustin - Tibok (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.186227", + "reason": "already_on_server" + }, + "prettymuch_eyes off you": { + "artist": "PRETTYMUCH", + "title": "Eyes Off You (Karaoke Version)", + "video_title": "PRETTYMUCH - Eyes Off You (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.201889", + "reason": "already_on_server" + }, + "lorde_shapeshifter": { + "artist": "Lorde", + "title": "Shapeshifter (Karaoke Version)", + "video_title": "Lorde - Shapeshifter (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.216119", + "reason": "already_on_server" + }, + "keith sweat, athena cage_nobody": { + "artist": "Keith Sweat, Athena Cage", + "title": "Nobody (Karaoke Version)", + "video_title": "Keith Sweat, Athena Cage - Nobody (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.230593", + "reason": "already_on_server" + }, + "max, huh yunjin_stupid in love": { + "artist": "MAX, HUH YUNJIN", + "title": "STUPID IN LOVE (Karaoke Version)", + "video_title": "MAX, HUH YUNJIN - STUPID IN LOVE (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.249100", + "reason": "already_on_server" + }, + "edward sharpe & the magnetic zeros_home": { + "artist": "Edward Sharpe & The Magnetic Zeros", + "title": "Home (Karaoke Version)", + "video_title": "Edward Sharpe & The Magnetic Zeros - Home (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.261583", + "reason": "already_on_server" + }, + "penelope scott_lotta true crime": { + "artist": "Penelope Scott", + "title": "Lotta True Crime (Karaoke Version)", + "video_title": "Penelope Scott - Lotta True Crime (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.277707", + "reason": "already_on_server" + }, + "alex g, emily yacina_treehouse": { + "artist": "Alex G, Emily Yacina", + "title": "Treehouse (Karaoke Version)", + "video_title": "Alex G, Emily Yacina - Treehouse (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.296486", + "reason": "already_on_server" + }, + "kimya dawson_you love me": { + "artist": "Kimya Dawson", + "title": "You Love Me (Karaoke Version)", + "video_title": "Kimya Dawson - You Love Me (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.311288", + "reason": "already_on_server" + }, + "towa bird_boomerang": { + "artist": "Towa Bird", + "title": "Boomerang (Karaoke Version)", + "video_title": "Towa Bird - Boomerang (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.331964", + "reason": "already_on_server" + }, + "j-hope, glorilla_killin' it girl": { + "artist": "j-hope, GloRilla", + "title": "Killin' It Girl (Karaoke Version)", + "video_title": "j-hope, GloRilla - Killin' It Girl (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.350172", + "reason": "already_on_server" + }, + "tate mcrae_miss possessive": { + "artist": "Tate McRae", + "title": "Miss possessive (Karaoke Version)", + "video_title": "Tate McRae - Miss possessive (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.370252", + "reason": "already_on_server" + }, + "katseye_gabriela": { + "artist": "KATSEYE", + "title": "Gabriela (Karaoke Version)", + "video_title": "KATSEYE - Gabriela (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.386727", + "reason": "already_on_server" + }, + "justyna steczkowska_gaja - eurovision edit": { + "artist": "Justyna Steczkowska", + "title": "GAJA - Eurovision Edit (Karaoke Version)", + "video_title": "Justyna Steczkowska - GAJA - Eurovision Edit (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.400857", + "reason": "already_on_server" + }, + "linkin park_numb": { + "artist": "Linkin Park", + "title": "Numb (Karaoke Version)", + "video_title": "Linkin Park - Numb (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.435790", + "reason": "already_on_server" + }, + "morgan wallen_just in case": { + "artist": "Morgan Wallen", + "title": "Just In Case (Karaoke Version)", + "video_title": "Morgan Wallen - Just In Case (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.449757", + "reason": "already_on_server" + }, + "don toliver_no pole": { + "artist": "Don Toliver", + "title": "No Pole (Karaoke Version)", + "video_title": "Don Toliver - No Pole (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.477962", + "reason": "already_on_server" + }, + "coldplay_sparks": { + "artist": "Coldplay", + "title": "Sparks (Karaoke Version)", + "video_title": "Coldplay - Sparks (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.496124", + "reason": "already_on_server" + }, + "ed sheeran_dive": { + "artist": "Ed Sheeran", + "title": "Dive (Karaoke Version)", + "video_title": "Ed Sheeran - Dive (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.518187", + "reason": "already_on_server" + }, + "amerie_1 thing": { + "artist": "Amerie", + "title": "1 Thing (Karaoke Version)", + "video_title": "Amerie - 1 Thing (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.544220", + "reason": "already_on_server" + }, + "sabrina carpenter_manchild": { + "artist": "Sabrina Carpenter", + "title": "Manchild (Karaoke Version)", + "video_title": "Sabrina Carpenter - Manchild (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.560366", + "reason": "already_on_server" + }, + "benson boone_sorry i'm here for someone else": { + "artist": "Benson Boone", + "title": "Sorry I'm Here For Someone Else (Karaoke Version)", + "video_title": "Benson Boone - Sorry I'm Here For Someone Else (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.582352", + "reason": "already_on_server" + }, + "the red clay strays_wondering why": { + "artist": "The Red Clay Strays", + "title": "Wondering Why (Karaoke Version)", + "video_title": "The Red Clay Strays - Wondering Why (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.603599", + "reason": "already_on_server" + }, + "pinkpantheress_illegal": { + "artist": "PinkPantheress", + "title": "Illegal (Karaoke Version)", + "video_title": "PinkPantheress - Illegal (Karaoke Version)", + "channel": "@SingKingKaraoke", + "marked_at": "2025-07-28T07:58:56.639835", + "reason": "already_on_server" + }, + "iggy pop, kate pierson_candy": { + "artist": "Iggy Pop, Kate Pierson", + "title": "Candy (Karaoke)", + "video_title": "Iggy Pop, Kate Pierson - Candy (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.794620", + "reason": "already_on_server" + }, + "porter wagoner_eat, drink and be merry (for tomorrow you'll cry)": { + "artist": "Porter Wagoner", + "title": "Eat, Drink And Be Merry (For Tomorrow You'll Cry) (Karaoke)", + "video_title": "Porter Wagoner - Eat, Drink And Be Merry (For Tomorrow You'll Cry) (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.818207", + "reason": "already_on_server" + }, + "shocking blue_venus": { + "artist": "Shocking Blue", + "title": "Venus (Karaoke)", + "video_title": "Shocking Blue - Venus (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.838227", + "reason": "already_on_server" + }, + "pratt & mcclain_happy days": { + "artist": "Pratt & McClain", + "title": "Happy Days (Karaoke)", + "video_title": "Pratt & McClain - Happy Days (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.853780", + "reason": "already_on_server" + }, + "george jones_a picture of me (without you)": { + "artist": "George Jones", + "title": "A Picture Of Me (Without You) (Karaoke)", + "video_title": "George Jones - A Picture Of Me (Without You) (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.871975", + "reason": "already_on_server" + }, + "little anthony & the imperials_shimmy shimmy ko-ko-bop": { + "artist": "Little Anthony & The Imperials", + "title": "Shimmy Shimmy Ko-Ko-Bop (Karaoke)", + "video_title": "Little Anthony & The Imperials - Shimmy Shimmy Ko-Ko-Bop (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.890634", + "reason": "already_on_server" + }, + "hairspray_i can hear the bells": { + "artist": "Hairspray", + "title": "I Can Hear The Bells (Karaoke)", + "video_title": "Hairspray - I Can Hear The Bells (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.908193", + "reason": "already_on_server" + }, + "the beatles_all my loving": { + "artist": "The Beatles", + "title": "All My Loving (Karaoke)", + "video_title": "The Beatles - All My Loving (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.924650", + "reason": "already_on_server" + }, + "mccoury brothers_walk out in the rain": { + "artist": "McCoury Brothers", + "title": "Walk Out In The Rain (Karaoke)", + "video_title": "McCoury Brothers - Walk Out In The Rain (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.942100", + "reason": "already_on_server" + }, + "anthony smith_john j. blanchard": { + "artist": "Anthony Smith", + "title": "John J. Blanchard (Karaoke)", + "video_title": "Anthony Smith - John J. Blanchard (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.962729", + "reason": "already_on_server" + }, + "lykke li_i'm good, i'm gone": { + "artist": "Lykke LI", + "title": "I'm Good, I'm Gone (Karaoke)", + "video_title": "Lykke LI - I'm Good, I'm Gone (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.979197", + "reason": "already_on_server" + }, + "tanya tucker_it's only over for you": { + "artist": "Tanya Tucker", + "title": "It's Only Over For You (Karaoke)", + "video_title": "Tanya Tucker - It's Only Over For You (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:56.993614", + "reason": "already_on_server" + }, + "avril lavigne_things i'll never say": { + "artist": "Avril Lavigne", + "title": "Things I'll Never Say (Karaoke)", + "video_title": "Avril Lavigne - Things I'll Never Say (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.009292", + "reason": "already_on_server" + }, + "aretha franklin, whitney houston_it isn't, it wasn't, it ain't never gonna be": { + "artist": "Aretha Franklin, Whitney Houston", + "title": "It Isn't, It Wasn't, It Ain't Never Gonna Be (Karaoke)", + "video_title": "Aretha Franklin, Whitney Houston - It Isn't, It Wasn't, It Ain't Never Gonna Be (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.026212", + "reason": "already_on_server" + }, + "rob thomas_her diamonds": { + "artist": "Rob Thomas", + "title": "Her Diamonds (Karaoke)", + "video_title": "Rob Thomas - Her Diamonds (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.046360", + "reason": "already_on_server" + }, + "darius rucker_history in the making": { + "artist": "Darius Rucker", + "title": "History In The Making (Karaoke)", + "video_title": "Darius Rucker - History In The Making (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.070156", + "reason": "already_on_server" + }, + "sevyn streeter_it won't stop ft. chris brown": { + "artist": "Sevyn Streeter", + "title": "It Won't Stop (Karaoke) ft. Chris Brown", + "video_title": "Sevyn Streeter - It Won't Stop (Karaoke) ft. Chris Brown", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.092856", + "reason": "already_on_server" + }, + "calvin harris_faith": { + "artist": "Calvin Harris", + "title": "Faith (Karaoke)", + "video_title": "Calvin Harris - Faith (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.110808", + "reason": "already_on_server" + }, + "glen campbell_i have you": { + "artist": "Glen Campbell", + "title": "I Have You (Karaoke)", + "video_title": "Glen Campbell - I Have You (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.130045", + "reason": "already_on_server" + }, + "no doubt_platinum blonde life": { + "artist": "No Doubt", + "title": "Platinum Blonde Life (Karaoke)", + "video_title": "No Doubt - Platinum Blonde Life (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.153720", + "reason": "already_on_server" + }, + "def leppard_bringin' on the heartbreak": { + "artist": "Def Leppard", + "title": "Bringin' On The Heartbreak (Karaoke)", + "video_title": "Def Leppard - Bringin' On The Heartbreak (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.241132", + "reason": "already_on_server" + }, + "no doubt_rock steady": { + "artist": "No Doubt", + "title": "Rock Steady (Karaoke)", + "video_title": "No Doubt - Rock Steady (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.316066", + "reason": "already_on_server" + }, + "calvin harris_outside ft. ellie goulding": { + "artist": "Calvin Harris", + "title": "Outside (Karaoke) ft. Ellie Goulding", + "video_title": "Calvin Harris - Outside (Karaoke) ft. Ellie Goulding", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.379399", + "reason": "already_on_server" + }, + "celine dion_my love": { + "artist": "Celine Dion", + "title": "My love (Karaoke)", + "video_title": "Celine Dion - My love (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.471278", + "reason": "already_on_server" + }, + "def leppard_two steps behind": { + "artist": "Def Leppard", + "title": "Two Steps Behind (Karaoke)", + "video_title": "Def Leppard - Two Steps Behind (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.496210", + "reason": "already_on_server" + }, + "carly simon_all i want is you": { + "artist": "Carly Simon", + "title": "All I Want Is You (Karaoke)", + "video_title": "Carly Simon - All I Want Is You (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.551556", + "reason": "already_on_server" + }, + "sugarland_all i want to do": { + "artist": "Sugarland", + "title": "All I Want To Do (Karaoke)", + "video_title": "Sugarland - All I Want To Do (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.576319", + "reason": "already_on_server" + }, + "john cougar mellencamp_ain't even done with the night": { + "artist": "John Cougar Mellencamp", + "title": "Ain't Even Done With The Night (Karaoke)", + "video_title": "John Cougar Mellencamp - Ain't Even Done With The Night (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.593743", + "reason": "already_on_server" + }, + "p.o.d._thinking about forever": { + "artist": "P.O.D.", + "title": "Thinking About Forever (Karaoke)", + "video_title": "P.O.D. - Thinking About Forever (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.620465", + "reason": "already_on_server" + }, + "alive and kicking_tighter, tighter": { + "artist": "Alive And Kicking", + "title": "Tighter, Tighter (Karaoke)", + "video_title": "Alive And Kicking - Tighter, Tighter (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.642482", + "reason": "already_on_server" + }, + "george strait_go on": { + "artist": "George Strait", + "title": "Go On (Karaoke)", + "video_title": "George Strait - Go On (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.663741", + "reason": "already_on_server" + }, + "songs from grease_those magic changes": { + "artist": "Songs from Grease", + "title": "Those Magic Changes (Karaoke)", + "video_title": "Songs from Grease - Those Magic Changes (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.681115", + "reason": "already_on_server" + }, + "songs from you're a good man, charlie brown_snoopy": { + "artist": "Songs from You're A Good Man, Charlie Brown", + "title": "Snoopy (Karaoke)", + "video_title": "Songs from You're A Good Man, Charlie Brown - Snoopy (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.712307", + "reason": "already_on_server" + }, + "sammy davis jr._that old black magic": { + "artist": "Sammy Davis Jr.", + "title": "That Old Black Magic (Karaoke)", + "video_title": "Sammy Davis Jr. - That Old Black Magic (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.734019", + "reason": "already_on_server" + }, + "marshmello_light it up ft. tyga, chris brown": { + "artist": "Marshmello", + "title": "Light It Up (Karaoke) ft. Tyga, Chris Brown", + "video_title": "Marshmello - Light It Up (Karaoke) ft. Tyga, Chris Brown", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.754034", + "reason": "already_on_server" + }, + "mavericks_there goes my heart": { + "artist": "Mavericks", + "title": "There Goes My Heart (Karaoke)", + "video_title": "Mavericks - There Goes My Heart (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.775143", + "reason": "already_on_server" + }, + "paul mccartney_spies like us": { + "artist": "Paul McCartney", + "title": "Spies Like Us (Karaoke)", + "video_title": "Paul McCartney - Spies Like Us (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.841216", + "reason": "already_on_server" + }, + "pearl jam_the fixer": { + "artist": "Pearl Jam", + "title": "The Fixer (Karaoke)", + "video_title": "Pearl Jam - The Fixer (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.866571", + "reason": "already_on_server" + }, + "the chainsmokers_the one": { + "artist": "The Chainsmokers", + "title": "The One (Karaoke)", + "video_title": "The Chainsmokers - The One (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.881464", + "reason": "already_on_server" + }, + "ciara_promise": { + "artist": "Ciara", + "title": "Promise (Karaoke)", + "video_title": "Ciara - Promise (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.901895", + "reason": "already_on_server" + }, + "michael marcagi_scared to start": { + "artist": "Michael Marcagi", + "title": "Scared To Start (Karaoke)", + "video_title": "Michael Marcagi - Scared To Start (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.936281", + "reason": "already_on_server" + }, + "darryl worley_a good day to run": { + "artist": "Darryl Worley", + "title": "A Good Day To Run (Karaoke)", + "video_title": "Darryl Worley - A Good Day To Run (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:57.970763", + "reason": "already_on_server" + }, + "chappell roan_pink pony club": { + "artist": "Chappell Roan", + "title": "Pink Pony Club (Karaoke)", + "video_title": "Chappell Roan - Pink Pony Club (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:58.004568", + "reason": "already_on_server" + }, + "wings_silly love songs": { + "artist": "Wings", + "title": "Silly Love Songs (Karaoke)", + "video_title": "Wings - Silly Love Songs (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T07:58:58.034106", + "reason": "already_on_server" + }, + "chappell roan_the giver": { + "artist": "Chappell Roan", + "title": "The Giver (Karaoke Version)", + "video_title": "Chappell Roan - The Giver (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.146070", + "reason": "already_on_server" + }, + "say you love me_fleetwood mac": { + "artist": "Say You Love Me", + "title": "Fleetwood Mac (Karaoke Version)", + "video_title": "Say You Love Me - Fleetwood Mac (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.174775", + "reason": "already_on_server" + }, + "jack black_steve's lava chicken from the minecraft movie": { + "artist": "Jack Black", + "title": "Steve's Lava Chicken from The Minecraft Movie (Karaoke Version)", + "video_title": "Jack Black - Steve's Lava Chicken from The Minecraft Movie (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.198548", + "reason": "already_on_server" + }, + "shaboozey_good news": { + "artist": "Shaboozey", + "title": "Good News (Karaoke Version)", + "video_title": "Shaboozey - Good News (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.218798", + "reason": "already_on_server" + }, + "lola young_messy": { + "artist": "Lola Young", + "title": "Messy (Karaoke Version)", + "video_title": "Lola Young - Messy (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.241921", + "reason": "already_on_server" + }, + "gigi perez_sailor song": { + "artist": "Gigi Perez", + "title": "Sailor Song (Karaoke Version)", + "video_title": "Gigi Perez - Sailor Song (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.260320", + "reason": "already_on_server" + }, + "lana del rey_diet mountain dew": { + "artist": "Lana Del Rey", + "title": "Diet Mountain Dew (Karaoke Version)", + "video_title": "Lana Del Rey - Diet Mountain Dew (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.303660", + "reason": "already_on_server" + }, + "the monkees_i'm a believer": { + "artist": "The Monkees", + "title": "I'm A Believer (Karaoke Version)", + "video_title": "The Monkees - I'm A Believer (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.330491", + "reason": "already_on_server" + }, + "the isley brothers_shout": { + "artist": "The Isley Brothers", + "title": "Shout (Karaoke Version)", + "video_title": "The Isley Brothers - Shout (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.355082", + "reason": "already_on_server" + }, + "tate mcrae_sports car": { + "artist": "Tate McRae", + "title": "Sports Car (Karaoke Version)", + "video_title": "Tate McRae - Sports Car (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.378170", + "reason": "already_on_server" + }, + "jeff buckley_lover, you should've come over": { + "artist": "Jeff Buckley", + "title": "Lover, You Should've Come Over (Karaoke Version)", + "video_title": "Jeff Buckley - Lover, You Should've Come Over (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.392936", + "reason": "already_on_server" + }, + "myles smith_stargazing": { + "artist": "Myles Smith", + "title": "Stargazing (Karaoke Version)", + "video_title": "Myles Smith - Stargazing (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.418311", + "reason": "already_on_server" + }, + "chris stapleton_think i'm in love with you": { + "artist": "Chris Stapleton", + "title": "Think I'm In Love With You (Karaoke Version)", + "video_title": "Chris Stapleton - Think I'm In Love With You (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.438059", + "reason": "already_on_server" + }, + "doechii_anxiety": { + "artist": "Doechii", + "title": "Anxiety (Karaoke Version)", + "video_title": "Doechii - Anxiety (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.461756", + "reason": "already_on_server" + }, + "bad bunny_dtmf": { + "artist": "Bad Bunny", + "title": "DtMF (Karaoke Version)", + "video_title": "Bad Bunny - DtMF (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.505853", + "reason": "already_on_server" + }, + "lisa_money": { + "artist": "Lisa", + "title": "Money (Karaoke Version)", + "video_title": "Lisa - Money (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.526336", + "reason": "already_on_server" + }, + "sabrina carpenter feat. dolly parton_please please please": { + "artist": "Sabrina Carpenter feat. Dolly Parton", + "title": "Please Please Please (Karaoke Version)", + "video_title": "Sabrina Carpenter feat. Dolly Parton - Please Please Please (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.544462", + "reason": "already_on_server" + }, + "alex warren_ordinary": { + "artist": "Alex Warren", + "title": "Ordinary (Karaoke Version)", + "video_title": "Alex Warren - Ordinary (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.568441", + "reason": "already_on_server" + }, + "lady gaga_abracadabra": { + "artist": "Lady Gaga", + "title": "Abracadabra (Karaoke Version)", + "video_title": "Lady Gaga - Abracadabra (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.605805", + "reason": "already_on_server" + }, + "rufus & chaka khan_ain't nobody": { + "artist": "Rufus & Chaka Khan", + "title": "Ain't Nobody (Karaoke Version)", + "video_title": "Rufus & Chaka Khan - Ain't Nobody (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.636001", + "reason": "already_on_server" + }, + "gotye feat. kimbra_somebody that i used to know": { + "artist": "Gotye feat. Kimbra", + "title": "Somebody That I Used To Know (Karaoke Version)", + "video_title": "Gotye feat. Kimbra - Somebody That I Used To Know (Karaoke Version)", + "channel": "@StingrayKaraoke", + "marked_at": "2025-07-28T07:58:58.674165", + "reason": "already_on_server" + }, + "chappell roan_red wine supernova": { + "artist": "Chappell Roan", + "title": "Red Wine Supernova (Karaoke)", + "video_title": "Chappell Roan - Red Wine Supernova (Karaoke)", + "channel": "@KaraokeOnVEVO", + "marked_at": "2025-07-28T08:08:58.214983", + "reason": "already_on_server" } } \ No newline at end of file diff --git a/karaoke_downloader/cli.py b/karaoke_downloader/cli.py index b9f3e24..959fc14 100644 --- a/karaoke_downloader/cli.py +++ b/karaoke_downloader/cli.py @@ -16,13 +16,14 @@ DEFAULT_CACHE_DURATION_HOURS = 24 def main(): parser = argparse.ArgumentParser( - description="Karaoke Video Downloader - Download YouTube playlists and channel videos for karaoke", + description="Karaoke Video Downloader - Download YouTube playlists and channel videos for karaoke (default: downloads latest videos from all channels)", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: - python download_karaoke.py https://www.youtube.com/playlist?list=XYZ - python download_karaoke.py https://www.youtube.com/@SingKingKaraoke/videos - python download_karaoke.py --file data/channels.txt + python download_karaoke.py --limit 10 # Download latest 10 videos from all channels + python download_karaoke.py --songlist-only --limit 10 # Download only songlist songs across channels + python download_karaoke.py https://www.youtube.com/@SingKingKaraoke/videos # Download from specific channel + python download_karaoke.py --file data/channels.txt # Download from custom channel list python download_karaoke.py --reset-channel SingKingKaraoke --delete-files """, ) @@ -178,7 +179,7 @@ Examples: parser.add_argument( "--latest-per-channel", action="store_true", - help="Download the latest N videos from each channel (use with --limit)", + help="Download the latest N videos from each channel (use with --limit) [DEPRECATED: This is now the default behavior]", ) parser.add_argument( "--fuzzy-match", @@ -445,8 +446,37 @@ Examples: args.url, force_refresh=args.refresh ) else: - parser.print_help() - sys.exit(1) + # Default behavior: download from channels (equivalent to --latest-per-channel) + print("๐ŸŽฏ No specific mode specified, defaulting to download from channels") + channel_file = args.file if args.file else "data/channels.txt" + if not os.path.exists(channel_file): + print(f"โŒ Channel file not found: {channel_file}") + print("Please provide a channel URL or ensure data/channels.txt exists") + sys.exit(1) + with open(channel_file, "r", encoding="utf-8") as f: + channel_urls = [ + line.strip() + for line in f + if line.strip() and not line.strip().startswith("#") + ] + limit = args.limit if args.limit else DEFAULT_LATEST_PER_CHANNEL_LIMIT + force_refresh_download_plan = ( + args.force_download_plan if hasattr(args, "force_download_plan") else False + ) + fuzzy_match = args.fuzzy_match if hasattr(args, "fuzzy_match") else False + fuzzy_threshold = ( + args.fuzzy_threshold + if hasattr(args, "fuzzy_threshold") + else DEFAULT_FUZZY_THRESHOLD + ) + success = downloader.download_latest_per_channel( + channel_urls, + limit=limit, + force_refresh_download_plan=force_refresh_download_plan, + fuzzy_match=fuzzy_match, + fuzzy_threshold=fuzzy_threshold, + force_download=args.force, + ) # Generate unmatched report if requested (additive feature) if args.generate_unmatched_report: @@ -560,13 +590,8 @@ Examples: else: print("โŒ No songlist available for report generation") - # If no download command was specified but generate-unmatched-report was used, exit here - if not any([args.songlist_only, args.songlist_focus, args.latest_per_channel, args.url]): - if args.generate_unmatched_report: - sys.exit(0) - else: - parser.print_help() - sys.exit(1) + # Initialize success variable + success = False downloader.tracker.force_save() if success: