HSDBPX2AMUS4NRA52EHIYOR7H37ABNGJWBJKPQABFMFDU7EITSIAC
EHIJAWMMW36KTRT7K4KRLJEAVOAORCINCIAWK3DJZSFTOUDWECWQC
6AOLKAQQZN4XTNV4SM5B7DYSV2GVDJNGD3CGIFCGO6OEMEANA4OQC
JYSIHNS67XTGAR4HN7ZHWFMGGYSK5IY6J6EHO4YUZOR7UMMWAORQC
XIHPYOWDLQY2MVMVUQPH23O3TBALRG4G2CHSLWSCAYMY5NVJ32WQC
DZWWNB56KIARRP27ZUAQ6SNDKSNDE7R3NPSK67U46IN2T7RXJVRAC
UOKFXM3RDWQDKVGA32NA4ZUOCXLB42GFM46HAZZPXD6EG4QAH2CQC
HAUQPHTCH6DAXE5DHKTVIYVLSENLS7SFWEQUF7LMUQ6MHCGOIEVAC
MR6G2DGGFP43HCF3PKPTDTFALMD3DJDMFDHDVODDHAUMFFV2VISAC
HBNBFXIYY66OQ7Z5PRFN77HXR7HX64HINNJL2FXUGF3PUVRB3LRAC
O7D47WKKNQGIJ72RI5RYD554SONYNLJXXGKPB7KWS7QH4Q4UKE4QC
H2MKJ36A3S5GYYHVK4ILG7AZYJDQGDBIJ6RMZMD66DRBLE66ZDBAC
IGJI574HSHCFEVDVR3Z3USNQIGMJWNDOAOBF3VS7V3KDCQST2FHAC
UIMZBURR7KOWSREO4GDH5C2LZDUTEZBKQNYWBYSFGUTRYJ4GKSNQC
5JMYBRF3UYX4LFH7JK6S4BEDKRVKDFIL4YKTCWKMKP4TMNNGQFKQC
476KTQSS5NXVCTVLVZQRGSYD5OAFBYG75VTSWBN26Q45RSMRT5YQC
6FJACP6KUOZ4HWK4PSS5PFPGDYXZSCAWSKIARWBDGCZTPJWXA62AC
M4FCDZ745GHHL3OLH64EVYOEOEGGGVIBCVFGX5JUJDJRE5OLCXLQC
O53GR2OQHGRKAVJT2RVPRHYFB54W5LM4DQYT7EYVGKU7HDK5CJJQC
JPN37V6Q35ZAW7A2DTGX2WJ3IJ66BAGHXHWXOGHQRHGFAOETFQ7AC
EEJ6CBJRTXLPQP44I2RLWVLJBX565DXXAWU4JIWNA3MMNE7WB5LQC
FFAFJQ5QVMHTLULZTGVM5PX7XQEZQUWLPH2GAN5BGVAYZOZZYG5QC
# podcast
---
`podcast` is a command line podcast player.
It currently supports:
- [x] Subscribing to RSS feeds
- [x] Streaming podcasts
- [x] Playing podcasts
- [ ] Shell Completions
- [x] zsh
- [ ] bash
- [ ] sh
- [ ] Searching for podcasts...(WIP)
By default, podcasts are downloaded to $HOME/Podcasts, but this folder can be set with the $PODCASTS environmental variable.
Individually: `podcast download $podcast_name 4`
Multiple: `podcast download $podcast_name 1,5,9-12,14`
All: `podcast download $podcast_name`
How many latest episodes to download when subscibing to new podcasts can be set in the $PODCASTS/.config YAML file
Downloads can be done a variety of ways:
- [x] Auto-download new episodes
- [x] Automatically check for updates
- [ ] Auto-delete old episodes
- [x] Parallel downloading of multiple podcasts
- [x] Unsubscribing from RSS feeds
NOTE: Playback requires either mpv or vlc to be installed
let mut path = get_podcast_dir();
path.push(".rss");
DirBuilder::new().recursive(true).create(&path).unwrap();
let mut resp = reqwest::get(url).unwrap();
let mut content: Vec<u8> = Vec::new();
resp.read_to_end(&mut content).unwrap();
let channel = Channel::read_from(BufReader::new(&content[..])).unwrap();
let mut filename = String::from(channel.title());
filename.push_str(".xml");
path.push(filename);
let mut file = File::create(&path).unwrap();
file.write_all(&content).unwrap();
if let Err(err) = download_rss_feed(url) {
eprintln!("Error: {}", err);
}
}
let download_limit = config.auto_download_limit as usize;
if download_limit > 0 {
let podcast = Podcast::from(channel);
let episodes = podcast.episodes();
&episodes[..download_limit].par_iter().for_each(|ref ep| {
if let Err(err) = ep.download(podcast.title()) {
eprintln!("Error downloading {}: {}", podcast.title(), err);
pub fn download_rss(config: &Config, url: &str) {
println!("Downloading episode(s)...");
match download_rss_feed(url) {
Ok(channel) => {
let download_limit = config.auto_download_limit as usize;
if download_limit > 0 {
let podcast = Podcast::from(channel);
let episodes = podcast.episodes();
&episodes[..download_limit].par_iter().for_each(|ref ep| {
if let Err(err) = ep.download(podcast.title()) {
eprintln!("Error downloading {}: {}", podcast.title(), err);
}
});
Some("subscribe") => state.subscribe(
matches
.subcommand_matches("subscribe")
.unwrap()
.value_of("URL")
.unwrap(),
&config,
),
Some("subscribe") => {
let subscribe_matches = matches.subcommand_matches("subscribe").unwrap();
let url = subscribe_matches.value_of("URL").unwrap();
state.subscribe(url);
if subscribe_matches.occurrences_of("download") > 0 {
download_rss(&config, url);
} else {
subscribe_rss(url);
}
}
pub fn download_rss_feed(url: &str) -> Result<Channel, String> {
let mut path = get_podcast_dir();
path.push(".rss");
DirBuilder::new().recursive(true).create(&path).unwrap();
let mut resp = reqwest::get(url).unwrap();
let mut content: Vec<u8> = Vec::new();
resp.read_to_end(&mut content).unwrap();
let channel = Channel::read_from(BufReader::new(&content[..])).unwrap();
let mut filename = String::from(channel.title());
filename.push_str(".xml");
path.push(filename);
let mut file = File::create(&path).unwrap();
file.write_all(&content).unwrap();
Ok(channel)
}