diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index 29138f1..ce0aa19 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -39,17 +39,16 @@ fn download_checker() -> Result<(), DataError> { } /// Delete watched `episodes` that have exceded their liftime after played. -fn played_cleaner() -> Result<(), DataError> { +fn played_cleaner(age: u32) -> Result<(), DataError> { + let age = age as i32; let mut episodes = dbqueries::get_played_cleaner_episodes()?; + let now_utc = Utc::now().timestamp() as i32 - age; - let now_utc = Utc::now().timestamp() as i32; episodes .par_iter_mut() .filter(|ep| ep.local_uri().is_some() && ep.played().is_some()) .for_each(|ep| { - // TODO: expose a config and a user set option. - // Chnage the test too when exposed - let limit = ep.played().unwrap() + 172_800; // add 2days in seconds + let limit = ep.played().unwrap(); if now_utc > limit { if let Err(err) = delete_local_content(ep) { error!("Error while trying to delete file: {:?}", ep.local_uri()); @@ -92,10 +91,10 @@ fn delete_local_content(ep: &mut EpisodeCleanerQuery) -> Result<(), DataError> { /// /// Runs a cleaner for played Episode's that are pass the lifetime limit and /// scheduled for removal. -pub fn checkup() -> Result<(), DataError> { +pub fn checkup(cleanup_age: u32) -> Result<(), DataError> { info!("Running database checks."); download_checker()?; - played_cleaner()?; + played_cleaner(cleanup_age)?; info!("Checks completed."); Ok(()) } @@ -262,14 +261,13 @@ mod tests { let _tmp_dir = helper_db(); let mut episode = dbqueries::get_episode_from_pk("foo_bar", 0).unwrap(); let now_utc = Utc::now().timestamp() as i32; - // let limit = now_utc - 172_800; let epoch = now_utc - 200_000; episode.set_played(Some(epoch)); episode.save().unwrap(); let valid_path = episode.local_uri().unwrap().to_owned(); // This should delete the file - played_cleaner().unwrap(); + played_cleaner(172_800).unwrap(); assert_eq!(Path::new(&valid_path).exists(), false); } @@ -278,14 +276,13 @@ mod tests { let _tmp_dir = helper_db(); let mut episode = dbqueries::get_episode_from_pk("foo_bar", 0).unwrap(); let now_utc = Utc::now().timestamp() as i32; - // limit = 172_800; let epoch = now_utc - 20_000; episode.set_played(Some(epoch)); episode.save().unwrap(); let valid_path = episode.local_uri().unwrap().to_owned(); // This should not delete the file - played_cleaner().unwrap(); + played_cleaner(172_800).unwrap(); assert_eq!(Path::new(&valid_path).exists(), true); } diff --git a/hammond-gtk/Cargo.toml b/hammond-gtk/Cargo.toml index 8e5daad..8b505be 100644 --- a/hammond-gtk/Cargo.toml +++ b/hammond-gtk/Cargo.toml @@ -10,7 +10,6 @@ chrono = "0.4.0" dissolve = "0.2.2" gdk = "0.7.0" gdk-pixbuf = "0.3.0" -gio = "0.3.0" glib = "0.4.1" humansize = "1.1.0" lazy_static = "1.0.0" @@ -31,6 +30,10 @@ serde_json = "1.0.11" features = ["v3_22"] version = "0.3.0" +[dependencies.gio] +features = ["v2_50"] +version = "0.3.0" + [dependencies.hammond-data] path = "../hammond-data" diff --git a/hammond-gtk/resources/org.gnome.Hammond.gschema.xml b/hammond-gtk/resources/org.gnome.Hammond.gschema.xml index 4b572e0..ae655cb 100644 --- a/hammond-gtk/resources/org.gnome.Hammond.gschema.xml +++ b/hammond-gtk/resources/org.gnome.Hammond.gschema.xml @@ -33,16 +33,12 @@ Whether to refresh content after startup - - true - Whether to periodically cleanup content - - + 2 How many periods of time to wait between automatic cleanups - + 'days' What period of time to wait between automatic cleanups diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 4fbdfd0..eb236a2 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -1,12 +1,11 @@ #![allow(new_without_default)] -use gio::{ApplicationExt, ApplicationExtManual, ApplicationFlags}; +use gio::{ApplicationExt, ApplicationExtManual, ApplicationFlags, Settings, SettingsExt}; use glib; use gtk; use gtk::prelude::*; use hammond_data::{Podcast, Source}; -use hammond_data::utils::checkup; use appnotif::*; use headerbar::Header; @@ -47,6 +46,7 @@ pub struct App { content: Arc, receiver: Receiver, sender: Sender, + settings: Settings, } impl App { @@ -84,6 +84,8 @@ impl App { // Add the overlay to the main window window.add(&overlay); + let settings = Settings::new("org.gnome.Hammond"); + App { app_instance: application, window, @@ -92,33 +94,45 @@ impl App { content, receiver, sender, + settings, } } fn setup_timed_callbacks(&self) { - let sender = self.sender.clone(); + self.setup_refresh_on_startup(); + self.setup_auto_refresh(); + } + + fn setup_refresh_on_startup(&self) { // Update the feeds right after the Application is initialized. - gtk::timeout_add_seconds(2, move || { - utils::refresh_feed_wrapper(None, sender.clone()); - glib::Continue(false) - }); + if self.settings.get_boolean("refresh-on-startup") { + let cleanup_age = utils::get_cleanup_age(&self.settings); + let sender = self.sender.clone(); + info!("Refresh on startup."); + + gtk::timeout_add_seconds(2, move || { + utils::refresh(None, sender.clone()); + utils::cleanup(cleanup_age); + + glib::Continue(false) + }); + } + } + + fn setup_auto_refresh(&self) { + let refresh_interval = utils::get_refresh_interval(&self.settings); + let cleanup_age = utils::get_cleanup_age(&self.settings); let sender = self.sender.clone(); - // Auto-updater, runs every hour. - // TODO: expose the interval in which it run to a user setting. - gtk::timeout_add_seconds(3600, move || { - utils::refresh_feed_wrapper(None, sender.clone()); + + info!("Auto-refresh every {:?} seconds.", refresh_interval); + + gtk::timeout_add_seconds(refresh_interval, move || { + utils::refresh(None, sender.clone()); + utils::cleanup(cleanup_age); + glib::Continue(true) }); - - // Run a database checkup once the application is initialized. - gtk::timeout_add(300, || { - if let Err(err) = checkup() { - error!("Check up failed: {}", err); - } - - glib::Continue(false) - }); } pub fn run(self) { @@ -137,9 +151,9 @@ impl App { match receiver.recv_timeout(Duration::from_millis(10)) { Ok(Action::UpdateSources(source)) => { if let Some(s) = source { - utils::refresh_feed_wrapper(Some(vec![s]), sender.clone()); + utils::refresh(Some(vec![s]), sender.clone()); } else { - utils::refresh_feed_wrapper(None, sender.clone()); + utils::refresh(None, sender.clone()); } } Ok(Action::RefreshAllViews) => content.update(), diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 5d94e7a..bd9e502 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -2,6 +2,7 @@ use failure::Error; use gdk_pixbuf::Pixbuf; +use gio::{Settings, SettingsExt}; use regex::Regex; use reqwest; use send_cell::SendCell; @@ -11,6 +12,7 @@ use serde_json::Value; use hammond_data::{PodcastCoverQuery, Source}; use hammond_data::dbqueries; use hammond_data::pipeline; +use hammond_data::utils::checkup; use hammond_downloader::downloader; use std::collections::HashMap; @@ -20,13 +22,33 @@ use std::thread; use app::Action; -pub fn refresh_feed_wrapper(source: Option>, sender: Sender) { +pub fn cleanup(age: u32) { + if let Err(err) = checkup(age) { + error!("Check up failed: {}", err); + } +} + +pub fn refresh(source: Option>, sender: Sender) { if let Err(err) = refresh_feed(source, sender) { error!("An error occured while trying to update the feeds."); error!("Error: {}", err); } } +pub fn get_refresh_interval(settings: &Settings) -> u32 { + let time = settings.get_int("auto-refresh-time") as u32; + let period = settings.get_string("auto-refresh-period").unwrap(); + + time_period_to_seconds(&time, period.as_str()) +} + +pub fn get_cleanup_age(settings: &Settings) -> u32 { + let time = settings.get_int("auto-refresh-time") as u32; + let period = settings.get_string("auto-refresh-period").unwrap(); + + time_period_to_seconds(&time, period.as_str()) +} + /// Update the rss feed(s) originating from `source`. /// If `source` is None, Fetches all the `Source` entries in the database and updates them. /// When It's done,it queues up a `RefreshViews` action. @@ -138,12 +160,42 @@ fn lookup_id(id: u32) -> Result { Ok(feedurl.into()) } +pub fn time_period_to_seconds(time: &u32, period: &str) -> u32 { + match period { + "weeks" => time * 604800, + "days" => time * 86400, + "hours" => time * 3600, + "minutes" => time * 60, + _ => time * 1, + } +} + #[cfg(test)] mod tests { use super::*; use hammond_data::Source; use hammond_data::dbqueries; + #[test] + fn test_time_period_to_seconds() { + let time = 2 as u32; + let week = 604800 * time as u32; + let day = 86400 * time as u32; + let hour = 3600 * time as u32; + let minute = 60 * time as u32; + let from_weeks = time_period_to_seconds(&time, "weeks"); + let from_days = time_period_to_seconds(&time, "days"); + let from_hours = time_period_to_seconds(&time, "hours"); + let from_minutes = time_period_to_seconds(&time, "minutes"); + let from_seconds = time_period_to_seconds(&time, "seconds"); + + assert_eq!(week, from_weeks); + assert_eq!(day, from_days); + assert_eq!(hour, from_hours); + assert_eq!(minute, from_minutes); + assert_eq!(time, from_seconds); + } + #[test] // This test inserts an rss feed to your `XDG_DATA/hammond/hammond.db` so we make it explicit // to run it.