Add cookie paste UI, treat break-on-existing as success, skip playlist metafiles

- Update cookies.txt by pasting Netscape-format contents in web UI settings and
  the desktop GUI settings window (shared write/validation in web.rs)
- Treat yt-dlp exit code 101 (--break-on-existing reached an archived video) as
  a successful "up to date" outcome instead of a failed job
- Add --no-write-playlist-metafiles so channel avatars/info aren't written as
  phantom "Title [CHANNEL_ID]" files

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Luna 2026-05-21 03:47:53 -07:00
parent 1ef3fe56c6
commit 3d317797ec
3 changed files with 149 additions and 1 deletions

View file

@ -164,6 +164,10 @@ impl Downloader {
.arg("--write-thumbnail")
.arg("--write-description")
.arg("--write-info-json")
// Don't write channel/playlist-level metafiles (avatar, info.json,
// description). They land as "Title [CHANNEL_ID].ext" files that match
// the per-video naming pattern and show up as phantom videos.
.arg("--no-write-playlist-metafiles")
.arg("--remux-video")
.arg("mkv")
.arg("--embed-metadata")
@ -257,7 +261,23 @@ impl Downloader {
}
}
let ok = child.wait().map(|s| s.success()).unwrap_or(false);
let ok = match child.wait() {
Ok(status) if status.success() => true,
// yt-dlp exits 101 when it stops early because of --break-on-existing
// (it reached an already-archived video). That's the normal "nothing
// new to download" outcome for a channel re-check, not a failure.
Ok(status) => {
if status.code() == Some(101) {
let _ = tx.send(Msg::Line(
"(up to date — stopped at already-downloaded content)".to_string(),
));
true
} else {
false
}
}
Err(_) => false,
};
let _ = tx.send(Msg::Finished(ok));
});