Compare commits
No commits in common. "0.0.0" and "master" have entirely different histories.
@ -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.
|
||||
|
||||
|
@ -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(())
|
||||
}
|
||||
|
@ -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[..])?
|
||||
};
|
||||
|
@ -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>,
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user