Compare commits

...

No commits in common. "0.0.0" and "master" have entirely different histories.

4 changed files with 29 additions and 24 deletions

View File

@ -36,7 +36,7 @@ The alias for the podcast is the name given to the folder where they are stored
Then simply run
```
podcast-downloader
podcast-hoarder
```
to bulk download all current episodes.

View File

@ -67,7 +67,7 @@ pub (crate) fn update_podcast(
.with_context(|| format!("failed to create output directory for podcast {}", alias))?;
}
println!(r#"info: scanning feed for "{}""#, alias);
println!(r#"[info] scanning feed for "{}""#, alias);
if feed_location.starts_with("http") {
let feed_url = feed_location;
@ -81,7 +81,7 @@ pub (crate) fn update_podcast(
.with_context(|| format!(r#"error when requesting feed url "{}" for {}"#, feed_url, alias))?;
if response.status_code != 200 {
eprintln!(r#"error: feed "{}" for alias {} responded with non-200 ({}) status code"#, feed_url, alias, response.status_code);
eprintln!(r#"[error] feed "{}" for alias {} responded with non-200 ({}) status code"#, feed_url, alias, response.status_code);
return Ok(());
}
@ -93,7 +93,7 @@ pub (crate) fn update_podcast(
match fs::read_to_string(&feed_path) {
Ok(feed) => update_podcast_from_feed(&output, &feed),
Err(err) => {
eprintln!(r#"error: failed to read path "{}" with error {}"#, feed_path.display(), err);
eprintln!(r#"[error] failed to read path "{}" with error {}"#, feed_path.display(), err);
Ok(())
}
}
@ -138,14 +138,14 @@ fn update_artwork<'a, 'b>(
}
if let Err(err) = download_to_file(new.as_ref(), &cover_path) {
eprintln!(r#"error: failed to download artwork with error "{}". skipping"#, err);
eprintln!(r#"[error] failed to download artwork with error "{}". skipping"#, err);
}
},
Ok(None) => {
println!(r#"warning: could not identify file type from url "{}" for podcast artwork "{}". skipping."#, new, channel.title);
println!(r#"[warning] could not identify file type from url "{}" for podcast artwork "{}". skipping."#, new, channel.title);
}
Err(err) => {
println!(r#"warning: failed to parse url "{}" for "{}" artwork with error: {}. skipping."#, new, channel.title, err);
println!(r#"[warning] failed to parse url "{}" for "{}" artwork with error: {}. skipping."#, new, channel.title, err);
},
};
@ -166,7 +166,7 @@ pub (crate) fn update_podcast_from_feed(
let feed = match xml_serde::from_str::<rss::Feed>(&feed) {
Ok(feed) => feed,
Err(err) => {
eprintln!(r#"error: failed to parse rss feed with error: "{}""#, err);
eprintln!(r#"[error] failed to parse rss feed with error: "{}""#, err);
return Ok(())
}
};
@ -206,7 +206,7 @@ pub (crate) fn update_podcast_from_feed(
} = item;
let Some(enclosure) = enclosure else {
println!(r#"warning: episode "{}" does not have an enclosure tag. skipping."#, title);
println!(r#"[warning] episode "{}" does not have an enclosure tag. skipping."#, title);
continue;
};
@ -228,9 +228,9 @@ pub (crate) fn update_podcast_from_feed(
// In this case we just redownload the file
// This gives an easy way to force a redownload
if !output.join(path).exists() {
println!(r#"info: redownloading "{}" as the file seems to have been deleted"#, title);
println!(r#"[info] redownloading "{}" as the file seems to have been deleted"#, title);
if let Err(err) = download_to_file(enclosure.url.as_ref(), path) {
eprintln!(r#"error: failed to redownload new episode with error "{}". skipping"#, err);
eprintln!(r#"[error] failed to redownload new episode with error: "{}". skipping"#, err);
continue;
}
}
@ -240,11 +240,11 @@ pub (crate) fn update_podcast_from_feed(
let extension = match extract_extension_from_url(enclosure.url.as_ref()) {
Ok(Some(extension)) => extension,
Ok(None) => {
println!(r#"warning: could not identify file type from url "{}" for episode "{}". skipping."#, url, title);
println!(r#"[warning] could not identify file type from url "{}" for episode "{}". skipping."#, url, title);
continue;
}
Err(err) => {
println!(r#"warning: failed to parse url "{}" for episode "{}" with error: {}. skipping."#, url, title, err);
println!(r#"[warning] failed to parse url "{}" for episode "{}" with error: {}. skipping."#, url, title, err);
continue;
},
};
@ -252,7 +252,7 @@ pub (crate) fn update_podcast_from_feed(
let file_path = if ["mp3", "m4a", "ogg", "wav", "mp4", "m4v", "mov", "aiff"].contains(&&extension.to_lowercase()[..]) {
output.join(format!("{}.{}", sanitise(&title), extension))
} else {
println!("warning: unsupported file extension: {}. skipping.", extension);
println!("[warning] unsupported file extension: {}. skipping.", extension);
continue;
};
@ -262,7 +262,7 @@ pub (crate) fn update_podcast_from_feed(
increment_file_name(&file_path).into_owned()
} else { file_path };
println!(r#"info: downloading "{}" to "{}""#, title, file_path.display());
println!(r#"[info] downloading "{}" to "{}""#, title, file_path.display());
match download_to_file(enclosure.url.as_ref(), &file_path) {
Ok(()) => {
@ -291,28 +291,33 @@ pub (crate) fn update_podcast_from_feed(
);
}
}
// Update the file as we go, but only if a change has occured
spec.write_to(&spec_file)?;
},
Err(err) => {
eprintln!(r#"error: failed to request episode "{}" with error "{}". skipping"#, title, err);
eprintln!(r#"[error] failed to request episode "{}" with error: "{}". skipping"#, title, err);
continue;
}
}
spec.write_to(&spec_file)?;
},
}
}
let mut feed_change = false;
// Setting episodes which have been removed to no longer be current
for (_, episodes) in &mut spec.feed {
for episode in episodes {
if !current_episodes.contains(episode.id.as_ref()) {
episode.current = false;
feed_change = true;
}
}
}
spec.write_to(&spec_file)?;
if feed_change {
spec.write_to(&spec_file)?;
}
Ok(())
}

View File

@ -15,7 +15,7 @@ fn main() -> anyhow::Result<()> {
let config : input::Config = {
let config = fs::read_to_string(&args.config)
.with_context(|| "failed to read in podcast configuration file")?;
.context("failed to read in podcast configuration file")?;
toml::from_str(&config[..])?
};

View File

@ -20,7 +20,7 @@ pub struct Rss<'a> {
pub struct Channel<'a> {
#[serde(rename = "item", default)]
pub (crate) items : Vec<Item<'a>>,
pub (crate) link : Cow<'a, str>,
pub (crate) link : Option<Cow<'a, str>>,
pub (crate) title : Cow<'a, str>,
pub (crate) description : Option<Cow<'a, str>>,
#[serde(rename = "{http://www.itunes.com/dtds/podcast-1.0.dtd}itunes:author")]
@ -34,7 +34,7 @@ pub struct Channel<'a> {
#[derive(Debug, serde::Deserialize)]
pub struct Image<'a> {
pub (crate) link : Cow<'a, str>,
pub (crate) link : Option<Cow<'a, str>>,
pub (crate) title : Cow<'a, str>,
pub (crate) url : Cow<'a, str>,
}
@ -85,7 +85,7 @@ pub struct Enclosure<'a> {
pub (crate) url : Cow<'a, str>,
#[serde(rename = "$attr:type")]
pub (crate) mime_type : Option<Cow<'a, str>>,
#[serde(rename = "$attr:length")]
pub (crate) length : Option<u64>,
//#[serde(rename = "$attr:length")]
//pub (crate) length : Option<u64>,
}