diff --git a/TODO.md b/TODO.md index 06f9ef4..3e69550 100644 --- a/TODO.md +++ b/TODO.md @@ -35,10 +35,11 @@ **DB changes:** -- [ ] episodes: add watched field -- [ ] Mark episodes/podcast for archival +- [x] episodes: add watched field - [x] Podcast deletion -- [ ] Download cleaner +- [x] Download cleaner +- [ ] Discuss and decide when to schedule the download cleaner. +- [ ] Mark episodes/podcast for archival - [ ] Mark stuff as Favorite. Maybe auto-archive favorites? - [ ] New episode notifier on podcast_flowbox_child, like the one vocal has diff --git a/hammond-data/src/dbcheckup.rs b/hammond-data/src/dbcheckup.rs index e41fa7e..1beb528 100644 --- a/hammond-data/src/dbcheckup.rs +++ b/hammond-data/src/dbcheckup.rs @@ -10,22 +10,20 @@ use std::path::Path; use std::fs; // TODO: Write unit test. -pub fn download_checker(db: Database) -> Result<()> { +fn download_checker(db: &Database) -> Result<()> { let mut episodes = { let tempdb = db.lock().unwrap(); dbqueries::get_downloaded_episodes(&tempdb)? }; episodes.par_iter_mut().for_each(|ep| { - if ep.local_uri().is_some() { - if !Path::new(ep.local_uri().unwrap()).exists() { - ep.set_local_uri(None); - let res = ep.save(&db.clone()); - if let Err(err) = res { - error!("Error while trying to update episode: {:#?}", ep); - error!("Error: {}", err); - }; - } + if !Path::new(ep.local_uri().unwrap()).exists() { + ep.set_local_uri(None); + let res = ep.save(&db.clone()); + if let Err(err) = res { + error!("Error while trying to update episode: {:#?}", ep); + error!("Error: {}", err); + }; } }); @@ -33,7 +31,7 @@ pub fn download_checker(db: Database) -> Result<()> { } // TODO: Write unit test. -pub fn watched_cleaner(db: &Database) -> Result<()> { +fn watched_cleaner(db: &Database) -> Result<()> { let mut episodes = { let tempdb = db.lock().unwrap(); dbqueries::get_watched_episodes(&tempdb)? @@ -46,7 +44,7 @@ pub fn watched_cleaner(db: &Database) -> Result<()> { // TODO: expose a config and a user set option. let limit = watched + 172_800; // add 2days in seconds if now_utc > limit { - let e = delete_local_content(db, &mut ep); + let e = delete_local_content(&db.clone(), &mut ep); if let Err(err) = e { error!("Error while trying to delete file: {:?}", ep.local_uri()); error!("Error: {}", err); @@ -79,3 +77,16 @@ pub fn delete_local_content(db: &Database, ep: &mut Episode) -> Result<()> { } Ok(()) } + +pub fn set_watched(db: &Database, ep: &mut Episode) -> Result<()> { + let epoch = Utc::now().timestamp() as i32; + ep.set_watched(Some(epoch)); + ep.save(db)?; + Ok(()) +} + +pub fn run(db: &Database) -> Result<()> { + download_checker(db)?; + watched_cleaner(db)?; + Ok(()) +} diff --git a/hammond-data/src/models.rs b/hammond-data/src/models.rs index 267ffa1..8eb3ff8 100644 --- a/hammond-data/src/models.rs +++ b/hammond-data/src/models.rs @@ -8,6 +8,7 @@ use errors::*; #[derive(Queryable, Identifiable, AsChangeset, Associations)] #[table_name = "episode"] +#[changeset_options(treat_none_as_null = "true")] #[belongs_to(Podcast, foreign_key = "podcast_id")] #[derive(Debug, Clone)] pub struct Episode { @@ -113,6 +114,7 @@ impl Episode { #[derive(Queryable, Identifiable, AsChangeset, Associations)] #[belongs_to(Source, foreign_key = "source_id")] +#[changeset_options(treat_none_as_null = "true")] #[table_name = "podcast"] #[derive(Debug, Clone)] pub struct Podcast { @@ -170,6 +172,7 @@ impl Podcast { #[derive(Queryable, Identifiable, AsChangeset)] #[table_name = "source"] +#[changeset_options(treat_none_as_null = "true")] #[derive(Debug, Clone)] pub struct Source { id: i32, diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index a089203..61123d2 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -15,11 +15,12 @@ extern crate open; use log::LogLevel; use hammond_data::index_feed; +use hammond_data::dbcheckup; use std::sync::{Arc, Mutex}; use gtk::prelude::*; -use gio::ApplicationExt; +use gio::{ActionMapExt, ApplicationExt, MenuExt, SimpleActionExt}; mod views; mod widgets; @@ -36,6 +37,11 @@ THIS IS STILL A PROTOTYPE. fn build_ui(app: >k::Application) { let db = Arc::new(Mutex::new(hammond_data::establish_connection())); + let menu = gio::Menu::new(); + menu.append("Quit", "app.quit"); + menu.append("Checkup", "app.check"); + app.set_app_menu(&menu); + // Get the main window let window = gtk::ApplicationWindow::new(app); window.set_default_size(1050, 600); @@ -48,10 +54,24 @@ fn build_ui(app: >k::Application) { Inhibit(false) }); + let quit = gio::SimpleAction::new("quit", None); + let window2 = window.clone(); + quit.connect_activate(move |_, _| { + window2.destroy(); + }); + app.add_action(&quit); + + let db2 = db.clone(); + let check = gio::SimpleAction::new("check", None); + check.connect_activate(move |_, _| { + let _ = dbcheckup::run(&db2); + }); + app.add_action(&check); + // Get the headerbar let header = headerbar::get_headerbar(&db, &stack); - // TODO: add delay, cause else theres lock contention for the db obj. + // TODO: add delay, cause else there's lock contention for the db obj. // utils::refresh_db(db.clone(), stack.clone()); window.set_titlebar(&header); diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 90001f7..d816e55 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -4,7 +4,7 @@ use hammond_data::dbqueries; use hammond_data::models::Episode; use hammond_downloader::downloader; use hammond_data::index_feed::Database; -use hammond_data::dbcheckup::delete_local_content; +use hammond_data::dbcheckup::*; use dissolve::strip_html_tags; @@ -81,8 +81,9 @@ fn epidose_widget(db: &Database, episode: &mut Episode, pd_title: &str) -> gtk:: delete_button.show(); } - play_button.connect_clicked(clone!(episode, db => move |_| { + play_button.connect_clicked(clone!(db, episode => move |_| { on_play_bttn_clicked(&db, episode.id()); + let _ = set_watched(&db, &mut episode.clone()); })); delete_button.connect_clicked(