diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index 29138f1..d17ee09 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -39,17 +39,15 @@ fn download_checker() -> Result<(), DataError> { } /// Delete watched `episodes` that have exceded their liftime after played. -fn played_cleaner() -> Result<(), DataError> { +fn played_cleaner(cleanup_date: DateTime) -> Result<(), DataError> { let mut episodes = dbqueries::get_played_cleaner_episodes()?; + let now_utc = cleanup_date.timestamp() as i32; - 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 +90,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_date: DateTime) -> Result<(), DataError> { info!("Running database checks."); download_checker()?; - played_cleaner()?; + played_cleaner(cleanup_date)?; info!("Checks completed."); Ok(()) } @@ -182,6 +180,7 @@ mod tests { use self::tempdir::TempDir; use super::*; + use chrono::Duration; use database::truncate_db; use models::NewEpisodeBuilder; @@ -261,15 +260,14 @@ mod tests { fn test_played_cleaner_expired() { 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; + let cleanup_date = Utc::now() - Duration::seconds(1000); + let epoch = cleanup_date.timestamp() as i32 - 1; 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(cleanup_date).unwrap(); assert_eq!(Path::new(&valid_path).exists(), false); } @@ -277,15 +275,14 @@ mod tests { fn test_played_cleaner_none() { 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; + let cleanup_date = Utc::now() - Duration::seconds(1000); + let epoch = cleanup_date.timestamp() as i32 + 1; 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(cleanup_date).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..a55659c 100644 --- a/hammond-gtk/resources/org.gnome.Hammond.gschema.xml +++ b/hammond-gtk/resources/org.gnome.Hammond.gschema.xml @@ -14,17 +14,17 @@ false Enable or disable dark theme - - + + true Whether to periodically refresh content - + 1 How many periods of time to wait between automatic refreshes - + 'hours' What period of time to wait between automatic refreshes @@ -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..c7ae2a5 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -1,12 +1,12 @@ #![allow(new_without_default)] -use gio::{ApplicationExt, ApplicationExtManual, ApplicationFlags}; +use gio::{ApplicationExt, ApplicationExtManual, ApplicationFlags, Settings, SettingsExt}; use glib; use gtk; +use gtk::SettingsExt as GtkSettingsExt; use gtk::prelude::*; use hammond_data::{Podcast, Source}; -use hammond_data::utils::checkup; use appnotif::*; use headerbar::Header; @@ -47,6 +47,7 @@ pub struct App { content: Arc, receiver: Receiver, sender: Sender, + settings: Settings, } impl App { @@ -84,6 +85,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 +95,52 @@ impl App { content, receiver, sender, + settings, } } fn setup_timed_callbacks(&self) { - let sender = self.sender.clone(); + self.setup_dark_theme(); + self.setup_refresh_on_startup(); + self.setup_auto_refresh(); + } + + fn setup_dark_theme(&self) { + let settings = gtk::Settings::get_default().unwrap(); + let enabled = self.settings.get_boolean("dark-theme"); + + settings.set_property_gtk_application_prefer_dark_theme(enabled); + } + + 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_date = utils::get_cleanup_date(&self.settings); + let sender = self.sender.clone(); + info!("Refresh on startup."); + + utils::cleanup(cleanup_date); + + gtk::timeout_add_seconds(2, move || { + utils::refresh(None, sender.clone()); + + glib::Continue(false) + }); + } + } + + fn setup_auto_refresh(&self) { + let refresh_interval = utils::get_refresh_interval(&self.settings).num_seconds() as u32; 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()); + 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 +159,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/main.rs b/hammond-gtk/src/main.rs index cd21890..991358e 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -89,11 +89,5 @@ fn main() { 600, ); - // This set's the app to dark mode. - // It wiil be in the user's preference later. - // Uncomment it to run with the dark theme variant. - // let settings = gtk::Settings::get_default().unwrap(); - // settings.set_property_gtk_application_prefer_dark_theme(true); - App::new().run(); } diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 5d94e7a..e67051f 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,37 @@ use std::thread; use app::Action; -pub fn refresh_feed_wrapper(source: Option>, sender: Sender) { +use chrono::Duration; +use chrono::prelude::*; + +pub fn cleanup(cleanup_date: DateTime) { + if let Err(err) = checkup(cleanup_date) { + 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) -> Duration { + let time = settings.get_int("refresh-interval-time") as i64; + let period = settings.get_string("refresh-interval-period").unwrap(); + + time_period_to_duration(time, period.as_str()) +} + +pub fn get_cleanup_date(settings: &Settings) -> DateTime { + let time = settings.get_int("cleanup-age-time") as i64; + let period = settings.get_string("cleanup-age-period").unwrap(); + let duration = time_period_to_duration(time, period.as_str()); + + Utc::now() - duration +} + /// 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 +164,40 @@ fn lookup_id(id: u32) -> Result { Ok(feedurl.into()) } +pub fn time_period_to_duration(time: i64, period: &str) -> Duration { + match period { + "weeks" => Duration::weeks(time), + "days" => Duration::days(time), + "hours" => Duration::hours(time), + "minutes" => Duration::minutes(time), + _ => Duration::seconds(time), + } +} + #[cfg(test)] mod tests { use super::*; use hammond_data::Source; use hammond_data::dbqueries; + #[test] + fn test_time_period_to_duration() { + let time = 2; + let week = 604800 * time; + let day = 86400 * time; + let hour = 3600 * time; + let minute = 60 * time; + + assert_eq!(week, time_period_to_duration(time, "weeks").num_seconds()); + assert_eq!(day, time_period_to_duration(time, "days").num_seconds()); + assert_eq!(hour, time_period_to_duration(time, "hours").num_seconds()); + assert_eq!( + minute, + time_period_to_duration(time, "minutes").num_seconds() + ); + assert_eq!(time, time_period_to_duration(time, "seconds").num_seconds()); + } + #[test] // This test inserts an rss feed to your `XDG_DATA/hammond/hammond.db` so we make it explicit // to run it.