import tempfile import unittest from pathlib import Path class SuspectedLiveDetectionTests(unittest.TestCase): def test_detect_reason_codes_matches_name_keyword(self): from musicdl.catalogsync.suspected_live import detect_suspected_live_reason_codes reason_codes = detect_suspected_live_reason_codes( name="Song A Live", album="Studio Album", ) self.assertEqual(["name_keyword"], reason_codes) def test_detect_reason_codes_matches_album_show_keyword(self): from musicdl.catalogsync.suspected_live import detect_suspected_live_reason_codes reason_codes = detect_suspected_live_reason_codes( name="年轻的战场", album="听!我们的歌", ) self.assertEqual(["album_show_keyword"], reason_codes) def test_detect_reason_codes_ignores_album_that_repeats_song_name(self): from musicdl.catalogsync.suspected_live import detect_suspected_live_reason_codes reason_codes = detect_suspected_live_reason_codes( name="Song A", album="Song A 演唱会特别版", ) self.assertEqual([], reason_codes) class SuspectedLiveScannerTests(unittest.TestCase): def _build_repo(self): from musicdl.catalogsync.db import initialize_database from musicdl.catalogsync.repository import CatalogRepository tmpdir = tempfile.TemporaryDirectory(ignore_cleanup_errors=True) self.addCleanup(tmpdir.cleanup) root = Path(tmpdir.name) db_path = root / "catalogsync.db" initialize_database(db_path).close() return root, db_path, CatalogRepository(db_path) def test_scan_suspected_live_songs_returns_downloaded_candidates_by_default(self): from musicdl.catalogsync.models import CatalogSong from musicdl.catalogsync.suspected_live import scan_suspected_live_songs root, db_path, repo = self._build_repo() library_root = root / "library" backend_id = repo.ensure_local_backend( library_root, name="default-local", is_default=True, ) downloaded_song_id = repo.upsert_song( CatalogSong( platform="qq", remote_song_id="downloaded-live-1", name="年轻的战场", singers="张杰", album="听!我们的歌", ) ) repo.record_local_file( song_id=downloaded_song_id, backend_id=backend_id, relative_path="qq/张杰/年轻的战场.flac", file_size_bytes=8, ext="flac", quality_label="lossless", ) repo.upsert_song( CatalogSong( platform="netease", remote_song_id="undownloaded-live-1", name="Besame Mucho", singers="王晰", album="我是歌手第四季 第6期", ) ) repo.upsert_song( CatalogSong( platform="qq", remote_song_id="downloaded-studio-1", name="Studio Song", singers="Singer A", album="Studio Album", ) ) matches = scan_suspected_live_songs(db_path) self.assertEqual(1, len(matches)) self.assertEqual(downloaded_song_id, matches[0].song_id) self.assertEqual(("album_show_keyword",), matches[0].reason_codes) def test_scan_suspected_live_songs_can_include_undownloaded(self): from musicdl.catalogsync.models import CatalogSong from musicdl.catalogsync.suspected_live import scan_suspected_live_songs _, db_path, repo = self._build_repo() first_song_id = repo.upsert_song( CatalogSong( platform="qq", remote_song_id="song-live-1", name="Song A", singers="Singer A", album="我们的歌", ) ) second_song_id = repo.upsert_song( CatalogSong( platform="netease", remote_song_id="song-live-2", name="Song B", singers="Singer B", album="我是歌手第四季 第6期", ) ) matches = scan_suspected_live_songs( db_path, downloaded_only=False, limit=2, ) self.assertEqual([second_song_id, first_song_id], [item.song_id for item in matches])