From 86019710a1ca139158ea1388672c471413281677 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 21 Oct 2017 08:05:00 +0300 Subject: [PATCH] Episode widgets update upon download. --- hammond-downloader/src/downloader.rs | 18 ++++++++++++- hammond-gtk/src/views/podcasts_view.rs | 15 +++-------- hammond-gtk/src/widgets/episode.rs | 36 ++++++++++++++++---------- hammond-gtk/src/widgets/podcast.rs | 27 +++++++++++++++++++ 4 files changed, 70 insertions(+), 26 deletions(-) diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 9e6198b..4fb84e9 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -5,6 +5,7 @@ use diesel::prelude::*; use std::fs::{rename, DirBuilder, File}; use std::io::{BufWriter, Read, Write}; use std::path::Path; +use std::thread; use errors::*; use hammond_data::dbqueries; @@ -114,11 +115,26 @@ pub fn get_episode(connection: &SqliteConnection, ep: &mut Episode, dl_folder: & // TODO: Check if its a valid path let dlpath = format!("{}/{}.{}", dl_folder, ep.title().unwrap().to_owned(), ext); // info!("Downloading {:?} into: {}", y.title(), dlpath); - download_to(&dlpath, ep.uri())?; // If download succedes set episode local_uri to dlpath. + // This should be at the end after download is finished, + // but its handy atm while the gtk client doesnt yet have custom signals. ep.set_local_uri(Some(&dlpath)); ep.save_changes::(connection)?; + + let uri = ep.uri().to_owned(); + + // This would not be needed in general but I want to be able to block the + // a higher order thread in src/widgets/episode.rs epsode. + thread::spawn(move || { + let res = download_to(&dlpath, uri.as_str()); + if let Err(err) = res { + error!("Something whent wrong while downloading."); + error!("Error: {}", err); + } else { + info!("Download of {} finished.", uri); + } + }); Ok(()) } diff --git a/hammond-gtk/src/views/podcasts_view.rs b/hammond-gtk/src/views/podcasts_view.rs index 7690ed9..94b5a0d 100644 --- a/hammond-gtk/src/views/podcasts_view.rs +++ b/hammond-gtk/src/views/podcasts_view.rs @@ -3,9 +3,7 @@ use gtk; use gtk::prelude::*; use gtk::StackTransitionType; -use gdk_pixbuf::Pixbuf; -use hammond_downloader::downloader; use diesel::prelude::SqliteConnection; use std::sync::{Arc, Mutex}; @@ -44,22 +42,14 @@ pub fn populate_podcasts_flowbox( let description = pd_model.get_value(&iter, 2).get::(); let image_uri = pd_model.get_value(&iter, 4).get::(); - let imgpath = downloader::cache_image(&title, image_uri.as_ref().map(|s| s.as_str())); - let pixbuf = if let Some(i) = imgpath { - Pixbuf::new_from_file_at_scale(&i, 200, 200, true).ok() - } else { - None - }; - + let pixbuf = get_pixbuf_from_path(image_uri.as_ref().map(|s| s.as_str()), &title); let f = create_flowbox_child(&title, pixbuf.clone()); let stack_clone = stack.clone(); let db_clone = db.clone(); f.connect_activate(move |_| { - let pdw = stack_clone.get_child_by_name("pdw").unwrap(); - stack_clone.remove(&pdw); - + let old = stack_clone.get_child_by_name("pdw").unwrap(); let pdw = podcast_widget( &db_clone.clone(), Some(title.as_str()), @@ -67,6 +57,7 @@ pub fn populate_podcasts_flowbox( pixbuf.clone(), ); + stack_clone.remove(&old); stack_clone.add_named(&pdw, "pdw"); stack_clone.set_visible_child(&pdw); println!("Hello World!, child activated"); diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 599cdad..b4cc355 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -13,9 +13,11 @@ use dissolve::strip_html_tags; use std::thread; use std::sync::{Arc, Mutex}; +use std::path::Path; use gtk; use gtk::prelude::*; +use gtk::ContainerExt; // use utils; @@ -55,36 +57,44 @@ fn epidose_widget( } if episode.local_uri().is_some() { - dl_button.hide(); - play_button.show(); let uri = episode.local_uri().unwrap().to_owned(); - play_button.connect_clicked(move |_| { - let e = open::that(&uri); - if e.is_err() { - error!("Error while trying to open: {}", uri); - } - }); + + if Path::new(&uri).exists() { + dl_button.hide(); + play_button.show(); + play_button.connect_clicked(move |_| { + let e = open::that(&uri); + if e.is_err() { + error!("Error while trying to open: {}", uri); + } + }); + } } let pd_title_cloned = pd_title.to_owned(); let db = connection.clone(); let ep_clone = episode.clone(); - dl_button.connect_clicked(move |_| { + let play_button_clone = play_button.clone(); + dl_button.connect_clicked(move |dl| { // ugly hack to bypass the borrowchecker let pd_title = pd_title_cloned.clone(); - let db = db.clone(); + let db_clone = db.clone(); let mut ep_clone = ep_clone.clone(); + // TODO: emit a signal and show notification when dl is finished and block play_bttn till + // then. thread::spawn(move || { - let dl_fold = downloader::get_dl_folder(&pd_title).unwrap(); - let tempdb = db.lock().unwrap(); + let dl_fold = downloader::get_dl_folder(&pd_title.clone()).unwrap(); + let tempdb = db_clone.lock().unwrap(); let e = downloader::get_episode(&tempdb, &mut ep_clone, dl_fold.as_str()); + drop(tempdb); if let Err(err) = e { error!("Error while trying to download: {}", ep_clone.uri()); error!("Error: {}", err); }; - // TODO: emit a signal in order to update the podcast widget. }); + dl.hide(); + play_button_clone.show(); }); ep diff --git a/hammond-gtk/src/widgets/podcast.rs b/hammond-gtk/src/widgets/podcast.rs index 037617b..8f09a97 100644 --- a/hammond-gtk/src/widgets/podcast.rs +++ b/hammond-gtk/src/widgets/podcast.rs @@ -4,6 +4,8 @@ use gdk_pixbuf::Pixbuf; use diesel::prelude::SqliteConnection; use hammond_data::dbqueries; +use hammond_data::models::Podcast; +use hammond_downloader::downloader; use std::sync::{Arc, Mutex}; @@ -70,6 +72,7 @@ pub fn create_flowbox_child(title: &str, cover: Option) -> gtk::FlowBoxC fbc } +// Figure if its better to completly ditch stores and just create the views from diesel models. pub fn podcast_liststore(connection: &SqliteConnection) -> gtk::ListStore { let builder = include_str!("../../gtk/podcast_widget.ui"); let builder = gtk::Builder::new_from_string(builder); @@ -94,3 +97,27 @@ pub fn podcast_liststore(connection: &SqliteConnection) -> gtk::ListStore { podcast_model } + +// pub fn update_podcast_widget(db: &Arc>, stack: >k::Stack, pd: +// &Podcast){ +// let old = stack.get_child_by_name("pdw").unwrap(); +// let pdw = pd_widget_from_diesel_model(&db.clone(), pd, &stack.clone()); + +// stack.remove(&old); +// stack.add_named(&pdw, "pdw"); +// stack.set_visible_child_full("pdw", StackTransitionType::None); +// } + +pub fn pd_widget_from_diesel_model(db: &Arc>, pd: &Podcast) -> gtk::Box { + let img = get_pixbuf_from_path(pd.image_uri(), pd.title()); + podcast_widget(&db.clone(), Some(pd.title()), Some(pd.description()), img) +} + +pub fn get_pixbuf_from_path(img_path: Option<&str>, pd_title: &str) -> Option { + let img_path = downloader::cache_image(pd_title, img_path); + if let Some(i) = img_path { + Pixbuf::new_from_file_at_scale(&i, 200, 200, true).ok() + } else { + None + } +}