- Bug: purge used Path(filename).name which stripped subdirectories,
so files like 'jawed/Me at the zoo.webm' were never found/deleted
- Fix: use output_dir / filename (preserves relative path)
- Also: clean up empty parent directories after file deletion so
uploader folders like 'jawed/' don't linger as empty dirs
Backend:
- New error_log table: url, domain, error, format_id, media_type,
session_id, created_at
- log_download_error() called when yt-dlp throws during download
- GET /admin/errors returns recent entries (limit 200)
- DELETE /admin/errors clears all entries
- Manual purge also clears error log
- Domain extracted from URL via urlparse for grouping
Frontend:
- New 'Errors' tab in admin panel (Sessions, Storage, Errors, Settings)
- Each error entry shows: domain, timestamp, full URL, error message,
format/media type metadata
- Red left border + error-colored message for visual scanning
- Clear Log button to wipe entries
- Empty state: 'No errors logged.'
Error entries contain enough context (full URL, error message, domain,
format, media type) to paste into an LLM for domain-specific debugging.
Settings flow:
- Each section has its own Save button — no ambiguous shared button
- Appearance & Defaults: Save covers welcome message + output formats
- Privacy & Data: Save covers privacy toggle + retention hours
- Security: Change Password button is self-contained
- Bottom note clarifies all settings reset on server restart
Purge improvements:
- Now clears orphaned sessions (sessions with no remaining jobs)
- 'Sure?' confirmation gate on manual purge (3s timeout revert)
- Purge result shows sessions_deleted count
- Cleaner result display: 'X jobs removed' instead of 'Rows deleted: X'
SSE broker:
- publish_all() broadcasts to all sessions (used for purge)
Settings tab reorganized into 3 sections:
- Appearance & Defaults: welcome message + output formats + Save
- Privacy & Data: privacy mode toggle + manual purge
- Security: change password
Manual purge fix:
- purge_all=True clears ALL completed/failed jobs regardless of age
- Previously only cleared jobs older than max_age_hours (7 days),
so recent downloads were never purged on manual trigger
SSE broadcast for purge:
- Added SSEBroker.publish_all() for cross-session broadcasts
- Purge endpoint sends job_removed events for each deleted job
- Frontend queue clears in real-time when admin purges
Privacy Mode feature:
- Toggle in Admin > Settings enables automatic purge of download
history, session logs, and files after configurable retention period
- Default retention: 24 hours when privacy mode is on
- Configurable 1-8760 hours via number input
- When enabled, starts purge scheduler (every 30 min) if not running
- When disabled, data persists indefinitely
Admin panel consolidation:
- Removed separate 'Purge' tab — manual purge moved to Settings
- Settings tab order: Privacy Mode > Manual Purge > Welcome Message >
Output Formats > Change Password
- Toggle switch UI with accent color and smooth animation
- Retention input with left accent border and unit label
Backend:
- PurgeConfig: added privacy_mode (bool) and privacy_retention_hours
- Purge service: uses privacy_retention_hours when privacy mode active
- PUT /admin/settings: accepts privacy_mode + privacy_retention_hours
- GET /config/public: exposes privacy settings to frontend
- Runtime overrides passed to purge service via config._runtime_overrides