diff --git a/Cargo.lock b/Cargo.lock index 1c9b099..c6f8ab0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -707,7 +707,10 @@ dependencies = [ "loggerv 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)", "send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] diff --git a/hammond-gtk/Cargo.toml b/hammond-gtk/Cargo.toml index 2d11674..a05fcad 100644 --- a/hammond-gtk/Cargo.toml +++ b/hammond-gtk/Cargo.toml @@ -22,6 +22,9 @@ send-cell = "0.1.2" url = "1.6.0" failure = "0.1.1" failure_derive = "0.1.1" +regex = "0.2.6" +reqwest = "0.8.5" +serde_json = "1.0" [dependencies.gtk] features = ["v3_22"] diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 013fcdc..ab85959 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -25,7 +25,10 @@ extern crate hammond_downloader; extern crate humansize; extern crate loggerv; extern crate open; +extern crate regex; +extern crate reqwest; extern crate send_cell; +extern crate serde_json; extern crate url; // extern crate rayon; diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 26ee2be..7fa8682 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -2,7 +2,10 @@ use failure::Error; use gdk_pixbuf::Pixbuf; +use regex::Regex; +use reqwest; use send_cell::SendCell; +use serde_json::Value; // use hammond_data::feed; use hammond_data::{PodcastCoverQuery, Source}; @@ -106,6 +109,34 @@ pub fn get_pixbuf_from_path(pd: &PodcastCoverQuery, size: u32) -> Result Result` +pub fn itunes_to_rss(url: &str) -> Result { + let id = itunes_id_from_url(url).ok_or_else(|| format_err!("Failed to find an Itunes ID."))?; + lookup_id(id) +} + +fn itunes_id_from_url(url: &str) -> Option { + lazy_static! { + static ref RE: Regex = Regex::new(r"/id([0-9]+)").unwrap(); + } + + // Get the itunes id from the url + let foo = RE.captures_iter(url).nth(0)?.get(1)?.as_str(); + // Parse it to a u32, this *should* never fail + foo.parse::().ok() +} + +fn lookup_id(id: u32) -> Result { + let url = format!("https://itunes.apple.com/lookup?id={}&entity=podcast", id); + let req: Value = reqwest::get(&url)?.json()?; + // FIXME: First time using serde, this could be done better and avoid using [] for indexing. + let feedurl = req["results"][0]["feedUrl"] + .as_str() + .ok_or_else(|| format_err!("Failed to get url from itunes response"))? + .into(); + Ok(feedurl) +} + #[cfg(test)] mod tests { use super::*; @@ -129,4 +160,30 @@ mod tests { let pxbuf = get_pixbuf_from_path(&pd.into(), 256); assert!(pxbuf.is_ok()); } + + #[test] + fn test_itunes_to_rss() { + let itunes_url = "https://itunes.apple.com/podcast/id1195206601"; + let rss_url = String::from("http://feeds.feedburner.com/InterceptedWithJeremyScahill"); + + assert_eq!(rss_url, itunes_to_rss(itunes_url).unwrap()); + } + + #[test] + fn test_itunes_id() { + let itunes_url = "https://itunes.apple.com/podcast/id1195206601"; + let id = 1195206601; + + assert_eq!(id, itunes_id_from_url(itunes_url).unwrap()); + } + + #[test] + fn test_itunes_lookup_id() { + let id = 1195206601; + + assert_eq!( + "http://feeds.feedburner.com/InterceptedWithJeremyScahill", + lookup_id(id).unwrap() + ); + } }