diff --git a/Cargo.lock b/Cargo.lock index 0dd5107..1e29df1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,6 +84,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "anyhow" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" + [[package]] name = "atom_syndication" version = "0.12.1" @@ -1039,6 +1045,7 @@ checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" name = "podal" version = "0.1.0" dependencies = [ + "anyhow", "atom_syndication", "bytes", "clap", diff --git a/Cargo.toml b/Cargo.toml index 04a0466..768b588 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ reqwest = { version = "0.11.18", features = ["json", "blocking"] } scraper = "0.17.1" clap = {version = "4.3.19", features = ["derive"]} bytes = "1.4.0" +anyhow = "1.0.72" [dev-dependencies] tempfile = "*" diff --git a/src/errors.rs b/src/errors.rs index 1135c29..149c8e4 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -13,6 +13,14 @@ impl Error { } } } +impl From for Error { + fn from(value: anyhow::Error) -> Self { + Self { + details: value.to_string(), + source: value.source().unwrap().to_string(), + } + } +} impl From for Error { fn from(value: Utf8Error) -> Self { Self { diff --git a/src/file/env.rs b/src/file/env.rs index 241de60..53eca4c 100644 --- a/src/file/env.rs +++ b/src/file/env.rs @@ -1,3 +1,5 @@ +use anyhow::Context; + use crate::params::Args; use crate::prelude::*; @@ -19,7 +21,9 @@ impl FileEnv { Self { open: Box::new(move |file_name| { let path = format!("{}/{}", &open_dir, file_name); - let file = File::open(path)?; + let file = File::open(&path).with_context(|| { + format!("FileEnv::open: file_name={file_name}, path={path}") + })?; Ok(file) }), append_line: Box::new(move |file_name, line| { diff --git a/src/file/read.rs b/src/file/read.rs index 1bd98e8..93f3fae 100644 --- a/src/file/read.rs +++ b/src/file/read.rs @@ -33,6 +33,7 @@ mod tests { let file_env = FileEnv::create(&Args { downloads: dir.path().to_string_lossy().to_string(), history: "downloaded.txt".to_string(), + subscriptions: file_name.to_string(), }); //when @@ -55,6 +56,7 @@ mod tests { let file_env = FileEnv::create(&Args { downloads: dir.path().to_string_lossy().to_string(), history: "downloaded.txt".to_string(), + subscriptions: file_name.to_string(), }); //when @@ -77,6 +79,7 @@ mod tests { let file_env = FileEnv::create(&Args { downloads: dir.path().to_string_lossy().to_string(), history: "downloaded.txt".to_string(), + subscriptions: file_name.to_string(), }); //when diff --git a/src/history/add.rs b/src/history/add.rs index 7ea8036..b22c4bd 100644 --- a/src/history/add.rs +++ b/src/history/add.rs @@ -42,6 +42,7 @@ mod tests { &FileEnv::create(&Args { downloads: dir.path().to_string_lossy().to_string(), history: "downloaded.txt".to_string(), + subscriptions: "subscriptions.txt".to_string(), }), )?; @@ -76,6 +77,7 @@ mod tests { &FileEnv::create(&Args { downloads: dir.path().to_string_lossy().to_string(), history: "downloaded.txt".to_string(), + subscriptions: "subscriptions.txt".to_string(), }), )?; diff --git a/src/history/find.rs b/src/history/find.rs index 148a623..1397b48 100644 --- a/src/history/find.rs +++ b/src/history/find.rs @@ -41,6 +41,7 @@ mod test { &FileEnv::create(&Args { downloads: dir.path().to_string_lossy().to_string(), history: "downloaded.txt".to_string(), + subscriptions: "subscriptions.txt".to_string(), }), )?; @@ -76,6 +77,7 @@ mod test { &FileEnv::create(&Args { downloads: dir.path().to_string_lossy().to_string(), history: "downloaded.txt".to_string(), + subscriptions: "subscriptions.txt".to_string(), }), )?; @@ -111,6 +113,7 @@ mod test { &FileEnv::create(&Args { downloads: dir.path().to_string_lossy().to_string(), history: "downloaded.txt".to_string(), + subscriptions: "subscriptions.txt".to_string(), }), )?; diff --git a/src/lib.rs b/src/lib.rs index 2095452..c28d6c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,8 +20,8 @@ pub struct Env { pub file: FileEnv, } -pub fn run(subscriptions: &str, site: &str, a: &Args, e: Env) -> Result<()> { - for channel_name in file::read::lines_from(subscriptions, &e.file)? { +pub fn run(site: &str, a: &Args, e: Env) -> Result<()> { + for channel_name in file::read::lines_from(&a.subscriptions, &e.file)? { println!("Channel: {}", channel_name); let feed_url = feed::find(site, &channel_name, &e.network)?; for entry in feed::get(&feed_url, &e.network)?.entries() { @@ -62,6 +62,8 @@ mod tests { let subs_file_name = "subs"; let subs_dir = create_text_file(subs_file_name, "@channel1\nignore me\n@channel2".as_bytes())?; + let subs_file_name = format!("{}/{}", subs_dir.path().to_string_lossy(), subs_file_name); + // one item from each channel is already listed in the downloads.txt file let history_file_name = "history"; let history_dir = create_text_file(history_file_name, "c1-f2\nc2-f3".as_bytes())?; @@ -74,6 +76,7 @@ mod tests { let args = Args { downloads: subs_dir.path().to_string_lossy().to_string(), history: history_file_name.clone(), + subscriptions: subs_file_name.clone(), }; let env = Env { network: NetworkEnv { @@ -95,10 +98,7 @@ mod tests { }, file: FileEnv { open: mock_file_open(HashMap::from([ - ( - subs_file_name.to_string(), - format!("{}/{}", subs_dir.path().to_string_lossy(), subs_file_name), - ), + (subs_file_name.to_string(), subs_file_name), (history_file_name.to_string(), history_file_name), ])), append_line: mock_file_append_line(), @@ -106,7 +106,7 @@ mod tests { }; //when - run(subs_file_name, site, &args, env)?; + run(site, &args, env)?; //then drop(subs_dir); drop(history_dir); diff --git a/src/main.rs b/src/main.rs index 4fcb4d8..324db00 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,13 +6,11 @@ use podal::prelude::*; fn main() -> Result<()> { println!("Podal"); - let subscriptions = "subscriptions.txt"; let site = "https://www.youtube.com/"; let args = Args::parse(); podal::run( - subscriptions, site, &args, podal::Env { diff --git a/src/params/mod.rs b/src/params/mod.rs index 10c3199..67f80d2 100644 --- a/src/params/mod.rs +++ b/src/params/mod.rs @@ -12,4 +12,9 @@ pub struct Args { /// Defaults to "downloaded.txt" located in the downloads directory. #[arg(long, default_value = "downloaded.txt")] pub history: String, + + /// The name of the subscriptions file. + /// Defaults to "subscriptions.txt" located in the downloads directory. + #[arg(long, default_value = "subscriptions.txt")] + pub subscriptions: String, } diff --git a/src/test_utils.rs b/src/test_utils.rs index a29fcfa..8f58ea3 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -7,6 +7,7 @@ use std::{ sync::mpsc::Sender, }; +use anyhow::Context; use tempfile::{tempdir, TempDir}; use crate::{ @@ -63,10 +64,12 @@ pub fn mock_network_fetch_as_bytes_with_rss_entries( pub fn mock_file_open(real_paths: HashMap) -> FileOpenFn { Box::new(move |path: &str| { if let Some(real_path) = real_paths.get(&path.to_string()) { - Ok(File::open(real_path)?) + Ok(File::open(real_path).with_context(|| { + format!("test_utils/mock_file_open: path={path}, real_path={real_path}, path_map=[{:?}]", real_paths) + })?) } else { Err(Error::message( - format!("Not implemented: file_open: {}", path).as_str(), + format!("Not implemented: test_utils/mock_file_open: {}", path).as_str(), )) } })