Merge branch '49-itunes-to-rss-resolver' into 'master'

Resolve "Itunes to RSS resolver."

Closes #49

See merge request alatiera/Hammond!20
This commit is contained in:
Jordan Petridis 2018-03-12 19:52:51 +00:00
commit 3af6e103aa
6 changed files with 76 additions and 1 deletions

View File

@ -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

3
Cargo.lock generated
View File

@ -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)",
]

View File

@ -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"]

View File

@ -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: &gtk::Entry, sender: Sender<Action>) -> 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: &gtk::Entry, sender: Sender<Action>) -> Result<(),
Ok(())
}
// FIXME: THIS SUCKS!
fn on_url_change(
entry: &gtk::Entry,
result: &gtk::Label,

View File

@ -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;

View File

@ -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,35 @@ pub fn get_pixbuf_from_path(pd: &PodcastCoverQuery, size: u32) -> Result<Pixbuf,
Ok(px)
}
#[inline]
// FIXME: the signature should be `fn foo(s: Url) -> Result<Url, Error>`
pub fn itunes_to_rss(url: &str) -> Result<String, Error> {
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<u32> {
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::<u32>().ok()
}
#[inline]
fn lookup_id(id: u32) -> Result<String, Error> {
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();
let feedurl = feedurl.ok_or_else(|| format_err!("Failed to get url from itunes response"))?;
Ok(feedurl.into())
}
#[cfg(test)]
mod tests {
use super::*;
@ -129,4 +161,25 @@ 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 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;
let rss_url = "http://feeds.feedburner.com/InterceptedWithJeremyScahill";
assert_eq!(rss_url, lookup_id(id).unwrap());
}
}