catacomb/src
Luna b24ef4be67 Live-stream recording, recent-additions feed, per-platform impersonate profiles
Three roadmap items together since they touch overlapping code:

Live-stream recording
- New `live: bool` argument on Downloader::start. When true, attaches
  `--live-from-start --wait-for-video 30`, suppresses
  `--break-on-existing` (every recording is a unique file), and
  prepends a UTC timestamp suffix to the output filename so
  re-recordings of the same broadcaster don't collide.
- The job label gains a "🔴 LIVE" marker so a long-running record is
  obviously different from a VOD pull.
- Both UIs gain a "🔴 Live stream" checkbox in the download panel,
  hidden when Music mode is selected. Works for Twitch *and* YouTube
  Live since yt-dlp recognizes both from the URL.
- Web `POST /api/download` accepts a `live: bool` body field; all
  other callers (scheduled re-check, right-click "Check for new
  videos") pass false.

Recent-additions feed
- `library::Video` gains `mtime_unix: Option<u64>` — populated from
  the metadata we already read for `file_size`, so no extra fs hit.
- New `SidebarView::Recent` (desktop) + `showRecent` (web) sort the
  whole library by mtime descending and cap at 100 entries.
- Sidebar entry "🕒 Recent additions" appears only when the library
  has any dated content, so a fresh install doesn't show an empty view.

Per-platform impersonation
- New `Platform::impersonate_target()`:
  - Twitch → None (skip impersonation; their OAuth/Helix dislikes
    mismatched TLS fingerprints).
  - TikTok → "Chrome-Android-131" (mobile profile matches their
    first-party app surface).
  - Everything else → "Chrome-146:Macos-26".
- `Downloader::apply_impersonation` now takes the platform and routes
  through the override; `repair()` (always YouTube-implicit) and
  `start_music()` (uses classify_url on the URL) wire through too.
- `/api/preview` does the same classification before dispatching to
  yt-dlp.
- 3 new tests confirm Twitch → None, TikTok → mobile, YouTube → desktop.

44 unit tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 00:17:59 -07:00
..
app.rs Live-stream recording, recent-additions feed, per-platform impersonate profiles 2026-05-25 00:17:59 -07:00
config.rs Add bundled yt-dlp, music library, Plex metadata, sort by date; security + perf hardening 2026-05-23 04:54:26 -07:00
database.rs Add bundled yt-dlp, music library, Plex metadata, sort by date; security + perf hardening 2026-05-23 04:54:26 -07:00
downloader.rs Live-stream recording, recent-additions feed, per-platform impersonate profiles 2026-05-25 00:17:59 -07:00
library.rs Live-stream recording, recent-additions feed, per-platform impersonate profiles 2026-05-25 00:17:59 -07:00
main.rs Add multi-platform support: TikTok, Twitch, Vimeo, Bandcamp, SoundCloud, Odysee 2026-05-24 22:16:40 -07:00
maintenance.rs Add bundled yt-dlp, music library, Plex metadata, sort by date; security + perf hardening 2026-05-23 04:54:26 -07:00
platform.rs Live-stream recording, recent-additions feed, per-platform impersonate profiles 2026-05-25 00:17:59 -07:00
plex.rs Add multi-platform support: TikTok, Twitch, Vimeo, Bandcamp, SoundCloud, Odysee 2026-05-24 22:16:40 -07:00
stats.rs Add statistics view, editable source_url, rewrite security audit 2026-05-23 05:34:29 -07:00
theme.rs Add web UI, AGPL3, notifications, continue watching, bulk watched, storage stats, scheduler 2026-05-11 04:27:04 -07:00
web.rs Live-stream recording, recent-additions feed, per-platform impersonate profiles 2026-05-25 00:17:59 -07:00
ytdlp_bin.rs Switch bundled yt-dlp to a Python venv with curl_cffi for impersonation 2026-05-24 23:17:27 -07:00