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 @@
+
+
+
+
+
+
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 @@
TrueFalselabel
+ TrueFalse
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 @@
TrueFalse
- end
+ center
+ center323232326432
- True
- 100
- 100
+ 50
+ 50TrueFalsecenter
@@ -52,18 +52,14 @@
centerstartvertical
- 3
+ 2TrueFalsecenter
- center
- middle
-
-
-
-
+ True
+ endFalse
@@ -75,9 +71,12 @@
TrueFalse
+ TrueTrue
+ word-charTrueend
+ 305
@@ -119,8 +118,8 @@
400TrueFalse
- startTrue
+ Truenone
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(),