Four nice-to-have items, plus surfacing the upload date in both UIs
since the user explicitly asked.
Upload date display
- Desktop: card meta row now includes a `YYYY-MM-DD` cell between the
ID and the duration; detail panel header shows it as `📅 YYYY-MM-DD`.
- Web: video player modal title gains a date+duration subline so the
viewer has context without opening the metadata pane (card meta
already shows the date).
- New `format_upload_date()` helper on the desktop side; the web side
reuses the existing `fmtDate()` JS.
Extract HTML_UI to include_str!
- `LOGIN_HTML` and `HTML_UI` moved out of `src/web.rs` into
`src/web_ui/login.html` and `src/web_ui/index.html`. The Rust file
drops from 2915 lines to 1806; editors now syntax-highlight the
HTML/CSS/JS, and UI diffs no longer overwhelm the Rust diff view.
- `include_str!` bakes them into the binary at compile time, so there
is no runtime fs lookup and no extra deploy artifacts.
Twitch clips-only mode
- `classify_twitch` now recognises `twitch.tv/<user>/clips` as a
Channel URL (was Unknown), so yt-dlp's TwitchClips extractor is
reachable from our normal download pipeline.
- Both UIs gain a "Clips only" toggle visible only when the URL is
a Twitch channel (not a specific VOD/clip). On submit, the URL is
rewritten to `twitch.tv/<user>/clips` before dispatch.
- 1 new platform test covers the clips-listing classification.
DB connection pool (r2d2_sqlite)
- `Database` now wraps an `r2d2`-managed SQLite pool. File-backed
databases get up to 4 connections; the in-memory fallback is capped
at 1 (since each in-memory connection is a fresh empty DB by default
in SQLite).
- `WebState.db` drops its outer `Mutex` — concurrent handlers each
check out their own connection from the pool. Static-file fetches
through `/files/` no longer serialize on the watched/positions/
password lookups that the auth middleware performs.
- Pool init failures are converted to `rusqlite::Error` so the
existing `Result<T>` return types still work.
47 unit tests pass.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
29 lines
1.2 KiB
TOML
29 lines
1.2 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"] }
|
|
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"] }
|
|
|
|
[profile.release]
|
|
opt-level = 2
|