Add watched tracking, resume positions, sort, density slider, channel metadata, mpv IPC, browser selector, auto-rescan
- SQLite DB for watched/position persistence (database.rs) - Mark watched toggle on cards and detail panel - mpv IPC socket integration for resume position tracking (unix) - Sort by title, duration, file size - Thumbnail density slider in top bar - Channel metadata banner (subscriber count, uploader, channel URL) - Cookie browser selector dropdown in settings - Auto-rescan library when a download job finishes - Fix yt-dlp --no-progress-bar flag (does not exist; removed) - Browser field wired through config → downloader Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
95a73b0980
commit
5b3b8fc901
7 changed files with 644 additions and 221 deletions
|
|
@ -1,4 +1,5 @@
|
|||
use rusqlite::{Connection, Result};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::path::Path;
|
||||
|
||||
pub struct Database {
|
||||
|
|
@ -13,39 +14,69 @@ impl Database {
|
|||
Ok(db)
|
||||
}
|
||||
|
||||
pub fn open_in_memory() -> Result<Self> {
|
||||
let conn = Connection::open_in_memory()?;
|
||||
let db = Database { conn };
|
||||
db.init_schema()?;
|
||||
Ok(db)
|
||||
}
|
||||
|
||||
fn init_schema(&self) -> Result<()> {
|
||||
self.conn.execute_batch(
|
||||
"CREATE TABLE IF NOT EXISTS videos (
|
||||
id TEXT PRIMARY KEY,
|
||||
channel TEXT NOT NULL,
|
||||
title TEXT NOT NULL,
|
||||
downloaded_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
"CREATE TABLE IF NOT EXISTS watched (
|
||||
video_id TEXT PRIMARY KEY,
|
||||
watched_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS downloads (
|
||||
id INTEGER PRIMARY KEY,
|
||||
url TEXT NOT NULL,
|
||||
directory TEXT NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
started_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
completed_at DATETIME
|
||||
CREATE TABLE IF NOT EXISTS positions (
|
||||
video_id TEXT PRIMARY KEY,
|
||||
position_secs REAL NOT NULL,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);",
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn record_download(&self, url: &str, dir: &str, status: &str) -> Result<()> {
|
||||
pub fn set_watched(&self, video_id: &str, watched: bool) -> Result<()> {
|
||||
if watched {
|
||||
self.conn.execute(
|
||||
"INSERT OR REPLACE INTO watched (video_id) VALUES (?1)",
|
||||
[video_id],
|
||||
)?;
|
||||
} else {
|
||||
self.conn.execute("DELETE FROM watched WHERE video_id = ?1", [video_id])?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_watched(&self) -> Result<HashSet<String>> {
|
||||
let mut stmt = self.conn.prepare("SELECT video_id FROM watched")?;
|
||||
let ids = stmt
|
||||
.query_map([], |row| row.get(0))?
|
||||
.filter_map(Result::ok)
|
||||
.collect();
|
||||
Ok(ids)
|
||||
}
|
||||
|
||||
pub fn set_position(&self, video_id: &str, position_secs: f64) -> Result<()> {
|
||||
self.conn.execute(
|
||||
"INSERT INTO downloads (url, directory, status) VALUES (?1, ?2, ?3)",
|
||||
[url, dir, status],
|
||||
"INSERT OR REPLACE INTO positions (video_id, position_secs, updated_at)
|
||||
VALUES (?1, ?2, CURRENT_TIMESTAMP)",
|
||||
rusqlite::params![video_id, position_secs],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update_download_status(&self, id: i64, status: &str) -> Result<()> {
|
||||
self.conn.execute(
|
||||
"UPDATE downloads SET status = ?1, completed_at = CURRENT_TIMESTAMP WHERE id = ?2",
|
||||
[status, &id.to_string()],
|
||||
)?;
|
||||
pub fn clear_position(&self, video_id: &str) -> Result<()> {
|
||||
self.conn.execute("DELETE FROM positions WHERE video_id = ?1", [video_id])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_positions(&self) -> Result<HashMap<String, f64>> {
|
||||
let mut stmt = self.conn.prepare("SELECT video_id, position_secs FROM positions")?;
|
||||
let map = stmt
|
||||
.query_map([], |row| Ok((row.get::<_, String>(0)?, row.get::<_, f64>(1)?)))?
|
||||
.filter_map(Result::ok)
|
||||
.collect();
|
||||
Ok(map)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue