From 31ad416c25eb156cf336d580c21a753fb6e0fabd Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 17 Oct 2017 22:26:59 +0300 Subject: [PATCH] Prototype of an Episode List widget. --- hammond-data/src/feedparser.rs | 24 +++---- hammond-gtk/gtk/EpisodeWidget.ui | 109 ++++++++++++++++++++++++++++++ hammond-gtk/gtk/pd_fb_child.ui | 1 + hammond-gtk/gtk/podcast_widget.ui | 23 +++---- hammond-gtk/src/main.rs | 56 ++++++++++++++- 5 files changed, 185 insertions(+), 28 deletions(-) create mode 100644 hammond-gtk/gtk/EpisodeWidget.ui diff --git a/hammond-data/src/feedparser.rs b/hammond-data/src/feedparser.rs index e32fee1..1f84748 100644 --- a/hammond-data/src/feedparser.rs +++ b/hammond-data/src/feedparser.rs @@ -7,9 +7,9 @@ use errors::*; // TODO: look into how bad-utf8 is handled in rss crate, // and figure if there is a need for checking before parsing. pub fn parse_podcast(chan: &Channel, source_id: i32) -> Result { - let title = chan.title().to_owned(); + let title = chan.title().trim().to_owned(); let link = chan.link().to_owned(); - let description = chan.description().to_owned(); + let description = chan.description().trim().to_owned(); // Some feeds miss baseurl and/or http:// // TODO: Sanitize the url, // could also be reuse to sanitize the new-url gui entrybox. @@ -26,12 +26,12 @@ pub fn parse_podcast(chan: &Channel, source_id: i32) -> Result Result { - let title = item.title(); - let description = item.description(); - let guid = item.guid().map(|x| x.value()); + let title = item.title().map(|s| s.trim()); + let description = item.description().map(|s| s.trim()); + let guid = item.guid().map(|x| x.value().trim()); let local_uri = None; - let mut uri = item.enclosure().map(|x| x.url()); + let mut uri = item.enclosure().map(|x| x.url().trim()); if uri == None { uri = item.link(); } @@ -200,10 +200,8 @@ mod tests { let channel = Channel::read_from(BufReader::new(file)).unwrap(); let firstitem = channel.items().first().unwrap(); - let descr = "\n \ -

A reporter finds that homes meant to replace New York’s troubled \ - psychiatric hospitals might be just as bad.

\ - \n \n "; + let descr = "

A reporter finds that homes meant to replace New York’s troubled \ + psychiatric hospitals might be just as bad.

"; let i = parse_episode(&firstitem, 0).unwrap(); assert_eq!( @@ -231,11 +229,9 @@ mod tests { let second = channel.items().iter().nth(1).unwrap(); let i2 = parse_episode(&second, 0).unwrap(); - let descr2 = "\n \ -

Jonathan Allen and Amie Parnes didn’t know their \ + let descr2 = "

Jonathan Allen and Amie Parnes didn’t know their \ book would be called ‘Shattered,’ or that their extraordinary access would \ - let them chronicle the mounting signs of a doomed campaign.

\ - \n \n "; + let them chronicle the mounting signs of a doomed campaign.

"; assert_eq!( i2.title, diff --git a/hammond-gtk/gtk/EpisodeWidget.ui b/hammond-gtk/gtk/EpisodeWidget.ui new file mode 100644 index 0000000..68327d3 --- /dev/null +++ b/hammond-gtk/gtk/EpisodeWidget.ui @@ -0,0 +1,109 @@ + + + + + + 100 + 25 + True + False + 5 + 5 + 5 + + + True + False + vertical + + + True + False + center + center + True + True + end + 1 + + + False + False + 0 + + + + + True + False + center + center + True + True + True + end + 3 + + + False + False + 1 + + + + + True + True + 5 + 0 + + + + + True + True + True + center + 5 + 5 + True + + + True + False + gtk-save + + + + + False + False + 5 + 1 + + + + + True + True + True + center + 5 + 5 + + + True + False + gtk-media-play + + + + + False + False + 5 + 2 + + + + diff --git a/hammond-gtk/gtk/pd_fb_child.ui b/hammond-gtk/gtk/pd_fb_child.ui index 5c3c70e..76ce153 100644 --- a/hammond-gtk/gtk/pd_fb_child.ui +++ b/hammond-gtk/gtk/pd_fb_child.ui @@ -41,6 +41,7 @@ True False label + True False diff --git a/hammond-gtk/gtk/podcast_widget.ui b/hammond-gtk/gtk/podcast_widget.ui index a61286b..37302be 100644 --- a/hammond-gtk/gtk/podcast_widget.ui +++ b/hammond-gtk/gtk/podcast_widget.ui @@ -9,18 +9,18 @@ True False - end + center + center 32 32 32 32 64 32 - True - 100 - 100 + 50 + 50 True False center @@ -52,18 +52,14 @@ center start vertical - 3 + 2 True False center - center - middle - - - - + True + end False @@ -75,9 +71,12 @@ True False + True True + word-char True end + 30 5 @@ -119,8 +118,8 @@ 400 True False - start True + True none diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 2b460f7..87fcdaf 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -15,6 +15,7 @@ extern crate loggerv; use log::LogLevel; use diesel::prelude::*; use hammond_data::dbqueries; +use std::rc; use gtk::prelude::*; use gio::ApplicationExt; @@ -73,6 +74,7 @@ fn create_and_fill_list_store( } fn podcast_widget( + connection: &SqliteConnection, title: Option<&str>, description: Option<&str>, image: Option, @@ -85,9 +87,12 @@ fn podcast_widget( let cover: gtk::Image = pd_widget_buidler.get_object("cover").unwrap(); let title_label: gtk::Label = pd_widget_buidler.get_object("title_label").unwrap(); let desc_label: gtk::Label = pd_widget_buidler.get_object("description_label").unwrap(); + let view: gtk::Viewport = pd_widget_buidler.get_object("view").unwrap(); if let Some(t) = title { title_label.set_text(t); + let listbox = episodes_listbox(connection, t); + view.add(&listbox); } if let Some(d) = description { @@ -102,6 +107,50 @@ fn podcast_widget( pd_widget } +fn epidose_widget(title: Option<&str>, description: Option<&str>) -> gtk::Box { + // This is just a prototype and will be reworked probably. + let builder = include_str!("../gtk/EpisodeWidget.ui"); + let builder = gtk::Builder::new_from_string(builder); + + let ep: gtk::Box = builder.get_object("episode_box").unwrap(); + let _dl_button: gtk::Button = builder.get_object("download_button").unwrap(); + let _play_button: gtk::Button = builder.get_object("play_button").unwrap(); + + let title_label: gtk::Label = builder.get_object("title_label").unwrap(); + let desc_label: gtk::Label = builder.get_object("desc_label").unwrap(); + + title_label.set_xalign(0.0); + desc_label.set_xalign(0.0); + + if let Some(t) = title { + title_label.set_text(t); + } + + if let Some(d) = description { + desc_label.set_text(d); + } + + ep +} + +fn episodes_listbox(connection: &SqliteConnection, pd_title: &str) -> gtk::ListBox { + let pd = dbqueries::load_podcast(connection, pd_title).unwrap(); + let episodes = dbqueries::get_pd_episodes(connection, &pd).unwrap(); + + let list = gtk::ListBox::new(); + episodes.iter().for_each(|ep| { + let w = epidose_widget(ep.title(), ep.description()); + list.add(&w) + }); + + list.set_vexpand(true); + list.set_hexpand(true); + list.set_visible(true); + list +} + +// I am sorry about the spaghetti code. +// Gonna clean it up when the GUI is a bit usuable. fn build_ui() { let glade_src = include_str!("../gtk/foo.ui"); let header_src = include_str!("../gtk/headerbar.ui"); @@ -113,7 +162,8 @@ fn build_ui() { // Get the Stack let stack: gtk::Stack = builder.get_object("stack1").unwrap(); - let pd_widget = podcast_widget(None, None, None); + let db = hammond_data::establish_connection(); + let pd_widget = podcast_widget(&db, None, None, None); stack.add_named(&pd_widget, "pdw"); // Get the headerbar let header: gtk::HeaderBar = header_build.get_object("headerbar1").unwrap(); @@ -166,11 +216,11 @@ fn build_ui() { hammond_data::index_feed::index_loop(db, false).unwrap(); }); - let db = hammond_data::establish_connection(); // let pd_model = create_and_fill_tree_store(&db, &builder); let pd_model = create_and_fill_list_store(&db, &builder); let iter = pd_model.get_iter_first().unwrap(); + let db = rc::Rc::new(db); // this will iterate over the episodes. // let iter = pd_model.iter_children(&iter).unwrap(); loop { @@ -191,10 +241,12 @@ fn build_ui() { 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 pdw = podcast_widget( + &db_clone, Some(title.as_str()), Some(description.as_str()), pixbuf.clone(),