about summary refs log tree commit diff stats
path: root/sys/nixpkgs/pkgs/yt/src/downloader.rs
diff options
context:
space:
mode:
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()