From 9da2414e8b08d9b13612085c986fba3779944b9a Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 12 Mar 2018 06:48:05 +0200 Subject: [PATCH 1/4] Initial implementation of an itunes_to_rss url resolver. #49 --- Cargo.lock | 3 +++ hammond-gtk/Cargo.toml | 3 +++ hammond-gtk/src/main.rs | 3 +++ hammond-gtk/src/utils.rs | 57 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 66 insertions(+) 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() + ); + } } From b87c331b12da9268e4cd6fbaf00df7bb1e0bb766 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 12 Mar 2018 07:28:09 +0200 Subject: [PATCH 2/4] Make the itunes_resolver functions inlined. --- hammond-gtk/src/utils.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 7fa8682..b0a93fe 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -109,12 +109,14 @@ 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) } +#[inline] fn itunes_id_from_url(url: &str) -> Option { lazy_static! { static ref RE: Regex = Regex::new(r"/id([0-9]+)").unwrap(); @@ -126,6 +128,7 @@ fn itunes_id_from_url(url: &str) -> Option { foo.parse::().ok() } +#[inline] 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()?; @@ -165,25 +168,20 @@ mod tests { 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; - + let itunes_url = "https://itunes.apple.com/podcast/id1195206601"; 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() - ); + let rss_url = "http://feeds.feedburner.com/InterceptedWithJeremyScahill"; + assert_eq!(rss_url, lookup_id(id).unwrap()); } } From 8a18630ae59227565112be795b3dbe48d7c710a7 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 12 Mar 2018 20:49:02 +0200 Subject: [PATCH 3/4] Initial integration of the itunes resolver with the Add button. --- hammond-gtk/src/headerbar.rs | 12 ++++++++++++ hammond-gtk/src/utils.rs | 8 +++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 15c6b83..3b5bd50 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -12,6 +12,7 @@ use std::sync::mpsc::Sender; use app::Action; use stacks::Content; +use utils::itunes_to_rss; #[derive(Debug, Clone)] pub struct Header { @@ -154,8 +155,18 @@ impl Header { } } +// FIXME: THIS ALSO SUCKS! fn on_add_bttn_clicked(entry: >k::Entry, sender: Sender) -> Result<(), Error> { let url = entry.get_text().unwrap_or_default(); + let url = if url.contains("itunes.com") || url.contains("apple.com") { + info!("Detected itunes url."); + let foo = itunes_to_rss(&url)?; + info!("Resolved to {}", foo); + foo + } else { + url.to_owned() + }; + let source = Source::from_url(&url).context("Failed to convert url to a Source entry.")?; entry.set_text(""); @@ -165,6 +176,7 @@ fn on_add_bttn_clicked(entry: >k::Entry, sender: Sender) -> Result<(), Ok(()) } +// FIXME: THIS SUCKS! fn on_url_change( entry: >k::Entry, result: >k::Label, diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index b0a93fe..5d94e7a 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -133,11 +133,9 @@ 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) + let feedurl = req["results"][0]["feedUrl"].as_str(); + let feedurl = feedurl.ok_or_else(|| format_err!("Failed to get url from itunes response"))?; + Ok(feedurl.into()) } #[cfg(test)] From 3dcc20ae86c1c1f44ef1fdd714d0d638262e68eb Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 12 Mar 2018 21:14:12 +0200 Subject: [PATCH 4/4] Update changelog. --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3caaa5..cb7dd84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] -* Ability to mark all episodes of a Show as watched. (#47)[https://gitlab.gnome.org/alatiera/Hammond/issues/47] +* Ability to mark all episodes of a Show as watched. [#47](https://gitlab.gnome.org/alatiera/Hammond/issues/47) +* Now you are able to subscribe to itunes™ podcasts by using the itunes link of the show.[#49](https://gitlab.gnome.org/alatiera/Hammond/issues/49) ## [0.3.0] - 2018-02-11