Two independent improvements from Phase 2.5.
## Panic hook → crash.log
GUI users launched from a .desktop file have no stderr — today panics
vanish without trace. Install a panic::set_hook early in main() that
appends a structured entry to <library_root>/yt-offline.crash.log for
every panic from every thread (UI, axum workers, downloader spawns,
tray bg thread, thumbnail decode workers).
Each entry: ISO-8601 timestamp, thread name, file:line, panic message,
and a backtrace when RUST_BACKTRACE is set. The default panic hook
still runs after ours, so dev workflows keep getting the stderr trace.
Bounded: when the log passes 256 KB the next write rotates it to .1
(one previous generation kept). No external date library — small
civil-time formula in-tree.
## Disk-full preflight
Before yt-dlp ever launches, statvfs the target filesystem. If free
space is under 500 MB, push a synthetic Failed job classified as
DiskFull instead of starting yt-dlp. That way:
- Users see the actual problem ("only 230 MB free on /mnt/…") in the
Downloads modal with the same "free up space and retry" hint the
error-classifier emits for mid-download ENOSPC.
- No half-written file lands on disk.
- No 30-second yt-dlp warmup wasted on a doomed run.
statvfs returning None (non-Unix, missing path) skips the check —
better to let yt-dlp run than to refuse on no data.
5 new tests: 3 in crash (civil-time, log shape, real-panic capture),
2 in disk_space (statvfs plumbing + missing-path None). 74 pass total.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
31 lines
1.3 KiB
TOML
31 lines
1.3 KiB
TOML
[package]
|
|
name = "yt-offline"
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
description = "Self-hosted archive for YouTube, TikTok, Twitch, Vimeo, Bandcamp, SoundCloud, Odysee and more. Desktop GUI + web UI, bundled yt-dlp with curl_cffi impersonation, Plex export, SQLite-backed resume tracking. AGPL-3.0."
|
|
|
|
[dependencies]
|
|
eframe = "0.29"
|
|
image = { version = "0.25", default-features = false, features = ["webp", "jpeg", "png"] }
|
|
toml = "0.8"
|
|
serde = { version = "1.0", features = ["derive"] }
|
|
serde_json = "1.0"
|
|
rusqlite = { version = "0.31", features = ["bundled"] }
|
|
r2d2 = "0.8"
|
|
r2d2_sqlite = "0.24"
|
|
notify-rust = { version = "4", default-features = false, features = ["z"] }
|
|
axum = { version = "0.7", features = ["macros", "ws"] }
|
|
tokio = { version = "1", features = ["full"] }
|
|
tokio-util = { version = "0.7", features = ["io"] }
|
|
tokio-stream = "0.1"
|
|
tower-http = { version = "0.5", features = ["cors", "fs", "compression-gzip"] }
|
|
argon2 = "0.5"
|
|
rand = "0.8"
|
|
# File-picker dialog for the desktop GUI. xdg-portal backend keeps it pure-Rust
|
|
# (zbus, no GTK/libdbus build dep), consistent with notify-rust above.
|
|
rfd = { version = "0.15", default-features = false, features = ["xdg-portal", "tokio"] }
|
|
ksni = { version = "0.3.4", features = ["tokio"] }
|
|
libc = "0.2.186"
|
|
|
|
[profile.release]
|
|
opt-level = 2
|