diff options
Diffstat (limited to '')
-rw-r--r-- | sys/nixpkgs/pkgs/yt/src/downloader.rs (renamed from sys/nixpkgs/pkgs/ytc/src/downloader.rs) | 112 |
1 files changed, 79 insertions, 33 deletions
diff --git a/sys/nixpkgs/pkgs/ytc/src/downloader.rs b/sys/nixpkgs/pkgs/yt/src/downloader.rs index dddebe05..1733500a 100644 --- a/sys/nixpkgs/pkgs/ytc/src/downloader.rs +++ b/sys/nixpkgs/pkgs/yt/src/downloader.rs @@ -1,7 +1,8 @@ use std::{ - fs, + fs::{self, canonicalize}, io::{stderr, stdout, Read}, mem, + os::unix::fs::symlink, path::PathBuf, process::Command, sync::mpsc::{self, Receiver, Sender}, @@ -9,40 +10,28 @@ use std::{ }; use anyhow::{bail, Context, Result}; -use log::debug; +use log::{debug, warn}; +use url::Url; -use crate::PlayThing; +use crate::constants::{status_path, CONCURRENT, DOWNLOAD_DIR, MPV_FLAGS, YT_DLP_FLAGS}; -const YT_DLP_FLAGS: [&str; 12] = [ - "--format", - "bestvideo[height<=?1080]+bestaudio/best", - "--embed-chapters", - "--progress", - "--write-comments", - "--extractor-args", - "youtube:max_comments=150,all,100;comment_sort=top", - "--write-info-json", - "--sponsorblock-mark", - "default", - "--sponsorblock-remove", - "sponsor", -]; - -const CONCURRENT: u32 = 5; - -const DOWNLOAD_DIR: &str = "/tmp/ytcc"; +#[derive(Debug)] +pub struct Downloadable { + pub url: Url, + pub id: Option<u32>, +} pub struct Downloader { sent: usize, download_thread: JoinHandle<Result<()>>, orx: Receiver<(PathBuf, Option<u32>)>, - itx: Option<Sender<PlayThing>>, - playspec: Vec<PlayThing>, + itx: Option<Sender<Downloadable>>, + playspec: Vec<Downloadable>, } impl Downloader { - pub fn new(mut playspec: Vec<PlayThing>) -> anyhow::Result<Downloader> { - let (itx, irx): (Sender<PlayThing>, Receiver<PlayThing>) = mpsc::channel(); + pub fn new(mut playspec: Vec<Downloadable>) -> anyhow::Result<Downloader> { + let (itx, irx): (Sender<Downloadable>, Receiver<Downloadable>) = mpsc::channel(); let (otx, orx) = mpsc::channel(); let jh = thread::spawn(move || -> Result<()> { while let Some(pt) = irx.recv().ok() { @@ -91,7 +80,10 @@ impl Downloader { debug!("Will add 1"); self.add(1).ok()?; } else { - debug!("Will drop sender"); + debug!( + "Done sending videos to be downloaded, downoladed: {} videos", + self.sent + ); let itx = mem::take(&mut self.itx); drop(itx) } @@ -99,7 +91,7 @@ impl Downloader { Some(ok) } Err(err) => { - debug!("Recieved error while listening: {}", err); + debug!("Received error while listening: {}", err); None } } @@ -110,9 +102,63 @@ impl Downloader { Err(err) => panic!("Can't join thread: '{:#?}'", err), } } + + pub fn consume(mut self) -> anyhow::Result<()> { + while let Some((path, id)) = self.next() { + debug!("Next path to play is: '{}'", path.display()); + let mut info_json = canonicalize(&path).context("Failed to canoncialize path")?; + info_json.set_extension("info.json"); + + if status_path()?.is_symlink() { + fs::remove_file(status_path()?).context("Failed to delete old status file")?; + } else if !status_path()?.exists() { + debug!( + "The status path at '{}' does not exists", + status_path()?.display() + ); + } else { + bail!( + "The status path ('{}') is not a symlink but exists!", + status_path()?.display() + ); + } + + symlink(info_json, status_path()?).context("Failed to symlink")?; + + let mut mpv = Command::new("mpv"); + mpv.stdout(stdout()); + mpv.stderr(stderr()); + mpv.args(MPV_FLAGS); + mpv.arg(&path); + + let status = mpv.status().context("Failed to run mpv")?; + if status.success() { + fs::remove_file(&path)?; + if let Some(id) = id { + println!("\x1b[32;1mMarking {} as watched!\x1b[0m", id); + let mut ytcc = std::process::Command::new("ytcc"); + ytcc.stdout(stdout()); + ytcc.stderr(stderr()); + ytcc.args(["mark"]); + ytcc.arg(id.to_string()); + let status = ytcc.status().context("Failed to run ytcc")?; + if let Some(code) = status.code() { + if code != 0 { + bail!("Ytcc failed with status: {}", code); + } + } + } + debug!("mpv exited with: '{}'", status); + } else { + warn!("mpv exited with: '{}'", status); + } + } + self.drop()?; + Ok(()) + } } -fn download_url(url: &str) -> Result<PathBuf> { +fn download_url(url: &Url) -> Result<PathBuf> { let output_file = tempfile::NamedTempFile::new().context("Failed to create tempfile")?; output_file .as_file() @@ -130,17 +176,17 @@ fn download_url(url: &str) -> Result<PathBuf> { yt_dlp.args([ "--output", "%(channel)s/%(title)s.%(ext)s", - url, + url.as_str(), "--print-to-file", "after_move:filepath", ]); yt_dlp.arg(output_file.path().as_os_str()); + let status = yt_dlp.status().context("Failed to run yt-dlp")?; - if let Some(code) = status.code() { - if code != 0 { - bail!("yt_dlp execution failed with error: '{}'", status); - } + if !status.success() { + bail!("yt_dlp execution failed with error: '{}'", status); } + let mut path = String::new(); output_file .as_file() |