v0.36.0: a playlist link says so before it downloads

Pasting a song from a YouTube Mix (watch?v=…&list=RD…) imported song
after song: yt-dlp takes the whole list by default, and a Mix runs to
thousands of rows and loops back on itself, so the linked song came in
again and again with nothing on screen saying why.

Now anything but a plain song link is listed first (--flat-playlist,
streamed into the dialog). One song goes straight through. Several become
a checklist: a song-in-a-list link ticks only its song and offers Just
This Song without waiting, and a playlist link ticks everything. Rows are
de-duplicated by id. The chosen songs download by their own pages, never
the list link, and more than one gets a per-song progress window (Hide
keeps downloading; the status-bar line brings it back).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 17:41:55 -07:00
co-authored by Claude Opus 5.5
parent ad1d152948
commit ac682774e9
9 changed files with 1185 additions and 102 deletions
+13 -6
View File
@@ -50,7 +50,7 @@ if mode == "fail":
src = os.environ.get("FAKE_YTDLP_AUDIO")
titles = ["First Song", "Second Song"]
for i, title in enumerate(titles, 1):
print(f"LTSTART {i}\\t{len(titles)}\\t{title}", flush=True)
print(f"LTSTART {i}\\t{len(titles)}\\tid{i}\\t{title}", flush=True)
print("[download] some noise yt-dlp prints", flush=True)
print("LTPROG 50.0%", flush=True)
path = os.path.join(dest, f"{title} [id{i}].mp3")
@@ -127,9 +127,10 @@ class TestCommand:
assert "-o" not in cmd and "--output" not in cmd
@pytest.mark.parametrize("line, expected", [
("LTSTART 2\t5\tSome Song\n", ("start", 2, 5, "Some Song")),
("LTSTART NA\tNA\tSolo\n", ("start", 1, 1, "Solo")),
("LTSTART 1\t1\tTab\tin title\n", ("start", 1, 1, "Tab\tin title")),
("LTSTART 2\t5\tab1\tSome Song\n", ("start", 2, 5, "ab1", "Some Song")),
("LTSTART NA\tNA\tx\tSolo\n", ("start", 1, 1, "x", "Solo")),
("LTSTART 1\t1\tx\tTab\tin title\n",
("start", 1, 1, "x", "Tab\tin title")),
("LTFILE /tmp/x/Song [abc].mp3\n", ("file", "/tmp/x/Song [abc].mp3")),
("LTPROG 45.3%\n", ("progress", 45)),
("LTPROG 100.0%\r\n", ("progress", 100)),
@@ -210,7 +211,8 @@ def _run_worker(url, dest, cancel_on_first=False):
worker = UrlImportWorker(url)
worker.temp_dir = dest
events = []
worker.item_started.connect(lambda i, n, t: events.append(("start", i, n, t)))
worker.item_started.connect(
lambda i, n, vid, t: events.append(("start", i, n, t)))
worker.progress.connect(lambda p: events.append(("progress", p)))
def on_file(path):
@@ -330,8 +332,13 @@ class TestWindow:
monkeypatch.setenv("FAKE_YTDLP_AUDIO", str(mp3_file))
class _Dialog:
def __init__(self, description, parent=None):
cookies_used = None
def __init__(self, description, parent=None, **_kw):
assert "T2" in description
def chosen_entries(self):
return []
def download_urls(self):
return [self.url()]
def exec(self):
return True
def url(self):