Merge branch 'master' into 33-downloader-re-work

This commit is contained in:
Jordan Petridis
2018-01-09 12:06:38 +02:00
11 changed files with 171 additions and 75 deletions
+3 -1
View File
@@ -1,3 +1,5 @@
//! Database Setup. This is only public to help with some unit tests.
use r2d2_diesel::ConnectionManager;
use diesel::prelude::*;
use r2d2;
@@ -35,7 +37,7 @@ lazy_static! {
static ref DB_PATH: PathBuf = TEMPDIR.path().join("hammond.db");
}
// FIXME: this should not be public
/// Get an r2d2 SqliteConnection.
pub fn connection() -> Pool {
POOL.clone()
}
-2
View File
@@ -56,8 +56,6 @@ pub mod utils;
pub mod feed;
#[allow(missing_docs)]
pub mod errors;
// FIXME: this should not be public
#[allow(missing_docs)]
pub mod database;
pub(crate) mod models;
mod parser;
+18 -3
View File
@@ -645,6 +645,7 @@ impl<'a> Source {
// TODO: Refactor into TryInto once it lands on stable.
pub fn into_feed(mut self, ignore_etags: bool) -> Result<Feed> {
use reqwest::header::{EntityTag, Headers, HttpDate, IfModifiedSince, IfNoneMatch};
use reqwest::StatusCode;
let mut headers = Headers::new();
@@ -670,12 +671,26 @@ impl<'a> Source {
self.update_etag(&req)?;
// TODO match on more stuff
// 301: Permanent redirect of the url
// 302: Temporary redirect of the url
// 301: Moved Permanently
// 304: Up to date Feed, checked with the Etag
// 307: Temporary redirect of the url
// 308: Permanent redirect of the url
// 401: Unathorized
// 403: Forbidden
// 408: Timeout
// 410: Feed deleted
match req.status() {
reqwest::StatusCode::NotModified => bail!("304, skipping.."),
StatusCode::NotModified => bail!("304: skipping.."),
StatusCode::TemporaryRedirect => debug!("307: Temporary Redirect."),
// TODO: Change the source uri to the new one
StatusCode::MovedPermanently | StatusCode::PermanentRedirect => {
warn!("Feed was moved permanently.")
}
StatusCode::Unauthorized => bail!("401: Unauthorized."),
StatusCode::Forbidden => bail!("403: Forbidden."),
StatusCode::NotFound => bail!("404: Not found."),
StatusCode::RequestTimeout => bail!("408: Request Timeout."),
StatusCode::Gone => bail!("410: Feed was deleted."),
_ => (),
};
+61 -1
View File
@@ -123,10 +123,70 @@ fn parse_itunes_duration(item: &Item) -> Option<i32> {
mod tests {
use std::fs::File;
use std::io::BufReader;
use rss::Channel;
use rss;
use super::*;
#[test]
fn test_itunes_duration() {
use rss::extension::itunes::ITunesItemExtensionBuilder;
// Input is a String<Int>
let extension = ITunesItemExtensionBuilder::default()
.duration(Some("3370".into()))
.build()
.unwrap();
let item = rss::ItemBuilder::default()
.itunes_ext(Some(extension))
.build()
.unwrap();
assert_eq!(parse_itunes_duration(&item), Some(3370));
// Input is a String<M:SS>
let extension = ITunesItemExtensionBuilder::default()
.duration(Some("6:10".into()))
.build()
.unwrap();
let item = rss::ItemBuilder::default()
.itunes_ext(Some(extension))
.build()
.unwrap();
assert_eq!(parse_itunes_duration(&item), Some(370));
// Input is a String<MM:SS>
let extension = ITunesItemExtensionBuilder::default()
.duration(Some("56:10".into()))
.build()
.unwrap();
let item = rss::ItemBuilder::default()
.itunes_ext(Some(extension))
.build()
.unwrap();
assert_eq!(parse_itunes_duration(&item), Some(3370));
// Input is a String<H:MM:SS>
let extension = ITunesItemExtensionBuilder::default()
.duration(Some("1:56:10".into()))
.build()
.unwrap();
let item = rss::ItemBuilder::default()
.itunes_ext(Some(extension))
.build()
.unwrap();
assert_eq!(parse_itunes_duration(&item), Some(6970));
// Input is a String<HH:MM:SS>
let extension = ITunesItemExtensionBuilder::default()
.duration(Some("01:56:10".into()))
.build()
.unwrap();
let item = rss::ItemBuilder::default()
.itunes_ext(Some(extension))
.build()
.unwrap();
assert_eq!(parse_itunes_duration(&item), Some(6970));
}
#[test]
fn test_new_podcast_intercepted() {
let file = File::open("tests/feeds/Intercepted.xml").unwrap();
+37 -2
View File
@@ -8,11 +8,13 @@ use itertools::Itertools;
use errors::*;
use dbqueries;
use models::queryables::EpisodeCleanerQuery;
use models::queryables::{EpisodeCleanerQuery, Podcast};
use xdg_dirs::DL_DIR;
use std::path::Path;
use std::fs;
/// Scan downloaded `episode` entries that might have broken `local_uri`s and set them to `None`.
fn download_checker() -> Result<()> {
let episodes = dbqueries::get_downloaded_episodes()?;
@@ -30,6 +32,7 @@ fn download_checker() -> Result<()> {
Ok(())
}
/// Delete watched `episodes` that have exceded their liftime after played.
fn played_cleaner() -> Result<()> {
let mut episodes = dbqueries::get_played_cleaner_episodes()?;
@@ -54,7 +57,7 @@ fn played_cleaner() -> Result<()> {
}
/// Check `ep.local_uri` field and delete the file it points to.
pub fn delete_local_content(ep: &mut EpisodeCleanerQuery) -> Result<()> {
fn delete_local_content(ep: &mut EpisodeCleanerQuery) -> Result<()> {
if ep.local_uri().is_some() {
let uri = ep.local_uri().unwrap().to_owned();
if Path::new(&uri).exists() {
@@ -119,6 +122,31 @@ pub fn replace_extra_spaces(s: &str) -> String {
.collect::<String>()
}
/// Returns the URI of a Podcast Downloads given it's title.
pub fn get_download_folder(pd_title: &str) -> Result<String> {
// It might be better to make it a hash of the title or the podcast rowid
let download_fold = format!("{}/{}", DL_DIR.to_str().unwrap(), pd_title);
// Create the folder
fs::DirBuilder::new()
.recursive(true)
.create(&download_fold)?;
Ok(download_fold)
}
/// Removes all the entries associated with the given show from the database,
/// and deletes all of the downloaded content.
/// TODO: Write Tests
pub fn delete_show(pd: &Podcast) -> Result<()> {
dbqueries::remove_feed(&pd)?;
info!("{} was removed succesfully.", pd.title());
let fold = get_download_folder(pd.title())?;
fs::remove_dir_all(&fold)?;
info!("All the content at, {} was removed succesfully", &fold);
Ok(())
}
#[cfg(test)]
mod tests {
extern crate tempdir;
@@ -277,4 +305,11 @@ mod tests {
assert_eq!(replace_extra_spaces(&bad_txt), valid_txt);
}
#[test]
fn test_get_dl_folder() {
let foo_ = format!("{}/{}", DL_DIR.to_str().unwrap(), "foo");
assert_eq!(get_download_folder("foo").unwrap(), foo_);
let _ = fs::remove_dir_all(foo_);
}
}