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:
commit
3af6e103aa
@ -6,7 +6,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|||||||
|
|
||||||
## [Unreleased]
|
## [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
|
## [0.3.0] - 2018-02-11
|
||||||
|
|
||||||
|
|||||||
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -707,7 +707,10 @@ dependencies = [
|
|||||||
"loggerv 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,9 @@ send-cell = "0.1.2"
|
|||||||
url = "1.6.0"
|
url = "1.6.0"
|
||||||
failure = "0.1.1"
|
failure = "0.1.1"
|
||||||
failure_derive = "0.1.1"
|
failure_derive = "0.1.1"
|
||||||
|
regex = "0.2.6"
|
||||||
|
reqwest = "0.8.5"
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
||||||
[dependencies.gtk]
|
[dependencies.gtk]
|
||||||
features = ["v3_22"]
|
features = ["v3_22"]
|
||||||
|
|||||||
@ -12,6 +12,7 @@ use std::sync::mpsc::Sender;
|
|||||||
|
|
||||||
use app::Action;
|
use app::Action;
|
||||||
use stacks::Content;
|
use stacks::Content;
|
||||||
|
use utils::itunes_to_rss;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Header {
|
pub struct Header {
|
||||||
@ -154,8 +155,18 @@ impl Header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: THIS ALSO SUCKS!
|
||||||
fn on_add_bttn_clicked(entry: >k::Entry, sender: Sender<Action>) -> Result<(), Error> {
|
fn on_add_bttn_clicked(entry: >k::Entry, sender: Sender<Action>) -> Result<(), Error> {
|
||||||
let url = entry.get_text().unwrap_or_default();
|
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.")?;
|
let source = Source::from_url(&url).context("Failed to convert url to a Source entry.")?;
|
||||||
entry.set_text("");
|
entry.set_text("");
|
||||||
|
|
||||||
@ -165,6 +176,7 @@ fn on_add_bttn_clicked(entry: >k::Entry, sender: Sender<Action>) -> Result<(),
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: THIS SUCKS!
|
||||||
fn on_url_change(
|
fn on_url_change(
|
||||||
entry: >k::Entry,
|
entry: >k::Entry,
|
||||||
result: >k::Label,
|
result: >k::Label,
|
||||||
|
|||||||
@ -25,7 +25,10 @@ extern crate hammond_downloader;
|
|||||||
extern crate humansize;
|
extern crate humansize;
|
||||||
extern crate loggerv;
|
extern crate loggerv;
|
||||||
extern crate open;
|
extern crate open;
|
||||||
|
extern crate regex;
|
||||||
|
extern crate reqwest;
|
||||||
extern crate send_cell;
|
extern crate send_cell;
|
||||||
|
extern crate serde_json;
|
||||||
extern crate url;
|
extern crate url;
|
||||||
// extern crate rayon;
|
// extern crate rayon;
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use gdk_pixbuf::Pixbuf;
|
use gdk_pixbuf::Pixbuf;
|
||||||
|
use regex::Regex;
|
||||||
|
use reqwest;
|
||||||
use send_cell::SendCell;
|
use send_cell::SendCell;
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
// use hammond_data::feed;
|
// use hammond_data::feed;
|
||||||
use hammond_data::{PodcastCoverQuery, Source};
|
use hammond_data::{PodcastCoverQuery, Source};
|
||||||
@ -106,6 +109,35 @@ pub fn get_pixbuf_from_path(pd: &PodcastCoverQuery, size: u32) -> Result<Pixbuf,
|
|||||||
Ok(px)
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
@ -129,4 +161,25 @@ mod tests {
|
|||||||
let pxbuf = get_pixbuf_from_path(&pd.into(), 256);
|
let pxbuf = get_pixbuf_from_path(&pd.into(), 256);
|
||||||
assert!(pxbuf.is_ok());
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user