mod rss; mod sync; mod input; mod manage; mod folders; mod playlist; mod download; use input::{Command, ListenStatus}; use std::fs; use anyhow::Context; fn main() -> anyhow::Result<()> { let args = { use clap::Parser; input::Args::parse() }; let config: input::Config = { let config = fs::read_to_string(&args.config) .context("failed to read in podcast configuration file")?; toml::from_str(&config[..])? }; let config_path = args.config.canonicalize()?; let Some(root) = config_path.parent() else { anyhow::bail!("could not get parent of configuration path for root directory") }; match args.command { Command::Download { podcast } => { // Updating single podcast if let Some(alias) = podcast { if let Some(source) = config.podcasts.get(&alias) { download::update_podcast(&alias, root, source)?; } else { anyhow::bail!(r#"podcast "{}" not found in configuration file"#, alias) } } // Updating all podcasts else { for (alias, source) in config.podcasts { download::update_podcast(&alias, root, &source)?; } } } Command::List { status, podcast } => { let output = folders::podcast_folder(root, &podcast); let spec_file = output.join(folders::SPEC_FILE); let spec = manage::Specification::read_from(&spec_file)?; for (_, episodes) in spec.feed_iter() { for episode in episodes { if status.is_none() || (episode.listened && status.is_some_and(|x| x == ListenStatus::Listened)) || (!episode.listened && status.is_some_and(|x| x == ListenStatus::Unlistened)) { println!("{}", episode.title()) } } } } Command::Mark { status, podcast } => { let output = folders::podcast_folder(root, &podcast); let spec_file = output.join(folders::SPEC_FILE); let mut spec = manage::Specification::read_from(&spec_file)?; for (_, episodes) in spec.feed_iter_mut() { for episode in episodes { episode.listened = status == ListenStatus::Listened; } } spec.write_to(&spec_file)?; } Command::Playlist { podcast } => { if let Some(alias) = podcast { playlist::generate_podcast_m3u(alias.as_str(), root, false)?; playlist::generate_podcast_m3u(alias.as_str(), root, true)?; } else { for (alias, _) in &config.podcasts { playlist::generate_podcast_m3u(alias.as_str(), root, true)?; playlist::generate_podcast_m3u(alias.as_str(), root, false)?; } playlist::generate_master_m3u(&config, root)?; } } Command::Sync { ipod_dir, download } => { // Sync listened podcasts sync::sync_listened( root, &ipod_dir.join(folders::LOCAL_PLAYLISTS_DIR).join(folders::LISTENED_PLAYLIST_PATH), true, )?; if download { // Download all new episodes for (alias, source) in &config.podcasts { download::update_podcast(&alias, root, &source)?; } } // Generate updated playlist files for (alias, _) in &config.podcasts { playlist::generate_podcast_m3u(alias.as_str(), root, true)?; playlist::generate_podcast_m3u(alias.as_str(), root, false)?; } playlist::generate_master_m3u(&config, root)?; // Sync podcasts and playlists sync::sync(root, &config, &ipod_dir)?; } }; Ok(()) }