hammond-gtk: Change utils::get_pixbuf_from_path function to return a Result.

This commit is contained in:
Jordan Petridis 2018-02-06 20:56:55 +02:00
parent c6e426cbac
commit 7ed1cd8b26
No known key found for this signature in database
GPG Key ID: CEABAD9F5683B9A6
4 changed files with 54 additions and 31 deletions

View File

@ -73,24 +73,25 @@ lazy_static! {
// GObjects do not implement Send trait, so SendCell is a way around that. // GObjects do not implement Send trait, so SendCell is a way around that.
// Also lazy_static requires Sync trait, so that's what the mutexes are. // Also lazy_static requires Sync trait, so that's what the mutexes are.
// TODO: maybe use something that would just scale to requested size? // TODO: maybe use something that would just scale to requested size?
pub fn get_pixbuf_from_path(pd: &PodcastCoverQuery, size: u32) -> Option<Pixbuf> { pub fn get_pixbuf_from_path(pd: &PodcastCoverQuery, size: u32) -> Result<Pixbuf, Error> {
{ {
let hashmap = CACHED_PIXBUFS.read().unwrap(); let hashmap = CACHED_PIXBUFS
let res = hashmap.get(&(pd.id(), size)); .read()
if let Some(px) = res { .map_err(|_| format_err!("Failed to get a lock on the pixbuf cache mutex."))?;
let m = px.lock().unwrap(); if let Some(px) = hashmap.get(&(pd.id(), size)) {
return Some(m.clone().into_inner()); let m = px.lock()
.map_err(|_| format_err!("Failed to lock pixbuf mutex."))?;
return Ok(m.clone().into_inner());
} }
} }
let img_path = downloader::cache_image(pd).ok()?; let img_path = downloader::cache_image(pd)?;
let px = Pixbuf::new_from_file_at_scale(&img_path, size as i32, size as i32, true).ok(); let px = Pixbuf::new_from_file_at_scale(&img_path, size as i32, size as i32, true)?;
if let Some(px) = px { let mut hashmap = CACHED_PIXBUFS
let mut hashmap = CACHED_PIXBUFS.write().unwrap(); .write()
.map_err(|_| format_err!("Failed to lock pixbuf mutex."))?;
hashmap.insert((pd.id(), size), Mutex::new(SendCell::new(px.clone()))); hashmap.insert((pd.id(), size), Mutex::new(SendCell::new(px.clone())));
return Some(px); Ok(px)
}
None
} }
#[cfg(test)] #[cfg(test)]
@ -114,6 +115,6 @@ mod tests {
// Get the Podcast // Get the Podcast
let pd = dbqueries::get_podcast_from_source_id(sid).unwrap(); let pd = dbqueries::get_podcast_from_source_id(sid).unwrap();
let pxbuf = get_pixbuf_from_path(&pd.into(), 256); let pxbuf = get_pixbuf_from_path(&pd.into(), 256);
assert!(pxbuf.is_some()); assert!(pxbuf.is_ok());
} }
} }

View File

@ -1,4 +1,5 @@
use chrono::prelude::*; use chrono::prelude::*;
use failure::Error;
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
@ -202,18 +203,30 @@ impl EpisodesViewWidget {
gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui"); gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui");
let container: gtk::Box = builder.get_object("container").unwrap(); let container: gtk::Box = builder.get_object("container").unwrap();
let image: gtk::Image = builder.get_object("cover").unwrap(); let image: gtk::Image = builder.get_object("cover").unwrap();
if let Ok(pd) = dbqueries::get_podcast_cover_from_id(episode.podcast_id()) {
get_pixbuf_from_path(&pd, 64).map(|img| image.set_from_pixbuf(&img));
}
let ep = EpisodeWidget::new(episode, sender.clone()); let ep = EpisodeWidget::new(episode, sender.clone());
container.pack_start(&ep.container, true, true, 6);
EpisodesViewWidget { let view = EpisodesViewWidget {
container, container,
image, image,
episode: ep.container, episode: ep.container,
} };
view.init(episode);
view
}
fn init(&self, episode: &mut EpisodeWidgetQuery) {
if let Err(err) = self.set_cover(episode) {
error!("Failed to set a cover: {}", err)
}
self.container.pack_start(&self.episode, true, true, 6);
}
fn set_cover(&self, episode: &mut EpisodeWidgetQuery) -> Result<(), Error> {
let pd = dbqueries::get_podcast_cover_from_id(episode.podcast_id())?;
let img = get_pixbuf_from_path(&pd, 64)?;
self.image.set_from_pixbuf(&img);
Ok(())
} }
} }

View File

@ -1,3 +1,4 @@
use failure::Error;
use gtk; use gtk;
use gtk::prelude::*; use gtk::prelude::*;
@ -114,11 +115,16 @@ impl ShowsChild {
fn init(&self, pd: &Podcast) { fn init(&self, pd: &Podcast) {
self.container.set_tooltip_text(pd.title()); self.container.set_tooltip_text(pd.title());
let cover = get_pixbuf_from_path(&pd.clone().into(), 256); if let Err(err) = self.set_cover(pd) {
if let Some(img) = cover { error!("Failed to set a cover: {}", err)
self.cover.set_from_pixbuf(&img); }
};
WidgetExt::set_name(&self.child, &pd.id().to_string()); WidgetExt::set_name(&self.child, &pd.id().to_string());
} }
fn set_cover(&self, pd: &Podcast) -> Result<(), Error> {
let image = get_pixbuf_from_path(&pd.clone().into(), 256)?;
self.cover.set_from_pixbuf(&image);
Ok(())
}
} }

View File

@ -72,9 +72,12 @@ impl ShowWidget {
})); }));
self.setup_listbox(pd, sender.clone()); self.setup_listbox(pd, sender.clone());
self.set_cover(pd);
self.set_description(pd.description()); self.set_description(pd.description());
if let Err(err) = self.set_cover(pd) {
error!("Failed to set a cover: {}", err)
}
let link = pd.link().to_owned(); let link = pd.link().to_owned();
self.link.set_tooltip_text(Some(link.as_str())); self.link.set_tooltip_text(Some(link.as_str()));
self.link.connect_clicked(move |_| { self.link.connect_clicked(move |_| {
@ -91,11 +94,11 @@ impl ShowWidget {
let listbox = episodes_listbox(pd, sender.clone()); let listbox = episodes_listbox(pd, sender.clone());
listbox.ok().map(|l| self.episodes.add(&l)); listbox.ok().map(|l| self.episodes.add(&l));
} }
/// Set the show cover. /// Set the show cover.
fn set_cover(&self, pd: &Podcast) { fn set_cover(&self, pd: &Podcast) -> Result<(), Error> {
let img = get_pixbuf_from_path(&pd.clone().into(), 128); let image = get_pixbuf_from_path(&pd.clone().into(), 128)?;
img.map(|i| self.cover.set_from_pixbuf(&i)); self.cover.set_from_pixbuf(&image);
Ok(())
} }
/// Set the descripton text. /// Set the descripton text.