From d8281c70a52bd03bc349e4525cf91c081bf75b17 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 10 Dec 2017 06:11:03 +0200 Subject: [PATCH 001/278] Better naming of a dbquery function. --- hammond-data/src/dbqueries.rs | 7 +------ hammond-data/src/models/insertables.rs | 5 ++--- hammond-data/src/utils.rs | 14 ++++++-------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index f83bc0b..391ec6e 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -155,12 +155,7 @@ pub fn get_podcast_from_source_id(sid: i32) -> Result { .get_result::(&*con)?) } -// TODO: unhack me -pub fn get_episode_from_new_episode( - con: &SqliteConnection, - title_: &str, - pid: i32, -) -> QueryResult { +pub fn get_episode_from_pk(con: &SqliteConnection, title_: &str, pid: i32) -> QueryResult { use schema::episode::dsl::*; episode diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index e63f64d..c847a2e 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -193,7 +193,7 @@ impl NewEpisode { // TODO: Refactor into batch indexes instead. pub(crate) fn into_episode(self, con: &SqliteConnection) -> Result { self.index(con)?; - Ok(dbqueries::get_episode_from_new_episode( + Ok(dbqueries::get_episode_from_pk( con, &self.title, self.podcast_id, @@ -201,8 +201,7 @@ impl NewEpisode { } pub(crate) fn index(&self, con: &SqliteConnection) -> QueryResult<()> { - // TODO: Change me - let ep = dbqueries::get_episode_from_new_episode(con, &self.title, self.podcast_id); + let ep = dbqueries::get_episode_from_pk(con, &self.title, self.podcast_id); match ep { Ok(foo) => { diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index 42a6af7..fb9fe1e 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -162,10 +162,8 @@ mod tests { .into_episode(&con) .unwrap(); - let mut ep1 = - dbqueries::get_episode_from_new_episode(&con, n1.title(), n1.podcast_id()).unwrap(); - let mut ep2 = - dbqueries::get_episode_from_new_episode(&con, n2.title(), n2.podcast_id()).unwrap(); + let mut ep1 = dbqueries::get_episode_from_pk(&con, n1.title(), n1.podcast_id()).unwrap(); + let mut ep2 = dbqueries::get_episode_from_pk(&con, n2.title(), n2.podcast_id()).unwrap(); ep1.set_local_uri(Some(valid_path.to_str().unwrap())); ep2.set_local_uri(Some(bad_path.to_str().unwrap())); @@ -192,7 +190,7 @@ mod tests { let mut episode = { let db = connection(); let con = db.get().unwrap(); - dbqueries::get_episode_from_new_episode(&con, "bar_baz", 1).unwrap() + dbqueries::get_episode_from_pk(&con, "bar_baz", 1).unwrap() }; checker_helper(&mut episode); @@ -205,7 +203,7 @@ mod tests { let mut episode = { let db = connection(); let con = db.get().unwrap(); - dbqueries::get_episode_from_new_episode(&con, "foo_bar", 0).unwrap() + dbqueries::get_episode_from_pk(&con, "foo_bar", 0).unwrap() }; let valid_path = episode.local_uri().unwrap().to_owned(); @@ -219,7 +217,7 @@ mod tests { let mut episode = { let db = connection(); let con = db.get().unwrap(); - dbqueries::get_episode_from_new_episode(&con, "foo_bar", 0).unwrap() + dbqueries::get_episode_from_pk(&con, "foo_bar", 0).unwrap() }; let now_utc = Utc::now().timestamp() as i32; // let limit = now_utc - 172_800; @@ -239,7 +237,7 @@ mod tests { let mut episode = { let db = connection(); let con = db.get().unwrap(); - dbqueries::get_episode_from_new_episode(&con, "foo_bar", 0).unwrap() + dbqueries::get_episode_from_pk(&con, "foo_bar", 0).unwrap() }; let now_utc = Utc::now().timestamp() as i32; // limit = 172_800; From 851be1fcfbcf651eb948c428f0ef01ef6d850ac5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 10 Dec 2017 06:47:10 +0200 Subject: [PATCH 002/278] Schema hotfix. --- .../migrations/2017-12-09-125835_change_episode_pk/down.sql | 6 +++++- .../migrations/2017-12-09-125835_change_episode_pk/up.sql | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hammond-data/migrations/2017-12-09-125835_change_episode_pk/down.sql b/hammond-data/migrations/2017-12-09-125835_change_episode_pk/down.sql index 01f66ff..866e08f 100644 --- a/hammond-data/migrations/2017-12-09-125835_change_episode_pk/down.sql +++ b/hammond-data/migrations/2017-12-09-125835_change_episode_pk/down.sql @@ -16,4 +16,8 @@ CREATE TABLE episode ( podcast_id INTEGER NOT NULL ); -INSERT INTO episode SELECT * FROM old_table; \ No newline at end of file +INSERT INTO episode (title, uri, local_uri, description, published_date, epoch, length, guid, played, favorite, archive, podcast_id) +SELECT title, uri, local_uri, description, published_date, epoch, length, guid, played, favorite, archive, podcast_id +FROM old_table; + +Drop table old_table; \ No newline at end of file diff --git a/hammond-data/migrations/2017-12-09-125835_change_episode_pk/up.sql b/hammond-data/migrations/2017-12-09-125835_change_episode_pk/up.sql index cbe40dd..2a8d1c0 100644 --- a/hammond-data/migrations/2017-12-09-125835_change_episode_pk/up.sql +++ b/hammond-data/migrations/2017-12-09-125835_change_episode_pk/up.sql @@ -2,7 +2,7 @@ ALTER TABLE episode RENAME TO old_table; CREATE TABLE episode ( title TEXT NOT NULL, - uri TEXT UNIQUE, + uri TEXT, local_uri TEXT, description TEXT, published_date TEXT, From e127941d8a59f33a2e4b6fd31780841baa869f9b Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 10 Dec 2017 09:53:05 +0200 Subject: [PATCH 003/278] Initial stackswitcher addition into the headerbar. --- hammond-gtk/resources/gtk/headerbar.ui | 10 +++++++++- hammond-gtk/src/content.rs | 14 ++++++++------ hammond-gtk/src/headerbar.rs | 6 ++++++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index d28c2ae..238c0a0 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -112,7 +112,6 @@ True False - Hammond False True @@ -131,6 +130,15 @@ + + + + True + False + center + True + True + 3 diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 249f589..a6c5764 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -24,8 +24,8 @@ impl Content { let podcasts = PopulatedView::new(); let empty = EmptyView::new(); - stack.add_named(&widget.container, "widget"); - stack.add_named(&podcasts.container, "podcasts"); + stack.add_titled(&widget.container, "widget", "Episodes"); + stack.add_titled(&podcasts.container, "podcasts", "Shows"); stack.add_named(&empty.container, "empty"); Content { @@ -58,7 +58,8 @@ impl Content { self.stack.remove(&old); self.widget = pdw; - self.stack.add_named(&self.widget.container, "widget"); + self.stack + .add_titled(&self.widget.container, "widget", "Episodes"); self.stack.set_visible_child_name(&vis); old.destroy(); } @@ -69,7 +70,8 @@ impl Content { self.stack.remove(&old); self.podcasts = pop; - self.stack.add_named(&self.podcasts.container, "podcasts"); + self.stack + .add_titled(&self.podcasts.container, "podcasts", "Shows"); self.stack.set_visible_child_name(&vis); old.destroy(); } @@ -200,14 +202,14 @@ impl ContentState { fn replace_widget(stack: >k::Stack, pdw: &PodcastWidget) { let old = stack.get_child_by_name("widget").unwrap(); stack.remove(&old); - stack.add_named(&pdw.container, "widget"); + stack.add_titled(&pdw.container, "widget", "Episode"); old.destroy(); } fn replace_podcasts(stack: >k::Stack, pop: &PopulatedView) { let old = stack.get_child_by_name("podcasts").unwrap(); stack.remove(&old); - stack.add_named(&pop.container, "podcasts"); + stack.add_titled(&pop.container, "podcasts", "Shows"); old.destroy(); } diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 20f491e..ef6b34a 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -13,6 +13,7 @@ pub struct Header { home: gtk::Button, refresh: gtk::Button, add_toggle: gtk::MenuButton, + switch: gtk::StackSwitcher, } impl Header { @@ -23,12 +24,16 @@ impl Header { let home: gtk::Button = builder.get_object("homebutton").unwrap(); let refresh: gtk::Button = builder.get_object("refbutton").unwrap(); let add_toggle: gtk::MenuButton = builder.get_object("add-toggle-button").unwrap(); + let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); + switch.set_halign(gtk::Align::Center); + switch.show(); Header { container: header, home, refresh, add_toggle, + switch, } } @@ -44,6 +49,7 @@ impl Header { let add_popover: gtk::Popover = builder.get_object("add-popover").unwrap(); let new_url: gtk::Entry = builder.get_object("new-url").unwrap(); let add_button: gtk::Button = builder.get_object("add-button").unwrap(); + self.switch.set_stack(stack); new_url.connect_changed(move |url| { println!("{:?}", url.get_text()); From 2461dca94d65b1b4bb7094fc7aa9b54186b7b508 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 10 Dec 2017 19:15:32 +0200 Subject: [PATCH 004/278] Remove home button. --- hammond-gtk/resources/gtk/headerbar.ui | 47 ++++++++------------------ hammond-gtk/src/content.rs | 10 ------ hammond-gtk/src/headerbar.rs | 11 +----- 3 files changed, 15 insertions(+), 53 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index 238c0a0..fc17ce5 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -115,21 +115,28 @@ False True - + True True - True + False + Add a new feed center - True - + True False - gtk-home + gtk-add True + 1 + + + 1 + @@ -137,10 +144,9 @@ False center True - True - 3 + 2 @@ -162,32 +168,7 @@ end - 2 - - - - - True - True - False - Add a new feed - center - - - True - False - gtk-add - True - 1 - - - - - - end - 3 + -1 diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index a6c5764..6a190e7 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -259,13 +259,3 @@ pub fn on_podcasts_child_activate(stack: >k::Stack, pd: &Podcast) { update_widget(stack, pd); stack.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft); } - -pub fn on_home_button_activate(stack: >k::Stack) { - let vis = stack.get_visible_child_name().unwrap(); - - if vis != "widget" { - update_podcasts(stack); - } - - show_podcasts(stack); -} diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index ef6b34a..7bcd41e 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -5,12 +5,11 @@ use hammond_data::Source; use hammond_data::utils::url_cleaner; use utils; -use content; +// use content; #[derive(Debug)] pub struct Header { pub container: gtk::HeaderBar, - home: gtk::Button, refresh: gtk::Button, add_toggle: gtk::MenuButton, switch: gtk::StackSwitcher, @@ -21,7 +20,6 @@ impl Header { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let header: gtk::HeaderBar = builder.get_object("headerbar1").unwrap(); - let home: gtk::Button = builder.get_object("homebutton").unwrap(); let refresh: gtk::Button = builder.get_object("refbutton").unwrap(); let add_toggle: gtk::MenuButton = builder.get_object("add-toggle-button").unwrap(); let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); @@ -30,7 +28,6 @@ impl Header { Header { container: header, - home, refresh, add_toggle, switch, @@ -64,12 +61,6 @@ impl Header { })); self.add_toggle.set_popover(&add_popover); - // TODO: make it a back arrow button, that will hide when appropriate, - // and add a StackSwitcher when more views are added. - self.home.connect_clicked(clone!(stack => move |_| { - content::on_home_button_activate(&stack); - })); - // FIXME: There appears to be a memmory leak here. self.refresh.connect_clicked(clone!(stack => move |_| { utils::refresh_feed(&stack, None, None); From e9b6e26f083ba4e3bb00a897deb2de43873ee468 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 10 Dec 2017 23:23:09 +0200 Subject: [PATCH 005/278] yet another attempt at implementing a stack state machine. --- hammond-gtk/src/content.rs | 158 ++++++++++++++++++++++++++++++++++++- 1 file changed, 156 insertions(+), 2 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 6a190e7..be7a491 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -89,8 +89,7 @@ pub trait UpdateView { fn update(&mut self); } -#[derive(Debug)] -pub struct Empty {} +pub struct Empty; #[derive(Debug)] pub struct PodcastsView {} @@ -259,3 +258,158 @@ pub fn on_podcasts_child_activate(stack: >k::Stack, pd: &Podcast) { update_widget(stack, pd); stack.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft); } + +// FIXME: Rename and remove aliases +type ShowsPopulated = PopulatedView; +type ShowsEmpty = EmptyView; +type EpisodesPopulated = PodcastWidget; +type EpisodesEmpty = EmptyView; + +struct Populated; +// struct Empty; +// struct Shows; +// struct Episodes; + +// Thats probably too overengineered +// struct StackStateMachine { +// shows: ShowsMachine, +// episodes: EpisodesMachine, +// stack: gtk::Stack, +// state: T, +// } + +#[derive(Debug, Clone)] +struct ShowsMachine { + populated: ShowsPopulated, + empty: ShowsEmpty, + stack: gtk::Stack, + state: S, +} + +#[derive(Debug)] +struct EpisodesMachine { + populated: EpisodesPopulated, + empty: EpisodesEmpty, + stack: gtk::Stack, + state: S, +} + +// impl Into> for StackStateMachine { +// fn into(self) -> StackStateMachine { +// self.stack.set_visible_child_name("shows"); + +// StackStateMachine { +// shows: self.shows, +// episodes: self.episodes, +// stack: self.stack, +// state: Shows {}, +// } +// } +// } + +// impl Into> for StackStateMachine { +// fn into(self) -> StackStateMachine { +// self.stack.set_visible_child_name("episodes"); + +// StackStateMachine { +// shows: self.shows, +// episodes: self.episodes, +// stack: self.stack, +// state: Episodes {}, +// } +// } +// } + +impl Into> for ShowsMachine { + fn into(self) -> ShowsMachine { + self.stack.set_visible_child_name("populated"); + + ShowsMachine { + populated: self.populated, + empty: self.empty, + stack: self.stack, + state: Populated {}, + } + } +} + +impl Into> for ShowsMachine { + fn into(self) -> ShowsMachine { + self.stack.set_visible_child_name("empty"); + + ShowsMachine { + populated: self.populated, + empty: self.empty, + stack: self.stack, + state: Empty {}, + } + } +} + +impl Into> for EpisodesMachine { + fn into(self) -> EpisodesMachine { + self.stack.set_visible_child_name("populated"); + + EpisodesMachine { + populated: self.populated, + empty: self.empty, + stack: self.stack, + state: Populated {}, + } + } +} + +impl Into> for EpisodesMachine { + fn into(self) -> EpisodesMachine { + self.stack.set_visible_child_name("empty"); + + EpisodesMachine { + populated: self.populated, + empty: self.empty, + stack: self.stack, + state: Empty {}, + } + } +} + +// enum StackStateWrapper { +// Shows(StackStateMachine), +// Episodes(StackStateMachine), +// } + +enum ShowStateWrapper { + Populated(EpisodesMachine), + Empty(EpisodesMachine), +} + +enum EpisodeStateWrapper { + Populated(EpisodesMachine), + Empty(EpisodesMachine), +} + +// impl StackStateWrapper { +// fn switch(mut self) -> Self { +// match self { +// StackStateWrapper::Shows(val) => StackStateWrapper::Episodes(val.into()), +// StackStateWrapper::Episodes(val) => StackStateWrapper::Shows(val.into()) +// } +// } +// } + +impl ShowStateWrapper { + fn switch(self) -> Self { + match self { + ShowStateWrapper::Populated(val) => ShowStateWrapper::Empty(val.into()), + ShowStateWrapper::Empty(val) => ShowStateWrapper::Populated(val.into()), + } + } +} + +impl EpisodeStateWrapper { + fn switch(self) -> Self { + match self { + EpisodeStateWrapper::Populated(val) => EpisodeStateWrapper::Empty(val.into()), + EpisodeStateWrapper::Empty(val) => EpisodeStateWrapper::Populated(val.into()), + } + } +} From ad7f5013f3459b81da88e40d104c5ce8ece26919 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 11 Dec 2017 11:15:54 +0200 Subject: [PATCH 006/278] Extend ShowsMachine functionality. --- hammond-data/src/parser.rs | 1 - hammond-gtk/src/content.rs | 114 ++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 66 deletions(-) diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 1be8064..393ac54 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -81,7 +81,6 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { .unwrap()) } - #[cfg(test)] mod tests { use std::fs::File; diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index be7a491..64063cc 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -97,69 +97,6 @@ pub struct PodcastsView {} #[derive(Debug)] pub struct WidgetsView {} -impl Into> for ContentState { - fn into(self) -> ContentState { - self.content.stack.set_visible_child_name("podcasts"); - - ContentState { - content: self.content, - state: PodcastsView {}, - } - } -} - -impl UpdateView for ContentState { - fn update(&mut self) {} -} - -impl Into> for ContentState { - fn into(self) -> ContentState { - self.content.stack.set_visible_child_name("empty"); - ContentState { - content: self.content, - state: Empty {}, - } - } -} - -impl Into> for ContentState { - fn into(self) -> ContentState { - self.content.stack.set_visible_child_name("widget"); - - ContentState { - content: self.content, - state: WidgetsView {}, - } - } -} - -impl UpdateView for ContentState { - fn update(&mut self) { - let pop = PopulatedView::new_initialized(&self.content.stack); - self.content.replace_podcasts(pop) - } -} - -impl Into> for ContentState { - fn into(self) -> ContentState { - self.content.stack.set_visible_child_name("podcasts"); - ContentState { - content: self.content, - state: PodcastsView {}, - } - } -} - -impl Into> for ContentState { - fn into(self) -> ContentState { - self.content.stack.set_visible_child_name("empty"); - ContentState { - content: self.content, - state: Empty {}, - } - } -} - impl UpdateView for ContentState { fn update(&mut self) { let old = self.content.stack.get_child_by_name("widget").unwrap(); @@ -286,6 +223,20 @@ struct ShowsMachine { state: S, } +impl ShowsMachine { + fn update(&mut self) { + let vis = self.stack.get_visible_child_name().unwrap(); + let old = self.stack.get_child_by_name("shows").unwrap(); + self.stack.remove(&old); + + let pop = ShowsPopulated::new_initialized(&self.stack); + self.populated = pop; + self.stack + .add_titled(&self.populated.container, "shows", "Shows"); + self.stack.set_visible_child_name(&vis); + } +} + #[derive(Debug)] struct EpisodesMachine { populated: EpisodesPopulated, @@ -320,6 +271,7 @@ struct EpisodesMachine { // } // } +// TODO: Impl instead of impl Into> for ShowsMachine { fn into(self) -> ShowsMachine { self.stack.set_visible_child_name("populated"); @@ -378,8 +330,8 @@ impl Into> for EpisodesMachine { // } enum ShowStateWrapper { - Populated(EpisodesMachine), - Empty(EpisodesMachine), + Populated(ShowsMachine), + Empty(ShowsMachine), } enum EpisodeStateWrapper { @@ -397,12 +349,44 @@ enum EpisodeStateWrapper { // } impl ShowStateWrapper { + fn new() -> Self { + let stack = gtk::Stack::new(); + let pop = ShowsPopulated::new_initialized(&stack); + let empty = EmptyView::new(); + + if pop.flowbox.get_children().is_empty() { + stack.set_visible_child_name("empty"); + ShowStateWrapper::Empty(ShowsMachine { + empty, + populated: pop, + stack, + state: Empty {}, + }) + } else { + stack.set_visible_child_name("shows"); + + ShowStateWrapper::Populated(ShowsMachine { + empty, + populated: pop, + stack, + state: Populated {}, + }) + } + } + fn switch(self) -> Self { match self { ShowStateWrapper::Populated(val) => ShowStateWrapper::Empty(val.into()), ShowStateWrapper::Empty(val) => ShowStateWrapper::Populated(val.into()), } } + + fn update(&mut self) { + match *self { + ShowStateWrapper::Populated(ref mut val) => val.update(), + ShowStateWrapper::Empty(ref mut val) => val.update(), + } + } } impl EpisodeStateWrapper { From fa33138d66d81a1028b3f6ab7f137d24410baa5f Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 11 Dec 2017 11:53:29 +0200 Subject: [PATCH 007/278] Start switching to the new stack architecture. --- hammond-gtk/src/content.rs | 184 ++++++++++++----------------- hammond-gtk/src/main.rs | 3 +- hammond-gtk/src/views/podcasts.rs | 35 +++--- hammond-gtk/src/widgets/podcast.rs | 1 - 4 files changed, 97 insertions(+), 126 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 64063cc..c75d4a1 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -8,78 +8,60 @@ use widgets::podcast::PodcastWidget; use views::podcasts::PopulatedView; use views::empty::EmptyView; -#[derive(Debug)] pub struct Content { pub stack: gtk::Stack, - pub widget: PodcastWidget, - pub podcasts: PopulatedView, - pub empty: EmptyView, + shows: ShowStateWrapper, + episodes: EpisodeStateWrapper, } impl Content { pub fn new() -> Content { let stack = gtk::Stack::new(); + let shows = ShowStateWrapper::new(); + let episodes = EpisodeStateWrapper::new(); - let widget = PodcastWidget::new(); - let podcasts = PopulatedView::new(); - let empty = EmptyView::new(); + let shows_stack = shows.get_stack(); + let ep_stack = episodes.get_stack(); - stack.add_titled(&widget.container, "widget", "Episodes"); - stack.add_titled(&podcasts.container, "podcasts", "Shows"); - stack.add_named(&empty.container, "empty"); + stack.add_titled(&ep_stack, "episodes", "Episodes"); + stack.add_titled(&shows_stack, "shows", "Shows"); Content { stack, - widget, - empty, - podcasts, + shows, + episodes, } } - pub fn new_initialized() -> Content { - let ct = Content::new(); - ct.init(); - ct - } + // pub fn new_initialized() -> Content { + // let ct = Content::new(); + // ct.init(); + // ct + // } - pub fn init(&self) { - self.podcasts.init(&self.stack); - if self.podcasts.flowbox.get_children().is_empty() { - self.stack.set_visible_child_name("empty"); - return; - } + // pub fn init(&self) { + // self.podcasts.init(); + // if self.podcasts.flowbox.get_children().is_empty() { + // self.stack.set_visible_child_name("empty"); + // return; + // } - self.stack.set_visible_child_name("podcasts"); - } + // self.stack.set_visible_child_name("podcasts"); + // } - fn replace_widget(&mut self, pdw: PodcastWidget) { - let vis = self.stack.get_visible_child_name().unwrap(); - let old = self.stack.get_child_by_name("widget").unwrap(); - self.stack.remove(&old); + // fn replace_widget(&mut self, pdw: PodcastWidget) { + // let vis = self.stack.get_visible_child_name().unwrap(); + // let old = self.stack.get_child_by_name("widget").unwrap(); + // self.stack.remove(&old); - self.widget = pdw; - self.stack - .add_titled(&self.widget.container, "widget", "Episodes"); - self.stack.set_visible_child_name(&vis); - old.destroy(); - } - - fn replace_podcasts(&mut self, pop: PopulatedView) { - let vis = self.stack.get_visible_child_name().unwrap(); - let old = self.stack.get_child_by_name("podcasts").unwrap(); - self.stack.remove(&old); - - self.podcasts = pop; - self.stack - .add_titled(&self.podcasts.container, "podcasts", "Shows"); - self.stack.set_visible_child_name(&vis); - old.destroy(); - } + // self.widget = pdw; + // self.stack + // .add_titled(&self.widget.container, "widget", "Episodes"); + // self.stack.set_visible_child_name(&vis); + // old.destroy(); + // } } -#[derive(Debug)] -// Experiementing with Wrapping gtk::Stack into a State machine. -// Gonna revist it when TryInto trais is stabilized. pub struct ContentState { content: Content, state: S, @@ -89,8 +71,6 @@ pub trait UpdateView { fn update(&mut self); } -pub struct Empty; - #[derive(Debug)] pub struct PodcastsView {} @@ -104,34 +84,7 @@ impl UpdateView for ContentState { let pd = dbqueries::get_podcast_from_id(id.parse::().unwrap()).unwrap(); let pdw = PodcastWidget::new_initialized(&self.content.stack, &pd); - self.content.replace_widget(pdw); - } -} - -impl ContentState { - #[allow(dead_code)] - pub fn new() -> Result, ContentState> { - let content = Content::new(); - - content.podcasts.init(&content.stack); - if content.podcasts.flowbox.get_children().is_empty() { - content.stack.set_visible_child_name("empty"); - return Err(ContentState { - content, - state: Empty {}, - }); - } - - content.stack.set_visible_child_name("podcasts"); - Ok(ContentState { - content, - state: PodcastsView {}, - }) - } - - #[allow(dead_code)] - pub fn get_stack(&self) -> gtk::Stack { - self.content.stack.clone() + // self.content.replace_widget(pdw); } } @@ -149,25 +102,8 @@ fn replace_podcasts(stack: >k::Stack, pop: &PopulatedView) { old.destroy(); } -#[allow(dead_code)] -pub fn show_widget(stack: >k::Stack) { - stack.set_visible_child_name("widget") -} - -pub fn show_podcasts(stack: >k::Stack) { - stack.set_visible_child_name("podcasts") -} - -pub fn show_empty(stack: >k::Stack) { - stack.set_visible_child_name("empty") -} - pub fn update_podcasts(stack: >k::Stack) { - let pods = PopulatedView::new_initialized(stack); - - if pods.flowbox.get_children().is_empty() { - show_empty(stack) - } + let pods = PopulatedView::new_initialized(); replace_podcasts(stack, &pods); } @@ -191,10 +127,10 @@ pub fn update_widget_preserve_vis(stack: >k::Stack, pd: &Podcast) { stack.set_visible_child_name(&vis) } -pub fn on_podcasts_child_activate(stack: >k::Stack, pd: &Podcast) { - update_widget(stack, pd); - stack.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft); -} +// pub fn on_podcasts_child_activate(stack: >k::Stack, pd: &Podcast) { +// update_widget(stack, pd); +// stack.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft); +// } // FIXME: Rename and remove aliases type ShowsPopulated = PopulatedView; @@ -203,7 +139,7 @@ type EpisodesPopulated = PodcastWidget; type EpisodesEmpty = EmptyView; struct Populated; -// struct Empty; +struct Empty; // struct Shows; // struct Episodes; @@ -229,7 +165,7 @@ impl ShowsMachine { let old = self.stack.get_child_by_name("shows").unwrap(); self.stack.remove(&old); - let pop = ShowsPopulated::new_initialized(&self.stack); + let pop = ShowsPopulated::new_initialized(); self.populated = pop; self.stack .add_titled(&self.populated.container, "shows", "Shows"); @@ -351,8 +287,10 @@ enum EpisodeStateWrapper { impl ShowStateWrapper { fn new() -> Self { let stack = gtk::Stack::new(); - let pop = ShowsPopulated::new_initialized(&stack); + let pop = ShowsPopulated::new_initialized(); let empty = EmptyView::new(); + stack.add_named(&pop.container, "populated"); + stack.add_named(&empty.container, "empty"); if pop.flowbox.get_children().is_empty() { stack.set_visible_child_name("empty"); @@ -363,7 +301,7 @@ impl ShowStateWrapper { state: Empty {}, }) } else { - stack.set_visible_child_name("shows"); + stack.set_visible_child_name("populated"); ShowStateWrapper::Populated(ShowsMachine { empty, @@ -387,13 +325,45 @@ impl ShowStateWrapper { ShowStateWrapper::Empty(ref mut val) => val.update(), } } + + fn get_stack(&self) -> gtk::Stack { + match *self { + ShowStateWrapper::Populated(ref val) => val.stack.clone(), + ShowStateWrapper::Empty(ref val) => val.stack.clone(), + } + } } impl EpisodeStateWrapper { + // FIXME: + fn new() -> Self { + let pop = PodcastWidget::new(); + let empty = EmptyView::new(); + let stack = gtk::Stack::new(); + + stack.add_named(&pop.container, "populated"); + stack.add_named(&empty.container, "empty"); + stack.set_visible_child_name("empty"); + + EpisodeStateWrapper::Empty(EpisodesMachine { + empty, + populated: pop, + stack, + state: Empty {}, + }) + } + fn switch(self) -> Self { match self { EpisodeStateWrapper::Populated(val) => EpisodeStateWrapper::Empty(val.into()), EpisodeStateWrapper::Empty(val) => EpisodeStateWrapper::Populated(val.into()), } } + + fn get_stack(&self) -> gtk::Stack { + match *self { + EpisodeStateWrapper::Populated(ref val) => val.stack.clone(), + EpisodeStateWrapper::Empty(ref val) => val.stack.clone(), + } + } } diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index f4fd89b..0cf43dd 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -67,7 +67,8 @@ fn build_ui(app: >k::Application) { // let ct = content::ContentState::new().unwrap(); // let stack = ct.get_stack(); - let ct = content::Content::new_initialized(); + // let ct = content::Content::new_initialized(); + let ct = content::Content::new(); let stack = ct.stack; window.add(&stack); diff --git a/hammond-gtk/src/views/podcasts.rs b/hammond-gtk/src/views/podcasts.rs index 711be87..0767d72 100644 --- a/hammond-gtk/src/views/podcasts.rs +++ b/hammond-gtk/src/views/podcasts.rs @@ -8,7 +8,7 @@ use hammond_data::Podcast; use utils::get_pixbuf_from_path; -use content; +// use content; #[derive(Debug, Clone)] pub struct PopulatedView { @@ -42,24 +42,25 @@ impl PopulatedView { } #[allow(dead_code)] - pub fn new_initialized(stack: >k::Stack) -> PopulatedView { + pub fn new_initialized() -> PopulatedView { let pop = PopulatedView::new(); - pop.init(stack); + pop.init(); pop } - pub fn init(&self, stack: >k::Stack) { - use gtk::WidgetExt; + pub fn init(&self) { + // pub fn init(&self, stack: >k::Stack) { + // use gtk::WidgetExt; - // TODO: handle unwraps. - self.flowbox - .connect_child_activated(clone!(stack => move |_, child| { - // This is such an ugly hack... - // let id = child.get_name().unwrap().parse::().unwrap(); - let id = WidgetExt::get_name(child).unwrap().parse::().unwrap(); - let parent = dbqueries::get_podcast_from_id(id).unwrap(); - on_flowbox_child_activate(&stack, &parent); - })); + // // TODO: handle unwraps. + // self.flowbox + // .connect_child_activated(clone!(stack => move |_, child| { + // // This is such an ugly hack... + // // let id = child.get_name().unwrap().parse::().unwrap(); + // let id = WidgetExt::get_name(child).unwrap().parse::().unwrap(); + // let parent = dbqueries::get_podcast_from_id(id).unwrap(); + // on_flowbox_child_activate(&stack, &parent); + // })); // Populate the flowbox with the Podcasts. self.populate_flowbox(); } @@ -139,6 +140,6 @@ impl PodcastChild { } } -fn on_flowbox_child_activate(stack: >k::Stack, parent: &Podcast) { - content::on_podcasts_child_activate(stack, parent) -} +// fn on_flowbox_child_activate(stack: >k::Stack, parent: &Podcast) { +// content::on_podcasts_child_activate(stack, parent) +// } diff --git a/hammond-gtk/src/widgets/podcast.rs b/hammond-gtk/src/widgets/podcast.rs index 206ffd9..b447384 100644 --- a/hammond-gtk/src/widgets/podcast.rs +++ b/hammond-gtk/src/widgets/podcast.rs @@ -112,7 +112,6 @@ fn on_unsub_button_clicked(stack: >k::Stack, pd: &Podcast, unsub_button: >k: }; } content::update_podcasts(stack); - content::show_podcasts(stack); } fn on_played_button_clicked(stack: >k::Stack, pd: &Podcast) { From ddb195db3c816d9b77a0382126fcc8f80f0ba3e5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 11 Dec 2017 13:51:16 +0200 Subject: [PATCH 008/278] Wired up refresh button. --- hammond-gtk/src/content.rs | 87 +++++++++++++----------------------- hammond-gtk/src/headerbar.rs | 30 ++++++++----- hammond-gtk/src/main.rs | 11 +++-- hammond-gtk/src/utils.rs | 17 ++++--- 4 files changed, 68 insertions(+), 77 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index c75d4a1..1001dce 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -33,58 +33,9 @@ impl Content { } } - // pub fn new_initialized() -> Content { - // let ct = Content::new(); - // ct.init(); - // ct - // } - - // pub fn init(&self) { - // self.podcasts.init(); - // if self.podcasts.flowbox.get_children().is_empty() { - // self.stack.set_visible_child_name("empty"); - // return; - // } - - // self.stack.set_visible_child_name("podcasts"); - // } - - // fn replace_widget(&mut self, pdw: PodcastWidget) { - // let vis = self.stack.get_visible_child_name().unwrap(); - // let old = self.stack.get_child_by_name("widget").unwrap(); - // self.stack.remove(&old); - - // self.widget = pdw; - // self.stack - // .add_titled(&self.widget.container, "widget", "Episodes"); - // self.stack.set_visible_child_name(&vis); - // old.destroy(); - // } -} - -pub struct ContentState { - content: Content, - state: S, -} - -pub trait UpdateView { - fn update(&mut self); -} - -#[derive(Debug)] -pub struct PodcastsView {} - -#[derive(Debug)] -pub struct WidgetsView {} - -impl UpdateView for ContentState { - fn update(&mut self) { - let old = self.content.stack.get_child_by_name("widget").unwrap(); - let id = WidgetExt::get_name(&old).unwrap(); - let pd = dbqueries::get_podcast_from_id(id.parse::().unwrap()).unwrap(); - - let pdw = PodcastWidget::new_initialized(&self.content.stack, &pd); - // self.content.replace_widget(pdw); + pub fn update(&mut self) { + self.shows.update(); + self.episodes.update(); } } @@ -162,13 +113,12 @@ struct ShowsMachine { impl ShowsMachine { fn update(&mut self) { let vis = self.stack.get_visible_child_name().unwrap(); - let old = self.stack.get_child_by_name("shows").unwrap(); + let old = self.stack.get_child_by_name("populated").unwrap(); self.stack.remove(&old); let pop = ShowsPopulated::new_initialized(); self.populated = pop; - self.stack - .add_titled(&self.populated.container, "shows", "Shows"); + self.stack.add_named(&self.populated.container, "populated"); self.stack.set_visible_child_name(&vis); } } @@ -181,6 +131,26 @@ struct EpisodesMachine { state: S, } +impl EpisodesMachine { + // FIXME: + fn update(&mut self) { + let vis = self.stack.get_visible_child_name().unwrap(); + let old = self.stack.get_child_by_name("populated").unwrap(); + + let id = WidgetExt::get_name(&old).unwrap(); + if id == "GtkBox" { + return; + } + let pd = dbqueries::get_podcast_from_id(id.parse::().unwrap()).unwrap(); + let pdw = EpisodesPopulated::new_initialized(&self.stack, &pd); + + self.populated = pdw; + self.stack.remove(&old); + self.stack.add_named(&self.populated.container, "populated"); + self.stack.set_visible_child_name(&vis); + } +} + // impl Into> for StackStateMachine { // fn into(self) -> StackStateMachine { // self.stack.set_visible_child_name("shows"); @@ -353,6 +323,13 @@ impl EpisodeStateWrapper { }) } + fn update(&mut self) { + match *self { + EpisodeStateWrapper::Populated(ref mut val) => val.update(), + EpisodeStateWrapper::Empty(ref mut val) => val.update(), + } + } + fn switch(self) -> Self { match self { EpisodeStateWrapper::Populated(val) => EpisodeStateWrapper::Empty(val.into()), diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 7bcd41e..34c8087 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -4,8 +4,10 @@ use gtk::prelude::*; use hammond_data::Source; use hammond_data::utils::url_cleaner; +use std::sync::{Arc, Mutex}; + use utils; -// use content; +use content::Content; #[derive(Debug)] pub struct Header { @@ -34,26 +36,31 @@ impl Header { } } - pub fn new_initialized(stack: >k::Stack) -> Header { + pub fn new_initialized(content: Arc>) -> Header { let header = Header::new(); - header.init(stack); + header.init(content); header } - fn init(&self, stack: >k::Stack) { + fn init(&self, content: Arc>) { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let add_popover: gtk::Popover = builder.get_object("add-popover").unwrap(); let new_url: gtk::Entry = builder.get_object("new-url").unwrap(); let add_button: gtk::Button = builder.get_object("add-button").unwrap(); - self.switch.set_stack(stack); + + { + let cont = content.lock().unwrap(); + self.switch.set_stack(&cont.stack); + } new_url.connect_changed(move |url| { println!("{:?}", url.get_text()); }); - add_button.connect_clicked(clone!(stack, add_popover, new_url => move |_| { - on_add_bttn_clicked(&stack, &new_url); + let cont = content.clone(); + add_button.connect_clicked(clone!(cont, add_popover, new_url => move |_| { + on_add_bttn_clicked(cont.clone(), &new_url); // TODO: lock the button instead of hiding and add notification of feed added. // TODO: map the spinner @@ -62,13 +69,14 @@ impl Header { self.add_toggle.set_popover(&add_popover); // FIXME: There appears to be a memmory leak here. - self.refresh.connect_clicked(clone!(stack => move |_| { - utils::refresh_feed(&stack, None, None); + let cont = content.clone(); + self.refresh.connect_clicked(clone!(cont => move |_| { + utils::refresh_feed(cont.clone(), None, None); })); } } -fn on_add_bttn_clicked(stack: >k::Stack, entry: >k::Entry) { +fn on_add_bttn_clicked(content: Arc>, entry: >k::Entry) { let url = entry.get_text().unwrap_or_default(); let url = url_cleaner(&url); let source = Source::from_url(&url); @@ -76,7 +84,7 @@ fn on_add_bttn_clicked(stack: >k::Stack, entry: >k::Entry) { if let Ok(s) = source { info!("{:?} feed added", url); // update the db - utils::refresh_feed(stack, Some(vec![s]), None); + utils::refresh_feed(content, Some(vec![s]), None); } else { error!("Feed probably already exists."); error!("Error: {:?}", source.unwrap_err()); diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 0cf43dd..9f4a4b4 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -22,6 +22,8 @@ use hammond_data::utils::checkup; use gtk::prelude::*; use gio::{ActionMapExt, ApplicationExt, MenuExt, SimpleActionExt}; +use std::sync::{Arc, Mutex}; + // http://gtk-rs.org/tuto/closures #[macro_export] macro_rules! clone { @@ -69,7 +71,8 @@ fn build_ui(app: >k::Application) { // let ct = content::Content::new_initialized(); let ct = content::Content::new(); - let stack = ct.stack; + let stack = ct.stack.clone(); + let ct = Arc::new(Mutex::new(ct)); window.add(&stack); window.connect_delete_event(|w, _| { @@ -93,8 +96,8 @@ fn build_ui(app: >k::Application) { app.add_action(&check); // queue a db update 1 minute after the startup. - gtk::idle_add(clone!(stack => move || { - utils::refresh_feed(&stack, None, Some(60)); + gtk::idle_add(clone!(ct => move || { + utils::refresh_feed(ct.clone(), None, Some(60)); glib::Continue(false) })); @@ -104,7 +107,7 @@ fn build_ui(app: >k::Application) { }); // Get the headerbar - let header = headerbar::Header::new_initialized(&stack); + let header = headerbar::Header::new_initialized(ct.clone()); window.set_titlebar(&header.container); window.show_all(); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 5402b90..0a6a5c2 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -11,10 +11,12 @@ use std::cell::RefCell; use std::sync::mpsc::{channel, Receiver}; use std::borrow::Cow; -use content; +use content::Content; use regex::Regex; -type Foo = RefCell)>>; +use std::sync::{Arc, Mutex}; + +type Foo = RefCell>, Receiver)>>; // Create a thread local storage that will store the arguments to be transfered. thread_local!(static GLOBAL: Foo = RefCell::new(None)); @@ -23,13 +25,13 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None)); /// If `source` is None, Fetches all the `Source` entries in the database and updates them. /// `delay` represents the desired time in seconds for the thread to sleep before executing. /// When It's done,it queues up a `podcast_view` refresh. -pub fn refresh_feed(stack: >k::Stack, source: Option>, delay: Option) { +pub fn refresh_feed(content: Arc>, source: Option>, delay: Option) { // Create a async channel. let (sender, receiver) = channel(); // Pass the desired arguments into the Local Thread Storage. - GLOBAL.with(clone!(stack => move |global| { - *global.borrow_mut() = Some((stack, receiver)); + GLOBAL.with(clone!(content => move |global| { + *global.borrow_mut() = Some((content, receiver)); })); thread::spawn(move || { @@ -57,9 +59,10 @@ pub fn refresh_feed(stack: >k::Stack, source: Option>, delay: Opti fn refresh_podcasts_view() -> glib::Continue { GLOBAL.with(|global| { - if let Some((ref stack, ref reciever)) = *global.borrow() { + if let Some((ref content, ref reciever)) = *global.borrow() { if reciever.try_recv().is_ok() { - content::update_podcasts_preserve_vis(stack); + let mut content = content.lock().unwrap(); + content.update(); } } }); From 211b36dfa37a0cec8c5ef4172da32f479438de98 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 11 Dec 2017 16:14:43 +0200 Subject: [PATCH 009/278] Fix showmachine updating. --- hammond-gtk/src/content.rs | 128 +++++++++++------------------ hammond-gtk/src/headerbar.rs | 9 +- hammond-gtk/src/widgets/podcast.rs | 8 +- 3 files changed, 58 insertions(+), 87 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 1001dce..4b7d32a 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -1,13 +1,14 @@ use gtk; use gtk::prelude::*; -use hammond_data::Podcast; +// use hammond_data::Podcast; use hammond_data::dbqueries; use widgets::podcast::PodcastWidget; use views::podcasts::PopulatedView; use views::empty::EmptyView; +#[derive(Debug, Clone)] pub struct Content { pub stack: gtk::Stack, shows: ShowStateWrapper, @@ -34,50 +35,12 @@ impl Content { } pub fn update(&mut self) { - self.shows.update(); + self.shows = self.shows.clone().update(); + // FIXME: like above self.episodes.update(); } } -fn replace_widget(stack: >k::Stack, pdw: &PodcastWidget) { - let old = stack.get_child_by_name("widget").unwrap(); - stack.remove(&old); - stack.add_titled(&pdw.container, "widget", "Episode"); - old.destroy(); -} - -fn replace_podcasts(stack: >k::Stack, pop: &PopulatedView) { - let old = stack.get_child_by_name("podcasts").unwrap(); - stack.remove(&old); - stack.add_titled(&pop.container, "podcasts", "Shows"); - old.destroy(); -} - -pub fn update_podcasts(stack: >k::Stack) { - let pods = PopulatedView::new_initialized(); - - replace_podcasts(stack, &pods); -} - -pub fn update_widget(stack: >k::Stack, pd: &Podcast) { - let pdw = PodcastWidget::new_initialized(stack, pd); - replace_widget(stack, &pdw); -} - -pub fn update_podcasts_preserve_vis(stack: >k::Stack) { - let vis = stack.get_visible_child_name().unwrap(); - update_podcasts(stack); - if vis != "empty" { - stack.set_visible_child_name(&vis) - } -} - -pub fn update_widget_preserve_vis(stack: >k::Stack, pd: &Podcast) { - let vis = stack.get_visible_child_name().unwrap(); - update_widget(stack, pd); - stack.set_visible_child_name(&vis) -} - // pub fn on_podcasts_child_activate(stack: >k::Stack, pd: &Podcast) { // update_widget(stack, pd); // stack.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft); @@ -89,7 +52,9 @@ type ShowsEmpty = EmptyView; type EpisodesPopulated = PodcastWidget; type EpisodesEmpty = EmptyView; +#[derive(Debug, Clone)] struct Populated; +#[derive(Debug, Clone)] struct Empty; // struct Shows; // struct Episodes; @@ -111,6 +76,21 @@ struct ShowsMachine { } impl ShowsMachine { + fn new(state: S) -> ShowsMachine { + let stack = gtk::Stack::new(); + let pop = ShowsPopulated::new_initialized(); + let empty = EmptyView::new(); + stack.add_named(&pop.container, "populated"); + stack.add_named(&empty.container, "empty"); + + ShowsMachine { + empty, + populated: pop, + stack, + state, + } + } + fn update(&mut self) { let vis = self.stack.get_visible_child_name().unwrap(); let old = self.stack.get_child_by_name("populated").unwrap(); @@ -123,7 +103,7 @@ impl ShowsMachine { } } -#[derive(Debug)] +#[derive(Debug, Clone)] struct EpisodesMachine { populated: EpisodesPopulated, empty: EpisodesEmpty, @@ -235,11 +215,13 @@ impl Into> for EpisodesMachine { // Episodes(StackStateMachine), // } +#[derive(Debug, Clone)] enum ShowStateWrapper { Populated(ShowsMachine), Empty(ShowsMachine), } +#[derive(Debug, Clone)] enum EpisodeStateWrapper { Populated(EpisodesMachine), Empty(EpisodesMachine), @@ -256,44 +238,34 @@ enum EpisodeStateWrapper { impl ShowStateWrapper { fn new() -> Self { - let stack = gtk::Stack::new(); - let pop = ShowsPopulated::new_initialized(); - let empty = EmptyView::new(); - stack.add_named(&pop.container, "populated"); - stack.add_named(&empty.container, "empty"); + let machine = ShowsMachine::new(Populated {}); - if pop.flowbox.get_children().is_empty() { - stack.set_visible_child_name("empty"); - ShowStateWrapper::Empty(ShowsMachine { - empty, - populated: pop, - stack, - state: Empty {}, - }) + if machine.populated.flowbox.get_children().is_empty() { + machine.stack.set_visible_child_name("empty"); + ShowStateWrapper::Empty(machine.into()) } else { - stack.set_visible_child_name("populated"); - - ShowStateWrapper::Populated(ShowsMachine { - empty, - populated: pop, - stack, - state: Populated {}, - }) + machine.stack.set_visible_child_name("populated"); + ShowStateWrapper::Populated(machine) } } - fn switch(self) -> Self { + fn update(mut self) -> Self { match self { - ShowStateWrapper::Populated(val) => ShowStateWrapper::Empty(val.into()), - ShowStateWrapper::Empty(val) => ShowStateWrapper::Populated(val.into()), - } - } - - fn update(&mut self) { - match *self { ShowStateWrapper::Populated(ref mut val) => val.update(), ShowStateWrapper::Empty(ref mut val) => val.update(), } + + if self.is_empty() { + match self { + ShowStateWrapper::Populated(val) => ShowStateWrapper::Empty(val.into()), + _ => self, + } + } else { + match self { + ShowStateWrapper::Empty(val) => ShowStateWrapper::Populated(val.into()), + _ => self, + } + } } fn get_stack(&self) -> gtk::Stack { @@ -302,6 +274,13 @@ impl ShowStateWrapper { ShowStateWrapper::Empty(ref val) => val.stack.clone(), } } + + fn is_empty(&self) -> bool { + match *self { + ShowStateWrapper::Populated(ref val) => val.populated.flowbox.get_children().is_empty(), + ShowStateWrapper::Empty(ref val) => val.populated.flowbox.get_children().is_empty(), + } + } } impl EpisodeStateWrapper { @@ -330,13 +309,6 @@ impl EpisodeStateWrapper { } } - fn switch(self) -> Self { - match self { - EpisodeStateWrapper::Populated(val) => EpisodeStateWrapper::Empty(val.into()), - EpisodeStateWrapper::Empty(val) => EpisodeStateWrapper::Populated(val.into()), - } - } - fn get_stack(&self) -> gtk::Stack { match *self { EpisodeStateWrapper::Populated(ref val) => val.stack.clone(), diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 34c8087..956e040 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -58,9 +58,8 @@ impl Header { println!("{:?}", url.get_text()); }); - let cont = content.clone(); - add_button.connect_clicked(clone!(cont, add_popover, new_url => move |_| { - on_add_bttn_clicked(cont.clone(), &new_url); + add_button.connect_clicked(clone!(content, add_popover, new_url => move |_| { + on_add_bttn_clicked(content.clone(), &new_url); // TODO: lock the button instead of hiding and add notification of feed added. // TODO: map the spinner @@ -70,9 +69,9 @@ impl Header { // FIXME: There appears to be a memmory leak here. let cont = content.clone(); - self.refresh.connect_clicked(clone!(cont => move |_| { + self.refresh.connect_clicked(move |_| { utils::refresh_feed(cont.clone(), None, None); - })); + }); } } diff --git a/hammond-gtk/src/widgets/podcast.rs b/hammond-gtk/src/widgets/podcast.rs index b447384..c0d4c34 100644 --- a/hammond-gtk/src/widgets/podcast.rs +++ b/hammond-gtk/src/widgets/podcast.rs @@ -10,9 +10,9 @@ use hammond_downloader::downloader; use widgets::episode::episodes_listbox; use utils::get_pixbuf_from_path; -use content; +// use content; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct PodcastWidget { pub container: gtk::Box, cover: gtk::Image, @@ -111,11 +111,11 @@ fn on_unsub_button_clicked(stack: >k::Stack, pd: &Podcast, unsub_button: >k: } }; } - content::update_podcasts(stack); + // content::update_podcasts(stack); } fn on_played_button_clicked(stack: >k::Stack, pd: &Podcast) { let _ = dbqueries::update_none_to_played_now(pd); - content::update_widget_preserve_vis(stack, pd); + // content::update_widget_preserve_vis(stack, pd); } From 01310ee7fa0abec74706748ca1d8bbd1a2458fbb Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 12 Dec 2017 16:01:19 +0200 Subject: [PATCH 010/278] Working non-state machine stack implementation. Removed the stack state-machines. It was confusing trying to both implement statemachines and re-design the stack architecture at the same time. --- hammond-gtk/src/content.rs | 343 ++++++++--------------------- hammond-gtk/src/headerbar.rs | 17 +- hammond-gtk/src/main.rs | 5 +- hammond-gtk/src/utils.rs | 24 +- hammond-gtk/src/views/podcasts.rs | 43 ++-- hammond-gtk/src/widgets/podcast.rs | 26 ++- 6 files changed, 146 insertions(+), 312 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 4b7d32a..8214ab9 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -1,318 +1,167 @@ use gtk; use gtk::prelude::*; -// use hammond_data::Podcast; +use hammond_data::Podcast; use hammond_data::dbqueries; -use widgets::podcast::PodcastWidget; use views::podcasts::PopulatedView; use views::empty::EmptyView; +use widgets::podcast::PodcastWidget; + +use std::rc::Rc; #[derive(Debug, Clone)] pub struct Content { pub stack: gtk::Stack, - shows: ShowStateWrapper, - episodes: EpisodeStateWrapper, + shows: Rc, + episodes: Rc, } impl Content { - pub fn new() -> Content { + pub fn new() -> Rc { let stack = gtk::Stack::new(); - let shows = ShowStateWrapper::new(); - let episodes = EpisodeStateWrapper::new(); + let shows = ShowStack::new(); + let episodes = EpisodeStack::new(); - let shows_stack = shows.get_stack(); - let ep_stack = episodes.get_stack(); + stack.add_titled(&episodes.stack, "episodes", "Episodes"); + stack.add_titled(&shows.stack, "shows", "Shows"); - stack.add_titled(&ep_stack, "episodes", "Episodes"); - stack.add_titled(&shows_stack, "shows", "Shows"); - - Content { + Rc::new(Content { stack, shows, episodes, - } + }) } - pub fn update(&mut self) { - self.shows = self.shows.clone().update(); - // FIXME: like above + pub fn update(&self) { + self.shows.update(); self.episodes.update(); } } -// pub fn on_podcasts_child_activate(stack: >k::Stack, pd: &Podcast) { -// update_widget(stack, pd); -// stack.set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft); -// } - -// FIXME: Rename and remove aliases -type ShowsPopulated = PopulatedView; -type ShowsEmpty = EmptyView; -type EpisodesPopulated = PodcastWidget; -type EpisodesEmpty = EmptyView; - #[derive(Debug, Clone)] -struct Populated; -#[derive(Debug, Clone)] -struct Empty; -// struct Shows; -// struct Episodes; - -// Thats probably too overengineered -// struct StackStateMachine { -// shows: ShowsMachine, -// episodes: EpisodesMachine, -// stack: gtk::Stack, -// state: T, -// } - -#[derive(Debug, Clone)] -struct ShowsMachine { - populated: ShowsPopulated, - empty: ShowsEmpty, - stack: gtk::Stack, - state: S, +pub struct ShowStack { + pub stack: gtk::Stack, } -impl ShowsMachine { - fn new(state: S) -> ShowsMachine { +impl ShowStack { + fn new() -> Rc { let stack = gtk::Stack::new(); - let pop = ShowsPopulated::new_initialized(); + + let show = Rc::new(ShowStack { stack }); + + let pop = PopulatedView::new_initialized(show.clone()); + let widget = PodcastWidget::new(); let empty = EmptyView::new(); - stack.add_named(&pop.container, "populated"); - stack.add_named(&empty.container, "empty"); - ShowsMachine { - empty, - populated: pop, - stack, - state, + show.stack.add_named(&pop.container, "podcasts"); + show.stack.add_named(&widget.container, "widget"); + show.stack.add_named(&empty.container, "empty"); + + if pop.is_empty() { + show.stack.set_visible_child_name("empty") + } else { + show.stack.set_visible_child_name("podcasts") } + + show } - fn update(&mut self) { + // fn is_empty(&self) -> bool { + // self.podcasts.is_empty() + // } + + pub fn update(&self) { + self.update_podcasts(); + self.update_widget(); + } + + pub fn update_podcasts(&self) { let vis = self.stack.get_visible_child_name().unwrap(); - let old = self.stack.get_child_by_name("populated").unwrap(); + let old = self.stack.get_child_by_name("podcasts").unwrap(); + + let pop = PopulatedView::new(); + pop.init(Rc::new(self.clone())); + self.stack.remove(&old); + self.stack.add_named(&pop.container, "podcasts"); - let pop = ShowsPopulated::new_initialized(); - self.populated = pop; - self.stack.add_named(&self.populated.container, "populated"); - self.stack.set_visible_child_name(&vis); + if pop.is_empty() { + self.stack.set_visible_child_name("empty"); + } else if vis != "empty" { + self.stack.set_visible_child_name(&vis); + } else { + self.stack.set_visible_child_name("podcasts"); + } + + old.destroy(); } -} -#[derive(Debug, Clone)] -struct EpisodesMachine { - populated: EpisodesPopulated, - empty: EpisodesEmpty, - stack: gtk::Stack, - state: S, -} + pub fn replace_widget(&self, pd: &Podcast) { + let old = self.stack.get_child_by_name("widget").unwrap(); + let new = PodcastWidget::new_initialized(Rc::new(self.clone()), pd); -impl EpisodesMachine { - // FIXME: - fn update(&mut self) { + self.stack.remove(&old); + self.stack.add_named(&new.container, "widget"); + } + + pub fn update_widget(&self) { let vis = self.stack.get_visible_child_name().unwrap(); - let old = self.stack.get_child_by_name("populated").unwrap(); + let old = self.stack.get_child_by_name("widget").unwrap(); let id = WidgetExt::get_name(&old).unwrap(); if id == "GtkBox" { return; } - let pd = dbqueries::get_podcast_from_id(id.parse::().unwrap()).unwrap(); - let pdw = EpisodesPopulated::new_initialized(&self.stack, &pd); - self.populated = pdw; - self.stack.remove(&old); - self.stack.add_named(&self.populated.container, "populated"); - self.stack.set_visible_child_name(&vis); - } -} - -// impl Into> for StackStateMachine { -// fn into(self) -> StackStateMachine { -// self.stack.set_visible_child_name("shows"); - -// StackStateMachine { -// shows: self.shows, -// episodes: self.episodes, -// stack: self.stack, -// state: Shows {}, -// } -// } -// } - -// impl Into> for StackStateMachine { -// fn into(self) -> StackStateMachine { -// self.stack.set_visible_child_name("episodes"); - -// StackStateMachine { -// shows: self.shows, -// episodes: self.episodes, -// stack: self.stack, -// state: Episodes {}, -// } -// } -// } - -// TODO: Impl instead of -impl Into> for ShowsMachine { - fn into(self) -> ShowsMachine { - self.stack.set_visible_child_name("populated"); - - ShowsMachine { - populated: self.populated, - empty: self.empty, - stack: self.stack, - state: Populated {}, + let pd = dbqueries::get_podcast_from_id(id.parse::().unwrap()); + if let Ok(pd) = pd { + self.replace_widget(&pd); + self.stack.set_visible_child_name(&vis); + old.destroy(); } } -} -impl Into> for ShowsMachine { - fn into(self) -> ShowsMachine { - self.stack.set_visible_child_name("empty"); - - ShowsMachine { - populated: self.populated, - empty: self.empty, - stack: self.stack, - state: Empty {}, - } + pub fn switch_podcasts_animated(&self) { + self.stack + .set_visible_child_full("podcasts", gtk::StackTransitionType::SlideRight); } -} -impl Into> for EpisodesMachine { - fn into(self) -> EpisodesMachine { - self.stack.set_visible_child_name("populated"); - - EpisodesMachine { - populated: self.populated, - empty: self.empty, - stack: self.stack, - state: Populated {}, - } + pub fn switch_widget_animated(&self) { + self.stack + .set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft) } } -impl Into> for EpisodesMachine { - fn into(self) -> EpisodesMachine { - self.stack.set_visible_child_name("empty"); - - EpisodesMachine { - populated: self.populated, - empty: self.empty, - stack: self.stack, - state: Empty {}, - } - } -} - -// enum StackStateWrapper { -// Shows(StackStateMachine), -// Episodes(StackStateMachine), -// } - -#[derive(Debug, Clone)] -enum ShowStateWrapper { - Populated(ShowsMachine), - Empty(ShowsMachine), -} - #[derive(Debug, Clone)] -enum EpisodeStateWrapper { - Populated(EpisodesMachine), - Empty(EpisodesMachine), +struct RecentEpisodes; + +#[derive(Debug, Clone)] +struct EpisodeStack { + // populated: RecentEpisodes, + // empty: EmptyView, + stack: gtk::Stack, } -// impl StackStateWrapper { -// fn switch(mut self) -> Self { -// match self { -// StackStateWrapper::Shows(val) => StackStateWrapper::Episodes(val.into()), -// StackStateWrapper::Episodes(val) => StackStateWrapper::Shows(val.into()) -// } -// } -// } - -impl ShowStateWrapper { - fn new() -> Self { - let machine = ShowsMachine::new(Populated {}); - - if machine.populated.flowbox.get_children().is_empty() { - machine.stack.set_visible_child_name("empty"); - ShowStateWrapper::Empty(machine.into()) - } else { - machine.stack.set_visible_child_name("populated"); - ShowStateWrapper::Populated(machine) - } - } - - fn update(mut self) -> Self { - match self { - ShowStateWrapper::Populated(ref mut val) => val.update(), - ShowStateWrapper::Empty(ref mut val) => val.update(), - } - - if self.is_empty() { - match self { - ShowStateWrapper::Populated(val) => ShowStateWrapper::Empty(val.into()), - _ => self, - } - } else { - match self { - ShowStateWrapper::Empty(val) => ShowStateWrapper::Populated(val.into()), - _ => self, - } - } - } - - fn get_stack(&self) -> gtk::Stack { - match *self { - ShowStateWrapper::Populated(ref val) => val.stack.clone(), - ShowStateWrapper::Empty(ref val) => val.stack.clone(), - } - } - - fn is_empty(&self) -> bool { - match *self { - ShowStateWrapper::Populated(ref val) => val.populated.flowbox.get_children().is_empty(), - ShowStateWrapper::Empty(ref val) => val.populated.flowbox.get_children().is_empty(), - } - } -} - -impl EpisodeStateWrapper { - // FIXME: - fn new() -> Self { - let pop = PodcastWidget::new(); +impl EpisodeStack { + fn new() -> Rc { + let _pop = RecentEpisodes {}; let empty = EmptyView::new(); let stack = gtk::Stack::new(); - stack.add_named(&pop.container, "populated"); + // stack.add_named(&pop.container, "populated"); stack.add_named(&empty.container, "empty"); + // FIXME: stack.set_visible_child_name("empty"); - EpisodeStateWrapper::Empty(EpisodesMachine { - empty, - populated: pop, + Rc::new(EpisodeStack { + // empty, + // populated: pop, stack, - state: Empty {}, }) } - fn update(&mut self) { - match *self { - EpisodeStateWrapper::Populated(ref mut val) => val.update(), - EpisodeStateWrapper::Empty(ref mut val) => val.update(), - } - } - - fn get_stack(&self) -> gtk::Stack { - match *self { - EpisodeStateWrapper::Populated(ref val) => val.stack.clone(), - EpisodeStateWrapper::Empty(ref val) => val.stack.clone(), - } + fn update(&self) { + // unimplemented!() } } diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 956e040..140eac2 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -4,7 +4,7 @@ use gtk::prelude::*; use hammond_data::Source; use hammond_data::utils::url_cleaner; -use std::sync::{Arc, Mutex}; +use std::rc::Rc; use utils; use content::Content; @@ -36,23 +36,19 @@ impl Header { } } - pub fn new_initialized(content: Arc>) -> Header { + pub fn new_initialized(content: Rc) -> Header { let header = Header::new(); header.init(content); header } - fn init(&self, content: Arc>) { + fn init(&self, content: Rc) { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let add_popover: gtk::Popover = builder.get_object("add-popover").unwrap(); let new_url: gtk::Entry = builder.get_object("new-url").unwrap(); let add_button: gtk::Button = builder.get_object("add-button").unwrap(); - - { - let cont = content.lock().unwrap(); - self.switch.set_stack(&cont.stack); - } + self.switch.set_stack(&content.stack); new_url.connect_changed(move |url| { println!("{:?}", url.get_text()); @@ -68,14 +64,13 @@ impl Header { self.add_toggle.set_popover(&add_popover); // FIXME: There appears to be a memmory leak here. - let cont = content.clone(); self.refresh.connect_clicked(move |_| { - utils::refresh_feed(cont.clone(), None, None); + utils::refresh_feed(content.clone(), None, None); }); } } -fn on_add_bttn_clicked(content: Arc>, entry: >k::Entry) { +fn on_add_bttn_clicked(content: Rc, entry: >k::Entry) { let url = entry.get_text().unwrap_or_default(); let url = url_cleaner(&url); let source = Source::from_url(&url); diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 9f4a4b4..77bd430 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -1,3 +1,5 @@ +#![cfg_attr(feature = "cargo-clippy", allow(clone_on_ref_ptr))] + extern crate gdk; extern crate gdk_pixbuf; extern crate gio; @@ -22,8 +24,6 @@ use hammond_data::utils::checkup; use gtk::prelude::*; use gio::{ActionMapExt, ApplicationExt, MenuExt, SimpleActionExt}; -use std::sync::{Arc, Mutex}; - // http://gtk-rs.org/tuto/closures #[macro_export] macro_rules! clone { @@ -72,7 +72,6 @@ fn build_ui(app: >k::Application) { // let ct = content::Content::new_initialized(); let ct = content::Content::new(); let stack = ct.stack.clone(); - let ct = Arc::new(Mutex::new(ct)); window.add(&stack); window.connect_delete_event(|w, _| { diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 0a6a5c2..7327854 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -1,5 +1,4 @@ use glib; -use gtk; use gdk_pixbuf::Pixbuf; use hammond_data::feed; @@ -9,14 +8,12 @@ use hammond_downloader::downloader; use std::{thread, time}; use std::cell::RefCell; use std::sync::mpsc::{channel, Receiver}; -use std::borrow::Cow; use content::Content; -use regex::Regex; -use std::sync::{Arc, Mutex}; +use std::rc::Rc; -type Foo = RefCell>, Receiver)>>; +type Foo = RefCell, Receiver)>>; // Create a thread local storage that will store the arguments to be transfered. thread_local!(static GLOBAL: Foo = RefCell::new(None)); @@ -25,13 +22,13 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None)); /// If `source` is None, Fetches all the `Source` entries in the database and updates them. /// `delay` represents the desired time in seconds for the thread to sleep before executing. /// When It's done,it queues up a `podcast_view` refresh. -pub fn refresh_feed(content: Arc>, source: Option>, delay: Option) { +pub fn refresh_feed(content: Rc, source: Option>, delay: Option) { // Create a async channel. let (sender, receiver) = channel(); // Pass the desired arguments into the Local Thread Storage. GLOBAL.with(clone!(content => move |global| { - *global.borrow_mut() = Some((content, receiver)); + *global.borrow_mut() = Some((content.clone(), receiver)); })); thread::spawn(move || { @@ -61,7 +58,6 @@ fn refresh_podcasts_view() -> glib::Continue { GLOBAL.with(|global| { if let Some((ref content, ref reciever)) = *global.borrow() { if reciever.try_recv().is_ok() { - let mut content = content.lock().unwrap(); content.update(); } } @@ -74,18 +70,6 @@ pub fn get_pixbuf_from_path(pd: &Podcast) -> Option { Pixbuf::new_from_file_at_scale(&img_path, 256, 256, true).ok() } -#[allow(dead_code)] -// WIP: parse html to markup -pub fn html_to_markup(s: &mut str) -> Cow { - s.trim(); - s.replace('&', "&"); - s.replace('<', "<"); - s.replace('>', ">"); - - let re = Regex::new("(?Phttps?://[^\\s&,)(\"]+(&\\w=[\\w._-]?)*(#[\\w._-]+)?)").unwrap(); - re.replace_all(s, "$url") -} - #[cfg(test)] mod tests { use hammond_data::Source; diff --git a/hammond-gtk/src/views/podcasts.rs b/hammond-gtk/src/views/podcasts.rs index 0767d72..58c5f14 100644 --- a/hammond-gtk/src/views/podcasts.rs +++ b/hammond-gtk/src/views/podcasts.rs @@ -7,8 +7,9 @@ use hammond_data::dbqueries; use hammond_data::Podcast; use utils::get_pixbuf_from_path; +use content::ShowStack; -// use content; +use std::rc::Rc; #[derive(Debug, Clone)] pub struct PopulatedView { @@ -42,25 +43,29 @@ impl PopulatedView { } #[allow(dead_code)] - pub fn new_initialized() -> PopulatedView { + pub fn new_initialized(show: Rc) -> PopulatedView { let pop = PopulatedView::new(); - pop.init(); + pop.init(show); pop } - pub fn init(&self) { - // pub fn init(&self, stack: >k::Stack) { - // use gtk::WidgetExt; + pub fn init(&self, show: Rc) { + use gtk::WidgetExt; - // // TODO: handle unwraps. - // self.flowbox - // .connect_child_activated(clone!(stack => move |_, child| { - // // This is such an ugly hack... - // // let id = child.get_name().unwrap().parse::().unwrap(); - // let id = WidgetExt::get_name(child).unwrap().parse::().unwrap(); - // let parent = dbqueries::get_podcast_from_id(id).unwrap(); - // on_flowbox_child_activate(&stack, &parent); - // })); + // TODO: handle unwraps. + // Note: flowbox_activation always adds "widnget" into the stack and switch to it, + // TODO: implement back button. + // so back button should always remove "widget" and destroy it. + let show = show.clone(); + self.flowbox + .connect_child_activated(clone!(show => move |_, child| { + // This is such an ugly hack... + let id = WidgetExt::get_name(child).unwrap().parse::().unwrap(); + let pd = dbqueries::get_podcast_from_id(id).unwrap(); + + show.replace_widget(&pd); + show.switch_widget_animated(); + })); // Populate the flowbox with the Podcasts. self.populate_flowbox(); } @@ -76,6 +81,10 @@ impl PopulatedView { self.flowbox.show_all(); } } + + pub fn is_empty(&self) -> bool { + self.flowbox.get_children().is_empty() + } } impl PodcastChild { @@ -139,7 +148,3 @@ impl PodcastChild { } } } - -// fn on_flowbox_child_activate(stack: >k::Stack, parent: &Podcast) { -// content::on_podcasts_child_activate(stack, parent) -// } diff --git a/hammond-gtk/src/widgets/podcast.rs b/hammond-gtk/src/widgets/podcast.rs index c0d4c34..1d7f91b 100644 --- a/hammond-gtk/src/widgets/podcast.rs +++ b/hammond-gtk/src/widgets/podcast.rs @@ -10,7 +10,8 @@ use hammond_downloader::downloader; use widgets::episode::episodes_listbox; use utils::get_pixbuf_from_path; -// use content; +use content::ShowStack; +use std::rc::Rc; #[derive(Debug, Clone)] pub struct PodcastWidget { @@ -47,18 +48,18 @@ impl PodcastWidget { } } - pub fn new_initialized(stack: >k::Stack, pd: &Podcast) -> PodcastWidget { + pub fn new_initialized(shows: Rc, pd: &Podcast) -> PodcastWidget { let pdw = PodcastWidget::new(); - pdw.init(stack, pd); + pdw.init(shows, pd); pdw } - pub fn init(&self, stack: >k::Stack, pd: &Podcast) { + pub fn init(&self, shows: Rc, pd: &Podcast) { WidgetExt::set_name(&self.container, &pd.id().to_string()); // TODO: should spawn a thread to avoid locking the UI probably. - self.unsub.connect_clicked(clone!(stack, pd => move |bttn| { - on_unsub_button_clicked(&stack, &pd, bttn); + self.unsub.connect_clicked(clone!(shows, pd => move |bttn| { + on_unsub_button_clicked(shows.clone(), &pd, bttn); })); self.title.set_text(pd.title()); @@ -77,8 +78,8 @@ impl PodcastWidget { self.cover.set_from_pixbuf(&i); } - self.played.connect_clicked(clone!(stack, pd => move |_| { - on_played_button_clicked(&stack, &pd); + self.played.connect_clicked(clone!(shows, pd => move |_| { + on_played_button_clicked(shows.clone(), &pd); })); self.show_played_button(pd); @@ -95,7 +96,7 @@ impl PodcastWidget { } } -fn on_unsub_button_clicked(stack: >k::Stack, pd: &Podcast, unsub_button: >k::Button) { +fn on_unsub_button_clicked(shows: Rc, pd: &Podcast, unsub_button: >k::Button) { let res = dbqueries::remove_feed(pd); if res.is_ok() { info!("{} was removed succesfully.", pd.title()); @@ -111,11 +112,12 @@ fn on_unsub_button_clicked(stack: >k::Stack, pd: &Podcast, unsub_button: >k: } }; } - // content::update_podcasts(stack); + shows.switch_podcasts_animated(); + shows.update_podcasts(); } -fn on_played_button_clicked(stack: >k::Stack, pd: &Podcast) { +fn on_played_button_clicked(shows: Rc, pd: &Podcast) { let _ = dbqueries::update_none_to_played_now(pd); - // content::update_widget_preserve_vis(stack, pd); + shows.update_widget(); } From d5d55d4ef30cc2dc6cd7a5c13bc4aa5bf6420707 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 12 Dec 2017 16:51:24 +0200 Subject: [PATCH 011/278] Update dependancies. --- Cargo.lock | 78 +++++++++++++++++------------------ hammond-downloader/Cargo.toml | 4 +- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 910f55f..95d51b2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,7 +91,7 @@ dependencies = [ [[package]] name = "base64" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -590,7 +590,7 @@ dependencies = [ "diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "hammond-data 0.1.0", - "hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -636,10 +636,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.11.7" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", @@ -650,7 +650,7 @@ dependencies = [ "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -663,9 +663,9 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -897,8 +897,8 @@ name = "native-tls" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "openssl 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -963,19 +963,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "openssl" -version = "0.9.22" +version = "0.9.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.22" +version = "0.9.23" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1144,7 +1144,7 @@ dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1168,16 +1168,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1220,13 +1220,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "schannel" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1281,18 +1281,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_json" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1302,7 +1302,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1335,7 +1335,7 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1409,10 +1409,10 @@ dependencies = [ [[package]] name = "thread_local" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1429,7 +1429,7 @@ dependencies = [ [[package]] name = "tokio-core" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1464,7 +1464,7 @@ dependencies = [ "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1484,7 +1484,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1619,7 +1619,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" "checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" -"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9" +"checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" @@ -1672,7 +1672,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum gtk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "905fcfbaaad1b44ec0b4bba9e4d527d728284c62bc2ba41fccedace2b096766f" "checksum html5ever 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba3a1fd1857a714d410c191364c5d7bf8a6487c0ab5575146d37dd7eb17ef523" "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" -"checksum hyper 0.11.7 (registry+https://github.com/rust-lang/crates.io-index)" = "4959ca95f55df4265bff2ad63066147255e6fa733682cf6d1cb5eaff6e53324b" +"checksum hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e0594792d2109069d0caffd176f674d770a84adf024c5bb48e686b1ee5ac7659" "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" @@ -1709,8 +1709,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" "checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" -"checksum openssl 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "419ef26bb651d72b6c5a603bcc4e4856a362460e62352dfffa53de91d2e81181" -"checksum openssl-sys 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5483bdc56756041ba6aa37c9cb59cc2219f012a2a1377d97ad35556ac6676ee7" +"checksum openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "169a4b9160baf9b9b1ab975418c673686638995ba921683a7f1e01470dcb8854" +"checksum openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "2200ffec628e3f14c39fc0131a301db214f1a7d584e36507ee8700b0c7fb7a46" "checksum pango 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e81c404ab81ea7ea2fc2431a0a7672507b80e4b8bf4b41eac3fc83cc665104e" "checksum pango-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34f34a1be107fe16abb2744e0e206bee4b3b07460b5fddd3009a6aaf60bd69ab" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" @@ -1738,15 +1738,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum schannel 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7554288337c1110e34d7a2433518d889374c1de1a45f856b7bcddb03702131fc" +"checksum schannel 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "4330c2e874379fbd28fa67ba43239dbe8c7fb00662ceb1078bd37474f08bf5ce" "checksum scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a2ff3fc5223829be817806c6441279c676e454cc7da608faf03b0ccc09d3889" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" "checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" -"checksum serde 1.0.23 (registry+https://github.com/rust-lang/crates.io-index)" = "6a7c37d7f192f00041e8a613e936717923a71bc0c9051fc4425a49b104140f05" -"checksum serde_json 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "ea28ea0cca944668919bec6af209864a8dfe769fd2b0b723f36b22e20c1bf69f" +"checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1" +"checksum serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf5b0b5b4bd22eeecb7e01ac2e1225c7ef5e4272b79ee28a8392a8c8489c839" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" @@ -1761,9 +1761,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" "checksum tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9de21546595a0873061940d994bbbc5c35f024ae4fd61ec5c5b159115684f508" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum thread_local 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1697c4b57aeeb7a536b647165a2825faddffb1d3bad386d507709bd51a90bb14" +"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)" = "d5d788d3aa77bc0ef3e9621256885555368b47bd495c13dd2e7413c89f845520" -"checksum tokio-core 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "c843a027f7c1df5f81e7734a0df3f67bf329411781ebf36393ce67beef6071e3" +"checksum tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c87c27560184212c9dc45cd8f38623f37918248aad5b58fb65303b5d07a98c6e" "checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743" "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" diff --git a/hammond-downloader/Cargo.toml b/hammond-downloader/Cargo.toml index f063adc..ed50616 100644 --- a/hammond-downloader/Cargo.toml +++ b/hammond-downloader/Cargo.toml @@ -6,7 +6,7 @@ workspace = "../" [dependencies] error-chain = "0.11.0" -hyper = "0.11.7" +hyper = "0.11.9" log = "0.3.8" mime_guess = "1.8.3" reqwest = "0.8.1" @@ -14,7 +14,7 @@ tempdir = "0.3.5" [dependencies.diesel] features = ["sqlite"] -version = "0.99" +version = "0.99.0" [dependencies.hammond-data] path = "../hammond-data" From 5defb5867a2b429b07b3c40339aa5bc98641f63d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 13 Dec 2017 11:35:17 +0200 Subject: [PATCH 012/278] Move and rename stuff. --- hammond-gtk/src/content.rs | 13 +++++----- hammond-gtk/src/views/episodes.rs | 1 + hammond-gtk/src/views/mod.rs | 3 ++- .../src/views/{podcasts.rs => shows.rs} | 26 +++++++++---------- hammond-gtk/src/widgets/episode.rs | 2 -- hammond-gtk/src/widgets/mod.rs | 2 +- .../src/widgets/{podcast.rs => show.rs} | 12 ++++----- 7 files changed, 30 insertions(+), 29 deletions(-) create mode 100644 hammond-gtk/src/views/episodes.rs rename hammond-gtk/src/views/{podcasts.rs => shows.rs} (88%) rename hammond-gtk/src/widgets/{podcast.rs => show.rs} (95%) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 8214ab9..4e71505 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -4,9 +4,10 @@ use gtk::prelude::*; use hammond_data::Podcast; use hammond_data::dbqueries; -use views::podcasts::PopulatedView; +use views::shows::ShowsPopulated; use views::empty::EmptyView; -use widgets::podcast::PodcastWidget; + +use widgets::show::ShowWidget; use std::rc::Rc; @@ -50,8 +51,8 @@ impl ShowStack { let show = Rc::new(ShowStack { stack }); - let pop = PopulatedView::new_initialized(show.clone()); - let widget = PodcastWidget::new(); + let pop = ShowsPopulated::new_initialized(show.clone()); + let widget = ShowWidget::new(); let empty = EmptyView::new(); show.stack.add_named(&pop.container, "podcasts"); @@ -80,7 +81,7 @@ impl ShowStack { let vis = self.stack.get_visible_child_name().unwrap(); let old = self.stack.get_child_by_name("podcasts").unwrap(); - let pop = PopulatedView::new(); + let pop = ShowsPopulated::new(); pop.init(Rc::new(self.clone())); self.stack.remove(&old); @@ -99,7 +100,7 @@ impl ShowStack { pub fn replace_widget(&self, pd: &Podcast) { let old = self.stack.get_child_by_name("widget").unwrap(); - let new = PodcastWidget::new_initialized(Rc::new(self.clone()), pd); + let new = ShowWidget::new_initialized(Rc::new(self.clone()), pd); self.stack.remove(&old); self.stack.add_named(&new.container, "widget"); diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/hammond-gtk/src/views/episodes.rs @@ -0,0 +1 @@ + diff --git a/hammond-gtk/src/views/mod.rs b/hammond-gtk/src/views/mod.rs index 9c47e7d..a9ea1bf 100644 --- a/hammond-gtk/src/views/mod.rs +++ b/hammond-gtk/src/views/mod.rs @@ -1,2 +1,3 @@ -pub mod podcasts; +pub mod shows; +pub mod episodes; pub mod empty; diff --git a/hammond-gtk/src/views/podcasts.rs b/hammond-gtk/src/views/shows.rs similarity index 88% rename from hammond-gtk/src/views/podcasts.rs rename to hammond-gtk/src/views/shows.rs index 58c5f14..5b2ee98 100644 --- a/hammond-gtk/src/views/podcasts.rs +++ b/hammond-gtk/src/views/shows.rs @@ -12,14 +12,14 @@ use content::ShowStack; use std::rc::Rc; #[derive(Debug, Clone)] -pub struct PopulatedView { +pub struct ShowsPopulated { pub container: gtk::Box, pub flowbox: gtk::FlowBox, viewport: gtk::Viewport, } #[derive(Debug)] -struct PodcastChild { +struct ShowsChild { container: gtk::Box, title: gtk::Label, cover: gtk::Image, @@ -28,14 +28,14 @@ struct PodcastChild { child: gtk::FlowBoxChild, } -impl PopulatedView { - pub fn new() -> PopulatedView { +impl ShowsPopulated { + pub fn new() -> ShowsPopulated { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcasts_view.ui"); let container: gtk::Box = builder.get_object("fb_parent").unwrap(); let flowbox: gtk::FlowBox = builder.get_object("flowbox").unwrap(); let viewport: gtk::Viewport = builder.get_object("viewport").unwrap(); - PopulatedView { + ShowsPopulated { container, flowbox, viewport, @@ -43,8 +43,8 @@ impl PopulatedView { } #[allow(dead_code)] - pub fn new_initialized(show: Rc) -> PopulatedView { - let pop = PopulatedView::new(); + pub fn new_initialized(show: Rc) -> ShowsPopulated { + let pop = ShowsPopulated::new(); pop.init(show); pop } @@ -75,7 +75,7 @@ impl PopulatedView { if let Ok(pds) = podcasts { pds.iter().for_each(|parent| { - let flowbox_child = PodcastChild::new_initialized(parent); + let flowbox_child = ShowsChild::new_initialized(parent); self.flowbox.add(&flowbox_child.child); }); self.flowbox.show_all(); @@ -87,8 +87,8 @@ impl PopulatedView { } } -impl PodcastChild { - fn new() -> PodcastChild { +impl ShowsChild { + fn new() -> ShowsChild { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcasts_child.ui"); // Copy of gnome-music AlbumWidget @@ -101,7 +101,7 @@ impl PodcastChild { let child = gtk::FlowBoxChild::new(); child.add(&container); - PodcastChild { + ShowsChild { container, title, cover, @@ -123,8 +123,8 @@ impl PodcastChild { self.configure_banner(pd); } - pub fn new_initialized(pd: &Podcast) -> PodcastChild { - let child = PodcastChild::new(); + pub fn new_initialized(pd: &Podcast) -> ShowsChild { + let child = ShowsChild::new(); child.init(pd); child diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 7166d0c..e69efd1 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -13,8 +13,6 @@ use hammond_data::utils::*; use hammond_data::errors::*; use hammond_data::utils::replace_extra_spaces; -// use utils::html_to_markup; - use std::thread; use std::cell::RefCell; use std::sync::mpsc::{channel, Receiver}; diff --git a/hammond-gtk/src/widgets/mod.rs b/hammond-gtk/src/widgets/mod.rs index 5752aa3..d33f990 100644 --- a/hammond-gtk/src/widgets/mod.rs +++ b/hammond-gtk/src/widgets/mod.rs @@ -1,2 +1,2 @@ -pub mod podcast; +pub mod show; pub mod episode; diff --git a/hammond-gtk/src/widgets/podcast.rs b/hammond-gtk/src/widgets/show.rs similarity index 95% rename from hammond-gtk/src/widgets/podcast.rs rename to hammond-gtk/src/widgets/show.rs index 1d7f91b..b21bb06 100644 --- a/hammond-gtk/src/widgets/podcast.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -14,7 +14,7 @@ use content::ShowStack; use std::rc::Rc; #[derive(Debug, Clone)] -pub struct PodcastWidget { +pub struct ShowWidget { pub container: gtk::Box, cover: gtk::Image, title: gtk::Label, @@ -24,8 +24,8 @@ pub struct PodcastWidget { played: gtk::Button, } -impl PodcastWidget { - pub fn new() -> PodcastWidget { +impl ShowWidget { + pub fn new() -> ShowWidget { // Adapted from gnome-music AlbumWidget let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcast_widget.ui"); let container: gtk::Box = builder.get_object("podcast_widget").unwrap(); @@ -37,7 +37,7 @@ impl PodcastWidget { let unsub: gtk::Button = builder.get_object("unsub_button").unwrap(); let played: gtk::Button = builder.get_object("mark_all_played_button").unwrap(); - PodcastWidget { + ShowWidget { container, cover, title, @@ -48,8 +48,8 @@ impl PodcastWidget { } } - pub fn new_initialized(shows: Rc, pd: &Podcast) -> PodcastWidget { - let pdw = PodcastWidget::new(); + pub fn new_initialized(shows: Rc, pd: &Podcast) -> ShowWidget { + let pdw = ShowWidget::new(); pdw.init(shows, pd); pdw } From 82a59d80dd73376a527475cd39f134134253fc23 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 13 Dec 2017 11:53:56 +0200 Subject: [PATCH 013/278] Update README.md and CONTRIBUTING.md --- CONTRIBUTING.md | 14 +++++++++++--- README.md | 11 +---------- hammond-gtk/src/views/shows.rs | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f1f3d07..2e46fdc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,6 +20,12 @@ It is recommended to add a pre-commit hook to run cargo test and cargo fmt cargo test -- --test-threads=1 && cargo fmt --all -- --write-mode=diff ``` +## Running the test suite + +The test suite sets a temporary sqlite database in the /tmp folder. Due to that it's not possible to run them in parrallel. + +In order to run the test suite use the following: `cargo test -- --test-threads=1` + # Issues, issues and more issues! There are many ways you can contribute to Hammond, and all of them involve creating issues @@ -67,8 +73,10 @@ Steps to reproduce: ## Pull Request Process 1. Ensure your code compiles. Run `make` before creating the pull request. -2. If you're adding new API, it must be properly documented. -3. The commit message is formatted as follows: +2. Ensure the test suit passes. Run `cargo test -- --test-threads=1`. +3. Ensure your code is properly formated. Run `cargo fmt --all`. +4. If you're adding new API, it must be properly documented. +5. The commit message is formatted as follows: ``` component: @@ -78,7 +86,7 @@ Steps to reproduce: ``` -4. You may merge the pull request in once you have the sign-off of the maintainers, or if you +6. You may merge the pull request in once you have the sign-off of the maintainers, or if you do not have permission to do that, you may request the second reviewer to merge it for you. ## Code of Conduct diff --git a/README.md b/README.md index 89a8a06..4d25ca6 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,7 @@ This is a prototype of a podcast client written in Rust. ![podcast_widget](./assets/podcast_widget.png) ## Getting in Touch -If you have any questions regarding the -use or development of Hammond, want to discuss design or simply hang out, please join us in [#hammond on irc.gnome.org.](irc://irc.gnome.org/#hammond) +If you have any questions regarding the use or development of Hammond, want to discuss design or simply hang out, please join us in [#hammond on irc.gnome.org.](irc://irc.gnome.org/#hammond) Sidenote: @@ -70,14 +69,6 @@ cd Hammond/ cargo build --all ``` -## Call for designers - -Currently there no design plans or mockups. They are highly needed in order to advance the Gtk Client. - -There is the will for a complete client re-write if a someone contributes the mockups. - -If you happen to be a designer and want to contribute please hope on [#hammond](irc://irc.gnome.org/#hammond) and get in touch with us. - ## Contributing There alot of thins yet to be done. diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index 5b2ee98..bd9cf62 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -14,7 +14,7 @@ use std::rc::Rc; #[derive(Debug, Clone)] pub struct ShowsPopulated { pub container: gtk::Box, - pub flowbox: gtk::FlowBox, + flowbox: gtk::FlowBox, viewport: gtk::Viewport, } From 0a52f87f3a852e08804a6632bf94e9d30900ee51 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 13 Dec 2017 12:21:34 +0200 Subject: [PATCH 014/278] Rename glade files. --- .../resources/gtk/{podcast_widget.ui => show_widget.ui} | 0 .../resources/gtk/{podcasts_child.ui => shows_child.ui} | 0 .../resources/gtk/{podcasts_view.ui => shows_view.ui} | 0 hammond-gtk/resources/resources.xml | 6 +++--- hammond-gtk/src/views/shows.rs | 7 ++----- hammond-gtk/src/widgets/show.rs | 2 +- 6 files changed, 6 insertions(+), 9 deletions(-) rename hammond-gtk/resources/gtk/{podcast_widget.ui => show_widget.ui} (100%) rename hammond-gtk/resources/gtk/{podcasts_child.ui => shows_child.ui} (100%) rename hammond-gtk/resources/gtk/{podcasts_view.ui => shows_view.ui} (100%) diff --git a/hammond-gtk/resources/gtk/podcast_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui similarity index 100% rename from hammond-gtk/resources/gtk/podcast_widget.ui rename to hammond-gtk/resources/gtk/show_widget.ui diff --git a/hammond-gtk/resources/gtk/podcasts_child.ui b/hammond-gtk/resources/gtk/shows_child.ui similarity index 100% rename from hammond-gtk/resources/gtk/podcasts_child.ui rename to hammond-gtk/resources/gtk/shows_child.ui diff --git a/hammond-gtk/resources/gtk/podcasts_view.ui b/hammond-gtk/resources/gtk/shows_view.ui similarity index 100% rename from hammond-gtk/resources/gtk/podcasts_view.ui rename to hammond-gtk/resources/gtk/shows_view.ui diff --git a/hammond-gtk/resources/resources.xml b/hammond-gtk/resources/resources.xml index df3f3cd..e8bdc73 100644 --- a/hammond-gtk/resources/resources.xml +++ b/hammond-gtk/resources/resources.xml @@ -3,10 +3,10 @@ banner.png gtk/episode_widget.ui - gtk/podcast_widget.ui + gtk/show_widget.ui gtk/empty_view.ui - gtk/podcasts_view.ui - gtk/podcasts_child.ui + gtk/shows_view.ui + gtk/shows_child.ui gtk/headerbar.ui diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index bd9cf62..8e7b802 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -30,7 +30,7 @@ struct ShowsChild { impl ShowsPopulated { pub fn new() -> ShowsPopulated { - let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcasts_view.ui"); + let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/shows_view.ui"); let container: gtk::Box = builder.get_object("fb_parent").unwrap(); let flowbox: gtk::FlowBox = builder.get_object("flowbox").unwrap(); let viewport: gtk::Viewport = builder.get_object("viewport").unwrap(); @@ -53,10 +53,7 @@ impl ShowsPopulated { use gtk::WidgetExt; // TODO: handle unwraps. - // Note: flowbox_activation always adds "widnget" into the stack and switch to it, // TODO: implement back button. - // so back button should always remove "widget" and destroy it. - let show = show.clone(); self.flowbox .connect_child_activated(clone!(show => move |_, child| { // This is such an ugly hack... @@ -89,7 +86,7 @@ impl ShowsPopulated { impl ShowsChild { fn new() -> ShowsChild { - let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcasts_child.ui"); + let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/shows_child.ui"); // Copy of gnome-music AlbumWidget let container: gtk::Box = builder.get_object("fb_child").unwrap(); diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index b21bb06..1adcc3d 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -27,7 +27,7 @@ pub struct ShowWidget { impl ShowWidget { pub fn new() -> ShowWidget { // Adapted from gnome-music AlbumWidget - let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/podcast_widget.ui"); + let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/show_widget.ui"); let container: gtk::Box = builder.get_object("podcast_widget").unwrap(); let cover: gtk::Image = builder.get_object("cover").unwrap(); From 0bb0035f3c3c1bcf2c3aa8fcb9b4e57611d282ec Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 13 Dec 2017 13:53:15 +0200 Subject: [PATCH 015/278] Rework of the Headerbar. Added a stack to switch between a normal and a BackButton view. Also added a centered stack switcher and removed the Home button. Backbutton is not wired yet. --- hammond-gtk/resources/gtk/headerbar.ui | 113 ++++++++++++++++++++++--- hammond-gtk/src/headerbar.rs | 15 +++- 2 files changed, 113 insertions(+), 15 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index fc17ce5..0946f21 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -1,5 +1,5 @@ - + @@ -109,20 +109,70 @@ - + True False - False - True - + + True + True + True + + + True + False + go-previous-symbolic + + + + + False + False + 0 + + + + + True + False + Show Title + + + + + + True + True + 1 + + + + + False + True + + + True + False + True + + + + + + + + True + False + 5 + + True True False Add a new feed - center - + True False gtk-add @@ -135,26 +185,63 @@ - 1 + False + False + 0 - + True False center True + 0 + False + True + 4 + + + + + True + True + True + + + True + False + open-menu-symbolic + + + + + False + False + end 2 - + + True + False + vertical + + + False + True + end + 3 + + + + True True True - center True True @@ -167,8 +254,10 @@ + False + False end - -1 + 3 diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 140eac2..1a8d6b4 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -15,24 +15,33 @@ pub struct Header { refresh: gtk::Button, add_toggle: gtk::MenuButton, switch: gtk::StackSwitcher, + stack: gtk::Stack, } impl Header { pub fn new() -> Header { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); - let header: gtk::HeaderBar = builder.get_object("headerbar1").unwrap(); - let refresh: gtk::Button = builder.get_object("refbutton").unwrap(); - let add_toggle: gtk::MenuButton = builder.get_object("add-toggle-button").unwrap(); + let header: gtk::HeaderBar = builder.get_object("headerbar").unwrap(); + let refresh: gtk::Button = builder.get_object("ref_button").unwrap(); + let add_toggle: gtk::MenuButton = builder.get_object("add_toggle_button").unwrap(); let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); + let stack: gtk::Stack = builder.get_object("headerbar_stack").unwrap(); + let normal_view: gtk::Box = builder.get_object("normal_view").unwrap(); + let back_view: gtk::Box = builder.get_object("back_view").unwrap(); switch.set_halign(gtk::Align::Center); switch.show(); + stack.add_named(&normal_view, "normal_view"); + stack.add_named(&back_view, "back_view"); + stack.set_visible_child_name("normal_view"); + Header { container: header, refresh, add_toggle, switch, + stack, } } From d74aa9c625546a9dc9605511fef03a8741f0d01b Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 13 Dec 2017 16:36:40 +0200 Subject: [PATCH 016/278] Wire Headerbar back button and change initialiazation order. --- hammond-gtk/resources/gtk/headerbar.ui | 101 ++++++++++++++----------- hammond-gtk/src/content.rs | 25 ++++-- hammond-gtk/src/headerbar.rs | 54 ++++++++++--- hammond-gtk/src/main.rs | 14 ++-- hammond-gtk/src/views/shows.rs | 9 ++- hammond-gtk/src/widgets/show.rs | 9 ++- 6 files changed, 136 insertions(+), 76 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index 0946f21..2c53892 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -146,6 +146,19 @@ 1 + + + True + False + vertical + + + False + True + end + 2 + + False @@ -166,42 +179,16 @@ False 5 - - True - True - False - Add a new feed - - - True - False - gtk-add - True - 1 - - - - - - False - False - 0 - - - - + True False - center - True - 0 + vertical False True - 4 + end + 0 @@ -221,20 +208,7 @@ False False end - 2 - - - - - True - False - vertical - - - False - True - end - 3 + 1 @@ -257,8 +231,47 @@ False False end + 2 + + + + + True + True + False + Add a new feed + + + True + False + gtk-add + True + 1 + + + + + + False + False 3 + + + True + False + center + True + 0 + + + False + True + 4 + + diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 4e71505..c87f88f 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -8,20 +8,21 @@ use views::shows::ShowsPopulated; use views::empty::EmptyView; use widgets::show::ShowWidget; +use headerbar::Header; use std::rc::Rc; #[derive(Debug, Clone)] pub struct Content { pub stack: gtk::Stack, - shows: Rc, + pub shows: Rc, episodes: Rc, } impl Content { - pub fn new() -> Rc { + pub fn new(header: Rc
) -> Rc { let stack = gtk::Stack::new(); - let shows = ShowStack::new(); + let shows = ShowStack::new(header); let episodes = EpisodeStack::new(); stack.add_titled(&episodes.stack, "episodes", "Episodes"); @@ -38,20 +39,28 @@ impl Content { self.shows.update(); self.episodes.update(); } + + pub fn get_stack(&self) -> gtk::Stack { + self.stack.clone() + } } #[derive(Debug, Clone)] pub struct ShowStack { pub stack: gtk::Stack, + header: Rc
, } impl ShowStack { - fn new() -> Rc { + fn new(header: Rc
) -> Rc { let stack = gtk::Stack::new(); - let show = Rc::new(ShowStack { stack }); + let show = Rc::new(ShowStack { + stack, + header: header.clone(), + }); - let pop = ShowsPopulated::new_initialized(show.clone()); + let pop = ShowsPopulated::new_initialized(show.clone(), header); let widget = ShowWidget::new(); let empty = EmptyView::new(); @@ -82,7 +91,7 @@ impl ShowStack { let old = self.stack.get_child_by_name("podcasts").unwrap(); let pop = ShowsPopulated::new(); - pop.init(Rc::new(self.clone())); + pop.init(Rc::new(self.clone()), self.header.clone()); self.stack.remove(&old); self.stack.add_named(&pop.container, "podcasts"); @@ -100,7 +109,7 @@ impl ShowStack { pub fn replace_widget(&self, pd: &Podcast) { let old = self.stack.get_child_by_name("widget").unwrap(); - let new = ShowWidget::new_initialized(Rc::new(self.clone()), pd); + let new = ShowWidget::new_initialized(Rc::new(self.clone()), self.header.clone(), pd); self.stack.remove(&old); self.stack.add_named(&new.container, "widget"); diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 1a8d6b4..0aa98a9 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -16,10 +16,12 @@ pub struct Header { add_toggle: gtk::MenuButton, switch: gtk::StackSwitcher, stack: gtk::Stack, + back_button: gtk::Button, + show_title: gtk::Label, } impl Header { - pub fn new() -> Header { + pub fn new() -> Rc
{ let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let header: gtk::HeaderBar = builder.get_object("headerbar").unwrap(); @@ -29,29 +31,40 @@ impl Header { let stack: gtk::Stack = builder.get_object("headerbar_stack").unwrap(); let normal_view: gtk::Box = builder.get_object("normal_view").unwrap(); let back_view: gtk::Box = builder.get_object("back_view").unwrap(); + let back_button: gtk::Button = builder.get_object("back_button").unwrap(); + let show_title: gtk::Label = builder.get_object("show_title").unwrap(); + + let stack = stack.clone(); + back_button.connect_clicked(clone!(stack => move |_| { + stack.set_visible_child_name("normal_view"); + })); + switch.set_halign(gtk::Align::Center); switch.show(); stack.add_named(&normal_view, "normal_view"); stack.add_named(&back_view, "back_view"); + stack.set_transition_type(gtk::StackTransitionType::Crossfade); stack.set_visible_child_name("normal_view"); - Header { + Rc::new(Header { container: header, refresh, add_toggle, switch, stack, - } + back_button, + show_title, + }) } - pub fn new_initialized(content: Rc) -> Header { - let header = Header::new(); - header.init(content); - header - } + // pub fn new_initialized(content: Rc) -> Rc
{ + // let header = Header::new(); + // header.init(content); + // header + // } - fn init(&self, content: Rc) { + pub fn init(&self, content: Rc) { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let add_popover: gtk::Popover = builder.get_object("add-popover").unwrap(); @@ -73,9 +86,28 @@ impl Header { self.add_toggle.set_popover(&add_popover); // FIXME: There appears to be a memmory leak here. - self.refresh.connect_clicked(move |_| { + self.refresh.connect_clicked(clone!(content => move |_| { utils::refresh_feed(content.clone(), None, None); - }); + })); + + let stack = self.stack.clone(); + self.back_button + .connect_clicked(clone!(content => move |_| { + content.shows.stack.set_visible_child_full("podcasts", gtk::StackTransitionType::SlideLeft); + stack.set_visible_child_name("normal_view") + })); + } + + pub fn switch_to_normal(&self) { + self.stack.set_visible_child_name("normal_view") + } + + pub fn switch_to_back(&self) { + self.stack.set_visible_child_name("back_view") + } + + pub fn set_show_title(&self, title: &str) { + self.show_title.set_text(title) } } diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 77bd430..0c594b9 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -70,9 +70,13 @@ fn build_ui(app: >k::Application) { // let stack = ct.get_stack(); // let ct = content::Content::new_initialized(); - let ct = content::Content::new(); - let stack = ct.stack.clone(); - window.add(&stack); + + // Get the headerbar + let header = headerbar::Header::new(); + let ct = content::Content::new(header.clone()); + header.init(ct.clone()); + window.set_titlebar(&header.container); + window.add(&ct.get_stack()); window.connect_delete_event(|w, _| { w.destroy(); @@ -105,10 +109,6 @@ fn build_ui(app: >k::Application) { glib::Continue(false) }); - // Get the headerbar - let header = headerbar::Header::new_initialized(ct.clone()); - window.set_titlebar(&header.container); - window.show_all(); window.activate(); app.connect_activate(move |_| ()); diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index 8e7b802..affbb15 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -8,6 +8,7 @@ use hammond_data::Podcast; use utils::get_pixbuf_from_path; use content::ShowStack; +use headerbar::Header; use std::rc::Rc; @@ -43,13 +44,13 @@ impl ShowsPopulated { } #[allow(dead_code)] - pub fn new_initialized(show: Rc) -> ShowsPopulated { + pub fn new_initialized(show: Rc, header: Rc
) -> ShowsPopulated { let pop = ShowsPopulated::new(); - pop.init(show); + pop.init(show, header); pop } - pub fn init(&self, show: Rc) { + pub fn init(&self, show: Rc, header: Rc
) { use gtk::WidgetExt; // TODO: handle unwraps. @@ -61,6 +62,8 @@ impl ShowsPopulated { let pd = dbqueries::get_podcast_from_id(id).unwrap(); show.replace_widget(&pd); + header.set_show_title(pd.title()); + header.switch_to_back(); show.switch_widget_animated(); })); // Populate the flowbox with the Podcasts. diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 1adcc3d..99da2b8 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -11,6 +11,8 @@ use hammond_downloader::downloader; use widgets::episode::episodes_listbox; use utils::get_pixbuf_from_path; use content::ShowStack; +use headerbar::Header; + use std::rc::Rc; #[derive(Debug, Clone)] @@ -48,18 +50,19 @@ impl ShowWidget { } } - pub fn new_initialized(shows: Rc, pd: &Podcast) -> ShowWidget { + pub fn new_initialized(shows: Rc, header: Rc
, pd: &Podcast) -> ShowWidget { let pdw = ShowWidget::new(); - pdw.init(shows, pd); + pdw.init(shows, header, pd); pdw } - pub fn init(&self, shows: Rc, pd: &Podcast) { + pub fn init(&self, shows: Rc, header: Rc
, pd: &Podcast) { WidgetExt::set_name(&self.container, &pd.id().to_string()); // TODO: should spawn a thread to avoid locking the UI probably. self.unsub.connect_clicked(clone!(shows, pd => move |bttn| { on_unsub_button_clicked(shows.clone(), &pd, bttn); + header.switch_to_normal(); })); self.title.set_text(pd.title()); From f0de6bfb1b272a1477769fc8025b71cfba6d711e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 13 Dec 2017 17:58:55 +0200 Subject: [PATCH 017/278] Use symbolic icons instead. --- hammond-gtk/resources/gtk/episode_widget.ui | 26 ++++++++++----------- hammond-gtk/resources/gtk/headerbar.ui | 6 ++--- hammond-gtk/resources/gtk/show_widget.ui | 8 +++---- 3 files changed, 17 insertions(+), 23 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index fdfacf7..6b85d48 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -1,5 +1,5 @@ - + @@ -11,26 +11,23 @@ 5 5 - + + delete_button True True end center - 5 - 5 True False - gtk-media-play - True + edit-delete-symbolic False False - 5 end 0 @@ -49,8 +46,7 @@ True False - gtk-save - True + document-save-symbolic @@ -63,23 +59,25 @@ - - delete_button + True True end center + 5 + 5 True False - gtk-delete + media-playback-start-symbolic False False + 5 end 0 @@ -95,7 +93,7 @@ True False - gtk-undo + edit-undo-symbolic @@ -118,7 +116,7 @@ True False - gtk-apply + object-select-symbolic diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index 2c53892..b06d65e 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -222,8 +222,7 @@ True False - gtk-refresh - True + view-refresh-symbolic
@@ -244,8 +243,7 @@ True False - gtk-add - True + list-add-symbolic 1
diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index 0241f05..9fd63c6 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -1,5 +1,5 @@ - + @@ -35,8 +35,6 @@ 1 1 1 - gtk-missing-image - True False @@ -95,7 +93,7 @@ False Unsubrscribe from this Podcast. Warn: This will delete downloaded content associated with this Podcast. - gtk-delete + edit-delete-symbolic
@@ -118,7 +116,7 @@ Warn: This will delete downloaded content associated with this Podcast. True False - gtk-apply + object-select-symbolic
From fe136c8dbefd8d201f549f805b799567c434258a Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 14 Dec 2017 08:42:52 +0200 Subject: [PATCH 018/278] use user-trash-symbolic instead of edit-delete-symbolic icon. --- hammond-gtk/resources/gtk/episode_widget.ui | 16 ++++++++-------- hammond-gtk/resources/gtk/show_widget.ui | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 6b85d48..71d846c 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -11,23 +11,25 @@ 5 5 - - delete_button + True True end center + 5 + 5 True False - edit-delete-symbolic + media-playback-start-symbolic False False + 5 end 0 @@ -59,25 +61,23 @@ - + + delete_button True True end center - 5 - 5 True False - media-playback-start-symbolic + user-trash-symbolic False False - 5 end 0 diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index 9fd63c6..6b30d01 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -93,7 +93,7 @@ False Unsubrscribe from this Podcast. Warn: This will delete downloaded content associated with this Podcast. - edit-delete-symbolic + user-trash-symbolic From ebbebf77354bd69c042d0021440f9627aae9a07b Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 14 Dec 2017 10:57:29 +0200 Subject: [PATCH 019/278] Initial implementation of the new EpisodeWidget. --- hammond-gtk/resources/gtk/episode_widget.ui | 301 ++++++++++---------- hammond-gtk/src/widgets/episode.rs | 138 ++++----- scripts/release.sh | 2 +- 3 files changed, 211 insertions(+), 230 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 71d846c..350caea 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -2,190 +2,171 @@ - - 100 - 25 + True False - 5 - 5 - 5 - - - True - True - end - center - 5 - 5 - - - True - False - media-playback-start-symbolic - - - - - False - False - 5 - end - 0 - - - - - True - True - True - end - center - 5 - 5 - True - - - True - False - document-save-symbolic - - - - - False - False - 5 - end - 0 - - - - - delete_button - True - True - end - center - - - True - False - user-trash-symbolic - - - - - False - False - end - 0 - - - - - True - True - Mark episode as Unplayed. - end - center - - - True - False - edit-undo-symbolic - - - - - False - False - end - 1 - - - - - True - True - True - Mark episode as played. - end - center - - - True - False - object-select-symbolic - - - - - False - False - end - 2 - - + vertical True False - vertical + 5 - + True False - start - center - True - True - end - 1 + vertical + 5 + + + True + False + start + Episode Title + True + True + end + 1 + + + True + True + 0 + + + + + True + False + 5 + + + True + False + 42 min + + + False + True + 0 + + + + + True + False + document-save-symbolic + + + False + True + 1 + + + + + True + True + 1 + + - False - False + True + True + 5 0 - + True - True - True + False - - True + + Cancel True - in - 100 - 600 - True - True + True + + + False + True + 5 + end + 0 + + + + + delete_button + True + True + end - + True - True - 5 - False - word-char - False + False + user-trash-symbolic + + False + False + 5 + end + 1 + - - + + True - False - Description: + True + True + end + True + + + True + False + document-save-symbolic + + + + False + False + 5 + end + 2 + + + + + True + True + end + + + True + False + media-playback-start-symbolic + + + + + False + False + 5 + end + 3 + False True + 5 1 @@ -193,7 +174,19 @@ True True - 3 + 5 + 0 + + + + + False + + + False + True + 5 + 1 diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index e69efd1..020341c 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -1,68 +1,75 @@ use glib; use gtk; use gtk::prelude::*; -use gtk::{ContainerExt, TextBufferExt}; use open; -use dissolve::strip_html_tags; use hammond_data::dbqueries; use hammond_data::{Episode, Podcast}; use hammond_downloader::downloader; use hammond_data::utils::*; use hammond_data::errors::*; -use hammond_data::utils::replace_extra_spaces; use std::thread; use std::cell::RefCell; use std::sync::mpsc::{channel, Receiver}; use std::path::Path; -type Foo = RefCell)>>; +type Foo = RefCell< + Option< + ( + gtk::Button, + gtk::Button, + gtk::Button, + gtk::Button, + gtk::ProgressBar, + Receiver, + ), + >, +>; thread_local!(static GLOBAL: Foo = RefCell::new(None)); #[derive(Debug)] struct EpisodeWidget { container: gtk::Box, - download: gtk::Button, play: gtk::Button, delete: gtk::Button, - played: gtk::Button, - unplayed: gtk::Button, + download: gtk::Button, + cancel: gtk::Button, title: gtk::Label, - description: gtk::TextView, - // description: gtk::Label, - expander: gtk::Expander, + duration: gtk::Label, + progress: gtk::ProgressBar, + an_indicator: gtk::Image, } impl EpisodeWidget { fn new() -> EpisodeWidget { - // This is just a prototype and will be reworked probably. let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episode_widget.ui"); - let container: gtk::Box = builder.get_object("episode_box").unwrap(); + let container: gtk::Box = builder.get_object("episode_container").unwrap(); + + let progress: gtk::ProgressBar = builder.get_object("progress_bar").unwrap(); + let an_indicator: gtk::Image = builder.get_object("an_indicator").unwrap(); + let download: gtk::Button = builder.get_object("download_button").unwrap(); let play: gtk::Button = builder.get_object("play_button").unwrap(); let delete: gtk::Button = builder.get_object("delete_button").unwrap(); - let played: gtk::Button = builder.get_object("mark_played_button").unwrap(); - let unplayed: gtk::Button = builder.get_object("mark_unplayed_button").unwrap(); + let cancel: gtk::Button = builder.get_object("cancel_button").unwrap(); let title: gtk::Label = builder.get_object("title_label").unwrap(); - let expander: gtk::Expander = builder.get_object("expand_desc").unwrap(); - let description: gtk::TextView = builder.get_object("desc_text_view").unwrap(); - // let description: gtk::Label = builder.get_object("desc_text").unwrap(); + let duration: gtk::Label = builder.get_object("duration_label").unwrap(); EpisodeWidget { container, + progress, + an_indicator, download, play, + cancel, delete, - played, - unplayed, title, - expander, - description, + duration, } } @@ -76,27 +83,6 @@ impl EpisodeWidget { self.title.set_xalign(0.0); self.title.set_text(episode.title()); - if episode.description().is_some() { - let text = episode.description().unwrap().to_owned(); - let description = &self.description; - self.expander - .connect_activate(clone!(description, text => move |_| { - // let mut text = text.clone(); - // html_to_markup(&mut text); - // description.set_markup(&text) - - let plain_text = strip_html_tags(&text).join(" "); - // TODO: handle unwrap - let buff = description.get_buffer().unwrap(); - buff.set_text(&replace_extra_spaces(&plain_text)); - })); - } - - if episode.played().is_some() { - self.unplayed.show(); - self.played.hide(); - } - // Show or hide the play/delete/download buttons upon widget initialization. let local_uri = episode.local_uri(); if local_uri.is_some() && Path::new(local_uri.unwrap()).exists() { @@ -105,15 +91,10 @@ impl EpisodeWidget { self.delete.show(); } - let played = &self.played; - let unplayed = &self.unplayed; - self.play - .connect_clicked(clone!(episode, played, unplayed => move |_| { + self.play.connect_clicked(clone!(episode => move |_| { let mut episode = episode.clone(); on_play_bttn_clicked(episode.rowid()); let _ = episode.set_played_now(); - played.hide(); - unplayed.show(); })); let play = &self.play; @@ -126,38 +107,24 @@ impl EpisodeWidget { download.show(); })); - let unplayed = &self.unplayed; - self.played - .connect_clicked(clone!(episode, unplayed => move |played| { - let mut episode = episode.clone(); - let _ = episode.set_played_now(); - played.hide(); - unplayed.show(); - })); - - let played = &self.played; - self.unplayed - .connect_clicked(clone!(episode, played => move |un| { - let mut episode = episode.clone(); - episode.set_played(None); - let _ = episode.save(); - un.hide(); - played.show(); - })); - let pd_title = pd.title().to_owned(); let play = &self.play; let delete = &self.delete; - self.download - .connect_clicked(clone!(play, delete, episode => move |dl| { + let cancel = &self.cancel; + let progress = &self.progress; + self.download.connect_clicked( + clone!(play, delete, episode, cancel, progress => move |dl| { on_download_clicked( &pd_title, &mut episode.clone(), dl, &play, &delete, + &cancel, + &progress ); - })); + }), + ); } } @@ -168,17 +135,30 @@ fn on_download_clicked( download_bttn: >k::Button, play_bttn: >k::Button, del_bttn: >k::Button, + cancel_bttn: >k::Button, + progress_bar: >k::ProgressBar, ) { // Create a async channel. let (sender, receiver) = channel(); // Pass the desired arguments into the Local Thread Storage. - GLOBAL.with(clone!(download_bttn, play_bttn, del_bttn => move |global| { - *global.borrow_mut() = Some((download_bttn, play_bttn, del_bttn, receiver)); - })); + GLOBAL.with( + clone!(download_bttn, play_bttn, del_bttn, cancel_bttn, progress_bar => move |global| { + *global.borrow_mut() = Some(( + download_bttn, + play_bttn, + del_bttn, + cancel_bttn, + progress_bar, + receiver)); + }), + ); let pd_title = pd_title.to_owned(); let mut ep = ep.clone(); + cancel_bttn.show(); + progress_bar.show(); + download_bttn.hide(); thread::spawn(move || { let download_fold = downloader::get_download_folder(&pd_title).unwrap(); let e = downloader::get_episode(&mut ep, download_fold.as_str()); @@ -223,13 +203,21 @@ fn on_delete_bttn_clicked(episode_id: i32) { fn receive() -> glib::Continue { GLOBAL.with(|global| { - if let Some((ref download_bttn, ref play_bttn, ref del_bttn, ref reciever)) = - *global.borrow() + if let Some(( + ref download_bttn, + ref play_bttn, + ref del_bttn, + ref cancel_bttn, + ref progress_bar, + ref reciever, + )) = *global.borrow() { if reciever.try_recv().is_ok() { download_bttn.hide(); play_bttn.show(); del_bttn.show(); + cancel_bttn.hide(); + progress_bar.hide(); } } }); diff --git a/scripts/release.sh b/scripts/release.sh index cced5a7..c393955 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -35,5 +35,5 @@ cp -rf vendor $DIST/ # packaging cd $DEST/dist -tar -czvf $VERSION.tar.gz $VERSION +tar -cJvf $VERSION.tar.xz $VERSION From 8fe6b526a54b3ac363412cc81659967f642972c0 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 14 Dec 2017 12:01:35 +0200 Subject: [PATCH 020/278] Add a new Diesel Model for the EpisodeWidget. --- hammond-data/src/dbqueries.rs | 17 +++- hammond-data/src/lib.rs | 2 +- hammond-data/src/models/queryables.rs | 129 ++++++++++++++++++++++++++ hammond-downloader/src/downloader.rs | 4 +- hammond-gtk/src/widgets/episode.rs | 15 +-- 5 files changed, 157 insertions(+), 10 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 391ec6e..f1bb8dd 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -2,7 +2,7 @@ use diesel::prelude::*; use diesel; -use models::queryables::{Episode, Podcast, Source}; +use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, Source}; use chrono::prelude::*; use errors::*; @@ -103,6 +103,21 @@ pub fn get_pd_episodes(parent: &Podcast) -> Result> { .load::(&*con)?) } +pub fn get_pd_episodeswidgets(parent: &Podcast) -> Result> { + use schema::episode::dsl::*; + + let db = connection(); + let con = db.get()?; + + Ok( + episode.select((rowid, title, uri, local_uri, epoch, length, played, podcast_id)) + .filter(podcast_id.eq(parent.id())) + // .group_by(epoch) + .order(epoch.desc()) + .load::(&*con)?, + ) +} + pub fn get_pd_unplayed_episodes(parent: &Podcast) -> Result> { use schema::episode::dsl::*; diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index c562fbd..97aec76 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -61,7 +61,7 @@ pub(crate) mod models; mod parser; mod schema; -pub use models::queryables::{Episode, Podcast, Source}; +pub use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, Source}; /// [XDG Base Direcotory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) Paths. #[allow(missing_debug_implementations)] diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index f0cab54..e8ae722 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -1,4 +1,6 @@ use chrono::prelude::*; +use diesel::prelude::*; +use diesel; use reqwest; use diesel::SaveChangesDsl; @@ -189,6 +191,133 @@ impl Episode { } } +#[derive(Queryable, AsChangeset, PartialEq)] +#[table_name = "episode"] +#[changeset_options(treat_none_as_null = "true")] +#[primary_key(title, podcast_id)] +#[derive(Debug, Clone)] +/// Diesel Model to be used for constructing `EpisodeWidgets`. +pub struct EpisodeWidgetQuery { + rowid: i32, + title: String, + uri: Option, + local_uri: Option, + epoch: i32, + length: Option, + played: Option, + // favorite: bool, + // archive: bool, + podcast_id: i32, +} + +impl EpisodeWidgetQuery { + /// Get the value of the sqlite's `ROW_ID` + pub fn rowid(&self) -> i32 { + self.rowid + } + + /// Get the value of the `title` field. + pub fn title(&self) -> &str { + &self.title + } + + /// Get the value of the `uri`. + /// + /// Represents the url(usually) that the media file will be located at. + pub fn uri(&self) -> Option<&str> { + self.uri.as_ref().map(|s| s.as_str()) + } + + /// Get the value of the `local_uri`. + /// + /// Represents the local uri,usually filesystem path, + /// that the media file will be located at. + pub fn local_uri(&self) -> Option<&str> { + self.local_uri.as_ref().map(|s| s.as_str()) + } + + /// Set the `local_uri`. + pub fn set_local_uri(&mut self, value: Option<&str>) { + self.local_uri = value.map(|x| x.to_string()); + } + + /// Get the `epoch` value. + /// + /// Retrieved from the rss Item publish date. + /// Value is set to Utc whenever possible. + pub fn epoch(&self) -> i32 { + self.epoch + } + + /// Get the `length`. + pub fn length(&self) -> Option { + self.length + } + + /// Set the `length`. + pub fn set_length(&mut self, value: Option) { + self.length = value; + } + + /// Epoch representation of the last time the episode was played. + /// + /// None/Null for unplayed. + pub fn played(&self) -> Option { + self.played + } + + /// Set the `played` value. + pub fn set_played(&mut self, value: Option) { + self.played = value; + } + + // /// Represents the archiving policy for the episode. + // pub fn archive(&self) -> bool { + // self.archive + // } + + // /// Set the `archive` policy. + // /// + // /// If true, the download cleanr will ignore the episode + // /// and the corresponding media value will never be automaticly deleted. + // pub fn set_archive(&mut self, b: bool) { + // self.archive = b + // } + + // /// Get the `favorite` status of the `Episode`. + // pub fn favorite(&self) -> bool { + // self.favorite + // } + + // /// Set `favorite` status. + // pub fn set_favorite(&mut self, b: bool) { + // self.favorite = b + // } + + /// `Podcast` table foreign key. + pub fn podcast_id(&self) -> i32 { + self.podcast_id + } + + /// Sets the `played` value with the current `epoch` timestap and save it. + pub fn set_played_now(&mut self) -> Result<()> { + let epoch = Utc::now().timestamp() as i32; + self.set_played(Some(epoch)); + self.save()?; + Ok(()) + } + + /// Helper method to easily save/"sync" current state of self to the Database. + pub fn save(&self) -> Result { + use schema::episode::dsl::*; + + let db = connection(); + let tempdb = db.get()?; + + Ok(diesel::update(episode).set(self).execute(&*tempdb)?) + } +} + #[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] #[belongs_to(Source, foreign_key = "source_id")] #[changeset_options(treat_none_as_null = "true")] diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index fafd726..4343e91 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -8,7 +8,7 @@ use std::io::{BufWriter, Read, Write}; use std::path::Path; use errors::*; -use hammond_data::{Episode, Podcast}; +use hammond_data::{Episode, EpisodeWidgetQuery, Podcast}; use hammond_data::xdg_dirs::{DL_DIR, HAMMOND_CACHE}; // TODO: Replace path that are of type &str with std::path. @@ -106,7 +106,7 @@ pub fn get_download_folder(pd_title: &str) -> Result { } // TODO: Refactor -pub fn get_episode(ep: &mut Episode, download_folder: &str) -> Result<()> { +pub fn get_episode(ep: &mut EpisodeWidgetQuery, download_folder: &str) -> Result<()> { // Check if its alrdy downloaded if ep.local_uri().is_some() { if Path::new(ep.local_uri().unwrap()).exists() { diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 020341c..89dbf1e 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -5,10 +5,10 @@ use gtk::prelude::*; use open; use hammond_data::dbqueries; -use hammond_data::{Episode, Podcast}; -use hammond_downloader::downloader; +use hammond_data::{EpisodeWidgetQuery, Podcast}; use hammond_data::utils::*; use hammond_data::errors::*; +use hammond_downloader::downloader; use std::thread; use std::cell::RefCell; @@ -73,13 +73,16 @@ impl EpisodeWidget { } } - pub fn new_initialized(episode: &mut Episode, pd: &Podcast) -> EpisodeWidget { + pub fn new_initialized(episode: &mut EpisodeWidgetQuery, pd: &Podcast) -> EpisodeWidget { let widget = EpisodeWidget::new(); widget.init(episode, pd); widget } - fn init(&self, episode: &mut Episode, pd: &Podcast) { + // TODO: calculate lenght. + // TODO: wire the progress_bar to the downloader. + // TODO: wire the cancel button. + fn init(&self, episode: &mut EpisodeWidgetQuery, pd: &Podcast) { self.title.set_xalign(0.0); self.title.set_text(episode.title()); @@ -131,7 +134,7 @@ impl EpisodeWidget { // TODO: show notification when dl is finished. fn on_download_clicked( pd_title: &str, - ep: &mut Episode, + ep: &mut EpisodeWidgetQuery, download_bttn: >k::Button, play_bttn: >k::Button, del_bttn: >k::Button, @@ -225,7 +228,7 @@ fn receive() -> glib::Continue { } pub fn episodes_listbox(pd: &Podcast) -> Result { - let episodes = dbqueries::get_pd_episodes(pd)?; + let episodes = dbqueries::get_pd_episodeswidgets(pd)?; let list = gtk::ListBox::new(); episodes.into_iter().for_each(|mut ep| { From afdb79b71258cab8c97e08e3c7df3aff7702684f Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 14 Dec 2017 13:38:18 +0200 Subject: [PATCH 021/278] Set the progress bar into activity mode. --- hammond-data/src/models/queryables.rs | 4 +++- hammond-gtk/resources/gtk/episode_widget.ui | 1 - hammond-gtk/src/widgets/episode.rs | 8 +++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index e8ae722..4290979 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -314,7 +314,9 @@ impl EpisodeWidgetQuery { let db = connection(); let tempdb = db.get()?; - Ok(diesel::update(episode).set(self).execute(&*tempdb)?) + Ok(diesel::update(episode.filter(rowid.eq(self.rowid))) + .set(self) + .execute(&*tempdb)?) } } diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 350caea..a6b5c6b 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -53,7 +53,6 @@ - True False document-save-symbolic diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 89dbf1e..d6d8a1e 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -85,6 +85,13 @@ impl EpisodeWidget { fn init(&self, episode: &mut EpisodeWidgetQuery, pd: &Podcast) { self.title.set_xalign(0.0); self.title.set_text(episode.title()); + self.progress.set_pulse_step(0.1); + + let progress = self.progress.clone(); + timeout_add(200, move || { + progress.pulse(); + glib::Continue(true) + }); // Show or hide the play/delete/download buttons upon widget initialization. let local_uri = episode.local_uri(); @@ -232,7 +239,6 @@ pub fn episodes_listbox(pd: &Podcast) -> Result { let list = gtk::ListBox::new(); episodes.into_iter().for_each(|mut ep| { - // let w = epidose_widget(&mut ep, pd.title()); let widget = EpisodeWidget::new_initialized(&mut ep, pd); list.add(&widget.container) }); From 9d07ba24b85a36c369220bca2ba241ef2d4c8053 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 14 Dec 2017 14:27:51 +0200 Subject: [PATCH 022/278] HeaderBar Refactor. Removed the Headerbar stack. Removed the ShowTitle. Fixed StackSwitcher centering. Set the Headerbar button valignment to center instead of fill. --- hammond-gtk/resources/gtk/headerbar.ui | 157 +++++++------------------ hammond-gtk/src/headerbar.rs | 55 ++++----- hammond-gtk/src/views/shows.rs | 2 +- 3 files changed, 65 insertions(+), 149 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index b06d65e..b35599d 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -109,93 +109,66 @@ - - True - False - - - True - True - True - - - True - False - go-previous-symbolic - - - - - False - False - 0 - - - - - True - False - Show Title - - - - - - True - True - 1 - - - - - True - False - vertical - - - False - True - end - 2 - - - False True - - + + True - False - True + True + False + Add a new feed + center - + + True + False + list-add-symbolic + 1 + + - - - True - False - 5 - - True - False - vertical + + True + False + True + Back + center + + + True + False + go-previous-symbolic + 1 + + + - False - True - end - 0 + 1 + + + True + False + center + center + + True True True + center True @@ -205,10 +178,7 @@ - False - False end - 1 @@ -216,6 +186,7 @@ True True True + center True True @@ -227,48 +198,8 @@ - False - False end - 2 - - - - - True - True - False - Add a new feed - - - True - False - list-add-symbolic - 1 - - - - - - False - False - 3 - - - - - True - False - center - True - 0 - - - False - True - 4 + 1 diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 0aa98a9..efa6931 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -15,9 +15,8 @@ pub struct Header { refresh: gtk::Button, add_toggle: gtk::MenuButton, switch: gtk::StackSwitcher, - stack: gtk::Stack, back_button: gtk::Button, - show_title: gtk::Label, + // show_title: gtk::Label, } impl Header { @@ -28,42 +27,21 @@ impl Header { let refresh: gtk::Button = builder.get_object("ref_button").unwrap(); let add_toggle: gtk::MenuButton = builder.get_object("add_toggle_button").unwrap(); let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); - let stack: gtk::Stack = builder.get_object("headerbar_stack").unwrap(); - let normal_view: gtk::Box = builder.get_object("normal_view").unwrap(); - let back_view: gtk::Box = builder.get_object("back_view").unwrap(); let back_button: gtk::Button = builder.get_object("back_button").unwrap(); - let show_title: gtk::Label = builder.get_object("show_title").unwrap(); - - let stack = stack.clone(); - back_button.connect_clicked(clone!(stack => move |_| { - stack.set_visible_child_name("normal_view"); - })); + // let show_title: gtk::Label = builder.get_object("show_title").unwrap(); switch.set_halign(gtk::Align::Center); switch.show(); - stack.add_named(&normal_view, "normal_view"); - stack.add_named(&back_view, "back_view"); - stack.set_transition_type(gtk::StackTransitionType::Crossfade); - stack.set_visible_child_name("normal_view"); - Rc::new(Header { container: header, refresh, add_toggle, switch, - stack, back_button, - show_title, }) } - // pub fn new_initialized(content: Rc) -> Rc
{ - // let header = Header::new(); - // header.init(content); - // header - // } - pub fn init(&self, content: Rc) { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); @@ -90,25 +68,32 @@ impl Header { utils::refresh_feed(content.clone(), None, None); })); - let stack = self.stack.clone(); + let switch = &self.switch; + let add_toggle = &self.add_toggle; self.back_button - .connect_clicked(clone!(content => move |_| { - content.shows.stack.set_visible_child_full("podcasts", gtk::StackTransitionType::SlideLeft); - stack.set_visible_child_name("normal_view") + .connect_clicked(clone!(content, switch, add_toggle => move |back| { + switch.show(); + add_toggle.show(); + back.hide(); + content.shows.stack.set_visible_child_full("podcasts", gtk::StackTransitionType::SlideRight); })); } - pub fn switch_to_normal(&self) { - self.stack.set_visible_child_name("normal_view") - } - pub fn switch_to_back(&self) { - self.stack.set_visible_child_name("back_view") + self.switch.hide(); + self.add_toggle.hide(); + self.back_button.show(); } - pub fn set_show_title(&self, title: &str) { - self.show_title.set_text(title) + pub fn switch_to_normal(&self) { + self.switch.show(); + self.add_toggle.show(); + self.back_button.hide(); } + + // pub fn set_show_title(&self, title: &str) { + // self.show_title.set_text(title) + // } } fn on_add_bttn_clicked(content: Rc, entry: >k::Entry) { diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index affbb15..5cb12b8 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -62,7 +62,7 @@ impl ShowsPopulated { let pd = dbqueries::get_podcast_from_id(id).unwrap(); show.replace_widget(&pd); - header.set_show_title(pd.title()); + // header.set_show_title(pd.title()); header.switch_to_back(); show.switch_widget_animated(); })); From a7208b0c61129fcbfb93a617f7903b85f4cdf5a4 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 14 Dec 2017 14:46:41 +0200 Subject: [PATCH 023/278] Set EpisodeWidget button valignment to center instead of fill. --- hammond-gtk/resources/gtk/episode_widget.ui | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index a6b5c6b..7cc0807 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -81,16 +81,17 @@ True False + 5 Cancel True True + center False True - 5 end 0 @@ -101,6 +102,7 @@ True True end + center True @@ -112,7 +114,6 @@ False False - 5 end 1 @@ -123,6 +124,7 @@ True True end + center True @@ -135,7 +137,6 @@ False False - 5 end 2 @@ -144,7 +145,7 @@ True True - end + center True @@ -156,7 +157,6 @@ False False - 5 end 3 From e3b540170a28630658e7818a48c87f761c8c7670 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 14 Dec 2017 15:32:21 +0200 Subject: [PATCH 024/278] Add file size indication based on rss item length. --- hammond-gtk/resources/gtk/episode_widget.ui | 14 +++++++++++++- hammond-gtk/src/widgets/episode.rs | 9 +++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 7cc0807..7e6106d 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -51,6 +51,18 @@ 0 + + + True + False + 42 mb + + + False + True + 1 + + False @@ -59,7 +71,7 @@ False True - 1 + 2 diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index d6d8a1e..746ea53 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -39,6 +39,7 @@ struct EpisodeWidget { cancel: gtk::Button, title: gtk::Label, duration: gtk::Label, + size: gtk::Label, progress: gtk::ProgressBar, an_indicator: gtk::Image, } @@ -59,6 +60,7 @@ impl EpisodeWidget { let title: gtk::Label = builder.get_object("title_label").unwrap(); let duration: gtk::Label = builder.get_object("duration_label").unwrap(); + let size: gtk::Label = builder.get_object("size_label").unwrap(); EpisodeWidget { container, @@ -70,6 +72,7 @@ impl EpisodeWidget { delete, title, duration, + size, } } @@ -83,6 +86,7 @@ impl EpisodeWidget { // TODO: wire the progress_bar to the downloader. // TODO: wire the cancel button. fn init(&self, episode: &mut EpisodeWidgetQuery, pd: &Podcast) { + self.duration.hide(); self.title.set_xalign(0.0); self.title.set_text(episode.title()); self.progress.set_pulse_step(0.1); @@ -93,6 +97,11 @@ impl EpisodeWidget { glib::Continue(true) }); + if let Some(size) = episode.length() { + let megabytes: f32 = size as f32 / 1024.0 / 1024.0; // episode.length represents bytes + self.size.set_text(&format!("{:.1} mb", megabytes)) + }; + // Show or hide the play/delete/download buttons upon widget initialization. let local_uri = episode.local_uri(); if local_uri.is_some() && Path::new(local_uri.unwrap()).exists() { From 0ac78fcff1cc81a5a4cfe81c7edb977bb5637ef5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 14 Dec 2017 18:03:37 +0200 Subject: [PATCH 025/278] Added date label into EpisodeWidget. --- Cargo.lock | 1 + hammond-data/src/parser.rs | 1 + hammond-gtk/Cargo.toml | 1 + hammond-gtk/resources/gtk/episode_widget.ui | 82 +++++++++++++++++---- hammond-gtk/src/main.rs | 1 + hammond-gtk/src/widgets/episode.rs | 22 ++++-- 6 files changed, 86 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95d51b2..500afb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -601,6 +601,7 @@ dependencies = [ name = "hammond-gtk" version = "0.1.0" dependencies = [ + "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)", "dissolve 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "gdk 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 393ac54..566b06f 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -33,6 +33,7 @@ pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast { } /// Parses an `rss::Item` into a `NewEpisode` Struct. +// TODO: parse itunes duration extension. pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { if item.title().is_none() { bail!("No title specified for the item.") diff --git a/hammond-gtk/Cargo.toml b/hammond-gtk/Cargo.toml index 810cbbb..b1cf01e 100644 --- a/hammond-gtk/Cargo.toml +++ b/hammond-gtk/Cargo.toml @@ -6,6 +6,7 @@ version = "0.1.0" workspace = "../" [dependencies] +chrono = "0.4.0" dissolve = "0.2.2" gdk = "0.7.0" gdk-pixbuf = "0.3.0" diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 7e6106d..2e7558e 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -18,15 +18,27 @@ vertical 5 - + True False - start - Episode Title - True - True - end - 1 + + + True + False + start + Episode Title + True + True + end + False + 1 + + + False + True + 0 + + True @@ -40,10 +52,11 @@ False 5 - + True False - 42 min + 1970/01/01 + False False @@ -52,10 +65,10 @@ - - True + False - 42 mb + True + · False @@ -64,9 +77,11 @@ - + False - document-save-symbolic + True + 42 min + False False @@ -74,6 +89,44 @@ 2 + + + True + False + · + + + False + True + 3 + + + + + True + False + 42 MB + False + + + False + True + 4 + + + + + False + True + 12 MB / 42 MB + False + + + False + True + 5 + + True @@ -185,7 +238,6 @@ True True - 5 0 diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 0c594b9..5b1bac6 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -6,6 +6,7 @@ extern crate gio; extern crate glib; extern crate gtk; +extern crate chrono; extern crate diesel; extern crate dissolve; extern crate hammond_data; diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 746ea53..54d2620 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -1,6 +1,8 @@ use glib; use gtk; + use gtk::prelude::*; +use chrono::prelude::*; use open; @@ -38,10 +40,11 @@ struct EpisodeWidget { download: gtk::Button, cancel: gtk::Button, title: gtk::Label, + date: gtk::Label, duration: gtk::Label, size: gtk::Label, progress: gtk::ProgressBar, - an_indicator: gtk::Image, + progress_label: gtk::Label, } impl EpisodeWidget { @@ -49,9 +52,7 @@ impl EpisodeWidget { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episode_widget.ui"); let container: gtk::Box = builder.get_object("episode_container").unwrap(); - let progress: gtk::ProgressBar = builder.get_object("progress_bar").unwrap(); - let an_indicator: gtk::Image = builder.get_object("an_indicator").unwrap(); let download: gtk::Button = builder.get_object("download_button").unwrap(); let play: gtk::Button = builder.get_object("play_button").unwrap(); @@ -59,13 +60,14 @@ impl EpisodeWidget { let cancel: gtk::Button = builder.get_object("cancel_button").unwrap(); let title: gtk::Label = builder.get_object("title_label").unwrap(); + let date: gtk::Label = builder.get_object("date_label").unwrap(); let duration: gtk::Label = builder.get_object("duration_label").unwrap(); let size: gtk::Label = builder.get_object("size_label").unwrap(); + let progress_label: gtk::Label = builder.get_object("progress_label").unwrap(); EpisodeWidget { container, progress, - an_indicator, download, play, cancel, @@ -73,6 +75,8 @@ impl EpisodeWidget { title, duration, size, + date, + progress_label, } } @@ -86,7 +90,6 @@ impl EpisodeWidget { // TODO: wire the progress_bar to the downloader. // TODO: wire the cancel button. fn init(&self, episode: &mut EpisodeWidgetQuery, pd: &Podcast) { - self.duration.hide(); self.title.set_xalign(0.0); self.title.set_text(episode.title()); self.progress.set_pulse_step(0.1); @@ -98,10 +101,15 @@ impl EpisodeWidget { }); if let Some(size) = episode.length() { - let megabytes: f32 = size as f32 / 1024.0 / 1024.0; // episode.length represents bytes - self.size.set_text(&format!("{:.1} mb", megabytes)) + let megabytes = size / 1024 / 1024; // episode.length represents bytes + self.size.set_text(&format!("{} MB", megabytes)) }; + let date = Utc.timestamp(i64::from(episode.epoch()), 0) + .format("%b %e") + .to_string(); + self.date.set_text(&date); + // Show or hide the play/delete/download buttons upon widget initialization. let local_uri = episode.local_uri(); if local_uri.is_some() && Path::new(local_uri.unwrap()).exists() { From 0c1e759a45aa0ebe38c6420e1283c842ddf7f5cd Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 15 Dec 2017 12:27:30 +0200 Subject: [PATCH 026/278] Dim out secondary label of EpisodeWidget. --- hammond-gtk/resources/gtk/episode_widget.ui | 12 +++++++++--- hammond-gtk/src/widgets/episode.rs | 17 ++++++++++++++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 2e7558e..4669fd1 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -6,6 +6,7 @@ True False vertical + 5 True @@ -27,7 +28,6 @@ False start Episode Title - True True end False @@ -56,6 +56,7 @@ True False 1970/01/01 + True False @@ -65,10 +66,11 @@ - + False True · + False False @@ -81,6 +83,7 @@ False True 42 min + True False @@ -90,10 +93,11 @@ - + True False · + False False @@ -106,6 +110,7 @@ True False 42 MB + True False @@ -119,6 +124,7 @@ False True 12 MB / 42 MB + True False diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 54d2620..6047602 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -65,6 +65,22 @@ impl EpisodeWidget { let size: gtk::Label = builder.get_object("size_label").unwrap(); let progress_label: gtk::Label = builder.get_object("progress_label").unwrap(); + let sep1: gtk::Label = builder.get_object("seperator1").unwrap(); + let sep2: gtk::Label = builder.get_object("seperator2").unwrap(); + + // Dim(grey out) the labels. + // If it's possible through glade, feel free to open a PR. + duration + .get_style_context() + .map(|c| c.add_class("dim-label")); + progress_label + .get_style_context() + .map(|c| c.add_class("dim-label")); + date.get_style_context().map(|c| c.add_class("dim-label")); + size.get_style_context().map(|c| c.add_class("dim-label")); + sep1.get_style_context().map(|c| c.add_class("dim-label")); + sep2.get_style_context().map(|c| c.add_class("dim-label")); + EpisodeWidget { container, progress, @@ -92,7 +108,6 @@ impl EpisodeWidget { fn init(&self, episode: &mut EpisodeWidgetQuery, pd: &Podcast) { self.title.set_xalign(0.0); self.title.set_text(episode.title()); - self.progress.set_pulse_step(0.1); let progress = self.progress.clone(); timeout_add(200, move || { From 4b0a6ea0f7dc1cc69c1b8ff9ad7db4ab50b36791 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 15 Dec 2017 13:45:08 +0200 Subject: [PATCH 027/278] Add Show title in the Headerbar when switching to ShowWidget. --- hammond-gtk/resources/gtk/episode_widget.ui | 4 +- hammond-gtk/resources/gtk/headerbar.ui | 60 +++++++++++++++------ hammond-gtk/src/headerbar.rs | 19 ++++--- hammond-gtk/src/views/shows.rs | 3 +- hammond-gtk/src/widgets/episode.rs | 5 +- 5 files changed, 63 insertions(+), 28 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 4669fd1..cc2d9d5 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -66,7 +66,7 @@ - + False True · @@ -93,7 +93,7 @@ - + True False · diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index b35599d..aa7d08e 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -156,30 +156,39 @@ - + True False - center - center - - - - - True - True - True - center + vertical - + True False - open-menu-symbolic + center + center + + False + True + 0 + + + + + False + True + Show Title + + + + + + False + True + 1 + - - end - @@ -202,5 +211,24 @@ 1 + + + True + True + True + center + + + True + False + open-menu-symbolic + + + + + end + 2 + + diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index efa6931..d683591 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -16,7 +16,7 @@ pub struct Header { add_toggle: gtk::MenuButton, switch: gtk::StackSwitcher, back_button: gtk::Button, - // show_title: gtk::Label, + show_title: gtk::Label, } impl Header { @@ -28,7 +28,7 @@ impl Header { let add_toggle: gtk::MenuButton = builder.get_object("add_toggle_button").unwrap(); let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); let back_button: gtk::Button = builder.get_object("back_button").unwrap(); - // let show_title: gtk::Label = builder.get_object("show_title").unwrap(); + let show_title: gtk::Label = builder.get_object("show_title").unwrap(); switch.set_halign(gtk::Align::Center); switch.show(); @@ -39,6 +39,7 @@ impl Header { add_toggle, switch, back_button, + show_title, }) } @@ -70,25 +71,31 @@ impl Header { let switch = &self.switch; let add_toggle = &self.add_toggle; - self.back_button - .connect_clicked(clone!(content, switch, add_toggle => move |back| { + let show_title = &self.show_title; + self.back_button.connect_clicked( + clone!(content, switch, add_toggle, show_title => move |back| { switch.show(); add_toggle.show(); back.hide(); + show_title.hide(); content.shows.stack.set_visible_child_full("podcasts", gtk::StackTransitionType::SlideRight); - })); + }), + ); } - pub fn switch_to_back(&self) { + pub fn switch_to_back(&self, title: &str) { self.switch.hide(); self.add_toggle.hide(); self.back_button.show(); + self.show_title.set_text(title); + self.show_title.show(); } pub fn switch_to_normal(&self) { self.switch.show(); self.add_toggle.show(); self.back_button.hide(); + self.show_title.hide(); } // pub fn set_show_title(&self, title: &str) { diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index 5cb12b8..981469b 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -62,8 +62,7 @@ impl ShowsPopulated { let pd = dbqueries::get_podcast_from_id(id).unwrap(); show.replace_widget(&pd); - // header.set_show_title(pd.title()); - header.switch_to_back(); + header.switch_to_back(pd.title()); show.switch_widget_animated(); })); // Populate the flowbox with the Podcasts. diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 6047602..921696f 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -65,8 +65,8 @@ impl EpisodeWidget { let size: gtk::Label = builder.get_object("size_label").unwrap(); let progress_label: gtk::Label = builder.get_object("progress_label").unwrap(); - let sep1: gtk::Label = builder.get_object("seperator1").unwrap(); - let sep2: gtk::Label = builder.get_object("seperator2").unwrap(); + let sep1: gtk::Label = builder.get_object("separator1").unwrap(); + let sep2: gtk::Label = builder.get_object("separator2").unwrap(); // Dim(grey out) the labels. // If it's possible through glade, feel free to open a PR. @@ -269,6 +269,7 @@ fn receive() -> glib::Continue { pub fn episodes_listbox(pd: &Podcast) -> Result { let episodes = dbqueries::get_pd_episodeswidgets(pd)?; + // TODO: add a separator let list = gtk::ListBox::new(); episodes.into_iter().for_each(|mut ep| { let widget = EpisodeWidget::new_initialized(&mut ep, pd); From c74153f56a9a34094dddddca0cbca3bc79204e38 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 15 Dec 2017 18:42:49 +0200 Subject: [PATCH 028/278] Initial implementation of the new ShowWidget. --- hammond-gtk/resources/gtk/show_widget.ui | 255 ++++++++++------------- hammond-gtk/src/utils.rs | 5 + hammond-gtk/src/widgets/show.rs | 64 +++--- 3 files changed, 147 insertions(+), 177 deletions(-) diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index 6b30d01..cfb2207 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -2,191 +2,156 @@ - + True False + vertical - + True - False - center - center - 32 - 32 - 32 - 32 - 64 - 32 + True + in - + True False - center - center - vertical - 15 - - - True - False - center - start - 1 - 1 - 1 - 1 - - - False - False - 0 - - True False - center - center + vertical True False - center + center - - 50 + + True + False + 128 + image-x-generic-symbolic + + + False + True + 0 + + + + True False center - Foobar - True - center - True - 28 - False + center + vertical + + + True + False + The people behind The Intercept’s fearless reporting and incisive commentary—Jeremy Scahill, Glenn Greenwald, Betsy Reed and others—discuss the crucial issues of our time: national security, civil liberties, foreign policy, and criminal justice. Plus interviews with artists, thinkers, and newsmakers who challenge our preconceptions about the world we live in. + True + + + False + True + 5 + 0 + + + + + True + False + + + True + True + True + + + True + False + emblem-system-symbolic + + + + + False + True + 5 + 0 + + + + + Website + True + True + True + + + False + True + 5 + 1 + + + + + Unsubscribe + True + True + True + + + False + True + 5 + end + 2 + + + + + False + True + 5 + 1 + + True True - 0 + 5 + 1 False True - 5 - 1 + 10 + 0 - + True - True - True - center - center + False + vertical - - True - False - Unsubrscribe from this Podcast. -Warn: This will delete downloaded content associated with this Podcast. - user-trash-symbolic - + - False - False - 5 - end + True + True 1 - - - True - True - Mark all episodes as Played. - center - center - - - True - False - object-select-symbolic - - - - - False - False - 2 - - - - False - False - 1 - - - - - True - True - in - 200 - 200 - True - True - - - True - True - False - word-char - False - - - - - True - True - 2 - - - - - False - False - 0 - - - - - False - False - 1 - - - - - True - True - True - True - never - - - 400 - True - False - none - - @@ -194,7 +159,7 @@ Warn: This will delete downloaded content associated with this Podcast. True True - 2 + 0 diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 7327854..56cdc56 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -70,6 +70,11 @@ pub fn get_pixbuf_from_path(pd: &Podcast) -> Option { Pixbuf::new_from_file_at_scale(&img_path, 256, 256, true).ok() } +pub fn get_pixbuf_from_path_128(pd: &Podcast) -> Option { + let img_path = downloader::cache_image(pd)?; + Pixbuf::new_from_file_at_scale(&img_path, 128, 128, true).ok() +} + #[cfg(test)] mod tests { use hammond_data::Source; diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 99da2b8..5aaff1a 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -9,7 +9,7 @@ use hammond_data::Podcast; use hammond_downloader::downloader; use widgets::episode::episodes_listbox; -use utils::get_pixbuf_from_path; +use utils::get_pixbuf_from_path_128; use content::ShowStack; use headerbar::Header; @@ -19,34 +19,38 @@ use std::rc::Rc; pub struct ShowWidget { pub container: gtk::Box, cover: gtk::Image, - title: gtk::Label, - description: gtk::TextView, - view: gtk::Viewport, + description: gtk::Label, + link: gtk::Button, + settings: gtk::Button, unsub: gtk::Button, - played: gtk::Button, + episodes: gtk::Box, } impl ShowWidget { pub fn new() -> ShowWidget { // Adapted from gnome-music AlbumWidget let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/show_widget.ui"); - let container: gtk::Box = builder.get_object("podcast_widget").unwrap(); + let container: gtk::Box = builder.get_object("container").unwrap(); + let episodes: gtk::Box = builder.get_object("episodes").unwrap(); let cover: gtk::Image = builder.get_object("cover").unwrap(); - let title: gtk::Label = builder.get_object("title_label").unwrap(); - let description: gtk::TextView = builder.get_object("desc_text_view").unwrap(); - let view: gtk::Viewport = builder.get_object("view").unwrap(); + let description: gtk::Label = builder.get_object("description").unwrap(); let unsub: gtk::Button = builder.get_object("unsub_button").unwrap(); - let played: gtk::Button = builder.get_object("mark_all_played_button").unwrap(); + let link: gtk::Button = builder.get_object("link_button").unwrap(); + let settings: gtk::Button = builder.get_object("settings_button").unwrap(); + + unsub + .get_style_context() + .map(|c| c.add_class("destructive-action")); ShowWidget { container, cover, - title, description, - view, unsub, - played, + link, + settings, + episodes, } } @@ -65,38 +69,34 @@ impl ShowWidget { header.switch_to_normal(); })); - self.title.set_text(pd.title()); let listbox = episodes_listbox(pd); if let Ok(l) = listbox { - self.view.add(&l); + self.episodes.add(&l); } - { - let buff = self.description.get_buffer().unwrap(); - buff.set_text(pd.description()); - } + self.description.set_text(pd.description()); - let img = get_pixbuf_from_path(pd); + let img = get_pixbuf_from_path_128(pd); if let Some(i) = img { self.cover.set_from_pixbuf(&i); } - self.played.connect_clicked(clone!(shows, pd => move |_| { - on_played_button_clicked(shows.clone(), &pd); - })); + // self.played.connect_clicked(clone!(shows, pd => move |_| { + // on_played_button_clicked(shows.clone(), &pd); + // })); - self.show_played_button(pd); + // self.show_played_button(pd); } - fn show_played_button(&self, pd: &Podcast) { - let new_episodes = dbqueries::get_pd_unplayed_episodes(pd); + // fn show_played_button(&self, pd: &Podcast) { + // let new_episodes = dbqueries::get_pd_unplayed_episodes(pd); - if let Ok(n) = new_episodes { - if !n.is_empty() { - self.played.show() - } - } - } + // if let Ok(n) = new_episodes { + // if !n.is_empty() { + // self.played.show() + // } + // } + // } } fn on_unsub_button_clicked(shows: Rc, pd: &Podcast, unsub_button: >k::Button) { From 6614818418b4829b6dc41791bb629000ae8efeec Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 15 Dec 2017 19:55:13 +0200 Subject: [PATCH 029/278] Use Gtk::Frame to limit ShowWidget's size. --- hammond-gtk/resources/gtk/show_widget.ui | 310 ++++++++++++++--------- hammond-gtk/src/widgets/show.rs | 4 +- 2 files changed, 195 insertions(+), 119 deletions(-) diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index cfb2207..cac47f5 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -19,125 +19,9 @@ True False - vertical + center - True - False - center - - - True - False - 128 - image-x-generic-symbolic - - - False - True - 0 - - - - - True - False - center - center - vertical - - - True - False - The people behind The Intercept’s fearless reporting and incisive commentary—Jeremy Scahill, Glenn Greenwald, Betsy Reed and others—discuss the crucial issues of our time: national security, civil liberties, foreign policy, and criminal justice. Plus interviews with artists, thinkers, and newsmakers who challenge our preconceptions about the world we live in. - True - - - False - True - 5 - 0 - - - - - True - False - - - True - True - True - - - True - False - emblem-system-symbolic - - - - - False - True - 5 - 0 - - - - - Website - True - True - True - - - False - True - 5 - 1 - - - - - Unsubscribe - True - True - True - - - False - True - 5 - end - 2 - - - - - False - True - 5 - 1 - - - - - True - True - 5 - 1 - - - - - False - True - 10 - 0 - - - - True False vertical @@ -148,9 +32,201 @@ True True + 0 + + + + + True + False + center + vertical + + + True + False + 0 + none + + + True + False + vertical + + + True + False + center + + + True + False + 128 + image-x-generic-symbolic + + + False + False + 5 + 0 + + + + + True + False + center + vertical + + + True + False + start + center + A podcast about learning the Rust + True + 80 + 80 + False + + + False + False + 5 + 0 + + + + + True + False + + + True + True + True + + + True + False + emblem-system-symbolic + + + + + False + True + 5 + 0 + + + + + Website + True + True + True + + + False + True + 5 + 1 + + + + + Unsubscribe + True + True + True + + + False + True + 5 + end + 2 + + + + + False + False + 5 + 1 + + + + + False + False + 5 + 1 + + + + + False + False + 10 + 0 + + + + + + + + + + False + False + 5 + 0 + + + + + True + False + 0 + none + + + + + + + + + True + True + 1 + + + + + False + True 1 + + + True + False + vertical + + + + + + False + True + 2 + + diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 5aaff1a..a8b9f83 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -23,7 +23,7 @@ pub struct ShowWidget { link: gtk::Button, settings: gtk::Button, unsub: gtk::Button, - episodes: gtk::Box, + episodes: gtk::Frame, } impl ShowWidget { @@ -31,7 +31,7 @@ impl ShowWidget { // Adapted from gnome-music AlbumWidget let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/show_widget.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); - let episodes: gtk::Box = builder.get_object("episodes").unwrap(); + let episodes: gtk::Frame = builder.get_object("episodes").unwrap(); let cover: gtk::Image = builder.get_object("cover").unwrap(); let description: gtk::Label = builder.get_object("description").unwrap(); From b1af25e4c0af6a4787dd33ba2eb79225c7127d57 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 15 Dec 2017 20:38:39 +0200 Subject: [PATCH 030/278] ShowWidget: Wire the website button to open podcast homepage. --- hammond-gtk/src/widgets/show.rs | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index a8b9f83..a9b27ba 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -1,6 +1,7 @@ use gtk::prelude::*; use gtk; use diesel::Identifiable; +use open; use std::fs; @@ -28,7 +29,6 @@ pub struct ShowWidget { impl ShowWidget { pub fn new() -> ShowWidget { - // Adapted from gnome-music AlbumWidget let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/show_widget.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); let episodes: gtk::Frame = builder.get_object("episodes").unwrap(); @@ -81,22 +81,16 @@ impl ShowWidget { self.cover.set_from_pixbuf(&i); } + let link = pd.link().to_owned(); + self.link.connect_clicked(move |_| { + info!("Opening link: {}", &link); + let _ = open::that(&link); + }); + // self.played.connect_clicked(clone!(shows, pd => move |_| { // on_played_button_clicked(shows.clone(), &pd); // })); - - // self.show_played_button(pd); } - - // fn show_played_button(&self, pd: &Podcast) { - // let new_episodes = dbqueries::get_pd_unplayed_episodes(pd); - - // if let Ok(n) = new_episodes { - // if !n.is_empty() { - // self.played.show() - // } - // } - // } } fn on_unsub_button_clicked(shows: Rc, pd: &Podcast, unsub_button: >k::Button) { From 3c90e98d43f7be1b9649ee587510e0f92fdc9f7d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 15 Dec 2017 20:46:55 +0200 Subject: [PATCH 031/278] ShowWidget: Make settings button a GtkMenuButton. --- hammond-gtk/resources/gtk/show_widget.ui | 9 +++++++-- hammond-gtk/src/widgets/show.rs | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index cac47f5..3e0f918 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -101,7 +101,7 @@ True False - + True True True @@ -109,6 +109,8 @@ True False + center + center emblem-system-symbolic @@ -116,7 +118,6 @@ False True - 5 0 @@ -126,6 +127,8 @@ True True True + center + center False @@ -140,6 +143,8 @@ True True True + center + center False diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index a9b27ba..4d1f7ea 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -22,7 +22,7 @@ pub struct ShowWidget { cover: gtk::Image, description: gtk::Label, link: gtk::Button, - settings: gtk::Button, + settings: gtk::MenuButton, unsub: gtk::Button, episodes: gtk::Frame, } @@ -37,7 +37,7 @@ impl ShowWidget { let description: gtk::Label = builder.get_object("description").unwrap(); let unsub: gtk::Button = builder.get_object("unsub_button").unwrap(); let link: gtk::Button = builder.get_object("link_button").unwrap(); - let settings: gtk::Button = builder.get_object("settings_button").unwrap(); + let settings: gtk::MenuButton = builder.get_object("settings_button").unwrap(); unsub .get_style_context() From 4375c7f4ceecbb00a4af4e02baba3396a8d4ca82 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 15 Dec 2017 21:00:51 +0200 Subject: [PATCH 032/278] EpisodeWidget: Added a separator in each widget. This is a work around since list_box_set_header_func is not yet available in the gtk-rs bindings. --- hammond-gtk/resources/gtk/episode_widget.ui | 17 ++++++++++++++--- hammond-gtk/src/widgets/episode.rs | 3 ++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index cc2d9d5..527dee8 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -6,7 +6,17 @@ True False vertical - 5 + + + True + False + + + False + True + 0 + + True @@ -244,7 +254,8 @@ True True - 0 + 5 + 1 @@ -255,7 +266,7 @@ False True 5 - 1 + 2 diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 921696f..fb166a3 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -273,7 +273,8 @@ pub fn episodes_listbox(pd: &Podcast) -> Result { let list = gtk::ListBox::new(); episodes.into_iter().for_each(|mut ep| { let widget = EpisodeWidget::new_initialized(&mut ep, pd); - list.add(&widget.container) + list.add(&widget.container); + list.add(>k::Separator::new(gtk::Orientation::Vertical)) }); list.set_vexpand(false); From 5989f4f54114b16f38e76c0b779dd5ad896bce7c Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 15 Dec 2017 21:15:20 +0200 Subject: [PATCH 033/278] ShowWidget: Set widget width to 600. --- hammond-gtk/resources/gtk/show_widget.ui | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index 3e0f918..2620800 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -37,6 +37,7 @@ + 600 True False center @@ -85,8 +86,7 @@ center A podcast about learning the Rust True - 80 - 80 + 60 False @@ -165,7 +165,7 @@ False - False + True 5 1 From dbe08f7deb1bc7dca622a7e2528cfc4b6d102cb0 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 16 Dec 2017 14:17:27 +0200 Subject: [PATCH 034/278] EpisodeListBox: Improve the separator workaround. --- hammond-gtk/resources/gtk/episode_widget.ui | 15 ++------------- hammond-gtk/resources/gtk/show_widget.ui | 2 +- hammond-gtk/src/widgets/episode.rs | 10 ++++++++-- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 527dee8..dc3cdf9 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -6,17 +6,6 @@ True False vertical - - - True - False - - - False - True - 0 - - True @@ -255,7 +244,7 @@ True True 5 - 1 + 0 @@ -266,7 +255,7 @@ False True 5 - 2 + 1 diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index 2620800..76a2b2a 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -196,7 +196,7 @@ True False 0 - none + in diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index fb166a3..35bfb02 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -269,12 +269,18 @@ fn receive() -> glib::Continue { pub fn episodes_listbox(pd: &Podcast) -> Result { let episodes = dbqueries::get_pd_episodeswidgets(pd)?; - // TODO: add a separator let list = gtk::ListBox::new(); + episodes.into_iter().for_each(|mut ep| { let widget = EpisodeWidget::new_initialized(&mut ep, pd); list.add(&widget.container); - list.add(>k::Separator::new(gtk::Orientation::Vertical)) + + let sep = gtk::Separator::new(gtk::Orientation::Vertical); + sep.set_sensitive(false); + sep.set_can_focus(false); + + list.add(&sep); + sep.show() }); list.set_vexpand(false); From 0653460fb2163fb2a1ca0aaa5b7a3df07c5c3763 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 16 Dec 2017 14:58:16 +0200 Subject: [PATCH 035/278] EpisodeWidget: prevent title label overflow. Set label's maximu character width to prevent it and elipsize instead. --- hammond-gtk/resources/gtk/episode_widget.ui | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index dc3cdf9..992a09b 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -27,8 +27,9 @@ False start Episode Title - True end + True + 70 False 1 From f8ae2dcffec3cc9f6d743a1c5cfeba797ffe2cb5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 16 Dec 2017 18:22:35 +0200 Subject: [PATCH 036/278] Update rustfmt.toml and remove rustfmt warnings. --- hammond-gtk/src/main.rs | 4 +--- rustfmt.toml | 19 +++---------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 5b1bac6..ef03853 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -52,9 +52,7 @@ mod content; mod utils; mod static_resource; -/* -THIS IS STILL A PROTOTYPE. -*/ +// THIS IS STILL A PROTOTYPE. fn build_ui(app: >k::Application) { let menu = gio::Menu::new(); diff --git a/rustfmt.toml b/rustfmt.toml index 7f1b8d9..c420ec1 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,26 +1,13 @@ unstable_features = true verbose = false -disable_all_formatting = false -skip_children = false max_width = 100 comment_width = 100 wrap_comments = true -error_on_line_overflow = true -error_on_line_overflow_comments = false tab_spaces = 4 -newline_style = "Unix" -fn_call_style = "Block" -report_todo = "Never" -report_fixme = "Never" -reorder_extern_crates = true -reorder_extern_crates_in_group = true -reorder_imports = false hard_tabs = false -spaces_within_parens = false +newline_style = "Unix" +reorder_imports = false write_mode = "Overwrite" -merge_derives = true condense_wildcard_suffixes = false format_strings = true -multiline_closure_forces_block = true -attributes_on_same_line_as_field = true -attributes_on_same_line_as_variant = true \ No newline at end of file +normalize_comments = true \ No newline at end of file From aca35c051318a83c2ad850e2809f6ee3b8bf3be9 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 16 Dec 2017 19:20:40 +0200 Subject: [PATCH 037/278] ShowWidget: Improve? description handling. --- hammond-gtk/resources/gtk/episode_widget.ui | 13 ++-- hammond-gtk/resources/gtk/show_widget.ui | 66 +++++++++++---------- 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 992a09b..c18c8a3 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -29,7 +29,7 @@ Episode Title end True - 70 + 60 False 1 @@ -41,7 +41,7 @@ - True + False True 0 @@ -135,14 +135,14 @@ - True + False True 1 - True + False True 5 0 @@ -162,7 +162,7 @@ False - True + False end 0 @@ -237,12 +237,13 @@ False True 5 + end 1 - True + False True 5 0 diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index 76a2b2a..cc3c9b4 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -31,7 +31,7 @@ True - True + False 0 @@ -58,6 +58,7 @@ True False center + 10 True @@ -67,8 +68,7 @@ False - False - 5 + True 0 @@ -76,30 +76,13 @@ True False - center vertical - - - True - False - start - center - A podcast about learning the Rust - True - 60 - False - - - False - False - 5 - 0 - - + 10 True False + 5 True @@ -158,23 +141,42 @@ False False - 5 + end + 0 + + + + + True + False + start + center + Show description + True + word-char + 55 + + + + + + True + True + end 1 - False + True True - 5 1 False - False - 10 + True 0 @@ -186,8 +188,8 @@ False - False - 5 + True + 25 0 @@ -205,7 +207,7 @@ - True + False True 1 @@ -227,8 +229,8 @@ - False - True + True + False 2 From f7af05a650116afe6e137ae54ca130fcaab2bd2c Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 16 Dec 2017 20:30:25 +0200 Subject: [PATCH 038/278] EpisodeWidget: Dim/Grey out widget if episode is played. --- hammond-data/src/dbqueries.rs | 2 +- hammond-gtk/src/widgets/episode.rs | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index f1bb8dd..7adb91c 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -50,7 +50,7 @@ pub fn get_played_episodes() -> Result> { Ok(episode.filter(played.is_not_null()).load::(&*con)?) } -pub fn get_episode_from_id(ep_id: i32) -> Result { +pub fn get_episode_from_rowid(ep_id: i32) -> Result { use schema::episode::dsl::*; let db = connection(); diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 35bfb02..11e2fbc 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -109,6 +109,12 @@ impl EpisodeWidget { self.title.set_xalign(0.0); self.title.set_text(episode.title()); + if episode.played().is_some() { + self.title + .get_style_context() + .map(|c| c.add_class("dim-label")); + } + let progress = self.progress.clone(); timeout_add(200, move || { progress.pulse(); @@ -133,10 +139,16 @@ impl EpisodeWidget { self.delete.show(); } - self.play.connect_clicked(clone!(episode => move |_| { + let title = &self.title; + self.play + .connect_clicked(clone!(episode, title => move |_| { let mut episode = episode.clone(); on_play_bttn_clicked(episode.rowid()); - let _ = episode.set_played_now(); + if episode.set_played_now().is_ok() { + title + .get_style_context() + .map(|c| c.add_class("dim-label")); + }; })); let play = &self.play; @@ -234,7 +246,7 @@ fn on_play_bttn_clicked(episode_id: i32) { } fn on_delete_bttn_clicked(episode_id: i32) { - let mut ep = dbqueries::get_episode_from_id(episode_id).unwrap(); + let mut ep = dbqueries::get_episode_from_rowid(episode_id).unwrap(); let e = delete_local_content(&mut ep); if let Err(err) = e { From 440badf1ebb813bbc2b683eef4f8d4e4f61af3bd Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 16 Dec 2017 20:45:15 +0200 Subject: [PATCH 039/278] ShowWidget: Strip html tags from the description. --- hammond-downloader/src/downloader.rs | 2 +- hammond-gtk/src/widgets/show.rs | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 4343e91..e3a4a0c 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -8,7 +8,7 @@ use std::io::{BufWriter, Read, Write}; use std::path::Path; use errors::*; -use hammond_data::{Episode, EpisodeWidgetQuery, Podcast}; +use hammond_data::{EpisodeWidgetQuery, Podcast}; use hammond_data::xdg_dirs::{DL_DIR, HAMMOND_CACHE}; // TODO: Replace path that are of type &str with std::path. diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 4d1f7ea..308964c 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -2,11 +2,11 @@ use gtk::prelude::*; use gtk; use diesel::Identifiable; use open; - -use std::fs; +use dissolve; use hammond_data::dbqueries; use hammond_data::Podcast; +use hammond_data::utils::replace_extra_spaces; use hammond_downloader::downloader; use widgets::episode::episodes_listbox; @@ -15,6 +15,7 @@ use content::ShowStack; use headerbar::Header; use std::rc::Rc; +use std::fs; #[derive(Debug, Clone)] pub struct ShowWidget { @@ -74,7 +75,9 @@ impl ShowWidget { self.episodes.add(&l); } - self.description.set_text(pd.description()); + // TODO: Temporary solution until we render html urls/bold/italic probably with markup. + let desc = dissolve::strip_html_tags(pd.description()).join(" "); + self.description.set_text(&replace_extra_spaces(&desc)); let img = get_pixbuf_from_path_128(pd); if let Some(i) = img { @@ -113,6 +116,7 @@ fn on_unsub_button_clicked(shows: Rc, pd: &Podcast, unsub_button: > shows.update_podcasts(); } +#[allow(dead_code)] fn on_played_button_clicked(shows: Rc, pd: &Podcast) { let _ = dbqueries::update_none_to_played_now(pd); From 75fe0f8ff5317ef47295e4a19f715e874d5f605c Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 17 Dec 2017 13:08:51 +0200 Subject: [PATCH 040/278] Use Default trait for creating Widget's that don't need arguments. --- hammond-gtk/src/content.rs | 8 ++--- hammond-gtk/src/headerbar.rs | 17 +++++++--- hammond-gtk/src/main.rs | 11 ++---- hammond-gtk/src/views/empty.rs | 10 ++++-- hammond-gtk/src/views/shows.rs | 54 ++++++++++++++++-------------- hammond-gtk/src/widgets/episode.rs | 12 ++++--- hammond-gtk/src/widgets/show.rs | 10 +++--- 7 files changed, 68 insertions(+), 54 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index c87f88f..adc4cb6 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -60,8 +60,8 @@ impl ShowStack { header: header.clone(), }); - let pop = ShowsPopulated::new_initialized(show.clone(), header); - let widget = ShowWidget::new(); + let pop = ShowsPopulated::new(show.clone(), header); + let widget = ShowWidget::default(); let empty = EmptyView::new(); show.stack.add_named(&pop.container, "podcasts"); @@ -90,7 +90,7 @@ impl ShowStack { let vis = self.stack.get_visible_child_name().unwrap(); let old = self.stack.get_child_by_name("podcasts").unwrap(); - let pop = ShowsPopulated::new(); + let pop = ShowsPopulated::default(); pop.init(Rc::new(self.clone()), self.header.clone()); self.stack.remove(&old); @@ -109,7 +109,7 @@ impl ShowStack { pub fn replace_widget(&self, pd: &Podcast) { let old = self.stack.get_child_by_name("widget").unwrap(); - let new = ShowWidget::new_initialized(Rc::new(self.clone()), self.header.clone(), pd); + let new = ShowWidget::new(Rc::new(self.clone()), self.header.clone(), pd); self.stack.remove(&old); self.stack.add_named(&new.container, "widget"); diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index d683591..057957e 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -19,8 +19,8 @@ pub struct Header { show_title: gtk::Label, } -impl Header { - pub fn new() -> Rc
{ +impl Default for Header { + fn default() -> Header { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let header: gtk::HeaderBar = builder.get_object("headerbar").unwrap(); @@ -33,14 +33,23 @@ impl Header { switch.set_halign(gtk::Align::Center); switch.show(); - Rc::new(Header { + Header { container: header, refresh, add_toggle, switch, back_button, show_title, - }) + } + } +} + +impl Header { + #[allow(dead_code)] + pub fn new(content: Rc) -> Rc
{ + let h = Header::default(); + h.init(content); + Rc::new(h) } pub fn init(&self, content: Rc) { diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index ef03853..dbe6c3a 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -24,6 +24,7 @@ use hammond_data::utils::checkup; use gtk::prelude::*; use gio::{ActionMapExt, ApplicationExt, MenuExt, SimpleActionExt}; +use std::rc::Rc; // http://gtk-rs.org/tuto/closures #[macro_export] @@ -52,8 +53,6 @@ mod content; mod utils; mod static_resource; -// THIS IS STILL A PROTOTYPE. - fn build_ui(app: >k::Application) { let menu = gio::Menu::new(); menu.append("Quit", "app.quit"); @@ -64,14 +63,8 @@ fn build_ui(app: >k::Application) { let window = gtk::ApplicationWindow::new(app); window.set_default_size(1150, 650); - // TODO: this will blow horribly - // let ct = content::ContentState::new().unwrap(); - // let stack = ct.get_stack(); - - // let ct = content::Content::new_initialized(); - // Get the headerbar - let header = headerbar::Header::new(); + let header = Rc::new(headerbar::Header::default()); let ct = content::Content::new(header.clone()); header.init(ct.clone()); window.set_titlebar(&header.container); diff --git a/hammond-gtk/src/views/empty.rs b/hammond-gtk/src/views/empty.rs index 1c93da7..ad3d152 100644 --- a/hammond-gtk/src/views/empty.rs +++ b/hammond-gtk/src/views/empty.rs @@ -5,11 +5,17 @@ pub struct EmptyView { pub container: gtk::Box, } -impl EmptyView { - pub fn new() -> EmptyView { +impl Default for EmptyView { + fn default() -> Self { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/empty_view.ui"); let view: gtk::Box = builder.get_object("empty_view").unwrap(); EmptyView { container: view } } } + +impl EmptyView { + pub fn new() -> EmptyView { + EmptyView::default() + } +} diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index 981469b..327a9b8 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -19,18 +19,8 @@ pub struct ShowsPopulated { viewport: gtk::Viewport, } -#[derive(Debug)] -struct ShowsChild { - container: gtk::Box, - title: gtk::Label, - cover: gtk::Image, - banner: gtk::Image, - number: gtk::Label, - child: gtk::FlowBoxChild, -} - -impl ShowsPopulated { - pub fn new() -> ShowsPopulated { +impl Default for ShowsPopulated { + fn default() -> Self { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/shows_view.ui"); let container: gtk::Box = builder.get_object("fb_parent").unwrap(); let flowbox: gtk::FlowBox = builder.get_object("flowbox").unwrap(); @@ -42,10 +32,11 @@ impl ShowsPopulated { viewport, } } +} - #[allow(dead_code)] - pub fn new_initialized(show: Rc, header: Rc
) -> ShowsPopulated { - let pop = ShowsPopulated::new(); +impl ShowsPopulated { + pub fn new(show: Rc, header: Rc
) -> ShowsPopulated { + let pop = ShowsPopulated::default(); pop.init(show, header); pop } @@ -74,7 +65,7 @@ impl ShowsPopulated { if let Ok(pds) = podcasts { pds.iter().for_each(|parent| { - let flowbox_child = ShowsChild::new_initialized(parent); + let flowbox_child = ShowsChild::new(parent); self.flowbox.add(&flowbox_child.child); }); self.flowbox.show_all(); @@ -86,11 +77,20 @@ impl ShowsPopulated { } } -impl ShowsChild { - fn new() -> ShowsChild { +#[derive(Debug)] +struct ShowsChild { + container: gtk::Box, + title: gtk::Label, + cover: gtk::Image, + banner: gtk::Image, + number: gtk::Label, + child: gtk::FlowBoxChild, +} + +impl Default for ShowsChild { + fn default() -> Self { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/shows_child.ui"); - // Copy of gnome-music AlbumWidget let container: gtk::Box = builder.get_object("fb_child").unwrap(); let title: gtk::Label = builder.get_object("pd_title").unwrap(); let cover: gtk::Image = builder.get_object("pd_cover").unwrap(); @@ -109,6 +109,15 @@ impl ShowsChild { child, } } +} + +impl ShowsChild { + pub fn new(pd: &Podcast) -> ShowsChild { + let child = ShowsChild::default(); + child.init(pd); + + child + } fn init(&self, pd: &Podcast) { self.title.set_text(pd.title()); @@ -122,13 +131,6 @@ impl ShowsChild { self.configure_banner(pd); } - pub fn new_initialized(pd: &Podcast) -> ShowsChild { - let child = ShowsChild::new(); - child.init(pd); - - child - } - fn configure_banner(&self, pd: &Podcast) { let bann = Pixbuf::new_from_resource_at_scale("/org/gnome/hammond/banner.png", 256, 256, true); diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 11e2fbc..9a9c673 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -47,8 +47,8 @@ struct EpisodeWidget { progress_label: gtk::Label, } -impl EpisodeWidget { - fn new() -> EpisodeWidget { +impl Default for EpisodeWidget { + fn default() -> Self { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episode_widget.ui"); let container: gtk::Box = builder.get_object("episode_container").unwrap(); @@ -95,9 +95,11 @@ impl EpisodeWidget { progress_label, } } +} - pub fn new_initialized(episode: &mut EpisodeWidgetQuery, pd: &Podcast) -> EpisodeWidget { - let widget = EpisodeWidget::new(); +impl EpisodeWidget { + pub fn new(episode: &mut EpisodeWidgetQuery, pd: &Podcast) -> EpisodeWidget { + let widget = EpisodeWidget::default(); widget.init(episode, pd); widget } @@ -284,7 +286,7 @@ pub fn episodes_listbox(pd: &Podcast) -> Result { let list = gtk::ListBox::new(); episodes.into_iter().for_each(|mut ep| { - let widget = EpisodeWidget::new_initialized(&mut ep, pd); + let widget = EpisodeWidget::new(&mut ep, pd); list.add(&widget.container); let sep = gtk::Separator::new(gtk::Orientation::Vertical); diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 308964c..c232661 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -28,8 +28,8 @@ pub struct ShowWidget { episodes: gtk::Frame, } -impl ShowWidget { - pub fn new() -> ShowWidget { +impl Default for ShowWidget { + fn default() -> Self { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/show_widget.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); let episodes: gtk::Frame = builder.get_object("episodes").unwrap(); @@ -54,9 +54,11 @@ impl ShowWidget { episodes, } } +} - pub fn new_initialized(shows: Rc, header: Rc
, pd: &Podcast) -> ShowWidget { - let pdw = ShowWidget::new(); +impl ShowWidget { + pub fn new(shows: Rc, header: Rc
, pd: &Podcast) -> ShowWidget { + let pdw = ShowWidget::default(); pdw.init(shows, header, pd); pdw } From 35009e257432e5788e2dbfd93cc7f7ab8091a055 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 17 Dec 2017 13:44:00 +0200 Subject: [PATCH 041/278] Added an auto-updater that runs each hour. --- hammond-gtk/src/headerbar.rs | 4 ++-- hammond-gtk/src/main.rs | 22 ++++++++++++++++++---- hammond-gtk/src/utils.rs | 12 +++--------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 057957e..4eb1a6d 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -75,7 +75,7 @@ impl Header { // FIXME: There appears to be a memmory leak here. self.refresh.connect_clicked(clone!(content => move |_| { - utils::refresh_feed(content.clone(), None, None); + utils::refresh_feed(content.clone(), None); })); let switch = &self.switch; @@ -120,7 +120,7 @@ fn on_add_bttn_clicked(content: Rc, entry: >k::Entry) { if let Ok(s) = source { info!("{:?} feed added", url); // update the db - utils::refresh_feed(content, Some(vec![s]), None); + utils::refresh_feed(content, Some(vec![s])); } else { error!("Feed probably already exists."); error!("Error: {:?}", source.unwrap_err()); diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index dbe6c3a..9e197e1 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -90,11 +90,25 @@ fn build_ui(app: >k::Application) { }); app.add_action(&check); - // queue a db update 1 minute after the startup. - gtk::idle_add(clone!(ct => move || { - utils::refresh_feed(ct.clone(), None, Some(60)); + // Update on startup + gtk::timeout_add_seconds( + 30, + clone!(ct => move || { + utils::refresh_feed(ct.clone(), None); glib::Continue(false) - })); + }), + ); + + // Auto-updater, runs every hour. + // TODO: expose the interval in which it run to a user setting. + // TODO: show notifications. + gtk::timeout_add_seconds( + 3600, + clone!(ct => move || { + utils::refresh_feed(ct.clone(), None); + glib::Continue(true) + }), + ); gtk::idle_add(move || { let _ = checkup(); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 56cdc56..c2f484d 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -5,14 +5,13 @@ use hammond_data::feed; use hammond_data::{Podcast, Source}; use hammond_downloader::downloader; -use std::{thread, time}; +use std::thread; use std::cell::RefCell; use std::sync::mpsc::{channel, Receiver}; +use std::rc::Rc; use content::Content; -use std::rc::Rc; - type Foo = RefCell, Receiver)>>; // Create a thread local storage that will store the arguments to be transfered. @@ -22,7 +21,7 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None)); /// If `source` is None, Fetches all the `Source` entries in the database and updates them. /// `delay` represents the desired time in seconds for the thread to sleep before executing. /// When It's done,it queues up a `podcast_view` refresh. -pub fn refresh_feed(content: Rc, source: Option>, delay: Option) { +pub fn refresh_feed(content: Rc, source: Option>) { // Create a async channel. let (sender, receiver) = channel(); @@ -32,11 +31,6 @@ pub fn refresh_feed(content: Rc, source: Option>, delay: Op })); thread::spawn(move || { - if let Some(s) = delay { - let t = time::Duration::from_secs(s); - thread::sleep(t); - } - let feeds = { if let Some(vec) = source { Ok(feed::fetch(vec)) From 4c8c1f0013d11022ce48c898ce7f054a777703c3 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 17 Dec 2017 13:52:00 +0200 Subject: [PATCH 042/278] Add update option to the app menu. --- hammond-gtk/src/main.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 9e197e1..d565154 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -57,6 +57,7 @@ fn build_ui(app: >k::Application) { let menu = gio::Menu::new(); menu.append("Quit", "app.quit"); menu.append("Checkup", "app.check"); + menu.append("Update feeds", "app.update"); app.set_app_menu(&menu); // Get the main window @@ -90,6 +91,13 @@ fn build_ui(app: >k::Application) { }); app.add_action(&check); + let update = gio::SimpleAction::new("update", None); + let ct_clone = ct.clone(); + update.connect_activate(move |_, _| { + utils::refresh_feed(ct_clone.clone(), None); + }); + app.add_action(&update); + // Update on startup gtk::timeout_add_seconds( 30, From 2eb58eae0069eae74ebafeb7ebe75efa6f1e24f1 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 17 Dec 2017 13:57:08 +0200 Subject: [PATCH 043/278] Headerbar: Remove refresh button. --- hammond-gtk/resources/gtk/headerbar.ui | 21 --------------------- hammond-gtk/src/headerbar.rs | 16 ++++------------ 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index aa7d08e..91bb4f0 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -190,27 +190,6 @@
- - - True - True - True - center - True - True - - - True - False - view-refresh-symbolic - - - - - end - 1 - - True diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 4eb1a6d..9d62773 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -12,7 +12,6 @@ use content::Content; #[derive(Debug)] pub struct Header { pub container: gtk::HeaderBar, - refresh: gtk::Button, add_toggle: gtk::MenuButton, switch: gtk::StackSwitcher, back_button: gtk::Button, @@ -24,7 +23,6 @@ impl Default for Header { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let header: gtk::HeaderBar = builder.get_object("headerbar").unwrap(); - let refresh: gtk::Button = builder.get_object("ref_button").unwrap(); let add_toggle: gtk::MenuButton = builder.get_object("add_toggle_button").unwrap(); let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); let back_button: gtk::Button = builder.get_object("back_button").unwrap(); @@ -35,7 +33,6 @@ impl Default for Header { Header { container: header, - refresh, add_toggle, switch, back_button, @@ -73,11 +70,6 @@ impl Header { })); self.add_toggle.set_popover(&add_popover); - // FIXME: There appears to be a memmory leak here. - self.refresh.connect_clicked(clone!(content => move |_| { - utils::refresh_feed(content.clone(), None); - })); - let switch = &self.switch; let add_toggle = &self.add_toggle; let show_title = &self.show_title; @@ -96,7 +88,7 @@ impl Header { self.switch.hide(); self.add_toggle.hide(); self.back_button.show(); - self.show_title.set_text(title); + self.set_show_title(title); self.show_title.show(); } @@ -107,9 +99,9 @@ impl Header { self.show_title.hide(); } - // pub fn set_show_title(&self, title: &str) { - // self.show_title.set_text(title) - // } + pub fn set_show_title(&self, title: &str) { + self.show_title.set_text(title) + } } fn on_add_bttn_clicked(content: Rc, entry: >k::Entry) { From 681b91d36800c2ee1c61b6cc67a60a8b784a300b Mon Sep 17 00:00:00 2001 From: Constantin Nickel Date: Sun, 17 Dec 2017 13:17:04 +0100 Subject: [PATCH 044/278] Set dim-label for secondary labels of EpisodeWidget in Glade. --- hammond-gtk/resources/gtk/episode_widget.ui | 18 ++++++++++++++++++ hammond-gtk/src/widgets/episode.rs | 16 ---------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index cc2d9d5..12d7dcb 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -58,6 +58,9 @@ 1970/01/01 True False + False @@ -71,6 +74,9 @@ True · False +
False @@ -85,6 +91,9 @@ 42 min True False +
False @@ -98,6 +107,9 @@ False · False +
False @@ -112,6 +124,9 @@ 42 MB True False +
False @@ -126,6 +141,9 @@ 12 MB / 42 MB True False +
False diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 921696f..a7cadbe 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -65,22 +65,6 @@ impl EpisodeWidget { let size: gtk::Label = builder.get_object("size_label").unwrap(); let progress_label: gtk::Label = builder.get_object("progress_label").unwrap(); - let sep1: gtk::Label = builder.get_object("separator1").unwrap(); - let sep2: gtk::Label = builder.get_object("separator2").unwrap(); - - // Dim(grey out) the labels. - // If it's possible through glade, feel free to open a PR. - duration - .get_style_context() - .map(|c| c.add_class("dim-label")); - progress_label - .get_style_context() - .map(|c| c.add_class("dim-label")); - date.get_style_context().map(|c| c.add_class("dim-label")); - size.get_style_context().map(|c| c.add_class("dim-label")); - sep1.get_style_context().map(|c| c.add_class("dim-label")); - sep2.get_style_context().map(|c| c.add_class("dim-label")); - EpisodeWidget { container, progress, From 0826514cbca57d1edead18c1ccc7981cd3951c5e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 17 Dec 2017 15:34:34 +0200 Subject: [PATCH 045/278] ShowsView: Remove new_episodes indicator. --- hammond-gtk/resources/banner.png | Bin 943 -> 0 bytes hammond-gtk/resources/gtk/shows_child.ui | 41 +++-------------------- hammond-gtk/src/views/shows.rs | 27 --------------- 3 files changed, 5 insertions(+), 63 deletions(-) delete mode 100644 hammond-gtk/resources/banner.png diff --git a/hammond-gtk/resources/banner.png b/hammond-gtk/resources/banner.png deleted file mode 100644 index a5384e5420614c82796131594fc9569b8a1313c7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 943 zcmd6l?MqW}6vw~6d);<*&ZdUT#%$UHnTcD`Fwi;cirT{nGs;T52xTt{#Wc%myFN6F zBI|`zl4u1LWNBILMGsD^7e%OHs90zgni;zJgv;jEU5S4~KRA5P`EbtRaL(`C4r8*+ zZ>b*uS!xQK1`xp|V8nv#&%b+65OMa_WELi@!Qft{MlKNFyp)WifHc@^1l8A<2vAax zx;;rUAPr$wO0)OV6hOzNvWe-(dq+P%+#Z#<*z!S}KjODG|GaMX89g&xmUf7~ynMHT zY-P(CM_XIld$ZBKqHAJqs7=pC3JvF(E+Z?&>t(ix#@OS_0*`z310X zOY z6i<9jI>K|N+Uiw%J-g~Ae>_@I<8G*})Zyy*n#RE<1`%?Xe{xoEP=uzps&3cw=QP(l zgIg~ZPP?PO*i$63RjFM$1zw3YJ^-6Z7e5QBSGhL)Y?eXUVpJx^bO#dN5 - + @@ -23,42 +23,11 @@ False center center - gtk-missing-image - True - 6 + 256 + image-x-generic-symbolic + 0
- - - - 1 - - - - - - 2 - -
True @@ -72,12 +41,12 @@ False center center - label True center end True 33 + False
False diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index 327a9b8..b8bac62 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -1,6 +1,5 @@ use gtk; use gtk::prelude::*; -use gdk_pixbuf::Pixbuf; use diesel::associations::Identifiable; use hammond_data::dbqueries; @@ -82,8 +81,6 @@ struct ShowsChild { container: gtk::Box, title: gtk::Label, cover: gtk::Image, - banner: gtk::Image, - number: gtk::Label, child: gtk::FlowBoxChild, } @@ -94,8 +91,6 @@ impl Default for ShowsChild { let container: gtk::Box = builder.get_object("fb_child").unwrap(); let title: gtk::Label = builder.get_object("pd_title").unwrap(); let cover: gtk::Image = builder.get_object("pd_cover").unwrap(); - let banner: gtk::Image = builder.get_object("banner").unwrap(); - let number: gtk::Label = builder.get_object("banner_label").unwrap(); let child = gtk::FlowBoxChild::new(); child.add(&container); @@ -104,8 +99,6 @@ impl Default for ShowsChild { container, title, cover, - banner, - number, child, } } @@ -115,7 +108,6 @@ impl ShowsChild { pub fn new(pd: &Podcast) -> ShowsChild { let child = ShowsChild::default(); child.init(pd); - child } @@ -128,24 +120,5 @@ impl ShowsChild { }; WidgetExt::set_name(&self.child, &pd.id().to_string()); - self.configure_banner(pd); - } - - fn configure_banner(&self, pd: &Podcast) { - let bann = - Pixbuf::new_from_resource_at_scale("/org/gnome/hammond/banner.png", 256, 256, true); - if let Ok(b) = bann { - self.banner.set_from_pixbuf(&b); - - let new_episodes = dbqueries::get_pd_unplayed_episodes(pd); - - if let Ok(n) = new_episodes { - if !n.is_empty() { - self.number.set_text(&n.len().to_string()); - self.banner.show(); - self.number.show(); - } - } - } } } From e04de5a576cdf4ca425c13409f62f6387edd76e9 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 17 Dec 2017 15:57:06 +0200 Subject: [PATCH 046/278] ShowsView: Move title to a tooltip, fix gresource, center flowbox halign. --- hammond-gtk/resources/gtk/shows_child.ui | 19 ------------------- hammond-gtk/resources/gtk/shows_view.ui | 6 +++--- hammond-gtk/resources/resources.xml | 1 - hammond-gtk/src/views/shows.rs | 5 +---- 4 files changed, 4 insertions(+), 27 deletions(-) diff --git a/hammond-gtk/resources/gtk/shows_child.ui b/hammond-gtk/resources/gtk/shows_child.ui index 82b0128..0fa68f6 100644 --- a/hammond-gtk/resources/gtk/shows_child.ui +++ b/hammond-gtk/resources/gtk/shows_child.ui @@ -35,24 +35,5 @@ 0 - - - True - False - center - center - True - center - end - True - 33 - False - - - False - False - 2 - -
diff --git a/hammond-gtk/resources/gtk/shows_view.ui b/hammond-gtk/resources/gtk/shows_view.ui index 5a3dff6..7981cb9 100644 --- a/hammond-gtk/resources/gtk/shows_view.ui +++ b/hammond-gtk/resources/gtk/shows_view.ui @@ -1,5 +1,5 @@ - + @@ -19,11 +19,11 @@ True False - baseline + center start True 5 - 2 + 5 20 none diff --git a/hammond-gtk/resources/resources.xml b/hammond-gtk/resources/resources.xml index e8bdc73..cb87ca4 100644 --- a/hammond-gtk/resources/resources.xml +++ b/hammond-gtk/resources/resources.xml @@ -1,7 +1,6 @@ - banner.png gtk/episode_widget.ui gtk/show_widget.ui gtk/empty_view.ui diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index b8bac62..d12dc58 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -79,7 +79,6 @@ impl ShowsPopulated { #[derive(Debug)] struct ShowsChild { container: gtk::Box, - title: gtk::Label, cover: gtk::Image, child: gtk::FlowBoxChild, } @@ -89,7 +88,6 @@ impl Default for ShowsChild { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/shows_child.ui"); let container: gtk::Box = builder.get_object("fb_child").unwrap(); - let title: gtk::Label = builder.get_object("pd_title").unwrap(); let cover: gtk::Image = builder.get_object("pd_cover").unwrap(); let child = gtk::FlowBoxChild::new(); @@ -97,7 +95,6 @@ impl Default for ShowsChild { ShowsChild { container, - title, cover, child, } @@ -112,7 +109,7 @@ impl ShowsChild { } fn init(&self, pd: &Podcast) { - self.title.set_text(pd.title()); + self.container.set_tooltip_text(pd.title()); let cover = get_pixbuf_from_path(pd); if let Some(img) = cover { From 32cd24fc7b7d69a691552e58a593f63ed93764d2 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 18 Dec 2017 18:20:40 +0200 Subject: [PATCH 047/278] EpisodesView: Added glade files and initial yak shaving. --- hammond-gtk/resources/gtk/episode_widget.ui | 6 +- hammond-gtk/resources/gtk/episodes_view.ui | 82 +++++++++++++++++++ .../resources/gtk/episodes_view_widget.ui | 25 ++++++ hammond-gtk/resources/gtk/show_widget.ui | 46 ++++++----- hammond-gtk/resources/resources.xml | 2 + hammond-gtk/src/content.rs | 7 +- hammond-gtk/src/views/episodes.rs | 46 +++++++++++ hammond-gtk/src/widgets/episode.rs | 6 +- hammond-gtk/src/widgets/show.rs | 4 - 9 files changed, 190 insertions(+), 34 deletions(-) create mode 100644 hammond-gtk/resources/gtk/episodes_view.ui create mode 100644 hammond-gtk/resources/gtk/episodes_view_widget.ui diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index dbf6a43..e7cf0a5 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -15,6 +15,7 @@ True False + center vertical 5 @@ -261,8 +262,8 @@ - False - True + True + False 5 0 @@ -275,6 +276,7 @@ False True 5 + end 1 diff --git a/hammond-gtk/resources/gtk/episodes_view.ui b/hammond-gtk/resources/gtk/episodes_view.ui new file mode 100644 index 0000000..8e8f3ab --- /dev/null +++ b/hammond-gtk/resources/gtk/episodes_view.ui @@ -0,0 +1,82 @@ + + + + + + True + False + vertical + + + True + True + in + + + True + False + + + True + False + center + + + True + False + vertical + + + + + + True + False + 0 + + + + + 600 + True + False + center + vertical + + + + + + False + True + 1 + + + + + True + False + vertical + + + + + + True + False + 2 + + + + + + + + + True + True + 0 + + + + diff --git a/hammond-gtk/resources/gtk/episodes_view_widget.ui b/hammond-gtk/resources/gtk/episodes_view_widget.ui new file mode 100644 index 0000000..a8ec5f9 --- /dev/null +++ b/hammond-gtk/resources/gtk/episodes_view_widget.ui @@ -0,0 +1,25 @@ + + + + + + True + False + + + True + False + 102 + image-x-generic-symbolic + + + False + True + 0 + + + + + + + diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index cc3c9b4..ead850a 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -78,6 +78,26 @@ False vertical 10 + + + True + False + start + end + Show description + True + 57 + + + + + + False + False + end + 1 + + True @@ -128,6 +148,9 @@ True center center + False @@ -145,27 +168,6 @@ 0 - - - True - False - start - center - Show description - True - word-char - 55 - - - - - - True - True - end - 1 - - True @@ -176,7 +178,7 @@
False - True + False 0 diff --git a/hammond-gtk/resources/resources.xml b/hammond-gtk/resources/resources.xml index cb87ca4..0c91cd0 100644 --- a/hammond-gtk/resources/resources.xml +++ b/hammond-gtk/resources/resources.xml @@ -4,6 +4,8 @@ gtk/episode_widget.ui gtk/show_widget.ui gtk/empty_view.ui + gtk/episodes_view.ui + gtk/episodes_view_widget.ui gtk/shows_view.ui gtk/shows_child.ui gtk/headerbar.ui diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index adc4cb6..3bdf019 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -6,6 +6,7 @@ use hammond_data::dbqueries; use views::shows::ShowsPopulated; use views::empty::EmptyView; +use views::episodes::EpisodesView; use widgets::show::ShowWidget; use headerbar::Header; @@ -155,14 +156,14 @@ struct EpisodeStack { impl EpisodeStack { fn new() -> Rc { - let _pop = RecentEpisodes {}; + let episodes = EpisodesView::default(); let empty = EmptyView::new(); let stack = gtk::Stack::new(); - // stack.add_named(&pop.container, "populated"); + stack.add_named(&episodes.container, "episodes"); stack.add_named(&empty.container, "empty"); // FIXME: - stack.set_visible_child_name("empty"); + stack.set_visible_child_name("episodes"); Rc::new(EpisodeStack { // empty, diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 8b13789..e8eb3da 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -1 +1,47 @@ +use gtk; +use gtk::prelude::*; +use widgets::episode::EpisodeWidget; + +#[derive(Debug, Clone)] +pub struct EpisodesView { + pub container: gtk::Box, + frame_parent: gtk::Box, +} + +impl Default for EpisodesView { + fn default() -> Self { + let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view.ui"); + let container: gtk::Box = builder.get_object("container").unwrap(); + let frame_parent: gtk::Box = builder.get_object("frame_parent").unwrap(); + + EpisodesView { + container, + frame_parent, + } + } +} + +#[derive(Debug, Clone)] +struct EpisodesViewWidget { + container: gtk::Box, + image: gtk::Image, + episode: gtk::Box, +} + +impl Default for EpisodesViewWidget { + fn default() -> Self { + let builder = + gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui"); + let container: gtk::Box = builder.get_object("container").unwrap(); + let image: gtk::Image = builder.get_object("cover").unwrap(); + let ep = EpisodeWidget::default(); + container.add(&ep.container); + + EpisodesViewWidget { + container, + image, + episode: ep.container, + } + } +} diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index fd9888d..8beb2b0 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -32,9 +32,9 @@ type Foo = RefCell< thread_local!(static GLOBAL: Foo = RefCell::new(None)); -#[derive(Debug)] -struct EpisodeWidget { - container: gtk::Box, +#[derive(Debug, Clone)] +pub struct EpisodeWidget { + pub container: gtk::Box, play: gtk::Button, delete: gtk::Button, download: gtk::Button, diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index c232661..7a30a63 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -40,10 +40,6 @@ impl Default for ShowWidget { let link: gtk::Button = builder.get_object("link_button").unwrap(); let settings: gtk::MenuButton = builder.get_object("settings_button").unwrap(); - unsub - .get_style_context() - .map(|c| c.add_class("destructive-action")); - ShowWidget { container, cover, From 61bd7893c7b19642eebb72c9c4924888e7e2fdc9 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 18 Dec 2017 19:10:50 +0200 Subject: [PATCH 048/278] EpisodeWidget: Remove Podcast depndancy from new() method. --- hammond-data/src/dbqueries.rs | 22 +++++++++++++ hammond-gtk/resources/gtk/episode_widget.ui | 5 +++ hammond-gtk/src/content.rs | 2 +- hammond-gtk/src/views/episodes.rs | 36 +++++++++++++++++++++ hammond-gtk/src/widgets/episode.rs | 14 ++++---- 5 files changed, 70 insertions(+), 9 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 7adb91c..5e26fcd 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -84,6 +84,28 @@ pub fn get_episodes_with_limit(limit: u32) -> Result> { .load::(&*con)?) } +pub fn get_episodeswidgets_with_limit(limit: u32) -> Result> { + use schema::episode::dsl::*; + + let db = connection(); + let con = db.get()?; + + Ok(episode + .select(( + rowid, + title, + uri, + local_uri, + epoch, + length, + played, + podcast_id, + )) + .order(epoch.desc()) + .limit(i64::from(limit)) + .load::(&*con)?) +} + pub fn get_podcast_from_id(pid: i32) -> Result { use schema::podcast::dsl::*; diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index e7cf0a5..e0aa126 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -177,6 +177,7 @@ Cancel True True + True center
@@ -191,6 +192,7 @@ delete_button True True + True end center @@ -213,6 +215,7 @@ True True True + True end center True @@ -235,6 +238,7 @@ True True + True center @@ -271,6 +275,7 @@ False + True False diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 3bdf019..0ea2bfb 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -156,7 +156,7 @@ struct EpisodeStack { impl EpisodeStack { fn new() -> Rc { - let episodes = EpisodesView::default(); + let episodes = EpisodesView::new(); let empty = EmptyView::new(); let stack = gtk::Stack::new(); diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index e8eb3da..dc8c923 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -1,8 +1,12 @@ use gtk; use gtk::prelude::*; +use hammond_data::dbqueries; + use widgets::episode::EpisodeWidget; +use std::rc::Rc; + #[derive(Debug, Clone)] pub struct EpisodesView { pub container: gtk::Box, @@ -22,6 +26,38 @@ impl Default for EpisodesView { } } +impl EpisodesView { + pub fn new() -> Rc { + let view = EpisodesView::default(); + + let episodes = dbqueries::get_episodeswidgets_with_limit(100).unwrap(); + let frame = gtk::Frame::new("Recent Episodes"); + let list = gtk::ListBox::new(); + + view.frame_parent.add(&frame); + frame.add(&list); + + list.set_vexpand(false); + list.set_hexpand(false); + list.set_visible(true); + list.set_selection_mode(gtk::SelectionMode::None); + + episodes.into_iter().for_each(|mut ep| { + let widget = EpisodeWidget::new(&mut ep); + list.add(&widget.container); + + let sep = gtk::Separator::new(gtk::Orientation::Vertical); + sep.set_sensitive(false); + sep.set_can_focus(false); + + list.add(&sep); + sep.show() + }); + + Rc::new(view) + } +} + #[derive(Debug, Clone)] struct EpisodesViewWidget { container: gtk::Box, diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 8beb2b0..d872fe5 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -82,16 +82,16 @@ impl Default for EpisodeWidget { } impl EpisodeWidget { - pub fn new(episode: &mut EpisodeWidgetQuery, pd: &Podcast) -> EpisodeWidget { + pub fn new(episode: &mut EpisodeWidgetQuery) -> EpisodeWidget { let widget = EpisodeWidget::default(); - widget.init(episode, pd); + widget.init(episode); widget } // TODO: calculate lenght. // TODO: wire the progress_bar to the downloader. // TODO: wire the cancel button. - fn init(&self, episode: &mut EpisodeWidgetQuery, pd: &Podcast) { + fn init(&self, episode: &mut EpisodeWidgetQuery) { self.title.set_xalign(0.0); self.title.set_text(episode.title()); @@ -147,7 +147,6 @@ impl EpisodeWidget { download.show(); })); - let pd_title = pd.title().to_owned(); let play = &self.play; let delete = &self.delete; let cancel = &self.cancel; @@ -155,7 +154,6 @@ impl EpisodeWidget { self.download.connect_clicked( clone!(play, delete, episode, cancel, progress => move |dl| { on_download_clicked( - &pd_title, &mut episode.clone(), dl, &play, @@ -170,7 +168,6 @@ impl EpisodeWidget { // TODO: show notification when dl is finished. fn on_download_clicked( - pd_title: &str, ep: &mut EpisodeWidgetQuery, download_bttn: >k::Button, play_bttn: >k::Button, @@ -194,7 +191,8 @@ fn on_download_clicked( }), ); - let pd_title = pd_title.to_owned(); + let pd = dbqueries::get_podcast_from_id(ep.podcast_id()).unwrap(); + let pd_title = pd.title().to_owned(); let mut ep = ep.clone(); cancel_bttn.show(); progress_bar.show(); @@ -270,7 +268,7 @@ pub fn episodes_listbox(pd: &Podcast) -> Result { let list = gtk::ListBox::new(); episodes.into_iter().for_each(|mut ep| { - let widget = EpisodeWidget::new(&mut ep, pd); + let widget = EpisodeWidget::new(&mut ep); list.add(&widget.container); let sep = gtk::Separator::new(gtk::Orientation::Vertical); From 5220eaceee3b426c359f5c833bd017ec80cb121e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 18 Dec 2017 21:35:51 +0200 Subject: [PATCH 049/278] EpisodesView: Add an empty cover to the widget. --- .../resources/gtk/episodes_view_widget.ui | 2 +- hammond-gtk/src/views/episodes.rs | 24 ++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/hammond-gtk/resources/gtk/episodes_view_widget.ui b/hammond-gtk/resources/gtk/episodes_view_widget.ui index a8ec5f9..3aa6d88 100644 --- a/hammond-gtk/resources/gtk/episodes_view_widget.ui +++ b/hammond-gtk/resources/gtk/episodes_view_widget.ui @@ -9,7 +9,7 @@ True False - 102 + 64 image-x-generic-symbolic diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index dc8c923..e418a44 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -2,6 +2,7 @@ use gtk; use gtk::prelude::*; use hammond_data::dbqueries; +use hammond_data::EpisodeWidgetQuery; use widgets::episode::EpisodeWidget; @@ -43,8 +44,8 @@ impl EpisodesView { list.set_selection_mode(gtk::SelectionMode::None); episodes.into_iter().for_each(|mut ep| { - let widget = EpisodeWidget::new(&mut ep); - list.add(&widget.container); + let viewep = EpisodesViewWidget::new(&mut ep); + list.add(&viewep.container); let sep = gtk::Separator::new(gtk::Orientation::Vertical); sep.set_sensitive(false); @@ -72,7 +73,24 @@ impl Default for EpisodesViewWidget { let container: gtk::Box = builder.get_object("container").unwrap(); let image: gtk::Image = builder.get_object("cover").unwrap(); let ep = EpisodeWidget::default(); - container.add(&ep.container); + container.pack_start(&ep.container, true, true, 5); + + EpisodesViewWidget { + container, + image, + episode: ep.container, + } + } +} + +impl EpisodesViewWidget { + fn new(episode: &mut EpisodeWidgetQuery) -> EpisodesViewWidget { + let builder = + gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui"); + let container: gtk::Box = builder.get_object("container").unwrap(); + let image: gtk::Image = builder.get_object("cover").unwrap(); + let ep = EpisodeWidget::new(episode); + container.pack_start(&ep.container, true, true, 5); EpisodesViewWidget { container, From f602e8c36d5c7297e31e0d3660815d094a23d7df Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 19 Dec 2017 11:04:44 +0200 Subject: [PATCH 050/278] EpisodesView: Create a DieselModel for EpisodeViewWidget. --- hammond-data/src/dbqueries.rs | 33 +++++++++++++---------- hammond-data/src/models/queryables.rs | 39 +++++++++++++++++++++++++++ hammond-data/src/utils.rs | 4 +++ hammond-gtk/src/views/episodes.rs | 7 ++--- 4 files changed, 66 insertions(+), 17 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 5e26fcd..47b59ef 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -2,7 +2,7 @@ use diesel::prelude::*; use diesel; -use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, Source}; +use models::queryables::{Episode, EpisodeViewWidgetQuery, EpisodeWidgetQuery, Podcast, Source}; use chrono::prelude::*; use errors::*; @@ -84,26 +84,31 @@ pub fn get_episodes_with_limit(limit: u32) -> Result> { .load::(&*con)?) } -pub fn get_episodeswidgets_with_limit(limit: u32) -> Result> { - use schema::episode::dsl::*; +pub fn get_episodes_view_widgets_with_limit(limit: u32) -> Result> { + use schema::{episode, podcast}; + + joinable!(episode -> podcast (rowid)); + allow_tables_to_appear_in_same_query!(episode, podcast); let db = connection(); let con = db.get()?; - Ok(episode + Ok(episode::table + .left_join(podcast::table) .select(( - rowid, - title, - uri, - local_uri, - epoch, - length, - played, - podcast_id, + episode::rowid, + episode::title, + episode::uri, + episode::local_uri, + episode::epoch, + episode::length, + episode::played, + episode::podcast_id, + (podcast::image_uri).nullable(), )) - .order(epoch.desc()) + .order(episode::epoch.desc()) .limit(i64::from(limit)) - .load::(&*con)?) + .load::(&*con)?) } pub fn get_podcast_from_id(pid: i32) -> Result { diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 4290979..e87d8b6 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -320,6 +320,45 @@ impl EpisodeWidgetQuery { } } +impl From for EpisodeWidgetQuery { + fn from(view: EpisodeViewWidgetQuery) -> EpisodeWidgetQuery { + EpisodeWidgetQuery { + rowid: view.rowid, + title: view.title, + uri: view.uri, + local_uri: view.local_uri, + epoch: view.epoch, + length: view.length, + played: view.played, + // favorite: view.favorite, + // archive: view.archive, + podcast_id: view.podcast_id, + } + } +} + +#[derive(Queryable, Debug, Clone)] +/// Diesel Model to be used for constructing `EpisodeWidgets`. +pub struct EpisodeViewWidgetQuery { + rowid: i32, + title: String, + uri: Option, + local_uri: Option, + epoch: i32, + length: Option, + played: Option, + // favorite: bool, + // archive: bool, + podcast_id: i32, + image_uri: Option, +} + +impl EpisodeViewWidgetQuery { + pub fn image_uri(&self) -> Option<&str> { + self.image_uri.as_ref().map(|s| s.as_str()) + } +} + #[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] #[belongs_to(Source, foreign_key = "source_id")] #[changeset_options(treat_none_as_null = "true")] diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index fb9fe1e..f15c757 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -14,6 +14,8 @@ use std::path::Path; use std::fs; fn download_checker() -> Result<()> { + // TODO: give it it's own diesel model, + // so it does not pull useless and expensive stuff like description. let episodes = dbqueries::get_downloaded_episodes()?; episodes @@ -35,6 +37,8 @@ fn checker_helper(ep: &mut Episode) { } fn played_cleaner() -> Result<()> { + // TODO: give it it's own diesel model, + // so it does not pull useless and expensive stuff like description. let episodes = dbqueries::get_played_episodes()?; let now_utc = Utc::now().timestamp() as i32; diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index e418a44..37b18c3 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -31,7 +31,7 @@ impl EpisodesView { pub fn new() -> Rc { let view = EpisodesView::default(); - let episodes = dbqueries::get_episodeswidgets_with_limit(100).unwrap(); + let episodes = dbqueries::get_episodes_view_widgets_with_limit(100).unwrap(); let frame = gtk::Frame::new("Recent Episodes"); let list = gtk::ListBox::new(); @@ -43,8 +43,9 @@ impl EpisodesView { list.set_visible(true); list.set_selection_mode(gtk::SelectionMode::None); - episodes.into_iter().for_each(|mut ep| { - let viewep = EpisodesViewWidget::new(&mut ep); + episodes.into_iter().for_each(|ep| { + info!("{:?}", &ep.image_uri()); + let viewep = EpisodesViewWidget::new(&mut ep.into()); list.add(&viewep.container); let sep = gtk::Separator::new(gtk::Orientation::Vertical); From ad9a932143699265be1fdcb952dd7a193ccf4069 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 19 Dec 2017 12:56:16 +0200 Subject: [PATCH 051/278] Fix diesel query. --- hammond-data/src/dbqueries.rs | 2 +- hammond-gtk/src/views/episodes.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 47b59ef..b51f884 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -87,7 +87,7 @@ pub fn get_episodes_with_limit(limit: u32) -> Result> { pub fn get_episodes_view_widgets_with_limit(limit: u32) -> Result> { use schema::{episode, podcast}; - joinable!(episode -> podcast (rowid)); + joinable!(episode -> podcast (podcast_id)); allow_tables_to_appear_in_same_query!(episode, podcast); let db = connection(); diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 37b18c3..120bc7f 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -44,7 +44,6 @@ impl EpisodesView { list.set_selection_mode(gtk::SelectionMode::None); episodes.into_iter().for_each(|ep| { - info!("{:?}", &ep.image_uri()); let viewep = EpisodesViewWidget::new(&mut ep.into()); list.add(&viewep.container); From 895591f628eeab91635161ac7b60841662d02d41 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 19 Dec 2017 13:19:38 +0200 Subject: [PATCH 052/278] EpisodesView: Use show cover image. --- hammond-data/src/lib.rs | 2 +- hammond-data/src/models/queryables.rs | 8 ++++++++ hammond-gtk/src/utils.rs | 7 +++++++ hammond-gtk/src/views/episodes.rs | 22 ++++++++++++++++------ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index 97aec76..711eb0c 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -61,7 +61,7 @@ pub(crate) mod models; mod parser; mod schema; -pub use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, Source}; +pub use models::queryables::{Episode, EpisodeViewWidgetQuery, EpisodeWidgetQuery, Podcast, Source}; /// [XDG Base Direcotory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) Paths. #[allow(missing_debug_implementations)] diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index e87d8b6..5120f83 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -354,9 +354,17 @@ pub struct EpisodeViewWidgetQuery { } impl EpisodeViewWidgetQuery { + /// Get the `image_uri`. + /// + /// Represents the uri(url usually) that the Feed cover image is located at. pub fn image_uri(&self) -> Option<&str> { self.image_uri.as_ref().map(|s| s.as_str()) } + + /// `Podcast` table foreign key. + pub fn podcast_id(&self) -> i32 { + self.podcast_id + } } #[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index c2f484d..66f5b54 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -59,6 +59,8 @@ fn refresh_podcasts_view() -> glib::Continue { glib::Continue(false) } +// FIXME: use something that would just scale? + pub fn get_pixbuf_from_path(pd: &Podcast) -> Option { let img_path = downloader::cache_image(pd)?; Pixbuf::new_from_file_at_scale(&img_path, 256, 256, true).ok() @@ -69,6 +71,11 @@ pub fn get_pixbuf_from_path_128(pd: &Podcast) -> Option { Pixbuf::new_from_file_at_scale(&img_path, 128, 128, true).ok() } +pub fn get_pixbuf_from_path_64(pd: &Podcast) -> Option { + let img_path = downloader::cache_image(pd)?; + Pixbuf::new_from_file_at_scale(&img_path, 64, 64, true).ok() +} + #[cfg(test)] mod tests { use hammond_data::Source; diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 120bc7f..00a883b 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -2,9 +2,10 @@ use gtk; use gtk::prelude::*; use hammond_data::dbqueries; -use hammond_data::EpisodeWidgetQuery; +use hammond_data::EpisodeViewWidgetQuery; use widgets::episode::EpisodeWidget; +use utils::get_pixbuf_from_path_64; use std::rc::Rc; @@ -32,11 +33,12 @@ impl EpisodesView { let view = EpisodesView::default(); let episodes = dbqueries::get_episodes_view_widgets_with_limit(100).unwrap(); - let frame = gtk::Frame::new("Recent Episodes"); + let frame = gtk::Frame::new(None); let list = gtk::ListBox::new(); - view.frame_parent.add(&frame); + view.frame_parent.pack_start(&frame, true, false, 10); frame.add(&list); + frame.set_shadow_type(gtk::ShadowType::In); list.set_vexpand(false); list.set_hexpand(false); @@ -44,7 +46,7 @@ impl EpisodesView { list.set_selection_mode(gtk::SelectionMode::None); episodes.into_iter().for_each(|ep| { - let viewep = EpisodesViewWidget::new(&mut ep.into()); + let viewep = EpisodesViewWidget::new(ep); list.add(&viewep.container); let sep = gtk::Separator::new(gtk::Orientation::Vertical); @@ -84,12 +86,20 @@ impl Default for EpisodesViewWidget { } impl EpisodesViewWidget { - fn new(episode: &mut EpisodeWidgetQuery) -> EpisodesViewWidget { + fn new(episode: EpisodeViewWidgetQuery) -> EpisodesViewWidget { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); let image: gtk::Image = builder.get_object("cover").unwrap(); - let ep = EpisodeWidget::new(episode); + + // FIXME: + let pd = dbqueries::get_podcast_from_id(episode.podcast_id()).unwrap(); + let img = get_pixbuf_from_path_64(&pd); + if let Some(i) = img { + image.set_from_pixbuf(&i); + } + + let ep = EpisodeWidget::new(&mut episode.into()); container.pack_start(&ep.container, true, true, 5); EpisodesViewWidget { From 914cad72f597e855de31e0c5f721b844ca5a7082 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 19 Dec 2017 20:45:40 +0200 Subject: [PATCH 053/278] EpisodesView: Custom Diesel model not really necessary. --- hammond-data/src/dbqueries.rs | 13 +++----- hammond-data/src/lib.rs | 2 +- hammond-data/src/models/queryables.rs | 47 --------------------------- hammond-gtk/src/utils.rs | 1 + hammond-gtk/src/views/episodes.rs | 21 ++++++------ 5 files changed, 17 insertions(+), 67 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index b51f884..caaa76a 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -2,7 +2,7 @@ use diesel::prelude::*; use diesel; -use models::queryables::{Episode, EpisodeViewWidgetQuery, EpisodeWidgetQuery, Podcast, Source}; +use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, Source}; use chrono::prelude::*; use errors::*; @@ -84,17 +84,13 @@ pub fn get_episodes_with_limit(limit: u32) -> Result> { .load::(&*con)?) } -pub fn get_episodes_view_widgets_with_limit(limit: u32) -> Result> { - use schema::{episode, podcast}; - - joinable!(episode -> podcast (podcast_id)); - allow_tables_to_appear_in_same_query!(episode, podcast); +pub fn get_episodes_widgets_with_limit(limit: u32) -> Result> { + use schema::episode; let db = connection(); let con = db.get()?; Ok(episode::table - .left_join(podcast::table) .select(( episode::rowid, episode::title, @@ -104,11 +100,10 @@ pub fn get_episodes_view_widgets_with_limit(limit: u32) -> Result(&*con)?) + .load::(&*con)?) } pub fn get_podcast_from_id(pid: i32) -> Result { diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index 711eb0c..97aec76 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -61,7 +61,7 @@ pub(crate) mod models; mod parser; mod schema; -pub use models::queryables::{Episode, EpisodeViewWidgetQuery, EpisodeWidgetQuery, Podcast, Source}; +pub use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, Source}; /// [XDG Base Direcotory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) Paths. #[allow(missing_debug_implementations)] diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 5120f83..4290979 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -320,53 +320,6 @@ impl EpisodeWidgetQuery { } } -impl From for EpisodeWidgetQuery { - fn from(view: EpisodeViewWidgetQuery) -> EpisodeWidgetQuery { - EpisodeWidgetQuery { - rowid: view.rowid, - title: view.title, - uri: view.uri, - local_uri: view.local_uri, - epoch: view.epoch, - length: view.length, - played: view.played, - // favorite: view.favorite, - // archive: view.archive, - podcast_id: view.podcast_id, - } - } -} - -#[derive(Queryable, Debug, Clone)] -/// Diesel Model to be used for constructing `EpisodeWidgets`. -pub struct EpisodeViewWidgetQuery { - rowid: i32, - title: String, - uri: Option, - local_uri: Option, - epoch: i32, - length: Option, - played: Option, - // favorite: bool, - // archive: bool, - podcast_id: i32, - image_uri: Option, -} - -impl EpisodeViewWidgetQuery { - /// Get the `image_uri`. - /// - /// Represents the uri(url usually) that the Feed cover image is located at. - pub fn image_uri(&self) -> Option<&str> { - self.image_uri.as_ref().map(|s| s.as_str()) - } - - /// `Podcast` table foreign key. - pub fn podcast_id(&self) -> i32 { - self.podcast_id - } -} - #[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] #[belongs_to(Source, foreign_key = "source_id")] #[changeset_options(treat_none_as_null = "true")] diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 66f5b54..3e22f8e 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -60,6 +60,7 @@ fn refresh_podcasts_view() -> glib::Continue { } // FIXME: use something that would just scale? +// TODO: make a diesel model with only title, local_uri pub fn get_pixbuf_from_path(pd: &Podcast) -> Option { let img_path = downloader::cache_image(pd)?; diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 00a883b..91c3137 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -2,7 +2,7 @@ use gtk; use gtk::prelude::*; use hammond_data::dbqueries; -use hammond_data::EpisodeViewWidgetQuery; +use hammond_data::EpisodeWidgetQuery; use widgets::episode::EpisodeWidget; use utils::get_pixbuf_from_path_64; @@ -32,7 +32,7 @@ impl EpisodesView { pub fn new() -> Rc { let view = EpisodesView::default(); - let episodes = dbqueries::get_episodes_view_widgets_with_limit(100).unwrap(); + let episodes = dbqueries::get_episodes_widgets_with_limit(100).unwrap(); let frame = gtk::Frame::new(None); let list = gtk::ListBox::new(); @@ -45,8 +45,8 @@ impl EpisodesView { list.set_visible(true); list.set_selection_mode(gtk::SelectionMode::None); - episodes.into_iter().for_each(|ep| { - let viewep = EpisodesViewWidget::new(ep); + episodes.into_iter().for_each(|mut ep| { + let viewep = EpisodesViewWidget::new(&mut ep); list.add(&viewep.container); let sep = gtk::Separator::new(gtk::Orientation::Vertical); @@ -86,20 +86,21 @@ impl Default for EpisodesViewWidget { } impl EpisodesViewWidget { - fn new(episode: EpisodeViewWidgetQuery) -> EpisodesViewWidget { + fn new(episode: &mut EpisodeWidgetQuery) -> EpisodesViewWidget { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); let image: gtk::Image = builder.get_object("cover").unwrap(); // FIXME: - let pd = dbqueries::get_podcast_from_id(episode.podcast_id()).unwrap(); - let img = get_pixbuf_from_path_64(&pd); - if let Some(i) = img { - image.set_from_pixbuf(&i); + if let Ok(pd) = dbqueries::get_podcast_from_id(episode.podcast_id()) { + let img = get_pixbuf_from_path_64(&pd); + if let Some(i) = img { + image.set_from_pixbuf(&i); + } } - let ep = EpisodeWidget::new(&mut episode.into()); + let ep = EpisodeWidget::new(episode); container.pack_start(&ep.container, true, true, 5); EpisodesViewWidget { From 632f011db5aeb4d15e0f0803ba54b53586760048 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 20 Dec 2017 13:13:32 +0200 Subject: [PATCH 054/278] EpisodeView: Implement initial view update. --- hammond-gtk/src/content.rs | 12 +++++++++++- hammond-gtk/src/views/episodes.rs | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 0ea2bfb..c869741 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -173,6 +173,16 @@ impl EpisodeStack { } fn update(&self) { - // unimplemented!() + // FIXME: figure out if it should switch to empty view + let vis = self.stack.get_visible_child_name().unwrap(); + let old = self.stack.get_child_by_name("episodes").unwrap(); + + let eps = EpisodesView::new(); + + self.stack.remove(&old); + self.stack.add_named(&eps.container, "episodes"); + self.stack.set_visible_child_name(&vis); + + old.destroy(); } } diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 91c3137..35f51a2 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -57,6 +57,7 @@ impl EpisodesView { sep.show() }); + view.container.show_all(); Rc::new(view) } } From bda09c032a44940e9978a1ec046ebf3b2b90d6f1 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 20 Dec 2017 13:18:29 +0200 Subject: [PATCH 055/278] EpisodeWidget: Update the progrress bar only when download clicked. --- hammond-gtk/src/widgets/episode.rs | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index d872fe5..7bd11e3 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -101,12 +101,6 @@ impl EpisodeWidget { .map(|c| c.add_class("dim-label")); } - let progress = self.progress.clone(); - timeout_add(200, move || { - progress.pulse(); - glib::Continue(true) - }); - if let Some(size) = episode.length() { let megabytes = size / 1024 / 1024; // episode.length represents bytes self.size.set_text(&format!("{} MB", megabytes)) @@ -150,7 +144,7 @@ impl EpisodeWidget { let play = &self.play; let delete = &self.delete; let cancel = &self.cancel; - let progress = &self.progress; + let progress = self.progress.clone(); self.download.connect_clicked( clone!(play, delete, episode, cancel, progress => move |dl| { on_download_clicked( @@ -159,7 +153,7 @@ impl EpisodeWidget { &play, &delete, &cancel, - &progress + progress.clone() ); }), ); @@ -173,20 +167,28 @@ fn on_download_clicked( play_bttn: >k::Button, del_bttn: >k::Button, cancel_bttn: >k::Button, - progress_bar: >k::ProgressBar, + progress_bar: gtk::ProgressBar, ) { + let progress = progress_bar.clone(); + + // Start the proggress_bar pulse. + timeout_add(200, move || { + progress_bar.pulse(); + glib::Continue(true) + }); + // Create a async channel. let (sender, receiver) = channel(); // Pass the desired arguments into the Local Thread Storage. GLOBAL.with( - clone!(download_bttn, play_bttn, del_bttn, cancel_bttn, progress_bar => move |global| { + clone!(download_bttn, play_bttn, del_bttn, cancel_bttn, progress => move |global| { *global.borrow_mut() = Some(( download_bttn, play_bttn, del_bttn, cancel_bttn, - progress_bar, + progress, receiver)); }), ); @@ -195,7 +197,7 @@ fn on_download_clicked( let pd_title = pd.title().to_owned(); let mut ep = ep.clone(); cancel_bttn.show(); - progress_bar.show(); + progress.show(); download_bttn.hide(); thread::spawn(move || { let download_fold = downloader::get_download_folder(&pd_title).unwrap(); From ccfea527ac0f24627fe3ef0c4c3c927a799b8822 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 20 Dec 2017 13:25:31 +0200 Subject: [PATCH 056/278] gitlab-ci: use --force for clippy and rustfmt isntallation. --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8726f9e..e64a2ba 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,7 +44,7 @@ rustfmt: CFG_RELEASE_CHANNEL: "nightly" script: - rustc --version && cargo --version - - cargo install rustfmt-nightly + - cargo install rustfmt-nightly --force - cargo fmt --all -- --write-mode=diff # Configure and run clippy on nightly @@ -54,5 +54,5 @@ clippy: stage: lint script: - rustc --version && cargo --version - - cargo install clippy + - cargo install clippy --force - cargo clippy --all From ace62f7ed6b1d213ee78f503f9f8f55566e4405f Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 20 Dec 2017 14:49:28 +0200 Subject: [PATCH 057/278] EpisodesView: Initial draft of episodewidget's splitting into the frames. --- hammond-gtk/resources/gtk/episodes_view.ui | 162 ++++++++++++++++++++- hammond-gtk/src/views/episodes.rs | 83 +++++++++-- 2 files changed, 229 insertions(+), 16 deletions(-) diff --git a/hammond-gtk/resources/gtk/episodes_view.ui b/hammond-gtk/resources/gtk/episodes_view.ui index 8e8f3ab..4776fd9 100644 --- a/hammond-gtk/resources/gtk/episodes_view.ui +++ b/hammond-gtk/resources/gtk/episodes_view.ui @@ -42,8 +42,168 @@ False center vertical + 7 - + + True + False + True + start + Today + + + + + + False + True + 0 + + + + + True + False + True + 0 + in + + + True + False + True + none + + + + + + + + False + True + 1 + + + + + True + False + True + start + Yesterday + + + + + + False + True + 2 + + + + + True + False + 0 + in + + + True + False + none + + + + + + + + False + True + 3 + + + + + True + False + True + start + This Week + + + + + + False + True + 4 + + + + + True + False + 0 + in + + + True + False + none + + + + + + + + False + True + 5 + + + + + True + False + True + start + This Month + + + + + + False + True + 6 + + + + + True + False + 0 + in + + + True + False + none + + + + + + + + False + True + 7 + diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 35f51a2..c711fb4 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -1,5 +1,6 @@ use gtk; use gtk::prelude::*; +use chrono::prelude::*; use hammond_data::dbqueries; use hammond_data::EpisodeWidgetQuery; @@ -9,10 +10,26 @@ use utils::get_pixbuf_from_path_64; use std::rc::Rc; +#[derive(Debug, Clone)] +enum ListSplit { + Today, + Yday, + Week, + Month, +} + #[derive(Debug, Clone)] pub struct EpisodesView { pub container: gtk::Box, frame_parent: gtk::Box, + today_box: gtk::ListBox, + yday_box: gtk::ListBox, + week_box: gtk::ListBox, + month_box: gtk::ListBox, + today_label: gtk::Label, + yday_label: gtk::Label, + week_label: gtk::Label, + month_label: gtk::Label, } impl Default for EpisodesView { @@ -20,10 +37,26 @@ impl Default for EpisodesView { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); let frame_parent: gtk::Box = builder.get_object("frame_parent").unwrap(); + let today_box: gtk::ListBox = builder.get_object("today_box").unwrap(); + let yday_box: gtk::ListBox = builder.get_object("yday_box").unwrap(); + let week_box: gtk::ListBox = builder.get_object("week_box").unwrap(); + let month_box: gtk::ListBox = builder.get_object("month_box").unwrap(); + let today_label: gtk::Label = builder.get_object("today_label").unwrap(); + let yday_label: gtk::Label = builder.get_object("yday_label").unwrap(); + let week_label: gtk::Label = builder.get_object("week_label").unwrap(); + let month_label: gtk::Label = builder.get_object("month_label").unwrap(); EpisodesView { container, frame_parent, + today_box, + yday_box, + week_box, + month_box, + today_label, + yday_label, + week_label, + month_label, } } } @@ -31,29 +64,35 @@ impl Default for EpisodesView { impl EpisodesView { pub fn new() -> Rc { let view = EpisodesView::default(); - let episodes = dbqueries::get_episodes_widgets_with_limit(100).unwrap(); - let frame = gtk::Frame::new(None); - let list = gtk::ListBox::new(); - - view.frame_parent.pack_start(&frame, true, false, 10); - frame.add(&list); - frame.set_shadow_type(gtk::ShadowType::In); - - list.set_vexpand(false); - list.set_hexpand(false); - list.set_visible(true); - list.set_selection_mode(gtk::SelectionMode::None); + let now_utc = Utc::now().timestamp() as i32; episodes.into_iter().for_each(|mut ep| { let viewep = EpisodesViewWidget::new(&mut ep); - list.add(&viewep.container); - let sep = gtk::Separator::new(gtk::Orientation::Vertical); sep.set_sensitive(false); sep.set_can_focus(false); - list.add(&sep); + let t = split(now_utc, ep.epoch()); + match t { + ListSplit::Today => { + view.today_box.add(&viewep.container); + view.today_box.add(&sep) + } + ListSplit::Yday => { + view.yday_box.add(&viewep.container); + view.yday_box.add(&sep) + } + ListSplit::Week => { + view.week_box.add(&viewep.container); + view.week_box.add(&sep) + } + _ => { + view.month_box.add(&viewep.container); + view.month_box.add(&sep) + } + } + sep.show() }); @@ -62,6 +101,20 @@ impl EpisodesView { } } +fn split(now_utc: i32, epoch: i32) -> ListSplit { + let t = now_utc - epoch; + + if t < 86_400 { + ListSplit::Today + } else if t < 172_800 { + ListSplit::Yday + } else if t < 604_800 { + ListSplit::Week + } else { + ListSplit::Month + } +} + #[derive(Debug, Clone)] struct EpisodesViewWidget { container: gtk::Box, From c070fc3032cb3346740305dccbb5849bd2b02f03 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 20 Dec 2017 15:12:55 +0200 Subject: [PATCH 058/278] EpisodesView: Ugly and Hacky Prototype of episode splitting. --- hammond-gtk/resources/gtk/episodes_view.ui | 311 +++++++++++++++------ hammond-gtk/src/views/episodes.rs | 105 +++++-- 2 files changed, 318 insertions(+), 98 deletions(-) diff --git a/hammond-gtk/resources/gtk/episodes_view.ui b/hammond-gtk/resources/gtk/episodes_view.ui index 4776fd9..b3a4456 100644 --- a/hammond-gtk/resources/gtk/episodes_view.ui +++ b/hammond-gtk/resources/gtk/episodes_view.ui @@ -44,15 +44,50 @@ vertical 7 - + True False True - start - Today - - - + vertical + + + True + False + start + Today + + + + + + False + True + 0 + + + + + True + False + 0 + in + + + True + False + none + + + + + + + + False + True + 1 + + False @@ -61,22 +96,49 @@ - + True False True - 0 - in + vertical - + True False - True - none + start + Yesterday + + + + + False + True + 0 + - - + + + True + False + 0 + in + + + True + False + none + + + + + + + + False + True + 1 + @@ -86,15 +148,50 @@ - + True False True - start - Yesterday - - - + vertical + + + True + False + start + This Week + + + + + + False + True + 0 + + + + + True + False + 0 + in + + + True + False + none + + + + + + + + False + True + 1 + + False @@ -103,20 +200,49 @@ - + True False - 0 - in + True + vertical - + True False - none + start + This Month + + + + + False + True + 0 + - - + + + True + False + 0 + in + + + True + False + none + + + + + + + + False + True + 1 + @@ -126,15 +252,50 @@ - + True False True - start - This Week - - - + vertical + + + True + False + start + This Year + + + + + + False + True + 0 + + + + + True + False + 0 + in + + + True + False + none + + + + + + + + False + True + 1 + + False @@ -143,20 +304,50 @@ - + True False - 0 - in + True + vertical - + True False - none + start + Older than a Year + + + + + False + True + 0 + - - + + + True + False + 0 + in + + + True + False + True + none + + + + + + + + False + True + 1 + @@ -165,46 +356,6 @@ 5 - - - True - False - True - start - This Month - - - - - - False - True - 6 - - - - - True - False - 0 - in - - - True - False - none - - - - - - - - False - True - 7 - - False diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index c711fb4..57191f1 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -16,20 +16,32 @@ enum ListSplit { Yday, Week, Month, + Year, + Rest, } #[derive(Debug, Clone)] pub struct EpisodesView { pub container: gtk::Box, frame_parent: gtk::Box, - today_box: gtk::ListBox, - yday_box: gtk::ListBox, - week_box: gtk::ListBox, - month_box: gtk::ListBox, + today_box: gtk::Box, + yday_box: gtk::Box, + week_box: gtk::Box, + month_box: gtk::Box, + year_box: gtk::Box, + rest_box: gtk::Box, + today_list: gtk::ListBox, + yday_list: gtk::ListBox, + week_list: gtk::ListBox, + month_list: gtk::ListBox, + year_list: gtk::ListBox, + rest_list: gtk::ListBox, today_label: gtk::Label, yday_label: gtk::Label, week_label: gtk::Label, month_label: gtk::Label, + year_label: gtk::Label, + rest_label: gtk::Label, } impl Default for EpisodesView { @@ -37,14 +49,24 @@ impl Default for EpisodesView { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); let frame_parent: gtk::Box = builder.get_object("frame_parent").unwrap(); - let today_box: gtk::ListBox = builder.get_object("today_box").unwrap(); - let yday_box: gtk::ListBox = builder.get_object("yday_box").unwrap(); - let week_box: gtk::ListBox = builder.get_object("week_box").unwrap(); - let month_box: gtk::ListBox = builder.get_object("month_box").unwrap(); + let today_box: gtk::Box = builder.get_object("today_box").unwrap(); + let yday_box: gtk::Box = builder.get_object("yday_box").unwrap(); + let week_box: gtk::Box = builder.get_object("week_box").unwrap(); + let month_box: gtk::Box = builder.get_object("month_box").unwrap(); + let year_box: gtk::Box = builder.get_object("year_box").unwrap(); + let rest_box: gtk::Box = builder.get_object("rest_box").unwrap(); + let today_list: gtk::ListBox = builder.get_object("today_list").unwrap(); + let yday_list: gtk::ListBox = builder.get_object("yday_list").unwrap(); + let week_list: gtk::ListBox = builder.get_object("week_list").unwrap(); + let month_list: gtk::ListBox = builder.get_object("month_list").unwrap(); + let year_list: gtk::ListBox = builder.get_object("year_list").unwrap(); + let rest_list: gtk::ListBox = builder.get_object("rest_list").unwrap(); let today_label: gtk::Label = builder.get_object("today_label").unwrap(); let yday_label: gtk::Label = builder.get_object("yday_label").unwrap(); let week_label: gtk::Label = builder.get_object("week_label").unwrap(); let month_label: gtk::Label = builder.get_object("month_label").unwrap(); + let year_label: gtk::Label = builder.get_object("year_label").unwrap(); + let rest_label: gtk::Label = builder.get_object("rest_label").unwrap(); EpisodesView { container, @@ -53,10 +75,20 @@ impl Default for EpisodesView { yday_box, week_box, month_box, + year_box, + rest_box, + today_list, + yday_list, + week_list, + month_list, + year_list, + rest_list, today_label, yday_label, week_label, month_label, + year_label, + rest_label, } } } @@ -76,31 +108,64 @@ impl EpisodesView { let t = split(now_utc, ep.epoch()); match t { ListSplit::Today => { - view.today_box.add(&viewep.container); - view.today_box.add(&sep) + view.today_list.add(&viewep.container); + view.today_list.add(&sep) } ListSplit::Yday => { - view.yday_box.add(&viewep.container); - view.yday_box.add(&sep) + view.yday_list.add(&viewep.container); + view.yday_list.add(&sep) } ListSplit::Week => { - view.week_box.add(&viewep.container); - view.week_box.add(&sep) + view.week_list.add(&viewep.container); + view.week_list.add(&sep) } - _ => { - view.month_box.add(&viewep.container); - view.month_box.add(&sep) + ListSplit::Month => { + view.month_list.add(&viewep.container); + view.month_list.add(&sep) + } + ListSplit::Year => { + view.year_list.add(&viewep.container); + view.year_list.add(&sep) + } + ListSplit::Rest => { + view.rest_list.add(&viewep.container); + view.rest_list.add(&sep) } } sep.show() }); + if view.today_list.get_children().is_empty() { + view.today_box.hide(); + } + + if view.yday_list.get_children().is_empty() { + view.yday_box.hide(); + } + + if view.week_list.get_children().is_empty() { + view.week_box.hide(); + } + + if view.month_list.get_children().is_empty() { + view.month_box.hide(); + } + + if view.year_list.get_children().is_empty() { + view.year_box.hide(); + } + + if view.rest_list.get_children().is_empty() { + view.rest_box.hide(); + } + view.container.show_all(); Rc::new(view) } } +// TODO: Avoid epoch calculations, use chrono instead. fn split(now_utc: i32, epoch: i32) -> ListSplit { let t = now_utc - epoch; @@ -110,8 +175,12 @@ fn split(now_utc: i32, epoch: i32) -> ListSplit { ListSplit::Yday } else if t < 604_800 { ListSplit::Week - } else { + } else if t < 2_419_200 { ListSplit::Month + } else if t < 31_536_000 { + ListSplit::Year + } else { + ListSplit::Rest } } From 2e06205eda3a3dd23a3fb9bed80dfb4328484b8e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 20 Dec 2017 18:19:31 +0200 Subject: [PATCH 059/278] Define a new Diesel Model for PodcastCover querries. Define new Diesel Model and impl From trait, Change the signature of downloader::cache_image function, Change and merge hammond-gtk::utils::get_pixbuf_from_path functions. --- hammond-data/src/dbqueries.rs | 13 ++++++++++- hammond-data/src/lib.rs | 2 +- hammond-data/src/models/queryables.rs | 33 +++++++++++++++++++++++++++ hammond-downloader/src/downloader.rs | 6 ++--- hammond-gtk/src/utils.rs | 20 ++++------------ hammond-gtk/src/views/episodes.rs | 6 ++--- hammond-gtk/src/views/shows.rs | 2 +- hammond-gtk/src/widgets/show.rs | 4 ++-- 8 files changed, 59 insertions(+), 27 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index caaa76a..261bd8b 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -2,7 +2,7 @@ use diesel::prelude::*; use diesel; -use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, Source}; +use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; use chrono::prelude::*; use errors::*; @@ -114,6 +114,17 @@ pub fn get_podcast_from_id(pid: i32) -> Result { Ok(podcast.filter(id.eq(pid)).get_result::(&*con)?) } +pub fn get_podcast_cover_from_id(pid: i32) -> Result { + use schema::podcast::dsl::*; + + let db = connection(); + let con = db.get()?; + Ok(podcast + .select((id, title, image_uri)) + .filter(id.eq(pid)) + .get_result::(&*con)?) +} + pub fn get_pd_episodes(parent: &Podcast) -> Result> { use schema::episode::dsl::*; diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index 97aec76..21b70ac 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -61,7 +61,7 @@ pub(crate) mod models; mod parser; mod schema; -pub use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, Source}; +pub use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; /// [XDG Base Direcotory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) Paths. #[allow(missing_debug_implementations)] diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 4290979..bd15320 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -427,6 +427,39 @@ impl Podcast { } } +#[derive(Queryable, Debug, Clone)] +/// Diesel Model of the podcast cover query. +/// Used for fetching information about a Podcast's cover. +pub struct PodcastCoverQuery { + id: i32, + title: String, + image_uri: Option, +} + +impl From for PodcastCoverQuery { + fn from(p: Podcast) -> PodcastCoverQuery { + PodcastCoverQuery { + id: *p.id(), + title: p.title, + image_uri: p.image_uri, + } + } +} + +impl PodcastCoverQuery { + /// Get the Feed `title`. + pub fn title(&self) -> &str { + &self.title + } + + /// Get the `image_uri`. + /// + /// Represents the uri(url usually) that the Feed cover image is located at. + pub fn image_uri(&self) -> Option<&str> { + self.image_uri.as_ref().map(|s| s.as_str()) + } +} + #[derive(Queryable, Identifiable, AsChangeset, PartialEq)] #[table_name = "source"] #[changeset_options(treat_none_as_null = "true")] diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index e3a4a0c..eb0fd2f 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -8,7 +8,7 @@ use std::io::{BufWriter, Read, Write}; use std::path::Path; use errors::*; -use hammond_data::{EpisodeWidgetQuery, Podcast}; +use hammond_data::{EpisodeWidgetQuery, PodcastCoverQuery}; use hammond_data::xdg_dirs::{DL_DIR, HAMMOND_CACHE}; // TODO: Replace path that are of type &str with std::path. @@ -131,7 +131,7 @@ pub fn get_episode(ep: &mut EpisodeWidgetQuery, download_folder: &str) -> Result } } -pub fn cache_image(pd: &Podcast) -> Option { +pub fn cache_image(pd: &PodcastCoverQuery) -> Option { let url = pd.image_uri()?.to_owned(); if url == "" { return None; @@ -207,7 +207,7 @@ mod tests { index(vec![feed]); // Get the Podcast - let pd = dbqueries::get_podcast_from_source_id(sid).unwrap(); + let pd = dbqueries::get_podcast_from_source_id(sid).unwrap().into(); let img_path = cache_image(&pd); let foo_ = format!( diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 3e22f8e..9c5eca9 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -2,7 +2,7 @@ use glib; use gdk_pixbuf::Pixbuf; use hammond_data::feed; -use hammond_data::{Podcast, Source}; +use hammond_data::{PodcastCoverQuery, Source}; use hammond_downloader::downloader; use std::thread; @@ -60,21 +60,9 @@ fn refresh_podcasts_view() -> glib::Continue { } // FIXME: use something that would just scale? -// TODO: make a diesel model with only title, local_uri - -pub fn get_pixbuf_from_path(pd: &Podcast) -> Option { +pub fn get_pixbuf_from_path(pd: &PodcastCoverQuery, size: u32) -> Option { let img_path = downloader::cache_image(pd)?; - Pixbuf::new_from_file_at_scale(&img_path, 256, 256, true).ok() -} - -pub fn get_pixbuf_from_path_128(pd: &Podcast) -> Option { - let img_path = downloader::cache_image(pd)?; - Pixbuf::new_from_file_at_scale(&img_path, 128, 128, true).ok() -} - -pub fn get_pixbuf_from_path_64(pd: &Podcast) -> Option { - let img_path = downloader::cache_image(pd)?; - Pixbuf::new_from_file_at_scale(&img_path, 64, 64, true).ok() + Pixbuf::new_from_file_at_scale(&img_path, size as i32, size as i32, true).ok() } #[cfg(test)] @@ -100,7 +88,7 @@ mod tests { // Get the Podcast let pd = dbqueries::get_podcast_from_source_id(sid).unwrap(); - let pxbuf = get_pixbuf_from_path(&pd); + let pxbuf = get_pixbuf_from_path(&pd.into(), 256); assert!(pxbuf.is_some()); } } diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 57191f1..51ce199 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -6,7 +6,7 @@ use hammond_data::dbqueries; use hammond_data::EpisodeWidgetQuery; use widgets::episode::EpisodeWidget; -use utils::get_pixbuf_from_path_64; +use utils::get_pixbuf_from_path; use std::rc::Rc; @@ -216,8 +216,8 @@ impl EpisodesViewWidget { let image: gtk::Image = builder.get_object("cover").unwrap(); // FIXME: - if let Ok(pd) = dbqueries::get_podcast_from_id(episode.podcast_id()) { - let img = get_pixbuf_from_path_64(&pd); + if let Ok(pd) = dbqueries::get_podcast_cover_from_id(episode.podcast_id()) { + let img = get_pixbuf_from_path(&pd, 64); if let Some(i) = img { image.set_from_pixbuf(&i); } diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index d12dc58..acd1022 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -111,7 +111,7 @@ impl ShowsChild { fn init(&self, pd: &Podcast) { self.container.set_tooltip_text(pd.title()); - let cover = get_pixbuf_from_path(pd); + let cover = get_pixbuf_from_path(&pd.clone().into(), 256); if let Some(img) = cover { self.cover.set_from_pixbuf(&img); }; diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 7a30a63..54b9840 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -10,7 +10,7 @@ use hammond_data::utils::replace_extra_spaces; use hammond_downloader::downloader; use widgets::episode::episodes_listbox; -use utils::get_pixbuf_from_path_128; +use utils::get_pixbuf_from_path; use content::ShowStack; use headerbar::Header; @@ -77,7 +77,7 @@ impl ShowWidget { let desc = dissolve::strip_html_tags(pd.description()).join(" "); self.description.set_text(&replace_extra_spaces(&desc)); - let img = get_pixbuf_from_path_128(pd); + let img = get_pixbuf_from_path(&pd.clone().into(), 128); if let Some(i) = img { self.cover.set_from_pixbuf(&i); } From 3c24b9f9d9ceca665d503bb75c06bce90d26c746 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 20 Dec 2017 19:00:14 +0200 Subject: [PATCH 060/278] hammond-data::utils: Added new Diesel model for the download checker. --- hammond-data/src/dbqueries.rs | 8 +++-- hammond-data/src/models/queryables.rs | 52 +++++++++++++++++++++++++++ hammond-data/src/utils.rs | 16 ++++++--- 3 files changed, 68 insertions(+), 8 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 261bd8b..2ce9061 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -2,7 +2,8 @@ use diesel::prelude::*; use diesel; -use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; +use models::queryables::{Episode, EpisodeDownloadCleanerQuery, EpisodeWidgetQuery, Podcast, + PodcastCoverQuery, Source}; use chrono::prelude::*; use errors::*; @@ -32,14 +33,15 @@ pub fn get_episodes() -> Result> { Ok(episode.order(epoch.desc()).load::(&*con)?) } -pub fn get_downloaded_episodes() -> Result> { +pub(crate) fn get_downloaded_episodes() -> Result> { use schema::episode::dsl::*; let db = connection(); let con = db.get()?; Ok(episode + .select((rowid, local_uri)) .filter(local_uri.is_not_null()) - .load::(&*con)?) + .load::(&*con)?) } pub fn get_played_episodes() -> Result> { diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index bd15320..cf6dded 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -320,6 +320,58 @@ impl EpisodeWidgetQuery { } } +#[derive(Queryable, AsChangeset, PartialEq)] +#[table_name = "episode"] +#[changeset_options(treat_none_as_null = "true")] +#[primary_key(title, podcast_id)] +#[derive(Debug, Clone)] +/// Diesel Model to be used for constructing `EpisodeWidgets`. +pub(crate) struct EpisodeDownloadCleanerQuery { + rowid: i32, + local_uri: Option, +} + +impl From for EpisodeDownloadCleanerQuery { + fn from(e: Episode) -> EpisodeDownloadCleanerQuery { + EpisodeDownloadCleanerQuery { + rowid: e.rowid(), + local_uri: e.local_uri, + } + } +} + +impl EpisodeDownloadCleanerQuery { + /// Get the value of the sqlite's `ROW_ID` + pub(crate) fn rowid(&self) -> i32 { + self.rowid + } + + /// Get the value of the `local_uri`. + /// + /// Represents the local uri,usually filesystem path, + /// that the media file will be located at. + pub(crate) fn local_uri(&self) -> Option<&str> { + self.local_uri.as_ref().map(|s| s.as_str()) + } + + /// Set the `local_uri`. + pub(crate) fn set_local_uri(&mut self, value: Option<&str>) { + self.local_uri = value.map(|x| x.to_string()); + } + + /// Helper method to easily save/"sync" current state of self to the Database. + pub(crate) fn save(&self) -> Result { + use schema::episode::dsl::*; + + let db = connection(); + let tempdb = db.get()?; + + Ok(diesel::update(episode.filter(rowid.eq(self.rowid()))) + .set(self) + .execute(&*tempdb)?) + } +} + #[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] #[belongs_to(Source, foreign_key = "source_id")] #[changeset_options(treat_none_as_null = "true")] diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index f15c757..39ea52b 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -8,7 +8,7 @@ use itertools::Itertools; use errors::*; use dbqueries; -use models::queryables::Episode; +use models::queryables::{Episode, EpisodeDownloadCleanerQuery}; use std::path::Path; use std::fs; @@ -25,7 +25,7 @@ fn download_checker() -> Result<()> { Ok(()) } -fn checker_helper(ep: &mut Episode) { +fn checker_helper(ep: &mut EpisodeDownloadCleanerQuery) { if !Path::new(ep.local_uri().unwrap()).exists() { ep.set_local_uri(None); let res = ep.save(); @@ -180,12 +180,16 @@ mod tests { #[test] fn test_download_checker() { - let _tmp_dir = helper_db(); + let tmp_dir = helper_db(); download_checker().unwrap(); let episodes = dbqueries::get_downloaded_episodes().unwrap(); + let valid_path = tmp_dir.path().join("virtual_dl.mp3"); assert_eq!(episodes.len(), 1); - assert_eq!("foo_bar", episodes.first().unwrap().title()); + assert_eq!( + Some(valid_path.to_str().unwrap()), + episodes.first().unwrap().local_uri() + ); } #[test] @@ -194,7 +198,9 @@ mod tests { let mut episode = { let db = connection(); let con = db.get().unwrap(); - dbqueries::get_episode_from_pk(&con, "bar_baz", 1).unwrap() + dbqueries::get_episode_from_pk(&con, "bar_baz", 1) + .unwrap() + .into() }; checker_helper(&mut episode); From db59bed69d7e1f1d21842d155ded25399881b7ce Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 20 Dec 2017 19:18:20 +0200 Subject: [PATCH 061/278] hammond-data::utils: Modified EpisodeCleaner Diesel model to also be used with played_cleaner. --- hammond-data/src/dbqueries.rs | 19 +++++++++++---- hammond-data/src/models/queryables.rs | 34 +++++++++++++++++++-------- hammond-data/src/utils.rs | 22 ++++++++--------- hammond-gtk/src/widgets/episode.rs | 4 +++- 4 files changed, 52 insertions(+), 27 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 2ce9061..4f0c5d2 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -2,7 +2,7 @@ use diesel::prelude::*; use diesel; -use models::queryables::{Episode, EpisodeDownloadCleanerQuery, EpisodeWidgetQuery, Podcast, +use models::queryables::{Episode, EpisodeCleanerQuery, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; use chrono::prelude::*; use errors::*; @@ -33,15 +33,15 @@ pub fn get_episodes() -> Result> { Ok(episode.order(epoch.desc()).load::(&*con)?) } -pub(crate) fn get_downloaded_episodes() -> Result> { +pub(crate) fn get_downloaded_episodes() -> Result> { use schema::episode::dsl::*; let db = connection(); let con = db.get()?; Ok(episode - .select((rowid, local_uri)) + .select((rowid, local_uri, played)) .filter(local_uri.is_not_null()) - .load::(&*con)?) + .load::(&*con)?) } pub fn get_played_episodes() -> Result> { @@ -52,6 +52,17 @@ pub fn get_played_episodes() -> Result> { Ok(episode.filter(played.is_not_null()).load::(&*con)?) } +pub fn get_played_cleaner_episodes() -> Result> { + use schema::episode::dsl::*; + + let db = connection(); + let con = db.get()?; + Ok(episode + .select((rowid, local_uri, played)) + .filter(played.is_not_null()) + .load::(&*con)?) +} + pub fn get_episode_from_rowid(ep_id: i32) -> Result { use schema::episode::dsl::*; diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index cf6dded..9ba23bb 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -325,24 +325,26 @@ impl EpisodeWidgetQuery { #[changeset_options(treat_none_as_null = "true")] #[primary_key(title, podcast_id)] #[derive(Debug, Clone)] -/// Diesel Model to be used for constructing `EpisodeWidgets`. -pub(crate) struct EpisodeDownloadCleanerQuery { +/// Diesel Model to be used internal with the `utils::checkup` function. +pub struct EpisodeCleanerQuery { rowid: i32, local_uri: Option, + played: Option, } -impl From for EpisodeDownloadCleanerQuery { - fn from(e: Episode) -> EpisodeDownloadCleanerQuery { - EpisodeDownloadCleanerQuery { +impl From for EpisodeCleanerQuery { + fn from(e: Episode) -> EpisodeCleanerQuery { + EpisodeCleanerQuery { rowid: e.rowid(), local_uri: e.local_uri, + played: e.played, } } } -impl EpisodeDownloadCleanerQuery { +impl EpisodeCleanerQuery { /// Get the value of the sqlite's `ROW_ID` - pub(crate) fn rowid(&self) -> i32 { + pub fn rowid(&self) -> i32 { self.rowid } @@ -350,17 +352,29 @@ impl EpisodeDownloadCleanerQuery { /// /// Represents the local uri,usually filesystem path, /// that the media file will be located at. - pub(crate) fn local_uri(&self) -> Option<&str> { + pub fn local_uri(&self) -> Option<&str> { self.local_uri.as_ref().map(|s| s.as_str()) } /// Set the `local_uri`. - pub(crate) fn set_local_uri(&mut self, value: Option<&str>) { + pub fn set_local_uri(&mut self, value: Option<&str>) { self.local_uri = value.map(|x| x.to_string()); } + /// Epoch representation of the last time the episode was played. + /// + /// None/Null for unplayed. + pub fn played(&self) -> Option { + self.played + } + + /// Set the `played` value. + pub fn set_played(&mut self, value: Option) { + self.played = value; + } + /// Helper method to easily save/"sync" current state of self to the Database. - pub(crate) fn save(&self) -> Result { + pub fn save(&self) -> Result { use schema::episode::dsl::*; let db = connection(); diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index 39ea52b..07dc34d 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -8,14 +8,12 @@ use itertools::Itertools; use errors::*; use dbqueries; -use models::queryables::{Episode, EpisodeDownloadCleanerQuery}; +use models::queryables::EpisodeCleanerQuery; use std::path::Path; use std::fs; fn download_checker() -> Result<()> { - // TODO: give it it's own diesel model, - // so it does not pull useless and expensive stuff like description. let episodes = dbqueries::get_downloaded_episodes()?; episodes @@ -25,7 +23,7 @@ fn download_checker() -> Result<()> { Ok(()) } -fn checker_helper(ep: &mut EpisodeDownloadCleanerQuery) { +fn checker_helper(ep: &mut EpisodeCleanerQuery) { if !Path::new(ep.local_uri().unwrap()).exists() { ep.set_local_uri(None); let res = ep.save(); @@ -37,9 +35,7 @@ fn checker_helper(ep: &mut EpisodeDownloadCleanerQuery) { } fn played_cleaner() -> Result<()> { - // TODO: give it it's own diesel model, - // so it does not pull useless and expensive stuff like description. - let episodes = dbqueries::get_played_episodes()?; + let episodes = dbqueries::get_played_cleaner_episodes()?; let now_utc = Utc::now().timestamp() as i32; episodes.into_par_iter().for_each(|mut ep| { @@ -54,7 +50,7 @@ fn played_cleaner() -> Result<()> { error!("Error while trying to delete file: {:?}", ep.local_uri()); error!("Error: {}", err); } else { - info!("Episode {:?} was deleted succesfully.", ep.title()); + info!("Episode {:?} was deleted succesfully.", ep.local_uri()); }; } } @@ -63,7 +59,7 @@ fn played_cleaner() -> Result<()> { } /// Check `ep.local_uri` field and delete the file it points to. -pub fn delete_local_content(ep: &mut Episode) -> Result<()> { +pub fn delete_local_content(ep: &mut EpisodeCleanerQuery) -> Result<()> { if ep.local_uri().is_some() { let uri = ep.local_uri().unwrap().to_owned(); if Path::new(&uri).exists() { @@ -110,7 +106,7 @@ pub fn url_cleaner(s: &str) -> String { } } -/// Helper functions that strips extra spaces and newlines and all the tabs. +/// Helper functions that strips extra spaces and newlines and ignores the tabs. #[allow(match_same_arms)] pub fn replace_extra_spaces(s: &str) -> String { s.trim() @@ -210,10 +206,12 @@ mod tests { #[test] fn test_download_cleaner() { let _tmp_dir = helper_db(); - let mut episode = { + let mut episode: EpisodeCleanerQuery = { let db = connection(); let con = db.get().unwrap(); - dbqueries::get_episode_from_pk(&con, "foo_bar", 0).unwrap() + dbqueries::get_episode_from_pk(&con, "foo_bar", 0) + .unwrap() + .into() }; let valid_path = episode.local_uri().unwrap().to_owned(); diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 7bd11e3..93ce6dd 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -232,7 +232,9 @@ fn on_play_bttn_clicked(episode_id: i32) { } fn on_delete_bttn_clicked(episode_id: i32) { - let mut ep = dbqueries::get_episode_from_rowid(episode_id).unwrap(); + let mut ep = dbqueries::get_episode_from_rowid(episode_id) + .unwrap() + .into(); let e = delete_local_content(&mut ep); if let Err(err) = e { From 336846f6dd6c04422579a6f67b4a2978b6964501 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 20 Dec 2017 21:25:00 +0200 Subject: [PATCH 062/278] EpisodesStack: Implemnt the transition between empty and populated. --- hammond-gtk/src/content.rs | 10 ++++++---- hammond-gtk/src/views/episodes.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index c869741..49ed951 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -173,15 +173,17 @@ impl EpisodeStack { } fn update(&self) { - // FIXME: figure out if it should switch to empty view - let vis = self.stack.get_visible_child_name().unwrap(); let old = self.stack.get_child_by_name("episodes").unwrap(); - let eps = EpisodesView::new(); self.stack.remove(&old); self.stack.add_named(&eps.container, "episodes"); - self.stack.set_visible_child_name(&vis); + + if eps.is_empty() { + self.stack.set_visible_child_name("empty"); + } else { + self.stack.set_visible_child_name("episodes"); + } old.destroy(); } diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 51ce199..bb7a44d 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -163,6 +163,34 @@ impl EpisodesView { view.container.show_all(); Rc::new(view) } + + pub fn is_empty(&self) -> bool { + if !self.today_list.get_children().is_empty() { + return false; + } + + if !self.yday_list.get_children().is_empty() { + return false; + } + + if !self.week_list.get_children().is_empty() { + return false; + } + + if !self.month_list.get_children().is_empty() { + return false; + } + + if !self.year_list.get_children().is_empty() { + return false; + } + + if !self.rest_list.get_children().is_empty() { + return false; + } + + true + } } // TODO: Avoid epoch calculations, use chrono instead. From 994ea5af2247f695301541d9ee6aed2982124231 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 20 Dec 2017 22:08:07 +0200 Subject: [PATCH 063/278] EpisodesView: Remove unused label. --- hammond-gtk/resources/gtk/episodes_view.ui | 12 ++++++------ hammond-gtk/src/views/episodes.rs | 18 ------------------ 2 files changed, 6 insertions(+), 24 deletions(-) diff --git a/hammond-gtk/resources/gtk/episodes_view.ui b/hammond-gtk/resources/gtk/episodes_view.ui index b3a4456..b633909 100644 --- a/hammond-gtk/resources/gtk/episodes_view.ui +++ b/hammond-gtk/resources/gtk/episodes_view.ui @@ -50,7 +50,7 @@ True vertical - + True False start @@ -102,7 +102,7 @@ True vertical - + True False start @@ -154,7 +154,7 @@ True vertical - + True False start @@ -206,7 +206,7 @@ True vertical - + True False start @@ -258,7 +258,7 @@ True vertical - + True False start @@ -310,7 +310,7 @@ True vertical - + True False start diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index bb7a44d..e34a7bc 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -36,12 +36,6 @@ pub struct EpisodesView { month_list: gtk::ListBox, year_list: gtk::ListBox, rest_list: gtk::ListBox, - today_label: gtk::Label, - yday_label: gtk::Label, - week_label: gtk::Label, - month_label: gtk::Label, - year_label: gtk::Label, - rest_label: gtk::Label, } impl Default for EpisodesView { @@ -61,12 +55,6 @@ impl Default for EpisodesView { let month_list: gtk::ListBox = builder.get_object("month_list").unwrap(); let year_list: gtk::ListBox = builder.get_object("year_list").unwrap(); let rest_list: gtk::ListBox = builder.get_object("rest_list").unwrap(); - let today_label: gtk::Label = builder.get_object("today_label").unwrap(); - let yday_label: gtk::Label = builder.get_object("yday_label").unwrap(); - let week_label: gtk::Label = builder.get_object("week_label").unwrap(); - let month_label: gtk::Label = builder.get_object("month_label").unwrap(); - let year_label: gtk::Label = builder.get_object("year_label").unwrap(); - let rest_label: gtk::Label = builder.get_object("rest_label").unwrap(); EpisodesView { container, @@ -83,12 +71,6 @@ impl Default for EpisodesView { month_list, year_list, rest_list, - today_label, - yday_label, - week_label, - month_label, - year_label, - rest_label, } } } From 74a6e5814abeb082314e73fcbed09171e7012bfd Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 21 Dec 2017 15:14:29 +0200 Subject: [PATCH 064/278] ShowWidget: Update EpisodesView when unsub button is activated. --- hammond-gtk/src/content.rs | 20 ++++++++++++-------- hammond-gtk/src/widgets/show.rs | 32 +++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 49ed951..5181a91 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -23,8 +23,8 @@ pub struct Content { impl Content { pub fn new(header: Rc
) -> Rc { let stack = gtk::Stack::new(); - let shows = ShowStack::new(header); let episodes = EpisodeStack::new(); + let shows = ShowStack::new(header, episodes.clone()); stack.add_titled(&episodes.stack, "episodes", "Episodes"); stack.add_titled(&shows.stack, "shows", "Shows"); @@ -50,15 +50,17 @@ impl Content { pub struct ShowStack { pub stack: gtk::Stack, header: Rc
, + epstack: Rc, } impl ShowStack { - fn new(header: Rc
) -> Rc { + fn new(header: Rc
, epstack: Rc) -> Rc { let stack = gtk::Stack::new(); let show = Rc::new(ShowStack { stack, header: header.clone(), + epstack, }); let pop = ShowsPopulated::new(show.clone(), header); @@ -110,7 +112,12 @@ impl ShowStack { pub fn replace_widget(&self, pd: &Podcast) { let old = self.stack.get_child_by_name("widget").unwrap(); - let new = ShowWidget::new(Rc::new(self.clone()), self.header.clone(), pd); + let new = ShowWidget::new( + Rc::new(self.clone()), + self.epstack.clone(), + self.header.clone(), + pd, + ); self.stack.remove(&old); self.stack.add_named(&new.container, "widget"); @@ -145,10 +152,7 @@ impl ShowStack { } #[derive(Debug, Clone)] -struct RecentEpisodes; - -#[derive(Debug, Clone)] -struct EpisodeStack { +pub struct EpisodeStack { // populated: RecentEpisodes, // empty: EmptyView, stack: gtk::Stack, @@ -172,7 +176,7 @@ impl EpisodeStack { }) } - fn update(&self) { + pub fn update(&self) { let old = self.stack.get_child_by_name("episodes").unwrap(); let eps = EpisodesView::new(); diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 54b9840..66da950 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -11,7 +11,7 @@ use hammond_downloader::downloader; use widgets::episode::episodes_listbox; use utils::get_pixbuf_from_path; -use content::ShowStack; +use content::{EpisodeStack, ShowStack}; use headerbar::Header; use std::rc::Rc; @@ -53,18 +53,30 @@ impl Default for ShowWidget { } impl ShowWidget { - pub fn new(shows: Rc, header: Rc
, pd: &Podcast) -> ShowWidget { + pub fn new( + shows: Rc, + epstack: Rc, + header: Rc
, + pd: &Podcast, + ) -> ShowWidget { let pdw = ShowWidget::default(); - pdw.init(shows, header, pd); + pdw.init(shows, epstack, header, pd); pdw } - pub fn init(&self, shows: Rc, header: Rc
, pd: &Podcast) { + pub fn init( + &self, + shows: Rc, + epstack: Rc, + header: Rc
, + pd: &Podcast, + ) { WidgetExt::set_name(&self.container, &pd.id().to_string()); // TODO: should spawn a thread to avoid locking the UI probably. - self.unsub.connect_clicked(clone!(shows, pd => move |bttn| { - on_unsub_button_clicked(shows.clone(), &pd, bttn); + self.unsub + .connect_clicked(clone!(shows, epstack, pd => move |bttn| { + on_unsub_button_clicked(shows.clone(), epstack.clone(), &pd, bttn); header.switch_to_normal(); })); @@ -94,7 +106,12 @@ impl ShowWidget { } } -fn on_unsub_button_clicked(shows: Rc, pd: &Podcast, unsub_button: >k::Button) { +fn on_unsub_button_clicked( + shows: Rc, + epstack: Rc, + pd: &Podcast, + unsub_button: >k::Button, +) { let res = dbqueries::remove_feed(pd); if res.is_ok() { info!("{} was removed succesfully.", pd.title()); @@ -112,6 +129,7 @@ fn on_unsub_button_clicked(shows: Rc, pd: &Podcast, unsub_button: > } shows.switch_podcasts_animated(); shows.update_podcasts(); + epstack.update(); } #[allow(dead_code)] From e416bca963872bc6581755484273ee429290ee0c Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 21 Dec 2017 17:36:07 +0200 Subject: [PATCH 065/278] Implemented a pixbuf cache mechanism. Since gdk_pixbuf::Pixbuf is refference counted and every episode, use the cover of the Podcast Feed/Show, We can only create a Pixbuf cover per show and pass around the Rc pointer. 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. --- Cargo.lock | 8 ++++++++ hammond-data/src/models/queryables.rs | 5 +++++ hammond-gtk/Cargo.toml | 2 ++ hammond-gtk/src/main.rs | 3 +++ hammond-gtk/src/utils.rs | 25 ++++++++++++++++++++++++- 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 500afb9..6fb2a52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,11 +611,13 @@ dependencies = [ "gtk 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hammond-data 0.1.0", "hammond-downloader 0.1.0", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "loggerv 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1280,6 +1282,11 @@ dependencies = [ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "send-cell" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "serde" version = "1.0.24" @@ -1746,6 +1753,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" +"checksum send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c620dd7e056b468b9d374a9f51cfa6bb4bf17a8ca4ee62e5efa0d99aaff2c41" "checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1" "checksum serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf5b0b5b4bd22eeecb7e01ac2e1225c7ef5e4272b79ee28a8392a8c8489c839" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 9ba23bb..aff1c4b 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -513,6 +513,11 @@ impl From for PodcastCoverQuery { } impl PodcastCoverQuery { + /// Get the Feed `id`. + pub fn id(&self) -> i32 { + self.id + } + /// Get the Feed `title`. pub fn title(&self) -> &str { &self.title diff --git a/hammond-gtk/Cargo.toml b/hammond-gtk/Cargo.toml index b1cf01e..5f250f3 100644 --- a/hammond-gtk/Cargo.toml +++ b/hammond-gtk/Cargo.toml @@ -12,11 +12,13 @@ gdk = "0.7.0" gdk-pixbuf = "0.3.0" gio = "0.3.0" glib = "0.4.0" +lazy_static = "1.0.0" log = "0.3.8" loggerv = "0.6.0" open = "1.2.1" rayon = "0.9.0" regex = "0.2.3" +send-cell = "0.1.2" [dependencies.diesel] features = ["sqlite"] diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index d565154..dd3b96a 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -12,10 +12,13 @@ extern crate dissolve; extern crate hammond_data; extern crate hammond_downloader; #[macro_use] +extern crate lazy_static; +#[macro_use] extern crate log; extern crate loggerv; extern crate open; extern crate regex; +extern crate send_cell; // extern crate rayon; // use rayon::prelude::*; diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 9c5eca9..1f73b1b 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -1,3 +1,4 @@ +use send_cell::SendCell; use glib; use gdk_pixbuf::Pixbuf; @@ -8,7 +9,9 @@ use hammond_downloader::downloader; use std::thread; use std::cell::RefCell; use std::sync::mpsc::{channel, Receiver}; +use std::sync::Mutex; use std::rc::Rc; +use std::collections::HashMap; use content::Content; @@ -59,10 +62,30 @@ fn refresh_podcasts_view() -> glib::Continue { glib::Continue(false) } +lazy_static! { + static ref CACHED_PIXBUFS: Mutex>>> = { + Mutex::new(HashMap::new()) + }; +} + // FIXME: use something that would just scale? pub fn get_pixbuf_from_path(pd: &PodcastCoverQuery, size: u32) -> Option { + let mut hashmap = CACHED_PIXBUFS.lock().unwrap(); + { + let res = hashmap.get(&(pd.id(), size)); + if let Some(px) = res { + let m = px.lock().unwrap(); + return Some(m.clone().into_inner()); + } + } + let img_path = downloader::cache_image(pd)?; - 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).ok(); + if let Some(px) = px { + hashmap.insert((pd.id(), size), Mutex::new(SendCell::new(px.clone()))); + return Some(px); + } + None } #[cfg(test)] From 13b2043b76d965ecb230c3ab913c6717b9dccb3e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 21 Dec 2017 19:10:37 +0200 Subject: [PATCH 066/278] EpisodesStack: Fix view selection upon creation. --- hammond-gtk/src/content.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 5181a91..7722ae0 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -166,8 +166,12 @@ impl EpisodeStack { stack.add_named(&episodes.container, "episodes"); stack.add_named(&empty.container, "empty"); - // FIXME: - stack.set_visible_child_name("episodes"); + + if episodes.is_empty() { + stack.set_visible_child_name("empty"); + } else { + stack.set_visible_child_name("episodes"); + } Rc::new(EpisodeStack { // empty, From c8310b1eb93fb2563430cfe0d9b70a9b4d408b4d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 21 Dec 2017 20:01:24 +0200 Subject: [PATCH 067/278] EpisodesView: Bump the labels size a bit. --- hammond-gtk/resources/gtk/episodes_view.ui | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hammond-gtk/resources/gtk/episodes_view.ui b/hammond-gtk/resources/gtk/episodes_view.ui index b633909..28c480a 100644 --- a/hammond-gtk/resources/gtk/episodes_view.ui +++ b/hammond-gtk/resources/gtk/episodes_view.ui @@ -57,6 +57,7 @@ Today +
@@ -109,6 +110,7 @@ Yesterday +
@@ -161,6 +163,7 @@ This Week +
@@ -213,6 +216,7 @@ This Month +
@@ -265,6 +269,7 @@ This Year +
@@ -317,6 +322,7 @@ Older than a Year +
From 378b8609aa25196fccaef52302fe4af547c96aea Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 21 Dec 2017 21:31:25 +0200 Subject: [PATCH 068/278] EpisodeWidget: Change the byte unit based on the size. Closes #18. --- Cargo.lock | 7 +++++++ hammond-gtk/Cargo.toml | 1 + hammond-gtk/resources/gtk/episode_widget.ui | 1 + hammond-gtk/src/main.rs | 1 + hammond-gtk/src/widgets/episode.rs | 10 ++++++++-- 5 files changed, 18 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6fb2a52..cdba1e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -611,6 +611,7 @@ dependencies = [ "gtk 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hammond-data 0.1.0", "hammond-downloader 0.1.0", + "humansize 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "loggerv 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -637,6 +638,11 @@ name = "httparse" version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "humansize" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "hyper" version = "0.11.9" @@ -1680,6 +1686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum gtk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "905fcfbaaad1b44ec0b4bba9e4d527d728284c62bc2ba41fccedace2b096766f" "checksum html5ever 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba3a1fd1857a714d410c191364c5d7bf8a6487c0ab5575146d37dd7eb17ef523" "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" +"checksum humansize 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d99804bdb0790b0c312a5a1115f83804b821f1a96d80759fbb57ce796d1f3778" "checksum hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e0594792d2109069d0caffd176f674d770a84adf024c5bb48e686b1ee5ac7659" "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" diff --git a/hammond-gtk/Cargo.toml b/hammond-gtk/Cargo.toml index 5f250f3..ceb387d 100644 --- a/hammond-gtk/Cargo.toml +++ b/hammond-gtk/Cargo.toml @@ -12,6 +12,7 @@ gdk = "0.7.0" gdk-pixbuf = "0.3.0" gio = "0.3.0" glib = "0.4.0" +humansize = "1.0.2" lazy_static = "1.0.0" log = "0.3.8" loggerv = "0.6.0" diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index e0aa126..b0332fc 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -122,6 +122,7 @@ True False + True 42 MB True False diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index dd3b96a..08bfeee 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -11,6 +11,7 @@ extern crate diesel; extern crate dissolve; extern crate hammond_data; extern crate hammond_downloader; +extern crate humansize; #[macro_use] extern crate lazy_static; #[macro_use] diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 93ce6dd..ddc0e3c 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -5,6 +5,7 @@ use gtk::prelude::*; use chrono::prelude::*; use open; +use humansize::{file_size_opts as size_opts, FileSize}; use hammond_data::dbqueries; use hammond_data::{EpisodeWidgetQuery, Podcast}; @@ -101,9 +102,14 @@ impl EpisodeWidget { .map(|c| c.add_class("dim-label")); } + // TODO: configure it so it will not show decimal places. if let Some(size) = episode.length() { - let megabytes = size / 1024 / 1024; // episode.length represents bytes - self.size.set_text(&format!("{} MB", megabytes)) + let s = size.file_size(size_opts::CONVENTIONAL); + if let Ok(s) = s { + self.size.set_text(&s); + } else { + self.size.hide(); + } }; let date = Utc.timestamp(i64::from(episode.epoch()), 0) From 4a033e6d89a9115e4292da0d3698409095668e99 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 21 Dec 2017 21:37:51 +0200 Subject: [PATCH 069/278] EpisodeWidget: Remove the decimal places in the size label. --- hammond-gtk/src/widgets/episode.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index ddc0e3c..00e0f8e 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -102,9 +102,21 @@ impl EpisodeWidget { .map(|c| c.add_class("dim-label")); } - // TODO: configure it so it will not show decimal places. + // Declare a custom humansize option struct + // See: https://docs.rs/humansize/1.0.2/humansize/file_size_opts/struct.FileSizeOpts.html + let custom_options = size_opts::FileSizeOpts { + divider: size_opts::Kilo::Binary, + units: size_opts::Kilo::Decimal, + decimal_places: 0, + decimal_zeroes: 0, + fixed_at: size_opts::FixedAt::No, + long_units: false, + space: true, + suffix: "", + }; + if let Some(size) = episode.length() { - let s = size.file_size(size_opts::CONVENTIONAL); + let s = size.file_size(custom_options); if let Ok(s) = s { self.size.set_text(&s); } else { From b7e160f735be468bf1023c4816af705a61297dbb Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 21 Dec 2017 21:50:50 +0200 Subject: [PATCH 070/278] EpisodeWidget: Change date representation based on it's year. Closes #19. --- hammond-gtk/src/widgets/episode.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 00e0f8e..da74711 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -124,10 +124,13 @@ impl EpisodeWidget { } }; - let date = Utc.timestamp(i64::from(episode.epoch()), 0) - .format("%b %e") - .to_string(); - self.date.set_text(&date); + let now = Utc::now(); + let date = Utc.timestamp(i64::from(episode.epoch()), 0); + if now.year() == date.year() { + self.date.set_text(&date.format("%e %b").to_string()); + } else { + self.date.set_text(&date.format("%e %b %Y").to_string()); + }; // Show or hide the play/delete/download buttons upon widget initialization. let local_uri = episode.local_uri(); From 2ad0539a82c34793d3acac603ec5f23699f0ddc6 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 21 Dec 2017 22:15:17 +0200 Subject: [PATCH 071/278] Downloader: Overwrite episode.lenght column upon download finish with the actual file size. Closes #22. --- hammond-downloader/src/downloader.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index eb0fd2f..d0505fd 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -6,6 +6,7 @@ use mime_guess; use std::fs::{rename, DirBuilder, File}; use std::io::{BufWriter, Read, Write}; use std::path::Path; +use std::fs; use errors::*; use hammond_data::{EpisodeWidgetQuery, PodcastCoverQuery}; @@ -123,6 +124,11 @@ pub fn get_episode(ep: &mut EpisodeWidgetQuery, download_folder: &str) -> Result if let Ok(path) = res { // If download succedes set episode local_uri to dlpath. ep.set_local_uri(Some(&path)); + + let size = fs::metadata(path); + if let Ok(s) = size { + ep.set_length(Some(s.len() as i32)) + }; ep.save()?; Ok(()) } else { From 8513ba3644be77dc03bd823884fc91c6b3e46b1e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 22 Dec 2017 14:29:41 +0200 Subject: [PATCH 072/278] EpisodesView: Use chrono to categorize widgets intead of epoch calculations. --- hammond-gtk/resources/gtk/episodes_view.ui | 2 +- hammond-gtk/src/views/episodes.rs | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/hammond-gtk/resources/gtk/episodes_view.ui b/hammond-gtk/resources/gtk/episodes_view.ui index 28c480a..9df8483 100644 --- a/hammond-gtk/resources/gtk/episodes_view.ui +++ b/hammond-gtk/resources/gtk/episodes_view.ui @@ -42,7 +42,7 @@ False center vertical - 7 + 25 True diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index e34a7bc..f1930c5 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -79,7 +79,7 @@ impl EpisodesView { pub fn new() -> Rc { let view = EpisodesView::default(); let episodes = dbqueries::get_episodes_widgets_with_limit(100).unwrap(); - let now_utc = Utc::now().timestamp() as i32; + let now_utc = Utc::now(); episodes.into_iter().for_each(|mut ep| { let viewep = EpisodesViewWidget::new(&mut ep); @@ -87,7 +87,7 @@ impl EpisodesView { sep.set_sensitive(false); sep.set_can_focus(false); - let t = split(now_utc, ep.epoch()); + let t = split(&now_utc, i64::from(ep.epoch())); match t { ListSplit::Today => { view.today_list.add(&viewep.container); @@ -175,19 +175,18 @@ impl EpisodesView { } } -// TODO: Avoid epoch calculations, use chrono instead. -fn split(now_utc: i32, epoch: i32) -> ListSplit { - let t = now_utc - epoch; +fn split(now: &DateTime, epoch: i64) -> ListSplit { + let ep = Utc.timestamp(epoch, 0); - if t < 86_400 { + if now.ordinal() == ep.ordinal() && now.year() == ep.year() { ListSplit::Today - } else if t < 172_800 { + } else if now.ordinal() == ep.ordinal() + 1 && now.year() == ep.year() { ListSplit::Yday - } else if t < 604_800 { + } else if now.iso_week().week() == ep.iso_week().week() && now.year() == ep.year() { ListSplit::Week - } else if t < 2_419_200 { + } else if now.month() == ep.month() && now.year() == ep.year() { ListSplit::Month - } else if t < 31_536_000 { + } else if now.year() == ep.year() { ListSplit::Year } else { ListSplit::Rest From b820ee4db70b8b8002c9781b9f622fd378dc4fd4 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 22 Dec 2017 14:51:57 +0200 Subject: [PATCH 073/278] hammond-data::parser : Do not clean image urls cause feeds put redirects for uri for some reason. --- hammond-data/src/models/insertables.rs | 4 ---- hammond-data/src/parser.rs | 8 ++------ 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index c847a2e..983e11b 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -112,10 +112,6 @@ impl NewPodcast { let con = db.get()?; match pd { Ok(foo) => { - if foo.source_id() != self.source_id { - error!("NSPD sid: {}, SPD sid: {}", self.source_id, foo.source_id()); - }; - if (foo.link() != self.link) || (foo.title() != self.title) || (foo.image_uri() != self.image_uri.as_ref().map(|x| x.as_str())) { diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 566b06f..b6b244d 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -17,9 +17,9 @@ pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast { let link = url_cleaner(chan.link()); let x = chan.itunes_ext().map(|s| s.image()); let image_uri = if let Some(img) = x { - img.map(|s| url_cleaner(s)) + img.map(|s| s.to_owned()) } else { - chan.image().map(|foo| url_cleaner(foo.url())) + chan.image().map(|foo| foo.url().to_owned()) }; NewPodcastBuilder::default() @@ -43,10 +43,6 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { .map(|s| replace_extra_spaces(&ammonia::clean(s))); let guid = item.guid().map(|s| s.value().trim().to_owned()); - // Its kinda weird this being an Option type. - // Rss 2.0 specified that it's optional. - // Though the db scema has a requirment of episode uri being Unique && Not Null. - // TODO: Restructure let x = item.enclosure().map(|s| url_cleaner(s.url())); // FIXME: refactor let uri = if x.is_some() { From 5541b18a6aee372bedc4ce2e08ff70a6680c9be4 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 22 Dec 2017 16:55:45 +0200 Subject: [PATCH 074/278] hammond-data::parser: Add itunesext_duration parser. --- hammond-data/src/parser.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index b6b244d..ea7f7db 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -64,6 +64,7 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { let epoch = date.map(|x| x.timestamp() as i32).unwrap_or(0); let length = item.enclosure().map(|x| x.length().parse().unwrap_or(0)); + let _duration = parse_itunes_duration(item); Ok(NewEpisodeBuilder::default() .title(title) @@ -78,6 +79,25 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { .unwrap()) } +/// Parses an Item Itunes extension and returns it's duration value in seconds. +// FIXME: Rafactor +fn parse_itunes_duration(item: &Item) -> Option { + let duration = item.itunes_ext().map(|s| s.duration())??; + + let mut seconds = 0; + let fk_apple = duration.split(':').collect::>(); + if fk_apple.len() == 3 { + seconds += fk_apple[0].parse::().unwrap_or(0) * 3600; + seconds += fk_apple[1].parse::().unwrap_or(0) * 60; + seconds += fk_apple[2].parse::().unwrap_or(0); + } else if fk_apple.len() == 2 { + seconds += fk_apple[0].parse::().unwrap_or(0) * 60; + seconds += fk_apple[1].parse::().unwrap_or(0); + } + + Some(seconds) +} + #[cfg(test)] mod tests { use std::fs::File; From 4512790f2d42e6ead1b3172a23529f4122346908 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 22 Dec 2017 17:30:07 +0200 Subject: [PATCH 075/278] hammond-data: Add duration column to the episode table. --- .../down.sql | 22 ++++++++++++++ .../up.sql | 23 ++++++++++++++ hammond-data/src/dbqueries.rs | 3 +- hammond-data/src/models/insertables.rs | 2 ++ hammond-data/src/models/queryables.rs | 30 +++++++++++++++++++ hammond-data/src/parser.rs | 3 +- hammond-data/src/schema.rs | 1 + 7 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 hammond-data/migrations/2017-12-22-145740_add_duration_column/down.sql create mode 100644 hammond-data/migrations/2017-12-22-145740_add_duration_column/up.sql diff --git a/hammond-data/migrations/2017-12-22-145740_add_duration_column/down.sql b/hammond-data/migrations/2017-12-22-145740_add_duration_column/down.sql new file mode 100644 index 0000000..7f1bbcb --- /dev/null +++ b/hammond-data/migrations/2017-12-22-145740_add_duration_column/down.sql @@ -0,0 +1,22 @@ +ALTER TABLE episode RENAME TO old_table; + +CREATE TABLE episode ( + title TEXT NOT NULL, + uri TEXT, + local_uri TEXT, + description TEXT, + published_date TEXT, + epoch INTEGER NOT NULL DEFAULT 0, + length INTEGER, + guid TEXT, + played INTEGER, + podcast_id INTEGER NOT NULL, + favorite INTEGER DEFAULT 0, + archive INTEGER DEFAULT 0, + PRIMARY KEY (title, podcast_id) +); + +INSERT INTO episode (title, uri, local_uri, description, published_date, epoch, length, guid, played, favorite, archive, podcast_id) +SELECT title, uri, local_uri, description, published_date, epoch, length, guid, played, favorite, archive, podcast_id +FROM old_table; +Drop table old_table; diff --git a/hammond-data/migrations/2017-12-22-145740_add_duration_column/up.sql b/hammond-data/migrations/2017-12-22-145740_add_duration_column/up.sql new file mode 100644 index 0000000..f2dcf10 --- /dev/null +++ b/hammond-data/migrations/2017-12-22-145740_add_duration_column/up.sql @@ -0,0 +1,23 @@ +ALTER TABLE episode RENAME TO old_table; + +CREATE TABLE episode ( + title TEXT NOT NULL, + uri TEXT, + local_uri TEXT, + description TEXT, + published_date TEXT, + epoch INTEGER NOT NULL DEFAULT 0, + length INTEGER, + duration INTEGER, + guid TEXT, + played INTEGER, + podcast_id INTEGER NOT NULL, + favorite INTEGER DEFAULT 0, + archive INTEGER DEFAULT 0, + PRIMARY KEY (title, podcast_id) +); + +INSERT INTO episode (title, uri, local_uri, description, published_date, epoch, length, guid, played, favorite, archive, podcast_id) +SELECT title, uri, local_uri, description, published_date, epoch, length, guid, played, favorite, archive, podcast_id +FROM old_table; +Drop table old_table; \ No newline at end of file diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 4f0c5d2..65236d6 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -111,6 +111,7 @@ pub fn get_episodes_widgets_with_limit(limit: u32) -> Result Result, published_date: Option, length: Option, + duration: Option, guid: Option, epoch: i32, podcast_id: i32, @@ -207,6 +208,7 @@ impl NewEpisode { if foo.title() != self.title.as_str() || foo.epoch() != self.epoch || foo.uri() != self.uri.as_ref().map(|s| s.as_str()) + || foo.duration() != self.duration { self.update(con, foo.rowid())?; } diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index aff1c4b..d4409cd 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -33,6 +33,7 @@ pub struct Episode { published_date: Option, epoch: i32, length: Option, + duration: Option, guid: Option, played: Option, favorite: bool, @@ -125,6 +126,8 @@ impl Episode { } /// Get the `length`. + /// + /// The number represents the size of the file in bytes. pub fn length(&self) -> Option { self.length } @@ -134,6 +137,18 @@ impl Episode { self.length = value; } + /// Get the `duration` value. + /// + /// The number represents the duration of the item/episode in seconds. + pub fn duration(&self) -> Option { + self.duration + } + + /// Set the `duration`. + pub fn set_duration(&mut self, value: Option) { + self.duration = value; + } + /// Epoch representation of the last time the episode was played. /// /// None/Null for unplayed. @@ -204,6 +219,7 @@ pub struct EpisodeWidgetQuery { local_uri: Option, epoch: i32, length: Option, + duration: Option, played: Option, // favorite: bool, // archive: bool, @@ -250,6 +266,8 @@ impl EpisodeWidgetQuery { } /// Get the `length`. + /// + /// The number represents the size of the file in bytes. pub fn length(&self) -> Option { self.length } @@ -259,6 +277,18 @@ impl EpisodeWidgetQuery { self.length = value; } + /// Get the `duration` value. + /// + /// The number represents the duration of the item/episode in seconds. + pub fn duration(&self) -> Option { + self.duration + } + + /// Set the `duration`. + pub fn set_duration(&mut self, value: Option) { + self.duration = value; + } + /// Epoch representation of the last time the episode was played. /// /// None/Null for unplayed. diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index ea7f7db..a08e025 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -64,13 +64,14 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { let epoch = date.map(|x| x.timestamp() as i32).unwrap_or(0); let length = item.enclosure().map(|x| x.length().parse().unwrap_or(0)); - let _duration = parse_itunes_duration(item); + let duration = parse_itunes_duration(item); Ok(NewEpisodeBuilder::default() .title(title) .uri(uri) .description(description) .length(length) + .duration(duration) .published_date(pub_date) .epoch(epoch) .guid(guid) diff --git a/hammond-data/src/schema.rs b/hammond-data/src/schema.rs index 7b43171..6389143 100644 --- a/hammond-data/src/schema.rs +++ b/hammond-data/src/schema.rs @@ -8,6 +8,7 @@ table! { published_date -> Nullable, epoch -> Integer, length -> Nullable, + duration -> Nullable, guid -> Nullable, played -> Nullable, favorite -> Bool, From 0129efb02ef1e8ea06f56617d1ed0478d3e031e9 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 22 Dec 2017 17:49:15 +0200 Subject: [PATCH 076/278] EpisodeWidget: Display episode's duration. Closes #21. --- hammond-gtk/src/widgets/episode.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index da74711..efaf745 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -46,6 +46,7 @@ pub struct EpisodeWidget { size: gtk::Label, progress: gtk::ProgressBar, progress_label: gtk::Label, + separator1: gtk::Label, } impl Default for EpisodeWidget { @@ -66,6 +67,8 @@ impl Default for EpisodeWidget { let size: gtk::Label = builder.get_object("size_label").unwrap(); let progress_label: gtk::Label = builder.get_object("progress_label").unwrap(); + let separator1: gtk::Label = builder.get_object("separator1").unwrap(); + EpisodeWidget { container, progress, @@ -78,6 +81,7 @@ impl Default for EpisodeWidget { size, date, progress_label, + separator1, } } } @@ -124,6 +128,12 @@ impl EpisodeWidget { } }; + if let Some(secs) = episode.duration() { + self.duration.set_text(&format!("{} min", secs / 60)); + self.duration.show(); + self.separator1.show(); + }; + let now = Utc::now(); let date = Utc.timestamp(i64::from(episode.epoch()), 0); if now.year() == date.year() { From 31b19dd88ec2834bbdd5b8e9c26f47da64531d57 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 22 Dec 2017 18:28:18 +0200 Subject: [PATCH 077/278] Just things apple force you to do. --- hammond-data/src/parser.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index a08e025..5ef3d21 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -82,9 +82,20 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { /// Parses an Item Itunes extension and returns it's duration value in seconds. // FIXME: Rafactor +// TODO: Write tests +#[allow(non_snake_case)] fn parse_itunes_duration(item: &Item) -> Option { let duration = item.itunes_ext().map(|s| s.duration())??; + // FOR SOME FUCKING REASON, IN THE APPLE EXTENSION SPEC + // THE DURATION CAN BE EITHER AN INT OF SECONDS OR + // A STRING OF THE FOLLOWING FORMATS: + // HH:MM:SS, H:MM:SS, MM:SS, M:SS + // LIKE WHO THE FUCK THOUGH THAT WOULD BE A GOOD IDEA. + if let Ok(NO_FUCKING_LOGIC) = duration.parse::() { + return Some(NO_FUCKING_LOGIC); + }; + let mut seconds = 0; let fk_apple = duration.split(':').collect::>(); if fk_apple.len() == 3 { From 7aebb4d50d334cc3c01bd05d2b59852f56ad7f98 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 22 Dec 2017 18:49:24 +0200 Subject: [PATCH 078/278] gitlab-ci: Add caching to the ci config. --- .gitlab-ci.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e64a2ba..1ae8422 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,6 +20,10 @@ before_script: - rustc --version && cargo --version - cargo build - cargo test --verbose -- --test-threads=1 + cache: + paths: + - target/ + - cargo/ variables: # RUSTFLAGS: "-C link-dead-code" @@ -46,6 +50,10 @@ rustfmt: - rustc --version && cargo --version - cargo install rustfmt-nightly --force - cargo fmt --all -- --write-mode=diff + cache: + paths: + - target/ + - cargo/ # Configure and run clippy on nightly # Only fails on errors atm. @@ -56,3 +64,7 @@ clippy: - rustc --version && cargo --version - cargo install clippy --force - cargo clippy --all + cache: + paths: + - target/ + - cargo/ From fac048a24d56b471352c6ff185c3d9fe813deb80 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 22 Dec 2017 20:47:37 +0200 Subject: [PATCH 079/278] Small Visual tweaks all over the client. --- .gitlab-ci.yml | 1 + hammond-gtk/resources/gtk/episode_widget.ui | 16 ++++++++-------- hammond-gtk/resources/gtk/episodes_view.ui | 9 ++++++++- hammond-gtk/resources/gtk/show_widget.ui | 6 +++--- hammond-gtk/resources/gtk/shows_view.ui | 6 ++++-- 5 files changed, 24 insertions(+), 14 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1ae8422..63dd6f7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -28,6 +28,7 @@ before_script: variables: # RUSTFLAGS: "-C link-dead-code" RUST_BACKTRACE: "FULL" + CARGO_HOME: $CI_PROJECT_DIR/cargo stable:test: # https://hub.docker.com/_/rust/ diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index b0332fc..f6dd911 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -10,14 +10,14 @@ True False - 5 + 6 True False center vertical - 5 + 6 True @@ -51,7 +51,7 @@ True False - 5 + 6 True @@ -164,7 +164,7 @@ False True - 5 + 6 0 @@ -172,7 +172,7 @@ True False - 5 + 6 Cancel @@ -260,7 +260,7 @@ False True - 5 + 6 end 1 @@ -269,7 +269,7 @@ True False - 5 + 6 0 @@ -281,7 +281,7 @@ False True - 5 + 6 end 1 diff --git a/hammond-gtk/resources/gtk/episodes_view.ui b/hammond-gtk/resources/gtk/episodes_view.ui index 9df8483..1d5333f 100644 --- a/hammond-gtk/resources/gtk/episodes_view.ui +++ b/hammond-gtk/resources/gtk/episodes_view.ui @@ -41,14 +41,16 @@ True False center + 24 vertical - 25 + 24 True False True vertical + 6 True @@ -102,6 +104,7 @@ False True vertical + 6 True @@ -155,6 +158,7 @@ False True vertical + 6 True @@ -208,6 +212,7 @@ False True vertical + 6 True @@ -261,6 +266,7 @@ False True vertical + 6 True @@ -314,6 +320,7 @@ False True vertical + 6 True diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index ead850a..0f83b05 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -58,7 +58,7 @@ True False center - 10 + 12 True @@ -77,7 +77,7 @@ True False vertical - 10 + 12 True @@ -191,7 +191,7 @@ False True - 25 + 24 0 diff --git a/hammond-gtk/resources/gtk/shows_view.ui b/hammond-gtk/resources/gtk/shows_view.ui index 7981cb9..5050ca0 100644 --- a/hammond-gtk/resources/gtk/shows_view.ui +++ b/hammond-gtk/resources/gtk/shows_view.ui @@ -21,9 +21,11 @@ False center start + 24 + 24 True - 5 - 5 + 12 + 12 20 none From ae6a97d7256d3f9d45ff8b55cdfcdbf94384bf17 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 22 Dec 2017 21:21:39 +0200 Subject: [PATCH 080/278] EpisodesViewWidget: Add margins from the cover. --- hammond-gtk/resources/gtk/episodes_view_widget.ui | 4 ++++ hammond-gtk/src/views/episodes.rs | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hammond-gtk/resources/gtk/episodes_view_widget.ui b/hammond-gtk/resources/gtk/episodes_view_widget.ui index 3aa6d88..bbe09b7 100644 --- a/hammond-gtk/resources/gtk/episodes_view_widget.ui +++ b/hammond-gtk/resources/gtk/episodes_view_widget.ui @@ -5,10 +5,14 @@ True False + 6 True False + 6 + 6 + 6 64 image-x-generic-symbolic diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index f1930c5..a388b3a 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -207,7 +207,7 @@ impl Default for EpisodesViewWidget { let container: gtk::Box = builder.get_object("container").unwrap(); let image: gtk::Image = builder.get_object("cover").unwrap(); let ep = EpisodeWidget::default(); - container.pack_start(&ep.container, true, true, 5); + container.pack_start(&ep.container, true, true, 6); EpisodesViewWidget { container, @@ -233,7 +233,7 @@ impl EpisodesViewWidget { } let ep = EpisodeWidget::new(episode); - container.pack_start(&ep.container, true, true, 5); + container.pack_start(&ep.container, true, true, 6); EpisodesViewWidget { container, From 832495beceb67972e3f7fa4e9db61ff06db3c00e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 22 Dec 2017 22:14:08 +0200 Subject: [PATCH 081/278] EpisodesView: Remove Year category. --- hammond-gtk/resources/gtk/episodes_view.ui | 56 +--------------------- hammond-gtk/src/main.rs | 2 +- hammond-gtk/src/views/episodes.rs | 21 -------- 3 files changed, 2 insertions(+), 77 deletions(-) diff --git a/hammond-gtk/resources/gtk/episodes_view.ui b/hammond-gtk/resources/gtk/episodes_view.ui index 1d5333f..8a493c0 100644 --- a/hammond-gtk/resources/gtk/episodes_view.ui +++ b/hammond-gtk/resources/gtk/episodes_view.ui @@ -260,60 +260,6 @@ 3 - - - True - False - True - vertical - 6 - - - True - False - start - This Year - - - - - - - False - True - 0 - - - - - True - False - 0 - in - - - True - False - none - - - - - - - - False - True - 1 - - - - - False - True - 4 - - True @@ -326,7 +272,7 @@ True False start - Older than a Year + Older diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 08bfeee..70f65f4 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -66,7 +66,7 @@ fn build_ui(app: >k::Application) { // Get the main window let window = gtk::ApplicationWindow::new(app); - window.set_default_size(1150, 650); + window.set_default_size(1024, 576); // Get the headerbar let header = Rc::new(headerbar::Header::default()); diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index a388b3a..915cac2 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -16,7 +16,6 @@ enum ListSplit { Yday, Week, Month, - Year, Rest, } @@ -28,13 +27,11 @@ pub struct EpisodesView { yday_box: gtk::Box, week_box: gtk::Box, month_box: gtk::Box, - year_box: gtk::Box, rest_box: gtk::Box, today_list: gtk::ListBox, yday_list: gtk::ListBox, week_list: gtk::ListBox, month_list: gtk::ListBox, - year_list: gtk::ListBox, rest_list: gtk::ListBox, } @@ -47,13 +44,11 @@ impl Default for EpisodesView { let yday_box: gtk::Box = builder.get_object("yday_box").unwrap(); let week_box: gtk::Box = builder.get_object("week_box").unwrap(); let month_box: gtk::Box = builder.get_object("month_box").unwrap(); - let year_box: gtk::Box = builder.get_object("year_box").unwrap(); let rest_box: gtk::Box = builder.get_object("rest_box").unwrap(); let today_list: gtk::ListBox = builder.get_object("today_list").unwrap(); let yday_list: gtk::ListBox = builder.get_object("yday_list").unwrap(); let week_list: gtk::ListBox = builder.get_object("week_list").unwrap(); let month_list: gtk::ListBox = builder.get_object("month_list").unwrap(); - let year_list: gtk::ListBox = builder.get_object("year_list").unwrap(); let rest_list: gtk::ListBox = builder.get_object("rest_list").unwrap(); EpisodesView { @@ -63,13 +58,11 @@ impl Default for EpisodesView { yday_box, week_box, month_box, - year_box, rest_box, today_list, yday_list, week_list, month_list, - year_list, rest_list, } } @@ -105,10 +98,6 @@ impl EpisodesView { view.month_list.add(&viewep.container); view.month_list.add(&sep) } - ListSplit::Year => { - view.year_list.add(&viewep.container); - view.year_list.add(&sep) - } ListSplit::Rest => { view.rest_list.add(&viewep.container); view.rest_list.add(&sep) @@ -134,10 +123,6 @@ impl EpisodesView { view.month_box.hide(); } - if view.year_list.get_children().is_empty() { - view.year_box.hide(); - } - if view.rest_list.get_children().is_empty() { view.rest_box.hide(); } @@ -163,10 +148,6 @@ impl EpisodesView { return false; } - if !self.year_list.get_children().is_empty() { - return false; - } - if !self.rest_list.get_children().is_empty() { return false; } @@ -186,8 +167,6 @@ fn split(now: &DateTime, epoch: i64) -> ListSplit { ListSplit::Week } else if now.month() == ep.month() && now.year() == ep.year() { ListSplit::Month - } else if now.year() == ep.year() { - ListSplit::Year } else { ListSplit::Rest } From 95c290df5038adfe53e47be35037a5da0c7866ac Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Fri, 22 Dec 2017 21:54:28 +0100 Subject: [PATCH 082/278] [ui] add custom style and [fix] draw List separators with css --- hammond-gtk/resources/gtk/style.css | 7 +++++++ hammond-gtk/resources/resources.xml | 1 + hammond-gtk/src/main.rs | 4 ++++ hammond-gtk/src/views/episodes.rs | 11 ----------- hammond-gtk/src/widgets/episode.rs | 7 ------- 5 files changed, 12 insertions(+), 18 deletions(-) create mode 100644 hammond-gtk/resources/gtk/style.css diff --git a/hammond-gtk/resources/gtk/style.css b/hammond-gtk/resources/gtk/style.css new file mode 100644 index 0000000..39bb770 --- /dev/null +++ b/hammond-gtk/resources/gtk/style.css @@ -0,0 +1,7 @@ +row { + border-bottom: solid 1px rgba(0,0,0, 0.1); +} + +row:last-child { + border-bottom: none; +} diff --git a/hammond-gtk/resources/resources.xml b/hammond-gtk/resources/resources.xml index 0c91cd0..366f71c 100644 --- a/hammond-gtk/resources/resources.xml +++ b/hammond-gtk/resources/resources.xml @@ -9,5 +9,6 @@ gtk/shows_view.ui gtk/shows_child.ui gtk/headerbar.ui + gtk/style.css diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 08bfeee..c50f04a 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -64,6 +64,10 @@ fn build_ui(app: >k::Application) { menu.append("Update feeds", "app.update"); app.set_app_menu(&menu); + // Add custom style + let provider = gtk::CssProvider::new(); + gtk::CssProvider::load_from_resource(&provider, "/org/gnome/hammond/gtk/style.css"); + gtk::StyleContext::add_provider_for_screen(&gdk::Screen::get_default().unwrap(), &provider, 600); // Get the main window let window = gtk::ApplicationWindow::new(app); window.set_default_size(1150, 650); diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index f1930c5..756b4a6 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -83,39 +83,28 @@ impl EpisodesView { episodes.into_iter().for_each(|mut ep| { let viewep = EpisodesViewWidget::new(&mut ep); - let sep = gtk::Separator::new(gtk::Orientation::Vertical); - sep.set_sensitive(false); - sep.set_can_focus(false); let t = split(&now_utc, i64::from(ep.epoch())); match t { ListSplit::Today => { view.today_list.add(&viewep.container); - view.today_list.add(&sep) } ListSplit::Yday => { view.yday_list.add(&viewep.container); - view.yday_list.add(&sep) } ListSplit::Week => { view.week_list.add(&viewep.container); - view.week_list.add(&sep) } ListSplit::Month => { view.month_list.add(&viewep.container); - view.month_list.add(&sep) } ListSplit::Year => { view.year_list.add(&viewep.container); - view.year_list.add(&sep) } ListSplit::Rest => { view.rest_list.add(&viewep.container); - view.rest_list.add(&sep) } } - - sep.show() }); if view.today_list.get_children().is_empty() { diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index efaf745..fb9c4ef 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -305,13 +305,6 @@ pub fn episodes_listbox(pd: &Podcast) -> Result { episodes.into_iter().for_each(|mut ep| { let widget = EpisodeWidget::new(&mut ep); list.add(&widget.container); - - let sep = gtk::Separator::new(gtk::Orientation::Vertical); - sep.set_sensitive(false); - sep.set_can_focus(false); - - list.add(&sep); - sep.show() }); list.set_vexpand(false); From f9d17afad31f9007fbbd3a0114ce1b96db807efb Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 23 Dec 2017 10:39:20 +0200 Subject: [PATCH 083/278] hammond-gtk: Remove app menu. --- hammond-gtk/src/main.rs | 46 ++++++++++------------------------------- 1 file changed, 11 insertions(+), 35 deletions(-) diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index c9a409b..424b528 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -27,7 +27,7 @@ use log::LogLevel; use hammond_data::utils::checkup; use gtk::prelude::*; -use gio::{ActionMapExt, ApplicationExt, MenuExt, SimpleActionExt}; +use gio::ApplicationExt; use std::rc::Rc; // http://gtk-rs.org/tuto/closures @@ -58,19 +58,9 @@ mod utils; mod static_resource; fn build_ui(app: >k::Application) { - let menu = gio::Menu::new(); - menu.append("Quit", "app.quit"); - menu.append("Checkup", "app.check"); - menu.append("Update feeds", "app.update"); - app.set_app_menu(&menu); - - // Add custom style - let provider = gtk::CssProvider::new(); - gtk::CssProvider::load_from_resource(&provider, "/org/gnome/hammond/gtk/style.css"); - gtk::StyleContext::add_provider_for_screen(&gdk::Screen::get_default().unwrap(), &provider, 600); // Get the main window let window = gtk::ApplicationWindow::new(app); - window.set_default_size(1024, 576); + window.set_default_size(860, 640); // Get the headerbar let header = Rc::new(headerbar::Header::default()); @@ -84,28 +74,6 @@ fn build_ui(app: >k::Application) { Inhibit(false) }); - // Setup quit in the app menu since default is overwritten. - let quit = gio::SimpleAction::new("quit", None); - let window2 = window.clone(); - quit.connect_activate(move |_, _| { - window2.destroy(); - }); - app.add_action(&quit); - - // Setup the checkup in the app menu. - let check = gio::SimpleAction::new("check", None); - check.connect_activate(move |_, _| { - let _ = checkup(); - }); - app.add_action(&check); - - let update = gio::SimpleAction::new("update", None); - let ct_clone = ct.clone(); - update.connect_activate(move |_, _| { - utils::refresh_feed(ct_clone.clone(), None); - }); - app.add_action(&update); - // Update on startup gtk::timeout_add_seconds( 30, @@ -114,7 +82,6 @@ fn build_ui(app: >k::Application) { glib::Continue(false) }), ); - // Auto-updater, runs every hour. // TODO: expose the interval in which it run to a user setting. // TODO: show notifications. @@ -146,6 +113,15 @@ fn main() { let application = gtk::Application::new("org.gnome.Hammond", gio::ApplicationFlags::empty()) .expect("Initialization failed..."); + // Add custom style + let provider = gtk::CssProvider::new(); + gtk::CssProvider::load_from_resource(&provider, "/org/gnome/hammond/gtk/style.css"); + gtk::StyleContext::add_provider_for_screen( + &gdk::Screen::get_default().unwrap(), + &provider, + 600, + ); + application.connect_startup(move |app| { build_ui(app); }); From 37dbfff7667d3516b58726bfa87bfd381b4da820 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 23 Dec 2017 14:22:02 +0200 Subject: [PATCH 084/278] gitlab-ci: Do not cache rustfmt and clippy stuff. --- .gitlab-ci.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 63dd6f7..f929e62 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -51,10 +51,6 @@ rustfmt: - rustc --version && cargo --version - cargo install rustfmt-nightly --force - cargo fmt --all -- --write-mode=diff - cache: - paths: - - target/ - - cargo/ # Configure and run clippy on nightly # Only fails on errors atm. @@ -65,7 +61,3 @@ clippy: - rustc --version && cargo --version - cargo install clippy --force - cargo clippy --all - cache: - paths: - - target/ - - cargo/ From 2d6f02c4075cc6e09c6b7e479d25a3a25d4bd564 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 23 Dec 2017 15:44:28 +0200 Subject: [PATCH 085/278] EpisodeWidget: Do not display size if it's 0 bytes. --- hammond-data/src/parser.rs | 2 +- hammond-gtk/resources/gtk/episode_widget.ui | 3 +-- hammond-gtk/src/widgets/episode.rs | 15 ++++++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 5ef3d21..352d273 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -63,7 +63,7 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { let pub_date = date.map(|x| x.to_rfc2822()).ok(); let epoch = date.map(|x| x.timestamp() as i32).unwrap_or(0); - let length = item.enclosure().map(|x| x.length().parse().unwrap_or(0)); + let length = || -> Option { item.enclosure().map(|x| x.length().parse().ok())? }(); let duration = parse_itunes_duration(item); Ok(NewEpisodeBuilder::default() diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index f6dd911..ff4a249 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -104,8 +104,8 @@ - True False + True · False end - 2 + + + + + False + + + True + False + vertical + + + True + False + False + False + Preferences + + + False + True + 0 + + + + + True + True + True + Update Podcasts + + + False + True + 1 + + + + + True + False + + + False + True + 2 + + + + + True + False + False + False + Import Feeds + + + False + True + 3 + + + + + True + False + False + False + Export Feeds + + + False + True + 4 + + + + + True + False + + + False + True + 5 + + + + + True + False + False + False + About + + + False + True + 6 + + + + + True + False + False + False + Help + + + False + True + 7 + + + + + True + False + False + False + Keyboard Shortcuts + + + False + True + 8 + + + + + submenu0 + 1 diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 9d62773..fb2e087 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -13,6 +13,7 @@ use content::Content; pub struct Header { pub container: gtk::HeaderBar, add_toggle: gtk::MenuButton, + menu_toggle: gtk::MenuButton, switch: gtk::StackSwitcher, back_button: gtk::Button, show_title: gtk::Label, @@ -23,7 +24,8 @@ impl Default for Header { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let header: gtk::HeaderBar = builder.get_object("headerbar").unwrap(); - let add_toggle: gtk::MenuButton = builder.get_object("add_toggle_button").unwrap(); + let add_toggle: gtk::MenuButton = builder.get_object("add_toggle").unwrap(); + let menu_toggle: gtk::MenuButton = builder.get_object("menu_toggle").unwrap(); let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); let back_button: gtk::Button = builder.get_object("back_button").unwrap(); let show_title: gtk::Label = builder.get_object("show_title").unwrap(); @@ -34,6 +36,7 @@ impl Default for Header { Header { container: header, add_toggle, + menu_toggle, switch, back_button, show_title, @@ -52,7 +55,8 @@ impl Header { pub fn init(&self, content: Rc) { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); - let add_popover: gtk::Popover = builder.get_object("add-popover").unwrap(); + let add_popover: gtk::Popover = builder.get_object("add_popover").unwrap(); + let menu_popover: gtk::PopoverMenu = builder.get_object("menu_popover").unwrap(); let new_url: gtk::Entry = builder.get_object("new-url").unwrap(); let add_button: gtk::Button = builder.get_object("add-button").unwrap(); self.switch.set_stack(&content.stack); @@ -69,6 +73,7 @@ impl Header { add_popover.hide(); })); self.add_toggle.set_popover(&add_popover); + self.menu_toggle.set_popover(&menu_popover); let switch = &self.switch; let add_toggle = &self.add_toggle; From 0a47b91913e4dbef6144dd49b2c481a51e404457 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 25 Dec 2017 22:03:37 +0200 Subject: [PATCH 092/278] Headerbar: Wire menu refresh button. --- hammond-gtk/resources/gtk/headerbar.ui | 16 ++++++++-------- hammond-gtk/src/headerbar.rs | 10 ++++++++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index c71c916..de6028b 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -7,7 +7,7 @@ Add a new feed center - + True False center @@ -18,7 +18,7 @@ vertical 6 - + True False start @@ -35,12 +35,12 @@ - + True False 6 - + True True 30 @@ -53,12 +53,12 @@ - + True True True - + Add True True @@ -99,7 +99,7 @@ - + False start You are already subscribed to that feed! @@ -240,7 +240,7 @@ - + True True True diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index fb2e087..96a3ecc 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -57,8 +57,9 @@ impl Header { let add_popover: gtk::Popover = builder.get_object("add_popover").unwrap(); let menu_popover: gtk::PopoverMenu = builder.get_object("menu_popover").unwrap(); - let new_url: gtk::Entry = builder.get_object("new-url").unwrap(); - let add_button: gtk::Button = builder.get_object("add-button").unwrap(); + let new_url: gtk::Entry = builder.get_object("new_url").unwrap(); + let add_button: gtk::Button = builder.get_object("add_button").unwrap(); + let refresh_button: gtk::Button = builder.get_object("refresh_button").unwrap(); self.switch.set_stack(&content.stack); new_url.connect_changed(move |url| { @@ -72,6 +73,11 @@ impl Header { // TODO: map the spinner add_popover.hide(); })); + + refresh_button.connect_clicked(clone!(content => move |_| { + utils::refresh_feed(content.clone(), None); + })); + self.add_toggle.set_popover(&add_popover); self.menu_toggle.set_popover(&menu_popover); From d5b937973273ed006c5669e95bf1d8c006a3e27f Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 25 Dec 2017 22:26:38 +0200 Subject: [PATCH 093/278] Headerbar: Remove some option from the menu. --- hammond-gtk/resources/gtk/headerbar.ui | 39 -------------------------- 1 file changed, 39 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index de6028b..4e6ac08 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -263,45 +263,6 @@ 2 - - - True - False - False - False - Import Feeds - - - False - True - 3 - - - - - True - False - False - False - Export Feeds - - - False - True - 4 - - - - - True - False - - - False - True - 5 - - True From fde4bedce6a46b62509c61e76fe1c5caeb9b32b0 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 25 Dec 2017 23:29:42 +0200 Subject: [PATCH 094/278] hammond-data::parser: Refactor Podcast tests. --- hammond-data/src/models/insertables.rs | 6 +- hammond-data/src/parser.rs | 80 +++++++++++++++----------- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index c2d5fe5..368d92b 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -22,7 +22,7 @@ trait Update { #[derive(Insertable)] #[table_name = "source"] -#[derive(Debug, Clone, Default, Builder)] +#[derive(Debug, Clone, Default, Builder, PartialEq)] #[builder(default)] #[builder(derive(Debug))] #[builder(setter(into))] @@ -68,7 +68,7 @@ impl NewSource { #[derive(Insertable, AsChangeset)] #[table_name = "podcast"] -#[derive(Debug, Clone, Default, Builder)] +#[derive(Debug, Clone, Default, Builder, PartialEq)] #[builder(default)] #[builder(derive(Debug))] #[builder(setter(into))] @@ -152,7 +152,7 @@ impl NewPodcast { #[derive(Insertable, AsChangeset)] #[table_name = "episode"] -#[derive(Debug, Clone, Default, Builder)] +#[derive(Debug, Clone, Default, Builder, PartialEq)] #[builder(default)] #[builder(derive(Debug))] #[builder(setter(into))] diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 352d273..644c6f3 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -128,19 +128,21 @@ mod tests { the crucial issues of our time: national security, civil liberties, foreign \ policy, and criminal justice. Plus interviews with artists, thinkers, and \ newsmakers who challenge our preconceptions about the world we live in."; - let pd = new_podcast(&channel, 0); - assert_eq!(pd.title(), "Intercepted with Jeremy Scahill"); - assert_eq!(pd.link(), "https://theintercept.com/podcasts"); - assert_eq!(pd.description(), descr); - assert_eq!( - pd.image_uri(), - Some( + let pd = new_podcast(&channel, 0); + let expected = NewPodcastBuilder::default() + .title("Intercepted with Jeremy Scahill") + .link("https://theintercept.com/podcasts") + .description(descr) + .image_uri(Some(String::from( "http://static.megaphone.fm/podcasts/d5735a50-d904-11e6-8532-73c7de466ea6/image/\ uploads_2F1484252190700-qhn5krasklbce3dh-a797539282700ea0298a3a26f7e49b0b_\ - 2FIntercepted_COVER%2B_281_29.png" - ) - ); + 2FIntercepted_COVER%2B_281_29.png") + )) + .build() + .unwrap(); + + assert_eq!(pd, expected); } #[test] @@ -153,13 +155,17 @@ mod tests { interest."; let pd = new_podcast(&channel, 0); - assert_eq!(pd.title(), "The Breakthrough"); - assert_eq!(pd.link(), "http://www.propublica.org/podcast"); - assert_eq!(pd.description(), descr); - assert_eq!( - pd.image_uri(), - Some("http://www.propublica.org/images/podcast_logo_2.png") - ); + let expected = NewPodcastBuilder::default() + .title("The Breakthrough") + .link("http://www.propublica.org/podcast") + .description(descr) + .image_uri(Some(String::from( + "http://www.propublica.org/images/podcast_logo_2.png", + ))) + .build() + .unwrap(); + + assert_eq!(pd, expected); } #[test] @@ -172,13 +178,17 @@ mod tests { Linux."; let pd = new_podcast(&channel, 0); - assert_eq!(pd.title(), "LINUX Unplugged Podcast"); - assert_eq!(pd.link(), "http://www.jupiterbroadcasting.com/"); - assert_eq!(pd.description(), descr); - assert_eq!( - pd.image_uri(), - Some("http://www.jupiterbroadcasting.com/images/LASUN-Badge1400.jpg") - ); + let expected = NewPodcastBuilder::default() + .title("LINUX Unplugged Podcast") + .link("http://www.jupiterbroadcasting.com/") + .description(descr) + .image_uri(Some(String::from( + "http://www.jupiterbroadcasting.com/images/LASUN-Badge1400.jpg", + ))) + .build() + .unwrap(); + + assert_eq!(pd, expected); } #[test] @@ -187,18 +197,18 @@ mod tests { let channel = Channel::read_from(BufReader::new(file)).unwrap(); let pd = new_podcast(&channel, 0); - let descr = "A weekly discussion of Rust RFCs"; - assert_eq!(pd.title(), "Request For Explanation"); - assert_eq!( - pd.link(), - "https://request-for-explanation.github.io/podcast/" - ); - assert_eq!(pd.description(), descr); - assert_eq!( - pd.image_uri(), - Some("https://request-for-explanation.github.io/podcast/podcast.png") - ); + let expected = NewPodcastBuilder::default() + .title("Request For Explanation") + .link("https://request-for-explanation.github.io/podcast/") + .description("A weekly discussion of Rust RFCs") + .image_uri(Some(String::from( + "https://request-for-explanation.github.io/podcast/podcast.png", + ))) + .build() + .unwrap(); + + assert_eq!(pd, expected); } #[test] From 933fec55a5c345386e74b2fd6ffe8ef506630b87 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 26 Dec 2017 13:40:52 +0200 Subject: [PATCH 095/278] hammond-data::parser: Refactor Episode tests. --- hammond-data/src/parser.rs | 302 ++++++++++++++++++++----------------- 1 file changed, 162 insertions(+), 140 deletions(-) diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 644c6f3..fc47aa2 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -222,43 +222,51 @@ mod tests { Shaun King explains his call for a boycott of the NFL and talks about his \ campaign to bring violent neo-Nazis to justice. Rapper Open Mike Eagle \ performs."; - let i = new_episode(&firstitem, 0).unwrap(); - assert_eq!(i.title(), "The Super Bowl of Racism"); - assert_eq!( - i.uri(), - Some("http://traffic.megaphone.fm/PPY6458293736.mp3") - ); - assert_eq!(i.description(), Some(descr)); - assert_eq!(i.length(), Some(66738886)); - assert_eq!(i.guid(), Some("7df4070a-9832-11e7-adac-cb37b05d5e24")); - assert_eq!(i.published_date(), Some("Wed, 13 Sep 2017 10:00:00 +0000")); - assert_eq!(i.epoch(), 1505296800); + let ep = new_episode(&firstitem, 0).unwrap(); + let expected = NewEpisodeBuilder::default() + .title("The Super Bowl of Racism") + .uri(Some(String::from( + "http://traffic.megaphone.fm/PPY6458293736.mp3", + ))) + .description(Some(String::from(descr))) + .guid(Some(String::from("7df4070a-9832-11e7-adac-cb37b05d5e24"))) + .published_date(Some(String::from("Wed, 13 Sep 2017 10:00:00 +0000"))) + .length(Some(66738886)) + .epoch(1505296800) + .duration(Some(4171)) + .build() + .unwrap(); + + assert_eq!(ep, expected); let second = channel.items().iter().nth(1).unwrap(); - let i2 = new_episode(&second, 0).unwrap(); + let ep = new_episode(&second, 0).unwrap(); - let descr2 = "This week on Intercepted: Jeremy gives an update on the aftermath of \ - Blackwater’s 2007 massacre of Iraqi civilians. Intercept reporter Lee Fang \ - lays out how a network of libertarian think tanks called the Atlas Network \ - is insidiously shaping political infrastructure in Latin America. We speak \ - with attorney and former Hugo Chavez adviser Eva Golinger about the \ - Venezuela\'s political turmoil.And we hear Claudia Lizardo of the \ - Caracas-based band, La Pequeña Revancha, talk about her music and hopes for \ - Venezuela."; - assert_eq!( - i2.title(), - "Atlas Golfed — U.S.-Backed Think Tanks Target Latin America" - ); - assert_eq!( - i2.uri(), - Some("http://traffic.megaphone.fm/FL5331443769.mp3") - ); - assert_eq!(i2.description(), Some(descr2)); - assert_eq!(i2.length(), Some(67527575)); - assert_eq!(i2.guid(), Some("7c207a24-e33f-11e6-9438-eb45dcf36a1d")); - assert_eq!(i2.published_date(), Some("Wed, 9 Aug 2017 10:00:00 +0000")); - assert_eq!(i2.epoch(), 1502272800); + let descr = "This week on Intercepted: Jeremy gives an update on the aftermath of \ + Blackwater’s 2007 massacre of Iraqi civilians. Intercept reporter Lee Fang \ + lays out how a network of libertarian think tanks called the Atlas Network \ + is insidiously shaping political infrastructure in Latin America. We speak \ + with attorney and former Hugo Chavez adviser Eva Golinger about the \ + Venezuela\'s political turmoil.And we hear Claudia Lizardo of the \ + Caracas-based band, La Pequeña Revancha, talk about her music and hopes for \ + Venezuela."; + + let expected = NewEpisodeBuilder::default() + .title("Atlas Golfed — U.S.-Backed Think Tanks Target Latin America") + .uri(Some(String::from( + "http://traffic.megaphone.fm/FL5331443769.mp3", + ))) + .description(Some(String::from(descr))) + .guid(Some(String::from("7c207a24-e33f-11e6-9438-eb45dcf36a1d"))) + .published_date(Some(String::from("Wed, 9 Aug 2017 10:00:00 +0000"))) + .length(Some(67527575)) + .epoch(1502272800) + .duration(Some(4220)) + .build() + .unwrap(); + + assert_eq!(ep, expected); } #[test] @@ -269,53 +277,52 @@ mod tests { let firstitem = channel.items().first().unwrap(); let descr = "

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

"; - let i = new_episode(&firstitem, 0).unwrap(); + let ep = new_episode(&firstitem, 0).unwrap(); - assert_eq!( - i.title(), - "The Breakthrough: Hopelessness and Exploitation Inside Homes for Mentally Ill" - ); - assert_eq!( - i.uri(), - Some("http://tracking.feedpress.it/link/10581/6726758/20170908-cliff-levy.mp3") - ); - assert_eq!(i.description(), Some(descr)); - assert_eq!(i.length(), Some(33396551)); - assert_eq!( - i.guid(), - Some( - "https://www.propublica.org/podcast/\ - the-breakthrough-hopelessness-exploitation-homes-for-mentally-ill#134472" - ) - ); - assert_eq!(i.published_date(), Some("Fri, 8 Sep 2017 12:00:00 +0000")); - assert_eq!(i.epoch(), 1504872000); + let expected = NewEpisodeBuilder::default() + .title("The Breakthrough: Hopelessness and Exploitation Inside Homes for Mentally Ill") + .uri(Some(String::from("http://tracking.feedpress.it/link/10581/6726758/20170908-cliff-levy.mp3"))) + .description(Some(String::from(descr))) + .guid(Some(String::from("https://www.propublica.org/podcast/\ + the-breakthrough-hopelessness-exploitation-homes-for-mentally-ill#134472"))) + .published_date(Some(String::from("Fri, 8 Sep 2017 12:00:00 +0000"))) + .length(Some(33396551)) + .epoch(1504872000) + .duration(Some(1670)) + .build() + .unwrap(); + + assert_eq!(ep, expected); let second = channel.items().iter().nth(1).unwrap(); - let i2 = new_episode(&second, 0).unwrap(); - 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.

"; + let ep = new_episode(&second, 0).unwrap(); + let descr = + "

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.

"; - assert_eq!( - i2.title(), - "The Breakthrough: Behind the Scenes of Hillary Clinton’s Failed Bid for President" - ); - assert_eq!( - i2.uri(), - Some("http://tracking.feedpress.it/link/10581/6726759/16_JohnAllen-CRAFT.mp3") - ); - assert_eq!(i2.description(), Some(descr2)); - assert_eq!(i2.length(), Some(17964071)); - assert_eq!( - i2.guid(), - Some( - "https://www.propublica.\ - org/podcast/the-breakthrough-hillary-clinton-failed-presidential-bid#133721" - ) - ); - assert_eq!(i2.published_date(), Some("Fri, 25 Aug 2017 12:00:00 +0000")); - assert_eq!(i2.epoch(), 1503662400); + let expected = + NewEpisodeBuilder::default() + .title( + "The Breakthrough: Behind the Scenes of Hillary Clinton’s Failed Bid for \ + President", + ) + .uri(Some(String::from( + "http://tracking.feedpress.it/link/10581/6726759/16_JohnAllen-CRAFT.mp3", + ))) + .description(Some(String::from(descr))) + .guid(Some(String::from( + "https://www.propublica.\ + org/podcast/the-breakthrough-hillary-clinton-failed-presidential-bid#133721", + ))) + .published_date(Some(String::from("Fri, 25 Aug 2017 12:00:00 +0000"))) + .length(Some(17964071)) + .epoch(1503662400) + .duration(Some(1125)) + .build() + .unwrap(); + + assert_eq!(ep, expected); } #[test] @@ -328,38 +335,49 @@ mod tests { decides to blow off a little steam by attacking his IoT devices, Wes has the \ scope on Equifax blaming open source & the Beard just saved the show. \ It’s a really packed episode!"; - let i = new_episode(&firstitem, 0).unwrap(); + let ep = new_episode(&firstitem, 0).unwrap(); - assert_eq!(i.title(), "Hacking Devices with Kali Linux | LUP 214"); - assert_eq!( - i.uri(), - Some("http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0214.mp3") - ); - assert_eq!(i.description(), Some(descr)); - assert_eq!(i.length(), Some(46479789)); - assert_eq!(i.guid(), Some("78A682B4-73E8-47B8-88C0-1BE62DD4EF9D")); - assert_eq!(i.published_date(), Some("Tue, 12 Sep 2017 22:24:42 -0700")); - assert_eq!(i.epoch(), 1505280282); + let expected = NewEpisodeBuilder::default() + .title("Hacking Devices with Kali Linux | LUP 214") + .uri(Some(String::from( + "http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0214.mp3", + ))) + .description(Some(String::from(descr))) + .guid(Some(String::from("78A682B4-73E8-47B8-88C0-1BE62DD4EF9D"))) + .published_date(Some(String::from("Tue, 12 Sep 2017 22:24:42 -0700"))) + .length(Some(46479789)) + .epoch(1505280282) + .duration(Some(5733)) + .build() + .unwrap(); + + assert_eq!(ep, expected); let second = channel.items().iter().nth(1).unwrap(); - let i2 = new_episode(&second, 0).unwrap(); + let ep = new_episode(&second, 0).unwrap(); - let descr2 = "

The Gnome project is about to solve one of our audience's biggest \ - Wayland’s concerns. But as the project takes on a new level of relevance, \ - decisions for the next version of Gnome have us worried about the \ - future.

\n

Plus we chat with Wimpy about the Ubuntu Rally in NYC, \ - Microsoft’s sneaky move to turn Windows 10 into the “ULTIMATE LINUX \ - RUNTIME”, community news & more!

"; - assert_eq!(i2.title(), "Gnome Does it Again | LUP 213"); - assert_eq!( - i2.uri(), - Some("http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0213.mp3") - ); - assert_eq!(i2.description(), Some(descr2)); - assert_eq!(i2.length(), Some(36544272)); - assert_eq!(i2.guid(), Some("1CE57548-B36C-4F14-832A-5D5E0A24E35B")); - assert_eq!(i2.published_date(), Some("Tue, 5 Sep 2017 20:57:27 -0700")); - assert_eq!(i2.epoch(), 1504670247); + let descr = "

The Gnome project is about to solve one of our audience's biggest \ + Wayland’s concerns. But as the project takes on a new level of relevance, \ + decisions for the next version of Gnome have us worried about the \ + future.

\n

Plus we chat with Wimpy about the Ubuntu Rally in NYC, \ + Microsoft’s sneaky move to turn Windows 10 into the “ULTIMATE LINUX \ + RUNTIME”, community news & more!

"; + + let expected = NewEpisodeBuilder::default() + .title("Gnome Does it Again | LUP 213") + .uri(Some(String::from( + "http://www.podtrac.com/pts/redirect.mp3/traffic.libsyn.com/jnite/lup-0213.mp3", + ))) + .description(Some(String::from(descr))) + .guid(Some(String::from("1CE57548-B36C-4F14-832A-5D5E0A24E35B"))) + .published_date(Some(String::from("Tue, 5 Sep 2017 20:57:27 -0700"))) + .length(Some(36544272)) + .epoch(1504670247) + .duration(Some(4491)) + .build() + .unwrap(); + + assert_eq!(ep, expected); } #[test] @@ -370,47 +388,51 @@ mod tests { let firstitem = channel.items().iter().nth(9).unwrap(); let descr = "This week we look at RFC 2094 \"Non-lexical lifetimes\""; - let i = new_episode(&firstitem, 0).unwrap(); + let ep = new_episode(&firstitem, 0).unwrap(); - assert_eq!(i.title(), "Episode #9 - A Once in a Lifetime RFC"); - assert_eq!( - i.uri(), - Some( + let expected = NewEpisodeBuilder::default() + .title("Episode #9 - A Once in a Lifetime RFC") + .uri(Some(String::from( "http://request-for-explanation.github.\ - io/podcast/ep9-a-once-in-a-lifetime-rfc/episode.mp3" - ) - ); - assert_eq!(i.description(), Some(descr)); - assert_eq!(i.length(), Some(15077388)); - assert_eq!( - i.guid(), - Some("https://request-for-explanation.github.io/podcast/ep9-a-once-in-a-lifetime-rfc/") - ); - assert_eq!(i.published_date(), Some("Mon, 28 Aug 2017 15:00:00 -0700")); - assert_eq!(i.epoch(), 1503957600); + io/podcast/ep9-a-once-in-a-lifetime-rfc/episode.mp3", + ))) + .description(Some(String::from(descr))) + .guid(Some(String::from( + "https://request-for-explanation.github.io/podcast/ep9-a-once-in-a-lifetime-rfc/", + ))) + .published_date(Some(String::from("Mon, 28 Aug 2017 15:00:00 -0700"))) + .length(Some(15077388)) + .epoch(1503957600) + .duration(Some(2533)) + .build() + .unwrap(); + + assert_eq!(ep, expected); let second = channel.items().iter().nth(8).unwrap(); - let i2 = new_episode(&second, 0).unwrap(); + let ep = new_episode(&second, 0).unwrap(); - let descr2 = "This week we look at RFC 2071 \"Add impl Trait type alias and variable \ - declarations\""; - assert_eq!(i2.title(), "Episode #8 - An Existential Crisis"); - assert_eq!( - i2.uri(), - Some( + let descr = "This week we look at RFC 2071 \"Add impl Trait type alias and \ + variable declarations\""; + + let expected = NewEpisodeBuilder::default() + .title("Episode #8 - An Existential Crisis") + .uri(Some(String::from( "http://request-for-explanation.github.\ - io/podcast/ep8-an-existential-crisis/episode.mp3" - ) - ); - assert_eq!(i2.description(), Some(descr2)); - assert_eq!(i2.length(), Some(13713219)); - assert_eq!( - i2.guid(), - Some("https://request-for-explanation.github.io/podcast/ep8-an-existential-crisis/") - ); - assert_eq!(i2.published_date(), Some("Tue, 15 Aug 2017 17:00:00 -0700")); - assert_eq!(i2.epoch(), 1502841600); + io/podcast/ep8-an-existential-crisis/episode.mp3", + ))) + .description(Some(String::from(descr))) + .guid(Some(String::from( + "https://request-for-explanation.github.io/podcast/ep8-an-existential-crisis/", + ))) + .published_date(Some(String::from("Tue, 15 Aug 2017 17:00:00 -0700"))) + .length(Some(13713219)) + .epoch(1502841600) + .duration(Some(2313)) + .build() + .unwrap(); + + assert_eq!(ep, expected); } } From e99ab58b830f9015236b44ef04ff280397ffad41 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 26 Dec 2017 15:46:25 +0200 Subject: [PATCH 096/278] Headerbar: Add margins to the hamburger menu. --- hammond-gtk/resources/gtk/headerbar.ui | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index 4e6ac08..0801116 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -215,6 +215,7 @@
end + 2
@@ -224,6 +225,10 @@ True False + 10 + 10 + 10 + 10 vertical @@ -244,7 +249,7 @@ True True True - Update Podcasts + Check for new episodes False From bfb74c4dba9cc36b35ccc8d4a48d4b93fd728ea8 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 26 Dec 2017 18:18:48 +0200 Subject: [PATCH 097/278] hammond-data: Index_loop does not wait for GET request to finish now. --- hammond-data/benches/bench.rs | 4 +- hammond-data/src/feed.rs | 93 +++++++++------------------- hammond-downloader/src/downloader.rs | 2 +- hammond-gtk/src/utils.rs | 24 ++++--- 4 files changed, 43 insertions(+), 80 deletions(-) diff --git a/hammond-data/benches/bench.rs b/hammond-data/benches/bench.rs index 4a71a8e..d721878 100644 --- a/hammond-data/benches/bench.rs +++ b/hammond-data/benches/bench.rs @@ -13,7 +13,7 @@ use rayon::prelude::*; use test::Bencher; use hammond_data::Source; -use hammond_data::feed::{index, Feed}; +use hammond_data::feed::*; use std::io::BufReader; @@ -43,7 +43,7 @@ fn index_urls() { }) .collect(); - index(feeds); + feeds.par_iter().for_each(|x| index(x)); } #[bench] diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index af38f1a..f613f16 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -99,58 +99,42 @@ impl Feed { .collect(); Ok(episodes) - - // This would return every episode of the feed from the db. - // self.index_channel_items(&pd)?; - // Ok(dbqueries::get_pd_episodes(&pd)?) } } -/// Use's `fetch_all` to retrieve a list of `Feed`s and use index them using `feed::index`. -pub fn index_all() -> Result<()> { - let feeds = fetch_all()?; - - index(feeds); - Ok(()) +/// Handle the indexing of a `Feed` into the Database. +pub fn index(feed: &Feed) { + if let Err(err) = feed.index() { + error!("Error While trying to update the database."); + error!("Error msg: {}", err); + }; } -/// Handle the indexing of a feed `F` into the Database. -/// -/// Consume a `ParallelIterator` and index it. -pub fn index>(feeds: F) { - feeds.into_par_iter().for_each(|f| { - let e = f.index(); - if e.is_err() { - error!("Error While trying to update the database."); - error!("Error msg: {}", e.unwrap_err()); - }; - }); +/// Consume a `Source` and return a `Feed`. +fn fetch(source: Source) -> Result { + let uri = source.uri().to_owned(); + let feed = Feed::from_source(source); + if feed.is_err() { + error!("Error While trying to fetch from source url: {}.", uri); + } + feed +} + +/// Index a "list" of `Source`s. +pub fn index_loop>(sources: S) { + sources + .into_par_iter() + .filter_map(|x| fetch(x).ok()) + .for_each(|x| index(&x)); + info!("Indexing done."); } -/// Retrieve a list of all the `Source` in the database, -/// then use `feed::fetch` to convert them into `Feed`s -/// and return them. -pub fn fetch_all() -> Result> { - let feeds = dbqueries::get_sources()?; - Ok(fetch(feeds)) -} - -/// Consume a `ParallelIterator` and return a list of `Feed`s. -pub fn fetch>(feeds: F) -> Vec { - let results: Vec<_> = feeds - .into_par_iter() - .filter_map(|x| { - let uri = x.uri().to_owned(); - let feed = Feed::from_source(x).ok(); - if feed.is_none() { - error!("Error While trying to fetch from source url: {}.", uri); - } - feed - }) - .collect(); - - results +/// Retrieves all `Sources` from the database and updates/indexes them. +pub fn index_all() -> Result<()> { + let sources = dbqueries::get_sources()?; + index_loop(sources); + Ok(()) } #[cfg(test)] @@ -183,25 +167,6 @@ mod tests { index_all().unwrap(); } - #[test] - /// Insert feeds and update/index them. - fn test_fetch_loop() { - truncate_db().unwrap(); - let inpt = vec![ - "https://request-for-explanation.github.io/podcast/rss.xml", - "https://feeds.feedburner.com/InterceptedWithJeremyScahill", - "http://feeds.propublica.org/propublica/podcast", - "http://feeds.feedburner.com/linuxunplugged", - ]; - - inpt.iter().for_each(|url| { - // Index the urls into the source table. - Source::from_url(url).unwrap(); - }); - - fetch_all().unwrap(); - } - #[test] fn test_complete_index() { // vec of (path, url) tuples. @@ -240,7 +205,7 @@ mod tests { .collect(); // Index the channels - index(feeds); + feeds.par_iter().for_each(|x| index(&x)); // Assert the index rows equal the controlled results assert_eq!(dbqueries::get_sources().unwrap().len(), 4); diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 685986f..9338637 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -212,7 +212,7 @@ mod tests { // Convert Source it into a Feed and index it let feed = source.into_feed().unwrap(); - index(vec![feed]); + index(&feed); // Get the Podcast let pd = dbqueries::get_podcast_from_source_id(sid).unwrap().into(); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index b88a6dc..c03c835 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -34,20 +34,18 @@ pub fn refresh_feed(content: Rc, source: Option>) { })); thread::spawn(move || { - let feeds = { - if let Some(vec) = source { - Ok(feed::fetch(vec)) - } else { - feed::fetch_all() - } + if let Some(s) = source { + feed::index_loop(s); + } else { + let e = feed::index_all(); + if let Err(err) = e { + error!("Error While trying to update the database."); + error!("Error msg: {}", err); + }; }; - if let Ok(x) = feeds { - feed::index(x); - - sender.send(true).expect("Couldn't send data to channel");; - glib::idle_add(refresh_podcasts_view); - }; + sender.send(true).expect("Couldn't send data to channel");; + glib::idle_add(refresh_podcasts_view); }); } @@ -113,7 +111,7 @@ mod tests { // Convert Source it into a Feed and index it let feed = source.into_feed().unwrap(); - index(vec![feed]); + index(&feed); // Get the Podcast let pd = dbqueries::get_podcast_from_source_id(sid).unwrap(); From 0a7825dffffcb5bb7248c5e981145bde07e02e01 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 26 Dec 2017 21:36:18 +0200 Subject: [PATCH 098/278] EpisodeWidget: Remove delete button and hide cancel button till refactor. --- hammond-gtk/resources/gtk/episode_widget.ui | 23 -------- hammond-gtk/src/widgets/episode.rs | 58 +++++++-------------- 2 files changed, 18 insertions(+), 63 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index ff4a249..4495b5e 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -187,29 +187,6 @@ 0 - - - delete_button - True - True - True - end - center - - - True - False - user-trash-symbolic - - - - - False - False - end - 1 - - True diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 6c26449..7e9e683 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -9,7 +9,7 @@ use humansize::{file_size_opts as size_opts, FileSize}; use hammond_data::dbqueries; use hammond_data::{EpisodeWidgetQuery, Podcast}; -use hammond_data::utils::*; +// use hammond_data::utils::*; use hammond_data::errors::*; use hammond_downloader::downloader; @@ -24,7 +24,6 @@ type Foo = RefCell< gtk::Button, gtk::Button, gtk::Button, - gtk::Button, gtk::ProgressBar, Receiver, ), @@ -37,7 +36,6 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None)); pub struct EpisodeWidget { pub container: gtk::Box, play: gtk::Button, - delete: gtk::Button, download: gtk::Button, cancel: gtk::Button, title: gtk::Label, @@ -59,7 +57,6 @@ impl Default for EpisodeWidget { let download: gtk::Button = builder.get_object("download_button").unwrap(); let play: gtk::Button = builder.get_object("play_button").unwrap(); - let delete: gtk::Button = builder.get_object("delete_button").unwrap(); let cancel: gtk::Button = builder.get_object("cancel_button").unwrap(); let title: gtk::Label = builder.get_object("title_label").unwrap(); @@ -77,7 +74,6 @@ impl Default for EpisodeWidget { download, play, cancel, - delete, title, duration, size, @@ -152,7 +148,6 @@ impl EpisodeWidget { if local_uri.is_some() && Path::new(local_uri.unwrap()).exists() { self.download.hide(); self.play.show(); - self.delete.show(); } let title = &self.title; @@ -168,31 +163,18 @@ impl EpisodeWidget { })); let play = &self.play; - let download = &self.download; - self.delete - .connect_clicked(clone!(episode, play, download => move |del| { - on_delete_bttn_clicked(episode.rowid()); - del.hide(); - play.hide(); - download.show(); - })); - - let play = &self.play; - let delete = &self.delete; let cancel = &self.cancel; let progress = self.progress.clone(); - self.download.connect_clicked( - clone!(play, delete, episode, cancel, progress => move |dl| { + self.download + .connect_clicked(clone!(play, episode, cancel, progress => move |dl| { on_download_clicked( &mut episode.clone(), dl, &play, - &delete, &cancel, progress.clone() ); - }), - ); + })); } } @@ -201,7 +183,6 @@ fn on_download_clicked( ep: &mut EpisodeWidgetQuery, download_bttn: >k::Button, play_bttn: >k::Button, - del_bttn: >k::Button, cancel_bttn: >k::Button, progress_bar: gtk::ProgressBar, ) { @@ -218,11 +199,10 @@ fn on_download_clicked( // Pass the desired arguments into the Local Thread Storage. GLOBAL.with( - clone!(download_bttn, play_bttn, del_bttn, cancel_bttn, progress => move |global| { + clone!(download_bttn, play_bttn, cancel_bttn, progress => move |global| { *global.borrow_mut() = Some(( download_bttn, play_bttn, - del_bttn, cancel_bttn, progress, receiver)); @@ -232,7 +212,7 @@ fn on_download_clicked( let pd = dbqueries::get_podcast_from_id(ep.podcast_id()).unwrap(); let pd_title = pd.title().to_owned(); let mut ep = ep.clone(); - cancel_bttn.show(); + // cancel_bttn.show(); progress.show(); download_bttn.hide(); thread::spawn(move || { @@ -267,25 +247,24 @@ fn on_play_bttn_clicked(episode_id: i32) { } } -fn on_delete_bttn_clicked(episode_id: i32) { - let mut ep = dbqueries::get_episode_from_rowid(episode_id) - .unwrap() - .into(); +// fn on_delete_bttn_clicked(episode_id: i32) { +// let mut ep = dbqueries::get_episode_from_rowid(episode_id) +// .unwrap() +// .into(); - let e = delete_local_content(&mut ep); - if let Err(err) = e { - error!("Error while trying to delete file: {:?}", ep.local_uri()); - error!("Error: {}", err); - }; -} +// let e = delete_local_content(&mut ep); +// if let Err(err) = e { +// error!("Error while trying to delete file: {:?}", ep.local_uri()); +// error!("Error: {}", err); +// }; +// } fn receive() -> glib::Continue { GLOBAL.with(|global| { if let Some(( ref download_bttn, ref play_bttn, - ref del_bttn, - ref cancel_bttn, + ref _cancel_bttn, ref progress_bar, ref reciever, )) = *global.borrow() @@ -293,8 +272,7 @@ fn receive() -> glib::Continue { if reciever.try_recv().is_ok() { download_bttn.hide(); play_bttn.show(); - del_bttn.show(); - cancel_bttn.hide(); + // cancel_bttn.hide(); progress_bar.hide(); } } From ada73a616faf533f09ded56dd9ffca6c15de0182 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 27 Dec 2017 15:13:09 +0200 Subject: [PATCH 099/278] EpisodeWidget: Make cancel button insensitive. --- hammond-gtk/resources/gtk/episode_widget.ui | 3 ++- hammond-gtk/src/widgets/episode.rs | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 4495b5e..f6ab3b7 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -175,8 +175,9 @@ Cancel + False True - True + False True center diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 7e9e683..475e3c9 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -212,7 +212,7 @@ fn on_download_clicked( let pd = dbqueries::get_podcast_from_id(ep.podcast_id()).unwrap(); let pd_title = pd.title().to_owned(); let mut ep = ep.clone(); - // cancel_bttn.show(); + cancel_bttn.show(); progress.show(); download_bttn.hide(); thread::spawn(move || { @@ -264,7 +264,7 @@ fn receive() -> glib::Continue { if let Some(( ref download_bttn, ref play_bttn, - ref _cancel_bttn, + ref cancel_bttn, ref progress_bar, ref reciever, )) = *global.borrow() @@ -272,7 +272,7 @@ fn receive() -> glib::Continue { if reciever.try_recv().is_ok() { download_bttn.hide(); play_bttn.show(); - // cancel_bttn.hide(); + cancel_bttn.hide(); progress_bar.hide(); } } From 1f0a2b5c6c9612f3db83f7043a15df3fdb5bd9d0 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 27 Dec 2017 17:40:31 +0200 Subject: [PATCH 100/278] hammond-data::parser: Prefer itunes_summary over item.description if it exists. Finishes #20. --- hammond-data/src/parser.rs | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index fc47aa2..4a3a2b0 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -38,15 +38,20 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { if item.title().is_none() { bail!("No title specified for the item.") } + let title = item.title().unwrap().trim().to_owned(); - let description = item.description() - .map(|s| replace_extra_spaces(&ammonia::clean(s))); let guid = item.guid().map(|s| s.value().trim().to_owned()); - let x = item.enclosure().map(|s| url_cleaner(s.url())); - // FIXME: refactor - let uri = if x.is_some() { - x + let summary = item.itunes_ext().map(|s| s.summary()).and_then(|s| s); + let description = if summary.is_some() { + summary.map(|s| replace_extra_spaces(&ammonia::clean(s))) + } else { + item.description() + .map(|s| replace_extra_spaces(&ammonia::clean(s))) + }; + + let uri = if let Some(url) = item.enclosure().map(|s| url_cleaner(s.url())) { + Some(url) } else if item.link().is_some() { item.link().map(|s| url_cleaner(s)) } else { @@ -275,8 +280,9 @@ mod tests { let channel = Channel::read_from(BufReader::new(file)).unwrap(); let firstitem = channel.items().first().unwrap(); - let descr = "

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

"; + let descr = + "A reporter finds that homes meant to replace New York’s troubled psychiatric \ + hospitals might be just as bad."; let ep = new_episode(&firstitem, 0).unwrap(); let expected = NewEpisodeBuilder::default() @@ -297,9 +303,9 @@ mod tests { let second = channel.items().iter().nth(1).unwrap(); let ep = new_episode(&second, 0).unwrap(); let descr = - "

Jonathan Allen and Amie Parnes didn’t know their book would be called \ + "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.

"; + mounting signs of a doomed campaign."; let expected = NewEpisodeBuilder::default() @@ -356,12 +362,12 @@ mod tests { let second = channel.items().iter().nth(1).unwrap(); let ep = new_episode(&second, 0).unwrap(); - let descr = "

The Gnome project is about to solve one of our audience's biggest \ - Wayland’s concerns. But as the project takes on a new level of relevance, \ - decisions for the next version of Gnome have us worried about the \ - future.

\n

Plus we chat with Wimpy about the Ubuntu Rally in NYC, \ - Microsoft’s sneaky move to turn Windows 10 into the “ULTIMATE LINUX \ - RUNTIME”, community news & more!

"; + let descr = + "The Gnome project is about to solve one of our audience's biggest Wayland’s \ + concerns. But as the project takes on a new level of relevance, decisions for the \ + next version of Gnome have us worried about the future.\nPlus we chat with Wimpy \ + about the Ubuntu Rally in NYC, Microsoft’s sneaky move to turn Windows 10 into the \ + “ULTIMATE LINUX RUNTIME”, community news & more!"; let expected = NewEpisodeBuilder::default() .title("Gnome Does it Again | LUP 213") From 7d7b09ff0f29d38529b7c8f032f4990d1fa3d526 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 27 Dec 2017 17:59:40 +0200 Subject: [PATCH 101/278] hammond-data::parser: Prefer itunes_summary over channel.description if it exists. Finishes #20. --- hammond-data/src/parser.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 4a3a2b0..00afbd0 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -12,7 +12,14 @@ use errors::*; /// Parses a `rss::Channel` into a `NewPodcast` Struct. pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast { let title = chan.title().trim(); - let description = replace_extra_spaces(&ammonia::clean(chan.description())); + + // Prefer itunes summary over rss.description since many feeds put html into rss.description. + let summary = chan.itunes_ext().map(|s| s.summary()).and_then(|s| s); + let description = if let Some(sum) = summary { + replace_extra_spaces(&ammonia::clean(sum)) + } else { + replace_extra_spaces(&ammonia::clean(chan.description())) + }; let link = url_cleaner(chan.link()); let x = chan.itunes_ext().map(|s| s.image()); @@ -42,6 +49,7 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { let title = item.title().unwrap().trim().to_owned(); let guid = item.guid().map(|s| s.value().trim().to_owned()); + // Prefer itunes summary over rss.description since many feeds put html into rss.description. let summary = item.itunes_ext().map(|s| s.summary()).and_then(|s| s); let description = if summary.is_some() { summary.map(|s| replace_extra_spaces(&ammonia::clean(s))) @@ -155,9 +163,8 @@ mod tests { let file = File::open("tests/feeds/TheBreakthrough.xml").unwrap(); let channel = Channel::read_from(BufReader::new(file)).unwrap(); - let descr = "Latest Articles and Investigations from ProPublica, an independent, \ - non-profit newsroom that produces investigative journalism in the public \ - interest."; + let descr = "The podcast that takes you behind the scenes with journalists to hear how \ + they nailed their biggest stories."; let pd = new_podcast(&channel, 0); let expected = NewPodcastBuilder::default() From a9d1084e057f1f43504040fe85d0501eef096c06 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 27 Dec 2017 18:14:50 +0200 Subject: [PATCH 102/278] gitlab-ci: Remove ci cache until gitlab-runner 10.4 release --- .gitlab-ci.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3374923..8b4b5e1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,10 +22,6 @@ before_script: - cd hammond-gtk/resources/ && glib-compile-resources --generate resources.xml && cd ../../ - cargo build - cargo test --verbose -- --test-threads=1 - cache: - paths: - - target/ - - cargo/ variables: # RUSTFLAGS: "-C link-dead-code" From 5942e47f2a3b0855c46e6426e6233988892d751a Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 28 Dec 2017 16:59:05 +0200 Subject: [PATCH 103/278] hammond-gtk: Split gtk::Application into its own module. --- hammond-gtk/src/app.rs | 112 ++++++++++++++++++++++++++++++++++++++++ hammond-gtk/src/main.rs | 67 ++---------------------- 2 files changed, 116 insertions(+), 63 deletions(-) create mode 100644 hammond-gtk/src/app.rs diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs new file mode 100644 index 0000000..3bd0e50 --- /dev/null +++ b/hammond-gtk/src/app.rs @@ -0,0 +1,112 @@ +use gtk; +use glib; +use gio; +use gtk::prelude::*; +use gio::ApplicationExtManual; +use gio::ApplicationExt; + +use hammond_data::utils::checkup; + +use headerbar::Header; +use content::Content; +use utils; + +use std::rc::Rc; + +#[derive(Debug, Clone)] +pub struct App { + app_instance: gtk::Application, + window: gtk::Window, + header: Rc
, + content: Rc, +} + +impl App { + pub fn new() -> App { + let application = + gtk::Application::new("org.gnome.Hammond", gio::ApplicationFlags::empty()) + .expect("Initialization failed..."); + + // Weird magic I copy-pasted that sets the Application Name in the Shell. + glib::set_application_name("Hammond"); + glib::set_prgname(Some("Hammond")); + + // Create the main window + let window = gtk::Window::new(gtk::WindowType::Toplevel); + window.set_default_size(860, 640); + window.set_title("Hammond"); + window.connect_delete_event(|w, _| { + w.destroy(); + Inhibit(false) + }); + + // TODO: Refactor the initialization order. + + // Create the headerbar + let header = Rc::new(Header::default()); + + // Create a content instance + let content = Content::new(header.clone()); + + // Initialize the headerbar + header.init(content.clone()); + + // Add the Headerbar to the window. + window.set_titlebar(&header.container); + // Add the content main stack to the window. + window.add(&content.get_stack()); + + App { + app_instance: application, + window, + header, + content, + } + } + + pub fn run(&self) { + let window = self.window.clone(); + let app = self.app_instance.clone(); + self.app_instance.connect_startup(move |_| { + build_ui(&window, &app); + }); + + let content = self.content.clone(); + // Update 30 seconds after the Application is initialized. + gtk::timeout_add_seconds( + 30, + clone!(content => move || { + utils::refresh_feed(content.clone(), None); + glib::Continue(false) + }), + ); + + let content = self.content.clone(); + // Auto-updater, runs every hour. + // TODO: expose the interval in which it run to a user setting. + // TODO: show notifications. + gtk::timeout_add_seconds( + 3600, + clone!(content => move || { + utils::refresh_feed(content.clone(), None); + glib::Continue(true) + }), + ); + + // Run a database checkup once the application is initialized. + gtk::idle_add(move || { + let _ = checkup(); + glib::Continue(false) + }); + + ApplicationExtManual::run(&self.app_instance, &[]); + } +} + +fn build_ui(window: >k::Window, app: >k::Application) { + window.set_application(app); + + window.show_all(); + window.activate(); + app.connect_activate(move |_| ()); +} diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index d9fd5bd..e58a0b3 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -24,11 +24,8 @@ extern crate send_cell; // use rayon::prelude::*; use log::LogLevel; -use hammond_data::utils::checkup; use gtk::prelude::*; -use gio::ApplicationExt; -use std::rc::Rc; // http://gtk-rs.org/tuto/closures #[macro_export] @@ -53,70 +50,19 @@ mod views; mod widgets; mod headerbar; mod content; +mod app; mod utils; mod static_resource; -fn build_ui(app: >k::Application) { - // Get the main window - let window = gtk::ApplicationWindow::new(app); - window.set_default_size(860, 640); - window.set_title("Hammond"); - - // Get the headerbar - let header = Rc::new(headerbar::Header::default()); - let ct = content::Content::new(header.clone()); - header.init(ct.clone()); - window.set_titlebar(&header.container); - window.add(&ct.get_stack()); - - window.connect_delete_event(|w, _| { - w.destroy(); - Inhibit(false) - }); - - // Update on startup - gtk::timeout_add_seconds( - 30, - clone!(ct => move || { - utils::refresh_feed(ct.clone(), None); - glib::Continue(false) - }), - ); - // Auto-updater, runs every hour. - // TODO: expose the interval in which it run to a user setting. - // TODO: show notifications. - gtk::timeout_add_seconds( - 3600, - clone!(ct => move || { - utils::refresh_feed(ct.clone(), None); - glib::Continue(true) - }), - ); - - gtk::idle_add(move || { - let _ = checkup(); - glib::Continue(false) - }); - - window.show_all(); - window.activate(); - app.connect_activate(move |_| ()); -} +use app::App; fn main() { - use gio::ApplicationExtManual; - // TODO: make the the logger a cli -vv option loggerv::init_with_level(LogLevel::Info).unwrap(); + gtk::init().expect("Error initializing gtk"); static_resource::init().expect("Something went wrong with the resource file initialization."); - let application = gtk::Application::new("org.gnome.Hammond", gio::ApplicationFlags::empty()) - .expect("Initialization failed..."); - - glib::set_application_name("Hammond"); - glib::set_prgname(Some("Hammond")); - // Add custom style let provider = gtk::CssProvider::new(); gtk::CssProvider::load_from_resource(&provider, "/org/gnome/hammond/gtk/style.css"); @@ -126,10 +72,5 @@ fn main() { 600, ); - application.connect_startup(move |app| { - build_ui(app); - }); - - // application.run(&[]); - ApplicationExtManual::run(&application, &[]); + App::new().run(); } From 287620d6cd23e48cdb0742a6cb6fd9dce2319f2d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 28 Dec 2017 19:16:51 +0200 Subject: [PATCH 104/278] hammond-gtk: Added some getters and removed some public fields. --- hammond-gtk/src/content.rs | 14 +++++++++++--- hammond-gtk/src/headerbar.rs | 7 ++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 7722ae0..630e7e2 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -15,8 +15,8 @@ use std::rc::Rc; #[derive(Debug, Clone)] pub struct Content { - pub stack: gtk::Stack, - pub shows: Rc, + stack: gtk::Stack, + shows: Rc, episodes: Rc, } @@ -44,11 +44,15 @@ impl Content { pub fn get_stack(&self) -> gtk::Stack { self.stack.clone() } + + pub fn get_shows(&self) -> Rc { + self.shows.clone() + } } #[derive(Debug, Clone)] pub struct ShowStack { - pub stack: gtk::Stack, + stack: gtk::Stack, header: Rc
, epstack: Rc, } @@ -149,6 +153,10 @@ impl ShowStack { self.stack .set_visible_child_full("widget", gtk::StackTransitionType::SlideLeft) } + + pub fn get_stack(&self) -> gtk::Stack { + self.stack.clone() + } } #[derive(Debug, Clone)] diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 96a3ecc..f811324 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -30,9 +30,6 @@ impl Default for Header { let back_button: gtk::Button = builder.get_object("back_button").unwrap(); let show_title: gtk::Label = builder.get_object("show_title").unwrap(); - switch.set_halign(gtk::Align::Center); - switch.show(); - Header { container: header, add_toggle, @@ -60,7 +57,7 @@ impl Header { let new_url: gtk::Entry = builder.get_object("new_url").unwrap(); let add_button: gtk::Button = builder.get_object("add_button").unwrap(); let refresh_button: gtk::Button = builder.get_object("refresh_button").unwrap(); - self.switch.set_stack(&content.stack); + self.switch.set_stack(&content.get_stack()); new_url.connect_changed(move |url| { println!("{:?}", url.get_text()); @@ -90,7 +87,7 @@ impl Header { add_toggle.show(); back.hide(); show_title.hide(); - content.shows.stack.set_visible_child_full("podcasts", gtk::StackTransitionType::SlideRight); + content.get_shows().get_stack().set_visible_child_full("podcasts", gtk::StackTransitionType::SlideRight); }), ); } From 8a7d6d9f1be8a73f67d5c10c44b1a8f34c76ca57 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 28 Dec 2017 22:41:22 +0200 Subject: [PATCH 105/278] Add an empty CHANGELOG that follows keepachangelog.com format. Closes #23. --- CHANGELOG | 10 ++++++++++ hammond-data/src/parser.rs | 1 - 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG diff --git a/CHANGELOG b/CHANGELOG new file mode 100644 index 0000000..6677a79 --- /dev/null +++ b/CHANGELOG @@ -0,0 +1,10 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +## [0.3.0] - xxxx-xx-xx + diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 00afbd0..ecb610c 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -40,7 +40,6 @@ pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast { } /// Parses an `rss::Item` into a `NewEpisode` Struct. -// TODO: parse itunes duration extension. pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { if item.title().is_none() { bail!("No title specified for the item.") From 1d78ab7c423d1100e5bbcbe3f276b7ae16d4a9a7 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 28 Dec 2017 23:19:36 +0200 Subject: [PATCH 106/278] Cargo upgrade. --- Cargo.lock | 278 +++++++++++++++++++++-------- hammond-data/Cargo.toml | 10 +- hammond-downloader/Cargo.toml | 4 +- hammond-gtk/Cargo.toml | 2 +- hammond-gtk/src/widgets/episode.rs | 1 + 5 files changed, 210 insertions(+), 85 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cdba1e2..2d33e5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,11 +22,11 @@ dependencies = [ [[package]] name = "ammonia" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "html5ever 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "html5ever 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "maplit 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -57,13 +57,12 @@ dependencies = [ [[package]] name = "atty" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -91,7 +90,7 @@ dependencies = [ [[package]] name = "base64" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -250,17 +249,17 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "derive_builder_core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_builder_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "derive_builder_core" -version = "0.1.7" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", @@ -369,6 +368,15 @@ dependencies = [ "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fuchsia-zircon" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "fuchsia-zircon-sys" version = "0.2.0" @@ -377,6 +385,11 @@ dependencies = [ "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "futf" version = "0.1.3" @@ -561,21 +574,21 @@ dependencies = [ name = "hammond-data" version = "0.1.0" dependencies = [ - "ammonia 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ammonia 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)", "diesel_migrations 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "r2d2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2-diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "rfc822_sanitizer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rss 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -590,10 +603,10 @@ dependencies = [ "diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "hammond-data 0.1.0", - "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -611,9 +624,9 @@ dependencies = [ "gtk 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "hammond-data 0.1.0", "hammond-downloader 0.1.0", - "humansize 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "loggerv 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -626,13 +639,25 @@ name = "html5ever" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "markup5ever 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "html5ever" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "markup5ever 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "httparse" version = "1.2.3" @@ -640,21 +665,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "humansize" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -672,7 +697,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -748,7 +773,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libflate" -version = "0.1.12" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -767,8 +792,19 @@ dependencies = [ [[package]] name = "log" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "loggerv" @@ -776,8 +812,8 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -803,6 +839,21 @@ dependencies = [ "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "markup5ever" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "matches" version = "0.1.6" @@ -839,7 +890,7 @@ name = "mime" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -883,7 +934,7 @@ dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1046,7 +1097,7 @@ version = "0.7.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1070,7 +1121,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "quick-xml" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1085,11 +1136,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "r2d2" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1099,15 +1150,24 @@ version = "0.99.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)", - "r2d2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rand" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1129,12 +1189,12 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1142,7 +1202,7 @@ name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1172,18 +1232,18 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libflate 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1208,8 +1268,8 @@ name = "rss" version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-xml 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quick-xml 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1295,9 +1355,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.24" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "serde_derive" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive_internals" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde_json" version = "1.0.8" @@ -1306,7 +1385,7 @@ dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1316,7 +1395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1349,7 +1428,21 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "string_cache" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", + "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1398,7 +1491,7 @@ name = "tempdir" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1417,7 +1510,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1437,7 +1530,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1449,7 +1542,7 @@ dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1463,7 +1556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1472,9 +1565,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1580,7 +1673,7 @@ name = "uuid" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1603,11 +1696,30 @@ name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -1626,14 +1738,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" "checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" -"checksum ammonia 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2cc0ea12b4977283c563e78eaf227b024d89d72a6394040fad4063899bfcfb48" +"checksum ammonia 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f1b9ec9f0a4d43499276dfba49b3e92bf9081e8f2206386caa02237bc71e1beb" "checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455" "checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" "checksum atk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "33a67fd81e1922dddc335887516f2f5254534e89c9d39fa89bca5d79bd150d34" -"checksum atty 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "21e50800ec991574876040fff8ee46b136a53e985286fbe6a3bdfe6421b78860" +"checksum atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859" "checksum backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8709cc7ec06f6f0ae6c2c7e12f6ed41540781f72b488d83734978295ceae182e" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" -"checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d" +"checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" @@ -1654,8 +1766,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a" -"checksum derive_builder 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03600ae366b6eb2314e54d62adc833d9866da03798acc61c61789654ceaa227a" -"checksum derive_builder_core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eed37eae64daa5511467b1a55cebdf472deeaef108d22f62f25e8bbcaffd56ac" +"checksum derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c998e6ab02a828dd9735c18f154e14100e674ed08cb4e1938f0e4177543f439" +"checksum derive_builder_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "735e24ee9e5fa8e16b86da5007856e97d592e11867e45d76e0c0d0a164a0b757" "checksum diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0b97bd43f72d4819fac99f24d0030184c64c5ebdee96f94c7a7d4215c50506a7" "checksum diesel_derives 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad228b6fd05c86050b95f56e497a8135073ffce28602e2200e63a21047eb474d" "checksum diesel_migrations 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "745dcfe39e3043c267e46dbe4f2ebbc9917039bdf4d81b108950be61244dfc89" @@ -1669,7 +1781,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" +"checksum fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd510087c325af53ba24f3be8f1c081b0982319adcb8b03cad764512923ccc19" "checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" +"checksum fuchsia-zircon-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "08b3a6f13ad6b96572b53ce7af74543132f1a7055ccceb6d073dd36c54481859" "checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" "checksum futures-cpupool 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "e86f49cc0d92fe1b97a5980ec32d56208272cbb00f15044ea9e2799dde766fdf" @@ -1685,9 +1799,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum gtk 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0847c507e52c1feaede13ef56fb4847742438602655449d5f1f782e8633f146f" "checksum gtk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "905fcfbaaad1b44ec0b4bba9e4d527d728284c62bc2ba41fccedace2b096766f" "checksum html5ever 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ba3a1fd1857a714d410c191364c5d7bf8a6487c0ab5575146d37dd7eb17ef523" +"checksum html5ever 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e579ac8647178ab915d400d7d22938bda5cd351c6c62e1c294d56884ccfc75fe" "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" -"checksum humansize 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d99804bdb0790b0c312a5a1115f83804b821f1a96d80759fbb57ce796d1f3778" -"checksum hyper 0.11.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e0594792d2109069d0caffd176f674d770a84adf024c5bb48e686b1ee5ac7659" +"checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" +"checksum hyper 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4844b207be8393981c5fcb61c9372d7c96432fcc8f5c3431a255a9d19b5c298b" "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" @@ -1699,13 +1814,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" "checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" "checksum libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "36fbc8a8929c632868295d0178dd8f63fc423fd7537ad0738372bd010b3ac9b0" -"checksum libflate 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ae46bcdafa496981e996e57c5be82c0a7f130a071323764c6faa4803619f1e67" +"checksum libflate 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6e0ae8f2ea4a426e1af2c2c1ba5696bd597368afe5068f9485fc960973fe6dfb" "checksum libsqlite3-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "370090ad578ba845a3ad4f383ceb3deba7abd51ab1915ad1f2c982cc6035e31c" -"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b" +"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" +"checksum log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a89a0c46ba789b8a247d4c567aed4d7c68e624672d238b45cc3ec20dc9f940" "checksum loggerv 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b178879253fab6ddb4ea931e1e6f514d45ce6a53f7fe618a0a8751f43e42e4f1" "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" "checksum maplit 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ed95049d40b8a1a7691adbabca028ad481f7e6a2921ce4846e1ee168b4e4ca5" "checksum markup5ever 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2cf89d3e0486c32c9d99521455ddf9a438910a1ce2bd376936086edc15dff5fc" +"checksum markup5ever 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7bccd18e4fab95f4410dc4d714163c2e88dd80e39a2a013998e345f337a569ab" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum migrations_internals 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ac1d17f6f161f4d91cb7e5a72cce5b24a60b80f96580a8ac94351c56b8606a" @@ -1735,19 +1852,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2" "checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903" "checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" -"checksum quick-xml 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d0fb3e41d968cd20da34a9e81abae097398b38fe0987149e321572eb75d3317" +"checksum quick-xml 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19602854dba17f93b3011fe272af6db3133d5b495279f504bf9104dc97879717" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" -"checksum r2d2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "59611202bee496c586ecd84e3ed149b4ec75981b0fc10d7f60e878fa23ae16e9" +"checksum r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9078ca6a8a5568ed142083bb2f7dc9295b69d16f867ddcc9849e51b17d8db46" "checksum r2d2-diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77aaed149a82720f4b664427f359e1b2a34d8787c1bc3fb1d167b104a1ddd866" -"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd" +"checksum rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7944d95d25ace8f377da3ac7068ce517e4c646754c43a1b1849177bbf72e59" +"checksum rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d5f78082e6a6d042862611e9640cf20776185fee506cf6cf67e93c6225cee31" "checksum rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf" "checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" -"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0" +"checksum redox_syscall 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "07b8f011e3254d5a9b318fde596d409a0001c9ae4c6e7907520c2eaa4d988c99" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322" "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" -"checksum reqwest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f73a8482e3b2b20ef5c07168b27048fc3778a012ce9b11a021556a450a01e9b5" +"checksum reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3161ca63fd11ce36c7718af239e6492a25a3dbfcec54240f959b9d816cf42413" "checksum rfc822_sanitizer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "680e8305c1e0cdf836dc4bec5424e045f278c975a3cac36d1ca01c4695f9d815" "checksum rss 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3fbc1a0587ebbc7404b3295c8e1f717d00dad48e3c205adadf916f15ff67d05b" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" @@ -1761,7 +1879,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" "checksum send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c620dd7e056b468b9d374a9f51cfa6bb4bf17a8ca4ee62e5efa0d99aaff2c41" -"checksum serde 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)" = "1c57ab4ec5fa85d08aaf8ed9245899d9bbdd66768945b21113b84d5f595cb6a1" +"checksum serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "d1d6af49db29f2f2678e442f4eb82e7d78f59dbbd3e373ccffc17fe70c1b94f8" +"checksum serde_derive 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "95b4ea937d8dff4c94d1a6fdd710eade6aedaa17c4049da29bb97a4f8a4f4bc1" +"checksum serde_derive_internals 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "730fe9f29fe8db69a601837f416e46cba07792031ed6b27557a43e49d62d89ae" "checksum serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf5b0b5b4bd22eeecb7e01ac2e1225c7ef5e4272b79ee28a8392a8c8489c839" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" @@ -1769,6 +1889,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d" "checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013" "checksum string_cache 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "413fc7852aeeb5472f1986ef755f561ddf0c789d3d796e65f0b6fe293ecd4ef8" +"checksum string_cache 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39cb4173bcbd1319da31faa5468a7e3870683d7a237150b0b0aaafd546f6ad12" "checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7" "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" @@ -1799,6 +1920,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "890b38836c01d72fdb636d15c9cfc52ec7fd783b330abc93cd1686f4308dfccc" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ec6667f60c23eca65c561e63a13d81b44234c2e38a6b6c959025ee907ec614cc" +"checksum winapi-x86_64-pc-windows-gnu 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98f12c52b2630cd05d2c3ffd8e008f7f48252c042b4871c72aed9dc733b96668" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a66b7c2281ebde13cf4391d70d4c7e5946c3c25e72a7b859ca8f677dcd0b0c61" diff --git a/hammond-data/Cargo.toml b/hammond-data/Cargo.toml index c28e25f..750c072 100644 --- a/hammond-data/Cargo.toml +++ b/hammond-data/Cargo.toml @@ -5,18 +5,18 @@ version = "0.1.0" workspace = "../" [dependencies] -ammonia = "1.0.0" +ammonia = "1.0.1" chrono = "0.4.0" -derive_builder = "0.5.0" +derive_builder = "0.5.1" dotenv = "0.10.1" error-chain = "0.11.0" itertools = "0.7.4" lazy_static = "1.0.0" log = "0.3.8" -r2d2 = "0.8.1" +r2d2 = "0.8.2" r2d2-diesel = "0.99.0" rayon = "0.9.0" -reqwest = "0.8.1" +reqwest = "0.8.2" rfc822_sanitizer = "0.3.3" rss = "1.2.1" url = "1.6.0" @@ -31,5 +31,5 @@ features = ["sqlite"] version = "0.99.0" [dev-dependencies] -rand = "0.3.18" +rand = "0.4.1" tempdir = "0.3.5" diff --git a/hammond-downloader/Cargo.toml b/hammond-downloader/Cargo.toml index ed50616..efb8754 100644 --- a/hammond-downloader/Cargo.toml +++ b/hammond-downloader/Cargo.toml @@ -6,10 +6,10 @@ workspace = "../" [dependencies] error-chain = "0.11.0" -hyper = "0.11.9" +hyper = "0.11.10" log = "0.3.8" mime_guess = "1.8.3" -reqwest = "0.8.1" +reqwest = "0.8.2" tempdir = "0.3.5" [dependencies.diesel] diff --git a/hammond-gtk/Cargo.toml b/hammond-gtk/Cargo.toml index ceb387d..b2265bf 100644 --- a/hammond-gtk/Cargo.toml +++ b/hammond-gtk/Cargo.toml @@ -12,7 +12,7 @@ gdk = "0.7.0" gdk-pixbuf = "0.3.0" gio = "0.3.0" glib = "0.4.0" -humansize = "1.0.2" +humansize = "1.1.0" lazy_static = "1.0.0" log = "0.3.8" loggerv = "0.6.0" diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 475e3c9..ae17d73 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -116,6 +116,7 @@ impl EpisodeWidget { long_units: false, space: true, suffix: "", + allow_negative: false, }; if let Some(size) = episode.length() { From 55b6fccefd89757a0e65055a5f02014be5e6b5ac Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 28 Dec 2017 23:46:09 +0200 Subject: [PATCH 107/278] Make it explicit to run some tests. --- .gitlab-ci.yml | 1 + hammond-downloader/src/downloader.rs | 3 +++ hammond-gtk/src/utils.rs | 3 +++ 3 files changed, 7 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8b4b5e1..65084e8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,6 +22,7 @@ before_script: - cd hammond-gtk/resources/ && glib-compile-resources --generate resources.xml && cd ../../ - cargo build - cargo test --verbose -- --test-threads=1 + - cargo test --verbose -- --test-threads=1 --ignored variables: # RUSTFLAGS: "-C link-dead-code" diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 9338637..2403cc9 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -202,6 +202,9 @@ mod tests { } #[test] + // This test inserts an rss feed to your `XDG_DATA/hammond/hammond.db` so we make it explicit + // to run it. + #[ignore] fn test_cache_image() { let url = "http://www.newrustacean.com/feed.xml"; diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index c03c835..b99252d 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -101,6 +101,9 @@ mod tests { use super::*; #[test] + // This test inserts an rss feed to your `XDG_DATA/hammond/hammond.db` so we make it explicit + // to run it. + #[ignore] fn test_get_pixbuf_from_path() { let url = "http://www.newrustacean.com/feed.xml"; From ca06a16bd9f6766428c20fd2c2e7b6e0008ffce5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 29 Dec 2017 02:45:02 +0200 Subject: [PATCH 108/278] Closes #2. Kudo to @jwykeham for the fix!. --- TODO.md | 3 --- hammond-data/src/feed.rs | 23 ++++++++++--------- hammond-data/src/models/queryables.rs | 32 +++++++++++++++------------ hammond-downloader/src/downloader.rs | 2 +- hammond-gtk/src/utils.rs | 2 +- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/TODO.md b/TODO.md index 6106680..5190a13 100644 --- a/TODO.md +++ b/TODO.md @@ -31,6 +31,3 @@ - [ ] Make Podcast cover fetchng and loading not block the execution of the program at startup. - [ ] Lazy evaluate episode loading based on the show_widget's scrolling. -**FIXME:** - -- [ ] Fix Etag/Last-modified implementation. [#2](https://gitlab.gnome.org/alatiera/Hammond/issues/2) diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index f613f16..efc77cb 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -26,7 +26,7 @@ pub struct Feed { impl Feed { /// Constructor that consumes a `Source` and returns the corresponding `Feed` struct. pub fn from_source(s: Source) -> Result { - s.into_feed() + s.into_feed(false) } /// Constructor that consumes a `Source` and a `rss::Channel` returns a `Feed` struct. @@ -112,19 +112,22 @@ pub fn index(feed: &Feed) { /// Consume a `Source` and return a `Feed`. fn fetch(source: Source) -> Result { - let uri = source.uri().to_owned(); - let feed = Feed::from_source(source); - if feed.is_err() { - error!("Error While trying to fetch from source url: {}.", uri); - } - feed + Feed::from_source(source) } /// Index a "list" of `Source`s. pub fn index_loop>(sources: S) { sources .into_par_iter() - .filter_map(|x| fetch(x).ok()) + .filter_map(|x| { + let foo = fetch(x); + if let Err(err) = foo { + error!("Error: {}", err); + None + } else { + foo.ok() + } + }) .for_each(|x| index(&x)); info!("Indexing done."); @@ -223,8 +226,8 @@ mod tests { assert_eq!(s1, s2); assert_eq!(s1.id(), s2.id()); - let f1 = s1.into_feed().unwrap(); - let f2 = s2.into_feed().unwrap(); + let f1 = s1.into_feed(false).unwrap(); + let f2 = s2.into_feed(false).unwrap(); let p1 = f1.get_podcast().unwrap(); let p2 = { diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index d4409cd..b83ba52 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -640,18 +640,22 @@ impl<'a> Source { /// /// Consumes `self` and Returns the corresponding `Feed` Object. // TODO: Refactor into TryInto once it lands on stable. - pub fn into_feed(mut self) -> Result { - use reqwest::header::{ETag, EntityTag, Headers, HttpDate, LastModified}; + pub fn into_feed(mut self, ignore_etags: bool) -> Result { + use reqwest::header::{EntityTag, Headers, HttpDate, IfModifiedSince, IfNoneMatch}; let mut headers = Headers::new(); - if let Some(foo) = self.http_etag() { - headers.set(ETag(EntityTag::new(true, foo.to_owned()))); - } + if !ignore_etags { + if let Some(foo) = self.http_etag() { + headers.set(IfNoneMatch::Items(vec![ + EntityTag::new(true, foo.to_owned()), + ])); + } - if let Some(foo) = self.last_modified() { - if let Ok(x) = foo.parse::() { - headers.set(LastModified(x)); + if let Some(foo) = self.last_modified() { + if let Ok(x) = foo.parse::() { + headers.set(IfModifiedSince(x)); + } } } @@ -663,17 +667,17 @@ impl<'a> Source { info!("GET to {} , returned: {}", self.uri(), req.status()); + self.update_etag(&req)?; + // TODO match on more stuff // 301: Permanent redirect of the url // 302: Temporary redirect of the url // 304: Up to date Feed, checked with the Etag // 410: Feed deleted - // match req.status() { - // reqwest::StatusCode::NotModified => (), - // _ => (), - // }; - - self.update_etag(&req)?; + match req.status() { + reqwest::StatusCode::NotModified => bail!("304, skipping.."), + _ => (), + }; let mut buf = String::new(); req.read_to_string(&mut buf)?; diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 2403cc9..7df62b6 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -214,7 +214,7 @@ mod tests { let sid = source.id().clone(); // Convert Source it into a Feed and index it - let feed = source.into_feed().unwrap(); + let feed = source.into_feed(true).unwrap(); index(&feed); // Get the Podcast diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index b99252d..cd77c1a 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -113,7 +113,7 @@ mod tests { let sid = source.id().clone(); // Convert Source it into a Feed and index it - let feed = source.into_feed().unwrap(); + let feed = source.into_feed(true).unwrap(); index(&feed); // Get the Podcast From fdd63afdfed3f979040bd8bc0bbe4e61b4fdc1cd Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 29 Dec 2017 16:05:10 +0200 Subject: [PATCH 109/278] hammond-gtk: Create Application wide actions. --- hammond-gtk/resources/gtk/headerbar.ui | 1 + hammond-gtk/src/app.rs | 33 ++++++++++++++++++++------ hammond-gtk/src/headerbar.rs | 5 ---- hammond-gtk/src/utils.rs | 4 ++-- 4 files changed, 29 insertions(+), 14 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index 0801116..dfcc7db 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -249,6 +249,7 @@ True True True + app.update Check for new episodes
diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 3bd0e50..01242e7 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -2,8 +2,7 @@ use gtk; use glib; use gio; use gtk::prelude::*; -use gio::ApplicationExtManual; -use gio::ApplicationExt; +use gio::{ActionMapExt, ApplicationExt, ApplicationExtManual, SimpleActionExt}; use hammond_data::utils::checkup; @@ -64,13 +63,23 @@ impl App { } } - pub fn run(&self) { - let window = self.window.clone(); - let app = self.app_instance.clone(); - self.app_instance.connect_startup(move |_| { - build_ui(&window, &app); + pub fn setup_actions(&self) { + let update = gio::SimpleAction::new("update", None); + let content = self.content.clone(); + update.connect_activate(move |_, _| { + utils::refresh_feed(content.clone(), None); }); + self.app_instance.add_action(&update); + let refresh = gio::SimpleAction::new("refresh", None); + let content = self.content.clone(); + update.connect_activate(move |_, _| { + content.update(); + }); + self.app_instance.add_action(&refresh); + } + + pub fn setup_timed_callbacks(&self) { let content = self.content.clone(); // Update 30 seconds after the Application is initialized. gtk::timeout_add_seconds( @@ -98,6 +107,16 @@ impl App { let _ = checkup(); glib::Continue(false) }); + } + + pub fn run(&self) { + let window = self.window.clone(); + let app = self.app_instance.clone(); + self.app_instance.connect_startup(move |_| { + build_ui(&window, &app); + }); + self.setup_timed_callbacks(); + self.setup_actions(); ApplicationExtManual::run(&self.app_instance, &[]); } diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index f811324..cc99eb7 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -56,7 +56,6 @@ impl Header { let menu_popover: gtk::PopoverMenu = builder.get_object("menu_popover").unwrap(); let new_url: gtk::Entry = builder.get_object("new_url").unwrap(); let add_button: gtk::Button = builder.get_object("add_button").unwrap(); - let refresh_button: gtk::Button = builder.get_object("refresh_button").unwrap(); self.switch.set_stack(&content.get_stack()); new_url.connect_changed(move |url| { @@ -71,10 +70,6 @@ impl Header { add_popover.hide(); })); - refresh_button.connect_clicked(clone!(content => move |_| { - utils::refresh_feed(content.clone(), None); - })); - self.add_toggle.set_popover(&add_popover); self.menu_toggle.set_popover(&menu_popover); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index cd77c1a..7bb3853 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -45,11 +45,11 @@ pub fn refresh_feed(content: Rc, source: Option>) { }; sender.send(true).expect("Couldn't send data to channel");; - glib::idle_add(refresh_podcasts_view); + glib::idle_add(refresh_everything); }); } -fn refresh_podcasts_view() -> glib::Continue { +fn refresh_everything() -> glib::Continue { GLOBAL.with(|global| { if let Some((ref content, ref reciever)) = *global.borrow() { if reciever.try_recv().is_ok() { From ac286888bdcfdafe59b1dbee19c65f59771575e9 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 29 Dec 2017 20:06:04 +0200 Subject: [PATCH 110/278] hammond-gtk: Add more GActions and wire the EpisodeWidget. --- hammond-gtk/resources/gtk/episode_widget.ui | 2 ++ hammond-gtk/src/app.rs | 18 +++++++++++++++++- hammond-gtk/src/content.rs | 10 +++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index f6ab3b7..3660ebb 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -196,6 +196,7 @@ True end center + app.refresh_episodes True @@ -218,6 +219,7 @@ True True center + app.refresh_episodes True diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 01242e7..200a016 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -73,10 +73,26 @@ impl App { let refresh = gio::SimpleAction::new("refresh", None); let content = self.content.clone(); - update.connect_activate(move |_, _| { + refresh.connect_activate(move |_, _| { content.update(); }); self.app_instance.add_action(&refresh); + + let refresh_episodes = gio::SimpleAction::new("refresh_episodes", None); + let content = self.content.clone(); + refresh_episodes.connect_activate(move |_, _| { + if content.get_stack().get_visible_child_name() != Some(String::from("episodes")) { + content.update_episode_view(); + } + }); + self.app_instance.add_action(&refresh_episodes); + + let refresh_shows = gio::SimpleAction::new("refresh_shows", None); + let content = self.content.clone(); + refresh_shows.connect_activate(move |_, _| { + content.update_shows_view(); + }); + self.app_instance.add_action(&refresh_shows); } pub fn setup_timed_callbacks(&self) { diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 630e7e2..73e2234 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -37,10 +37,18 @@ impl Content { } pub fn update(&self) { - self.shows.update(); + self.update_shows_view(); + self.update_episode_view(); + } + + pub fn update_episode_view(&self) { self.episodes.update(); } + pub fn update_shows_view(&self) { + self.shows.update(); + } + pub fn get_stack(&self) -> gtk::Stack { self.stack.clone() } From 036292284df4f4c7fa6c3cc14a6726f758f8f3d4 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 29 Dec 2017 20:21:36 +0200 Subject: [PATCH 111/278] hammond-data: Do not clean source url's cause some feeds use queries as identifiers for some reason. --- hammond-data/src/models/insertables.rs | 4 +--- hammond-gtk/src/headerbar.rs | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index 368d92b..6e6d5b1 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -5,7 +5,6 @@ use diesel::prelude::*; use schema::{episode, podcast, source}; use models::queryables::{Episode, Podcast, Source}; -use utils::url_cleaner; use errors::*; use dbqueries; @@ -41,9 +40,8 @@ impl Insert for NewSource { impl NewSource { pub(crate) fn new_with_uri(uri: &str) -> NewSource { - let uri = url_cleaner(uri); NewSource { - uri, + uri: uri.trim().to_string(), last_modified: None, http_etag: None, } diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index cc99eb7..a399182 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -2,7 +2,6 @@ use gtk; use gtk::prelude::*; use hammond_data::Source; -use hammond_data::utils::url_cleaner; use std::rc::Rc; @@ -109,7 +108,6 @@ impl Header { fn on_add_bttn_clicked(content: Rc, entry: >k::Entry) { let url = entry.get_text().unwrap_or_default(); - let url = url_cleaner(&url); let source = Source::from_url(&url); if let Ok(s) = source { From bcc089bd82539638941c8d256ec553bb1006be83 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 29 Dec 2017 20:33:47 +0200 Subject: [PATCH 112/278] ShowWidget: Migrate unsub button to use the GAction instead. --- hammond-gtk/resources/gtk/show_widget.ui | 1 + hammond-gtk/src/content.rs | 7 +---- hammond-gtk/src/widgets/show.rs | 34 +++++------------------- 3 files changed, 9 insertions(+), 33 deletions(-) diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index 1bc45e7..cb3aa36 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -151,6 +151,7 @@ True center center + app.update diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 73e2234..6293d59 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -124,12 +124,7 @@ impl ShowStack { pub fn replace_widget(&self, pd: &Podcast) { let old = self.stack.get_child_by_name("widget").unwrap(); - let new = ShowWidget::new( - Rc::new(self.clone()), - self.epstack.clone(), - self.header.clone(), - pd, - ); + let new = ShowWidget::new(Rc::new(self.clone()), self.header.clone(), pd); self.stack.remove(&old); self.stack.add_named(&new.container, "widget"); diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 66da950..0da781f 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -11,7 +11,7 @@ use hammond_downloader::downloader; use widgets::episode::episodes_listbox; use utils::get_pixbuf_from_path; -use content::{EpisodeStack, ShowStack}; +use content::ShowStack; use headerbar::Header; use std::rc::Rc; @@ -53,30 +53,17 @@ impl Default for ShowWidget { } impl ShowWidget { - pub fn new( - shows: Rc, - epstack: Rc, - header: Rc
, - pd: &Podcast, - ) -> ShowWidget { + pub fn new(shows: Rc, header: Rc
, pd: &Podcast) -> ShowWidget { let pdw = ShowWidget::default(); - pdw.init(shows, epstack, header, pd); + pdw.init(shows, header, pd); pdw } - pub fn init( - &self, - shows: Rc, - epstack: Rc, - header: Rc
, - pd: &Podcast, - ) { + pub fn init(&self, shows: Rc, header: Rc
, pd: &Podcast) { WidgetExt::set_name(&self.container, &pd.id().to_string()); - // TODO: should spawn a thread to avoid locking the UI probably. - self.unsub - .connect_clicked(clone!(shows, epstack, pd => move |bttn| { - on_unsub_button_clicked(shows.clone(), epstack.clone(), &pd, bttn); + self.unsub.connect_clicked(clone!(shows, pd => move |bttn| { + on_unsub_button_clicked(shows.clone(), &pd, bttn); header.switch_to_normal(); })); @@ -106,12 +93,7 @@ impl ShowWidget { } } -fn on_unsub_button_clicked( - shows: Rc, - epstack: Rc, - pd: &Podcast, - unsub_button: >k::Button, -) { +fn on_unsub_button_clicked(shows: Rc, pd: &Podcast, unsub_button: >k::Button) { let res = dbqueries::remove_feed(pd); if res.is_ok() { info!("{} was removed succesfully.", pd.title()); @@ -128,8 +110,6 @@ fn on_unsub_button_clicked( }; } shows.switch_podcasts_animated(); - shows.update_podcasts(); - epstack.update(); } #[allow(dead_code)] From ce08d49107f38d2a8093d7dc481b582ffa86e2b8 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 29 Dec 2017 22:58:20 +0200 Subject: [PATCH 113/278] Headerbar: Added update indication. --- hammond-gtk/resources/gtk/headerbar.ui | 31 +++++++++++++++++++++ hammond-gtk/resources/gtk/show_widget.ui | 2 +- hammond-gtk/src/app.rs | 9 ++++--- hammond-gtk/src/headerbar.rs | 34 ++++++++++++++++++++---- hammond-gtk/src/utils.rs | 14 ++++++---- 5 files changed, 76 insertions(+), 14 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index dfcc7db..f1450d7 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -159,6 +159,37 @@ 1 + + + False + True + + + False + + + False + True + 6 + 0 + + + + + False + Fetching new episodes + + + False + True + 1 + + + + + 3 + + True diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index cb3aa36..01725ae 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -151,7 +151,7 @@ True center center - app.update + app.refresh diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 200a016..cd953f5 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -66,8 +66,9 @@ impl App { pub fn setup_actions(&self) { let update = gio::SimpleAction::new("update", None); let content = self.content.clone(); + let header = self.header.clone(); update.connect_activate(move |_, _| { - utils::refresh_feed(content.clone(), None); + utils::refresh_feed(content.clone(), header.clone(), None); }); self.app_instance.add_action(&update); @@ -97,23 +98,25 @@ impl App { pub fn setup_timed_callbacks(&self) { let content = self.content.clone(); + let header = self.header.clone(); // Update 30 seconds after the Application is initialized. gtk::timeout_add_seconds( 30, clone!(content => move || { - utils::refresh_feed(content.clone(), None); + utils::refresh_feed(content.clone(), header.clone(), None); glib::Continue(false) }), ); let content = self.content.clone(); + let header = self.header.clone(); // Auto-updater, runs every hour. // TODO: expose the interval in which it run to a user setting. // TODO: show notifications. gtk::timeout_add_seconds( 3600, clone!(content => move || { - utils::refresh_feed(content.clone(), None); + utils::refresh_feed(content.clone(), header.clone(), None); glib::Continue(true) }), ); diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index a399182..983cb5c 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -8,7 +8,7 @@ use std::rc::Rc; use utils; use content::Content; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct Header { pub container: gtk::HeaderBar, add_toggle: gtk::MenuButton, @@ -16,6 +16,9 @@ pub struct Header { switch: gtk::StackSwitcher, back_button: gtk::Button, show_title: gtk::Label, + update_box: gtk::Box, + update_label: gtk::Label, + update_spinner: gtk::Spinner, } impl Default for Header { @@ -28,6 +31,9 @@ impl Default for Header { let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); let back_button: gtk::Button = builder.get_object("back_button").unwrap(); let show_title: gtk::Label = builder.get_object("show_title").unwrap(); + let update_box: gtk::Box = builder.get_object("update_notification").unwrap(); + let update_label: gtk::Label = builder.get_object("update_label").unwrap(); + let update_spinner: gtk::Spinner = builder.get_object("update_spinner").unwrap(); Header { container: header, @@ -36,6 +42,9 @@ impl Default for Header { switch, back_button, show_title, + update_box, + update_label, + update_spinner, } } } @@ -61,8 +70,9 @@ impl Header { println!("{:?}", url.get_text()); }); - add_button.connect_clicked(clone!(content, add_popover, new_url => move |_| { - on_add_bttn_clicked(content.clone(), &new_url); + let header = Rc::new(self.clone()); + add_button.connect_clicked(clone!(content, header, add_popover, new_url => move |_| { + on_add_bttn_clicked(content.clone(), header.clone(), &new_url); // TODO: lock the button instead of hiding and add notification of feed added. // TODO: map the spinner @@ -104,16 +114,30 @@ impl Header { pub fn set_show_title(&self, title: &str) { self.show_title.set_text(title) } + + pub fn show_update_notification(&self) { + self.update_spinner.start(); + self.update_box.show(); + self.update_spinner.show(); + self.update_label.show(); + } + + pub fn hide_update_notification(&self) { + self.update_spinner.stop(); + self.update_box.hide(); + self.update_spinner.hide(); + self.update_label.hide(); + } } -fn on_add_bttn_clicked(content: Rc, entry: >k::Entry) { +fn on_add_bttn_clicked(content: Rc, headerbar: Rc
, entry: >k::Entry) { let url = entry.get_text().unwrap_or_default(); let source = Source::from_url(&url); if let Ok(s) = source { info!("{:?} feed added", url); // update the db - utils::refresh_feed(content, Some(vec![s])); + utils::refresh_feed(content, headerbar, Some(vec![s])); } else { error!("Feed probably already exists."); error!("Error: {:?}", source.unwrap_err()); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 7bb3853..26c236d 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -14,8 +14,9 @@ use std::rc::Rc; use std::collections::HashMap; use content::Content; +use headerbar::Header; -type Foo = RefCell, Receiver)>>; +type Foo = RefCell, Rc
, Receiver)>>; // Create a thread local storage that will store the arguments to be transfered. thread_local!(static GLOBAL: Foo = RefCell::new(None)); @@ -24,13 +25,15 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None)); /// If `source` is None, Fetches all the `Source` entries in the database and updates them. /// `delay` represents the desired time in seconds for the thread to sleep before executing. /// When It's done,it queues up a `podcast_view` refresh. -pub fn refresh_feed(content: Rc, source: Option>) { +pub fn refresh_feed(content: Rc, headerbar: Rc
, source: Option>) { + headerbar.show_update_notification(); + // Create a async channel. let (sender, receiver) = channel(); // Pass the desired arguments into the Local Thread Storage. - GLOBAL.with(clone!(content => move |global| { - *global.borrow_mut() = Some((content.clone(), receiver)); + GLOBAL.with(clone!(content, headerbar => move |global| { + *global.borrow_mut() = Some((content.clone(), headerbar.clone(), receiver)); })); thread::spawn(move || { @@ -51,9 +54,10 @@ pub fn refresh_feed(content: Rc, source: Option>) { fn refresh_everything() -> glib::Continue { GLOBAL.with(|global| { - if let Some((ref content, ref reciever)) = *global.borrow() { + if let Some((ref content, ref headerbar, ref reciever)) = *global.borrow() { if reciever.try_recv().is_ok() { content.update(); + headerbar.hide_update_notification(); } } }); From 4894683924dbfa9b4b6b2e943e7552bbb3afd6e4 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 30 Dec 2017 18:12:53 +0200 Subject: [PATCH 114/278] hammond-gtk: Set the default theme to the dark variant for now. --- hammond-gtk/src/main.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index e58a0b3..622cd10 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -72,5 +72,11 @@ fn main() { 600, ); + // This set's the app to dark mode. + // It wiil be in the user's preference later but for now + // I will abuse my power and force it on everyone till then :P. + let settings = gtk::Settings::get_default().unwrap(); + settings.set_property_gtk_application_prefer_dark_theme(true); + App::new().run(); } From 5730e71e2a83bbfb80525c16b68132e1e278871f Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 30 Dec 2017 20:54:23 +0200 Subject: [PATCH 115/278] Clear TODO and FIXME that are no longer releavant. --- README.md | 2 +- hammond-data/src/models/queryables.rs | 4 ---- hammond-data/src/parser.rs | 1 - hammond-gtk/src/app.rs | 5 ++++- hammond-gtk/src/headerbar.rs | 3 --- hammond-gtk/src/views/episodes.rs | 1 - hammond-gtk/src/views/shows.rs | 1 - 7 files changed, 5 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 4d25ca6..12e4c93 100644 --- a/README.md +++ b/README.md @@ -99,7 +99,7 @@ $ tree -d │   ├── resources # GResources folder │   │   └── gtk # Contains the glade.ui files. │   └── src -│   ├── views # Currently only contains the Podcasts_view. +│   ├── views # Currently only contains the Empty and Episodes views. │   └── widgets # Contains custom widgets such as Podcast and Episode. ``` diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index b83ba52..99672bc 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -612,7 +612,6 @@ impl<'a> Source { let etag = headers.get::(); let lmod = headers.get::(); - // FIXME: This dsnt work most of the time apparently if self.http_etag() != etag.map(|x| x.tag()) || self.last_modified != lmod.map(|x| { format!("{}", x) }) { @@ -659,9 +658,6 @@ impl<'a> Source { } } - // FIXME: I have fucked up somewhere here. - // Getting back 200 codes even though I supposedly sent etags. - // info!("Headers: {:?}", headers); let client = reqwest::Client::builder().referer(false).build()?; let mut req = client.get(self.uri()).headers(headers).send()?; diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index ecb610c..c5e4f4d 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -8,7 +8,6 @@ use utils::replace_extra_spaces; use errors::*; -// TODO: Extend the support for parsing itunes extensions /// Parses a `rss::Channel` into a `NewPodcast` Struct. pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast { let title = chan.title().trim(); diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index cd953f5..99415d9 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -64,6 +64,7 @@ impl App { } pub fn setup_actions(&self) { + // Updates the database and refreshes every view. let update = gio::SimpleAction::new("update", None); let content = self.content.clone(); let header = self.header.clone(); @@ -72,6 +73,7 @@ impl App { }); self.app_instance.add_action(&update); + // Refreshes the `Content` let refresh = gio::SimpleAction::new("refresh", None); let content = self.content.clone(); refresh.connect_activate(move |_, _| { @@ -79,6 +81,7 @@ impl App { }); self.app_instance.add_action(&refresh); + // Refreshes the `EpisodesStack` let refresh_episodes = gio::SimpleAction::new("refresh_episodes", None); let content = self.content.clone(); refresh_episodes.connect_activate(move |_, _| { @@ -88,6 +91,7 @@ impl App { }); self.app_instance.add_action(&refresh_episodes); + // Refreshes the `ShowStack` let refresh_shows = gio::SimpleAction::new("refresh_shows", None); let content = self.content.clone(); refresh_shows.connect_activate(move |_, _| { @@ -143,7 +147,6 @@ impl App { fn build_ui(window: >k::Window, app: >k::Application) { window.set_application(app); - window.show_all(); window.activate(); app.connect_activate(move |_| ()); diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 983cb5c..8f4c38e 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -73,9 +73,6 @@ impl Header { let header = Rc::new(self.clone()); add_button.connect_clicked(clone!(content, header, add_popover, new_url => move |_| { on_add_bttn_clicked(content.clone(), header.clone(), &new_url); - - // TODO: lock the button instead of hiding and add notification of feed added. - // TODO: map the spinner add_popover.hide(); })); diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 2312d15..7a4d794 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -193,7 +193,6 @@ impl EpisodesViewWidget { let container: gtk::Box = builder.get_object("container").unwrap(); let image: gtk::Image = builder.get_object("cover").unwrap(); - // FIXME: if let Ok(pd) = dbqueries::get_podcast_cover_from_id(episode.podcast_id()) { let img = get_pixbuf_from_path(&pd, 64); if let Some(i) = img { diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index acd1022..46b2865 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -44,7 +44,6 @@ impl ShowsPopulated { use gtk::WidgetExt; // TODO: handle unwraps. - // TODO: implement back button. self.flowbox .connect_child_activated(clone!(show => move |_, child| { // This is such an ugly hack... From 3c84d889fd9e1da7c1cd78df5e4d9ff211bd1a44 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 30 Dec 2017 21:19:29 +0200 Subject: [PATCH 116/278] Headerbar: Do more stuff through glade, cut some code. --- hammond-gtk/resources/gtk/headerbar.ui | 20 ++++++++++---------- hammond-gtk/src/headerbar.rs | 7 ------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index f1450d7..9183a43 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -6,6 +6,8 @@ False Add a new feed center + add_toggle + bottom True @@ -123,6 +125,7 @@ False Add a new feed center + add_popover True @@ -230,8 +233,8 @@ True True False - Add a new feed center + menu_popover True @@ -250,8 +253,9 @@ - + False + menu_toggle True @@ -265,7 +269,7 @@ True False - False + True False Preferences @@ -304,7 +308,7 @@ True False - False + True False About @@ -318,7 +322,7 @@ True False - False + True False Help @@ -332,7 +336,7 @@ True False - False + True False Keyboard Shortcuts @@ -343,10 +347,6 @@ - - submenu0 - 1 - diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 8f4c38e..2244c0c 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -12,7 +12,6 @@ use content::Content; pub struct Header { pub container: gtk::HeaderBar, add_toggle: gtk::MenuButton, - menu_toggle: gtk::MenuButton, switch: gtk::StackSwitcher, back_button: gtk::Button, show_title: gtk::Label, @@ -27,7 +26,6 @@ impl Default for Header { let header: gtk::HeaderBar = builder.get_object("headerbar").unwrap(); let add_toggle: gtk::MenuButton = builder.get_object("add_toggle").unwrap(); - let menu_toggle: gtk::MenuButton = builder.get_object("menu_toggle").unwrap(); let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); let back_button: gtk::Button = builder.get_object("back_button").unwrap(); let show_title: gtk::Label = builder.get_object("show_title").unwrap(); @@ -38,7 +36,6 @@ impl Default for Header { Header { container: header, add_toggle, - menu_toggle, switch, back_button, show_title, @@ -61,7 +58,6 @@ impl Header { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let add_popover: gtk::Popover = builder.get_object("add_popover").unwrap(); - let menu_popover: gtk::PopoverMenu = builder.get_object("menu_popover").unwrap(); let new_url: gtk::Entry = builder.get_object("new_url").unwrap(); let add_button: gtk::Button = builder.get_object("add_button").unwrap(); self.switch.set_stack(&content.get_stack()); @@ -76,9 +72,6 @@ impl Header { add_popover.hide(); })); - self.add_toggle.set_popover(&add_popover); - self.menu_toggle.set_popover(&menu_popover); - let switch = &self.switch; let add_toggle = &self.add_toggle; let show_title = &self.show_title; From 963ff212adf94de522224ab062d1976787630caf Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 30 Dec 2017 21:56:44 +0200 Subject: [PATCH 117/278] hammond-gtk: Add some tooltips. Closes #13. --- hammond-gtk/resources/gtk/episode_widget.ui | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 3660ebb..66fc8f6 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -194,6 +194,7 @@ True True True + Download this episode end center app.refresh_episodes @@ -218,6 +219,7 @@ True True True + Play this episode center app.refresh_episodes From e727734443e1169aed6f17bb8b81e095401d08bc Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 30 Dec 2017 22:23:10 +0200 Subject: [PATCH 118/278] DB Schema: Remove episode.published_date column. --- .../down.sql | 24 +++++++++++++++++++ .../up.sql | 23 ++++++++++++++++++ hammond-data/src/models/insertables.rs | 5 ---- hammond-data/src/models/queryables.rs | 11 --------- hammond-data/src/parser.rs | 10 -------- hammond-data/src/schema.rs | 1 - 6 files changed, 47 insertions(+), 27 deletions(-) create mode 100644 hammond-data/migrations/2017-12-30-201631_remove_published_date/down.sql create mode 100644 hammond-data/migrations/2017-12-30-201631_remove_published_date/up.sql diff --git a/hammond-data/migrations/2017-12-30-201631_remove_published_date/down.sql b/hammond-data/migrations/2017-12-30-201631_remove_published_date/down.sql new file mode 100644 index 0000000..e5ec3e3 --- /dev/null +++ b/hammond-data/migrations/2017-12-30-201631_remove_published_date/down.sql @@ -0,0 +1,24 @@ +ALTER TABLE episode RENAME TO old_table; + +CREATE TABLE episode ( + title TEXT NOT NULL, + uri TEXT, + local_uri TEXT, + description TEXT, + published_date TEXT, + epoch INTEGER NOT NULL DEFAULT 0, + length INTEGER, + duration INTEGER, + guid TEXT, + played INTEGER, + podcast_id INTEGER NOT NULL, + favorite INTEGER DEFAULT 0, + archive INTEGER DEFAULT 0, + PRIMARY KEY (title, podcast_id) +); + +INSERT INTO episode (title, uri, local_uri, description, epoch, length, duration, guid, played, favorite, archive, podcast_id) +SELECT title, uri, local_uri, description, epoch, length, duration, guid, played, favorite, archive, podcast_id +FROM old_table; + +Drop table old_table; \ No newline at end of file diff --git a/hammond-data/migrations/2017-12-30-201631_remove_published_date/up.sql b/hammond-data/migrations/2017-12-30-201631_remove_published_date/up.sql new file mode 100644 index 0000000..2723e95 --- /dev/null +++ b/hammond-data/migrations/2017-12-30-201631_remove_published_date/up.sql @@ -0,0 +1,23 @@ +ALTER TABLE episode RENAME TO old_table; + +CREATE TABLE episode ( + title TEXT NOT NULL, + uri TEXT, + local_uri TEXT, + description TEXT, + epoch INTEGER NOT NULL DEFAULT 0, + length INTEGER, + duration INTEGER, + guid TEXT, + played INTEGER, + podcast_id INTEGER NOT NULL, + favorite INTEGER DEFAULT 0, + archive INTEGER DEFAULT 0, + PRIMARY KEY (title, podcast_id) +); + +INSERT INTO episode (title, uri, local_uri, description, epoch, length, duration, guid, played, favorite, archive, podcast_id) +SELECT title, uri, local_uri, description, epoch, length, duration, guid, played, favorite, archive, podcast_id +FROM old_table; + +Drop table old_table; \ No newline at end of file diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index 6e6d5b1..8f2689a 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -158,7 +158,6 @@ pub(crate) struct NewEpisode { title: String, uri: Option, description: Option, - published_date: Option, length: Option, duration: Option, guid: Option, @@ -234,10 +233,6 @@ impl NewEpisode { self.description.as_ref().map(|s| s.as_str()) } - pub(crate) fn published_date(&self) -> Option<&str> { - self.published_date.as_ref().map(|s| s.as_str()) - } - pub(crate) fn guid(&self) -> Option<&str> { self.guid.as_ref().map(|s| s.as_str()) } diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 99672bc..d1a9cc0 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -30,7 +30,6 @@ pub struct Episode { uri: Option, local_uri: Option, description: Option, - published_date: Option, epoch: i32, length: Option, duration: Option, @@ -92,16 +91,6 @@ impl Episode { self.description = value.map(|x| x.to_string()); } - /// Get the the `published_date`. - pub fn published_date(&self) -> Option<&str> { - self.published_date.as_ref().map(|s| s.as_str()) - } - - /// Set the `published_date`. - pub fn set_published_date(&mut self, value: Option<&str>) { - self.published_date = value.map(|x| x.to_string().to_owned()); - } - /// Get the value of the `description`. pub fn guid(&self) -> Option<&str> { self.guid.as_ref().map(|s| s.as_str()) diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index c5e4f4d..0bfa5e9 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -71,7 +71,6 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { // Should treat information from the rss feeds as invalid by default. // Case: Thu, 05 Aug 2016 06:00:00 -0400 <-- Actually that was friday. - let pub_date = date.map(|x| x.to_rfc2822()).ok(); let epoch = date.map(|x| x.timestamp() as i32).unwrap_or(0); let length = || -> Option { item.enclosure().map(|x| x.length().parse().ok())? }(); @@ -83,7 +82,6 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { .description(description) .length(length) .duration(duration) - .published_date(pub_date) .epoch(epoch) .guid(guid) .podcast_id(parent_id) @@ -241,7 +239,6 @@ mod tests { ))) .description(Some(String::from(descr))) .guid(Some(String::from("7df4070a-9832-11e7-adac-cb37b05d5e24"))) - .published_date(Some(String::from("Wed, 13 Sep 2017 10:00:00 +0000"))) .length(Some(66738886)) .epoch(1505296800) .duration(Some(4171)) @@ -269,7 +266,6 @@ mod tests { ))) .description(Some(String::from(descr))) .guid(Some(String::from("7c207a24-e33f-11e6-9438-eb45dcf36a1d"))) - .published_date(Some(String::from("Wed, 9 Aug 2017 10:00:00 +0000"))) .length(Some(67527575)) .epoch(1502272800) .duration(Some(4220)) @@ -296,7 +292,6 @@ mod tests { .description(Some(String::from(descr))) .guid(Some(String::from("https://www.propublica.org/podcast/\ the-breakthrough-hopelessness-exploitation-homes-for-mentally-ill#134472"))) - .published_date(Some(String::from("Fri, 8 Sep 2017 12:00:00 +0000"))) .length(Some(33396551)) .epoch(1504872000) .duration(Some(1670)) @@ -326,7 +321,6 @@ mod tests { "https://www.propublica.\ org/podcast/the-breakthrough-hillary-clinton-failed-presidential-bid#133721", ))) - .published_date(Some(String::from("Fri, 25 Aug 2017 12:00:00 +0000"))) .length(Some(17964071)) .epoch(1503662400) .duration(Some(1125)) @@ -355,7 +349,6 @@ mod tests { ))) .description(Some(String::from(descr))) .guid(Some(String::from("78A682B4-73E8-47B8-88C0-1BE62DD4EF9D"))) - .published_date(Some(String::from("Tue, 12 Sep 2017 22:24:42 -0700"))) .length(Some(46479789)) .epoch(1505280282) .duration(Some(5733)) @@ -381,7 +374,6 @@ mod tests { ))) .description(Some(String::from(descr))) .guid(Some(String::from("1CE57548-B36C-4F14-832A-5D5E0A24E35B"))) - .published_date(Some(String::from("Tue, 5 Sep 2017 20:57:27 -0700"))) .length(Some(36544272)) .epoch(1504670247) .duration(Some(4491)) @@ -411,7 +403,6 @@ mod tests { .guid(Some(String::from( "https://request-for-explanation.github.io/podcast/ep9-a-once-in-a-lifetime-rfc/", ))) - .published_date(Some(String::from("Mon, 28 Aug 2017 15:00:00 -0700"))) .length(Some(15077388)) .epoch(1503957600) .duration(Some(2533)) @@ -437,7 +428,6 @@ mod tests { .guid(Some(String::from( "https://request-for-explanation.github.io/podcast/ep8-an-existential-crisis/", ))) - .published_date(Some(String::from("Tue, 15 Aug 2017 17:00:00 -0700"))) .length(Some(13713219)) .epoch(1502841600) .duration(Some(2313)) diff --git a/hammond-data/src/schema.rs b/hammond-data/src/schema.rs index 6389143..d50a2f5 100644 --- a/hammond-data/src/schema.rs +++ b/hammond-data/src/schema.rs @@ -5,7 +5,6 @@ table! { uri -> Nullable, local_uri -> Nullable, description -> Nullable, - published_date -> Nullable, epoch -> Integer, length -> Nullable, duration -> Nullable, From 785a5f80c68c3baaf03701b40eb3d585cb820a7d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 31 Dec 2017 01:42:28 +0200 Subject: [PATCH 119/278] hammond-data::utils: Small and minor refactor. --- hammond-data/src/feed.rs | 2 +- hammond-data/src/utils.rs | 49 +++++++++++++++------------------------ 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index efc77cb..750c4a0 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -74,7 +74,7 @@ impl Feed { fn parse_channel_items(&self, pd: &Podcast) -> Vec { let items = self.channel.items(); let new_episodes: Vec<_> = items - .into_par_iter() + .par_iter() .filter_map(|item| parser::new_episode(item, *pd.id()).ok()) .collect(); diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index 07dc34d..d6c7cfd 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -18,43 +18,38 @@ fn download_checker() -> Result<()> { episodes .into_par_iter() - .for_each(|mut ep| checker_helper(&mut ep)); + .filter(|ep| !Path::new(ep.local_uri().unwrap()).exists()) + .for_each(|mut ep| { + ep.set_local_uri(None); + if let Err(err) = ep.save() { + error!("Error while trying to update episode: {:#?}", ep); + error!("Error: {}", err); + }; + }); Ok(()) } -fn checker_helper(ep: &mut EpisodeCleanerQuery) { - if !Path::new(ep.local_uri().unwrap()).exists() { - ep.set_local_uri(None); - let res = ep.save(); - if let Err(err) = res { - error!("Error while trying to update episode: {:#?}", ep); - error!("Error: {}", err); - }; - } -} - fn played_cleaner() -> Result<()> { - let episodes = dbqueries::get_played_cleaner_episodes()?; + let mut episodes = dbqueries::get_played_cleaner_episodes()?; let now_utc = Utc::now().timestamp() as i32; - episodes.into_par_iter().for_each(|mut ep| { - if ep.local_uri().is_some() && ep.played().is_some() { - let played = ep.played().unwrap(); + episodes + .par_iter_mut() + .filter(|ep| ep.local_uri().is_some() && ep.played().is_some()) + .for_each(|ep| { // TODO: expose a config and a user set option. // Chnage the test too when exposed - let limit = played + 172_800; // add 2days in seconds + let limit = ep.played().unwrap() + 172_800; // add 2days in seconds if now_utc > limit { - let e = delete_local_content(&mut ep); - if let Err(err) = e { + if let Err(err) = delete_local_content(ep) { error!("Error while trying to delete file: {:?}", ep.local_uri()); error!("Error: {}", err); } else { info!("Episode {:?} was deleted succesfully.", ep.local_uri()); }; } - } - }); + }); Ok(()) } @@ -186,20 +181,14 @@ mod tests { Some(valid_path.to_str().unwrap()), episodes.first().unwrap().local_uri() ); - } - #[test] - fn test_checker_helper() { let _tmp_dir = helper_db(); - let mut episode = { + download_checker().unwrap(); + let episode = { let db = connection(); let con = db.get().unwrap(); - dbqueries::get_episode_from_pk(&con, "bar_baz", 1) - .unwrap() - .into() + dbqueries::get_episode_from_pk(&con, "bar_baz", 1).unwrap() }; - - checker_helper(&mut episode); assert!(episode.local_uri().is_none()); } From a3cd76dbf888791278e6edba09a96b368bd2c735 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 31 Dec 2017 03:59:48 +0200 Subject: [PATCH 120/278] hammond-downloader: Use glob Insead of hardcoded file extensions. --- Cargo.lock | 15 +++++++--- hammond-downloader/Cargo.toml | 1 + hammond-downloader/src/downloader.rs | 44 +++++++++++++--------------- hammond-downloader/src/lib.rs | 1 + 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d33e5d..3e8538e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -410,7 +410,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -519,6 +519,11 @@ dependencies = [ "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "glob" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "gobject-sys" version = "0.5.0" @@ -602,6 +607,7 @@ version = "0.1.0" dependencies = [ "diesel 0.99.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hammond-data 0.1.0", "hyper 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1010,7 +1016,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1188,7 +1194,7 @@ dependencies = [ "coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1795,6 +1801,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum gio-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a303bbf7a5e75ab3b627117ff10e495d1b9e97e1d68966285ac2b1f6270091bc" "checksum glib 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "450247060df7d52fdad31e1d66f30d967e925c9d1d26a0ae050cfe33dcd00d08" "checksum glib-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9693049613ff52b93013cc3d2590366d8e530366d288438724b73f6c7dc4be8" +"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb" "checksum gobject-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60d507c87a71b1143c66ed21a969be9b99a76df234b342d733e787e6c9c7d7c2" "checksum gtk 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0847c507e52c1feaede13ef56fb4847742438602655449d5f1f782e8633f146f" "checksum gtk-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "905fcfbaaad1b44ec0b4bba9e4d527d728284c62bc2ba41fccedace2b096766f" @@ -1839,7 +1846,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" -"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" +"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" "checksum openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "169a4b9160baf9b9b1ab975418c673686638995ba921683a7f1e01470dcb8854" "checksum openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "2200ffec628e3f14c39fc0131a301db214f1a7d584e36507ee8700b0c7fb7a46" diff --git a/hammond-downloader/Cargo.toml b/hammond-downloader/Cargo.toml index efb8754..7116ab7 100644 --- a/hammond-downloader/Cargo.toml +++ b/hammond-downloader/Cargo.toml @@ -11,6 +11,7 @@ log = "0.3.8" mime_guess = "1.8.3" reqwest = "0.8.2" tempdir = "0.3.5" +glob = "0.2.11" [dependencies.diesel] features = ["sqlite"] diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 7df62b6..fc6220a 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -2,6 +2,7 @@ use reqwest; use hyper::header::*; use tempdir::TempDir; use mime_guess; +use glob::glob; use std::fs::{rename, DirBuilder, File}; use std::io::{BufWriter, Read, Write}; @@ -43,7 +44,8 @@ fn download_into(dir: &str, file_title: &str, url: &str) -> Result { info!("Extension: {}", ext); // Construct a temp file to save desired content. - let tempdir = TempDir::new_in(dir, "")?; + // It has to be a `new_in` instead of new cause rename can't move cross filesystems. + let tempdir = TempDir::new_in(dir, "temp_download")?; let out_file = format!("{}/temp.part", tempdir.path().to_str().unwrap(),); @@ -151,21 +153,13 @@ pub fn cache_image(pd: &PodcastCoverQuery) -> Option { pd.title().to_owned() ); - // Hacky way - // TODO: make it so it returns the first cover.* file encountered. - // Use glob instead - let png = format!("{}/cover.png", download_fold); - let jpg = format!("{}/cover.jpg", download_fold); - let jpe = format!("{}/cover.jpe", download_fold); - let jpeg = format!("{}/cover.jpeg", download_fold); - if Path::new(&png).exists() { - return Some(png); - } else if Path::new(&jpe).exists() { - return Some(jpe); - } else if Path::new(&jpg).exists() { - return Some(jpg); - } else if Path::new(&jpeg).exists() { - return Some(jpeg); + // Weird glob magic. + if let Ok(mut foo) = glob(&format!("{}/cover.*", download_fold)) { + // For some reason there is no .first() method so nth(0) is used + let path = foo.nth(0).and_then(|x| x.ok()); + if let Some(p) = path { + return Some(p.to_str()?.into()); + } }; DirBuilder::new() @@ -173,14 +167,16 @@ pub fn cache_image(pd: &PodcastCoverQuery) -> Option { .create(&download_fold) .unwrap(); - let dlpath = download_into(&download_fold, "cover", &url); - if let Ok(path) = dlpath { - info!("Cached img into: {}", &path); - Some(path) - } else { - error!("Failed to get feed image."); - error!("Error: {}", dlpath.unwrap_err()); - None + match download_into(&download_fold, "cover", &url) { + Ok(path) => { + info!("Cached img into: {}", &path); + Some(path) + } + Err(err) => { + error!("Failed to get feed image."); + error!("Error: {}", err); + None + } } } diff --git a/hammond-downloader/src/lib.rs b/hammond-downloader/src/lib.rs index 98f6678..9e57db8 100644 --- a/hammond-downloader/src/lib.rs +++ b/hammond-downloader/src/lib.rs @@ -3,6 +3,7 @@ extern crate diesel; #[macro_use] extern crate error_chain; +extern crate glob; extern crate hammond_data; extern crate hyper; #[macro_use] From a3c204a02d1c32bd861e5d970b4decf67784ab88 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 1 Jan 2018 00:42:14 +0200 Subject: [PATCH 121/278] Headerbar: Fix add popup. --- hammond-gtk/resources/gtk/headerbar.ui | 1 - hammond-gtk/src/headerbar.rs | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index 9183a43..68c4541 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -125,7 +125,6 @@ False Add a new feed center - add_popover True diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 2244c0c..3b5f17e 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -72,6 +72,8 @@ impl Header { add_popover.hide(); })); + self.add_toggle.set_popover(&add_popover); + let switch = &self.switch; let add_toggle = &self.add_toggle; let show_title = &self.show_title; From e42353e03f62ed0e77484a1e7883d94bfb5dc12a Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 1 Jan 2018 00:46:31 +0200 Subject: [PATCH 122/278] cargo update --- Cargo.lock | 74 +++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2d33e5d..c6a9339 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,7 +206,7 @@ dependencies = [ [[package]] name = "crc" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -310,7 +310,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -410,7 +410,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -630,7 +630,7 @@ dependencies = [ "loggerv 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -778,7 +778,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crc 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -795,12 +795,12 @@ name = "log" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "log" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -846,9 +846,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "tendril 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1010,7 +1010,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "num_cpus" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1140,7 +1140,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1188,7 +1188,7 @@ dependencies = [ "coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1207,19 +1207,19 @@ dependencies = [ [[package]] name = "regex" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "regex-syntax" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1243,8 +1243,8 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1260,7 +1260,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1355,22 +1355,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_derive" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive_internals 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "serde_derive_internals" -version = "0.18.1" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1379,13 +1379,13 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1395,7 +1395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1428,7 +1428,7 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1442,7 +1442,7 @@ dependencies = [ "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", "precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1761,7 +1761,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" -"checksum crc 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "64d4a687c40efbc7d376958117b34d5f1cece11709110a742405bf58e7a34f00" +"checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7" "checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" "checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" @@ -1817,7 +1817,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum libflate 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6e0ae8f2ea4a426e1af2c2c1ba5696bd597368afe5068f9485fc960973fe6dfb" "checksum libsqlite3-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "370090ad578ba845a3ad4f383ceb3deba7abd51ab1915ad1f2c982cc6035e31c" "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3a89a0c46ba789b8a247d4c567aed4d7c68e624672d238b45cc3ec20dc9f940" +"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" "checksum loggerv 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b178879253fab6ddb4ea931e1e6f514d45ce6a53f7fe618a0a8751f43e42e4f1" "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" "checksum maplit 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ed95049d40b8a1a7691adbabca028ad481f7e6a2921ce4846e1ee168b4e4ca5" @@ -1839,7 +1839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-integer 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "d1452e8b06e448a07f0e6ebb0bb1d92b8890eea63288c0b627331d53514d0fba" "checksum num-iter 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "7485fcc84f85b4ecd0ea527b14189281cf27d60e583ae65ebc9c088b13dffe01" "checksum num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "cacfcab5eb48250ee7d0c7896b51a2c5eec99c1feea5f32025635f5ae4b00070" -"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d" +"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" "checksum openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "169a4b9160baf9b9b1ab975418c673686638995ba921683a7f1e01470dcb8854" "checksum openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "2200ffec628e3f14c39fc0131a301db214f1a7d584e36507ee8700b0c7fb7a46" @@ -1862,8 +1862,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" "checksum redox_syscall 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)" = "07b8f011e3254d5a9b318fde596d409a0001c9ae4c6e7907520c2eaa4d988c99" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ac6ab4e9218ade5b423358bbd2567d1617418403c7a512603630181813316322" -"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" +"checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" +"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" "checksum reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3161ca63fd11ce36c7718af239e6492a25a3dbfcec54240f959b9d816cf42413" "checksum rfc822_sanitizer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "680e8305c1e0cdf836dc4bec5424e045f278c975a3cac36d1ca01c4695f9d815" @@ -1879,10 +1879,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" "checksum send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c620dd7e056b468b9d374a9f51cfa6bb4bf17a8ca4ee62e5efa0d99aaff2c41" -"checksum serde 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "d1d6af49db29f2f2678e442f4eb82e7d78f59dbbd3e373ccffc17fe70c1b94f8" -"checksum serde_derive 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "95b4ea937d8dff4c94d1a6fdd710eade6aedaa17c4049da29bb97a4f8a4f4bc1" -"checksum serde_derive_internals 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "730fe9f29fe8db69a601837f416e46cba07792031ed6b27557a43e49d62d89ae" -"checksum serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf5b0b5b4bd22eeecb7e01ac2e1225c7ef5e4272b79ee28a8392a8c8489c839" +"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526" +"checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0" +"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5" +"checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb" "checksum serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce0fd303af908732989354c6f02e05e2e6d597152870f2c6990efb0577137480" "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537" "checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23" From b32f448957f3ffd8c6c0a8c16375c1112cb26aff Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 1 Jan 2018 16:36:15 +0200 Subject: [PATCH 123/278] When downloading an episode, set it's title to rowid instead of it's title. --- Cargo.lock | 1 + hammond-downloader/Cargo.toml | 1 + hammond-downloader/src/downloader.rs | 15 +++++++-------- hammond-downloader/src/lib.rs | 2 ++ 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e8538e..900c1e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -610,6 +610,7 @@ dependencies = [ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hammond-data 0.1.0", "hyper 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/hammond-downloader/Cargo.toml b/hammond-downloader/Cargo.toml index 7116ab7..cb7d6f5 100644 --- a/hammond-downloader/Cargo.toml +++ b/hammond-downloader/Cargo.toml @@ -12,6 +12,7 @@ mime_guess = "1.8.3" reqwest = "0.8.2" tempdir = "0.3.5" glob = "0.2.11" +lazy_static = "1.0.0" [dependencies.diesel] features = ["sqlite"] diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index fc6220a..14a205d 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -34,7 +34,6 @@ fn download_into(dir: &str, file_title: &str, url: &str) -> Result { } let headers = resp.headers().clone(); - let ct_len = headers.get::().map(|ct_len| **ct_len); let ct_type = headers.get::(); ct_len.map(|x| info!("File Lenght: {}", x)); @@ -46,7 +45,6 @@ fn download_into(dir: &str, file_title: &str, url: &str) -> Result { // Construct a temp file to save desired content. // It has to be a `new_in` instead of new cause rename can't move cross filesystems. let tempdir = TempDir::new_in(dir, "temp_download")?; - let out_file = format!("{}/temp.part", tempdir.path().to_str().unwrap(),); // Save requested content into the file. @@ -60,7 +58,7 @@ fn download_into(dir: &str, file_title: &str, url: &str) -> Result { Ok(target) } -// Determine the file extension from the http content-type header. +/// Determine the file extension from the http content-type header. fn get_ext(content: Option) -> Option { let cont = content.clone()?; content @@ -121,7 +119,7 @@ pub fn get_episode(ep: &mut EpisodeWidgetQuery, download_folder: &str) -> Result ep.save()?; }; - let res = download_into(download_folder, ep.title(), ep.uri().unwrap()); + let res = download_into(download_folder, &ep.rowid().to_string(), ep.uri().unwrap()); if let Ok(path) = res { // If download succedes set episode local_uri to dlpath. @@ -147,14 +145,14 @@ pub fn cache_image(pd: &PodcastCoverQuery) -> Option { return None; } - let download_fold = format!( + let cache_download_fold = format!( "{}{}", HAMMOND_CACHE.to_str().unwrap(), pd.title().to_owned() ); // Weird glob magic. - if let Ok(mut foo) = glob(&format!("{}/cover.*", download_fold)) { + if let Ok(mut foo) = glob(&format!("{}/cover.*", cache_download_fold)) { // For some reason there is no .first() method so nth(0) is used let path = foo.nth(0).and_then(|x| x.ok()); if let Some(p) = path { @@ -162,12 +160,13 @@ pub fn cache_image(pd: &PodcastCoverQuery) -> Option { } }; + // Create the folders if they don't exist. DirBuilder::new() .recursive(true) - .create(&download_fold) + .create(&cache_download_fold) .unwrap(); - match download_into(&download_fold, "cover", &url) { + match download_into(&cache_download_fold, "cover", &url) { Ok(path) => { info!("Cached img into: {}", &path); Some(path) diff --git a/hammond-downloader/src/lib.rs b/hammond-downloader/src/lib.rs index 9e57db8..ef75fa5 100644 --- a/hammond-downloader/src/lib.rs +++ b/hammond-downloader/src/lib.rs @@ -7,6 +7,8 @@ extern crate glob; extern crate hammond_data; extern crate hyper; #[macro_use] +extern crate lazy_static; +#[macro_use] extern crate log; extern crate mime_guess; extern crate reqwest; From 15b3eb115cd096192506caea592ff285c84ecb0a Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 1 Jan 2018 19:46:27 +0200 Subject: [PATCH 124/278] ShowWidget: Add tooltip to the website button. --- hammond-gtk/src/widgets/show.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 0da781f..0061119 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -82,6 +82,7 @@ impl ShowWidget { } let link = pd.link().to_owned(); + WidgetExt::set_tooltip_text(&self.link, Some(link.as_str())); self.link.connect_clicked(move |_| { info!("Opening link: {}", &link); let _ = open::that(&link); From 37e9b6fbf06cfb14d9987ac28c306cff55990752 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 2 Jan 2018 07:23:53 +0200 Subject: [PATCH 125/278] 'How hard could it be' --- hammond-data/src/database.rs | 3 +- hammond-data/src/lib.rs | 4 +- hammond-data/src/models/queryables.rs | 16 ++++ hammond-downloader/src/downloader.rs | 2 +- hammond-downloader/src/lib.rs | 1 + hammond-downloader/src/manager.rs | 121 ++++++++++++++++++++++++++ hammond-gtk/src/widgets/episode.rs | 1 - 7 files changed, 144 insertions(+), 4 deletions(-) create mode 100644 hammond-downloader/src/manager.rs diff --git a/hammond-data/src/database.rs b/hammond-data/src/database.rs index bb18bda..00454a8 100644 --- a/hammond-data/src/database.rs +++ b/hammond-data/src/database.rs @@ -35,7 +35,8 @@ lazy_static! { static ref DB_PATH: PathBuf = TEMPDIR.path().join("hammond.db"); } -pub(crate) fn connection() -> Pool { +// FIXME: this should not be public +pub fn connection() -> Pool { POOL.clone() } diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index 21b70ac..f9ed95d 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -56,7 +56,9 @@ pub mod utils; pub mod feed; #[allow(missing_docs)] pub mod errors; -pub(crate) mod database; +// FIXME: this should not be public +#[allow(missing_docs)] +pub mod database; pub(crate) mod models; mod parser; mod schema; diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index d1a9cc0..99fc27c 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -215,6 +215,22 @@ pub struct EpisodeWidgetQuery { podcast_id: i32, } +impl From for EpisodeWidgetQuery { + fn from(e: Episode) -> EpisodeWidgetQuery { + EpisodeWidgetQuery { + rowid: e.rowid, + title: e.title, + uri: e.uri, + local_uri: e.local_uri, + epoch: e.epoch, + length: e.length, + duration: e.duration, + played: e.played, + podcast_id: e.podcast_id, + } + } +} + impl EpisodeWidgetQuery { /// Get the value of the sqlite's `ROW_ID` pub fn rowid(&self) -> i32 { diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 14a205d..2f9e721 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -39,7 +39,7 @@ fn download_into(dir: &str, file_title: &str, url: &str) -> Result { ct_len.map(|x| info!("File Lenght: {}", x)); ct_type.map(|x| info!("Content Type: {}", x)); - let ext = get_ext(ct_type.cloned()).unwrap_or(String::from("unkown")); + let ext = get_ext(ct_type.cloned()).unwrap_or(String::from("unknown")); info!("Extension: {}", ext); // Construct a temp file to save desired content. diff --git a/hammond-downloader/src/lib.rs b/hammond-downloader/src/lib.rs index ef75fa5..31cc0b2 100644 --- a/hammond-downloader/src/lib.rs +++ b/hammond-downloader/src/lib.rs @@ -16,3 +16,4 @@ extern crate tempdir; pub mod downloader; pub mod errors; +pub mod manager; diff --git a/hammond-downloader/src/manager.rs b/hammond-downloader/src/manager.rs new file mode 100644 index 0000000..eeb4057 --- /dev/null +++ b/hammond-downloader/src/manager.rs @@ -0,0 +1,121 @@ +use hammond_data::Episode; +use hammond_data::dbqueries; + +use downloader::get_episode; + +use std::collections::HashSet; +use std::sync::{Arc, Mutex}; +use std::path::PathBuf; +use std::thread; + +struct DonwloadInstance { + uri: String, + // FIXME: MAKE ME A PATHBUF + local_uri: Option, + downloaded_bytes: u64, + total_bytes: u64, +} + +impl DonwloadInstance { + fn new(url: &str, total_bytes: u64) -> Self { + DonwloadInstance { + uri: url.into(), + local_uri: None, + downloaded_bytes: 0, + total_bytes, + } + } +} + +struct Manager { + active: Arc>>, +} + +impl Default for Manager { + fn default() -> Self { + Manager { + active: Arc::new(Mutex::new(HashSet::new())), + } + } +} + +impl Manager { + fn new() -> Self { + Manager::default() + } + + fn add(&self, id: i32, directory: &str) { + { + let mut m = self.active.lock().unwrap(); + m.insert(id); + } + + let dir = directory.to_owned(); + let list = self.active.clone(); + thread::spawn(move || { + let episode = dbqueries::get_episode_from_rowid(id).unwrap(); + let e = get_episode(&mut episode.into(), dir.as_str()); + if let Err(err) = e { + error!("Error: {}", err); + }; + + let mut m = list.lock().unwrap(); + m.remove(&id); + }); + } +} + +#[cfg(test)] +mod tests { + use super::*; + use downloader; + + use diesel::Identifiable; + + use hammond_data::database; + use hammond_data::feed::*; + use hammond_data::{Episode, Source}; + use hammond_data::dbqueries; + + use std::path::Path; + use std::{thread, time}; + + #[test] + // This test inserts an rss feed to your `XDG_DATA/hammond/hammond.db` so we make it explicit + // to run it. + #[ignore] + // THIS IS NOT A RELIABLE TEST + // Just quick sanity check + fn test_start_dl() { + let url = "http://www.newrustacean.com/feed.xml"; + + // Create and index a source + let source = Source::from_url(url).unwrap(); + // Copy it's id + let sid = source.id().clone(); + + // Convert Source it into a Feed and index it + let feed = source.into_feed(true).unwrap(); + index(&feed); + + // Get the Podcast + let pd = dbqueries::get_podcast_from_source_id(sid).unwrap(); + // Get an episode + let episode: Episode = { + let con = database::connection(); + dbqueries::get_episode_from_pk(&*con.get().unwrap(), "e000: Hello, world!", *pd.id()) + .unwrap() + }; + + let manager = Manager::new(); + let download_fold = downloader::get_download_folder(&pd.title()).unwrap(); + manager.add(episode.rowid(), download_fold.as_str()); + + // Give it soem time to download the file + thread::sleep(time::Duration::from_secs(20)); + + let final_path = format!("{}/{}.unknown", &download_fold, episode.rowid()); + println!("{}", &final_path); + assert!(Path::new(&final_path).exists()); + } +} diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index ae17d73..ce952be 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -179,7 +179,6 @@ impl EpisodeWidget { } } -// TODO: show notification when dl is finished. fn on_download_clicked( ep: &mut EpisodeWidgetQuery, download_bttn: >k::Button, From c61d322569a8ed5f838656e43bcffee4171d5145 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 2 Jan 2018 08:00:38 +0200 Subject: [PATCH 126/278] EpisodeWidget: Implement shared download state. --- hammond-downloader/src/manager.rs | 10 +++--- hammond-gtk/src/app.rs | 6 ++++ hammond-gtk/src/widgets/episode.rs | 51 +++++++++++++++--------------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/hammond-downloader/src/manager.rs b/hammond-downloader/src/manager.rs index eeb4057..53a914a 100644 --- a/hammond-downloader/src/manager.rs +++ b/hammond-downloader/src/manager.rs @@ -27,8 +27,10 @@ impl DonwloadInstance { } } -struct Manager { - active: Arc>>, +#[derive(Debug, Clone)] +// FIXME: privacy stuff +pub struct Manager { + pub active: Arc>>, } impl Default for Manager { @@ -40,11 +42,11 @@ impl Default for Manager { } impl Manager { - fn new() -> Self { + pub fn new() -> Self { Manager::default() } - fn add(&self, id: i32, directory: &str) { + pub fn add(&self, id: i32, directory: &str) { { let mut m = self.active.lock().unwrap(); m.insert(id); diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 99415d9..35fe044 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -5,12 +5,18 @@ use gtk::prelude::*; use gio::{ActionMapExt, ApplicationExt, ApplicationExtManual, SimpleActionExt}; use hammond_data::utils::checkup; +use hammond_downloader::manager::Manager; use headerbar::Header; use content::Content; use utils; use std::rc::Rc; +use std::sync::{Arc, Mutex}; + +lazy_static! { + pub static ref DOWNLOADS_MANAGER: Arc> = Arc::new(Mutex::new(Manager::new())); +} #[derive(Debug, Clone)] pub struct App { diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index ce952be..a318488 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -13,6 +13,8 @@ use hammond_data::{EpisodeWidgetQuery, Podcast}; use hammond_data::errors::*; use hammond_downloader::downloader; +use app::DOWNLOADS_MANAGER; + use std::thread; use std::cell::RefCell; use std::sync::mpsc::{channel, Receiver}; @@ -105,6 +107,14 @@ impl EpisodeWidget { .map(|c| c.add_class("dim-label")); } + { + let m = DOWNLOADS_MANAGER.lock().unwrap(); + let list = m.active.lock().unwrap(); + if list.contains(&episode.rowid()) { + self.show_progess_bar() + }; + } + // Declare a custom humansize option struct // See: https://docs.rs/humansize/1.0.2/humansize/file_size_opts/struct.FileSizeOpts.html let custom_options = size_opts::FileSizeOpts { @@ -177,6 +187,16 @@ impl EpisodeWidget { ); })); } + + fn show_progess_bar(&self) { + let progress_bar = self.progress.clone(); + timeout_add(200, move || { + progress_bar.pulse(); + glib::Continue(true) + }); + + self.progress.show(); + } } fn on_download_clicked( @@ -194,37 +214,18 @@ fn on_download_clicked( glib::Continue(true) }); - // Create a async channel. - let (sender, receiver) = channel(); - - // Pass the desired arguments into the Local Thread Storage. - GLOBAL.with( - clone!(download_bttn, play_bttn, cancel_bttn, progress => move |global| { - *global.borrow_mut() = Some(( - download_bttn, - play_bttn, - cancel_bttn, - progress, - receiver)); - }), - ); - let pd = dbqueries::get_podcast_from_id(ep.podcast_id()).unwrap(); let pd_title = pd.title().to_owned(); let mut ep = ep.clone(); cancel_bttn.show(); progress.show(); download_bttn.hide(); - thread::spawn(move || { - let download_fold = downloader::get_download_folder(&pd_title).unwrap(); - let e = downloader::get_episode(&mut ep, download_fold.as_str()); - if let Err(err) = e { - error!("Error while trying to download: {:?}", ep.uri()); - error!("Error: {}", err); - }; - sender.send(true).expect("Couldn't send data to channel");; - glib::idle_add(receive); - }); + let download_fold = downloader::get_download_folder(&pd_title).unwrap(); + { + let m = DOWNLOADS_MANAGER.clone(); + let man = m.lock().unwrap(); + man.add(ep.rowid(), &download_fold); + } } fn on_play_bttn_clicked(episode_id: i32) { From c67c6e463ecd959c0f9a35ec7d1542235d1ec9c5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 2 Jan 2018 08:19:24 +0200 Subject: [PATCH 127/278] EpisodeWidget: Its still a mess, but a bit cleaner. --- hammond-gtk/src/widgets/episode.rs | 59 +++++------------------------- 1 file changed, 9 insertions(+), 50 deletions(-) diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index a318488..b0bafbe 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -15,25 +15,8 @@ use hammond_downloader::downloader; use app::DOWNLOADS_MANAGER; -use std::thread; -use std::cell::RefCell; -use std::sync::mpsc::{channel, Receiver}; use std::path::Path; -type Foo = RefCell< - Option< - ( - gtk::Button, - gtk::Button, - gtk::Button, - gtk::ProgressBar, - Receiver, - ), - >, ->; - -thread_local!(static GLOBAL: Foo = RefCell::new(None)); - #[derive(Debug, Clone)] pub struct EpisodeWidget { pub container: gtk::Box, @@ -173,15 +156,13 @@ impl EpisodeWidget { }; })); - let play = &self.play; let cancel = &self.cancel; let progress = self.progress.clone(); self.download - .connect_clicked(clone!(play, episode, cancel, progress => move |dl| { + .connect_clicked(clone!(episode, cancel, progress => move |dl| { on_download_clicked( - &mut episode.clone(), + &episode, dl, - &play, &cancel, progress.clone() ); @@ -196,13 +177,14 @@ impl EpisodeWidget { }); self.progress.show(); + self.download.hide(); + self.cancel.show(); } } fn on_download_clicked( - ep: &mut EpisodeWidgetQuery, + ep: &EpisodeWidgetQuery, download_bttn: >k::Button, - play_bttn: >k::Button, cancel_bttn: >k::Button, progress_bar: gtk::ProgressBar, ) { @@ -216,14 +198,12 @@ fn on_download_clicked( let pd = dbqueries::get_podcast_from_id(ep.podcast_id()).unwrap(); let pd_title = pd.title().to_owned(); - let mut ep = ep.clone(); cancel_bttn.show(); progress.show(); download_bttn.hide(); let download_fold = downloader::get_download_folder(&pd_title).unwrap(); { - let m = DOWNLOADS_MANAGER.clone(); - let man = m.lock().unwrap(); + let man = DOWNLOADS_MANAGER.lock().unwrap(); man.add(ep.rowid(), &download_fold); } } @@ -260,34 +240,13 @@ fn on_play_bttn_clicked(episode_id: i32) { // }; // } -fn receive() -> glib::Continue { - GLOBAL.with(|global| { - if let Some(( - ref download_bttn, - ref play_bttn, - ref cancel_bttn, - ref progress_bar, - ref reciever, - )) = *global.borrow() - { - if reciever.try_recv().is_ok() { - download_bttn.hide(); - play_bttn.show(); - cancel_bttn.hide(); - progress_bar.hide(); - } - } - }); - glib::Continue(false) -} - pub fn episodes_listbox(pd: &Podcast) -> Result { - let episodes = dbqueries::get_pd_episodeswidgets(pd)?; + let mut episodes = dbqueries::get_pd_episodeswidgets(pd)?; let list = gtk::ListBox::new(); - episodes.into_iter().for_each(|mut ep| { - let widget = EpisodeWidget::new(&mut ep); + episodes.iter_mut().for_each(|ep| { + let widget = EpisodeWidget::new(ep); list.add(&widget.container); }); From 2d71a991218049525034a2f439cf36c82938f18c Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 2 Jan 2018 20:47:49 +0200 Subject: [PATCH 128/278] Change the auto-updater and checkup startup scheduling. --- hammond-data/src/utils.rs | 2 ++ hammond-gtk/src/app.rs | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index d6c7cfd..fd0224b 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -84,8 +84,10 @@ pub fn delete_local_content(ep: &mut EpisodeCleanerQuery) -> Result<()> { /// Runs a cleaner for played Episode's that are pass the lifetime limit and /// scheduled for removal. pub fn checkup() -> Result<()> { + info!("Running database checks."); download_checker()?; played_cleaner()?; + info!("Checks completed."); Ok(()) } diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 99415d9..29d634d 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -103,9 +103,9 @@ impl App { pub fn setup_timed_callbacks(&self) { let content = self.content.clone(); let header = self.header.clone(); - // Update 30 seconds after the Application is initialized. + // Update the feeds right after the Application is initialized. gtk::timeout_add_seconds( - 30, + 2, clone!(content => move || { utils::refresh_feed(content.clone(), header.clone(), None); glib::Continue(false) @@ -126,7 +126,7 @@ impl App { ); // Run a database checkup once the application is initialized. - gtk::idle_add(move || { + gtk::timeout_add(300, || { let _ = checkup(); glib::Continue(false) }); From f54ae2f1d57e33dca33364a5e71b664248a75b10 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 3 Jan 2018 03:02:46 +0200 Subject: [PATCH 129/278] EpisodeWidget: Code cleanup and splitting. --- hammond-gtk/src/widgets/episode.rs | 128 ++++++++++++++++++----------- 1 file changed, 78 insertions(+), 50 deletions(-) diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index ae17d73..c5048ff 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -96,60 +96,20 @@ impl EpisodeWidget { // TODO: wire the progress_bar to the downloader. // TODO: wire the cancel button. fn init(&self, episode: &mut EpisodeWidgetQuery) { - self.title.set_xalign(0.0); - self.title.set_text(episode.title()); + // Set the title label state. + self.set_title(episode); - if episode.played().is_some() { - self.title - .get_style_context() - .map(|c| c.add_class("dim-label")); - } + // Set the size label. + self.set_size(episode.length()); - // Declare a custom humansize option struct - // See: https://docs.rs/humansize/1.0.2/humansize/file_size_opts/struct.FileSizeOpts.html - let custom_options = size_opts::FileSizeOpts { - divider: size_opts::Kilo::Binary, - units: size_opts::Kilo::Decimal, - decimal_places: 0, - decimal_zeroes: 0, - fixed_at: size_opts::FixedAt::No, - long_units: false, - space: true, - suffix: "", - allow_negative: false, - }; + // Set the duaration label. + self.set_duration(episode.duration()); - if let Some(size) = episode.length() { - if size != 0 { - let s = size.file_size(custom_options); - if let Ok(s) = s { - self.size.set_text(&s); - self.size.show(); - self.separator2.show(); - } - } - }; - - if let Some(secs) = episode.duration() { - self.duration.set_text(&format!("{} min", secs / 60)); - self.duration.show(); - self.separator1.show(); - }; - - let now = Utc::now(); - let date = Utc.timestamp(i64::from(episode.epoch()), 0); - if now.year() == date.year() { - self.date.set_text(&date.format("%e %b").to_string()); - } else { - self.date.set_text(&date.format("%e %b %Y").to_string()); - }; + // Set the date label. + self.set_date(episode.epoch()); // Show or hide the play/delete/download buttons upon widget initialization. - let local_uri = episode.local_uri(); - if local_uri.is_some() && Path::new(local_uri.unwrap()).exists() { - self.download.hide(); - self.play.show(); - } + self.show_buttons(episode.local_uri()); let title = &self.title; self.play @@ -177,9 +137,77 @@ impl EpisodeWidget { ); })); } + + /// Show or hide the play/delete/download buttons upon widget initialization. + fn show_buttons(&self, local_uri: Option<&str>) { + if local_uri.is_some() && Path::new(local_uri.unwrap()).exists() { + self.download.hide(); + self.play.show(); + } + } + + /// Determine the title state. + fn set_title(&self, episode: &EpisodeWidgetQuery) { + self.title.set_xalign(0.0); + self.title.set_text(episode.title()); + + // Grey out the title if the episode is played. + if episode.played().is_some() { + self.title + .get_style_context() + .map(|c| c.add_class("dim-label")); + } + } + + /// Set the date label depending on the current time. + fn set_date(&self, epoch: i32) { + let now = Utc::now(); + let date = Utc.timestamp(i64::from(epoch), 0); + if now.year() == date.year() { + self.date.set_text(&date.format("%e %b").to_string()); + } else { + self.date.set_text(&date.format("%e %b %Y").to_string()); + }; + } + + /// Set the duration label. + fn set_duration(&self, seconds: Option) { + if let Some(secs) = seconds { + self.duration.set_text(&format!("{} min", secs / 60)); + self.duration.show(); + self.separator1.show(); + } + } + + /// Set the Episode label dependings on its size + fn set_size(&self, bytes: Option) { + // Declare a custom humansize option struct + // See: https://docs.rs/humansize/1.0.2/humansize/file_size_opts/struct.FileSizeOpts.html + let custom_options = size_opts::FileSizeOpts { + divider: size_opts::Kilo::Binary, + units: size_opts::Kilo::Decimal, + decimal_places: 0, + decimal_zeroes: 0, + fixed_at: size_opts::FixedAt::No, + long_units: false, + space: true, + suffix: "", + allow_negative: false, + }; + + if let Some(size) = bytes { + if size != 0 { + let s = size.file_size(custom_options); + if let Ok(s) = s { + self.size.set_text(&s); + self.size.show(); + self.separator2.show(); + } + } + }; + } } -// TODO: show notification when dl is finished. fn on_download_clicked( ep: &mut EpisodeWidgetQuery, download_bttn: >k::Button, From a0476fedece7b28169eed9632d08fcd92152711c Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 3 Jan 2018 03:33:33 +0200 Subject: [PATCH 130/278] ShowWidget: Split init into smaller functions and add comments. --- hammond-gtk/src/widgets/show.rs | 44 ++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 0061119..df57fd6 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -60,6 +60,7 @@ impl ShowWidget { } pub fn init(&self, shows: Rc, header: Rc
, pd: &Podcast) { + // Hacky workaround so the pd.id() can be retrieved from the `ShowStack`. WidgetExt::set_name(&self.container, &pd.id().to_string()); self.unsub.connect_clicked(clone!(shows, pd => move |bttn| { @@ -67,30 +68,39 @@ impl ShowWidget { header.switch_to_normal(); })); - let listbox = episodes_listbox(pd); - if let Ok(l) = listbox { - self.episodes.add(&l); - } - - // TODO: Temporary solution until we render html urls/bold/italic probably with markup. - let desc = dissolve::strip_html_tags(pd.description()).join(" "); - self.description.set_text(&replace_extra_spaces(&desc)); - - let img = get_pixbuf_from_path(&pd.clone().into(), 128); - if let Some(i) = img { - self.cover.set_from_pixbuf(&i); - } + self.setup_listbox(pd); + self.set_cover(pd); + self.set_description(pd.description()); let link = pd.link().to_owned(); - WidgetExt::set_tooltip_text(&self.link, Some(link.as_str())); + self.link.set_tooltip_text(Some(link.as_str())); self.link.connect_clicked(move |_| { info!("Opening link: {}", &link); let _ = open::that(&link); }); + } - // self.played.connect_clicked(clone!(shows, pd => move |_| { - // on_played_button_clicked(shows.clone(), &pd); - // })); + /// Populate the listbox with the shows episodes. + fn setup_listbox(&self, pd: &Podcast) { + let listbox = episodes_listbox(pd); + if let Ok(l) = listbox { + self.episodes.add(&l); + } + } + + /// Set the show cover. + fn set_cover(&self, pd: &Podcast) { + let img = get_pixbuf_from_path(&pd.clone().into(), 128); + if let Some(i) = img { + self.cover.set_from_pixbuf(&i); + } + } + + /// Set the descripton text. + fn set_description(&self, text: &str) { + // TODO: Temporary solution until we render html urls/bold/italic probably with markup. + let desc = dissolve::strip_html_tags(text).join(" "); + self.description.set_text(&replace_extra_spaces(&desc)); } } From c8537e94740e129904fb05883be06188992d17c7 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 3 Jan 2018 05:58:50 +0200 Subject: [PATCH 131/278] GtkApplication: Start to refactor to into a App-channel structure. --- hammond-gtk/src/app.rs | 39 +++++++++++++++++++++++++++++++----- hammond-gtk/src/headerbar.rs | 24 ++++++++++------------ 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 29d634d..1934244 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -5,19 +5,28 @@ use gtk::prelude::*; use gio::{ActionMapExt, ApplicationExt, ApplicationExtManual, SimpleActionExt}; use hammond_data::utils::checkup; +use hammond_data::Source; use headerbar::Header; use content::Content; use utils; use std::rc::Rc; +use std::sync::mpsc::{channel, Receiver}; +use std::time::Duration; -#[derive(Debug, Clone)] +#[derive(Clone, Debug)] +pub enum Action { + UpdateSources(Option), +} + +#[derive(Debug)] pub struct App { app_instance: gtk::Application, window: gtk::Window, header: Rc
, content: Rc, + receiver: Receiver, } impl App { @@ -34,11 +43,14 @@ impl App { let window = gtk::Window::new(gtk::WindowType::Toplevel); window.set_default_size(860, 640); window.set_title("Hammond"); - window.connect_delete_event(|w, _| { - w.destroy(); + let app_clone = application.clone(); + window.connect_delete_event(move |_, _| { + app_clone.quit(); Inhibit(false) }); + let (sender, receiver) = channel(); + // TODO: Refactor the initialization order. // Create the headerbar @@ -48,7 +60,7 @@ impl App { let content = Content::new(header.clone()); // Initialize the headerbar - header.init(content.clone()); + header.init(content.clone(), sender.clone()); // Add the Headerbar to the window. window.set_titlebar(&header.container); @@ -60,6 +72,7 @@ impl App { window, header, content, + receiver, } } @@ -132,7 +145,7 @@ impl App { }); } - pub fn run(&self) { + pub fn run(self) { let window = self.window.clone(); let app = self.app_instance.clone(); self.app_instance.connect_startup(move |_| { @@ -141,6 +154,22 @@ impl App { self.setup_timed_callbacks(); self.setup_actions(); + let receiver = self.receiver; + let content = self.content.clone(); + let headerbar = self.header.clone(); + gtk::idle_add(clone!(content, headerbar => move || { + match receiver.recv_timeout(Duration::from_millis(5)) { + Ok(Action::UpdateSources(source)) => { + if let Some(s) = source { + utils::refresh_feed(content.clone(), headerbar.clone(), Some(vec!(s))) + } + } + _ => (), + } + + Continue(true) + })); + ApplicationExtManual::run(&self.app_instance, &[]); } } diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 3b5f17e..9b0fad9 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -4,8 +4,9 @@ use gtk::prelude::*; use hammond_data::Source; use std::rc::Rc; +use std::sync::mpsc::Sender; +use app::Action; -use utils; use content::Content; #[derive(Debug, Clone)] @@ -48,13 +49,13 @@ impl Default for Header { impl Header { #[allow(dead_code)] - pub fn new(content: Rc) -> Rc
{ + pub fn new(content: Rc, sender: Sender) -> Rc
{ let h = Header::default(); - h.init(content); + h.init(content, sender); Rc::new(h) } - pub fn init(&self, content: Rc) { + pub fn init(&self, content: Rc, sender: Sender) { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let add_popover: gtk::Popover = builder.get_object("add_popover").unwrap(); @@ -66,9 +67,8 @@ impl Header { println!("{:?}", url.get_text()); }); - let header = Rc::new(self.clone()); - add_button.connect_clicked(clone!(content, header, add_popover, new_url => move |_| { - on_add_bttn_clicked(content.clone(), header.clone(), &new_url); + add_button.connect_clicked(clone!(add_popover, new_url, sender => move |_| { + on_add_bttn_clicked(&new_url, sender.clone()); add_popover.hide(); })); @@ -122,16 +122,14 @@ impl Header { } } -fn on_add_bttn_clicked(content: Rc, headerbar: Rc
, entry: >k::Entry) { +fn on_add_bttn_clicked(entry: >k::Entry, sender: Sender) { let url = entry.get_text().unwrap_or_default(); let source = Source::from_url(&url); - if let Ok(s) = source { - info!("{:?} feed added", url); - // update the db - utils::refresh_feed(content, headerbar, Some(vec![s])); + if source.is_ok() { + sender.send(Action::UpdateSources(source.ok())).unwrap(); } else { - error!("Feed probably already exists."); + error!("Something went wrong."); error!("Error: {:?}", source.unwrap_err()); } } From 84da6aac8c7358c3b0ddb233f1f8f5b2f403c9fe Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 3 Jan 2018 06:23:12 +0200 Subject: [PATCH 132/278] ShowWidget: Replace the unsub simple action with a Channel Action. --- hammond-gtk/resources/gtk/show_widget.ui | 1 - hammond-gtk/src/app.rs | 10 +++++++- hammond-gtk/src/content.rs | 19 +++++++++++--- hammond-gtk/src/widgets/show.rs | 32 +++++++++++++++++++----- 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index 01725ae..1bc45e7 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -151,7 +151,6 @@ True center center - app.refresh diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 1934244..d9c29b5 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -18,6 +18,8 @@ use std::time::Duration; #[derive(Clone, Debug)] pub enum Action { UpdateSources(Option), + RefreshViews, + RefreshEpisodesView, } #[derive(Debug)] @@ -57,7 +59,7 @@ impl App { let header = Rc::new(Header::default()); // Create a content instance - let content = Content::new(header.clone()); + let content = Content::new(header.clone(), sender.clone()); // Initialize the headerbar header.init(content.clone(), sender.clone()); @@ -164,6 +166,12 @@ impl App { utils::refresh_feed(content.clone(), headerbar.clone(), Some(vec!(s))) } } + Ok(Action::RefreshViews) => { + content.update(); + } + Ok(Action::RefreshEpisodesView) => { + content.update_episode_view(); + } _ => (), } diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 6293d59..2e0161d 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -10,21 +10,24 @@ use views::episodes::EpisodesView; use widgets::show::ShowWidget; use headerbar::Header; +use app::Action; use std::rc::Rc; +use std::sync::mpsc::Sender; #[derive(Debug, Clone)] pub struct Content { stack: gtk::Stack, shows: Rc, episodes: Rc, + sender: Sender, } impl Content { - pub fn new(header: Rc
) -> Rc { + pub fn new(header: Rc
, sender: Sender) -> Rc { let stack = gtk::Stack::new(); let episodes = EpisodeStack::new(); - let shows = ShowStack::new(header, episodes.clone()); + let shows = ShowStack::new(header, episodes.clone(), sender.clone()); stack.add_titled(&episodes.stack, "episodes", "Episodes"); stack.add_titled(&shows.stack, "shows", "Shows"); @@ -33,6 +36,7 @@ impl Content { stack, shows, episodes, + sender, }) } @@ -63,16 +67,18 @@ pub struct ShowStack { stack: gtk::Stack, header: Rc
, epstack: Rc, + sender: Sender, } impl ShowStack { - fn new(header: Rc
, epstack: Rc) -> Rc { + fn new(header: Rc
, epstack: Rc, sender: Sender) -> Rc { let stack = gtk::Stack::new(); let show = Rc::new(ShowStack { stack, header: header.clone(), epstack, + sender, }); let pop = ShowsPopulated::new(show.clone(), header); @@ -124,7 +130,12 @@ impl ShowStack { pub fn replace_widget(&self, pd: &Podcast) { let old = self.stack.get_child_by_name("widget").unwrap(); - let new = ShowWidget::new(Rc::new(self.clone()), self.header.clone(), pd); + let new = ShowWidget::new( + Rc::new(self.clone()), + self.header.clone(), + pd, + self.sender.clone(), + ); self.stack.remove(&old); self.stack.add_named(&new.container, "widget"); diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index df57fd6..a7ce989 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -13,8 +13,10 @@ use widgets::episode::episodes_listbox; use utils::get_pixbuf_from_path; use content::ShowStack; use headerbar::Header; +use app::Action; use std::rc::Rc; +use std::sync::mpsc::Sender; use std::fs; #[derive(Debug, Clone)] @@ -53,18 +55,30 @@ impl Default for ShowWidget { } impl ShowWidget { - pub fn new(shows: Rc, header: Rc
, pd: &Podcast) -> ShowWidget { + pub fn new( + shows: Rc, + header: Rc
, + pd: &Podcast, + sender: Sender, + ) -> ShowWidget { let pdw = ShowWidget::default(); - pdw.init(shows, header, pd); + pdw.init(shows, header, pd, sender); pdw } - pub fn init(&self, shows: Rc, header: Rc
, pd: &Podcast) { + pub fn init( + &self, + shows: Rc, + header: Rc
, + pd: &Podcast, + sender: Sender, + ) { // Hacky workaround so the pd.id() can be retrieved from the `ShowStack`. WidgetExt::set_name(&self.container, &pd.id().to_string()); - self.unsub.connect_clicked(clone!(shows, pd => move |bttn| { - on_unsub_button_clicked(shows.clone(), &pd, bttn); + self.unsub + .connect_clicked(clone!(shows, pd, sender => move |bttn| { + on_unsub_button_clicked(shows.clone(), &pd, bttn, sender.clone()); header.switch_to_normal(); })); @@ -104,7 +118,12 @@ impl ShowWidget { } } -fn on_unsub_button_clicked(shows: Rc, pd: &Podcast, unsub_button: >k::Button) { +fn on_unsub_button_clicked( + shows: Rc, + pd: &Podcast, + unsub_button: >k::Button, + sender: Sender, +) { let res = dbqueries::remove_feed(pd); if res.is_ok() { info!("{} was removed succesfully.", pd.title()); @@ -120,6 +139,7 @@ fn on_unsub_button_clicked(shows: Rc, pd: &Podcast, unsub_button: > } }; } + sender.send(Action::RefreshViews).unwrap(); shows.switch_podcasts_animated(); } From 33cd6e69ff888e83e9617ba0d597719ec2f17158 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 3 Jan 2018 06:53:19 +0200 Subject: [PATCH 133/278] EpisodeWidget: Migrate to use a Channel Action instead of simple Action. --- hammond-gtk/resources/gtk/episode_widget.ui | 2 - hammond-gtk/src/app.rs | 6 +-- hammond-gtk/src/content.rs | 16 +++++-- hammond-gtk/src/views/episodes.rs | 10 +++-- hammond-gtk/src/widgets/episode.rs | 47 +++++++++------------ hammond-gtk/src/widgets/show.rs | 6 +-- 6 files changed, 43 insertions(+), 44 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 66fc8f6..ea1edcb 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -197,7 +197,6 @@ Download this episode end center - app.refresh_episodes True @@ -221,7 +220,6 @@ True Play this episode center - app.refresh_episodes True diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index d9c29b5..e0cb3a0 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -19,7 +19,7 @@ use std::time::Duration; pub enum Action { UpdateSources(Option), RefreshViews, - RefreshEpisodesView, + RefreshEpisodesViewBGR, } #[derive(Debug)] @@ -169,8 +169,8 @@ impl App { Ok(Action::RefreshViews) => { content.update(); } - Ok(Action::RefreshEpisodesView) => { - content.update_episode_view(); + Ok(Action::RefreshEpisodesViewBGR) => { + content.update_episode_view_if_baground(); } _ => (), } diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 2e0161d..01b5de4 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -26,7 +26,7 @@ pub struct Content { impl Content { pub fn new(header: Rc
, sender: Sender) -> Rc { let stack = gtk::Stack::new(); - let episodes = EpisodeStack::new(); + let episodes = EpisodeStack::new(sender.clone()); let shows = ShowStack::new(header, episodes.clone(), sender.clone()); stack.add_titled(&episodes.stack, "episodes", "Episodes"); @@ -49,6 +49,12 @@ impl Content { self.episodes.update(); } + pub fn update_episode_view_if_baground(&self) { + if self.stack.get_visible_child_name() != Some("episodes".into()) { + self.episodes.update(); + } + } + pub fn update_shows_view(&self) { self.shows.update(); } @@ -178,11 +184,12 @@ pub struct EpisodeStack { // populated: RecentEpisodes, // empty: EmptyView, stack: gtk::Stack, + sender: Sender, } impl EpisodeStack { - fn new() -> Rc { - let episodes = EpisodesView::new(); + fn new(sender: Sender) -> Rc { + let episodes = EpisodesView::new(sender.clone()); let empty = EmptyView::new(); let stack = gtk::Stack::new(); @@ -199,12 +206,13 @@ impl EpisodeStack { // empty, // populated: pop, stack, + sender, }) } pub fn update(&self) { let old = self.stack.get_child_by_name("episodes").unwrap(); - let eps = EpisodesView::new(); + let eps = EpisodesView::new(self.sender.clone()); self.stack.remove(&old); self.stack.add_named(&eps.container, "episodes"); diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 7a4d794..cddde81 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -7,8 +7,10 @@ use hammond_data::EpisodeWidgetQuery; use widgets::episode::EpisodeWidget; use utils::get_pixbuf_from_path; +use app::Action; use std::rc::Rc; +use std::sync::mpsc::Sender; #[derive(Debug, Clone)] enum ListSplit { @@ -69,13 +71,13 @@ impl Default for EpisodesView { } impl EpisodesView { - pub fn new() -> Rc { + pub fn new(sender: Sender) -> Rc { let view = EpisodesView::default(); let episodes = dbqueries::get_episodes_widgets_with_limit(100).unwrap(); let now_utc = Utc::now(); episodes.into_iter().for_each(|mut ep| { - let viewep = EpisodesViewWidget::new(&mut ep); + let viewep = EpisodesViewWidget::new(&mut ep, sender.clone()); let t = split(&now_utc, i64::from(ep.epoch())); match t { @@ -187,7 +189,7 @@ impl Default for EpisodesViewWidget { } impl EpisodesViewWidget { - fn new(episode: &mut EpisodeWidgetQuery) -> EpisodesViewWidget { + fn new(episode: &mut EpisodeWidgetQuery, sender: Sender) -> EpisodesViewWidget { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/episodes_view_widget.ui"); let container: gtk::Box = builder.get_object("container").unwrap(); @@ -200,7 +202,7 @@ impl EpisodesViewWidget { } } - let ep = EpisodeWidget::new(episode); + let ep = EpisodeWidget::new(episode, sender.clone()); container.pack_start(&ep.container, true, true, 6); EpisodesViewWidget { diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index c5048ff..f6bab76 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -13,9 +13,11 @@ use hammond_data::{EpisodeWidgetQuery, Podcast}; use hammond_data::errors::*; use hammond_downloader::downloader; +use app::Action; + use std::thread; use std::cell::RefCell; -use std::sync::mpsc::{channel, Receiver}; +use std::sync::mpsc::{channel, Receiver, Sender}; use std::path::Path; type Foo = RefCell< @@ -86,16 +88,16 @@ impl Default for EpisodeWidget { } impl EpisodeWidget { - pub fn new(episode: &mut EpisodeWidgetQuery) -> EpisodeWidget { + pub fn new(episode: &mut EpisodeWidgetQuery, sender: Sender) -> EpisodeWidget { let widget = EpisodeWidget::default(); - widget.init(episode); + widget.init(episode, sender); widget } // TODO: calculate lenght. // TODO: wire the progress_bar to the downloader. // TODO: wire the cancel button. - fn init(&self, episode: &mut EpisodeWidgetQuery) { + fn init(&self, episode: &mut EpisodeWidgetQuery, sender: Sender) { // Set the title label state. self.set_title(episode); @@ -113,29 +115,32 @@ impl EpisodeWidget { let title = &self.title; self.play - .connect_clicked(clone!(episode, title => move |_| { + .connect_clicked(clone!(episode, title, sender => move |_| { let mut episode = episode.clone(); on_play_bttn_clicked(episode.rowid()); if episode.set_played_now().is_ok() { title .get_style_context() .map(|c| c.add_class("dim-label")); + sender.clone().send(Action::RefreshEpisodesViewBGR).unwrap(); }; })); let play = &self.play; let cancel = &self.cancel; let progress = self.progress.clone(); - self.download - .connect_clicked(clone!(play, episode, cancel, progress => move |dl| { + self.download.connect_clicked( + clone!(play, episode, cancel, progress, sender => move |dl| { on_download_clicked( &mut episode.clone(), dl, &play, &cancel, - progress.clone() + progress.clone(), + sender.clone() ); - })); + }), + ); } /// Show or hide the play/delete/download buttons upon widget initialization. @@ -214,6 +219,7 @@ fn on_download_clicked( play_bttn: >k::Button, cancel_bttn: >k::Button, progress_bar: gtk::ProgressBar, + sender: Sender, ) { let progress = progress_bar.clone(); @@ -223,27 +229,13 @@ fn on_download_clicked( glib::Continue(true) }); - // Create a async channel. - let (sender, receiver) = channel(); - - // Pass the desired arguments into the Local Thread Storage. - GLOBAL.with( - clone!(download_bttn, play_bttn, cancel_bttn, progress => move |global| { - *global.borrow_mut() = Some(( - download_bttn, - play_bttn, - cancel_bttn, - progress, - receiver)); - }), - ); - let pd = dbqueries::get_podcast_from_id(ep.podcast_id()).unwrap(); let pd_title = pd.title().to_owned(); let mut ep = ep.clone(); cancel_bttn.show(); progress.show(); download_bttn.hide(); + sender.send(Action::RefreshEpisodesViewBGR); thread::spawn(move || { let download_fold = downloader::get_download_folder(&pd_title).unwrap(); let e = downloader::get_episode(&mut ep, download_fold.as_str()); @@ -251,8 +243,7 @@ fn on_download_clicked( error!("Error while trying to download: {:?}", ep.uri()); error!("Error: {}", err); }; - sender.send(true).expect("Couldn't send data to channel");; - glib::idle_add(receive); + sender.send(Action::RefreshViews); }); } @@ -309,13 +300,13 @@ fn receive() -> glib::Continue { glib::Continue(false) } -pub fn episodes_listbox(pd: &Podcast) -> Result { +pub fn episodes_listbox(pd: &Podcast, sender: Sender) -> Result { let episodes = dbqueries::get_pd_episodeswidgets(pd)?; let list = gtk::ListBox::new(); episodes.into_iter().for_each(|mut ep| { - let widget = EpisodeWidget::new(&mut ep); + let widget = EpisodeWidget::new(&mut ep, sender.clone()); list.add(&widget.container); }); diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index a7ce989..a248a02 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -82,7 +82,7 @@ impl ShowWidget { header.switch_to_normal(); })); - self.setup_listbox(pd); + self.setup_listbox(pd, sender.clone()); self.set_cover(pd); self.set_description(pd.description()); @@ -95,8 +95,8 @@ impl ShowWidget { } /// Populate the listbox with the shows episodes. - fn setup_listbox(&self, pd: &Podcast) { - let listbox = episodes_listbox(pd); + fn setup_listbox(&self, pd: &Podcast, sender: Sender) { + let listbox = episodes_listbox(pd, sender.clone()); if let Ok(l) = listbox { self.episodes.add(&l); } From 2633161c67eca55055b6906952979b4d60e203d0 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 3 Jan 2018 06:57:15 +0200 Subject: [PATCH 134/278] GtkApplication: Remove some SimpleActions. --- hammond-gtk/src/app.rs | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index e0cb3a0..0219ea8 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -87,32 +87,6 @@ impl App { utils::refresh_feed(content.clone(), header.clone(), None); }); self.app_instance.add_action(&update); - - // Refreshes the `Content` - let refresh = gio::SimpleAction::new("refresh", None); - let content = self.content.clone(); - refresh.connect_activate(move |_, _| { - content.update(); - }); - self.app_instance.add_action(&refresh); - - // Refreshes the `EpisodesStack` - let refresh_episodes = gio::SimpleAction::new("refresh_episodes", None); - let content = self.content.clone(); - refresh_episodes.connect_activate(move |_, _| { - if content.get_stack().get_visible_child_name() != Some(String::from("episodes")) { - content.update_episode_view(); - } - }); - self.app_instance.add_action(&refresh_episodes); - - // Refreshes the `ShowStack` - let refresh_shows = gio::SimpleAction::new("refresh_shows", None); - let content = self.content.clone(); - refresh_shows.connect_activate(move |_, _| { - content.update_shows_view(); - }); - self.app_instance.add_action(&refresh_shows); } pub fn setup_timed_callbacks(&self) { From c33b493dcd8aa5b54004eb89a9423007f2f966f9 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 3 Jan 2018 08:02:06 +0200 Subject: [PATCH 135/278] Migrate Headerbar transitions into Channel actions. --- hammond-gtk/src/app.rs | 19 ++++++----- hammond-gtk/src/content.rs | 22 ++++--------- hammond-gtk/src/views/shows.rs | 13 ++++---- hammond-gtk/src/widgets/episode.rs | 52 ++++-------------------------- hammond-gtk/src/widgets/show.rs | 20 +++--------- 5 files changed, 35 insertions(+), 91 deletions(-) diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 0219ea8..a4fa10b 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -20,6 +20,8 @@ pub enum Action { UpdateSources(Option), RefreshViews, RefreshEpisodesViewBGR, + HeaderBarShowTile(String), + HeaderBarNormal, } #[derive(Debug)] @@ -53,16 +55,11 @@ impl App { let (sender, receiver) = channel(); - // TODO: Refactor the initialization order. + // Create a content instance + let content = Content::new(sender.clone()); // Create the headerbar - let header = Rc::new(Header::default()); - - // Create a content instance - let content = Content::new(header.clone(), sender.clone()); - - // Initialize the headerbar - header.init(content.clone(), sender.clone()); + let header = Header::new(content.clone(), sender); // Add the Headerbar to the window. window.set_titlebar(&header.container); @@ -146,6 +143,12 @@ impl App { Ok(Action::RefreshEpisodesViewBGR) => { content.update_episode_view_if_baground(); } + Ok(Action::HeaderBarShowTile(title)) => { + headerbar.switch_to_back(&title) + } + Ok(Action::HeaderBarNormal) => { + headerbar.switch_to_normal() + } _ => (), } diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 01b5de4..ae3cc8c 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -9,7 +9,6 @@ use views::empty::EmptyView; use views::episodes::EpisodesView; use widgets::show::ShowWidget; -use headerbar::Header; use app::Action; use std::rc::Rc; @@ -24,10 +23,10 @@ pub struct Content { } impl Content { - pub fn new(header: Rc
, sender: Sender) -> Rc { + pub fn new(sender: Sender) -> Rc { let stack = gtk::Stack::new(); let episodes = EpisodeStack::new(sender.clone()); - let shows = ShowStack::new(header, episodes.clone(), sender.clone()); + let shows = ShowStack::new(episodes.clone(), sender.clone()); stack.add_titled(&episodes.stack, "episodes", "Episodes"); stack.add_titled(&shows.stack, "shows", "Shows"); @@ -71,23 +70,21 @@ impl Content { #[derive(Debug, Clone)] pub struct ShowStack { stack: gtk::Stack, - header: Rc
, epstack: Rc, sender: Sender, } impl ShowStack { - fn new(header: Rc
, epstack: Rc, sender: Sender) -> Rc { + fn new(epstack: Rc, sender: Sender) -> Rc { let stack = gtk::Stack::new(); let show = Rc::new(ShowStack { stack, - header: header.clone(), epstack, - sender, + sender: sender.clone(), }); - let pop = ShowsPopulated::new(show.clone(), header); + let pop = ShowsPopulated::new(show.clone(), sender.clone()); let widget = ShowWidget::default(); let empty = EmptyView::new(); @@ -118,7 +115,7 @@ impl ShowStack { let old = self.stack.get_child_by_name("podcasts").unwrap(); let pop = ShowsPopulated::default(); - pop.init(Rc::new(self.clone()), self.header.clone()); + pop.init(Rc::new(self.clone()), self.sender.clone()); self.stack.remove(&old); self.stack.add_named(&pop.container, "podcasts"); @@ -136,12 +133,7 @@ impl ShowStack { pub fn replace_widget(&self, pd: &Podcast) { let old = self.stack.get_child_by_name("widget").unwrap(); - let new = ShowWidget::new( - Rc::new(self.clone()), - self.header.clone(), - pd, - self.sender.clone(), - ); + let new = ShowWidget::new(Rc::new(self.clone()), pd, self.sender.clone()); self.stack.remove(&old); self.stack.add_named(&new.container, "widget"); diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index 46b2865..9edf535 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -7,9 +7,10 @@ use hammond_data::Podcast; use utils::get_pixbuf_from_path; use content::ShowStack; -use headerbar::Header; +use app::Action; use std::rc::Rc; +use std::sync::mpsc::Sender; #[derive(Debug, Clone)] pub struct ShowsPopulated { @@ -34,24 +35,24 @@ impl Default for ShowsPopulated { } impl ShowsPopulated { - pub fn new(show: Rc, header: Rc
) -> ShowsPopulated { + pub fn new(show: Rc, sender: Sender) -> ShowsPopulated { let pop = ShowsPopulated::default(); - pop.init(show, header); + pop.init(show, sender); pop } - pub fn init(&self, show: Rc, header: Rc
) { + pub fn init(&self, show: Rc, sender: Sender) { use gtk::WidgetExt; // TODO: handle unwraps. self.flowbox - .connect_child_activated(clone!(show => move |_, child| { + .connect_child_activated(clone!(show, sender => move |_, child| { // This is such an ugly hack... let id = WidgetExt::get_name(child).unwrap().parse::().unwrap(); let pd = dbqueries::get_podcast_from_id(id).unwrap(); show.replace_widget(&pd); - header.switch_to_back(pd.title()); + sender.send(Action::HeaderBarShowTile(pd.title().into())).unwrap(); show.switch_widget_animated(); })); // Populate the flowbox with the Podcasts. diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index f6bab76..aef5146 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -16,24 +16,9 @@ use hammond_downloader::downloader; use app::Action; use std::thread; -use std::cell::RefCell; -use std::sync::mpsc::{channel, Receiver, Sender}; +use std::sync::mpsc::Sender; use std::path::Path; -type Foo = RefCell< - Option< - ( - gtk::Button, - gtk::Button, - gtk::Button, - gtk::ProgressBar, - Receiver, - ), - >, ->; - -thread_local!(static GLOBAL: Foo = RefCell::new(None)); - #[derive(Debug, Clone)] pub struct EpisodeWidget { pub container: gtk::Box, @@ -126,21 +111,18 @@ impl EpisodeWidget { }; })); - let play = &self.play; let cancel = &self.cancel; let progress = self.progress.clone(); - self.download.connect_clicked( - clone!(play, episode, cancel, progress, sender => move |dl| { + self.download + .connect_clicked(clone!(episode, cancel, progress, sender => move |dl| { on_download_clicked( &mut episode.clone(), dl, - &play, &cancel, progress.clone(), sender.clone() ); - }), - ); + })); } /// Show or hide the play/delete/download buttons upon widget initialization. @@ -216,7 +198,6 @@ impl EpisodeWidget { fn on_download_clicked( ep: &mut EpisodeWidgetQuery, download_bttn: >k::Button, - play_bttn: >k::Button, cancel_bttn: >k::Button, progress_bar: gtk::ProgressBar, sender: Sender, @@ -235,7 +216,7 @@ fn on_download_clicked( cancel_bttn.show(); progress.show(); download_bttn.hide(); - sender.send(Action::RefreshEpisodesViewBGR); + sender.send(Action::RefreshEpisodesViewBGR).unwrap(); thread::spawn(move || { let download_fold = downloader::get_download_folder(&pd_title).unwrap(); let e = downloader::get_episode(&mut ep, download_fold.as_str()); @@ -243,7 +224,7 @@ fn on_download_clicked( error!("Error while trying to download: {:?}", ep.uri()); error!("Error: {}", err); }; - sender.send(Action::RefreshViews); + sender.send(Action::RefreshViews).unwrap(); }); } @@ -279,27 +260,6 @@ fn on_play_bttn_clicked(episode_id: i32) { // }; // } -fn receive() -> glib::Continue { - GLOBAL.with(|global| { - if let Some(( - ref download_bttn, - ref play_bttn, - ref cancel_bttn, - ref progress_bar, - ref reciever, - )) = *global.borrow() - { - if reciever.try_recv().is_ok() { - download_bttn.hide(); - play_bttn.show(); - cancel_bttn.hide(); - progress_bar.hide(); - } - } - }); - glib::Continue(false) -} - pub fn episodes_listbox(pd: &Podcast, sender: Sender) -> Result { let episodes = dbqueries::get_pd_episodeswidgets(pd)?; diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index a248a02..b717faf 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -12,7 +12,6 @@ use hammond_downloader::downloader; use widgets::episode::episodes_listbox; use utils::get_pixbuf_from_path; use content::ShowStack; -use headerbar::Header; use app::Action; use std::rc::Rc; @@ -55,31 +54,20 @@ impl Default for ShowWidget { } impl ShowWidget { - pub fn new( - shows: Rc, - header: Rc
, - pd: &Podcast, - sender: Sender, - ) -> ShowWidget { + pub fn new(shows: Rc, pd: &Podcast, sender: Sender) -> ShowWidget { let pdw = ShowWidget::default(); - pdw.init(shows, header, pd, sender); + pdw.init(shows, pd, sender); pdw } - pub fn init( - &self, - shows: Rc, - header: Rc
, - pd: &Podcast, - sender: Sender, - ) { + pub fn init(&self, shows: Rc, pd: &Podcast, sender: Sender) { // Hacky workaround so the pd.id() can be retrieved from the `ShowStack`. WidgetExt::set_name(&self.container, &pd.id().to_string()); self.unsub .connect_clicked(clone!(shows, pd, sender => move |bttn| { on_unsub_button_clicked(shows.clone(), &pd, bttn, sender.clone()); - header.switch_to_normal(); + sender.send(Action::HeaderBarNormal).unwrap(); })); self.setup_listbox(pd, sender.clone()); From 67bc3e5225e4026cf1f4da0c3a4d62b84ce5032d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 3 Jan 2018 08:12:55 +0200 Subject: [PATCH 136/278] Minor cleanup. --- hammond-gtk/src/content.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index ae3cc8c..273c6ef 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -26,7 +26,7 @@ impl Content { pub fn new(sender: Sender) -> Rc { let stack = gtk::Stack::new(); let episodes = EpisodeStack::new(sender.clone()); - let shows = ShowStack::new(episodes.clone(), sender.clone()); + let shows = ShowStack::new(sender.clone()); stack.add_titled(&episodes.stack, "episodes", "Episodes"); stack.add_titled(&shows.stack, "shows", "Shows"); @@ -70,17 +70,15 @@ impl Content { #[derive(Debug, Clone)] pub struct ShowStack { stack: gtk::Stack, - epstack: Rc, sender: Sender, } impl ShowStack { - fn new(epstack: Rc, sender: Sender) -> Rc { + fn new(sender: Sender) -> Rc { let stack = gtk::Stack::new(); let show = Rc::new(ShowStack { stack, - epstack, sender: sender.clone(), }); @@ -114,8 +112,7 @@ impl ShowStack { let vis = self.stack.get_visible_child_name().unwrap(); let old = self.stack.get_child_by_name("podcasts").unwrap(); - let pop = ShowsPopulated::default(); - pop.init(Rc::new(self.clone()), self.sender.clone()); + let pop = ShowsPopulated::new(Rc::new(self.clone()), self.sender.clone()); self.stack.remove(&old); self.stack.add_named(&pop.container, "podcasts"); @@ -173,8 +170,6 @@ impl ShowStack { #[derive(Debug, Clone)] pub struct EpisodeStack { - // populated: RecentEpisodes, - // empty: EmptyView, stack: gtk::Stack, sender: Sender, } From f30c645596c8019d450d48dd41c658ac9a9c3722 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 4 Jan 2018 16:05:42 +0200 Subject: [PATCH 137/278] hammond_gtk: Refactor refresh_feed func to use the Application channel. --- hammond-gtk/src/app.rs | 35 ++++++++++++++++------------------- hammond-gtk/src/utils.rs | 27 ++++++++++++++++----------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index a4fa10b..15ce75f 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -12,7 +12,7 @@ use content::Content; use utils; use std::rc::Rc; -use std::sync::mpsc::{channel, Receiver}; +use std::sync::mpsc::{channel, Receiver, Sender}; use std::time::Duration; #[derive(Clone, Debug)] @@ -31,6 +31,7 @@ pub struct App { header: Rc
, content: Rc, receiver: Receiver, + sender: Sender, } impl App { @@ -59,7 +60,7 @@ impl App { let content = Content::new(sender.clone()); // Create the headerbar - let header = Header::new(content.clone(), sender); + let header = Header::new(content.clone(), sender.clone()); // Add the Headerbar to the window. window.set_titlebar(&header.container); @@ -72,44 +73,39 @@ impl App { header, content, receiver, + sender, } } pub fn setup_actions(&self) { // Updates the database and refreshes every view. let update = gio::SimpleAction::new("update", None); - let content = self.content.clone(); let header = self.header.clone(); + let sender = self.sender.clone(); update.connect_activate(move |_, _| { - utils::refresh_feed(content.clone(), header.clone(), None); + utils::refresh_feed(header.clone(), None, sender.clone()); }); self.app_instance.add_action(&update); } pub fn setup_timed_callbacks(&self) { - let content = self.content.clone(); let header = self.header.clone(); + let sender = self.sender.clone(); // Update the feeds right after the Application is initialized. - gtk::timeout_add_seconds( - 2, - clone!(content => move || { - utils::refresh_feed(content.clone(), header.clone(), None); + gtk::timeout_add_seconds(2, move || { + utils::refresh_feed(header.clone(), None, sender.clone()); glib::Continue(false) - }), - ); + }); - let content = self.content.clone(); let header = self.header.clone(); + let sender = self.sender.clone(); // Auto-updater, runs every hour. // TODO: expose the interval in which it run to a user setting. // TODO: show notifications. - gtk::timeout_add_seconds( - 3600, - clone!(content => move || { - utils::refresh_feed(content.clone(), header.clone(), None); + gtk::timeout_add_seconds(3600, move || { + utils::refresh_feed(header.clone(), None, sender.clone()); glib::Continue(true) - }), - ); + }); // Run a database checkup once the application is initialized. gtk::timeout_add(300, || { @@ -130,11 +126,12 @@ impl App { let receiver = self.receiver; let content = self.content.clone(); let headerbar = self.header.clone(); + let sender = self.sender.clone(); gtk::idle_add(clone!(content, headerbar => move || { match receiver.recv_timeout(Duration::from_millis(5)) { Ok(Action::UpdateSources(source)) => { if let Some(s) = source { - utils::refresh_feed(content.clone(), headerbar.clone(), Some(vec!(s))) + utils::refresh_feed(headerbar.clone(), Some(vec!(s)), sender.clone()) } } Ok(Action::RefreshViews) => { diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 26c236d..62f5e43 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -8,15 +8,15 @@ use hammond_downloader::downloader; use std::thread; use std::cell::RefCell; -use std::sync::mpsc::{channel, Receiver}; +use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::Mutex; use std::rc::Rc; use std::collections::HashMap; -use content::Content; use headerbar::Header; +use app::Action; -type Foo = RefCell, Rc
, Receiver)>>; +type Foo = RefCell, Receiver)>>; // Create a thread local storage that will store the arguments to be transfered. thread_local!(static GLOBAL: Foo = RefCell::new(None)); @@ -25,15 +25,19 @@ thread_local!(static GLOBAL: Foo = RefCell::new(None)); /// If `source` is None, Fetches all the `Source` entries in the database and updates them. /// `delay` represents the desired time in seconds for the thread to sleep before executing. /// When It's done,it queues up a `podcast_view` refresh. -pub fn refresh_feed(content: Rc, headerbar: Rc
, source: Option>) { +pub fn refresh_feed( + headerbar: Rc
, + source: Option>, + app_sender: Sender, +) { headerbar.show_update_notification(); // Create a async channel. let (sender, receiver) = channel(); // Pass the desired arguments into the Local Thread Storage. - GLOBAL.with(clone!(content, headerbar => move |global| { - *global.borrow_mut() = Some((content.clone(), headerbar.clone(), receiver)); + GLOBAL.with(clone!(headerbar => move |global| { + *global.borrow_mut() = Some((headerbar.clone(), receiver)); })); thread::spawn(move || { @@ -47,16 +51,17 @@ pub fn refresh_feed(content: Rc, headerbar: Rc
, source: Option< }; }; - sender.send(true).expect("Couldn't send data to channel");; - glib::idle_add(refresh_everything); + app_sender.send(Action::RefreshViews).unwrap(); + + let _ = sender.send(true); + glib::idle_add(hide_update_indicator); }); } -fn refresh_everything() -> glib::Continue { +fn hide_update_indicator() -> glib::Continue { GLOBAL.with(|global| { - if let Some((ref content, ref headerbar, ref reciever)) = *global.borrow() { + if let Some((ref headerbar, ref reciever)) = *global.borrow() { if reciever.try_recv().is_ok() { - content.update(); headerbar.hide_update_notification(); } } From f873278a961f272524b16c3bfb18bbfdb896c46d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 4 Jan 2018 16:16:34 +0200 Subject: [PATCH 138/278] hammond_gtk: Move the gtk callback to an Application channel action. --- hammond-gtk/src/app.rs | 4 ++++ hammond-gtk/src/utils.rs | 50 +++++++--------------------------------- 2 files changed, 12 insertions(+), 42 deletions(-) diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 15ce75f..471b92a 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -22,6 +22,7 @@ pub enum Action { RefreshEpisodesViewBGR, HeaderBarShowTile(String), HeaderBarNormal, + HeaderBarHideUpdateIndicator, } #[derive(Debug)] @@ -146,6 +147,9 @@ impl App { Ok(Action::HeaderBarNormal) => { headerbar.switch_to_normal() } + Ok(Action::HeaderBarHideUpdateIndicator) => { + headerbar.hide_update_notification() + } _ => (), } diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 62f5e43..b4ff12f 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -1,5 +1,4 @@ use send_cell::SendCell; -use glib; use gdk_pixbuf::Pixbuf; use hammond_data::feed; @@ -7,8 +6,7 @@ use hammond_data::{PodcastCoverQuery, Source}; use hammond_downloader::downloader; use std::thread; -use std::cell::RefCell; -use std::sync::mpsc::{channel, Receiver, Sender}; +use std::sync::mpsc::Sender; use std::sync::Mutex; use std::rc::Rc; use std::collections::HashMap; @@ -16,59 +14,27 @@ use std::collections::HashMap; use headerbar::Header; use app::Action; -type Foo = RefCell, Receiver)>>; - -// Create a thread local storage that will store the arguments to be transfered. -thread_local!(static GLOBAL: Foo = RefCell::new(None)); - -/// Update the rss feed(s) originating from `Source`. +/// Update the rss feed(s) originating from `source`. /// If `source` is None, Fetches all the `Source` entries in the database and updates them. -/// `delay` represents the desired time in seconds for the thread to sleep before executing. -/// When It's done,it queues up a `podcast_view` refresh. -pub fn refresh_feed( - headerbar: Rc
, - source: Option>, - app_sender: Sender, -) { +/// When It's done,it queues up a `RefreshViews` action. +pub fn refresh_feed(headerbar: Rc
, source: Option>, sender: Sender) { headerbar.show_update_notification(); - // Create a async channel. - let (sender, receiver) = channel(); - - // Pass the desired arguments into the Local Thread Storage. - GLOBAL.with(clone!(headerbar => move |global| { - *global.borrow_mut() = Some((headerbar.clone(), receiver)); - })); - thread::spawn(move || { if let Some(s) = source { feed::index_loop(s); } else { - let e = feed::index_all(); - if let Err(err) = e { + if let Err(err) = feed::index_all() { error!("Error While trying to update the database."); error!("Error msg: {}", err); - }; + } }; - app_sender.send(Action::RefreshViews).unwrap(); - - let _ = sender.send(true); - glib::idle_add(hide_update_indicator); + sender.send(Action::HeaderBarHideUpdateIndicator).unwrap(); + sender.send(Action::RefreshViews).unwrap(); }); } -fn hide_update_indicator() -> glib::Continue { - GLOBAL.with(|global| { - if let Some((ref headerbar, ref reciever)) = *global.borrow() { - if reciever.try_recv().is_ok() { - headerbar.hide_update_notification(); - } - } - }); - glib::Continue(false) -} - lazy_static! { static ref CACHED_PIXBUFS: Mutex>>> = { Mutex::new(HashMap::new()) From 750abb519b4a604af7e47e293ec588255584d234 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 4 Jan 2018 16:42:17 +0200 Subject: [PATCH 139/278] GtkApplication: Change the action channel polling interval. --- hammond-gtk/src/app.rs | 23 ++++++++--------------- hammond-gtk/src/views/episodes.rs | 1 + hammond-gtk/src/widgets/episode.rs | 8 ++++---- 3 files changed, 13 insertions(+), 19 deletions(-) diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 471b92a..18bb469 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -13,7 +13,6 @@ use utils; use std::rc::Rc; use std::sync::mpsc::{channel, Receiver, Sender}; -use std::time::Duration; #[derive(Clone, Debug)] pub enum Action { @@ -124,15 +123,15 @@ impl App { self.setup_timed_callbacks(); self.setup_actions(); - let receiver = self.receiver; let content = self.content.clone(); let headerbar = self.header.clone(); let sender = self.sender.clone(); - gtk::idle_add(clone!(content, headerbar => move || { - match receiver.recv_timeout(Duration::from_millis(5)) { + let receiver = self.receiver; + gtk::timeout_add(250, move || { + match receiver.try_recv() { Ok(Action::UpdateSources(source)) => { if let Some(s) = source { - utils::refresh_feed(headerbar.clone(), Some(vec!(s)), sender.clone()) + utils::refresh_feed(headerbar.clone(), Some(vec![s]), sender.clone()) } } Ok(Action::RefreshViews) => { @@ -141,20 +140,14 @@ impl App { Ok(Action::RefreshEpisodesViewBGR) => { content.update_episode_view_if_baground(); } - Ok(Action::HeaderBarShowTile(title)) => { - headerbar.switch_to_back(&title) - } - Ok(Action::HeaderBarNormal) => { - headerbar.switch_to_normal() - } - Ok(Action::HeaderBarHideUpdateIndicator) => { - headerbar.hide_update_notification() - } + Ok(Action::HeaderBarShowTile(title)) => headerbar.switch_to_back(&title), + Ok(Action::HeaderBarNormal) => headerbar.switch_to_normal(), + Ok(Action::HeaderBarHideUpdateIndicator) => headerbar.hide_update_notification(), _ => (), } Continue(true) - })); + }); ApplicationExtManual::run(&self.app_instance, &[]); } diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index cddde81..85d946b 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -70,6 +70,7 @@ impl Default for EpisodesView { } } +// TODO: REFACTOR ME impl EpisodesView { pub fn new(sender: Sender) -> Rc { let view = EpisodesView::default(); diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index aef5146..eb9eb37 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -107,7 +107,7 @@ impl EpisodeWidget { title .get_style_context() .map(|c| c.add_class("dim-label")); - sender.clone().send(Action::RefreshEpisodesViewBGR).unwrap(); + sender.send(Action::RefreshEpisodesViewBGR).unwrap(); }; })); @@ -261,12 +261,12 @@ fn on_play_bttn_clicked(episode_id: i32) { // } pub fn episodes_listbox(pd: &Podcast, sender: Sender) -> Result { - let episodes = dbqueries::get_pd_episodeswidgets(pd)?; + let mut episodes = dbqueries::get_pd_episodeswidgets(pd)?; let list = gtk::ListBox::new(); - episodes.into_iter().for_each(|mut ep| { - let widget = EpisodeWidget::new(&mut ep, sender.clone()); + episodes.iter_mut().for_each(|ep| { + let widget = EpisodeWidget::new(ep, sender.clone()); list.add(&widget.container); }); From 29837ad39a94f693bdaafa36afe790e29e2f42df Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 4 Jan 2018 17:05:05 +0200 Subject: [PATCH 140/278] Default to using Arc instead of Rc with composite structs of GtkWidgets. --- hammond-gtk/src/app.rs | 6 +++--- hammond-gtk/src/content.rs | 29 ++++++++++++----------------- hammond-gtk/src/headerbar.rs | 10 +++++----- hammond-gtk/src/utils.rs | 5 ++--- hammond-gtk/src/views/episodes.rs | 6 +++--- hammond-gtk/src/views/shows.rs | 6 +++--- hammond-gtk/src/widgets/show.rs | 10 +++++----- 7 files changed, 33 insertions(+), 39 deletions(-) diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 18bb469..d760020 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -11,8 +11,8 @@ use headerbar::Header; use content::Content; use utils; -use std::rc::Rc; use std::sync::mpsc::{channel, Receiver, Sender}; +use std::sync::Arc; #[derive(Clone, Debug)] pub enum Action { @@ -28,8 +28,8 @@ pub enum Action { pub struct App { app_instance: gtk::Application, window: gtk::Window, - header: Rc
, - content: Rc, + header: Arc
, + content: Arc, receiver: Receiver, sender: Sender, } diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 273c6ef..ef0a37e 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -11,19 +11,19 @@ use views::episodes::EpisodesView; use widgets::show::ShowWidget; use app::Action; -use std::rc::Rc; +use std::sync::Arc; use std::sync::mpsc::Sender; #[derive(Debug, Clone)] pub struct Content { stack: gtk::Stack, - shows: Rc, - episodes: Rc, + shows: Arc, + episodes: Arc, sender: Sender, } impl Content { - pub fn new(sender: Sender) -> Rc { + pub fn new(sender: Sender) -> Arc { let stack = gtk::Stack::new(); let episodes = EpisodeStack::new(sender.clone()); let shows = ShowStack::new(sender.clone()); @@ -31,7 +31,7 @@ impl Content { stack.add_titled(&episodes.stack, "episodes", "Episodes"); stack.add_titled(&shows.stack, "shows", "Shows"); - Rc::new(Content { + Arc::new(Content { stack, shows, episodes, @@ -62,7 +62,7 @@ impl Content { self.stack.clone() } - pub fn get_shows(&self) -> Rc { + pub fn get_shows(&self) -> Arc { self.shows.clone() } } @@ -74,10 +74,10 @@ pub struct ShowStack { } impl ShowStack { - fn new(sender: Sender) -> Rc { + fn new(sender: Sender) -> Arc { let stack = gtk::Stack::new(); - let show = Rc::new(ShowStack { + let show = Arc::new(ShowStack { stack, sender: sender.clone(), }); @@ -112,7 +112,7 @@ impl ShowStack { let vis = self.stack.get_visible_child_name().unwrap(); let old = self.stack.get_child_by_name("podcasts").unwrap(); - let pop = ShowsPopulated::new(Rc::new(self.clone()), self.sender.clone()); + let pop = ShowsPopulated::new(Arc::new(self.clone()), self.sender.clone()); self.stack.remove(&old); self.stack.add_named(&pop.container, "podcasts"); @@ -130,7 +130,7 @@ impl ShowStack { pub fn replace_widget(&self, pd: &Podcast) { let old = self.stack.get_child_by_name("widget").unwrap(); - let new = ShowWidget::new(Rc::new(self.clone()), pd, self.sender.clone()); + let new = ShowWidget::new(Arc::new(self.clone()), pd, self.sender.clone()); self.stack.remove(&old); self.stack.add_named(&new.container, "widget"); @@ -175,7 +175,7 @@ pub struct EpisodeStack { } impl EpisodeStack { - fn new(sender: Sender) -> Rc { + fn new(sender: Sender) -> Arc { let episodes = EpisodesView::new(sender.clone()); let empty = EmptyView::new(); let stack = gtk::Stack::new(); @@ -189,12 +189,7 @@ impl EpisodeStack { stack.set_visible_child_name("episodes"); } - Rc::new(EpisodeStack { - // empty, - // populated: pop, - stack, - sender, - }) + Arc::new(EpisodeStack { stack, sender }) } pub fn update(&self) { diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 9b0fad9..7c251fb 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -3,10 +3,10 @@ use gtk::prelude::*; use hammond_data::Source; -use std::rc::Rc; use std::sync::mpsc::Sender; -use app::Action; +use std::sync::Arc; +use app::Action; use content::Content; #[derive(Debug, Clone)] @@ -49,13 +49,13 @@ impl Default for Header { impl Header { #[allow(dead_code)] - pub fn new(content: Rc, sender: Sender) -> Rc
{ + pub fn new(content: Arc, sender: Sender) -> Arc
{ let h = Header::default(); h.init(content, sender); - Rc::new(h) + Arc::new(h) } - pub fn init(&self, content: Rc, sender: Sender) { + pub fn init(&self, content: Arc, sender: Sender) { let builder = gtk::Builder::new_from_resource("/org/gnome/hammond/gtk/headerbar.ui"); let add_popover: gtk::Popover = builder.get_object("add_popover").unwrap(); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index b4ff12f..4928abc 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -7,8 +7,7 @@ use hammond_downloader::downloader; use std::thread; use std::sync::mpsc::Sender; -use std::sync::Mutex; -use std::rc::Rc; +use std::sync::{Arc, Mutex}; use std::collections::HashMap; use headerbar::Header; @@ -17,7 +16,7 @@ use app::Action; /// Update the rss feed(s) originating from `source`. /// If `source` is None, Fetches all the `Source` entries in the database and updates them. /// When It's done,it queues up a `RefreshViews` action. -pub fn refresh_feed(headerbar: Rc
, source: Option>, sender: Sender) { +pub fn refresh_feed(headerbar: Arc
, source: Option>, sender: Sender) { headerbar.show_update_notification(); thread::spawn(move || { diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 85d946b..5fb69f6 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -9,8 +9,8 @@ use widgets::episode::EpisodeWidget; use utils::get_pixbuf_from_path; use app::Action; -use std::rc::Rc; use std::sync::mpsc::Sender; +use std::sync::Arc; #[derive(Debug, Clone)] enum ListSplit { @@ -72,7 +72,7 @@ impl Default for EpisodesView { // TODO: REFACTOR ME impl EpisodesView { - pub fn new(sender: Sender) -> Rc { + pub fn new(sender: Sender) -> Arc { let view = EpisodesView::default(); let episodes = dbqueries::get_episodes_widgets_with_limit(100).unwrap(); let now_utc = Utc::now(); @@ -121,7 +121,7 @@ impl EpisodesView { } view.container.show_all(); - Rc::new(view) + Arc::new(view) } pub fn is_empty(&self) -> bool { diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index 9edf535..01ab9e7 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -9,8 +9,8 @@ use utils::get_pixbuf_from_path; use content::ShowStack; use app::Action; -use std::rc::Rc; use std::sync::mpsc::Sender; +use std::sync::Arc; #[derive(Debug, Clone)] pub struct ShowsPopulated { @@ -35,13 +35,13 @@ impl Default for ShowsPopulated { } impl ShowsPopulated { - pub fn new(show: Rc, sender: Sender) -> ShowsPopulated { + pub fn new(show: Arc, sender: Sender) -> ShowsPopulated { let pop = ShowsPopulated::default(); pop.init(show, sender); pop } - pub fn init(&self, show: Rc, sender: Sender) { + pub fn init(&self, show: Arc, sender: Sender) { use gtk::WidgetExt; // TODO: handle unwraps. diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index b717faf..2c31c03 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -14,8 +14,8 @@ use utils::get_pixbuf_from_path; use content::ShowStack; use app::Action; -use std::rc::Rc; use std::sync::mpsc::Sender; +use std::sync::Arc; use std::fs; #[derive(Debug, Clone)] @@ -54,13 +54,13 @@ impl Default for ShowWidget { } impl ShowWidget { - pub fn new(shows: Rc, pd: &Podcast, sender: Sender) -> ShowWidget { + pub fn new(shows: Arc, pd: &Podcast, sender: Sender) -> ShowWidget { let pdw = ShowWidget::default(); pdw.init(shows, pd, sender); pdw } - pub fn init(&self, shows: Rc, pd: &Podcast, sender: Sender) { + pub fn init(&self, shows: Arc, pd: &Podcast, sender: Sender) { // Hacky workaround so the pd.id() can be retrieved from the `ShowStack`. WidgetExt::set_name(&self.container, &pd.id().to_string()); @@ -107,7 +107,7 @@ impl ShowWidget { } fn on_unsub_button_clicked( - shows: Rc, + shows: Arc, pd: &Podcast, unsub_button: >k::Button, sender: Sender, @@ -132,7 +132,7 @@ fn on_unsub_button_clicked( } #[allow(dead_code)] -fn on_played_button_clicked(shows: Rc, pd: &Podcast) { +fn on_played_button_clicked(shows: Arc, pd: &Podcast) { let _ = dbqueries::update_none_to_played_now(pd); shows.update_widget(); From 9d82b0edda06e27316b6eb4049cc38db2351cbf1 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 4 Jan 2018 17:27:55 +0200 Subject: [PATCH 141/278] EpisodeWidget ui tweaks. --- hammond-gtk/resources/gtk/episode_widget.ui | 9 +++++---- hammond-gtk/resources/gtk/episodes_view.ui | 2 +- hammond-gtk/resources/gtk/show_widget.ui | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index ea1edcb..7d06799 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -15,22 +15,22 @@ True False - center + start vertical 6 True False + start True False - start Episode Title end True - 60 + 64 False 1 @@ -51,12 +51,13 @@ True False + start 6 True False - 1970/01/01 + 3 Jan True False + + + False + True + 6 + + False diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index fa74bbc..33aa7d2 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -28,6 +28,10 @@ impl Progress { }; ratio } + + pub fn get_total_size(&self) -> u64 { + self.total_bytes + } } impl Default for Progress { diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 75d9885..59dcf85 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -17,8 +17,27 @@ use app::Action; use manager; use std::sync::mpsc::Sender; +use std::sync::Arc; use std::path::Path; +lazy_static! { + static ref SIZE_OPTS: Arc = { + // Declare a custom humansize option struct + // See: https://docs.rs/humansize/1.0.2/humansize/file_size_opts/struct.FileSizeOpts.html + Arc::new(size_opts::FileSizeOpts { + divider: size_opts::Kilo::Binary, + units: size_opts::Kilo::Decimal, + decimal_places: 0, + decimal_zeroes: 0, + fixed_at: size_opts::FixedAt::No, + long_units: false, + space: true, + suffix: "", + allow_negative: false, + }) + }; +} + #[derive(Debug, Clone)] pub struct EpisodeWidget { pub container: gtk::Box, @@ -28,11 +47,12 @@ pub struct EpisodeWidget { title: gtk::Label, date: gtk::Label, duration: gtk::Label, - size: gtk::Label, progress: gtk::ProgressBar, - progress_label: gtk::Label, + total_size: gtk::Label, + local_size: gtk::Label, separator1: gtk::Label, separator2: gtk::Label, + prog_separator: gtk::Label, } impl Default for EpisodeWidget { @@ -49,11 +69,12 @@ impl Default for EpisodeWidget { let title: gtk::Label = builder.get_object("title_label").unwrap(); let date: gtk::Label = builder.get_object("date_label").unwrap(); let duration: gtk::Label = builder.get_object("duration_label").unwrap(); - let size: gtk::Label = builder.get_object("size_label").unwrap(); - let progress_label: gtk::Label = builder.get_object("progress_label").unwrap(); + let local_size: gtk::Label = builder.get_object("local_size").unwrap(); + let total_size: gtk::Label = builder.get_object("total_size").unwrap(); let separator1: gtk::Label = builder.get_object("separator1").unwrap(); let separator2: gtk::Label = builder.get_object("separator2").unwrap(); + let prog_separator: gtk::Label = builder.get_object("prog_separator").unwrap(); EpisodeWidget { container, @@ -63,11 +84,12 @@ impl Default for EpisodeWidget { cancel, title, duration, - size, date, - progress_label, + total_size, + local_size, separator1, separator2, + prog_separator, } } } @@ -87,7 +109,7 @@ impl EpisodeWidget { self.set_title(episode); // Set the size label. - self.set_size(episode.length()); + self.set_total_size(episode.length()); // Set the duaration label. self.set_duration(episode.duration()); @@ -164,33 +186,20 @@ impl EpisodeWidget { } /// Set the Episode label dependings on its size - fn set_size(&self, bytes: Option) { - // Declare a custom humansize option struct - // See: https://docs.rs/humansize/1.0.2/humansize/file_size_opts/struct.FileSizeOpts.html - let custom_options = size_opts::FileSizeOpts { - divider: size_opts::Kilo::Binary, - units: size_opts::Kilo::Decimal, - decimal_places: 0, - decimal_zeroes: 0, - fixed_at: size_opts::FixedAt::No, - long_units: false, - space: true, - suffix: "", - allow_negative: false, - }; - + fn set_total_size(&self, bytes: Option) { if let Some(size) = bytes { if size != 0 { - let s = size.file_size(custom_options); + let s = size.file_size(SIZE_OPTS.clone()); if let Ok(s) = s { - self.size.set_text(&s); - self.size.show(); + self.total_size.set_text(&s); + self.total_size.show(); self.separator2.show(); } } }; } + // FIXME: REFACTOR ME fn determine_progess_bar(&self) { let id = WidgetExt::get_name(&self.container) .unwrap() @@ -204,10 +213,14 @@ impl EpisodeWidget { let progress_bar = self.progress.clone(); if let Some(prog) = m.get(&id) { - self.progress.show(); self.download.hide(); + self.progress.show(); + self.local_size.show(); + self.total_size.show(); + self.prog_separator.show(); self.cancel.show(); + // Setup a callback that will update the progress bar. timeout_add( 400, clone!(prog => move || { @@ -231,11 +244,36 @@ impl EpisodeWidget { glib::Continue(false) } else if !active { glib::Continue(false) - }else { + } else { glib::Continue(true) } }), ); + + let total_size = self.total_size.clone(); + // Setup a callback that will update the total_size label + // with the http ContentLength header number rather than + // relying to the RSS feed. + timeout_add( + 500, + clone!(prog, total_size => move || { + let total_bytes = { + let m = prog.lock().unwrap(); + m.get_total_size() + }; + + debug!("Total Size: {}", total_bytes); + if total_bytes != 0 { + let size = total_bytes.file_size(SIZE_OPTS.clone()); + if let Ok(s) = size { + total_size.set_text(&s); + } + glib::Continue(false) + } else { + glib::Continue(true) + } + }), + ); } } } From c54f29e82ad005fdd22f5d04500476e34f96004e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 9 Jan 2018 04:20:38 +0200 Subject: [PATCH 163/278] EpisodeWidget: Modulate callbacks. --- hammond-gtk/src/widgets/episode.rs | 116 ++++++++++++++++------------- 1 file changed, 66 insertions(+), 50 deletions(-) diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 59dcf85..b6036ec 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -17,7 +17,7 @@ use app::Action; use manager; use std::sync::mpsc::Sender; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::path::Path; lazy_static! { @@ -212,6 +212,7 @@ impl EpisodeWidget { }; let progress_bar = self.progress.clone(); + let total_size = self.total_size.clone(); if let Some(prog) = m.get(&id) { self.download.hide(); self.progress.show(); @@ -221,59 +222,12 @@ impl EpisodeWidget { self.cancel.show(); // Setup a callback that will update the progress bar. - timeout_add( - 400, - clone!(prog => move || { - let fraction = { - let m = prog.lock().unwrap(); - m.get_fraction() - }; + update_progressbar_callback(prog.clone(), id, progress_bar); - // I hate floating points. - if (fraction >= 0.0) && (fraction <= 1.0) && (!fraction.is_nan()) { - progress_bar.set_fraction(fraction); - } - // info!("Fraction: {}", progress_bar.get_fraction()); - // info!("Fraction: {}", fraction); - let active = { - let m = manager::ACTIVE_DOWNLOADS.read().unwrap(); - m.contains_key(&id) - }; - - if (fraction >= 1.0) && (!fraction.is_nan()){ - glib::Continue(false) - } else if !active { - glib::Continue(false) - } else { - glib::Continue(true) - } - }), - ); - - let total_size = self.total_size.clone(); // Setup a callback that will update the total_size label // with the http ContentLength header number rather than // relying to the RSS feed. - timeout_add( - 500, - clone!(prog, total_size => move || { - let total_bytes = { - let m = prog.lock().unwrap(); - m.get_total_size() - }; - - debug!("Total Size: {}", total_bytes); - if total_bytes != 0 { - let size = total_bytes.file_size(SIZE_OPTS.clone()); - if let Ok(s) = size { - total_size.set_text(&s); - } - glib::Continue(false) - } else { - glib::Continue(true) - } - }), - ); + update_total_size_callback(prog.clone(), total_size); } } } @@ -310,6 +264,68 @@ fn on_play_bttn_clicked(episode_id: i32) { } } +// Setup a callback that will update the progress bar. +fn update_progressbar_callback( + prog: Arc>, + episode_rowid: i32, + progress_bar: gtk::ProgressBar, +) { + timeout_add( + 400, + clone!(prog, progress_bar=> move || { + let fraction = { + let m = prog.lock().unwrap(); + m.get_fraction() + }; + + // I hate floating points. + if (fraction >= 0.0) && (fraction <= 1.0) && (!fraction.is_nan()) { + progress_bar.set_fraction(fraction); + } + // info!("Fraction: {}", progress_bar.get_fraction()); + // info!("Fraction: {}", fraction); + let active = { + let m = manager::ACTIVE_DOWNLOADS.read().unwrap(); + m.contains_key(&episode_rowid) + }; + + if (fraction >= 1.0) && (!fraction.is_nan()){ + glib::Continue(false) + } else if !active { + glib::Continue(false) + } else { + glib::Continue(true) + } + }), + ); +} + +// Setup a callback that will update the total_size label +// with the http ContentLength header number rather than +// relying to the RSS feed. +fn update_total_size_callback(prog: Arc>, total_size: gtk::Label) { + timeout_add( + 500, + clone!(prog, total_size => move || { + let total_bytes = { + let m = prog.lock().unwrap(); + m.get_total_size() + }; + + debug!("Total Size: {}", total_bytes); + if total_bytes != 0 { + let size = total_bytes.file_size(SIZE_OPTS.clone()); + if let Ok(s) = size { + total_size.set_text(&s); + } + glib::Continue(false) + } else { + glib::Continue(true) + } + }), + ); +} + // fn on_delete_bttn_clicked(episode_id: i32) { // let mut ep = dbqueries::get_episode_from_rowid(episode_id) // .unwrap() From 68d7c621d318f4f54e0beb5c5d0769934b12dd73 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 9 Jan 2018 06:15:41 +0200 Subject: [PATCH 164/278] EpisodeWidget: Update the local_size label. --- hammond-gtk/src/manager.rs | 4 ++++ hammond-gtk/src/widgets/episode.rs | 25 +++++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index 33aa7d2..81d87db 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -32,6 +32,10 @@ impl Progress { pub fn get_total_size(&self) -> u64 { self.total_bytes } + + pub fn get_downloaded(&self) -> u64 { + self.downloaded_bytes + } } impl Default for Progress { diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index b6036ec..8ec2133 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -206,23 +206,28 @@ impl EpisodeWidget { .parse::() .unwrap(); - let m = manager::ACTIVE_DOWNLOADS.read().unwrap(); - if !m.contains_key(&id) { - return; + let prog_struct = { + let m = manager::ACTIVE_DOWNLOADS.read().unwrap(); + if !m.contains_key(&id) { + return; + }; + m.get(&id).cloned() }; let progress_bar = self.progress.clone(); let total_size = self.total_size.clone(); - if let Some(prog) = m.get(&id) { + let local_size = self.local_size.clone(); + if let Some(prog) = prog_struct { self.download.hide(); self.progress.show(); self.local_size.show(); self.total_size.show(); + self.separator2.show(); self.prog_separator.show(); self.cancel.show(); // Setup a callback that will update the progress bar. - update_progressbar_callback(prog.clone(), id, progress_bar); + update_progressbar_callback(prog.clone(), id, progress_bar, local_size); // Setup a callback that will update the total_size label // with the http ContentLength header number rather than @@ -269,15 +274,19 @@ fn update_progressbar_callback( prog: Arc>, episode_rowid: i32, progress_bar: gtk::ProgressBar, + local_size: gtk::Label, ) { timeout_add( 400, - clone!(prog, progress_bar=> move || { - let fraction = { + clone!(prog, progress_bar => move || { + let (fraction, downloaded) = { let m = prog.lock().unwrap(); - m.get_fraction() + (m.get_fraction(), m.get_downloaded()) }; + // Update local_size label + downloaded.file_size(SIZE_OPTS.clone()).map(|x| local_size.set_text(&x)); + // I hate floating points. if (fraction >= 0.0) && (fraction <= 1.0) && (!fraction.is_nan()) { progress_bar.set_fraction(fraction); From 87a259e1a4df4f13bab0aff42b0c9191b912d6e3 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 9 Jan 2018 07:21:38 +0200 Subject: [PATCH 165/278] Minor cleanup. --- hammond-gtk/src/widgets/episode.rs | 26 ++++++++++++++------------ hammond-gtk/src/widgets/show.rs | 22 +++++++++------------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 8ec2133..b700daa 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -189,12 +189,11 @@ impl EpisodeWidget { fn set_total_size(&self, bytes: Option) { if let Some(size) = bytes { if size != 0 { - let s = size.file_size(SIZE_OPTS.clone()); - if let Ok(s) = s { + size.file_size(SIZE_OPTS.clone()).ok().map(|s| { self.total_size.set_text(&s); self.total_size.show(); self.separator2.show(); - } + }); } }; } @@ -250,16 +249,17 @@ fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: Sender) { } fn on_play_bttn_clicked(episode_id: i32) { - let local_uri = dbqueries::get_episode_local_uri_from_id(episode_id).unwrap(); + let local_uri = dbqueries::get_episode_local_uri_from_id(episode_id) + .ok() + .and_then(|x| x); if let Some(uri) = local_uri { if Path::new(&uri).exists() { info!("Opening {}", uri); - let e = open::that(&uri); - if let Err(err) = e { + open::that(&uri).err().map(|err| { error!("Error while trying to open file: {}", uri); error!("Error: {}", err); - }; + }); } } else { error!( @@ -285,14 +285,18 @@ fn update_progressbar_callback( }; // Update local_size label - downloaded.file_size(SIZE_OPTS.clone()).map(|x| local_size.set_text(&x)); + downloaded.file_size(SIZE_OPTS.clone()).ok().map(|x| local_size.set_text(&x)); // I hate floating points. + // Update the progress_bar. if (fraction >= 0.0) && (fraction <= 1.0) && (!fraction.is_nan()) { progress_bar.set_fraction(fraction); } + // info!("Fraction: {}", progress_bar.get_fraction()); // info!("Fraction: {}", fraction); + + // Check if the download is still active let active = { let m = manager::ACTIVE_DOWNLOADS.read().unwrap(); m.contains_key(&episode_rowid) @@ -323,10 +327,8 @@ fn update_total_size_callback(prog: Arc>, total_size: g debug!("Total Size: {}", total_bytes); if total_bytes != 0 { - let size = total_bytes.file_size(SIZE_OPTS.clone()); - if let Ok(s) = size { - total_size.set_text(&s); - } + // Update the total_size label + total_bytes.file_size(SIZE_OPTS.clone()).ok().map(|x| total_size.set_text(&x)); glib::Continue(false) } else { glib::Continue(true) diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 6470596..eb7fc24 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -82,24 +82,22 @@ impl ShowWidget { self.link.set_tooltip_text(Some(link.as_str())); self.link.connect_clicked(move |_| { info!("Opening link: {}", &link); - let _ = open::that(&link); + open::that(&link) + .err() + .map(|err| error!("Something went wrong: {}", err)); }); } /// Populate the listbox with the shows episodes. fn setup_listbox(&self, pd: &Podcast, sender: Sender) { let listbox = episodes_listbox(pd, sender.clone()); - if let Ok(l) = listbox { - self.episodes.add(&l); - } + listbox.ok().map(|l| self.episodes.add(&l)); } /// Set the show cover. fn set_cover(&self, pd: &Podcast) { let img = get_pixbuf_from_path(&pd.clone().into(), 128); - if let Some(i) = img { - self.cover.set_from_pixbuf(&i); - } + img.map(|i| self.cover.set_from_pixbuf(&i)); } /// Set the descripton text. @@ -126,19 +124,17 @@ fn on_unsub_button_clicked( unsub_button.hide(); // Spawn a thread so it won't block the ui. thread::spawn(clone!(pd => move || { - let res = dbqueries::remove_feed(&pd); - if res.is_ok() { + dbqueries::remove_feed(&pd).ok().map(|_| { info!("{} was removed succesfully.", pd.title()); - let dl_fold = downloader::get_download_folder(pd.title()); - if let Ok(fold) = dl_fold { + downloader::get_download_folder(pd.title()).ok().map(|fold| { let res3 = fs::remove_dir_all(&fold); // TODO: Show errors? if res3.is_ok() { info!("All the content at, {} was removed succesfully", &fold); } - }; - } + }); + }); })); shows.switch_podcasts_animated(); // Queue a refresh after the switch to avoid blocking the db. From ea70addbc6eb4096cb8a745f8c55d0d56f3d2267 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 9 Jan 2018 09:21:07 +0200 Subject: [PATCH 166/278] Removed some unwrap()s. --- hammond-data/src/models/queryables.rs | 1 - hammond-gtk/src/manager.rs | 38 +++++++++++++++------------ hammond-gtk/src/views/episodes.rs | 5 +--- hammond-gtk/src/widgets/episode.rs | 26 +++++++++++------- 4 files changed, 38 insertions(+), 32 deletions(-) diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 99fc27c..53f2e53 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -613,7 +613,6 @@ impl<'a> Source { fn update_etag(&mut self, req: &reqwest::Response) -> Result<()> { let headers = req.headers(); - // let etag = headers.get_raw("ETag").unwrap(); let etag = headers.get::(); let lmod = headers.get::(); diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index 81d87db..1cec780 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -68,29 +68,33 @@ pub fn add(id: i32, directory: &str, sender: Sender) { let prog = Arc::new(Mutex::new(Progress::default())); { - let mut m = ACTIVE_DOWNLOADS.write().unwrap(); - m.insert(id, prog.clone()); - } - { - let m = ACTIVE_DOWNLOADS.read().unwrap(); - info!("ACTIVE DOWNLOADS: {:#?}", m); + ACTIVE_DOWNLOADS + .write() + .ok() + .map(|mut m| m.insert(id, prog.clone())); } + // { + // let m = ACTIVE_DOWNLOADS.read().unwrap(); + // info!("ACTIVE DOWNLOADS: {:#?}", m); + // } let dir = directory.to_owned(); thread::spawn(move || { - let episode = dbqueries::get_episode_from_rowid(id).unwrap(); - let e = get_episode(&mut episode.into(), dir.as_str(), Some(prog)); - if let Err(err) = e { - error!("Error: {}", err); - }; + if let Ok(episode) = dbqueries::get_episode_from_rowid(id) { + get_episode(&mut episode.into(), dir.as_str(), Some(prog)) + .err() + .map(|err| { + error!("Error while trying to download an episode"); + error!("Error: {}", err); + }); - { - let mut m = ACTIVE_DOWNLOADS.write().unwrap(); - m.remove(&id); + { + ACTIVE_DOWNLOADS.write().ok().map(|mut x| x.remove(&id)); + } + + sender.send(Action::RefreshEpisodesView).unwrap(); + sender.send(Action::RefreshWidget).unwrap(); } - - sender.send(Action::RefreshEpisodesView).unwrap(); - sender.send(Action::RefreshWidget).unwrap(); }); } diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index c0b04a8..5bb44b9 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -205,10 +205,7 @@ impl EpisodesViewWidget { let image: gtk::Image = builder.get_object("cover").unwrap(); if let Ok(pd) = dbqueries::get_podcast_cover_from_id(episode.podcast_id()) { - let img = get_pixbuf_from_path(&pd, 64); - if let Some(i) = img { - image.set_from_pixbuf(&i); - } + get_pixbuf_from_path(&pd, 64).map(|img| image.set_from_pixbuf(&img)); } let ep = EpisodeWidget::new(episode, sender.clone()); diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index b700daa..651d4c2 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -205,13 +205,15 @@ impl EpisodeWidget { .parse::() .unwrap(); - let prog_struct = { - let m = manager::ACTIVE_DOWNLOADS.read().unwrap(); - if !m.contains_key(&id) { - return; - }; - m.get(&id).cloned() - }; + let prog_struct = || -> Option<_> { + if let Ok(m) = manager::ACTIVE_DOWNLOADS.read() { + if !m.contains_key(&id) { + return None; + }; + return m.get(&id).cloned(); + } + None + }(); let progress_bar = self.progress.clone(); let total_size = self.total_size.clone(); @@ -237,11 +239,15 @@ impl EpisodeWidget { } fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: Sender) { - let pd = dbqueries::get_podcast_from_id(ep.podcast_id()).unwrap(); - let download_fold = downloader::get_download_folder(&pd.title().to_owned()).unwrap(); + let download_fold = dbqueries::get_podcast_from_id(ep.podcast_id()) + .ok() + .map(|pd| downloader::get_download_folder(&pd.title().to_owned()).ok()) + .and_then(|x| x); // Start a new download. - manager::add(ep.rowid(), &download_fold, sender.clone()); + if let Some(fold) = download_fold { + manager::add(ep.rowid(), &fold, sender.clone()); + } // Update Views sender.send(Action::RefreshEpisodesView).unwrap(); From 0ba5e14d7fdc8564840a0d7d4a5796e89e241c5c Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 9 Jan 2018 10:10:54 +0200 Subject: [PATCH 167/278] EpisodeWidget: Only update if it's visible. --- hammond-gtk/src/app.rs | 6 ++++++ hammond-gtk/src/content.rs | 29 ++++++++++++++++++++++++++--- hammond-gtk/src/manager.rs | 3 ++- hammond-gtk/src/widgets/episode.rs | 2 +- hammond-gtk/src/widgets/show.rs | 5 +++-- 5 files changed, 38 insertions(+), 7 deletions(-) diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 262293b..53ca4e2 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -20,7 +20,10 @@ pub enum Action { RefreshAllViews, RefreshEpisodesView, RefreshEpisodesViewBGR, + RefreshShowsView, RefreshWidget, + RefreshWidgetIfVis, + RefreshWidgetIfSame(i32), HeaderBarShowTile(String), HeaderBarNormal, HeaderBarHideUpdateIndicator, @@ -137,7 +140,10 @@ impl App { } } Ok(Action::RefreshAllViews) => content.update(), + Ok(Action::RefreshShowsView) => content.update_shows_view(), Ok(Action::RefreshWidget) => content.update_widget(), + Ok(Action::RefreshWidgetIfVis) => content.update_widget_if_visible(), + Ok(Action::RefreshWidgetIfSame(id)) => content.update_widget_if_same(id), Ok(Action::RefreshEpisodesView) => content.update_episode_view(), Ok(Action::RefreshEpisodesViewBGR) => content.update_episode_view_if_baground(), Ok(Action::HeaderBarShowTile(title)) => headerbar.switch_to_back(&title), diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 57a8018..5d03ed3 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -64,6 +64,18 @@ impl Content { self.shows.update_widget(); } + pub fn update_widget_if_same(&self, pid: i32) { + self.shows.update_widget_if_same(pid); + } + + pub fn update_widget_if_visible(&self) { + if self.stack.get_visible_child_name() == Some("shows".to_string()) + && self.shows.get_stack().get_visible_child_name() == Some("widget".to_string()) + { + self.shows.update_widget(); + } + } + pub fn get_stack(&self) -> gtk::Stack { self.stack.clone() } @@ -186,12 +198,12 @@ impl ShowStack { let vis = self.stack.get_visible_child_name().unwrap(); let old = self.stack.get_child_by_name("widget").unwrap(); - let id = WidgetExt::get_name(&old).unwrap(); - if id == "GtkBox" { + let id = WidgetExt::get_name(&old); + if id == Some("GtkBox".to_string()) || id.is_none() { return; } - let pd = dbqueries::get_podcast_from_id(id.parse::().unwrap()); + let pd = dbqueries::get_podcast_from_id(id.unwrap().parse::().unwrap()); if let Ok(pd) = pd { self.replace_widget(&pd); self.stack.set_visible_child_name(&vis); @@ -199,6 +211,17 @@ impl ShowStack { } } + // Only update widget if it's podcast_id is equal to pid. + pub fn update_widget_if_same(&self, pid: i32) { + let old = self.stack.get_child_by_name("widget").unwrap(); + + let id = WidgetExt::get_name(&old); + if id != Some(pid.to_string()) || id.is_none() { + return; + } + self.update_widget(); + } + pub fn switch_podcasts_animated(&self) { self.stack .set_visible_child_full("podcasts", gtk::StackTransitionType::SlideRight); diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index 1cec780..6f6d7e7 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -81,6 +81,7 @@ pub fn add(id: i32, directory: &str, sender: Sender) { let dir = directory.to_owned(); thread::spawn(move || { if let Ok(episode) = dbqueries::get_episode_from_rowid(id) { + let id = episode.podcast_id(); get_episode(&mut episode.into(), dir.as_str(), Some(prog)) .err() .map(|err| { @@ -93,7 +94,7 @@ pub fn add(id: i32, directory: &str, sender: Sender) { } sender.send(Action::RefreshEpisodesView).unwrap(); - sender.send(Action::RefreshWidget).unwrap(); + sender.send(Action::RefreshWidgetIfSame(id)).unwrap(); } }); } diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 651d4c2..56ea735 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -251,7 +251,7 @@ fn on_download_clicked(ep: &EpisodeWidgetQuery, sender: Sender) { // Update Views sender.send(Action::RefreshEpisodesView).unwrap(); - sender.send(Action::RefreshWidget).unwrap(); + sender.send(Action::RefreshWidgetIfVis).unwrap(); } fn on_play_bttn_clicked(episode_id: i32) { diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index eb7fc24..74d69a3 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -71,7 +71,6 @@ impl ShowWidget { self.unsub .connect_clicked(clone!(shows, pd, sender => move |bttn| { on_unsub_button_clicked(shows.clone(), &pd, bttn, sender.clone()); - sender.send(Action::HeaderBarNormal).unwrap(); })); self.setup_listbox(pd, sender.clone()); @@ -137,8 +136,10 @@ fn on_unsub_button_clicked( }); })); shows.switch_podcasts_animated(); + sender.send(Action::HeaderBarNormal).unwrap(); // Queue a refresh after the switch to avoid blocking the db. - sender.send(Action::RefreshAllViews).unwrap(); + sender.send(Action::RefreshShowsView).unwrap(); + sender.send(Action::RefreshEpisodesView).unwrap(); } #[allow(dead_code)] From d4e3bf696b3c09ed459150a36fd24e261cdc71bd Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 9 Jan 2018 10:52:52 +0200 Subject: [PATCH 168/278] EpisodeWidget: Fix updating. --- hammond-gtk/src/manager.rs | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index 6f6d7e7..49fd2f9 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -68,20 +68,16 @@ pub fn add(id: i32, directory: &str, sender: Sender) { let prog = Arc::new(Mutex::new(Progress::default())); { - ACTIVE_DOWNLOADS - .write() - .ok() - .map(|mut m| m.insert(id, prog.clone())); + if let Ok(mut m) = ACTIVE_DOWNLOADS.write() { + m.insert(id, prog.clone()); + } } - // { - // let m = ACTIVE_DOWNLOADS.read().unwrap(); - // info!("ACTIVE DOWNLOADS: {:#?}", m); - // } let dir = directory.to_owned(); thread::spawn(move || { if let Ok(episode) = dbqueries::get_episode_from_rowid(id) { - let id = episode.podcast_id(); + let pid = episode.podcast_id(); + let id = episode.rowid(); get_episode(&mut episode.into(), dir.as_str(), Some(prog)) .err() .map(|err| { @@ -90,11 +86,19 @@ pub fn add(id: i32, directory: &str, sender: Sender) { }); { - ACTIVE_DOWNLOADS.write().ok().map(|mut x| x.remove(&id)); + if let Ok(mut m) = ACTIVE_DOWNLOADS.write() { + info!("Removed: {:?}", m.remove(&id)); + } } + // { + // if let Ok(m) = ACTIVE_DOWNLOADS.read() { + // debug!("ACTIVE DOWNLOADS: {:#?}", m); + // } + // } + sender.send(Action::RefreshEpisodesView).unwrap(); - sender.send(Action::RefreshWidgetIfSame(id)).unwrap(); + sender.send(Action::RefreshWidgetIfSame(pid)).unwrap(); } }); } From 7f8544373faca60c14d62c32a26d3a60594dd980 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 10 Jan 2018 02:14:49 +0200 Subject: [PATCH 169/278] EpisodesView: Show 50 episodes instead of 100. --- hammond-downloader/src/downloader.rs | 8 ++------ hammond-gtk/src/manager.rs | 3 ++- hammond-gtk/src/views/episodes.rs | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index ad29411..180e586 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -177,11 +177,7 @@ pub fn cache_image(pd: &PodcastCoverQuery) -> Option { return None; } - let cache_download_fold = format!( - "{}{}", - HAMMOND_CACHE.to_str().unwrap(), - pd.title().to_owned() - ); + let cache_download_fold = format!("{}{}", HAMMOND_CACHE.to_str()?, pd.title().to_owned()); // Weird glob magic. if let Ok(mut foo) = glob(&format!("{}/cover.*", cache_download_fold)) { @@ -196,7 +192,7 @@ pub fn cache_image(pd: &PodcastCoverQuery) -> Option { DirBuilder::new() .recursive(true) .create(&cache_download_fold) - .unwrap(); + .ok()?; match download_into(&cache_download_fold, "cover", &url, None) { Ok(path) => { diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index d482fbe..b6830d6 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -20,8 +20,9 @@ pub struct Progress { impl Progress { pub fn get_fraction(&self) -> f64 { - info!("Progress: {:?}", self); let ratio = self.downloaded_bytes as f64 / self.total_bytes as f64; + debug!("{:?}", self); + debug!("Ratio completed: {}", ratio); if ratio >= 1.0 { return 1.0; diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index 5bb44b9..dc36148 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -77,7 +77,7 @@ impl Default for EpisodesView { impl EpisodesView { pub fn new(sender: Sender) -> Arc { let view = EpisodesView::default(); - let episodes = dbqueries::get_episodes_widgets_with_limit(100).unwrap(); + let episodes = dbqueries::get_episodes_widgets_with_limit(50).unwrap(); let now_utc = Utc::now(); episodes.into_iter().for_each(|mut ep| { From 3899e8ed39f40de682c094b48183680129298a6d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 10 Jan 2018 02:59:47 +0200 Subject: [PATCH 170/278] Add GPL notices to the glade ui files. --- hammond-gtk/resources/gtk/empty_view.ui | 30 ++++++++++++++++- hammond-gtk/resources/gtk/episode_widget.ui | 30 ++++++++++++++++- hammond-gtk/resources/gtk/episodes_view.ui | 30 ++++++++++++++++- .../resources/gtk/episodes_view_widget.ui | 30 ++++++++++++++++- hammond-gtk/resources/gtk/headerbar.ui | 30 ++++++++++++++++- hammond-gtk/resources/gtk/show_widget.ui | 32 +++++++++++++++++-- hammond-gtk/resources/gtk/shows_child.ui | 30 ++++++++++++++++- hammond-gtk/resources/gtk/shows_view.ui | 30 ++++++++++++++++- 8 files changed, 233 insertions(+), 9 deletions(-) diff --git a/hammond-gtk/resources/gtk/empty_view.ui b/hammond-gtk/resources/gtk/empty_view.ui index f4937cd..c3df79b 100644 --- a/hammond-gtk/resources/gtk/empty_view.ui +++ b/hammond-gtk/resources/gtk/empty_view.ui @@ -1,7 +1,35 @@ - + + + + + + True False diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 64a9ad1..5752192 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -1,7 +1,35 @@ - + + + + + + True False diff --git a/hammond-gtk/resources/gtk/episodes_view.ui b/hammond-gtk/resources/gtk/episodes_view.ui index a606233..e7c4cdd 100644 --- a/hammond-gtk/resources/gtk/episodes_view.ui +++ b/hammond-gtk/resources/gtk/episodes_view.ui @@ -1,7 +1,35 @@ - + + + + + + container True diff --git a/hammond-gtk/resources/gtk/episodes_view_widget.ui b/hammond-gtk/resources/gtk/episodes_view_widget.ui index bbe09b7..b00238e 100644 --- a/hammond-gtk/resources/gtk/episodes_view_widget.ui +++ b/hammond-gtk/resources/gtk/episodes_view_widget.ui @@ -1,7 +1,35 @@ - + + + + + + True False diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index 68c4541..00fa466 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -1,7 +1,35 @@ - + + + + + + False Add a new feed diff --git a/hammond-gtk/resources/gtk/show_widget.ui b/hammond-gtk/resources/gtk/show_widget.ui index f8e076b..887a98b 100644 --- a/hammond-gtk/resources/gtk/show_widget.ui +++ b/hammond-gtk/resources/gtk/show_widget.ui @@ -1,7 +1,35 @@ - - + + + + + + + True False diff --git a/hammond-gtk/resources/gtk/shows_child.ui b/hammond-gtk/resources/gtk/shows_child.ui index 0fa68f6..1f4113a 100644 --- a/hammond-gtk/resources/gtk/shows_child.ui +++ b/hammond-gtk/resources/gtk/shows_child.ui @@ -1,7 +1,35 @@ - + + + + + + 256 256 diff --git a/hammond-gtk/resources/gtk/shows_view.ui b/hammond-gtk/resources/gtk/shows_view.ui index 4fa9396..ce9e962 100644 --- a/hammond-gtk/resources/gtk/shows_view.ui +++ b/hammond-gtk/resources/gtk/shows_view.ui @@ -1,7 +1,35 @@ - + + + + + + fb_parent True From a63a6e168c2094aa4564a6e07032125cd403392b Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 10 Jan 2018 08:27:13 +0200 Subject: [PATCH 171/278] Added BrokenFeed Issue template. --- .gitlab/issue_templates/BrokenFeed.md | 22 ++++++++++++++++++++++ README.md | 8 ++++---- hammond-gtk/src/manager.rs | 1 + 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 .gitlab/issue_templates/BrokenFeed.md diff --git a/.gitlab/issue_templates/BrokenFeed.md b/.gitlab/issue_templates/BrokenFeed.md new file mode 100644 index 0000000..793e53f --- /dev/null +++ b/.gitlab/issue_templates/BrokenFeed.md @@ -0,0 +1,22 @@ +## Invalid RSS Feed Template. + +Please provide the source of the xml rss feed. + +**Feed URL** +example.com/podcast + +**Detailed description of the issue**. +Would be helpfull if error messages where included from stderr. +If you are not sure how to do it, feel free to ask and we will walk you through it! + +Some common cases might be: +* Feed cannot be added +* Broken Feed Image +* Episode(s) do not download + +Steps to reproduce: + +1. Open Hammond +2. Do an action +3. ... + diff --git a/README.md b/README.md index 12e4c93..d1c7932 100644 --- a/README.md +++ b/README.md @@ -87,8 +87,8 @@ There are also some minor tasks tagged with `TODO:` and `FIXME:` in the source c ```sh $ tree -d ├── assets # png's used in the README.md -├── hammond-data # Storate related stuff, Sqlite db, XDG setup. -│   ├── migrations # Diesel migrations. +├── hammond-data # Storate related stuff, SQLite, XDG setup, RSS Parser. +│   ├── migrations # Diesel SQL migrations. │   │   └── ... │   ├── src │   └── tests @@ -99,8 +99,8 @@ $ tree -d │   ├── resources # GResources folder │   │   └── gtk # Contains the glade.ui files. │   └── src -│   ├── views # Currently only contains the Empty and Episodes views. -│   └── widgets # Contains custom widgets such as Podcast and Episode. +│   ├── views # Contains the Empty, Episodes and Shows view. +│   └── widgets # Contains custom widgets such as Show and Episode. ``` ## A note about the project's name diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index b6830d6..b0b27f8 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -150,6 +150,7 @@ mod tests { let download_fold = get_download_folder(&pd.title()).unwrap(); add(episode.rowid(), download_fold.as_str(), sender); + assert_eq!(ACTIVE_DOWNLOADS.read().unwrap().len(), 1); // Give it soem time to download the file thread::sleep(time::Duration::from_secs(40)); From 77f005caab5a3641f2a24c7846bbaf90ae80ac17 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 10 Jan 2018 09:04:24 +0200 Subject: [PATCH 172/278] Update Contributing.md --- .gitlab/issue_templates/BrokenFeed.md | 4 ++- .gitlab/issue_templates/Bug.md | 11 ------ CONTRIBUTING.md | 49 +++++++++++++++++++-------- README.md | 7 ++-- 4 files changed, 41 insertions(+), 30 deletions(-) diff --git a/.gitlab/issue_templates/BrokenFeed.md b/.gitlab/issue_templates/BrokenFeed.md index 793e53f..f74b997 100644 --- a/.gitlab/issue_templates/BrokenFeed.md +++ b/.gitlab/issue_templates/BrokenFeed.md @@ -3,9 +3,11 @@ Please provide the source of the xml rss feed. **Feed URL** + example.com/podcast -**Detailed description of the issue**. +**Detailed description of the issue** + Would be helpfull if error messages where included from stderr. If you are not sure how to do it, feel free to ask and we will walk you through it! diff --git a/.gitlab/issue_templates/Bug.md b/.gitlab/issue_templates/Bug.md index e42b565..17060a6 100644 --- a/.gitlab/issue_templates/Bug.md +++ b/.gitlab/issue_templates/Bug.md @@ -7,14 +7,3 @@ Steps to reproduce: 2. Do an action 3. ... -## Design Tasks - -* [ ] design tasks - -## Development Tasks - -* [ ] development tasks - -## QA Tasks - -* [ ] qa (quality assurance) tasks diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2e46fdc..b0e9192 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,36 +1,55 @@ -## Contributing +## Contributing to Hammond + +Thank you for looking in this file! When contributing to the development of Hammond, please first discuss the change you wish to make via issue, email, or any other method with the maintainers before making a change. -Please note we have a code of conduct, please follow it in all your interactions with the project. +If you have any questions regarding the use or development of Hammond, +want to discuss design or simply hang out, please join us in [#hammond on irc.gnome.org.](irc://irc.gnome.org/#hammond) + +Please note we have a [code of conduct](https://wiki.gnome.org/Foundation/CodeOfConduc), please follow it in all your interactions with the project. + +## Source repository + +Hammond's main source repository is at gitlab.gnome.org. You can view +the web interface [here](https://gitlab.gnome.org/alatiera/hammond) + +Development happens in the master branch. + +Note that we don't do bug tracking in the Github mirror. + +If you need to publish a branch, feel free to do it at any +publically-accessible Git hosting service, although gitlab.gnome.org +makes things easier for the maintainers. ## Style -We use rustfmt for code formatting and we enforce it on the gitlab-CI server. +We use [rustfmt](https://github.com/rust-lang-nursery/rustfmt) for code formatting and we enforce it on the gitlab-CI server. Quick setup - ``` - cargo install rustfmt-nightly - cargo fmt --all - ``` +``` +cargo install rustfmt-nightly +cargo fmt --all + ``` -It is recommended to add a pre-commit hook to run cargo test and cargo fmt - ``` - #!/bin/sh - cargo test -- --test-threads=1 && cargo fmt --all -- --write-mode=diff - ``` +It is recommended to add a pre-commit hook to run cargo test and `cargo fmt`. +Don't forget to `git add` again after `cargo fmt`. +``` +#!/bin/sh +cargo test -- --test-threads=1 && cargo fmt --all -- --write-mode=diff +``` ## Running the test suite -The test suite sets a temporary sqlite database in the /tmp folder. Due to that it's not possible to run them in parrallel. +The test suite sets a temporary sqlite database in the `/tmp` folder. +Due to that it's not possible to run them in parrallel. In order to run the test suite use the following: `cargo test -- --test-threads=1` # Issues, issues and more issues! There are many ways you can contribute to Hammond, and all of them involve creating issues -in [Hammond issue tracker](https://gitlab.gnome.org/alatiera/Hammond/issues). This is the -entry point for your contribution. +in [Hammond issue tracker](https://gitlab.gnome.org/alatiera/Hammond/issues). This is the entry point for your contribution. To create an effective and high quality ticket, try to put the following information on your ticket: diff --git a/README.md b/README.md index d1c7932..dbb3a12 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,8 @@ This is a prototype of a podcast client written in Rust. ![podcast_widget](./assets/podcast_widget.png) ## Getting in Touch -If you have any questions regarding the use or development of Hammond, want to discuss design or simply hang out, please join us in [#hammond on irc.gnome.org.](irc://irc.gnome.org/#hammond) +If you have any questions regarding the use or development of Hammond, +want to discuss design or simply hang out, please join us in [#hammond on irc.gnome.org.](irc://irc.gnome.org/#hammond) Sidenote: @@ -49,14 +50,14 @@ Flatpak instructions... Soon™. * Gtk+ 3.22 or later * Meson -**Debian/Ubuntu**: +**Debian/Ubuntu** ```sh apt-get update -yqq apt-get install -yqq --no-install-recommends build-essential apt-get install -yqq --no-install-recommends libgtk-3-dev meson ``` -**Fedora**: +**Fedora** ```sh dnf install -y gtk3-devel glib2-devel openssl-devel sqlite-devel meson ``` From 8a90de3c0ef0f6545762fd8030f5bd4495fb2609 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 10 Jan 2018 09:43:38 +0200 Subject: [PATCH 173/278] Implement download cancel action. #24 --- hammond-downloader/src/downloader.rs | 12 ++++++++--- hammond-gtk/resources/gtk/episode_widget.ui | 1 - hammond-gtk/src/manager.rs | 24 +++++++++++++++------ hammond-gtk/src/widgets/episode.rs | 7 ++++++ 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 180e586..13f3117 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -20,6 +20,7 @@ use hammond_data::xdg_dirs::HAMMOND_CACHE; pub trait DownloadProgress { fn set_downloaded(&mut self, downloaded: u64); fn set_size(&mut self, bytes: u64); + fn should_cancel(&self) -> bool; } // Adapted from https://github.com/mattgathu/rget . @@ -113,12 +114,17 @@ fn save_io( buffer.truncate(bcount); if !buffer.is_empty() { writer.write_all(buffer.as_slice())?; + // This sucks. + // Actually the whole download module is hack, so w/e. if let Some(prog) = progress.clone() { - // This sucks. let len = writer.get_ref().metadata().map(|x| x.len()); if let Ok(l) = len { - let mut m = prog.lock().unwrap(); - m.set_downloaded(l); + if let Ok(mut m) = prog.lock() { + if m.should_cancel() { + bail!("Download was cancelled."); + } + m.set_downloaded(l); + } } } } else { diff --git a/hammond-gtk/resources/gtk/episode_widget.ui b/hammond-gtk/resources/gtk/episode_widget.ui index 5752192..d270cb0 100644 --- a/hammond-gtk/resources/gtk/episode_widget.ui +++ b/hammond-gtk/resources/gtk/episode_widget.ui @@ -221,7 +221,6 @@ Tobias Bernard Cancel - False True False True diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index b0b27f8..d054fa7 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -16,6 +16,17 @@ use std::thread; pub struct Progress { total_bytes: u64, downloaded_bytes: u64, + cancel: bool, +} + +impl Default for Progress { + fn default() -> Self { + Progress { + total_bytes: 0, + downloaded_bytes: 0, + cancel: false, + } + } } impl Progress { @@ -37,14 +48,9 @@ impl Progress { pub fn get_downloaded(&self) -> u64 { self.downloaded_bytes } -} -impl Default for Progress { - fn default() -> Self { - Progress { - total_bytes: 0, - downloaded_bytes: 0, - } + pub fn cancel(&mut self) { + self.cancel = true; } } @@ -56,6 +62,10 @@ impl DownloadProgress for Progress { fn set_size(&mut self, bytes: u64) { self.total_bytes = bytes; } + + fn should_cancel(&self) -> bool { + self.cancel + } } lazy_static! { diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index b17c9ce..73bd8bd 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -240,6 +240,13 @@ impl EpisodeWidget { // with the http ContentLength header number rather than // relying to the RSS feed. update_total_size_callback(prog.clone(), total_size); + + self.cancel.connect_clicked(clone!(prog => move |cancel| { + if let Ok(mut m) = prog.lock() { + m.cancel(); + cancel.set_sensitive(false); + } + })); } } } From 95ff3715a3d003cf4d06f184a04de6283b7006aa Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 11 Jan 2018 01:14:54 +0200 Subject: [PATCH 174/278] Migrate StackSwitch actions to use the AppAction channel. --- hammond-gtk/src/app.rs | 13 ++++++++++--- hammond-gtk/src/content.rs | 20 ++++++++++---------- hammond-gtk/src/views/shows.rs | 21 ++++++++++----------- hammond-gtk/src/widgets/show.rs | 25 +++++++++---------------- 4 files changed, 39 insertions(+), 40 deletions(-) diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 53ca4e2..1c214b2 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -5,13 +5,14 @@ use gtk::prelude::*; use gio::{ActionMapExt, ApplicationExt, ApplicationExtManual, SimpleActionExt}; use hammond_data::utils::checkup; -use hammond_data::Source; +use hammond_data::{Podcast, Source}; use headerbar::Header; use content::Content; use utils; use std::sync::Arc; +use std::time::Duration; use std::sync::mpsc::{channel, Receiver, Sender}; #[derive(Clone, Debug)] @@ -23,7 +24,10 @@ pub enum Action { RefreshShowsView, RefreshWidget, RefreshWidgetIfVis, + ReplaceWidget(Podcast), RefreshWidgetIfSame(i32), + ShowWidgetAnimated, + ShowShowsAnimated, HeaderBarShowTile(String), HeaderBarNormal, HeaderBarHideUpdateIndicator, @@ -132,8 +136,8 @@ impl App { let headerbar = self.header.clone(); let sender = self.sender.clone(); let receiver = self.receiver; - gtk::timeout_add(250, move || { - match receiver.try_recv() { + gtk::idle_add(move || { + match receiver.recv_timeout(Duration::from_millis(10)) { Ok(Action::UpdateSources(source)) => { if let Some(s) = source { utils::refresh_feed(headerbar.clone(), Some(vec![s]), sender.clone()) @@ -146,6 +150,9 @@ impl App { Ok(Action::RefreshWidgetIfSame(id)) => content.update_widget_if_same(id), Ok(Action::RefreshEpisodesView) => content.update_episode_view(), Ok(Action::RefreshEpisodesViewBGR) => content.update_episode_view_if_baground(), + Ok(Action::ReplaceWidget(ref pd)) => content.get_shows().replace_widget(pd), + Ok(Action::ShowWidgetAnimated) => content.get_shows().switch_widget_animated(), + Ok(Action::ShowShowsAnimated) => content.get_shows().switch_podcasts_animated(), Ok(Action::HeaderBarShowTile(title)) => headerbar.switch_to_back(&title), Ok(Action::HeaderBarNormal) => headerbar.switch_to_normal(), Ok(Action::HeaderBarHideUpdateIndicator) => headerbar.hide_update_notification(), diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 69754a4..10d3d79 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -26,8 +26,8 @@ pub struct Content { impl Content { pub fn new(sender: Sender) -> Arc { let stack = gtk::Stack::new(); - let episodes = EpisodeStack::new(sender.clone()); - let shows = ShowStack::new(sender.clone()); + let episodes = Arc::new(EpisodeStack::new(sender.clone())); + let shows = Arc::new(ShowStack::new(sender.clone())); stack.add_titled(&episodes.stack, "episodes", "Episodes"); stack.add_titled(&shows.stack, "shows", "Shows"); @@ -92,15 +92,15 @@ pub struct ShowStack { } impl ShowStack { - fn new(sender: Sender) -> Arc { + fn new(sender: Sender) -> ShowStack { let stack = gtk::Stack::new(); - let show = Arc::new(ShowStack { + let show = ShowStack { stack, sender: sender.clone(), - }); + }; - let pop = ShowsPopulated::new(show.clone(), sender.clone()); + let pop = ShowsPopulated::new(sender.clone()); let widget = ShowWidget::default(); let empty = EmptyView::new(); @@ -144,7 +144,7 @@ impl ShowStack { .unwrap(); debug!("Name: {:?}", WidgetExt::get_name(&scrolled_window)); - let pop = ShowsPopulated::new(Arc::new(self.clone()), self.sender.clone()); + let pop = ShowsPopulated::new(self.sender.clone()); // Copy the vertical scrollbar adjustment from the old view into the new one. scrolled_window .get_vadjustment() @@ -174,7 +174,7 @@ impl ShowStack { .unwrap(); debug!("Name: {:?}", WidgetExt::get_name(&old)); - let new = ShowWidget::new(Arc::new(self.clone()), pd, self.sender.clone()); + let new = ShowWidget::new(pd, self.sender.clone()); // Each composite ShowWidget is a gtkBox with the Podcast.id encoded in the gtk::Widget // name. It's a hack since we can't yet subclass GObject easily. let oldid = WidgetExt::get_name(&old); @@ -253,7 +253,7 @@ pub struct EpisodeStack { } impl EpisodeStack { - fn new(sender: Sender) -> Arc { + fn new(sender: Sender) -> EpisodeStack { let episodes = EpisodesView::new(sender.clone()); let empty = EmptyView::new(); let stack = gtk::Stack::new(); @@ -267,7 +267,7 @@ impl EpisodeStack { stack.set_visible_child_name("episodes"); } - Arc::new(EpisodeStack { stack, sender }) + EpisodeStack { stack, sender } } pub fn update(&self) { diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index df8dc57..3a5b40b 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -6,11 +6,9 @@ use hammond_data::dbqueries; use hammond_data::Podcast; use utils::get_pixbuf_from_path; -use content::ShowStack; use app::Action; use std::sync::mpsc::Sender; -use std::sync::Arc; #[derive(Debug, Clone)] pub struct ShowsPopulated { @@ -35,26 +33,27 @@ impl Default for ShowsPopulated { } impl ShowsPopulated { - pub fn new(show: Arc, sender: Sender) -> ShowsPopulated { + pub fn new(sender: Sender) -> ShowsPopulated { let pop = ShowsPopulated::default(); - pop.init(show, sender); + pop.init(sender); pop } - pub fn init(&self, show: Arc, sender: Sender) { + pub fn init(&self, sender: Sender) { use gtk::WidgetExt; // TODO: handle unwraps. - self.flowbox - .connect_child_activated(clone!(show, sender => move |_, child| { + self.flowbox.connect_child_activated(move |_, child| { // This is such an ugly hack... let id = WidgetExt::get_name(child).unwrap().parse::().unwrap(); let pd = dbqueries::get_podcast_from_id(id).unwrap(); - show.replace_widget(&pd); - sender.send(Action::HeaderBarShowTile(pd.title().into())).unwrap(); - show.switch_widget_animated(); - })); + sender + .send(Action::HeaderBarShowTile(pd.title().into())) + .unwrap(); + sender.send(Action::ReplaceWidget(pd)).unwrap(); + sender.send(Action::ShowWidgetAnimated).unwrap(); + }); // Populate the flowbox with the Podcasts. self.populate_flowbox(); } diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index ca2e850..1b08638 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -10,11 +10,9 @@ use hammond_data::utils::{delete_show, replace_extra_spaces}; use widgets::episode::episodes_listbox; use utils::get_pixbuf_from_path; -use content::ShowStack; use app::Action; use std::sync::mpsc::Sender; -use std::sync::Arc; use std::thread; #[derive(Debug, Clone)] @@ -56,19 +54,19 @@ impl Default for ShowWidget { } impl ShowWidget { - pub fn new(shows: Arc, pd: &Podcast, sender: Sender) -> ShowWidget { + pub fn new(pd: &Podcast, sender: Sender) -> ShowWidget { let pdw = ShowWidget::default(); - pdw.init(shows, pd, sender); + pdw.init(pd, sender); pdw } - pub fn init(&self, shows: Arc, pd: &Podcast, sender: Sender) { + pub fn init(&self, pd: &Podcast, sender: Sender) { // Hacky workaround so the pd.id() can be retrieved from the `ShowStack`. WidgetExt::set_name(&self.container, &pd.id().to_string()); self.unsub - .connect_clicked(clone!(shows, pd, sender => move |bttn| { - on_unsub_button_clicked(shows.clone(), &pd, bttn, sender.clone()); + .connect_clicked(clone!(pd, sender => move |bttn| { + on_unsub_button_clicked(&pd, bttn, sender.clone()); })); self.setup_listbox(pd, sender.clone()); @@ -110,12 +108,7 @@ impl ShowWidget { } } -fn on_unsub_button_clicked( - shows: Arc, - pd: &Podcast, - unsub_button: >k::Button, - sender: Sender, -) { +fn on_unsub_button_clicked(pd: &Podcast, unsub_button: >k::Button, sender: Sender) { // hack to get away without properly checking for none. // if pressed twice would panic. unsub_button.hide(); @@ -126,16 +119,16 @@ fn on_unsub_button_clicked( error!("Error: {}", err); } })); - shows.switch_podcasts_animated(); sender.send(Action::HeaderBarNormal).unwrap(); + sender.send(Action::ShowShowsAnimated).unwrap(); // Queue a refresh after the switch to avoid blocking the db. sender.send(Action::RefreshShowsView).unwrap(); sender.send(Action::RefreshEpisodesView).unwrap(); } #[allow(dead_code)] -fn on_played_button_clicked(shows: Arc, pd: &Podcast) { +fn on_played_button_clicked(pd: &Podcast, sender: Sender) { let _ = dbqueries::update_none_to_played_now(pd); - shows.update_widget(); + sender.send(Action::RefreshWidget).unwrap(); } From 88a4c2d9f026d5cc2d324e0262db36f2bf8ca517 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 12 Jan 2018 00:33:58 +0200 Subject: [PATCH 175/278] gitlab-ci: Disable nightly builds and clippy. --- .gitlab-ci.yml | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 65084e8..0f9f325 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,9 +11,6 @@ before_script: - apt-get install -yqq --no-install-recommends libgtk-3-dev # - apt-get install -yqq --no-install-recommends meson -# kcov -# - apt-get install -y libcurl4-openssl-dev libelf-dev libdw-dev cmake gcc binutils-dev libiberty-dev - .cargo_test_template: &cargo_test stage: test script: @@ -34,10 +31,10 @@ stable:test: image: "rust" <<: *cargo_test -nightly:test: - # https://hub.docker.com/r/rustlang/rust/ - image: "rustlang/rust:nightly" - <<: *cargo_test +# nightly:test: +# # https://hub.docker.com/r/rustlang/rust/ +# image: "rustlang/rust:nightly" +# <<: *cargo_test # Configure and run rustfmt on nightly # Exits and builds fails if on bad format @@ -53,12 +50,12 @@ rustfmt: # Configure and run clippy on nightly # Only fails on errors atm. -clippy: - image: "rustlang/rust:nightly" - stage: lint - script: - - rustc --version && cargo --version - - cargo install clippy --force - # Force regeneration of gresources regardless of artifacts chage - - cd hammond-gtk/resources/ && glib-compile-resources --generate resources.xml && cd ../../ - - cargo clippy --all +# clippy: +# image: "rustlang/rust:nightly" +# stage: lint +# script: +# - rustc --version && cargo --version +# - cargo install clippy --force +# # Force regeneration of gresources regardless of artifacts chage +# - cd hammond-gtk/resources/ && glib-compile-resources --generate resources.xml && cd ../../ +# - cargo clippy --all From e192cf661834907117b53a603d9310ee58911d34 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 12 Jan 2018 01:41:36 +0200 Subject: [PATCH 176/278] Headerbar: Use application action channel instead of GAction. --- hammond-gtk/resources/gtk/headerbar.ui | 3 +-- hammond-gtk/src/app.rs | 16 +++------------- hammond-gtk/src/headerbar.rs | 7 +++++++ 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/hammond-gtk/resources/gtk/headerbar.ui b/hammond-gtk/resources/gtk/headerbar.ui index 00fa466..e728022 100644 --- a/hammond-gtk/resources/gtk/headerbar.ui +++ b/hammond-gtk/resources/gtk/headerbar.ui @@ -307,11 +307,10 @@ Tobias Bernard - + True True True - app.update Check for new episodes diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index 1c214b2..bc9890d 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -2,7 +2,7 @@ use gtk; use glib; use gio; use gtk::prelude::*; -use gio::{ActionMapExt, ApplicationExt, ApplicationExtManual, SimpleActionExt}; +use gio::{ApplicationExt, ApplicationExtManual}; use hammond_data::utils::checkup; use hammond_data::{Podcast, Source}; @@ -86,17 +86,6 @@ impl App { } } - pub fn setup_actions(&self) { - // Updates the database and refreshes every view. - let update = gio::SimpleAction::new("update", None); - let header = self.header.clone(); - let sender = self.sender.clone(); - update.connect_activate(move |_, _| { - utils::refresh_feed(header.clone(), None, sender.clone()); - }); - self.app_instance.add_action(&update); - } - pub fn setup_timed_callbacks(&self) { let header = self.header.clone(); let sender = self.sender.clone(); @@ -130,7 +119,6 @@ impl App { build_ui(&window, &app); }); self.setup_timed_callbacks(); - self.setup_actions(); let content = self.content.clone(); let headerbar = self.header.clone(); @@ -141,6 +129,8 @@ impl App { Ok(Action::UpdateSources(source)) => { if let Some(s) = source { utils::refresh_feed(headerbar.clone(), Some(vec![s]), sender.clone()) + } else { + utils::refresh_feed(headerbar.clone(), None, sender.clone()) } } Ok(Action::RefreshAllViews) => content.update(), diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 7c251fb..82839a7 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -16,6 +16,7 @@ pub struct Header { switch: gtk::StackSwitcher, back_button: gtk::Button, show_title: gtk::Label, + update_button: gtk::ModelButton, update_box: gtk::Box, update_label: gtk::Label, update_spinner: gtk::Spinner, @@ -30,6 +31,7 @@ impl Default for Header { let switch: gtk::StackSwitcher = builder.get_object("switch").unwrap(); let back_button: gtk::Button = builder.get_object("back_button").unwrap(); let show_title: gtk::Label = builder.get_object("show_title").unwrap(); + let update_button: gtk::ModelButton = builder.get_object("update_button").unwrap(); let update_box: gtk::Box = builder.get_object("update_notification").unwrap(); let update_label: gtk::Label = builder.get_object("update_label").unwrap(); let update_spinner: gtk::Spinner = builder.get_object("update_spinner").unwrap(); @@ -40,6 +42,7 @@ impl Default for Header { switch, back_button, show_title, + update_button, update_box, update_label, update_spinner, @@ -74,6 +77,10 @@ impl Header { self.add_toggle.set_popover(&add_popover); + self.update_button.connect_clicked(move |_| { + sender.send(Action::UpdateSources(None)).unwrap(); + }); + let switch = &self.switch; let add_toggle = &self.add_toggle; let show_title = &self.show_title; From 01fe5c4730287b3b1df47816a35e1336f1598e2e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 12 Jan 2018 01:48:52 +0200 Subject: [PATCH 177/278] Revert to using light theme. --- hammond-gtk/src/main.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 9dead41..6e4c510 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -74,10 +74,10 @@ fn main() { ); // This set's the app to dark mode. - // It wiil be in the user's preference later but for now - // I will abuse my power and force it on everyone till then :P. - let settings = gtk::Settings::get_default().unwrap(); - settings.set_property_gtk_application_prefer_dark_theme(true); + // It wiil be in the user's preference later. + // Uncomment it to run with the dark theme variant. + // let settings = gtk::Settings::get_default().unwrap(); + // settings.set_property_gtk_application_prefer_dark_theme(true); App::new().run(); } From 58854c2ebd087592b1791f20103acb22d0c6a0a3 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 12 Jan 2018 03:28:02 +0200 Subject: [PATCH 178/278] Update Screenshots and README.md --- README.md | 38 +++++++++++++++++++++++++++----------- assets/episodes_view.png | Bin 0 -> 113893 bytes assets/podcast_widget.png | Bin 110135 -> 0 bytes assets/podcasts_view.png | Bin 522659 -> 0 bytes assets/show_widget.png | Bin 0 -> 121928 bytes assets/shows_view.png | Bin 0 -> 587388 bytes 6 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 assets/episodes_view.png delete mode 100644 assets/podcast_widget.png delete mode 100644 assets/podcasts_view.png create mode 100644 assets/show_widget.png create mode 100644 assets/shows_view.png diff --git a/README.md b/README.md index dbb3a12..15cd239 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,19 @@ # Hammond -## Multithreaded and reliable Gtk+ Podcast client. -This is a prototype of a podcast client written in Rust. + +## A Podcast Client for the GNOME Desktop written in Rust. [![pipeline status](https://gitlab.gnome.org/alatiera/Hammond/badges/master/pipeline.svg)](https://gitlab.gnome.org/alatiera/Hammond/commits/master) -![podcasts_view](./assets/podcasts_view.png) -![podcast_widget](./assets/podcast_widget.png) +### Features -## Getting in Touch -If you have any questions regarding the use or development of Hammond, -want to discuss design or simply hang out, please join us in [#hammond on irc.gnome.org.](irc://irc.gnome.org/#hammond) +* TBA -Sidenote: - -There isn't much documentation yet, so you will probably have question about parts of the Code. +![episdes_view](./assets/episodes_view.png) +![shows_view](./assets/shows_view.png) +![show_widget](./assets/show_widget.png) ## Quick start + The following steps assume you have a working installation of rustc and cargo. If you dont take a look at [rustup.rs](rustup.rs) @@ -25,7 +23,22 @@ cd Hammond/ cargo run -p hammond-gtk --release ``` +## Broken Feed + +Did you found or tried to use a Feed that does not work with hammond ? +Please [open an issue](https://gitlab.gnome.org/alatiera/Hammond/issues/new) and choose the `BrokenFeed` template so we will know and fix it! + +## Getting in Touch + +If you have any questions regarding the use or development of Hammond, +want to discuss design or simply hang out, please join us in [#hammond on irc.gnome.org.](irc://irc.gnome.org/#hammond) + +Sidenote: + +There isn't much documentation yet, so you will probably have question about parts of the Code. + ## Install from soure + ```sh git clone https://gitlab.gnome.org/alatiera/hammond.git cd Hammond/ @@ -40,17 +53,19 @@ You can run `sudo make uninstall` for removal And `make clean` to clean up the enviroment after instalation. ### Flatpak + Flatpak instructions... Soon™. ## Building -### Dependancies +### Dependancies * Rust stable 1.22 or later. * Gtk+ 3.22 or later * Meson **Debian/Ubuntu** + ```sh apt-get update -yqq apt-get install -yqq --no-install-recommends build-essential @@ -58,6 +73,7 @@ apt-get install -yqq --no-install-recommends libgtk-3-dev meson ``` **Fedora** + ```sh dnf install -y gtk3-devel glib2-devel openssl-devel sqlite-devel meson ``` diff --git a/assets/episodes_view.png b/assets/episodes_view.png new file mode 100644 index 0000000000000000000000000000000000000000..e03b5288937b5e1f6d1474cb54fba7aab0baceef GIT binary patch literal 113893 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 literal 0 HcmV?d00001 diff --git a/assets/podcast_widget.png b/assets/podcast_widget.png deleted file mode 100644 index 279a48efe8396d67ae963eab3748a1c0e137f79b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110135 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ξV)q4NYXU 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∈Yq-yz$xGw$u79b51D|7(IpTjDO1omUnCJbh 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�kLdbD>B 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%0D`8{tawjl!#tQxe@Sf5y;mE4gFs!{W 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

ht2excL8ibDx>H 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 literal 0 HcmV?d00001 diff --git a/assets/shows_view.png b/assets/shows_view.png new file mode 100644 index 0000000000000000000000000000000000000000..d02af921c95131e880196a6d96a10c8d8fbe8310 GIT binary patch literal 587388 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

    ;gn+23W11DhUO*{^8 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 z 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

    rQ^TNj393Xyi=DuF+v`K7pE^aot>-(; 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

    ZNm#pM3*-hCrKR#qA(`T^!NoU&oD-Dr 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 literal 0 HcmV?d00001 From e20b96e061a9ccdf06617323b45beed08ed29a18 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 12 Jan 2018 03:36:09 +0200 Subject: [PATCH 179/278] Update CHANGELOG.md --- CHANGELOG => CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) rename CHANGELOG => CHANGELOG.md (59%) diff --git a/CHANGELOG b/CHANGELOG.md similarity index 59% rename from CHANGELOG rename to CHANGELOG.md index 6677a79..31086ac 100644 --- a/CHANGELOG +++ b/CHANGELOG.md @@ -6,5 +6,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] -## [0.3.0] - xxxx-xx-xx +## [0.3.0] - xxxx-01-xx +No Notes where provided prior to this release. + +## [0.2.0] - 2017-11-28 + +No Notes where provided prior to this release. + +## [0.1.0] - 2017-11-13 + +Initial Release \ No newline at end of file From 8e367b7e866ba7aeec7ea12255d76281fdbd452f Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Fri, 12 Jan 2018 08:50:16 +0200 Subject: [PATCH 180/278] Dont ask me how this is working. --- Cargo.lock | 198 ++++++++++---------------- hammond-data/Cargo.toml | 4 + hammond-data/src/errors.rs | 2 + hammond-data/src/lib.rs | 14 +- hammond-data/src/models/queryables.rs | 25 +++- hammond-data/src/pipeline.rs | 110 ++++++++++++++ hammond-downloader/src/downloader.rs | 2 +- hammond-gtk/src/widgets/episode.rs | 2 +- 8 files changed, 223 insertions(+), 134 deletions(-) create mode 100644 hammond-data/src/pipeline.rs diff --git a/Cargo.lock b/Cargo.lock index ba57fd0..e7b7883 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,15 +3,6 @@ name = "adler32" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "advapi32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "aho-corasick" version = "0.6.4" @@ -82,7 +73,7 @@ name = "backtrace-sys" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -95,11 +86,6 @@ dependencies = [ "safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "bitflags" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bitflags" version = "0.9.1" @@ -122,7 +108,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "bytes" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -159,7 +145,7 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -210,15 +196,6 @@ dependencies = [ "build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "crypt32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "debug_unreachable" version = "0.1.1" @@ -351,32 +328,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "fuchsia-zircon" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "fuchsia-zircon-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -575,17 +536,21 @@ dependencies = [ "diesel_migrations 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "dotenv 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)", + "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2-diesel 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "rfc822_sanitizer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "rss 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "xdg 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -598,7 +563,7 @@ dependencies = [ "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hammond-data 0.1.0", - "hyper 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -648,7 +613,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "markup5ever 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "markup5ever 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -665,21 +630,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "hyper" -version = "0.11.10" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -692,9 +657,9 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -721,7 +686,7 @@ dependencies = [ [[package]] name = "itertools" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -758,7 +723,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazycell" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -836,7 +801,7 @@ dependencies = [ [[package]] name = "markup5ever" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", @@ -920,14 +885,14 @@ dependencies = [ [[package]] name = "mio" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", @@ -953,7 +918,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1025,15 +990,15 @@ dependencies = [ "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.23" +version = "0.9.24" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", "pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "vcpkg 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1092,7 +1057,7 @@ version = "0.7.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1150,20 +1115,21 @@ dependencies = [ [[package]] name = "rand" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rand" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1184,12 +1150,12 @@ dependencies = [ "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "redox_syscall" -version = "0.1.34" +version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1197,7 +1163,7 @@ name = "redox_termios" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "redox_syscall 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1230,9 +1196,9 @@ name = "reqwest" version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1241,7 +1207,7 @@ dependencies = [ "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_urlencoded 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1284,16 +1250,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "schannel" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1314,15 +1275,6 @@ name = "scopeguard" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "secur32-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "security-framework" version = "0.1.16" @@ -1486,7 +1438,7 @@ name = "tempdir" version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1505,7 +1457,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1524,20 +1476,20 @@ version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "tokio-core" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1548,7 +1500,7 @@ name = "tokio-io" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1561,11 +1513,11 @@ dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1585,7 +1537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)", "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", "tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1667,7 +1619,7 @@ name = "uuid" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1730,7 +1682,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum adler32 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6cbd0b9af8587c72beadc9f72d35b9fbb070982c9e6203e46e93f10df25f8f45" -"checksum advapi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e06588080cb19d0acb6739808aafa5f26bfb2ca015b2b6370028b44cf7cb8a9a" "checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" "checksum ammonia 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f1b9ec9f0a4d43499276dfba49b3e92bf9081e8f2206386caa02237bc71e1beb" "checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455" @@ -1740,23 +1691,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2" "checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661" "checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4" -"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d" "checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" "checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" "checksum build_const 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e90dc84f5e62d2ebe7676b83c22d33b6db8bd27340fb6ffbff0a364efa0cb9c9" "checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23" -"checksum bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d828f97b58cc5de3e40c421d0cf2132d6b2da4ee0e11b8632fa838f0f9333ad6" +"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9" "checksum c_vec 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6237ac5a4b1e81c213c24c6437964c61e646df910a914b4ab1487b46df20bd13" "checksum cairo-rs 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6b5695f59fd036fe5741bc5a4eb20c78fbe42256e3b08a2af26bbcbe8070bf3" "checksum cairo-sys-rs 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c6e18fecaeac51809db57f45f4553cc0975225a7eb435a7a7e91e5e8113a84d" -"checksum cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a9b13a57efd6b30ecd6598ebdb302cca617930b5470647570468a65d12ef9719" +"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0" "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" "checksum chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c20ebe0b2b08b0aeddba49c609fe7957ba2e33449882cb186a180bc60682fa9" "checksum coco 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c06169f5beb7e31c7c67ebf5540b8b472d23e3eade3b2ec7d1f5b504a85f91bd" "checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" "checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" "checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7" -"checksum crypt32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e34988f7e069e0b2f3bfc064295161e489b2d4e04a2e4248fb94360cdf00b4ec" "checksum debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9a032eac705ca39214d169f83e3d3da290af06d8d1d344d1baad2fd002dca4b3" "checksum derive-error-chain 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9ca9ade651388daad7c993f005d0d20c4f6fe78c1cdc93e95f161c6f5ede4a" "checksum derive_builder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c998e6ab02a828dd9735c18f154e14100e674ed08cb4e1938f0e4177543f439" @@ -1773,10 +1722,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" -"checksum fuchsia-zircon 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bd510087c325af53ba24f3be8f1c081b0982319adcb8b03cad764512923ccc19" -"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82" -"checksum fuchsia-zircon-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "08b3a6f13ad6b96572b53ce7af74543132f1a7055ccceb6d073dd36c54481859" +"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" "checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3" "checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1" "checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" @@ -1796,17 +1743,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum html5ever 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e579ac8647178ab915d400d7d22938bda5cd351c6c62e1c294d56884ccfc75fe" "checksum httparse 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "af2f2dd97457e8fb1ae7c5a420db346af389926e36f43768b96f101546b04a07" "checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e" -"checksum hyper 0.11.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4844b207be8393981c5fcb61c9372d7c96432fcc8f5c3431a255a9d19b5c298b" +"checksum hyper 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)" = "856a5eb897fbc26890ddf8760ad4bbfc6bd777233522d9c48379ca9563d40517" "checksum hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c81fa95203e2a6087242c38691a0210f23e9f3f8f944350bd676522132e2985" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7" -"checksum itertools 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "947aa0b9bb417792efa3936c5dada2d680b3bc27ea6a88ffa062f4c4d86ef8c5" +"checksum itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b07332223953b5051bceb67e8c4700aa65291535568e1f12408c43c4a42c0394" "checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" "checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" "checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum lazycell 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3b585b7a6811fb03aa10e74b278a0f00f8dd9b45dc681f148bb29fa5cb61859b" +"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef" "checksum libc 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)" = "96264e9b293e95d25bfcbbf8a88ffd1aedc85b754eba8b7d78012f638ba220eb" "checksum libflate 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "1a429b86418868c7ea91ee50e9170683f47fd9d94f5375438ec86ec3adb74e8e" "checksum libsqlite3-sys 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "370090ad578ba845a3ad4f383ceb3deba7abd51ab1915ad1f2c982cc6035e31c" @@ -1816,7 +1763,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum mac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" "checksum maplit 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ed95049d40b8a1a7691adbabca028ad481f7e6a2921ce4846e1ee168b4e4ca5" "checksum markup5ever 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2cf89d3e0486c32c9d99521455ddf9a438910a1ce2bd376936086edc15dff5fc" -"checksum markup5ever 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7bccd18e4fab95f4410dc4d714163c2e88dd80e39a2a013998e345f337a569ab" +"checksum markup5ever 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c220b3a3d75543b76e5c1fcab6635a8430ab5f9bfa011d003c3787ae0abf4ffa" "checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376" "checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" "checksum migrations_internals 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd5248cbbe4f45d5b4e6cf13a9f37aa587d31c41d2d8b80a0bf0aaf2e30c862d" @@ -1825,7 +1772,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd" "checksum mime_guess 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dc7e82a15629bb4ecd9e72365bf33d1382be91e030f820edb8e2a21c02430da8" "checksum mime_guess 2.0.0-alpha.3 (registry+https://github.com/rust-lang/crates.io-index)" = "013572795763289e14710c7b279461295f2673b2b338200c235082cd7ca9e495" -"checksum mio 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0e8411968194c7b139e9105bc4ae7db0bae232af087147e72f0616ebf5fdb9cb" +"checksum mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "75f72a93f046f1517e3cfddc0a096eb756a2ba727d36edc8227dee769a50a9b0" "checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" "checksum native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04b781c9134a954c84f0594b9ab3f5606abc516030388e8511887ef4c204a1e5" "checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09" @@ -1836,7 +1783,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum open 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c281318d992e4432cfa799969467003d05921582a7489a8325e37f8a450d5113" "checksum openssl 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "169a4b9160baf9b9b1ab975418c673686638995ba921683a7f1e01470dcb8854" -"checksum openssl-sys 0.9.23 (registry+https://github.com/rust-lang/crates.io-index)" = "2200ffec628e3f14c39fc0131a301db214f1a7d584e36507ee8700b0c7fb7a46" +"checksum openssl-sys 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "14ba54ac7d5a4eabd1d5f2c1fdeb7e7c14debfa669d94b983d01b465e767ba9e" "checksum pango 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e81c404ab81ea7ea2fc2431a0a7672507b80e4b8bf4b41eac3fc83cc665104e" "checksum pango-sys 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34f34a1be107fe16abb2744e0e206bee4b3b07460b5fddd3009a6aaf60bd69ab" "checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" @@ -1850,11 +1797,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f9078ca6a8a5568ed142083bb2f7dc9295b69d16f867ddcc9849e51b17d8db46" "checksum r2d2-diesel 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9c29bad92da76d02bc2c020452ebc3a3fe6fa74cfab91e711c43116e4fb1a3" -"checksum rand 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "9e7944d95d25ace8f377da3ac7068ce517e4c646754c43a1b1849177bbf72e59" -"checksum rand 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d5f78082e6a6d042862611e9640cf20776185fee506cf6cf67e93c6225cee31" +"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1" +"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5" "checksum rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed02d09394c94ffbdfdc755ad62a132e94c3224a8354e78a1200ced34df12edf" "checksum rayon-core 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e64b609139d83da75902f88fd6c01820046840a18471e4dfcd5ac7c0f46bea53" -"checksum redox_syscall 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "df1a5c588807af3b0cbbfa2f1358f2d5ec6ad546858c1ccd30dfbb127021706b" +"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "744554e01ccbd98fff8c457c3b092cd67af62a555a43bfe97ae8a0451f7799fa" "checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" @@ -1865,11 +1812,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" -"checksum schannel 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "4330c2e874379fbd28fa67ba43239dbe8c7fb00662ceb1078bd37474f08bf5ce" +"checksum schannel 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "acece75e0f987c48863a6c792ec8b7d6c4177d4a027f8ccc72f849794f437016" "checksum scheduled-thread-pool 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a2ff3fc5223829be817806c6441279c676e454cc7da608faf03b0ccc09d3889" "checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d" "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum secur32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3f412dfa83308d893101dd59c10d6fda8283465976c28c287c5c855bf8d216bc" "checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" "checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" "checksum send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c620dd7e056b468b9d374a9f51cfa6bb4bf17a8ca4ee62e5efa0d99aaff2c41" @@ -1894,7 +1840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" "checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" -"checksum tokio-core 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c87c27560184212c9dc45cd8f38623f37918248aad5b58fb65303b5d07a98c6e" +"checksum tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "52b4e32d8edbf29501aabb3570f027c6ceb00ccef6538f4bddba0200503e74e8" "checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743" "checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389" "checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162" diff --git a/hammond-data/Cargo.toml b/hammond-data/Cargo.toml index 458572f..eacdd51 100644 --- a/hammond-data/Cargo.toml +++ b/hammond-data/Cargo.toml @@ -21,6 +21,10 @@ rfc822_sanitizer = "0.3.3" rss = "1.2.1" url = "1.6.0" xdg = "2.1.0" +futures = "0.1.17" +hyper = "0.11.12" +tokio-core = "0.1.12" +hyper-tls = "0.1.2" [dependencies.diesel] features = ["sqlite"] diff --git a/hammond-data/src/errors.rs b/hammond-data/src/errors.rs index 274a1a1..acdae74 100644 --- a/hammond-data/src/errors.rs +++ b/hammond-data/src/errors.rs @@ -3,6 +3,7 @@ use diesel_migrations::RunMigrationsError; use rss; use reqwest; use r2d2; +use hyper; use std::io; @@ -13,6 +14,7 @@ error_chain! { DieselMigrationError(RunMigrationsError); RSSError(rss::Error); ReqError(reqwest::Error); + HyperError(hyper::Error); IoError(io::Error); } } diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index cde29e9..74a779b 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -15,10 +15,11 @@ non_shorthand_field_patterns, no_mangle_generic_items, overflowing_literals, path_statements, patterns_in_fns_without_body, plugin_as_library, private_in_public, private_no_mangle_fns, private_no_mangle_statics, safe_extern_statics, - unconditional_recursion, unions_with_drop_fields, unused, unused_allocation, - unused_comparisons, unused_parens, while_true)] -#![deny(missing_debug_implementations, missing_docs, trivial_casts, trivial_numeric_casts, - unused_extern_crates)] + unconditional_recursion, unions_with_drop_fields, unused_allocation, unused_comparisons, + unused_parens, while_true)] +#![deny(missing_debug_implementations, missing_docs, trivial_casts, trivial_numeric_casts)] +// FIXME: uncomment +// unused_extern_crates, unused)] #[macro_use] extern crate error_chain; @@ -40,6 +41,9 @@ extern crate derive_builder; extern crate ammonia; extern crate chrono; +extern crate futures; +extern crate hyper; +extern crate hyper_tls; extern crate itertools; extern crate r2d2; extern crate r2d2_diesel; @@ -47,6 +51,7 @@ extern crate rayon; extern crate reqwest; extern crate rfc822_sanitizer; extern crate rss; +extern crate tokio_core; extern crate url; extern crate xdg; @@ -60,6 +65,7 @@ pub mod database; pub(crate) mod models; mod parser; mod schema; +mod pipeline; pub use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 6779abc..5825a74 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -6,6 +6,7 @@ use reqwest; use diesel::SaveChangesDsl; use reqwest::header::{ETag, LastModified}; use rss::Channel; +use hyper; use schema::{episode, podcast, source}; use feed::Feed; @@ -574,8 +575,10 @@ impl PodcastCoverQuery { pub struct Source { id: i32, uri: String, - last_modified: Option, - http_etag: Option, + /// FIXME + pub last_modified: Option, + /// FIXME + pub http_etag: Option, } impl<'a> Source { @@ -627,6 +630,24 @@ impl<'a> Source { Ok(()) } + /// Docs + pub fn update_etag2(&mut self, req: &hyper::Response) -> Result<()> { + let headers = req.headers(); + + let etag = headers.get::(); + let lmod = headers.get::(); + + if self.http_etag() != etag.map(|x| x.tag()) || self.last_modified != lmod.map(|x| { + format!("{}", x) + }) { + self.http_etag = etag.map(|x| x.tag().to_string().to_owned()); + self.last_modified = lmod.map(|x| format!("{}", x)); + self.save()?; + } + + Ok(()) + } + /// Helper method to easily save/"sync" current state of self to the Database. pub fn save(&self) -> Result { let db = connection(); diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs new file mode 100644 index 0000000..a05190a --- /dev/null +++ b/hammond-data/src/pipeline.rs @@ -0,0 +1,110 @@ +extern crate futures; +extern crate hyper; +extern crate tokio_core; + +use std::io::{self, Write}; +use std::str::FromStr; +use futures::{Future, Stream}; +// use futures::future::join_all; +use hyper::Client; +use hyper::client::HttpConnector; +use hyper::Method; +use hyper::Uri; +use tokio_core::reactor::Core; +use hyper_tls::HttpsConnector; +// use errors::*; +// use hyper::header::{ETag, LastModified}; + +use Source; + +#[allow(dead_code)] +fn foo() { + let uri = "https://www.rust-lang.org/".parse().unwrap(); + let mut core = Core::new().unwrap(); + let handle = core.handle(); + let client = Client::configure() + .connector(HttpsConnector::new(4, &handle).unwrap()) + .build(&handle); + + let work = client.get(uri).and_then(|res| { + println!("Response: {}", res.status()); + + res.body() + .for_each(|chunk| io::stdout().write_all(&chunk).map_err(From::from)) + }); + + core.run(work).unwrap(); +} + +#[allow(dead_code)] +fn req_constructor( + client: &mut Client>, + s: &mut Source, +) -> Box> { + use hyper::header::{EntityTag, HttpDate, IfModifiedSince, IfNoneMatch}; + + let uri = Uri::from_str(&s.uri()).unwrap(); + let mut req = hyper::Request::new(Method::Get, uri); + + // if !ignore_etags { + if let Some(foo) = s.http_etag() { + req.headers_mut().set(IfNoneMatch::Items(vec![ + EntityTag::new(true, foo.to_owned()), + ])); + } + + if let Some(foo) = s.last_modified() { + if let Ok(x) = foo.parse::() { + req.headers_mut().set(IfModifiedSince(x)); + } + } + // } + + let work = client.request(req); + Box::new(work) +} + +#[cfg(test)] +mod tests { + use super::*; + use futures::future::result; + use rss::Channel; + + use database::truncate_db; + use Source; + + #[test] + fn test_foo() { + foo() + } + + #[test] + fn test_bar() { + truncate_db().unwrap(); + + let mut core = Core::new().unwrap(); + let mut client = Client::configure() + .connector(HttpsConnector::new(4, &core.handle()).unwrap()) + .build(&core.handle()); + + let url = "https://feeds.feedburner.com/InterceptedWithJeremyScahill"; + let mut source = Source::from_url(url).unwrap(); + + let channel = req_constructor(&mut client, &mut source) + .map(|res| { + info!("Status: {}", res.status()); + source.update_etag2(&res); + res + }) + .and_then(|res| res.body().concat2()) + .map(|concat2| concat2.into_iter()) + .map(|iter| { + let utf_8_bytes = iter.collect::>(); + let buf = String::from_utf8_lossy(&utf_8_bytes).into_owned(); + Channel::from_str(&buf).unwrap() + }); + + let chan = core.run(channel).unwrap(); + println!("{:?}", chan); + } +} diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 13f3117..e5aa2a0 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -51,7 +51,7 @@ fn download_into( ct_len.map(|x| info!("File Lenght: {}", x)); ct_type.map(|x| info!("Content Type: {}", x)); - let ext = get_ext(ct_type.cloned()).unwrap_or(String::from("unknown")); + let ext = get_ext(ct_type.cloned()).unwrap_or_else(|| String::from("unknown")); info!("Extension: {}", ext); // Construct a temp file to save desired content. diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 73bd8bd..2ecc4d6 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -142,7 +142,7 @@ impl EpisodeWidget { self.download .connect_clicked(clone!(episode, sender => move |dl| { dl.set_sensitive(false); - on_download_clicked(&mut episode.clone(), sender.clone()); + on_download_clicked(&episode, sender.clone()); })); } From 771b7b38046c12444241a0b0c2ac54e5650fd581 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 13 Jan 2018 01:28:02 +0200 Subject: [PATCH 181/278] Something Something futures. --- hammond-data/src/lib.rs | 1 + hammond-data/src/pipeline.rs | 35 +++++++++++++++++++---------------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index 74a779b..fd293f7 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -20,6 +20,7 @@ #![deny(missing_debug_implementations, missing_docs, trivial_casts, trivial_numeric_casts)] // FIXME: uncomment // unused_extern_crates, unused)] +// #![feature(conservative_impl_trait)] #[macro_use] extern crate error_chain; diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index a05190a..8a26b10 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -1,19 +1,17 @@ -extern crate futures; -extern crate hyper; -extern crate tokio_core; - +use hyper; use std::io::{self, Write}; use std::str::FromStr; use futures::{Future, Stream}; -// use futures::future::join_all; use hyper::Client; use hyper::client::HttpConnector; use hyper::Method; use hyper::Uri; use tokio_core::reactor::Core; use hyper_tls::HttpsConnector; +use rss; // use errors::*; // use hyper::header::{ETag, LastModified}; +// use futures::future::join_all; use Source; @@ -64,11 +62,21 @@ fn req_constructor( Box::new(work) } +#[allow(dead_code)] +fn res_to_channel(res: hyper::Response) -> Box> { + let chan = res.body().concat2().map(|x| x.into_iter()).map(|iter| { + let utf_8_bytes = iter.collect::>(); + let buf = String::from_utf8_lossy(&utf_8_bytes).into_owned(); + rss::Channel::from_str(&buf).unwrap() + }); + // .map_err(|_| ()); + Box::new(chan) +} + #[cfg(test)] mod tests { use super::*; - use futures::future::result; - use rss::Channel; + // use futures::future::result; use database::truncate_db; use Source; @@ -92,19 +100,14 @@ mod tests { let channel = req_constructor(&mut client, &mut source) .map(|res| { - info!("Status: {}", res.status()); - source.update_etag2(&res); + println!("Status: {}", res.status()); + source.update_etag2(&res).unwrap(); res }) - .and_then(|res| res.body().concat2()) - .map(|concat2| concat2.into_iter()) - .map(|iter| { - let utf_8_bytes = iter.collect::>(); - let buf = String::from_utf8_lossy(&utf_8_bytes).into_owned(); - Channel::from_str(&buf).unwrap() - }); + .and_then(|res| res_to_channel(res)); let chan = core.run(channel).unwrap(); + // let c = chan.wait().unwrap(); println!("{:?}", chan); } } From 1dd25f91fd469bc092d5a119261ec82573200dd5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 13 Jan 2018 05:47:23 +0200 Subject: [PATCH 182/278] Minor cleanup --- hammond-data/src/models/queryables.rs | 22 ++++++--- hammond-data/src/pipeline.rs | 70 +++++++++++---------------- 2 files changed, 41 insertions(+), 51 deletions(-) diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 5825a74..b659193 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -8,6 +8,12 @@ use reqwest::header::{ETag, LastModified}; use rss::Channel; use hyper; +// use futures::{future, Future, Stream}; +// use hyper::Client; +// use hyper::client::HttpConnector; +// use hyper::Method; +// use hyper::Uri; + use schema::{episode, podcast, source}; use feed::Feed; use errors::*; @@ -611,6 +617,14 @@ impl<'a> Source { self.http_etag = value.map(|x| x.to_string()); } + /// Helper method to easily save/"sync" current state of self to the Database. + pub fn save(&self) -> Result { + let db = connection(); + let tempdb = db.get()?; + + Ok(self.save_changes::(&*tempdb)?) + } + /// Extract Etag and LastModifier from req, and update self and the /// corresponding db row. fn update_etag(&mut self, req: &reqwest::Response) -> Result<()> { @@ -648,14 +662,6 @@ impl<'a> Source { Ok(()) } - /// Helper method to easily save/"sync" current state of self to the Database. - pub fn save(&self) -> Result { - let db = connection(); - let tempdb = db.get()?; - - Ok(self.save_changes::(&*tempdb)?) - } - /// `Feed` constructor. /// /// Fetches the latest xml Feed. diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index 8a26b10..e37897a 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -1,62 +1,48 @@ +use rss; + use hyper; -use std::io::{self, Write}; -use std::str::FromStr; -use futures::{Future, Stream}; use hyper::Client; use hyper::client::HttpConnector; use hyper::Method; use hyper::Uri; -use tokio_core::reactor::Core; use hyper_tls::HttpsConnector; -use rss; -// use errors::*; // use hyper::header::{ETag, LastModified}; +// use hyper::header::{ETag, LastModified}; + +use futures::{Future, Stream}; // use futures::future::join_all; +use tokio_core::reactor::Core; + +// use std::io::{self, Write}; +use std::str::FromStr; use Source; +// use errors::*; #[allow(dead_code)] -fn foo() { - let uri = "https://www.rust-lang.org/".parse().unwrap(); - let mut core = Core::new().unwrap(); - let handle = core.handle(); - let client = Client::configure() - .connector(HttpsConnector::new(4, &handle).unwrap()) - .build(&handle); - - let work = client.get(uri).and_then(|res| { - println!("Response: {}", res.status()); - - res.body() - .for_each(|chunk| io::stdout().write_all(&chunk).map_err(From::from)) - }); - - core.run(work).unwrap(); -} - -#[allow(dead_code)] -fn req_constructor( +fn request_constructor( + s: &Source, client: &mut Client>, - s: &mut Source, + ignore_etags: bool, ) -> Box> { use hyper::header::{EntityTag, HttpDate, IfModifiedSince, IfNoneMatch}; let uri = Uri::from_str(&s.uri()).unwrap(); let mut req = hyper::Request::new(Method::Get, uri); - // if !ignore_etags { - if let Some(foo) = s.http_etag() { - req.headers_mut().set(IfNoneMatch::Items(vec![ - EntityTag::new(true, foo.to_owned()), - ])); - } + if !ignore_etags { + if let Some(foo) = s.http_etag() { + req.headers_mut().set(IfNoneMatch::Items(vec![ + EntityTag::new(true, foo.to_owned()), + ])); + } - if let Some(foo) = s.last_modified() { - if let Ok(x) = foo.parse::() { - req.headers_mut().set(IfModifiedSince(x)); + if let Some(foo) = s.last_modified() { + if let Ok(x) = foo.parse::() { + req.headers_mut().set(IfModifiedSince(x)); + } } } - // } let work = client.request(req); Box::new(work) @@ -80,11 +66,7 @@ mod tests { use database::truncate_db; use Source; - - #[test] - fn test_foo() { - foo() - } + // use feed::Feed; #[test] fn test_bar() { @@ -98,15 +80,17 @@ mod tests { let url = "https://feeds.feedburner.com/InterceptedWithJeremyScahill"; let mut source = Source::from_url(url).unwrap(); - let channel = req_constructor(&mut client, &mut source) + let channel = request_constructor(&source, &mut client, false) .map(|res| { println!("Status: {}", res.status()); source.update_etag2(&res).unwrap(); res }) .and_then(|res| res_to_channel(res)); + // .map(|chan| Feed::from_channel_source(chan, source)); let chan = core.run(channel).unwrap(); + // let c = chan.wait().unwrap(); println!("{:?}", chan); } From ee9cede921dd575f0cc491d61e6124a34363358e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 13 Jan 2018 06:08:51 +0200 Subject: [PATCH 183/278] hammond_data: Remove Source dependancy from Feed struct. --- hammond-data/src/feed.rs | 24 ++++++++++++------------ hammond-data/src/models/queryables.rs | 4 ++-- hammond-data/src/pipeline.rs | 2 +- hammond-downloader/src/downloader.rs | 2 +- hammond-gtk/src/manager.rs | 2 +- hammond-gtk/src/utils.rs | 2 +- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 750c4a0..8fa4fc9 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -1,4 +1,4 @@ -//! Index and retrieve Feeds. +//! Index Feeds. use rayon::prelude::*; use diesel::prelude::*; @@ -20,20 +20,20 @@ use errors::*; /// that corresponds to the `Source.uri` field. pub struct Feed { channel: rss::Channel, - source: Source, + source_id: i32, } impl Feed { /// Constructor that consumes a `Source` and returns the corresponding `Feed` struct. - pub fn from_source(s: Source) -> Result { + pub fn from_source(s: &mut Source) -> Result { s.into_feed(false) } /// Constructor that consumes a `Source` and a `rss::Channel` returns a `Feed` struct. - pub fn from_channel_source(chan: rss::Channel, s: Source) -> Feed { + pub fn from_channel_source(chan: rss::Channel, s: i32) -> Feed { Feed { channel: chan, - source: s, + source_id: s, } } @@ -68,7 +68,7 @@ impl Feed { } fn parse_channel(&self) -> NewPodcast { - parser::new_podcast(&self.channel, *self.source.id()) + parser::new_podcast(&self.channel, self.source_id) } fn parse_channel_items(&self, pd: &Podcast) -> Vec { @@ -111,7 +111,7 @@ pub fn index(feed: &Feed) { } /// Consume a `Source` and return a `Feed`. -fn fetch(source: Source) -> Result { +fn fetch(source: &mut Source) -> Result { Feed::from_source(source) } @@ -119,8 +119,8 @@ fn fetch(source: Source) -> Result { pub fn index_loop>(sources: S) { sources .into_par_iter() - .filter_map(|x| { - let foo = fetch(x); + .filter_map(|mut x| { + let foo = fetch(&mut x); if let Err(err) = foo { error!("Error: {}", err); None @@ -203,7 +203,7 @@ mod tests { let feed = fs::File::open(path).unwrap(); // parse it into a channel let chan = rss::Channel::read_from(BufReader::new(feed)).unwrap(); - Feed::from_channel_source(chan, s) + Feed::from_channel_source(chan, *s.id()) }) .collect(); @@ -221,8 +221,8 @@ mod tests { truncate_db().unwrap(); let url = "https://feeds.feedburner.com/InterceptedWithJeremyScahill"; - let s1 = Source::from_url(url).unwrap(); - let s2 = Source::from_url(url).unwrap(); + let mut s1 = Source::from_url(url).unwrap(); + let mut s2 = Source::from_url(url).unwrap(); assert_eq!(s1, s2); assert_eq!(s1.id(), s2.id()); diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index b659193..2557e88 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -670,7 +670,7 @@ impl<'a> Source { /// /// Consumes `self` and Returns the corresponding `Feed` Object. // TODO: Refactor into TryInto once it lands on stable. - pub fn into_feed(mut self, ignore_etags: bool) -> Result { + pub fn into_feed(&mut self, ignore_etags: bool) -> Result { use reqwest::header::{EntityTag, Headers, HttpDate, IfModifiedSince, IfNoneMatch}; use reqwest::StatusCode; @@ -725,7 +725,7 @@ impl<'a> Source { req.read_to_string(&mut buf)?; let chan = Channel::from_str(&buf)?; - Ok(Feed::from_channel_source(chan, self)) + Ok(Feed::from_channel_source(chan, self.id)) } /// Construct a new `Source` with the given `uri` and index it. diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index e37897a..ebc6367 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -11,7 +11,6 @@ use hyper_tls::HttpsConnector; use futures::{Future, Stream}; // use futures::future::join_all; -use tokio_core::reactor::Core; // use std::io::{self, Write}; use std::str::FromStr; @@ -63,6 +62,7 @@ fn res_to_channel(res: hyper::Response) -> Box Date: Sat, 13 Jan 2018 07:09:59 +0200 Subject: [PATCH 184/278] This works somehow... --- hammond-data/src/models/queryables.rs | 73 ++++++++++++++++++++++--- hammond-data/src/pipeline.rs | 78 ++------------------------- 2 files changed, 72 insertions(+), 79 deletions(-) diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 2557e88..863d51a 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -6,13 +6,17 @@ use reqwest; use diesel::SaveChangesDsl; use reqwest::header::{ETag, LastModified}; use rss::Channel; -use hyper; -// use futures::{future, Future, Stream}; -// use hyper::Client; -// use hyper::client::HttpConnector; -// use hyper::Method; -// use hyper::Uri; +use hyper; +use hyper::Client; +use hyper::client::HttpConnector; +use hyper::Method; +use hyper::Uri; +use hyper_tls::HttpsConnector; +// use hyper::header::{ETag, LastModified}; + +use futures::{Future, Stream}; +// use futures::future::join_all; use schema::{episode, podcast, source}; use feed::Feed; @@ -728,8 +732,65 @@ impl<'a> Source { Ok(Feed::from_channel_source(chan, self.id)) } + #[allow(dead_code)] + /// Docs + pub fn into_fututre_feed( + &'a mut self, + client: &'a mut Client>, + ignore_etags: bool, + ) -> Box + 'a> { + let id = *self.id(); + let feed = request_constructor(&self, client, ignore_etags) + .map(move |res| { + println!("Status: {}", res.status()); + self.update_etag2(&res).unwrap(); + res + }) + .and_then(move |res| response_to_channel(res)) + .map(move |chan| Feed::from_channel_source(chan, id)); + + Box::new(feed) + } + /// Construct a new `Source` with the given `uri` and index it. pub fn from_url(uri: &str) -> Result { NewSource::new_with_uri(uri).into_source() } } + +fn request_constructor( + s: &Source, + client: &mut Client>, + ignore_etags: bool, +) -> Box> { + use hyper::header::{EntityTag, HttpDate, IfModifiedSince, IfNoneMatch}; + + let uri = Uri::from_str(&s.uri()).unwrap(); + let mut req = hyper::Request::new(Method::Get, uri); + + if !ignore_etags { + if let Some(foo) = s.http_etag() { + req.headers_mut().set(IfNoneMatch::Items(vec![ + EntityTag::new(true, foo.to_owned()), + ])); + } + + if let Some(foo) = s.last_modified() { + if let Ok(x) = foo.parse::() { + req.headers_mut().set(IfModifiedSince(x)); + } + } + } + + let work = client.request(req); + Box::new(work) +} + +fn response_to_channel(res: hyper::Response) -> Box> { + let chan = res.body().concat2().map(|x| x.into_iter()).map(|iter| { + let utf_8_bytes = iter.collect::>(); + let buf = String::from_utf8_lossy(&utf_8_bytes).into_owned(); + Channel::from_str(&buf).unwrap() + }); + Box::new(chan) +} diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index ebc6367..b9d4dab 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -1,72 +1,12 @@ -use rss; - -use hyper; -use hyper::Client; -use hyper::client::HttpConnector; -use hyper::Method; -use hyper::Uri; -use hyper_tls::HttpsConnector; -// use hyper::header::{ETag, LastModified}; -// use hyper::header::{ETag, LastModified}; - -use futures::{Future, Stream}; -// use futures::future::join_all; - -// use std::io::{self, Write}; -use std::str::FromStr; - -use Source; -// use errors::*; - -#[allow(dead_code)] -fn request_constructor( - s: &Source, - client: &mut Client>, - ignore_etags: bool, -) -> Box> { - use hyper::header::{EntityTag, HttpDate, IfModifiedSince, IfNoneMatch}; - - let uri = Uri::from_str(&s.uri()).unwrap(); - let mut req = hyper::Request::new(Method::Get, uri); - - if !ignore_etags { - if let Some(foo) = s.http_etag() { - req.headers_mut().set(IfNoneMatch::Items(vec![ - EntityTag::new(true, foo.to_owned()), - ])); - } - - if let Some(foo) = s.last_modified() { - if let Ok(x) = foo.parse::() { - req.headers_mut().set(IfModifiedSince(x)); - } - } - } - - let work = client.request(req); - Box::new(work) -} - -#[allow(dead_code)] -fn res_to_channel(res: hyper::Response) -> Box> { - let chan = res.body().concat2().map(|x| x.into_iter()).map(|iter| { - let utf_8_bytes = iter.collect::>(); - let buf = String::from_utf8_lossy(&utf_8_bytes).into_owned(); - rss::Channel::from_str(&buf).unwrap() - }); - // .map_err(|_| ()); - Box::new(chan) -} - #[cfg(test)] mod tests { - use super::*; // use futures::future::result; use tokio_core::reactor::Core; + use hyper::Client; + use hyper_tls::HttpsConnector; use database::truncate_db; use Source; - // use feed::Feed; #[test] fn test_bar() { @@ -80,18 +20,10 @@ mod tests { let url = "https://feeds.feedburner.com/InterceptedWithJeremyScahill"; let mut source = Source::from_url(url).unwrap(); - let channel = request_constructor(&source, &mut client, false) - .map(|res| { - println!("Status: {}", res.status()); - source.update_etag2(&res).unwrap(); - res - }) - .and_then(|res| res_to_channel(res)); - // .map(|chan| Feed::from_channel_source(chan, source)); + let feed = source.into_fututre_feed(&mut client, false); - let chan = core.run(channel).unwrap(); + let f = core.run(feed).unwrap(); - // let c = chan.wait().unwrap(); - println!("{:?}", chan); + println!("{:?}", f); } } From e4d77a6ba42e9f43594e7a4dadf96abed6fc2610 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 13 Jan 2018 07:46:56 +0200 Subject: [PATCH 185/278] Cleanup the id() method mess of the diesel models. --- Cargo.lock | 2 -- hammond-data/src/dbqueries.rs | 4 ++-- hammond-data/src/feed.rs | 5 ++--- hammond-data/src/models/insertables.rs | 2 +- hammond-data/src/models/queryables.rs | 14 ++++++++++++-- hammond-downloader/Cargo.toml | 4 ---- hammond-downloader/src/downloader.rs | 3 +-- hammond-downloader/src/errors.rs | 2 -- hammond-downloader/src/lib.rs | 1 - hammond-gtk/Cargo.toml | 4 ---- hammond-gtk/src/main.rs | 1 - hammond-gtk/src/manager.rs | 5 ++--- hammond-gtk/src/utils.rs | 3 +-- hammond-gtk/src/views/shows.rs | 1 - hammond-gtk/src/widgets/show.rs | 1 - 15 files changed, 21 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e7b7883..091ed0d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -559,7 +559,6 @@ dependencies = [ name = "hammond-downloader" version = "0.1.0" dependencies = [ - "diesel 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hammond-data 0.1.0", @@ -575,7 +574,6 @@ name = "hammond-gtk" version = "0.1.0" dependencies = [ "chrono 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "diesel 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "dissolve 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "gdk 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "gdk-pixbuf 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 65236d6..bf89235 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -232,8 +232,8 @@ pub fn remove_feed(pd: &Podcast) -> Result<()> { con.transaction(|| -> Result<()> { delete_source(&con, pd.source_id())?; - delete_podcast(&con, *pd.id())?; - delete_podcast_episodes(&con, *pd.id())?; + delete_podcast(&con, pd.id())?; + delete_podcast_episodes(&con, pd.id())?; info!("Feed removed from the Database."); Ok(()) }) diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 8fa4fc9..fc86ca2 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -4,7 +4,6 @@ use rayon::prelude::*; use diesel::prelude::*; use rayon::iter::IntoParallelIterator; -use diesel::associations::Identifiable; use rss; use dbqueries; @@ -75,7 +74,7 @@ impl Feed { let items = self.channel.items(); let new_episodes: Vec<_> = items .par_iter() - .filter_map(|item| parser::new_episode(item, *pd.id()).ok()) + .filter_map(|item| parser::new_episode(item, pd.id()).ok()) .collect(); new_episodes @@ -203,7 +202,7 @@ mod tests { let feed = fs::File::open(path).unwrap(); // parse it into a channel let chan = rss::Channel::read_from(BufReader::new(feed)).unwrap(); - Feed::from_channel_source(chan, *s.id()) + Feed::from_channel_source(chan, s.id()) }) .collect(); diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index 8f2689a..e66f54f 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -113,7 +113,7 @@ impl NewPodcast { if (foo.link() != self.link) || (foo.title() != self.title) || (foo.image_uri() != self.image_uri.as_ref().map(|x| x.as_str())) { - self.update(&con, *foo.id())?; + self.update(&con, foo.id())?; } } Err(_) => { diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 863d51a..7c40be0 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -451,6 +451,11 @@ pub struct Podcast { } impl Podcast { + /// Get the Feed `id`. + pub fn id(&self) -> i32 { + self.id + } + /// Get the Feed `title`. pub fn title(&self) -> &str { &self.title @@ -551,7 +556,7 @@ pub struct PodcastCoverQuery { impl From for PodcastCoverQuery { fn from(p: Podcast) -> PodcastCoverQuery { PodcastCoverQuery { - id: *p.id(), + id: p.id(), title: p.title, image_uri: p.image_uri, } @@ -592,6 +597,11 @@ pub struct Source { } impl<'a> Source { + /// Get the source `id` column. + pub fn id(&self) -> i32 { + self.id + } + /// Represents the location(usually url) of the Feed xml file. pub fn uri(&self) -> &str { &self.uri @@ -739,7 +749,7 @@ impl<'a> Source { client: &'a mut Client>, ignore_etags: bool, ) -> Box + 'a> { - let id = *self.id(); + let id = self.id(); let feed = request_constructor(&self, client, ignore_etags) .map(move |res| { println!("Status: {}", res.status()); diff --git a/hammond-downloader/Cargo.toml b/hammond-downloader/Cargo.toml index f541ba8..ada57e7 100644 --- a/hammond-downloader/Cargo.toml +++ b/hammond-downloader/Cargo.toml @@ -13,9 +13,5 @@ reqwest = "0.8.2" tempdir = "0.3.5" glob = "0.2.11" -[dependencies.diesel] -features = ["sqlite"] -version = "1.0.0" - [dependencies.hammond-data] path = "../hammond-data" diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index b1e9679..09d2e44 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -219,7 +219,6 @@ mod tests { use hammond_data::Source; use hammond_data::feed::index; use hammond_data::dbqueries; - use diesel::associations::Identifiable; #[test] // This test inserts an rss feed to your `XDG_DATA/hammond/hammond.db` so we make it explicit @@ -231,7 +230,7 @@ mod tests { // Create and index a source let mut source = Source::from_url(url).unwrap(); // Copy it's id - let sid = source.id().clone(); + let sid = source.id(); // Convert Source it into a Feed and index it let feed = source.into_feed(true).unwrap(); diff --git a/hammond-downloader/src/errors.rs b/hammond-downloader/src/errors.rs index 297d7eb..4b019c5 100644 --- a/hammond-downloader/src/errors.rs +++ b/hammond-downloader/src/errors.rs @@ -1,4 +1,3 @@ -use diesel::result; use reqwest; use hammond_data; use std::io; @@ -7,7 +6,6 @@ error_chain! { foreign_links { ReqError(reqwest::Error); IoError(io::Error); - DieselResultError(result::Error); DataError(hammond_data::errors::Error); } } diff --git a/hammond-downloader/src/lib.rs b/hammond-downloader/src/lib.rs index 9e57db8..197da0d 100644 --- a/hammond-downloader/src/lib.rs +++ b/hammond-downloader/src/lib.rs @@ -1,6 +1,5 @@ #![recursion_limit = "1024"] -extern crate diesel; #[macro_use] extern crate error_chain; extern crate glob; diff --git a/hammond-gtk/Cargo.toml b/hammond-gtk/Cargo.toml index db947d5..0dc8267 100644 --- a/hammond-gtk/Cargo.toml +++ b/hammond-gtk/Cargo.toml @@ -21,10 +21,6 @@ rayon = "0.9.0" regex = "0.2.3" send-cell = "0.1.2" -[dependencies.diesel] -features = ["sqlite"] -version = "1.0.0" - [dependencies.gtk] features = ["v3_22"] version = "0.3.0" diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 6e4c510..7f63acd 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -7,7 +7,6 @@ extern crate glib; extern crate gtk; extern crate chrono; -extern crate diesel; extern crate dissolve; extern crate hammond_data; extern crate hammond_downloader; diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index 2c426af..f6ba174 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -117,7 +117,6 @@ pub fn add(id: i32, directory: &str, sender: Sender) { #[cfg(test)] mod tests { use super::*; - use diesel::Identifiable; use hammond_data::database; use hammond_data::utils::get_download_folder; @@ -141,7 +140,7 @@ mod tests { // Create and index a source let mut source = Source::from_url(url).unwrap(); // Copy it's id - let sid = source.id().clone(); + let sid = source.id(); // Convert Source it into a Feed and index it let feed = source.into_feed(true).unwrap(); @@ -152,7 +151,7 @@ mod tests { // Get an episode let episode: Episode = { let con = database::connection(); - dbqueries::get_episode_from_pk(&*con.get().unwrap(), "e000: Hello, world!", *pd.id()) + dbqueries::get_episode_from_pk(&*con.get().unwrap(), "e000: Hello, world!", pd.id()) .unwrap() }; diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index c97aafa..1f55c5f 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -70,7 +70,6 @@ mod tests { use hammond_data::Source; use hammond_data::feed::index; use hammond_data::dbqueries; - use diesel::associations::Identifiable; use super::*; #[test] @@ -83,7 +82,7 @@ mod tests { // Create and index a source let mut source = Source::from_url(url).unwrap(); // Copy it's id - let sid = source.id().clone(); + let sid = source.id(); // Convert Source it into a Feed and index it let feed = source.into_feed(true).unwrap(); diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index 3a5b40b..72a5b1e 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -1,6 +1,5 @@ use gtk; use gtk::prelude::*; -use diesel::associations::Identifiable; use hammond_data::dbqueries; use hammond_data::Podcast; diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index 1b08638..c67db1d 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -1,6 +1,5 @@ use gtk::prelude::*; use gtk; -use diesel::Identifiable; use open; use dissolve; From e162f8fd3f9ac90b58ee0b864e260eb50dacd5e1 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 13 Jan 2018 08:31:16 +0200 Subject: [PATCH 186/278] Non-working yet benchmark. --- hammond-data/benches/bench.rs | 48 ++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/hammond-data/benches/bench.rs b/hammond-data/benches/bench.rs index d721878..d6dd37d 100644 --- a/hammond-data/benches/bench.rs +++ b/hammond-data/benches/bench.rs @@ -1,19 +1,29 @@ #![feature(test)] extern crate diesel; +extern crate futures; extern crate hammond_data; +extern crate hyper; +extern crate hyper_tls; extern crate rand; extern crate rayon; extern crate rss; extern crate tempdir; extern crate test; +extern crate tokio_core; use rayon::prelude::*; use test::Bencher; +use tokio_core::reactor::Core; +use hyper::Client; +use hyper_tls::HttpsConnector; +use futures::future::*; + use hammond_data::Source; use hammond_data::feed::*; +use hammond_data::database::truncate_db; use std::io::BufReader; @@ -39,7 +49,7 @@ fn index_urls() { let s = Source::from_url(url).unwrap(); // parse it into a channel let chan = rss::Channel::read_from(BufReader::new(buff)).unwrap(); - Feed::from_channel_source(chan, s) + Feed::from_channel_source(chan, s.id()) }) .collect(); @@ -64,3 +74,39 @@ fn bench_index_unchanged_feeds(b: &mut Bencher) { } }); } + +#[bench] +fn bench_get_normal_feeds(b: &mut Bencher) { + truncate_db().unwrap(); + + b.iter(|| { + URLS.iter().for_each(|&(_, url)| { + let mut s = Source::from_url(url).unwrap(); + s.into_feed(true).unwrap(); + }) + }); +} + +#[bench] +fn bench_get_future_feeds(b: &mut Bencher) { + truncate_db().unwrap(); + + b.iter(|| { + let mut core = Core::new().unwrap(); + let mut handle = core.handle(); + let mut client = Client::configure() + .connector(HttpsConnector::new(4, &handle).unwrap()) + .build(&handle); + + let mut foo: Vec<_>; + + URLS.iter().for_each(|&(_, url)| { + let mut s = Source::from_url(url).unwrap(); + let future = s.into_fututre_feed(&mut client, true); + foo.push(future); + }); + + let work = join_all(foo); + core.run(work).unwrap(); + }); +} From a5fd79e220cf7dcc23d59d632603517e9922ad3e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sat, 13 Jan 2018 14:47:38 +0200 Subject: [PATCH 187/278] I hate futures error handling. --- hammond-data/benches/bench.rs | 50 +++++++++++++------ hammond-data/src/models/queryables.rs | 71 ++++++++++++++++++++------- hammond-data/src/pipeline.rs | 28 ----------- 3 files changed, 86 insertions(+), 63 deletions(-) diff --git a/hammond-data/benches/bench.rs b/hammond-data/benches/bench.rs index d6dd37d..bcbc7c0 100644 --- a/hammond-data/benches/bench.rs +++ b/hammond-data/benches/bench.rs @@ -1,6 +1,5 @@ #![feature(test)] -extern crate diesel; extern crate futures; extern crate hammond_data; extern crate hyper; @@ -8,11 +7,10 @@ extern crate hyper_tls; extern crate rand; extern crate rayon; extern crate rss; -extern crate tempdir; extern crate test; extern crate tokio_core; -use rayon::prelude::*; +// use rayon::prelude::*; use test::Bencher; @@ -42,8 +40,26 @@ static URLS: &[(&[u8], &str)] = &[ (LAS, "https://feeds2.feedburner.com/TheLinuxActionShow"), ]; +static URLS2: &[&str] = &[ + "https://feeds.feedburner.com/InterceptedWithJeremyScahill", + "http://www.badvoltage.org/feed/ogg/", + "https://www.theguardian.com/news/series/the-audio-long-read/podcast.xml", + "http://feeds.feedburner.com/coderradiomp3", + "https://rss.art19.com/steal-the-stars", + "https://feeds.mozilla-podcasts.org/irl", + "http://economicupdate.libsyn.com/rss", + "http://feeds.feedburner.com/linuxunplugged", + "http://ubuntupodcast.org/feed/ogg/", + "http://www.newrustacean.com/feed.xml", + "http://feeds.propublica.org/propublica/podcast", + "https://rss.acast.com/thetipoff", + "http://feeds.soundcloud.com/users/soundcloud:users:277306156/sounds.rss", + "http://revolutionspodcast.libsyn.com/rss/", + "https://www.greaterthancode.com/feed/podcast", +]; + fn index_urls() { - let feeds: Vec<_> = URLS.par_iter() + let feeds: Vec<_> = URLS.iter() .map(|&(buff, url)| { // Create and insert a Source into db let s = Source::from_url(url).unwrap(); @@ -53,7 +69,7 @@ fn index_urls() { }) .collect(); - feeds.par_iter().for_each(|x| index(x)); + feeds.iter().for_each(|x| index(x)); } #[bench] @@ -77,13 +93,14 @@ fn bench_index_unchanged_feeds(b: &mut Bencher) { #[bench] fn bench_get_normal_feeds(b: &mut Bencher) { + // Index first so it will only bench the comparison test case. truncate_db().unwrap(); b.iter(|| { - URLS.iter().for_each(|&(_, url)| { + URLS2.iter().for_each(|url| { let mut s = Source::from_url(url).unwrap(); - s.into_feed(true).unwrap(); - }) + let _feed = s.into_feed(true); + }); }); } @@ -93,20 +110,21 @@ fn bench_get_future_feeds(b: &mut Bencher) { b.iter(|| { let mut core = Core::new().unwrap(); - let mut handle = core.handle(); - let mut client = Client::configure() + let handle = core.handle(); + let client = Client::configure() .connector(HttpsConnector::new(4, &handle).unwrap()) .build(&handle); - let mut foo: Vec<_>; + let mut foo = vec![]; - URLS.iter().for_each(|&(_, url)| { - let mut s = Source::from_url(url).unwrap(); - let future = s.into_fututre_feed(&mut client, true); + URLS2.iter().for_each(|url| { + let s = Source::from_url(url).unwrap(); + let future = s.into_fututre_feed(&client, true); foo.push(future); }); let work = join_all(foo); - core.run(work).unwrap(); - }); + let res = core.run(work); + assert!(res.is_ok()); + }) } diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 7c40be0..528cf82 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -15,8 +15,7 @@ use hyper::Uri; use hyper_tls::HttpsConnector; // use hyper::header::{ETag, LastModified}; -use futures::{Future, Stream}; -// use futures::future::join_all; +use futures::prelude::*; use schema::{episode, podcast, source}; use feed::Feed; @@ -596,7 +595,7 @@ pub struct Source { pub http_etag: Option, } -impl<'a> Source { +impl Source { /// Get the source `id` column. pub fn id(&self) -> i32 { self.id @@ -659,7 +658,7 @@ impl<'a> Source { } /// Docs - pub fn update_etag2(&mut self, req: &hyper::Response) -> Result<()> { + pub fn update_etag2(mut self, req: &hyper::Response) -> Result<()> { let headers = req.headers(); let etag = headers.get::(); @@ -745,18 +744,21 @@ impl<'a> Source { #[allow(dead_code)] /// Docs pub fn into_fututre_feed( - &'a mut self, - client: &'a mut Client>, + self, + client: &Client>, ignore_etags: bool, - ) -> Box + 'a> { + ) -> Box> { let id = self.id(); let feed = request_constructor(&self, client, ignore_etags) .map(move |res| { - println!("Status: {}", res.status()); - self.update_etag2(&res).unwrap(); + if let Err(err) = self.update_etag2(&res) { + error!("Failed to update Source struct with new etag values"); + error!("Error: {}", err); + }; res }) - .and_then(move |res| response_to_channel(res)) + .map_err(From::from) + .and_then(|res| response_to_channel(res)) .map(move |chan| Feed::from_channel_source(chan, id)); Box::new(feed) @@ -770,11 +772,12 @@ impl<'a> Source { fn request_constructor( s: &Source, - client: &mut Client>, + client: &Client>, ignore_etags: bool, -) -> Box> { +) -> Box> { use hyper::header::{EntityTag, HttpDate, IfModifiedSince, IfNoneMatch}; + // FIXME: remove unwrap let uri = Uri::from_str(&s.uri()).unwrap(); let mut req = hyper::Request::new(Method::Get, uri); @@ -792,15 +795,45 @@ fn request_constructor( } } - let work = client.request(req); + let work = client.request(req).map_err(From::from); Box::new(work) } -fn response_to_channel(res: hyper::Response) -> Box> { - let chan = res.body().concat2().map(|x| x.into_iter()).map(|iter| { - let utf_8_bytes = iter.collect::>(); - let buf = String::from_utf8_lossy(&utf_8_bytes).into_owned(); - Channel::from_str(&buf).unwrap() - }); +fn response_to_channel(res: hyper::Response) -> Box> { + let chan = res.body() + .concat2() + .map(|x| x.into_iter()) + .map_err(From::from) + .and_then(|iter| { + let utf_8_bytes = iter.collect::>(); + let buf = String::from_utf8_lossy(&utf_8_bytes).into_owned(); + let chan = Channel::from_str(&buf).map_err(From::from); + chan + }); Box::new(chan) } + +#[cfg(test)] +mod tests { + use super::*; + use tokio_core::reactor::Core; + + use database::truncate_db; + + #[test] + fn test_into_future_feed() { + truncate_db().unwrap(); + + let mut core = Core::new().unwrap(); + let client = Client::configure() + .connector(HttpsConnector::new(4, &core.handle()).unwrap()) + .build(&core.handle()); + + let url = "http://www.newrustacean.com/feed.xml"; + let source = Source::from_url(url).unwrap(); + + let feed = source.into_fututre_feed(&client, true); + + assert!(core.run(feed).is_ok()); + } +} diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index b9d4dab..8b13789 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -1,29 +1 @@ -#[cfg(test)] -mod tests { - // use futures::future::result; - use tokio_core::reactor::Core; - use hyper::Client; - use hyper_tls::HttpsConnector; - use database::truncate_db; - use Source; - - #[test] - fn test_bar() { - truncate_db().unwrap(); - - let mut core = Core::new().unwrap(); - let mut client = Client::configure() - .connector(HttpsConnector::new(4, &core.handle()).unwrap()) - .build(&core.handle()); - - let url = "https://feeds.feedburner.com/InterceptedWithJeremyScahill"; - let mut source = Source::from_url(url).unwrap(); - - let feed = source.into_fututre_feed(&mut client, false); - - let f = core.run(feed).unwrap(); - - println!("{:?}", f); - } -} From d60dbfbd6bf8215b66fb8733550592e30d913c58 Mon Sep 17 00:00:00 2001 From: Tobias Bernard Date: Sat, 13 Jan 2018 15:16:22 +0000 Subject: [PATCH 188/278] Fix some typos in README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 15cd239..2758805 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,9 @@ cd Hammond/ cargo run -p hammond-gtk --release ``` -## Broken Feed +## Broken Feeds -Did you found or tried to use a Feed that does not work with hammond ? +Found a feed that does not work in Hammond? Please [open an issue](https://gitlab.gnome.org/alatiera/Hammond/issues/new) and choose the `BrokenFeed` template so we will know and fix it! ## Getting in Touch @@ -33,7 +33,7 @@ Please [open an issue](https://gitlab.gnome.org/alatiera/Hammond/issues/new) and If you have any questions regarding the use or development of Hammond, want to discuss design or simply hang out, please join us in [#hammond on irc.gnome.org.](irc://irc.gnome.org/#hammond) -Sidenote: +Note: There isn't much documentation yet, so you will probably have question about parts of the Code. @@ -46,7 +46,7 @@ cd Hammond/ make && sudo make install ``` -**Additionall:** +**Additional:** You can run `sudo make uninstall` for removal @@ -58,7 +58,7 @@ Flatpak instructions... Soon™. ## Building -### Dependancies +### Dependencies * Rust stable 1.22 or later. * Gtk+ 3.22 or later @@ -128,9 +128,9 @@ It has nothing to do with the horrible headlines on the news. ## Acknowledgments -Hammond's design is heavily insired by [Gnome-Music](https://wiki.gnome.org/Design/Apps/Music) and [Vocal](http://vocalproject.net/). +Hammond's design is heavily insired by [GNOME Music](https://wiki.gnome.org/Design/Apps/Music) and [Vocal](http://vocalproject.net/). -We also copied some elements from [Gnome-news](https://wiki.gnome.org/Design/Apps/Potential/News). +We also copied some elements from [GNOME News](https://wiki.gnome.org/Design/Apps/Potential/News). And almost the entirety of the build system is copied from the [Fractal](https://gitlab.gnome.org/danigm/fractal) project. From 1031315cdd432f9f36ea4183b178b47aeec5279d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 14 Jan 2018 06:37:47 +0200 Subject: [PATCH 189/278] Getting somewhere? --- Cargo.lock | 1 + hammond-data/Cargo.toml | 1 + hammond-data/src/errors.rs | 2 + hammond-data/src/feed.rs | 3 +- hammond-data/src/lib.rs | 3 +- hammond-data/src/models/queryables.rs | 1 + hammond-data/src/pipeline.rs | 65 +++++++++++++++++++++++++++ hammond-gtk/src/utils.rs | 19 +++++--- 8 files changed, 88 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 091ed0d..64d6542 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -542,6 +542,7 @@ dependencies = [ "itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "native-tls 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "r2d2-diesel 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/hammond-data/Cargo.toml b/hammond-data/Cargo.toml index eacdd51..13b6037 100644 --- a/hammond-data/Cargo.toml +++ b/hammond-data/Cargo.toml @@ -25,6 +25,7 @@ futures = "0.1.17" hyper = "0.11.12" tokio-core = "0.1.12" hyper-tls = "0.1.2" +native-tls = "0.1.4" [dependencies.diesel] features = ["sqlite"] diff --git a/hammond-data/src/errors.rs b/hammond-data/src/errors.rs index acdae74..7f8f88a 100644 --- a/hammond-data/src/errors.rs +++ b/hammond-data/src/errors.rs @@ -4,6 +4,7 @@ use rss; use reqwest; use r2d2; use hyper; +use native_tls; use std::io; @@ -15,6 +16,7 @@ error_chain! { RSSError(rss::Error); ReqError(reqwest::Error); HyperError(hyper::Error); + TLSError(native_tls::Error); IoError(io::Error); } } diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index fc86ca2..0add944 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -36,7 +36,8 @@ impl Feed { } } - fn index(&self) -> Result<()> { + /// docs + pub fn index(&self) -> Result<()> { let pd = self.get_podcast()?; self.index_channel_items(&pd) } diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index fd293f7..96a190d 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -46,6 +46,7 @@ extern crate futures; extern crate hyper; extern crate hyper_tls; extern crate itertools; +extern crate native_tls; extern crate r2d2; extern crate r2d2_diesel; extern crate rayon; @@ -66,7 +67,7 @@ pub mod database; pub(crate) mod models; mod parser; mod schema; -mod pipeline; +pub mod pipeline; pub use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 528cf82..b679d03 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -16,6 +16,7 @@ use hyper_tls::HttpsConnector; // use hyper::header::{ETag, LastModified}; use futures::prelude::*; +// use futures::future::ok; use schema::{episode, podcast, source}; use feed::Feed; diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index 8b13789..d2cb80b 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -1 +1,66 @@ +//! Docs. +use futures::future::*; +use errors::Error; +use Source; + +use tokio_core::reactor::Core; +use hyper::Client; +use hyper_tls::HttpsConnector; +// use futures::future::*; + +// Weird magic from #rust irc channel +// kudos to remexre +fn collect_futures( + futures: Vec, +) -> Box>, Error = Error>> +where + F: 'static + Future, + ::Item: 'static, + ::Error: 'static, +{ + Box::new(loop_fn((futures, vec![]), |(futures, mut done)| { + select_all(futures).then(|r| { + let (r, rest) = match r { + Ok((r, _, rest)) => (Ok(r), rest), + Err((r, _, rest)) => (Err(r), rest), + }; + done.push(r); + if rest.len() == 0 { + Ok(Loop::Break(done)) + } else { + Ok(Loop::Continue((rest, done))) + } + }) + })) +} + +pub use self::dirtyhack::pipeline; + +// Use a submodule ot not polute the collect_futures definition with the errorchain Result. +mod dirtyhack { + use super::*; + use errors::*; + + /// Docs + pub fn pipeline>(sources: S) -> Result<()> { + let mut core = Core::new()?; + let handle = core.handle(); + let client = Client::configure() + // FIXME: numcpus instead of 4 + .connector(HttpsConnector::new(4, &handle)?) + .build(&handle); + + let list = sources + .into_iter() + .map(|s| s.into_fututre_feed(&client, false).map(|feed| feed.index())) + .collect(); + + let f = core.run(collect_futures(list))?; + f.into_iter() + .filter_map(|x| x.err()) + .for_each(|err| error!("Error: {}", err)); + + Ok(()) + } +} diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 1f55c5f..74c1446 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -1,7 +1,9 @@ use send_cell::SendCell; use gdk_pixbuf::Pixbuf; -use hammond_data::feed; +// use hammond_data::feed; +use hammond_data::pipeline; +use hammond_data::dbqueries; use hammond_data::{PodcastCoverQuery, Source}; use hammond_downloader::downloader; @@ -21,10 +23,17 @@ pub fn refresh_feed(headerbar: Arc
    , source: Option>, sender: thread::spawn(move || { if let Some(s) = source { - feed::index_loop(s); - } else if let Err(err) = feed::index_all() { - error!("Error While trying to update the database."); - error!("Error msg: {}", err); + // feed::index_loop(s); + if let Err(err) = pipeline::pipeline(s) { + error!("Error While trying to update the database."); + error!("Error msg: {}", err); + } + } else { + let sources = dbqueries::get_sources().unwrap(); + if let Err(err) = pipeline::pipeline(sources) { + error!("Error While trying to update the database."); + error!("Error msg: {}", err); + } }; sender.send(Action::HeaderBarHideUpdateIndicator).unwrap(); From e63a366fdc4ba35ad5618a1f04fa47dad12d8447 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 14 Jan 2018 06:48:42 +0200 Subject: [PATCH 190/278] I don't know why the benchmarks keep cycling. --- hammond-data/benches/bench.rs | 44 +++++++++++------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/hammond-data/benches/bench.rs b/hammond-data/benches/bench.rs index bcbc7c0..b7f9f76 100644 --- a/hammond-data/benches/bench.rs +++ b/hammond-data/benches/bench.rs @@ -1,24 +1,16 @@ #![feature(test)] -extern crate futures; extern crate hammond_data; extern crate hyper; -extern crate hyper_tls; extern crate rand; -extern crate rayon; +// extern crate rayon; extern crate rss; extern crate test; -extern crate tokio_core; // use rayon::prelude::*; use test::Bencher; -use tokio_core::reactor::Core; -use hyper::Client; -use hyper_tls::HttpsConnector; -use futures::future::*; - use hammond_data::Source; use hammond_data::feed::*; use hammond_data::database::truncate_db; @@ -41,6 +33,7 @@ static URLS: &[(&[u8], &str)] = &[ ]; static URLS2: &[&str] = &[ + "https://www.pcper.com/rss/podcasts-mp3.rss", "https://feeds.feedburner.com/InterceptedWithJeremyScahill", "http://www.badvoltage.org/feed/ogg/", "https://www.theguardian.com/news/series/the-audio-long-read/podcast.xml", @@ -95,36 +88,27 @@ fn bench_index_unchanged_feeds(b: &mut Bencher) { fn bench_get_normal_feeds(b: &mut Bencher) { // Index first so it will only bench the comparison test case. truncate_db().unwrap(); + URLS2.iter().for_each(|url| { + Source::from_url(url).unwrap(); + }); b.iter(|| { - URLS2.iter().for_each(|url| { - let mut s = Source::from_url(url).unwrap(); - let _feed = s.into_feed(true); - }); + let sources = hammond_data::dbqueries::get_sources().unwrap(); + index_loop(sources); + println!("I RUN"); }); } #[bench] fn bench_get_future_feeds(b: &mut Bencher) { truncate_db().unwrap(); + URLS2.iter().for_each(|url| { + Source::from_url(url).unwrap(); + }); b.iter(|| { - let mut core = Core::new().unwrap(); - let handle = core.handle(); - let client = Client::configure() - .connector(HttpsConnector::new(4, &handle).unwrap()) - .build(&handle); - - let mut foo = vec![]; - - URLS2.iter().for_each(|url| { - let s = Source::from_url(url).unwrap(); - let future = s.into_fututre_feed(&client, true); - foo.push(future); - }); - - let work = join_all(foo); - let res = core.run(work); - assert!(res.is_ok()); + let sources = hammond_data::dbqueries::get_sources().unwrap(); + hammond_data::pipeline::pipeline(sources).unwrap(); + println!("I RUN"); }) } From 2f7a22355f803f00ff9b24cc7cd50518a2e34c5d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Sun, 14 Jan 2018 08:27:50 +0200 Subject: [PATCH 191/278] Minor cleanup of the mess. --- hammond-data/src/lib.rs | 9 +-- hammond-data/src/models/insertables.rs | 2 +- hammond-data/src/models/queryables.rs | 99 +++++++++++++------------- hammond-data/src/pipeline.rs | 17 +++-- hammond-gtk/src/utils.rs | 8 ++- 5 files changed, 75 insertions(+), 60 deletions(-) diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index 96a190d..047d265 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -19,7 +19,8 @@ unused_parens, while_true)] #![deny(missing_debug_implementations, missing_docs, trivial_casts, trivial_numeric_casts)] // FIXME: uncomment -// unused_extern_crates, unused)] +// #![deny(unused_extern_crates, unused)] + // #![feature(conservative_impl_trait)] #[macro_use] @@ -59,15 +60,15 @@ extern crate xdg; #[allow(missing_docs)] pub mod dbqueries; -pub mod utils; -pub mod feed; #[allow(missing_docs)] pub mod errors; +pub mod utils; +pub mod feed; pub mod database; +pub mod pipeline; pub(crate) mod models; mod parser; mod schema; -pub mod pipeline; pub use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index e66f54f..01d2e10 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -39,7 +39,7 @@ impl Insert for NewSource { } impl NewSource { - pub(crate) fn new_with_uri(uri: &str) -> NewSource { + pub(crate) fn new(uri: &str) -> NewSource { NewSource { uri: uri.trim().to_string(), last_modified: None, diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index b679d03..b8eef3c 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -4,16 +4,12 @@ use diesel; use reqwest; use diesel::SaveChangesDsl; -use reqwest::header::{ETag, LastModified}; use rss::Channel; -use hyper; -use hyper::Client; use hyper::client::HttpConnector; -use hyper::Method; -use hyper::Uri; +use hyper::{Client, Method, Request, Response, StatusCode, Uri}; +use hyper::header::{ETag, EntityTag, HttpDate, IfModifiedSince, IfNoneMatch, LastModified}; use hyper_tls::HttpsConnector; -// use hyper::header::{ETag, LastModified}; use futures::prelude::*; // use futures::future::ok; @@ -639,10 +635,10 @@ impl Source { Ok(self.save_changes::(&*tempdb)?) } - /// Extract Etag and LastModifier from req, and update self and the + /// Extract Etag and LastModifier from res, and update self and the /// corresponding db row. - fn update_etag(&mut self, req: &reqwest::Response) -> Result<()> { - let headers = req.headers(); + fn update_etag(&mut self, res: &reqwest::Response) -> Result<()> { + let headers = res.headers(); let etag = headers.get::(); let lmod = headers.get::(); @@ -658,9 +654,10 @@ impl Source { Ok(()) } - /// Docs - pub fn update_etag2(mut self, req: &hyper::Response) -> Result<()> { - let headers = req.headers(); + /// Extract Etag and LastModifier from res, and update self and the + /// corresponding db row. + fn update_etag2(mut self, res: &Response) -> Result<()> { + let headers = res.headers(); let etag = headers.get::(); let lmod = headers.get::(); @@ -686,7 +683,6 @@ impl Source { // TODO: Refactor into TryInto once it lands on stable. pub fn into_feed(&mut self, ignore_etags: bool) -> Result { use reqwest::header::{EntityTag, Headers, HttpDate, IfModifiedSince, IfNoneMatch}; - use reqwest::StatusCode; let mut headers = Headers::new(); @@ -705,44 +701,20 @@ impl Source { } let client = reqwest::Client::builder().referer(false).build()?; - let mut req = client.get(self.uri()).headers(headers).send()?; + let mut res = client.get(self.uri()).headers(headers).send()?; - info!("GET to {} , returned: {}", self.uri(), req.status()); + info!("GET to {} , returned: {}", self.uri(), res.status()); - self.update_etag(&req)?; - - // TODO match on more stuff - // 301: Moved Permanently - // 304: Up to date Feed, checked with the Etag - // 307: Temporary redirect of the url - // 308: Permanent redirect of the url - // 401: Unathorized - // 403: Forbidden - // 408: Timeout - // 410: Feed deleted - match req.status() { - StatusCode::NotModified => bail!("304: skipping.."), - StatusCode::TemporaryRedirect => debug!("307: Temporary Redirect."), - // TODO: Change the source uri to the new one - StatusCode::MovedPermanently | StatusCode::PermanentRedirect => { - warn!("Feed was moved permanently.") - } - StatusCode::Unauthorized => bail!("401: Unauthorized."), - StatusCode::Forbidden => bail!("403: Forbidden."), - StatusCode::NotFound => bail!("404: Not found."), - StatusCode::RequestTimeout => bail!("408: Request Timeout."), - StatusCode::Gone => bail!("410: Feed was deleted."), - _ => (), - }; + self.update_etag(&res)?; + match_status(res.status())?; let mut buf = String::new(); - req.read_to_string(&mut buf)?; + res.read_to_string(&mut buf)?; let chan = Channel::from_str(&buf)?; Ok(Feed::from_channel_source(chan, self.id)) } - #[allow(dead_code)] /// Docs pub fn into_fututre_feed( self, @@ -750,6 +722,8 @@ impl Source { ignore_etags: bool, ) -> Box> { let id = self.id(); + // TODO: make URI future + // TODO: make a status match future let feed = request_constructor(&self, client, ignore_etags) .map(move |res| { if let Err(err) = self.update_etag2(&res) { @@ -766,21 +740,23 @@ impl Source { } /// Construct a new `Source` with the given `uri` and index it. + /// + /// This only indexes the `Source` struct, not the Podcast Feed. pub fn from_url(uri: &str) -> Result { - NewSource::new_with_uri(uri).into_source() + NewSource::new(uri).into_source() } } +// TODO: make ignore_etags an Enum for better ergonomics. +// #bools_are_just_2variant_enmus fn request_constructor( s: &Source, client: &Client>, ignore_etags: bool, -) -> Box> { - use hyper::header::{EntityTag, HttpDate, IfModifiedSince, IfNoneMatch}; - +) -> Box> { // FIXME: remove unwrap let uri = Uri::from_str(&s.uri()).unwrap(); - let mut req = hyper::Request::new(Method::Get, uri); + let mut req = Request::new(Method::Get, uri); if !ignore_etags { if let Some(foo) = s.http_etag() { @@ -800,7 +776,7 @@ fn request_constructor( Box::new(work) } -fn response_to_channel(res: hyper::Response) -> Box> { +fn response_to_channel(res: Response) -> Box> { let chan = res.body() .concat2() .map(|x| x.into_iter()) @@ -814,6 +790,33 @@ fn response_to_channel(res: hyper::Response) -> Box Result<()> { + match code { + StatusCode::NotModified => bail!("304: skipping.."), + StatusCode::TemporaryRedirect => debug!("307: Temporary Redirect."), + // TODO: Change the source uri to the new one + StatusCode::MovedPermanently | StatusCode::PermanentRedirect => { + warn!("Feed was moved permanently.") + } + StatusCode::Unauthorized => bail!("401: Unauthorized."), + StatusCode::Forbidden => bail!("403: Forbidden."), + StatusCode::NotFound => bail!("404: Not found."), + StatusCode::RequestTimeout => bail!("408: Request Timeout."), + StatusCode::Gone => bail!("410: Feed was deleted."), + _ => (), + }; + Ok(()) +} + #[cfg(test)] mod tests { use super::*; diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index d2cb80b..bf51449 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -1,13 +1,13 @@ //! Docs. -use futures::future::*; use errors::Error; use Source; use tokio_core::reactor::Core; use hyper::Client; use hyper_tls::HttpsConnector; -// use futures::future::*; +use futures::prelude::*; +use futures::future::*; // Weird magic from #rust irc channel // kudos to remexre @@ -42,8 +42,13 @@ mod dirtyhack { use super::*; use errors::*; - /// Docs - pub fn pipeline>(sources: S) -> Result<()> { + /// The pipline to be run for indexing and updating a Podcast feed that originates from + /// `Source.uri`. + /// + /// Messy temp diagram: + /// Source -> GET Request -> Update Etags -> Check Status -> Parse xml/Rss -> + /// Convert rss::Channel into Feed -> Index Podcast -> Index Episodes. + pub fn pipeline>(sources: S, ignore_etags: bool) -> Result<()> { let mut core = Core::new()?; let handle = core.handle(); let client = Client::configure() @@ -53,7 +58,9 @@ mod dirtyhack { let list = sources .into_iter() - .map(|s| s.into_fututre_feed(&client, false).map(|feed| feed.index())) + // FIXME: Make proper indexing futures instead of wrapping up existing + // blocking functions + .map(|s| s.into_fututre_feed(&client, ignore_etags).map(|feed| feed.index())) .collect(); let f = core.run(collect_futures(list))?; diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 74c1446..207cb79 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -19,18 +19,22 @@ use app::Action; /// If `source` is None, Fetches all the `Source` entries in the database and updates them. /// When It's done,it queues up a `RefreshViews` action. pub fn refresh_feed(headerbar: Arc
    , source: Option>, sender: Sender) { + // TODO: make it an application channel action. + // I missed it before apparently. headerbar.show_update_notification(); thread::spawn(move || { + // FIXME: This is messy at best. if let Some(s) = source { // feed::index_loop(s); - if let Err(err) = pipeline::pipeline(s) { + // TODO: determine if it needs to ignore_etags. + if let Err(err) = pipeline::pipeline(s, true) { error!("Error While trying to update the database."); error!("Error msg: {}", err); } } else { let sources = dbqueries::get_sources().unwrap(); - if let Err(err) = pipeline::pipeline(sources) { + if let Err(err) = pipeline::pipeline(sources, false) { error!("Error While trying to update the database."); error!("Error msg: {}", err); } From 10345ffda73ef6eade5f0754f999c82f116b5156 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 15 Jan 2018 10:16:01 +0200 Subject: [PATCH 192/278] Pipeline: add matching on status code. --- hammond-data/benches/bench.rs | 3 +-- hammond-data/src/models/queryables.rs | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/hammond-data/benches/bench.rs b/hammond-data/benches/bench.rs index b7f9f76..ffbaed2 100644 --- a/hammond-data/benches/bench.rs +++ b/hammond-data/benches/bench.rs @@ -108,7 +108,6 @@ fn bench_get_future_feeds(b: &mut Bencher) { b.iter(|| { let sources = hammond_data::dbqueries::get_sources().unwrap(); - hammond_data::pipeline::pipeline(sources).unwrap(); - println!("I RUN"); + hammond_data::pipeline::pipeline(sources, false).unwrap(); }) } diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index b8eef3c..52d53fd 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -6,6 +6,7 @@ use reqwest; use diesel::SaveChangesDsl; use rss::Channel; +use hyper; use hyper::client::HttpConnector; use hyper::{Client, Method, Request, Response, StatusCode, Uri}; use hyper::header::{ETag, EntityTag, HttpDate, IfModifiedSince, IfNoneMatch, LastModified}; @@ -723,16 +724,16 @@ impl Source { ) -> Box> { let id = self.id(); // TODO: make URI future - // TODO: make a status match future let feed = request_constructor(&self, client, ignore_etags) - .map(move |res| { - if let Err(err) = self.update_etag2(&res) { - error!("Failed to update Source struct with new etag values"); - error!("Error: {}", err); - }; - res - }) .map_err(From::from) + .and_then(move |res| { + self.update_etag2(&res)?; + Ok(res) + }) + .and_then(|res| -> Result { + match_status(res.status())?; + Ok(res) + }) .and_then(|res| response_to_channel(res)) .map(move |chan| Feed::from_channel_source(chan, id)); @@ -753,7 +754,7 @@ fn request_constructor( s: &Source, client: &Client>, ignore_etags: bool, -) -> Box> { +) -> Box> { // FIXME: remove unwrap let uri = Uri::from_str(&s.uri()).unwrap(); let mut req = Request::new(Method::Get, uri); From 3358fcd0b3e761eab00d109e6525e7f66fa120e3 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Mon, 15 Jan 2018 11:03:40 +0200 Subject: [PATCH 193/278] hammond_data::Feed: general cleanup of no longer needed stuff. --- hammond-data/benches/bench.rs | 2 +- hammond-data/src/feed.rs | 45 +++++++++++--------------- hammond-data/src/models/insertables.rs | 1 + hammond-data/src/models/queryables.rs | 5 ++- hammond-downloader/src/downloader.rs | 3 +- hammond-gtk/src/manager.rs | 3 +- hammond-gtk/src/utils.rs | 3 +- 7 files changed, 26 insertions(+), 36 deletions(-) diff --git a/hammond-data/benches/bench.rs b/hammond-data/benches/bench.rs index ffbaed2..6f79f9e 100644 --- a/hammond-data/benches/bench.rs +++ b/hammond-data/benches/bench.rs @@ -62,7 +62,7 @@ fn index_urls() { }) .collect(); - feeds.iter().for_each(|x| index(x)); + feeds.iter().for_each(|x| x.index().unwrap()); } #[bench] diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 0add944..01e3840 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -9,11 +9,14 @@ use rss; use dbqueries; use parser; -use models::queryables::{Episode, Podcast, Source}; +use models::queryables::{Podcast, Source}; use models::insertables::{NewEpisode, NewPodcast}; use database::connection; use errors::*; +#[cfg(test)] +use models::queryables::Episode; + #[derive(Debug)] /// Wrapper struct that hold a `Source` and the `rss::Channel` /// that corresponds to the `Source.uri` field. @@ -29,11 +32,8 @@ impl Feed { } /// Constructor that consumes a `Source` and a `rss::Channel` returns a `Feed` struct. - pub fn from_channel_source(chan: rss::Channel, s: i32) -> Feed { - Feed { - channel: chan, - source_id: s, - } + pub fn from_channel_source(channel: rss::Channel, source_id: i32) -> Feed { + Feed { channel, source_id } } /// docs @@ -85,15 +85,15 @@ impl Feed { self.parse_channel().into_podcast() } - #[allow(dead_code)] + #[cfg(test)] + /// This returns only the episodes in the xml feed. + /// Used for unit-tests only. fn get_episodes(&self) -> Result> { let pd = self.get_podcast()?; let eps = self.parse_channel_items(&pd); let db = connection(); let con = db.get()?; - // TODO: Make it parallel - // This returns only the episodes in the xml feed. let episodes: Vec<_> = eps.into_iter() .filter_map(|ep| ep.into_episode(&con).ok()) .collect(); @@ -102,25 +102,12 @@ impl Feed { } } -/// Handle the indexing of a `Feed` into the Database. -pub fn index(feed: &Feed) { - if let Err(err) = feed.index() { - error!("Error While trying to update the database."); - error!("Error msg: {}", err); - }; -} - -/// Consume a `Source` and return a `Feed`. -fn fetch(source: &mut Source) -> Result { - Feed::from_source(source) -} - /// Index a "list" of `Source`s. pub fn index_loop>(sources: S) { sources .into_par_iter() - .filter_map(|mut x| { - let foo = fetch(&mut x); + .filter_map(|mut source| { + let foo = Feed::from_source(&mut source); if let Err(err) = foo { error!("Error: {}", err); None @@ -128,7 +115,13 @@ pub fn index_loop>(sources: S) { foo.ok() } }) - .for_each(|x| index(&x)); + // Handle the indexing of a `Feed` into the Database. + .for_each(|feed| { + if let Err(err) = feed.index() { + error!("Error While trying to update the database."); + error!("Error msg: {}", err); + } + }); info!("Indexing done."); } @@ -208,7 +201,7 @@ mod tests { .collect(); // Index the channels - feeds.par_iter().for_each(|x| index(&x)); + feeds.par_iter().for_each(|x| x.index().unwrap()); // Assert the index rows equal the controlled results assert_eq!(dbqueries::get_sources().unwrap().len(), 4); diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index 01d2e10..972cd41 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -185,6 +185,7 @@ impl Update for NewEpisode { impl NewEpisode { // TODO: Refactor into batch indexes instead. + #[allow(dead_code)] pub(crate) fn into_episode(self, con: &SqliteConnection) -> Result { self.index(con)?; Ok(dbqueries::get_episode_from_pk( diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 52d53fd..0b93a3c 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -13,7 +13,7 @@ use hyper::header::{ETag, EntityTag, HttpDate, IfModifiedSince, IfNoneMatch, Las use hyper_tls::HttpsConnector; use futures::prelude::*; -// use futures::future::ok; +// use futures::future::{ok, result}; use schema::{episode, podcast, source}; use feed::Feed; @@ -723,7 +723,6 @@ impl Source { ignore_etags: bool, ) -> Box> { let id = self.id(); - // TODO: make URI future let feed = request_constructor(&self, client, ignore_etags) .map_err(From::from) .and_then(move |res| { @@ -755,7 +754,7 @@ fn request_constructor( client: &Client>, ignore_etags: bool, ) -> Box> { - // FIXME: remove unwrap + // FIXME: remove unwrap somehow let uri = Uri::from_str(&s.uri()).unwrap(); let mut req = Request::new(Method::Get, uri); diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 09d2e44..437624c 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -217,7 +217,6 @@ pub fn cache_image(pd: &PodcastCoverQuery) -> Option { mod tests { use super::*; use hammond_data::Source; - use hammond_data::feed::index; use hammond_data::dbqueries; #[test] @@ -234,7 +233,7 @@ mod tests { // Convert Source it into a Feed and index it let feed = source.into_feed(true).unwrap(); - index(&feed); + feed.index().unwrap(); // Get the Podcast let pd = dbqueries::get_podcast_from_source_id(sid).unwrap().into(); diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index f6ba174..fe9edd6 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -120,7 +120,6 @@ mod tests { use hammond_data::database; use hammond_data::utils::get_download_folder; - use hammond_data::feed::*; use hammond_data::{Episode, Source}; use hammond_data::dbqueries; @@ -144,7 +143,7 @@ mod tests { // Convert Source it into a Feed and index it let feed = source.into_feed(true).unwrap(); - index(&feed); + feed.index().unwrap(); // Get the Podcast let pd = dbqueries::get_podcast_from_source_id(sid).unwrap(); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 207cb79..f73230e 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -81,7 +81,6 @@ pub fn get_pixbuf_from_path(pd: &PodcastCoverQuery, size: u32) -> Option #[cfg(test)] mod tests { use hammond_data::Source; - use hammond_data::feed::index; use hammond_data::dbqueries; use super::*; @@ -99,7 +98,7 @@ mod tests { // Convert Source it into a Feed and index it let feed = source.into_feed(true).unwrap(); - index(&feed); + feed.index().unwrap(); // Get the Podcast let pd = dbqueries::get_podcast_from_source_id(sid).unwrap(); From 7f78e87551c28fd4f89515e937a9b1a4b78f6993 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 16 Jan 2018 12:35:08 +0200 Subject: [PATCH 194/278] hammond_data::Feed: Remove unused parts. --- TODO.md | 5 +- hammond-data/benches/bench.rs | 1 - hammond-data/src/feed.rs | 87 ++++++-------------------- hammond-data/src/models/insertables.rs | 1 + 4 files changed, 22 insertions(+), 72 deletions(-) diff --git a/TODO.md b/TODO.md index 5190a13..71d1fda 100644 --- a/TODO.md +++ b/TODO.md @@ -10,7 +10,6 @@ ## Second - [ ] Make use of file metadas, [This](https://github.com/GuillaumeGomez/audio-video-metadata) might be helpfull. -- [ ] Notifications - [ ] Episode queue - [ ] Embedded player - [ ] MPRIS integration @@ -21,8 +20,8 @@ - [ ] Download Queue - [ ] Ability to Stream content on demand - [ ] soundcloud and itunes feeds // [This](http://getrssfeed.com) seems intresting. -- [ ] Integrate with Itunes API for various crap -- [ ] YoutubeFeeds +- [ ] Integrate with Itunes API for various crap? +- [ ] YoutubeFeeds? ## Rest Tasks diff --git a/hammond-data/benches/bench.rs b/hammond-data/benches/bench.rs index 6f79f9e..9d3dcbc 100644 --- a/hammond-data/benches/bench.rs +++ b/hammond-data/benches/bench.rs @@ -95,7 +95,6 @@ fn bench_get_normal_feeds(b: &mut Bencher) { b.iter(|| { let sources = hammond_data::dbqueries::get_sources().unwrap(); index_loop(sources); - println!("I RUN"); }); } diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 01e3840..11bd6bc 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -14,11 +14,11 @@ use models::insertables::{NewEpisode, NewPodcast}; use database::connection; use errors::*; -#[cfg(test)] -use models::queryables::Episode; +// #[cfg(test)] +// use models::queryables::Episode; #[derive(Debug)] -/// Wrapper struct that hold a `Source` and the `rss::Channel` +/// Wrapper struct that hold a `Source` id and the `rss::Channel` /// that corresponds to the `Source.uri` field. pub struct Feed { channel: rss::Channel, @@ -36,18 +36,12 @@ impl Feed { Feed { channel, source_id } } - /// docs + /// Index the contents of the RSS `Feed` into the database. pub fn index(&self) -> Result<()> { - let pd = self.get_podcast()?; + let pd = self.parse_podcast().into_podcast()?; self.index_channel_items(&pd) } - // #[allow(dead_code)] - // fn index_channel(&self) -> Result<()> { - // self.parse_channel().index()?; - // Ok(()) - // } - // TODO: Refactor transcactions and find a way to do it in parallel. fn index_channel_items(&self, pd: &Podcast) -> Result<()> { let episodes = self.parse_channel_items(pd); @@ -56,8 +50,7 @@ impl Feed { let _ = con.transaction::<(), Error, _>(|| { episodes.into_iter().for_each(|x| { - let e = x.index(&con); - if let Err(err) = e { + if let Err(err) = x.index(&con) { error!("Failed to index episode: {:?}.", x.title()); error!("Error msg: {}", err); }; @@ -67,7 +60,7 @@ impl Feed { Ok(()) } - fn parse_channel(&self) -> NewPodcast { + fn parse_podcast(&self) -> NewPodcast { parser::new_podcast(&self.channel, self.source_id) } @@ -81,25 +74,20 @@ impl Feed { new_episodes } - fn get_podcast(&self) -> Result { - self.parse_channel().into_podcast() - } + // #[cfg(test)] + // /// This returns only the episodes in the xml feed. + // fn get_episodes(&self) -> Result> { + // let pd = self.get_podcast()?; + // let eps = self.parse_channel_items(&pd); - #[cfg(test)] - /// This returns only the episodes in the xml feed. - /// Used for unit-tests only. - fn get_episodes(&self) -> Result> { - let pd = self.get_podcast()?; - let eps = self.parse_channel_items(&pd); + // let db = connection(); + // let con = db.get()?; + // let episodes: Vec<_> = eps.into_iter() + // .filter_map(|ep| ep.into_episode(&con).ok()) + // .collect(); - let db = connection(); - let con = db.get()?; - let episodes: Vec<_> = eps.into_iter() - .filter_map(|ep| ep.into_episode(&con).ok()) - .collect(); - - Ok(episodes) - } + // Ok(episodes) + // } } /// Index a "list" of `Source`s. @@ -208,41 +196,4 @@ mod tests { assert_eq!(dbqueries::get_podcasts().unwrap().len(), 4); assert_eq!(dbqueries::get_episodes().unwrap().len(), 274); } - - #[test] - fn test_partial_index_podcast() { - truncate_db().unwrap(); - let url = "https://feeds.feedburner.com/InterceptedWithJeremyScahill"; - - let mut s1 = Source::from_url(url).unwrap(); - let mut s2 = Source::from_url(url).unwrap(); - assert_eq!(s1, s2); - assert_eq!(s1.id(), s2.id()); - - let f1 = s1.into_feed(false).unwrap(); - let f2 = s2.into_feed(false).unwrap(); - - let p1 = f1.get_podcast().unwrap(); - let p2 = { - f2.index().unwrap(); - f2.get_podcast().unwrap() - }; - assert_eq!(p1, p2); - assert_eq!(p1.id(), p2.id()); - assert_eq!(p1.source_id(), p2.source_id()); - - let eps1 = f1.get_episodes().unwrap(); - let eps2 = { - f2.index().unwrap(); - f2.get_episodes().unwrap() - }; - - eps1.into_par_iter().zip(eps2).into_par_iter().for_each( - |(ep1, ep2): (Episode, Episode)| { - assert_eq!(ep1, ep2); - assert_eq!(ep1.id(), ep2.id()); - assert_eq!(ep1.podcast_id(), ep2.podcast_id()); - }, - ); - } } diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index 972cd41..3dad2d9 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -113,6 +113,7 @@ impl NewPodcast { if (foo.link() != self.link) || (foo.title() != self.title) || (foo.image_uri() != self.image_uri.as_ref().map(|x| x.as_str())) { + info!("NewEpisode: {:?}\n OldEpisode: {:?}", self, foo); self.update(&con, foo.id())?; } } From b3460b15a2c08236be78cf0f60a8774e50195ac1 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 16 Jan 2018 13:44:33 +0200 Subject: [PATCH 195/278] hammond_data::Feed: add parse_podcast_future method. --- hammond-data/src/feed.rs | 17 +++++++++++++++++ hammond-data/src/lib.rs | 1 + hammond-data/src/models/queryables.rs | 1 + hammond-data/src/pipeline.rs | 10 ++++++---- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 11bd6bc..f10debe 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -2,6 +2,8 @@ use rayon::prelude::*; use diesel::prelude::*; +use futures::prelude::*; +use futures::future::*; use rayon::iter::IntoParallelIterator; use rss; @@ -42,6 +44,17 @@ impl Feed { self.index_channel_items(&pd) } + /// Docs + // FIXME: docs + // FIXME: lifetime stuff + pub fn index_future(self) -> Box> { + let indx = self.parse_podcast_futture() + .and_then(|pd| pd.into_podcast()) + .and_then(move |pd| self.index_channel_items(&pd)); + + Box::new(indx) + } + // TODO: Refactor transcactions and find a way to do it in parallel. fn index_channel_items(&self, pd: &Podcast) -> Result<()> { let episodes = self.parse_channel_items(pd); @@ -64,6 +77,10 @@ impl Feed { parser::new_podcast(&self.channel, self.source_id) } + fn parse_podcast_futture(&self) -> Box> { + Box::new(ok(self.parse_podcast())) + } + fn parse_channel_items(&self, pd: &Podcast) -> Vec { let items = self.channel.items(); let new_episodes: Vec<_> = items diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index 047d265..5507eee 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -71,6 +71,7 @@ mod parser; mod schema; pub use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; +// pub use feed::Feed; /// [XDG Base Direcotory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) Paths. #[allow(missing_debug_implementations)] diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index 0b93a3c..d6f8390 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -716,6 +716,7 @@ impl Source { Ok(Feed::from_channel_source(chan, self.id)) } + // FIXME: /// Docs pub fn into_fututre_feed( self, diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index bf51449..2510248 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -1,14 +1,16 @@ +// FIXME: //! Docs. -use errors::Error; -use Source; - use tokio_core::reactor::Core; use hyper::Client; use hyper_tls::HttpsConnector; use futures::prelude::*; use futures::future::*; +use errors::Error; +use Source; +// use Feed; + // Weird magic from #rust irc channel // kudos to remexre fn collect_futures( @@ -60,7 +62,7 @@ mod dirtyhack { .into_iter() // FIXME: Make proper indexing futures instead of wrapping up existing // blocking functions - .map(|s| s.into_fututre_feed(&client, ignore_etags).map(|feed| feed.index())) + .map(|s| s.into_fututre_feed(&client, ignore_etags).map(|feed| feed.index_future())) .collect(); let f = core.run(collect_futures(list))?; From bf4f655ed2ac8285dbd940d26643d6107422592e Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 16 Jan 2018 14:37:51 +0200 Subject: [PATCH 196/278] Pipeline: remove submodule hack. --- hammond-data/src/pipeline.rs | 72 +++++++++++++++++------------------- 1 file changed, 33 insertions(+), 39 deletions(-) diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index 2510248..1e0c0cb 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -7,15 +7,46 @@ use hyper_tls::HttpsConnector; use futures::prelude::*; use futures::future::*; -use errors::Error; +use errors::*; use Source; // use Feed; +use std; + +/// The pipline to be run for indexing and updating a Podcast feed that originates from +/// `Source.uri`. +/// +/// Messy temp diagram: +/// Source -> GET Request -> Update Etags -> Check Status -> Parse xml/Rss -> +/// Convert rss::Channel into Feed -> Index Podcast -> Index Episodes. +pub fn pipeline>(sources: S, ignore_etags: bool) -> Result<()> { + let mut core = Core::new()?; + let handle = core.handle(); + let client = Client::configure() + // FIXME: numcpus instead of 4 + .connector(HttpsConnector::new(4, &handle)?) + .build(&handle); + + let list = sources + .into_iter() + // FIXME: Make proper indexing futures instead of wrapping up existing + // blocking functions + .map(|s| s.into_fututre_feed(&client, ignore_etags).map(|feed| feed.index_future())) + .collect(); + + let f = core.run(collect_futures(list))?; + f.into_iter() + .filter_map(|x| x.err()) + .for_each(|err| error!("Error: {}", err)); + + Ok(()) +} + // Weird magic from #rust irc channel // kudos to remexre fn collect_futures( futures: Vec, -) -> Box>, Error = Error>> +) -> Box>, Error = Error>> where F: 'static + Future, ::Item: 'static, @@ -36,40 +67,3 @@ where }) })) } - -pub use self::dirtyhack::pipeline; - -// Use a submodule ot not polute the collect_futures definition with the errorchain Result. -mod dirtyhack { - use super::*; - use errors::*; - - /// The pipline to be run for indexing and updating a Podcast feed that originates from - /// `Source.uri`. - /// - /// Messy temp diagram: - /// Source -> GET Request -> Update Etags -> Check Status -> Parse xml/Rss -> - /// Convert rss::Channel into Feed -> Index Podcast -> Index Episodes. - pub fn pipeline>(sources: S, ignore_etags: bool) -> Result<()> { - let mut core = Core::new()?; - let handle = core.handle(); - let client = Client::configure() - // FIXME: numcpus instead of 4 - .connector(HttpsConnector::new(4, &handle)?) - .build(&handle); - - let list = sources - .into_iter() - // FIXME: Make proper indexing futures instead of wrapping up existing - // blocking functions - .map(|s| s.into_fututre_feed(&client, ignore_etags).map(|feed| feed.index_future())) - .collect(); - - let f = core.run(collect_futures(list))?; - f.into_iter() - .filter_map(|x| x.err()) - .for_each(|err| error!("Error: {}", err)); - - Ok(()) - } -} From fa03c20b00da6d4f7448a59b2b8c66d666348f82 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 16 Jan 2018 14:52:20 +0200 Subject: [PATCH 197/278] Feed: add parse_channel_items_future method. --- hammond-data/src/feed.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index f10debe..0c19012 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -91,6 +91,22 @@ impl Feed { new_episodes } + // This could also retrurn a FutureResult>, Error> Instead + #[allow(dead_code)] + fn parse_channel_items_future( + &self, + pd: &Podcast, + ) -> Box>> { + let items = self.channel.items(); + + let episodes: Vec<_> = items + .par_iter() + .map(|item| result(parser::new_episode(item, pd.id()))) + .collect(); + + Box::new(episodes) + } + // #[cfg(test)] // /// This returns only the episodes in the xml feed. // fn get_episodes(&self) -> Result> { From 978e5a61f64ec587dabc400016701c8d48a31c59 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 16 Jan 2018 17:26:41 +0200 Subject: [PATCH 198/278] Dbquerries: add EXIST querries for podcast and episode. --- hammond-data/src/dbqueries.rs | 27 +++++++++++++++++++++++++++ hammond-data/src/errors.rs | 4 ++-- hammond-data/src/feed.rs | 10 +++------- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index bf89235..10df983 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -257,6 +257,33 @@ pub fn delete_podcast_episodes(con: &SqliteConnection, parent_id: i32) -> QueryR diesel::delete(episode.filter(podcast_id.eq(parent_id))).execute(&*con) } +pub fn podcast_exists(source_id_: i32) -> Result { + use schema::podcast::dsl::*; + use diesel::select; + use diesel::dsl::exists; + + let db = connection(); + let con = db.get()?; + + select(exists(podcast.filter(source_id.eq(source_id_)))) + .get_result(&*con) + .map_err(From::from) +} + +#[cfg_attr(rustfmt, rustfmt_skip)] +pub fn episode_exists(title_: &str, podcast_id_: i32) -> Result { + use schema::episode::dsl::*; + use diesel::select; + use diesel::dsl::exists; + + let db = connection(); + let con = db.get()?; + + select(exists(episode.filter(podcast_id.eq(podcast_id_)).filter(title.eq(title_)))) + .get_result(&*con) + .map_err(From::from) +} + pub fn update_none_to_played_now(parent: &Podcast) -> Result { use schema::episode::dsl::*; diff --git a/hammond-data/src/errors.rs b/hammond-data/src/errors.rs index 7f8f88a..3beb3f2 100644 --- a/hammond-data/src/errors.rs +++ b/hammond-data/src/errors.rs @@ -1,4 +1,4 @@ -use diesel::result; +use diesel; use diesel_migrations::RunMigrationsError; use rss; use reqwest; @@ -11,7 +11,7 @@ use std::io; error_chain! { foreign_links { R2D2Error(r2d2::Error); - DieselResultError(result::Error); + DieselResultError(diesel::result::Error); DieselMigrationError(RunMigrationsError); RSSError(rss::Error); ReqError(reqwest::Error); diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 0c19012..591f811 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -93,13 +93,9 @@ impl Feed { // This could also retrurn a FutureResult>, Error> Instead #[allow(dead_code)] - fn parse_channel_items_future( - &self, - pd: &Podcast, - ) -> Box>> { - let items = self.channel.items(); - - let episodes: Vec<_> = items + fn parse_episodes_future(&self, pd: &Podcast) -> Box>> { + let episodes = self.channel + .items() .par_iter() .map(|item| result(parser::new_episode(item, pd.id()))) .collect(); From f64779f70a9cd7dad5d961bc7005db176a1ffad4 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Tue, 16 Jan 2018 18:33:32 +0200 Subject: [PATCH 199/278] Parser: Add NewEpisodeMinimal struct. Parsing whole episodes can be expensive and we only need a subset to determine if it should be indexed/updated or ignored. --- hammond-data/src/models/insertables.rs | 110 ++++++++++++++++++++++++- hammond-data/src/parser.rs | 2 +- 2 files changed, 108 insertions(+), 4 deletions(-) diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index 3dad2d9..ce92734 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -1,15 +1,27 @@ #![allow(unused_mut)] use diesel::prelude::*; +use diesel; + +use rss; +use ammonia; +use rfc822_sanitizer::parse_from_rfc2822_with_fallback as parse_rfc822; +use utils::{replace_extra_spaces, url_cleaner}; use schema::{episode, podcast, source}; use models::queryables::{Episode, Podcast, Source}; +use dbqueries; +use database::connection; +use parser; use errors::*; -use dbqueries; -use diesel; -use database::connection; +#[allow(dead_code)] +enum IndexState { + Index(T), + Update(T), + NotChanged, +} trait Insert { fn insert(&self, &SqliteConnection) -> QueryResult; @@ -166,6 +178,19 @@ pub(crate) struct NewEpisode { podcast_id: i32, } +impl From for NewEpisode { + fn from(e: NewEpisodeMinimal) -> Self { + NewEpisodeBuilder::default() + .title(e.title) + .uri(e.uri) + .duration(e.duration) + .epoch(e.epoch) + .podcast_id(e.podcast_id) + .build() + .unwrap() + } +} + impl Insert for NewEpisode { fn insert(&self, con: &SqliteConnection) -> QueryResult { use schema::episode::dsl::*; @@ -251,3 +276,82 @@ impl NewEpisode { self.podcast_id } } + +#[derive(Insertable, AsChangeset)] +#[table_name = "episode"] +#[derive(Debug, Clone, Default, Builder, PartialEq)] +#[builder(derive(Debug))] +#[builder(setter(into))] +pub(crate) struct NewEpisodeMinimal { + title: String, + uri: Option, + duration: Option, + epoch: i32, + podcast_id: i32, +} + +impl NewEpisodeMinimal { + #[allow(dead_code)] + fn new(item: &rss::Item, parent_id: i32) -> Result { + if item.title().is_none() { + bail!("No title specified for the item.") + } + + let title = item.title().unwrap().trim().to_owned(); + + let uri = if let Some(url) = item.enclosure().map(|s| url_cleaner(s.url())) { + Some(url) + } else if item.link().is_some() { + item.link().map(|s| url_cleaner(s)) + } else { + bail!("No url specified for the item.") + }; + + let date = parse_rfc822( + // Default to rfc2822 represantation of epoch 0. + item.pub_date().unwrap_or("Thu, 1 Jan 1970 00:00:00 +0000"), + ); + // Should treat information from the rss feeds as invalid by default. + // Case: Thu, 05 Aug 2016 06:00:00 -0400 <-- Actually that was friday. + let epoch = date.map(|x| x.timestamp() as i32).unwrap_or(0); + + let duration = parser::parse_itunes_duration(item); + + Ok(NewEpisodeMinimalBuilder::default() + .title(title) + .uri(uri) + .duration(duration) + .epoch(epoch) + .podcast_id(parent_id) + .build() + .unwrap()) + } + + #[allow(dead_code)] + fn into_new_episode(self, item: &rss::Item) -> NewEpisode { + let guid = item.guid().map(|s| s.value().trim().to_owned()); + let length = || -> Option { item.enclosure().map(|x| x.length().parse().ok())? }(); + + // Prefer itunes summary over rss.description since many feeds put html into + // rss.description. + let summary = item.itunes_ext().map(|s| s.summary()).and_then(|s| s); + let description = if summary.is_some() { + summary.map(|s| replace_extra_spaces(&ammonia::clean(s))) + } else { + item.description() + .map(|s| replace_extra_spaces(&ammonia::clean(s))) + }; + + NewEpisodeBuilder::default() + .title(self.title) + .uri(self.uri) + .duration(self.duration) + .epoch(self.epoch) + .podcast_id(self.podcast_id) + .guid(guid) + .length(length) + .description(description) + .build() + .unwrap() + } +} diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 9f9299b..03d1a46 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -93,7 +93,7 @@ pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { // FIXME: Rafactor // TODO: Write tests #[allow(non_snake_case)] -fn parse_itunes_duration(item: &Item) -> Option { +pub(crate) fn parse_itunes_duration(item: &Item) -> Option { let duration = item.itunes_ext().map(|s| s.duration())??; // FOR SOME FUCKING REASON, IN THE APPLE EXTENSION SPEC From bd9844f0121173daeae8343d1364155933148a5f Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 17 Jan 2018 07:13:34 +0200 Subject: [PATCH 200/278] Dbquerries: Use map_err() instead of ? into Ok() pattern. --- hammond-data/src/dbqueries.rs | 95 +++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 37 deletions(-) diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 10df983..9dfbd81 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -14,7 +14,7 @@ pub fn get_sources() -> Result> { let db = connection(); let con = db.get()?; - Ok(source.load::(&*con)?) + source.load::(&*con).map_err(From::from) } pub fn get_podcasts() -> Result> { @@ -22,7 +22,7 @@ pub fn get_podcasts() -> Result> { let db = connection(); let con = db.get()?; - Ok(podcast.load::(&*con)?) + podcast.load::(&*con).map_err(From::from) } pub fn get_episodes() -> Result> { @@ -30,7 +30,10 @@ pub fn get_episodes() -> Result> { let db = connection(); let con = db.get()?; - Ok(episode.order(epoch.desc()).load::(&*con)?) + episode + .order(epoch.desc()) + .load::(&*con) + .map_err(From::from) } pub(crate) fn get_downloaded_episodes() -> Result> { @@ -38,10 +41,11 @@ pub(crate) fn get_downloaded_episodes() -> Result> { let db = connection(); let con = db.get()?; - Ok(episode + episode .select((rowid, local_uri, played)) .filter(local_uri.is_not_null()) - .load::(&*con)?) + .load::(&*con) + .map_err(From::from) } pub fn get_played_episodes() -> Result> { @@ -49,7 +53,10 @@ pub fn get_played_episodes() -> Result> { let db = connection(); let con = db.get()?; - Ok(episode.filter(played.is_not_null()).load::(&*con)?) + episode + .filter(played.is_not_null()) + .load::(&*con) + .map_err(From::from) } pub fn get_played_cleaner_episodes() -> Result> { @@ -57,10 +64,11 @@ pub fn get_played_cleaner_episodes() -> Result> { let db = connection(); let con = db.get()?; - Ok(episode + episode .select((rowid, local_uri, played)) .filter(played.is_not_null()) - .load::(&*con)?) + .load::(&*con) + .map_err(From::from) } pub fn get_episode_from_rowid(ep_id: i32) -> Result { @@ -68,9 +76,10 @@ pub fn get_episode_from_rowid(ep_id: i32) -> Result { let db = connection(); let con = db.get()?; - Ok(episode + episode .filter(rowid.eq(ep_id)) - .get_result::(&*con)?) + .get_result::(&*con) + .map_err(From::from) } pub fn get_episode_local_uri_from_id(ep_id: i32) -> Result> { @@ -79,10 +88,11 @@ pub fn get_episode_local_uri_from_id(ep_id: i32) -> Result> { let db = connection(); let con = db.get()?; - Ok(episode + episode .filter(rowid.eq(ep_id)) .select(local_uri) - .get_result::>(&*con)?) + .get_result::>(&*con) + .map_err(From::from) } pub fn get_episodes_with_limit(limit: u32) -> Result> { @@ -91,10 +101,11 @@ pub fn get_episodes_with_limit(limit: u32) -> Result> { let db = connection(); let con = db.get()?; - Ok(episode + episode .order(epoch.desc()) .limit(i64::from(limit)) - .load::(&*con)?) + .load::(&*con) + .map_err(From::from) } pub fn get_episodes_widgets_with_limit(limit: u32) -> Result> { @@ -103,7 +114,7 @@ pub fn get_episodes_widgets_with_limit(limit: u32) -> Result Result(&*con)?) + .load::(&*con) + .map_err(From::from) } pub fn get_podcast_from_id(pid: i32) -> Result { @@ -125,7 +137,10 @@ pub fn get_podcast_from_id(pid: i32) -> Result { let db = connection(); let con = db.get()?; - Ok(podcast.filter(id.eq(pid)).get_result::(&*con)?) + podcast + .filter(id.eq(pid)) + .get_result::(&*con) + .map_err(From::from) } pub fn get_podcast_cover_from_id(pid: i32) -> Result { @@ -133,10 +148,11 @@ pub fn get_podcast_cover_from_id(pid: i32) -> Result { let db = connection(); let con = db.get()?; - Ok(podcast + podcast .select((id, title, image_uri)) .filter(id.eq(pid)) - .get_result::(&*con)?) + .get_result::(&*con) + .map_err(From::from) } pub fn get_pd_episodes(parent: &Podcast) -> Result> { @@ -145,9 +161,10 @@ pub fn get_pd_episodes(parent: &Podcast) -> Result> { let db = connection(); let con = db.get()?; - Ok(Episode::belonging_to(parent) + Episode::belonging_to(parent) .order(epoch.desc()) - .load::(&*con)?) + .load::(&*con) + .map_err(From::from) } pub fn get_pd_episodeswidgets(parent: &Podcast) -> Result> { @@ -156,13 +173,12 @@ pub fn get_pd_episodeswidgets(parent: &Podcast) -> Result(&*con)?, - ) + .load::(&*con) + .map_err(From::from) } pub fn get_pd_unplayed_episodes(parent: &Podcast) -> Result> { @@ -171,10 +187,11 @@ pub fn get_pd_unplayed_episodes(parent: &Podcast) -> Result> { let db = connection(); let con = db.get()?; - Ok(Episode::belonging_to(parent) + Episode::belonging_to(parent) .filter(played.is_null()) .order(epoch.desc()) - .load::(&*con)?) + .load::(&*con) + .map_err(From::from) } pub fn get_pd_episodes_limit(parent: &Podcast, limit: u32) -> Result> { @@ -183,10 +200,11 @@ pub fn get_pd_episodes_limit(parent: &Podcast, limit: u32) -> Result(&*con)?) + .load::(&*con) + .map_err(From::from) } pub fn get_source_from_uri(uri_: &str) -> Result { @@ -194,7 +212,10 @@ pub fn get_source_from_uri(uri_: &str) -> Result { let db = connection(); let con = db.get()?; - Ok(source.filter(uri.eq(uri_)).get_result::(&*con)?) + source + .filter(uri.eq(uri_)) + .get_result::(&*con) + .map_err(From::from) } // pub fn get_podcast_from_title(title_: &str) -> QueryResult { @@ -212,9 +233,10 @@ pub fn get_podcast_from_source_id(sid: i32) -> Result { let db = connection(); let con = db.get()?; - Ok(podcast + podcast .filter(source_id.eq(sid)) - .get_result::(&*con)?) + .get_result::(&*con) + .map_err(From::from) } pub fn get_episode_from_pk(con: &SqliteConnection, title_: &str, pid: i32) -> QueryResult { @@ -292,10 +314,9 @@ pub fn update_none_to_played_now(parent: &Podcast) -> Result { let epoch_now = Utc::now().timestamp() as i32; con.transaction(|| -> Result { - Ok( - diesel::update(Episode::belonging_to(parent).filter(played.is_null())) - .set(played.eq(Some(epoch_now))) - .execute(&*con)?, - ) + diesel::update(Episode::belonging_to(parent).filter(played.is_null())) + .set(played.eq(Some(epoch_now))) + .execute(&*con) + .map_err(From::from) }) } From 8174fe0bac762cdc43b29e23f631aca6d08038d8 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 17 Jan 2018 07:16:59 +0200 Subject: [PATCH 201/278] hammond_data: Move parse_episode from parser into a NewEpisode method. --- hammond-data/src/feed.rs | 4 +- hammond-data/src/models/insertables.rs | 8 ++- hammond-data/src/parser.rs | 73 ++++---------------------- 3 files changed, 20 insertions(+), 65 deletions(-) diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 591f811..999d8ad 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -85,7 +85,7 @@ impl Feed { let items = self.channel.items(); let new_episodes: Vec<_> = items .par_iter() - .filter_map(|item| parser::new_episode(item, pd.id()).ok()) + .filter_map(|item| NewEpisode::new(item, pd.id()).ok()) .collect(); new_episodes @@ -97,7 +97,7 @@ impl Feed { let episodes = self.channel .items() .par_iter() - .map(|item| result(parser::new_episode(item, pd.id()))) + .map(|item| result(NewEpisode::new(item, pd.id()))) .collect(); Box::new(episodes) diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index ce92734..e4e9c4b 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -210,6 +210,12 @@ impl Update for NewEpisode { } impl NewEpisode { + #[allow(dead_code)] + /// Parses an `rss::Item` into a `NewEpisode` Struct. + pub(crate) fn new(item: &rss::Item, podcast_id: i32) -> Result { + NewEpisodeMinimal::new(item, podcast_id).map(|ep| ep.into_new_episode(item)) + } + // TODO: Refactor into batch indexes instead. #[allow(dead_code)] pub(crate) fn into_episode(self, con: &SqliteConnection) -> Result { @@ -227,7 +233,7 @@ impl NewEpisode { match ep { Ok(foo) => { if foo.podcast_id() != self.podcast_id { - error!("NEP pid: {}, EP pid: {}", self.podcast_id, foo.podcast_id()); + error!("NEP pid: {}\nEP pid: {}", self.podcast_id, foo.podcast_id()); }; if foo.title() != self.title.as_str() || foo.epoch() != self.epoch diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 03d1a46..79dad1a 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -1,12 +1,11 @@ use ammonia; use rss::{Channel, Item}; -use rfc822_sanitizer::parse_from_rfc2822_with_fallback; -use models::insertables::{NewEpisode, NewEpisodeBuilder, NewPodcast, NewPodcastBuilder}; +use models::insertables::{NewPodcast, NewPodcastBuilder}; use utils::url_cleaner; use utils::replace_extra_spaces; -use errors::*; +// use errors::*; /// Parses a `rss::Channel` into a `NewPodcast` Struct. pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast { @@ -38,57 +37,6 @@ pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast { .unwrap() } -/// Parses an `rss::Item` into a `NewEpisode` Struct. -pub(crate) fn new_episode(item: &Item, parent_id: i32) -> Result { - if item.title().is_none() { - bail!("No title specified for the item.") - } - - let title = item.title().unwrap().trim().to_owned(); - let guid = item.guid().map(|s| s.value().trim().to_owned()); - - // Prefer itunes summary over rss.description since many feeds put html into rss.description. - let summary = item.itunes_ext().map(|s| s.summary()).and_then(|s| s); - let description = if summary.is_some() { - summary.map(|s| replace_extra_spaces(&ammonia::clean(s))) - } else { - item.description() - .map(|s| replace_extra_spaces(&ammonia::clean(s))) - }; - - let uri = if let Some(url) = item.enclosure().map(|s| url_cleaner(s.url())) { - Some(url) - } else if item.link().is_some() { - item.link().map(|s| url_cleaner(s)) - } else { - bail!("No url specified for the item.") - }; - - let date = parse_from_rfc2822_with_fallback( - // Default to rfc2822 represantation of epoch 0. - item.pub_date().unwrap_or("Thu, 1 Jan 1970 00:00:00 +0000"), - ); - - // Should treat information from the rss feeds as invalid by default. - // Case: Thu, 05 Aug 2016 06:00:00 -0400 <-- Actually that was friday. - let epoch = date.map(|x| x.timestamp() as i32).unwrap_or(0); - - let length = || -> Option { item.enclosure().map(|x| x.length().parse().ok())? }(); - let duration = parse_itunes_duration(item); - - Ok(NewEpisodeBuilder::default() - .title(title) - .uri(uri) - .description(description) - .length(length) - .duration(duration) - .epoch(epoch) - .guid(guid) - .podcast_id(parent_id) - .build() - .unwrap()) -} - /// Parses an Item Itunes extension and returns it's duration value in seconds. // FIXME: Rafactor // TODO: Write tests @@ -124,6 +72,7 @@ mod tests { use std::fs::File; use std::io::BufReader; use rss; + use models::insertables::{NewEpisode, NewEpisodeBuilder}; use super::*; @@ -291,7 +240,7 @@ mod tests { campaign to bring violent neo-Nazis to justice. Rapper Open Mike Eagle \ performs."; - let ep = new_episode(&firstitem, 0).unwrap(); + let ep = NewEpisode::new(&firstitem, 0).unwrap(); let expected = NewEpisodeBuilder::default() .title("The Super Bowl of Racism") .uri(Some(String::from( @@ -308,7 +257,7 @@ mod tests { assert_eq!(ep, expected); let second = channel.items().iter().nth(1).unwrap(); - let ep = new_episode(&second, 0).unwrap(); + let ep = NewEpisode::new(&second, 0).unwrap(); let descr = "This week on Intercepted: Jeremy gives an update on the aftermath of \ Blackwater’s 2007 massacre of Iraqi civilians. Intercept reporter Lee Fang \ @@ -344,7 +293,7 @@ mod tests { let descr = "A reporter finds that homes meant to replace New York’s troubled psychiatric \ hospitals might be just as bad."; - let ep = new_episode(&firstitem, 0).unwrap(); + let ep = NewEpisode::new(&firstitem, 0).unwrap(); let expected = NewEpisodeBuilder::default() .title("The Breakthrough: Hopelessness and Exploitation Inside Homes for Mentally Ill") @@ -361,7 +310,7 @@ mod tests { assert_eq!(ep, expected); let second = channel.items().iter().nth(1).unwrap(); - let ep = new_episode(&second, 0).unwrap(); + let ep = NewEpisode::new(&second, 0).unwrap(); let descr = "Jonathan Allen and Amie Parnes didn’t know their book would be called \ ‘Shattered,’ or that their extraordinary access would let them chronicle the \ @@ -400,7 +349,7 @@ mod tests { decides to blow off a little steam by attacking his IoT devices, Wes has the \ scope on Equifax blaming open source & the Beard just saved the show. \ It’s a really packed episode!"; - let ep = new_episode(&firstitem, 0).unwrap(); + let ep = NewEpisode::new(&firstitem, 0).unwrap(); let expected = NewEpisodeBuilder::default() .title("Hacking Devices with Kali Linux | LUP 214") @@ -418,7 +367,7 @@ mod tests { assert_eq!(ep, expected); let second = channel.items().iter().nth(1).unwrap(); - let ep = new_episode(&second, 0).unwrap(); + let ep = NewEpisode::new(&second, 0).unwrap(); let descr = "The Gnome project is about to solve one of our audience's biggest Wayland’s \ @@ -451,7 +400,7 @@ mod tests { let firstitem = channel.items().iter().nth(9).unwrap(); let descr = "This week we look at RFC 2094 \"Non-lexical lifetimes\""; - let ep = new_episode(&firstitem, 0).unwrap(); + let ep = NewEpisode::new(&firstitem, 0).unwrap(); let expected = NewEpisodeBuilder::default() .title("Episode #9 - A Once in a Lifetime RFC") @@ -472,7 +421,7 @@ mod tests { assert_eq!(ep, expected); let second = channel.items().iter().nth(8).unwrap(); - let ep = new_episode(&second, 0).unwrap(); + let ep = NewEpisode::new(&second, 0).unwrap(); let descr = "This week we look at RFC 2071 \"Add impl Trait type alias and \ From 3766db2b14ab3ec36d59dff68311b65a3cf6e53f Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 17 Jan 2018 07:31:24 +0200 Subject: [PATCH 202/278] hammond_data: Move parse_podcast into a NewEpisode method. --- hammond-data/src/feed.rs | 3 +- hammond-data/src/models/insertables.rs | 31 +++++++++++++ hammond-data/src/parser.rs | 63 ++++++-------------------- 3 files changed, 45 insertions(+), 52 deletions(-) diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 999d8ad..a961914 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -9,7 +9,6 @@ use rayon::iter::IntoParallelIterator; use rss; use dbqueries; -use parser; use models::queryables::{Podcast, Source}; use models::insertables::{NewEpisode, NewPodcast}; @@ -74,7 +73,7 @@ impl Feed { } fn parse_podcast(&self) -> NewPodcast { - parser::new_podcast(&self.channel, self.source_id) + NewPodcast::new(&self.channel, self.source_id) } fn parse_podcast_futture(&self) -> Box> { diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/insertables.rs index e4e9c4b..4ac1c1a 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/insertables.rs @@ -109,6 +109,37 @@ impl Update for NewPodcast { } impl NewPodcast { + /// Parses a `rss::Channel` into a `NewPodcast` Struct. + pub(crate) fn new(chan: &rss::Channel, source_id: i32) -> NewPodcast { + let title = chan.title().trim(); + + // Prefer itunes summary over rss.description since many feeds put html into + // rss.description. + let summary = chan.itunes_ext().map(|s| s.summary()).and_then(|s| s); + let description = if let Some(sum) = summary { + replace_extra_spaces(&ammonia::clean(sum)) + } else { + replace_extra_spaces(&ammonia::clean(chan.description())) + }; + + let link = url_cleaner(chan.link()); + let x = chan.itunes_ext().map(|s| s.image()); + let image_uri = if let Some(img) = x { + img.map(|s| s.to_owned()) + } else { + chan.image().map(|foo| foo.url().to_owned()) + }; + + NewPodcastBuilder::default() + .title(title) + .description(description) + .link(link) + .image_uri(image_uri) + .source_id(source_id) + .build() + .unwrap() + } + // Look out for when tryinto lands into stable. pub(crate) fn into_podcast(self) -> Result { self.index()?; diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 79dad1a..68d304d 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -1,41 +1,4 @@ -use ammonia; -use rss::{Channel, Item}; - -use models::insertables::{NewPodcast, NewPodcastBuilder}; -use utils::url_cleaner; -use utils::replace_extra_spaces; - -// use errors::*; - -/// Parses a `rss::Channel` into a `NewPodcast` Struct. -pub(crate) fn new_podcast(chan: &Channel, source_id: i32) -> NewPodcast { - let title = chan.title().trim(); - - // Prefer itunes summary over rss.description since many feeds put html into rss.description. - let summary = chan.itunes_ext().map(|s| s.summary()).and_then(|s| s); - let description = if let Some(sum) = summary { - replace_extra_spaces(&ammonia::clean(sum)) - } else { - replace_extra_spaces(&ammonia::clean(chan.description())) - }; - - let link = url_cleaner(chan.link()); - let x = chan.itunes_ext().map(|s| s.image()); - let image_uri = if let Some(img) = x { - img.map(|s| s.to_owned()) - } else { - chan.image().map(|foo| foo.url().to_owned()) - }; - - NewPodcastBuilder::default() - .title(title) - .description(description) - .link(link) - .image_uri(image_uri) - .source_id(source_id) - .build() - .unwrap() -} +use rss::Item; /// Parses an Item Itunes extension and returns it's duration value in seconds. // FIXME: Rafactor @@ -71,21 +34,21 @@ pub(crate) fn parse_itunes_duration(item: &Item) -> Option { mod tests { use std::fs::File; use std::io::BufReader; - use rss; + use rss::{Channel, ItemBuilder}; + use rss::extension::itunes::ITunesItemExtensionBuilder; use models::insertables::{NewEpisode, NewEpisodeBuilder}; + use models::insertables::{NewPodcast, NewPodcastBuilder}; use super::*; #[test] fn test_itunes_duration() { - use rss::extension::itunes::ITunesItemExtensionBuilder; - // Input is a String let extension = ITunesItemExtensionBuilder::default() .duration(Some("3370".into())) .build() .unwrap(); - let item = rss::ItemBuilder::default() + let item = ItemBuilder::default() .itunes_ext(Some(extension)) .build() .unwrap(); @@ -96,7 +59,7 @@ mod tests { .duration(Some("6:10".into())) .build() .unwrap(); - let item = rss::ItemBuilder::default() + let item = ItemBuilder::default() .itunes_ext(Some(extension)) .build() .unwrap(); @@ -107,7 +70,7 @@ mod tests { .duration(Some("56:10".into())) .build() .unwrap(); - let item = rss::ItemBuilder::default() + let item = ItemBuilder::default() .itunes_ext(Some(extension)) .build() .unwrap(); @@ -118,7 +81,7 @@ mod tests { .duration(Some("1:56:10".into())) .build() .unwrap(); - let item = rss::ItemBuilder::default() + let item = ItemBuilder::default() .itunes_ext(Some(extension)) .build() .unwrap(); @@ -129,7 +92,7 @@ mod tests { .duration(Some("01:56:10".into())) .build() .unwrap(); - let item = rss::ItemBuilder::default() + let item = ItemBuilder::default() .itunes_ext(Some(extension)) .build() .unwrap(); @@ -147,7 +110,7 @@ mod tests { policy, and criminal justice. Plus interviews with artists, thinkers, and \ newsmakers who challenge our preconceptions about the world we live in."; - let pd = new_podcast(&channel, 0); + let pd = NewPodcast::new(&channel, 0); let expected = NewPodcastBuilder::default() .title("Intercepted with Jeremy Scahill") .link("https://theintercept.com/podcasts") @@ -170,7 +133,7 @@ mod tests { let descr = "The podcast that takes you behind the scenes with journalists to hear how \ they nailed their biggest stories."; - let pd = new_podcast(&channel, 0); + let pd = NewPodcast::new(&channel, 0); let expected = NewPodcastBuilder::default() .title("The Breakthrough") @@ -193,7 +156,7 @@ mod tests { let descr = "An open show powered by community LINUX Unplugged takes the best attributes \ of open collaboration and focuses them into a weekly lifestyle show about \ Linux."; - let pd = new_podcast(&channel, 0); + let pd = NewPodcast::new(&channel, 0); let expected = NewPodcastBuilder::default() .title("LINUX Unplugged Podcast") @@ -213,7 +176,7 @@ mod tests { let file = File::open("tests/feeds/R4Explanation.xml").unwrap(); let channel = Channel::read_from(BufReader::new(file)).unwrap(); - let pd = new_podcast(&channel, 0); + let pd = NewPodcast::new(&channel, 0); let expected = NewPodcastBuilder::default() .title("Request For Explanation") From 3a6f6d89316720002aa5444cdf48f837e374d9f6 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 17 Jan 2018 08:27:39 +0200 Subject: [PATCH 203/278] hammond_data: Split models::insertables into multiple modules. --- hammond-data/src/feed.rs | 3 +- hammond-data/src/models/mod.rs | 25 ++- .../models/{insertables.rs => new_episode.rs} | 199 ++---------------- hammond-data/src/models/new_podcast.rs | 131 ++++++++++++ hammond-data/src/models/new_source.rs | 58 +++++ hammond-data/src/models/queryables.rs | 2 +- hammond-data/src/parser.rs | 4 +- hammond-data/src/utils.rs | 2 +- 8 files changed, 231 insertions(+), 193 deletions(-) rename hammond-data/src/models/{insertables.rs => new_episode.rs} (54%) create mode 100644 hammond-data/src/models/new_podcast.rs create mode 100644 hammond-data/src/models/new_source.rs diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index a961914..f4d9390 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -11,7 +11,8 @@ use rss; use dbqueries; use models::queryables::{Podcast, Source}; -use models::insertables::{NewEpisode, NewPodcast}; +use models::NewPodcast; +use models::NewEpisode; use database::connection; use errors::*; diff --git a/hammond-data/src/models/mod.rs b/hammond-data/src/models/mod.rs index 9f4dc1b..2f23b13 100644 --- a/hammond-data/src/models/mod.rs +++ b/hammond-data/src/models/mod.rs @@ -1,2 +1,25 @@ -pub(crate) mod insertables; pub(crate) mod queryables; +pub(crate) mod new_episode; +pub(crate) mod new_podcast; +pub(crate) mod new_source; + +use diesel::prelude::*; + +pub(crate) use self::new_episode::{NewEpisode, NewEpisodeMinimal}; +pub(crate) use self::new_podcast::NewPodcast; +pub(crate) use self::new_source::NewSource; + +#[allow(dead_code)] +enum IndexState { + Index(T), + Update(T), + NotChanged, +} + +pub trait Insert { + fn insert(&self, &SqliteConnection) -> QueryResult; +} + +pub trait Update { + fn update(&self, &SqliteConnection, i32) -> QueryResult; +} diff --git a/hammond-data/src/models/insertables.rs b/hammond-data/src/models/new_episode.rs similarity index 54% rename from hammond-data/src/models/insertables.rs rename to hammond-data/src/models/new_episode.rs index 4ac1c1a..db4a69a 100644 --- a/hammond-data/src/models/insertables.rs +++ b/hammond-data/src/models/new_episode.rs @@ -1,196 +1,18 @@ -#![allow(unused_mut)] - use diesel::prelude::*; use diesel; +use schema::episode; use rss; use ammonia; use rfc822_sanitizer::parse_from_rfc2822_with_fallback as parse_rfc822; -use utils::{replace_extra_spaces, url_cleaner}; -use schema::{episode, podcast, source}; -use models::queryables::{Episode, Podcast, Source}; use dbqueries; -use database::connection; -use parser; - use errors::*; +use models::{Insert, Update}; +use models::queryables::Episode; -#[allow(dead_code)] -enum IndexState { - Index(T), - Update(T), - NotChanged, -} - -trait Insert { - fn insert(&self, &SqliteConnection) -> QueryResult; -} - -trait Update { - fn update(&self, &SqliteConnection, i32) -> QueryResult; -} - -#[derive(Insertable)] -#[table_name = "source"] -#[derive(Debug, Clone, Default, Builder, PartialEq)] -#[builder(default)] -#[builder(derive(Debug))] -#[builder(setter(into))] -pub(crate) struct NewSource { - uri: String, - last_modified: Option, - http_etag: Option, -} - -impl Insert for NewSource { - fn insert(&self, con: &SqliteConnection) -> QueryResult { - use schema::source::dsl::*; - diesel::insert_into(source).values(self).execute(&*con) - } -} - -impl NewSource { - pub(crate) fn new(uri: &str) -> NewSource { - NewSource { - uri: uri.trim().to_string(), - last_modified: None, - http_etag: None, - } - } - - fn index(&self) -> Result<()> { - let db = connection(); - let con = db.get()?; - - // Throw away the result like `insert or ignore` - // Diesel deos not support `insert or ignore` yet. - let _ = self.insert(&con); - Ok(()) - } - - // Look out for when tryinto lands into stable. - pub(crate) fn into_source(self) -> Result { - self.index()?; - dbqueries::get_source_from_uri(&self.uri) - } -} - -#[derive(Insertable, AsChangeset)] -#[table_name = "podcast"] -#[derive(Debug, Clone, Default, Builder, PartialEq)] -#[builder(default)] -#[builder(derive(Debug))] -#[builder(setter(into))] -pub(crate) struct NewPodcast { - title: String, - link: String, - description: String, - image_uri: Option, - source_id: i32, -} - -impl Insert for NewPodcast { - fn insert(&self, con: &SqliteConnection) -> QueryResult { - use schema::podcast::dsl::*; - diesel::insert_into(podcast).values(self).execute(&*con) - } -} - -impl Update for NewPodcast { - fn update(&self, con: &SqliteConnection, podcast_id: i32) -> QueryResult { - use schema::podcast::dsl::*; - - info!("Updating {}", self.title); - diesel::update(podcast.filter(id.eq(podcast_id))) - .set(self) - .execute(&*con) - } -} - -impl NewPodcast { - /// Parses a `rss::Channel` into a `NewPodcast` Struct. - pub(crate) fn new(chan: &rss::Channel, source_id: i32) -> NewPodcast { - let title = chan.title().trim(); - - // Prefer itunes summary over rss.description since many feeds put html into - // rss.description. - let summary = chan.itunes_ext().map(|s| s.summary()).and_then(|s| s); - let description = if let Some(sum) = summary { - replace_extra_spaces(&ammonia::clean(sum)) - } else { - replace_extra_spaces(&ammonia::clean(chan.description())) - }; - - let link = url_cleaner(chan.link()); - let x = chan.itunes_ext().map(|s| s.image()); - let image_uri = if let Some(img) = x { - img.map(|s| s.to_owned()) - } else { - chan.image().map(|foo| foo.url().to_owned()) - }; - - NewPodcastBuilder::default() - .title(title) - .description(description) - .link(link) - .image_uri(image_uri) - .source_id(source_id) - .build() - .unwrap() - } - - // Look out for when tryinto lands into stable. - pub(crate) fn into_podcast(self) -> Result { - self.index()?; - Ok(dbqueries::get_podcast_from_source_id(self.source_id)?) - } - - pub(crate) fn index(&self) -> Result<()> { - let pd = dbqueries::get_podcast_from_source_id(self.source_id); - - let db = connection(); - let con = db.get()?; - match pd { - Ok(foo) => { - if (foo.link() != self.link) || (foo.title() != self.title) - || (foo.image_uri() != self.image_uri.as_ref().map(|x| x.as_str())) - { - info!("NewEpisode: {:?}\n OldEpisode: {:?}", self, foo); - self.update(&con, foo.id())?; - } - } - Err(_) => { - self.insert(&con)?; - } - } - Ok(()) - } -} - -#[allow(dead_code)] -// Ignore the following geters. They are used in unit tests mainly. -impl NewPodcast { - pub(crate) fn source_id(&self) -> i32 { - self.source_id - } - - pub(crate) fn title(&self) -> &str { - &self.title - } - - pub(crate) fn link(&self) -> &str { - &self.link - } - - pub(crate) fn description(&self) -> &str { - &self.description - } - - pub(crate) fn image_uri(&self) -> Option<&str> { - self.image_uri.as_ref().map(|s| s.as_str()) - } -} +use utils::{replace_extra_spaces, url_cleaner}; +use parser; #[derive(Insertable, AsChangeset)] #[table_name = "episode"] @@ -217,6 +39,7 @@ impl From for NewEpisode { .duration(e.duration) .epoch(e.epoch) .podcast_id(e.podcast_id) + .guid(e.guid) .build() .unwrap() } @@ -324,17 +147,19 @@ pub(crate) struct NewEpisodeMinimal { uri: Option, duration: Option, epoch: i32, + guid: Option, podcast_id: i32, } impl NewEpisodeMinimal { #[allow(dead_code)] - fn new(item: &rss::Item, parent_id: i32) -> Result { + pub(crate) fn new(item: &rss::Item, parent_id: i32) -> Result { if item.title().is_none() { bail!("No title specified for the item.") } let title = item.title().unwrap().trim().to_owned(); + let guid = item.guid().map(|s| s.value().trim().to_owned()); let uri = if let Some(url) = item.enclosure().map(|s| url_cleaner(s.url())) { Some(url) @@ -359,14 +184,14 @@ impl NewEpisodeMinimal { .uri(uri) .duration(duration) .epoch(epoch) + .guid(guid) .podcast_id(parent_id) .build() .unwrap()) } #[allow(dead_code)] - fn into_new_episode(self, item: &rss::Item) -> NewEpisode { - let guid = item.guid().map(|s| s.value().trim().to_owned()); + pub(crate) fn into_new_episode(self, item: &rss::Item) -> NewEpisode { let length = || -> Option { item.enclosure().map(|x| x.length().parse().ok())? }(); // Prefer itunes summary over rss.description since many feeds put html into @@ -385,7 +210,7 @@ impl NewEpisodeMinimal { .duration(self.duration) .epoch(self.epoch) .podcast_id(self.podcast_id) - .guid(guid) + .guid(self.guid) .length(length) .description(description) .build() diff --git a/hammond-data/src/models/new_podcast.rs b/hammond-data/src/models/new_podcast.rs new file mode 100644 index 0000000..ccf3906 --- /dev/null +++ b/hammond-data/src/models/new_podcast.rs @@ -0,0 +1,131 @@ +use diesel::prelude::*; +use diesel; + +use rss; +use ammonia; + +use schema::podcast; +use models::queryables::Podcast; +use models::{Insert, Update}; + +use dbqueries; +use database::connection; +use utils::{replace_extra_spaces, url_cleaner}; + +use errors::*; + +#[derive(Insertable, AsChangeset)] +#[table_name = "podcast"] +#[derive(Debug, Clone, Default, Builder, PartialEq)] +#[builder(default)] +#[builder(derive(Debug))] +#[builder(setter(into))] +pub(crate) struct NewPodcast { + title: String, + link: String, + description: String, + image_uri: Option, + source_id: i32, +} + +impl Insert for NewPodcast { + fn insert(&self, con: &SqliteConnection) -> QueryResult { + use schema::podcast::dsl::*; + diesel::insert_into(podcast).values(self).execute(&*con) + } +} + +impl Update for NewPodcast { + fn update(&self, con: &SqliteConnection, podcast_id: i32) -> QueryResult { + use schema::podcast::dsl::*; + + info!("Updating {}", self.title); + diesel::update(podcast.filter(id.eq(podcast_id))) + .set(self) + .execute(&*con) + } +} + +impl NewPodcast { + /// Parses a `rss::Channel` into a `NewPodcast` Struct. + pub(crate) fn new(chan: &rss::Channel, source_id: i32) -> NewPodcast { + let title = chan.title().trim(); + + // Prefer itunes summary over rss.description since many feeds put html into + // rss.description. + let summary = chan.itunes_ext().map(|s| s.summary()).and_then(|s| s); + let description = if let Some(sum) = summary { + replace_extra_spaces(&ammonia::clean(sum)) + } else { + replace_extra_spaces(&ammonia::clean(chan.description())) + }; + + let link = url_cleaner(chan.link()); + let x = chan.itunes_ext().map(|s| s.image()); + let image_uri = if let Some(img) = x { + img.map(|s| s.to_owned()) + } else { + chan.image().map(|foo| foo.url().to_owned()) + }; + + NewPodcastBuilder::default() + .title(title) + .description(description) + .link(link) + .image_uri(image_uri) + .source_id(source_id) + .build() + .unwrap() + } + + // Look out for when tryinto lands into stable. + pub(crate) fn into_podcast(self) -> Result { + self.index()?; + Ok(dbqueries::get_podcast_from_source_id(self.source_id)?) + } + + pub(crate) fn index(&self) -> Result<()> { + let pd = dbqueries::get_podcast_from_source_id(self.source_id); + + let db = connection(); + let con = db.get()?; + match pd { + Ok(foo) => { + if (foo.link() != self.link) || (foo.title() != self.title) + || (foo.image_uri() != self.image_uri.as_ref().map(|x| x.as_str())) + { + info!("NewEpisode: {:?}\n OldEpisode: {:?}", self, foo); + self.update(&con, foo.id())?; + } + } + Err(_) => { + self.insert(&con)?; + } + } + Ok(()) + } +} + +#[allow(dead_code)] +// Ignore the following geters. They are used in unit tests mainly. +impl NewPodcast { + pub(crate) fn source_id(&self) -> i32 { + self.source_id + } + + pub(crate) fn title(&self) -> &str { + &self.title + } + + pub(crate) fn link(&self) -> &str { + &self.link + } + + pub(crate) fn description(&self) -> &str { + &self.description + } + + pub(crate) fn image_uri(&self) -> Option<&str> { + self.image_uri.as_ref().map(|s| s.as_str()) + } +} diff --git a/hammond-data/src/models/new_source.rs b/hammond-data/src/models/new_source.rs new file mode 100644 index 0000000..50b55e9 --- /dev/null +++ b/hammond-data/src/models/new_source.rs @@ -0,0 +1,58 @@ +#![allow(unused_mut)] + +use diesel::prelude::*; +use diesel; + +use schema::source; +use models::queryables::Source; +use models::{Insert, Update}; + +use dbqueries; +use database::connection; + +use errors::*; + +#[derive(Insertable)] +#[table_name = "source"] +#[derive(Debug, Clone, Default, Builder, PartialEq)] +#[builder(default)] +#[builder(derive(Debug))] +#[builder(setter(into))] +pub(crate) struct NewSource { + uri: String, + last_modified: Option, + http_etag: Option, +} + +impl Insert for NewSource { + fn insert(&self, con: &SqliteConnection) -> QueryResult { + use schema::source::dsl::*; + diesel::insert_into(source).values(self).execute(&*con) + } +} + +impl NewSource { + pub(crate) fn new(uri: &str) -> NewSource { + NewSource { + uri: uri.trim().to_string(), + last_modified: None, + http_etag: None, + } + } + + fn index(&self) -> Result<()> { + let db = connection(); + let con = db.get()?; + + // Throw away the result like `insert or ignore` + // Diesel deos not support `insert or ignore` yet. + let _ = self.insert(&con); + Ok(()) + } + + // Look out for when tryinto lands into stable. + pub(crate) fn into_source(self) -> Result { + self.index()?; + dbqueries::get_source_from_uri(&self.uri) + } +} diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs index d6f8390..834df52 100644 --- a/hammond-data/src/models/queryables.rs +++ b/hammond-data/src/models/queryables.rs @@ -19,7 +19,7 @@ use schema::{episode, podcast, source}; use feed::Feed; use errors::*; -use models::insertables::NewSource; +use models::NewSource; use database::connection; use std::io::Read; diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index 68d304d..a17c932 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -36,8 +36,8 @@ mod tests { use std::io::BufReader; use rss::{Channel, ItemBuilder}; use rss::extension::itunes::ITunesItemExtensionBuilder; - use models::insertables::{NewEpisode, NewEpisodeBuilder}; - use models::insertables::{NewPodcast, NewPodcastBuilder}; + use models::new_episode::{NewEpisode, NewEpisodeBuilder}; + use models::new_podcast::{NewPodcast, NewPodcastBuilder}; use super::*; diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index 108a6ac..77e126f 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -153,7 +153,7 @@ mod tests { use super::*; use database::{connection, truncate_db}; - use models::insertables::NewEpisodeBuilder; + use models::new_episode::NewEpisodeBuilder; use self::tempdir::TempDir; use std::fs::File; use std::io::Write; From e707087e72810a57363b714252fa14bc4ec2e9f5 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 17 Jan 2018 08:45:14 +0200 Subject: [PATCH 204/278] hammond_data: Split models::queriables into multiple modules. --- hammond-data/src/dbqueries.rs | 3 +- hammond-data/src/feed.rs | 5 +- hammond-data/src/lib.rs | 2 +- hammond-data/src/models/episode.rs | 414 ++++++++++++ hammond-data/src/models/mod.rs | 10 +- hammond-data/src/models/new_episode.rs | 2 +- hammond-data/src/models/new_podcast.rs | 2 +- hammond-data/src/models/new_source.rs | 2 +- hammond-data/src/models/podcast.rs | 158 +++++ hammond-data/src/models/queryables.rs | 844 ------------------------- hammond-data/src/models/source.rs | 286 +++++++++ hammond-data/src/utils.rs | 2 +- 12 files changed, 874 insertions(+), 856 deletions(-) create mode 100644 hammond-data/src/models/episode.rs create mode 100644 hammond-data/src/models/podcast.rs delete mode 100644 hammond-data/src/models/queryables.rs create mode 100644 hammond-data/src/models/source.rs diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 9dfbd81..edc9603 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -2,8 +2,7 @@ use diesel::prelude::*; use diesel; -use models::queryables::{Episode, EpisodeCleanerQuery, EpisodeWidgetQuery, Podcast, - PodcastCoverQuery, Source}; +use models::{Episode, EpisodeCleanerQuery, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; use chrono::prelude::*; use errors::*; diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index f4d9390..38d33a3 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -9,10 +9,7 @@ use rayon::iter::IntoParallelIterator; use rss; use dbqueries; - -use models::queryables::{Podcast, Source}; -use models::NewPodcast; -use models::NewEpisode; +use models::{NewEpisode, NewPodcast, Podcast, Source}; use database::connection; use errors::*; diff --git a/hammond-data/src/lib.rs b/hammond-data/src/lib.rs index 5507eee..d9f7c92 100644 --- a/hammond-data/src/lib.rs +++ b/hammond-data/src/lib.rs @@ -70,7 +70,7 @@ pub(crate) mod models; mod parser; mod schema; -pub use models::queryables::{Episode, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; +pub use models::{Episode, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; // pub use feed::Feed; /// [XDG Base Direcotory](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html) Paths. diff --git a/hammond-data/src/models/episode.rs b/hammond-data/src/models/episode.rs new file mode 100644 index 0000000..52d863a --- /dev/null +++ b/hammond-data/src/models/episode.rs @@ -0,0 +1,414 @@ +use chrono::prelude::*; +use diesel::prelude::*; +use diesel; + +use diesel::SaveChangesDsl; + +use schema::episode; +use errors::*; +use database::connection; +use models::Podcast; + +#[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] +#[table_name = "episode"] +#[changeset_options(treat_none_as_null = "true")] +#[primary_key(title, podcast_id)] +#[belongs_to(Podcast, foreign_key = "podcast_id")] +#[derive(Debug, Clone)] +/// Diesel Model of the episode table. +pub struct Episode { + rowid: i32, + title: String, + uri: Option, + local_uri: Option, + description: Option, + epoch: i32, + length: Option, + duration: Option, + guid: Option, + played: Option, + favorite: bool, + archive: bool, + podcast_id: i32, +} + +impl Episode { + /// Get the value of the sqlite's `ROW_ID` + pub fn rowid(&self) -> i32 { + self.rowid + } + + /// Get the value of the `title` field. + pub fn title(&self) -> &str { + &self.title + } + + /// Set the `title`. + pub fn set_title(&mut self, value: &str) { + self.title = value.to_string(); + } + + /// Get the value of the `uri`. + /// + /// Represents the url(usually) that the media file will be located at. + pub fn uri(&self) -> Option<&str> { + self.uri.as_ref().map(|s| s.as_str()) + } + + /// Set the `uri`. + pub fn set_uri(&mut self, value: Option<&str>) { + self.uri = value.map(|x| x.to_string()); + } + + /// Get the value of the `local_uri`. + /// + /// Represents the local uri,usually filesystem path, + /// that the media file will be located at. + pub fn local_uri(&self) -> Option<&str> { + self.local_uri.as_ref().map(|s| s.as_str()) + } + + /// Set the `local_uri`. + pub fn set_local_uri(&mut self, value: Option<&str>) { + self.local_uri = value.map(|x| x.to_string()); + } + + /// Get the `description`. + pub fn description(&self) -> Option<&str> { + self.description.as_ref().map(|s| s.as_str()) + } + + /// Set the `description`. + pub fn set_description(&mut self, value: Option<&str>) { + self.description = value.map(|x| x.to_string()); + } + + /// Get the value of the `description`. + pub fn guid(&self) -> Option<&str> { + self.guid.as_ref().map(|s| s.as_str()) + } + + /// Set the `guid`. + pub fn set_guid(&mut self, value: Option<&str>) { + self.guid = value.map(|x| x.to_string()); + } + + /// Get the `epoch` value. + /// + /// Retrieved from the rss Item publish date. + /// Value is set to Utc whenever possible. + pub fn epoch(&self) -> i32 { + self.epoch + } + + /// Set the `epoch`. + pub fn set_epoch(&mut self, value: i32) { + self.epoch = value; + } + + /// Get the `length`. + /// + /// The number represents the size of the file in bytes. + pub fn length(&self) -> Option { + self.length + } + + /// Set the `length`. + pub fn set_length(&mut self, value: Option) { + self.length = value; + } + + /// Get the `duration` value. + /// + /// The number represents the duration of the item/episode in seconds. + pub fn duration(&self) -> Option { + self.duration + } + + /// Set the `duration`. + pub fn set_duration(&mut self, value: Option) { + self.duration = value; + } + + /// Epoch representation of the last time the episode was played. + /// + /// None/Null for unplayed. + pub fn played(&self) -> Option { + self.played + } + + /// Set the `played` value. + pub fn set_played(&mut self, value: Option) { + self.played = value; + } + + /// Represents the archiving policy for the episode. + pub fn archive(&self) -> bool { + self.archive + } + + /// Set the `archive` policy. + /// + /// If true, the download cleanr will ignore the episode + /// and the corresponding media value will never be automaticly deleted. + pub fn set_archive(&mut self, b: bool) { + self.archive = b + } + + /// Get the `favorite` status of the `Episode`. + pub fn favorite(&self) -> bool { + self.favorite + } + + /// Set `favorite` status. + pub fn set_favorite(&mut self, b: bool) { + self.favorite = b + } + + /// `Podcast` table foreign key. + pub fn podcast_id(&self) -> i32 { + self.podcast_id + } + + /// Sets the `played` value with the current `epoch` timestap and save it. + pub fn set_played_now(&mut self) -> Result<()> { + let epoch = Utc::now().timestamp() as i32; + self.set_played(Some(epoch)); + self.save()?; + Ok(()) + } + + /// Helper method to easily save/"sync" current state of self to the Database. + pub fn save(&self) -> Result { + let db = connection(); + let tempdb = db.get()?; + + Ok(self.save_changes::(&*tempdb)?) + } +} + +#[derive(Queryable, AsChangeset, PartialEq)] +#[table_name = "episode"] +#[changeset_options(treat_none_as_null = "true")] +#[primary_key(title, podcast_id)] +#[derive(Debug, Clone)] +/// Diesel Model to be used for constructing `EpisodeWidgets`. +pub struct EpisodeWidgetQuery { + rowid: i32, + title: String, + uri: Option, + local_uri: Option, + epoch: i32, + length: Option, + duration: Option, + played: Option, + // favorite: bool, + // archive: bool, + podcast_id: i32, +} + +impl From for EpisodeWidgetQuery { + fn from(e: Episode) -> EpisodeWidgetQuery { + EpisodeWidgetQuery { + rowid: e.rowid, + title: e.title, + uri: e.uri, + local_uri: e.local_uri, + epoch: e.epoch, + length: e.length, + duration: e.duration, + played: e.played, + podcast_id: e.podcast_id, + } + } +} + +impl EpisodeWidgetQuery { + /// Get the value of the sqlite's `ROW_ID` + pub fn rowid(&self) -> i32 { + self.rowid + } + + /// Get the value of the `title` field. + pub fn title(&self) -> &str { + &self.title + } + + /// Get the value of the `uri`. + /// + /// Represents the url(usually) that the media file will be located at. + pub fn uri(&self) -> Option<&str> { + self.uri.as_ref().map(|s| s.as_str()) + } + + /// Get the value of the `local_uri`. + /// + /// Represents the local uri,usually filesystem path, + /// that the media file will be located at. + pub fn local_uri(&self) -> Option<&str> { + self.local_uri.as_ref().map(|s| s.as_str()) + } + + /// Set the `local_uri`. + pub fn set_local_uri(&mut self, value: Option<&str>) { + self.local_uri = value.map(|x| x.to_string()); + } + + /// Get the `epoch` value. + /// + /// Retrieved from the rss Item publish date. + /// Value is set to Utc whenever possible. + pub fn epoch(&self) -> i32 { + self.epoch + } + + /// Get the `length`. + /// + /// The number represents the size of the file in bytes. + pub fn length(&self) -> Option { + self.length + } + + /// Set the `length`. + pub fn set_length(&mut self, value: Option) { + self.length = value; + } + + /// Get the `duration` value. + /// + /// The number represents the duration of the item/episode in seconds. + pub fn duration(&self) -> Option { + self.duration + } + + /// Set the `duration`. + pub fn set_duration(&mut self, value: Option) { + self.duration = value; + } + + /// Epoch representation of the last time the episode was played. + /// + /// None/Null for unplayed. + pub fn played(&self) -> Option { + self.played + } + + /// Set the `played` value. + pub fn set_played(&mut self, value: Option) { + self.played = value; + } + + // /// Represents the archiving policy for the episode. + // pub fn archive(&self) -> bool { + // self.archive + // } + + // /// Set the `archive` policy. + // /// + // /// If true, the download cleanr will ignore the episode + // /// and the corresponding media value will never be automaticly deleted. + // pub fn set_archive(&mut self, b: bool) { + // self.archive = b + // } + + // /// Get the `favorite` status of the `Episode`. + // pub fn favorite(&self) -> bool { + // self.favorite + // } + + // /// Set `favorite` status. + // pub fn set_favorite(&mut self, b: bool) { + // self.favorite = b + // } + + /// `Podcast` table foreign key. + pub fn podcast_id(&self) -> i32 { + self.podcast_id + } + + /// Sets the `played` value with the current `epoch` timestap and save it. + pub fn set_played_now(&mut self) -> Result<()> { + let epoch = Utc::now().timestamp() as i32; + self.set_played(Some(epoch)); + self.save()?; + Ok(()) + } + + /// Helper method to easily save/"sync" current state of self to the Database. + pub fn save(&self) -> Result { + use schema::episode::dsl::*; + + let db = connection(); + let tempdb = db.get()?; + + Ok(diesel::update(episode.filter(rowid.eq(self.rowid))) + .set(self) + .execute(&*tempdb)?) + } +} + +#[derive(Queryable, AsChangeset, PartialEq)] +#[table_name = "episode"] +#[changeset_options(treat_none_as_null = "true")] +#[primary_key(title, podcast_id)] +#[derive(Debug, Clone)] +/// Diesel Model to be used internal with the `utils::checkup` function. +pub struct EpisodeCleanerQuery { + rowid: i32, + local_uri: Option, + played: Option, +} + +impl From for EpisodeCleanerQuery { + fn from(e: Episode) -> EpisodeCleanerQuery { + EpisodeCleanerQuery { + rowid: e.rowid(), + local_uri: e.local_uri, + played: e.played, + } + } +} + +impl EpisodeCleanerQuery { + /// Get the value of the sqlite's `ROW_ID` + pub fn rowid(&self) -> i32 { + self.rowid + } + + /// Get the value of the `local_uri`. + /// + /// Represents the local uri,usually filesystem path, + /// that the media file will be located at. + pub fn local_uri(&self) -> Option<&str> { + self.local_uri.as_ref().map(|s| s.as_str()) + } + + /// Set the `local_uri`. + pub fn set_local_uri(&mut self, value: Option<&str>) { + self.local_uri = value.map(|x| x.to_string()); + } + + /// Epoch representation of the last time the episode was played. + /// + /// None/Null for unplayed. + pub fn played(&self) -> Option { + self.played + } + + /// Set the `played` value. + pub fn set_played(&mut self, value: Option) { + self.played = value; + } + + /// Helper method to easily save/"sync" current state of self to the Database. + pub fn save(&self) -> Result { + use schema::episode::dsl::*; + + let db = connection(); + let tempdb = db.get()?; + + Ok(diesel::update(episode.filter(rowid.eq(self.rowid()))) + .set(self) + .execute(&*tempdb)?) + } +} diff --git a/hammond-data/src/models/mod.rs b/hammond-data/src/models/mod.rs index 2f23b13..6e0972c 100644 --- a/hammond-data/src/models/mod.rs +++ b/hammond-data/src/models/mod.rs @@ -1,14 +1,22 @@ -pub(crate) mod queryables; pub(crate) mod new_episode; pub(crate) mod new_podcast; pub(crate) mod new_source; +pub(crate) mod episode; +pub(crate) mod podcast; +pub(crate) mod source; + use diesel::prelude::*; pub(crate) use self::new_episode::{NewEpisode, NewEpisodeMinimal}; pub(crate) use self::new_podcast::NewPodcast; pub(crate) use self::new_source::NewSource; +pub use self::episode::{Episode, EpisodeWidgetQuery}; +pub use self::podcast::{Podcast, PodcastCoverQuery}; +pub use self::source::Source; +pub(crate) use self::episode::EpisodeCleanerQuery; + #[allow(dead_code)] enum IndexState { Index(T), diff --git a/hammond-data/src/models/new_episode.rs b/hammond-data/src/models/new_episode.rs index db4a69a..bc12dd9 100644 --- a/hammond-data/src/models/new_episode.rs +++ b/hammond-data/src/models/new_episode.rs @@ -9,7 +9,7 @@ use rfc822_sanitizer::parse_from_rfc2822_with_fallback as parse_rfc822; use dbqueries; use errors::*; use models::{Insert, Update}; -use models::queryables::Episode; +use models::Episode; use utils::{replace_extra_spaces, url_cleaner}; use parser; diff --git a/hammond-data/src/models/new_podcast.rs b/hammond-data/src/models/new_podcast.rs index ccf3906..b3765c9 100644 --- a/hammond-data/src/models/new_podcast.rs +++ b/hammond-data/src/models/new_podcast.rs @@ -5,7 +5,7 @@ use rss; use ammonia; use schema::podcast; -use models::queryables::Podcast; +use models::Podcast; use models::{Insert, Update}; use dbqueries; diff --git a/hammond-data/src/models/new_source.rs b/hammond-data/src/models/new_source.rs index 50b55e9..33f320d 100644 --- a/hammond-data/src/models/new_source.rs +++ b/hammond-data/src/models/new_source.rs @@ -4,7 +4,7 @@ use diesel::prelude::*; use diesel; use schema::source; -use models::queryables::Source; +use models::Source; use models::{Insert, Update}; use dbqueries; diff --git a/hammond-data/src/models/podcast.rs b/hammond-data/src/models/podcast.rs new file mode 100644 index 0000000..63554c7 --- /dev/null +++ b/hammond-data/src/models/podcast.rs @@ -0,0 +1,158 @@ +use diesel::SaveChangesDsl; + +// use futures::future::{ok, result}; + +use schema::podcast; +use errors::*; +use database::connection; +use models::Source; + +#[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] +#[belongs_to(Source, foreign_key = "source_id")] +#[changeset_options(treat_none_as_null = "true")] +#[table_name = "podcast"] +#[derive(Debug, Clone)] +/// Diesel Model of the podcast table. +pub struct Podcast { + id: i32, + title: String, + link: String, + description: String, + image_uri: Option, + favorite: bool, + archive: bool, + always_dl: bool, + source_id: i32, +} + +impl Podcast { + /// Get the Feed `id`. + pub fn id(&self) -> i32 { + self.id + } + + /// Get the Feed `title`. + pub fn title(&self) -> &str { + &self.title + } + + /// Get the Feed `link`. + /// + /// Usually the website/homepage of the content creator. + pub fn link(&self) -> &str { + &self.link + } + + /// Set the Podcast/Feed `link`. + pub fn set_link(&mut self, value: &str) { + self.link = value.to_string(); + } + + /// Get the `description`. + pub fn description(&self) -> &str { + &self.description + } + + /// Set the `description`. + pub fn set_description(&mut self, value: &str) { + self.description = value.to_string(); + } + + /// Get the `image_uri`. + /// + /// Represents the uri(url usually) that the Feed cover image is located at. + pub fn image_uri(&self) -> Option<&str> { + self.image_uri.as_ref().map(|s| s.as_str()) + } + + /// Set the `image_uri`. + pub fn set_image_uri(&mut self, value: Option<&str>) { + self.image_uri = value.map(|x| x.to_string()); + } + + /// Represents the archiving policy for the episode. + pub fn archive(&self) -> bool { + self.archive + } + + /// Set the `archive` policy. + pub fn set_archive(&mut self, b: bool) { + self.archive = b + } + + /// Get the `favorite` status of the `Podcast` Feed. + pub fn favorite(&self) -> bool { + self.favorite + } + + /// Set `favorite` status. + pub fn set_favorite(&mut self, b: bool) { + self.favorite = b + } + + /// Represents the download policy for the `Podcast` Feed. + /// + /// Reserved for the use with a Download manager, yet to be implemented. + /// + /// If true Podcast Episode should be downloaded automaticly/skipping + /// the selection queue. + pub fn always_download(&self) -> bool { + self.always_dl + } + + /// Set the download policy. + pub fn set_always_download(&mut self, b: bool) { + self.always_dl = b + } + + /// `Source` table foreign key. + pub fn source_id(&self) -> i32 { + self.source_id + } + + /// Helper method to easily save/"sync" current state of self to the Database. + pub fn save(&self) -> Result { + let db = connection(); + let tempdb = db.get()?; + + Ok(self.save_changes::(&*tempdb)?) + } +} + +#[derive(Queryable, Debug, Clone)] +/// Diesel Model of the podcast cover query. +/// Used for fetching information about a Podcast's cover. +pub struct PodcastCoverQuery { + id: i32, + title: String, + image_uri: Option, +} + +impl From for PodcastCoverQuery { + fn from(p: Podcast) -> PodcastCoverQuery { + PodcastCoverQuery { + id: p.id(), + title: p.title, + image_uri: p.image_uri, + } + } +} + +impl PodcastCoverQuery { + /// Get the Feed `id`. + pub fn id(&self) -> i32 { + self.id + } + + /// Get the Feed `title`. + pub fn title(&self) -> &str { + &self.title + } + + /// Get the `image_uri`. + /// + /// Represents the uri(url usually) that the Feed cover image is located at. + pub fn image_uri(&self) -> Option<&str> { + self.image_uri.as_ref().map(|s| s.as_str()) + } +} diff --git a/hammond-data/src/models/queryables.rs b/hammond-data/src/models/queryables.rs deleted file mode 100644 index 834df52..0000000 --- a/hammond-data/src/models/queryables.rs +++ /dev/null @@ -1,844 +0,0 @@ -use chrono::prelude::*; -use diesel::prelude::*; -use diesel; - -use reqwest; -use diesel::SaveChangesDsl; -use rss::Channel; - -use hyper; -use hyper::client::HttpConnector; -use hyper::{Client, Method, Request, Response, StatusCode, Uri}; -use hyper::header::{ETag, EntityTag, HttpDate, IfModifiedSince, IfNoneMatch, LastModified}; -use hyper_tls::HttpsConnector; - -use futures::prelude::*; -// use futures::future::{ok, result}; - -use schema::{episode, podcast, source}; -use feed::Feed; -use errors::*; - -use models::NewSource; -use database::connection; - -use std::io::Read; -use std::str::FromStr; - -#[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] -#[table_name = "episode"] -#[changeset_options(treat_none_as_null = "true")] -#[primary_key(title, podcast_id)] -#[belongs_to(Podcast, foreign_key = "podcast_id")] -#[derive(Debug, Clone)] -/// Diesel Model of the episode table. -pub struct Episode { - rowid: i32, - title: String, - uri: Option, - local_uri: Option, - description: Option, - epoch: i32, - length: Option, - duration: Option, - guid: Option, - played: Option, - favorite: bool, - archive: bool, - podcast_id: i32, -} - -impl Episode { - /// Get the value of the sqlite's `ROW_ID` - pub fn rowid(&self) -> i32 { - self.rowid - } - - /// Get the value of the `title` field. - pub fn title(&self) -> &str { - &self.title - } - - /// Set the `title`. - pub fn set_title(&mut self, value: &str) { - self.title = value.to_string(); - } - - /// Get the value of the `uri`. - /// - /// Represents the url(usually) that the media file will be located at. - pub fn uri(&self) -> Option<&str> { - self.uri.as_ref().map(|s| s.as_str()) - } - - /// Set the `uri`. - pub fn set_uri(&mut self, value: Option<&str>) { - self.uri = value.map(|x| x.to_string()); - } - - /// Get the value of the `local_uri`. - /// - /// Represents the local uri,usually filesystem path, - /// that the media file will be located at. - pub fn local_uri(&self) -> Option<&str> { - self.local_uri.as_ref().map(|s| s.as_str()) - } - - /// Set the `local_uri`. - pub fn set_local_uri(&mut self, value: Option<&str>) { - self.local_uri = value.map(|x| x.to_string()); - } - - /// Get the `description`. - pub fn description(&self) -> Option<&str> { - self.description.as_ref().map(|s| s.as_str()) - } - - /// Set the `description`. - pub fn set_description(&mut self, value: Option<&str>) { - self.description = value.map(|x| x.to_string()); - } - - /// Get the value of the `description`. - pub fn guid(&self) -> Option<&str> { - self.guid.as_ref().map(|s| s.as_str()) - } - - /// Set the `guid`. - pub fn set_guid(&mut self, value: Option<&str>) { - self.guid = value.map(|x| x.to_string()); - } - - /// Get the `epoch` value. - /// - /// Retrieved from the rss Item publish date. - /// Value is set to Utc whenever possible. - pub fn epoch(&self) -> i32 { - self.epoch - } - - /// Set the `epoch`. - pub fn set_epoch(&mut self, value: i32) { - self.epoch = value; - } - - /// Get the `length`. - /// - /// The number represents the size of the file in bytes. - pub fn length(&self) -> Option { - self.length - } - - /// Set the `length`. - pub fn set_length(&mut self, value: Option) { - self.length = value; - } - - /// Get the `duration` value. - /// - /// The number represents the duration of the item/episode in seconds. - pub fn duration(&self) -> Option { - self.duration - } - - /// Set the `duration`. - pub fn set_duration(&mut self, value: Option) { - self.duration = value; - } - - /// Epoch representation of the last time the episode was played. - /// - /// None/Null for unplayed. - pub fn played(&self) -> Option { - self.played - } - - /// Set the `played` value. - pub fn set_played(&mut self, value: Option) { - self.played = value; - } - - /// Represents the archiving policy for the episode. - pub fn archive(&self) -> bool { - self.archive - } - - /// Set the `archive` policy. - /// - /// If true, the download cleanr will ignore the episode - /// and the corresponding media value will never be automaticly deleted. - pub fn set_archive(&mut self, b: bool) { - self.archive = b - } - - /// Get the `favorite` status of the `Episode`. - pub fn favorite(&self) -> bool { - self.favorite - } - - /// Set `favorite` status. - pub fn set_favorite(&mut self, b: bool) { - self.favorite = b - } - - /// `Podcast` table foreign key. - pub fn podcast_id(&self) -> i32 { - self.podcast_id - } - - /// Sets the `played` value with the current `epoch` timestap and save it. - pub fn set_played_now(&mut self) -> Result<()> { - let epoch = Utc::now().timestamp() as i32; - self.set_played(Some(epoch)); - self.save()?; - Ok(()) - } - - /// Helper method to easily save/"sync" current state of self to the Database. - pub fn save(&self) -> Result { - let db = connection(); - let tempdb = db.get()?; - - Ok(self.save_changes::(&*tempdb)?) - } -} - -#[derive(Queryable, AsChangeset, PartialEq)] -#[table_name = "episode"] -#[changeset_options(treat_none_as_null = "true")] -#[primary_key(title, podcast_id)] -#[derive(Debug, Clone)] -/// Diesel Model to be used for constructing `EpisodeWidgets`. -pub struct EpisodeWidgetQuery { - rowid: i32, - title: String, - uri: Option, - local_uri: Option, - epoch: i32, - length: Option, - duration: Option, - played: Option, - // favorite: bool, - // archive: bool, - podcast_id: i32, -} - -impl From for EpisodeWidgetQuery { - fn from(e: Episode) -> EpisodeWidgetQuery { - EpisodeWidgetQuery { - rowid: e.rowid, - title: e.title, - uri: e.uri, - local_uri: e.local_uri, - epoch: e.epoch, - length: e.length, - duration: e.duration, - played: e.played, - podcast_id: e.podcast_id, - } - } -} - -impl EpisodeWidgetQuery { - /// Get the value of the sqlite's `ROW_ID` - pub fn rowid(&self) -> i32 { - self.rowid - } - - /// Get the value of the `title` field. - pub fn title(&self) -> &str { - &self.title - } - - /// Get the value of the `uri`. - /// - /// Represents the url(usually) that the media file will be located at. - pub fn uri(&self) -> Option<&str> { - self.uri.as_ref().map(|s| s.as_str()) - } - - /// Get the value of the `local_uri`. - /// - /// Represents the local uri,usually filesystem path, - /// that the media file will be located at. - pub fn local_uri(&self) -> Option<&str> { - self.local_uri.as_ref().map(|s| s.as_str()) - } - - /// Set the `local_uri`. - pub fn set_local_uri(&mut self, value: Option<&str>) { - self.local_uri = value.map(|x| x.to_string()); - } - - /// Get the `epoch` value. - /// - /// Retrieved from the rss Item publish date. - /// Value is set to Utc whenever possible. - pub fn epoch(&self) -> i32 { - self.epoch - } - - /// Get the `length`. - /// - /// The number represents the size of the file in bytes. - pub fn length(&self) -> Option { - self.length - } - - /// Set the `length`. - pub fn set_length(&mut self, value: Option) { - self.length = value; - } - - /// Get the `duration` value. - /// - /// The number represents the duration of the item/episode in seconds. - pub fn duration(&self) -> Option { - self.duration - } - - /// Set the `duration`. - pub fn set_duration(&mut self, value: Option) { - self.duration = value; - } - - /// Epoch representation of the last time the episode was played. - /// - /// None/Null for unplayed. - pub fn played(&self) -> Option { - self.played - } - - /// Set the `played` value. - pub fn set_played(&mut self, value: Option) { - self.played = value; - } - - // /// Represents the archiving policy for the episode. - // pub fn archive(&self) -> bool { - // self.archive - // } - - // /// Set the `archive` policy. - // /// - // /// If true, the download cleanr will ignore the episode - // /// and the corresponding media value will never be automaticly deleted. - // pub fn set_archive(&mut self, b: bool) { - // self.archive = b - // } - - // /// Get the `favorite` status of the `Episode`. - // pub fn favorite(&self) -> bool { - // self.favorite - // } - - // /// Set `favorite` status. - // pub fn set_favorite(&mut self, b: bool) { - // self.favorite = b - // } - - /// `Podcast` table foreign key. - pub fn podcast_id(&self) -> i32 { - self.podcast_id - } - - /// Sets the `played` value with the current `epoch` timestap and save it. - pub fn set_played_now(&mut self) -> Result<()> { - let epoch = Utc::now().timestamp() as i32; - self.set_played(Some(epoch)); - self.save()?; - Ok(()) - } - - /// Helper method to easily save/"sync" current state of self to the Database. - pub fn save(&self) -> Result { - use schema::episode::dsl::*; - - let db = connection(); - let tempdb = db.get()?; - - Ok(diesel::update(episode.filter(rowid.eq(self.rowid))) - .set(self) - .execute(&*tempdb)?) - } -} - -#[derive(Queryable, AsChangeset, PartialEq)] -#[table_name = "episode"] -#[changeset_options(treat_none_as_null = "true")] -#[primary_key(title, podcast_id)] -#[derive(Debug, Clone)] -/// Diesel Model to be used internal with the `utils::checkup` function. -pub struct EpisodeCleanerQuery { - rowid: i32, - local_uri: Option, - played: Option, -} - -impl From for EpisodeCleanerQuery { - fn from(e: Episode) -> EpisodeCleanerQuery { - EpisodeCleanerQuery { - rowid: e.rowid(), - local_uri: e.local_uri, - played: e.played, - } - } -} - -impl EpisodeCleanerQuery { - /// Get the value of the sqlite's `ROW_ID` - pub fn rowid(&self) -> i32 { - self.rowid - } - - /// Get the value of the `local_uri`. - /// - /// Represents the local uri,usually filesystem path, - /// that the media file will be located at. - pub fn local_uri(&self) -> Option<&str> { - self.local_uri.as_ref().map(|s| s.as_str()) - } - - /// Set the `local_uri`. - pub fn set_local_uri(&mut self, value: Option<&str>) { - self.local_uri = value.map(|x| x.to_string()); - } - - /// Epoch representation of the last time the episode was played. - /// - /// None/Null for unplayed. - pub fn played(&self) -> Option { - self.played - } - - /// Set the `played` value. - pub fn set_played(&mut self, value: Option) { - self.played = value; - } - - /// Helper method to easily save/"sync" current state of self to the Database. - pub fn save(&self) -> Result { - use schema::episode::dsl::*; - - let db = connection(); - let tempdb = db.get()?; - - Ok(diesel::update(episode.filter(rowid.eq(self.rowid()))) - .set(self) - .execute(&*tempdb)?) - } -} - -#[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] -#[belongs_to(Source, foreign_key = "source_id")] -#[changeset_options(treat_none_as_null = "true")] -#[table_name = "podcast"] -#[derive(Debug, Clone)] -/// Diesel Model of the podcast table. -pub struct Podcast { - id: i32, - title: String, - link: String, - description: String, - image_uri: Option, - favorite: bool, - archive: bool, - always_dl: bool, - source_id: i32, -} - -impl Podcast { - /// Get the Feed `id`. - pub fn id(&self) -> i32 { - self.id - } - - /// Get the Feed `title`. - pub fn title(&self) -> &str { - &self.title - } - - /// Get the Feed `link`. - /// - /// Usually the website/homepage of the content creator. - pub fn link(&self) -> &str { - &self.link - } - - /// Set the Podcast/Feed `link`. - pub fn set_link(&mut self, value: &str) { - self.link = value.to_string(); - } - - /// Get the `description`. - pub fn description(&self) -> &str { - &self.description - } - - /// Set the `description`. - pub fn set_description(&mut self, value: &str) { - self.description = value.to_string(); - } - - /// Get the `image_uri`. - /// - /// Represents the uri(url usually) that the Feed cover image is located at. - pub fn image_uri(&self) -> Option<&str> { - self.image_uri.as_ref().map(|s| s.as_str()) - } - - /// Set the `image_uri`. - pub fn set_image_uri(&mut self, value: Option<&str>) { - self.image_uri = value.map(|x| x.to_string()); - } - - /// Represents the archiving policy for the episode. - pub fn archive(&self) -> bool { - self.archive - } - - /// Set the `archive` policy. - pub fn set_archive(&mut self, b: bool) { - self.archive = b - } - - /// Get the `favorite` status of the `Podcast` Feed. - pub fn favorite(&self) -> bool { - self.favorite - } - - /// Set `favorite` status. - pub fn set_favorite(&mut self, b: bool) { - self.favorite = b - } - - /// Represents the download policy for the `Podcast` Feed. - /// - /// Reserved for the use with a Download manager, yet to be implemented. - /// - /// If true Podcast Episode should be downloaded automaticly/skipping - /// the selection queue. - pub fn always_download(&self) -> bool { - self.always_dl - } - - /// Set the download policy. - pub fn set_always_download(&mut self, b: bool) { - self.always_dl = b - } - - /// `Source` table foreign key. - pub fn source_id(&self) -> i32 { - self.source_id - } - - /// Helper method to easily save/"sync" current state of self to the Database. - pub fn save(&self) -> Result { - let db = connection(); - let tempdb = db.get()?; - - Ok(self.save_changes::(&*tempdb)?) - } -} - -#[derive(Queryable, Debug, Clone)] -/// Diesel Model of the podcast cover query. -/// Used for fetching information about a Podcast's cover. -pub struct PodcastCoverQuery { - id: i32, - title: String, - image_uri: Option, -} - -impl From for PodcastCoverQuery { - fn from(p: Podcast) -> PodcastCoverQuery { - PodcastCoverQuery { - id: p.id(), - title: p.title, - image_uri: p.image_uri, - } - } -} - -impl PodcastCoverQuery { - /// Get the Feed `id`. - pub fn id(&self) -> i32 { - self.id - } - - /// Get the Feed `title`. - pub fn title(&self) -> &str { - &self.title - } - - /// Get the `image_uri`. - /// - /// Represents the uri(url usually) that the Feed cover image is located at. - pub fn image_uri(&self) -> Option<&str> { - self.image_uri.as_ref().map(|s| s.as_str()) - } -} - -#[derive(Queryable, Identifiable, AsChangeset, PartialEq)] -#[table_name = "source"] -#[changeset_options(treat_none_as_null = "true")] -#[derive(Debug, Clone)] -/// Diesel Model of the source table. -pub struct Source { - id: i32, - uri: String, - /// FIXME - pub last_modified: Option, - /// FIXME - pub http_etag: Option, -} - -impl Source { - /// Get the source `id` column. - pub fn id(&self) -> i32 { - self.id - } - - /// Represents the location(usually url) of the Feed xml file. - pub fn uri(&self) -> &str { - &self.uri - } - - /// Represents the Http Last-Modified Header field. - /// - /// See [RFC 7231](https://tools.ietf.org/html/rfc7231#section-7.2) for more. - pub fn last_modified(&self) -> Option<&str> { - self.last_modified.as_ref().map(|s| s.as_str()) - } - - /// Set `last_modified` value. - pub fn set_last_modified(&mut self, value: Option<&str>) { - self.last_modified = value.map(|x| x.to_string()); - } - - /// Represents the Http Etag Header field. - /// - /// See [RFC 7231](https://tools.ietf.org/html/rfc7231#section-7.2) for more. - pub fn http_etag(&self) -> Option<&str> { - self.http_etag.as_ref().map(|s| s.as_str()) - } - - /// Set `http_etag` value. - pub fn set_http_etag(&mut self, value: Option<&str>) { - self.http_etag = value.map(|x| x.to_string()); - } - - /// Helper method to easily save/"sync" current state of self to the Database. - pub fn save(&self) -> Result { - let db = connection(); - let tempdb = db.get()?; - - Ok(self.save_changes::(&*tempdb)?) - } - - /// Extract Etag and LastModifier from res, and update self and the - /// corresponding db row. - fn update_etag(&mut self, res: &reqwest::Response) -> Result<()> { - let headers = res.headers(); - - let etag = headers.get::(); - let lmod = headers.get::(); - - if self.http_etag() != etag.map(|x| x.tag()) || self.last_modified != lmod.map(|x| { - format!("{}", x) - }) { - self.http_etag = etag.map(|x| x.tag().to_string().to_owned()); - self.last_modified = lmod.map(|x| format!("{}", x)); - self.save()?; - } - - Ok(()) - } - - /// Extract Etag and LastModifier from res, and update self and the - /// corresponding db row. - fn update_etag2(mut self, res: &Response) -> Result<()> { - let headers = res.headers(); - - let etag = headers.get::(); - let lmod = headers.get::(); - - if self.http_etag() != etag.map(|x| x.tag()) || self.last_modified != lmod.map(|x| { - format!("{}", x) - }) { - self.http_etag = etag.map(|x| x.tag().to_string().to_owned()); - self.last_modified = lmod.map(|x| format!("{}", x)); - self.save()?; - } - - Ok(()) - } - - /// `Feed` constructor. - /// - /// Fetches the latest xml Feed. - /// - /// Updates the validator Http Headers. - /// - /// Consumes `self` and Returns the corresponding `Feed` Object. - // TODO: Refactor into TryInto once it lands on stable. - pub fn into_feed(&mut self, ignore_etags: bool) -> Result { - use reqwest::header::{EntityTag, Headers, HttpDate, IfModifiedSince, IfNoneMatch}; - - let mut headers = Headers::new(); - - if !ignore_etags { - if let Some(foo) = self.http_etag() { - headers.set(IfNoneMatch::Items(vec![ - EntityTag::new(true, foo.to_owned()), - ])); - } - - if let Some(foo) = self.last_modified() { - if let Ok(x) = foo.parse::() { - headers.set(IfModifiedSince(x)); - } - } - } - - let client = reqwest::Client::builder().referer(false).build()?; - let mut res = client.get(self.uri()).headers(headers).send()?; - - info!("GET to {} , returned: {}", self.uri(), res.status()); - - self.update_etag(&res)?; - match_status(res.status())?; - - let mut buf = String::new(); - res.read_to_string(&mut buf)?; - let chan = Channel::from_str(&buf)?; - - Ok(Feed::from_channel_source(chan, self.id)) - } - - // FIXME: - /// Docs - pub fn into_fututre_feed( - self, - client: &Client>, - ignore_etags: bool, - ) -> Box> { - let id = self.id(); - let feed = request_constructor(&self, client, ignore_etags) - .map_err(From::from) - .and_then(move |res| { - self.update_etag2(&res)?; - Ok(res) - }) - .and_then(|res| -> Result { - match_status(res.status())?; - Ok(res) - }) - .and_then(|res| response_to_channel(res)) - .map(move |chan| Feed::from_channel_source(chan, id)); - - Box::new(feed) - } - - /// Construct a new `Source` with the given `uri` and index it. - /// - /// This only indexes the `Source` struct, not the Podcast Feed. - pub fn from_url(uri: &str) -> Result { - NewSource::new(uri).into_source() - } -} - -// TODO: make ignore_etags an Enum for better ergonomics. -// #bools_are_just_2variant_enmus -fn request_constructor( - s: &Source, - client: &Client>, - ignore_etags: bool, -) -> Box> { - // FIXME: remove unwrap somehow - let uri = Uri::from_str(&s.uri()).unwrap(); - let mut req = Request::new(Method::Get, uri); - - if !ignore_etags { - if let Some(foo) = s.http_etag() { - req.headers_mut().set(IfNoneMatch::Items(vec![ - EntityTag::new(true, foo.to_owned()), - ])); - } - - if let Some(foo) = s.last_modified() { - if let Ok(x) = foo.parse::() { - req.headers_mut().set(IfModifiedSince(x)); - } - } - } - - let work = client.request(req).map_err(From::from); - Box::new(work) -} - -fn response_to_channel(res: Response) -> Box> { - let chan = res.body() - .concat2() - .map(|x| x.into_iter()) - .map_err(From::from) - .and_then(|iter| { - let utf_8_bytes = iter.collect::>(); - let buf = String::from_utf8_lossy(&utf_8_bytes).into_owned(); - let chan = Channel::from_str(&buf).map_err(From::from); - chan - }); - Box::new(chan) -} - -// TODO match on more stuff -// 301: Moved Permanently -// 304: Up to date Feed, checked with the Etag -// 307: Temporary redirect of the url -// 308: Permanent redirect of the url -// 401: Unathorized -// 403: Forbidden -// 408: Timeout -// 410: Feed deleted -fn match_status(code: StatusCode) -> Result<()> { - match code { - StatusCode::NotModified => bail!("304: skipping.."), - StatusCode::TemporaryRedirect => debug!("307: Temporary Redirect."), - // TODO: Change the source uri to the new one - StatusCode::MovedPermanently | StatusCode::PermanentRedirect => { - warn!("Feed was moved permanently.") - } - StatusCode::Unauthorized => bail!("401: Unauthorized."), - StatusCode::Forbidden => bail!("403: Forbidden."), - StatusCode::NotFound => bail!("404: Not found."), - StatusCode::RequestTimeout => bail!("408: Request Timeout."), - StatusCode::Gone => bail!("410: Feed was deleted."), - _ => (), - }; - Ok(()) -} - -#[cfg(test)] -mod tests { - use super::*; - use tokio_core::reactor::Core; - - use database::truncate_db; - - #[test] - fn test_into_future_feed() { - truncate_db().unwrap(); - - let mut core = Core::new().unwrap(); - let client = Client::configure() - .connector(HttpsConnector::new(4, &core.handle()).unwrap()) - .build(&core.handle()); - - let url = "http://www.newrustacean.com/feed.xml"; - let source = Source::from_url(url).unwrap(); - - let feed = source.into_fututre_feed(&client, true); - - assert!(core.run(feed).is_ok()); - } -} diff --git a/hammond-data/src/models/source.rs b/hammond-data/src/models/source.rs new file mode 100644 index 0000000..a65d6dc --- /dev/null +++ b/hammond-data/src/models/source.rs @@ -0,0 +1,286 @@ +use reqwest; +use diesel::SaveChangesDsl; +use rss::Channel; + +use hyper; +use hyper::client::HttpConnector; +use hyper::{Client, Method, Request, Response, StatusCode, Uri}; +use hyper::header::{ETag, EntityTag, HttpDate, IfModifiedSince, IfNoneMatch, LastModified}; +use hyper_tls::HttpsConnector; + +use futures::prelude::*; +// use futures::future::{ok, result}; + +use schema::source; +use feed::Feed; +use errors::*; + +use models::NewSource; +use database::connection; + +use std::io::Read; +use std::str::FromStr; + +#[derive(Queryable, Identifiable, AsChangeset, PartialEq)] +#[table_name = "source"] +#[changeset_options(treat_none_as_null = "true")] +#[derive(Debug, Clone)] +/// Diesel Model of the source table. +pub struct Source { + id: i32, + uri: String, + /// FIXME + pub last_modified: Option, + /// FIXME + pub http_etag: Option, +} + +impl Source { + /// Get the source `id` column. + pub fn id(&self) -> i32 { + self.id + } + + /// Represents the location(usually url) of the Feed xml file. + pub fn uri(&self) -> &str { + &self.uri + } + + /// Represents the Http Last-Modified Header field. + /// + /// See [RFC 7231](https://tools.ietf.org/html/rfc7231#section-7.2) for more. + pub fn last_modified(&self) -> Option<&str> { + self.last_modified.as_ref().map(|s| s.as_str()) + } + + /// Set `last_modified` value. + pub fn set_last_modified(&mut self, value: Option<&str>) { + self.last_modified = value.map(|x| x.to_string()); + } + + /// Represents the Http Etag Header field. + /// + /// See [RFC 7231](https://tools.ietf.org/html/rfc7231#section-7.2) for more. + pub fn http_etag(&self) -> Option<&str> { + self.http_etag.as_ref().map(|s| s.as_str()) + } + + /// Set `http_etag` value. + pub fn set_http_etag(&mut self, value: Option<&str>) { + self.http_etag = value.map(|x| x.to_string()); + } + + /// Helper method to easily save/"sync" current state of self to the Database. + pub fn save(&self) -> Result { + let db = connection(); + let tempdb = db.get()?; + + Ok(self.save_changes::(&*tempdb)?) + } + + /// Extract Etag and LastModifier from res, and update self and the + /// corresponding db row. + fn update_etag(&mut self, res: &reqwest::Response) -> Result<()> { + let headers = res.headers(); + + let etag = headers.get::(); + let lmod = headers.get::(); + + if self.http_etag() != etag.map(|x| x.tag()) || self.last_modified != lmod.map(|x| { + format!("{}", x) + }) { + self.http_etag = etag.map(|x| x.tag().to_string().to_owned()); + self.last_modified = lmod.map(|x| format!("{}", x)); + self.save()?; + } + + Ok(()) + } + + /// Extract Etag and LastModifier from res, and update self and the + /// corresponding db row. + fn update_etag2(mut self, res: &Response) -> Result<()> { + let headers = res.headers(); + + let etag = headers.get::(); + let lmod = headers.get::(); + + if self.http_etag() != etag.map(|x| x.tag()) || self.last_modified != lmod.map(|x| { + format!("{}", x) + }) { + self.http_etag = etag.map(|x| x.tag().to_string().to_owned()); + self.last_modified = lmod.map(|x| format!("{}", x)); + self.save()?; + } + + Ok(()) + } + + /// `Feed` constructor. + /// + /// Fetches the latest xml Feed. + /// + /// Updates the validator Http Headers. + /// + /// Consumes `self` and Returns the corresponding `Feed` Object. + // TODO: Refactor into TryInto once it lands on stable. + pub fn into_feed(&mut self, ignore_etags: bool) -> Result { + use reqwest::header::{EntityTag, Headers, HttpDate, IfModifiedSince, IfNoneMatch}; + + let mut headers = Headers::new(); + + if !ignore_etags { + if let Some(foo) = self.http_etag() { + headers.set(IfNoneMatch::Items(vec![ + EntityTag::new(true, foo.to_owned()), + ])); + } + + if let Some(foo) = self.last_modified() { + if let Ok(x) = foo.parse::() { + headers.set(IfModifiedSince(x)); + } + } + } + + let client = reqwest::Client::builder().referer(false).build()?; + let mut res = client.get(self.uri()).headers(headers).send()?; + + info!("GET to {} , returned: {}", self.uri(), res.status()); + + self.update_etag(&res)?; + match_status(res.status())?; + + let mut buf = String::new(); + res.read_to_string(&mut buf)?; + let chan = Channel::from_str(&buf)?; + + Ok(Feed::from_channel_source(chan, self.id)) + } + + // FIXME: + /// Docs + pub fn into_fututre_feed( + self, + client: &Client>, + ignore_etags: bool, + ) -> Box> { + let id = self.id(); + let feed = request_constructor(&self, client, ignore_etags) + .map_err(From::from) + .and_then(move |res| { + self.update_etag2(&res)?; + Ok(res) + }) + .and_then(|res| -> Result { + match_status(res.status())?; + Ok(res) + }) + .and_then(|res| response_to_channel(res)) + .map(move |chan| Feed::from_channel_source(chan, id)); + + Box::new(feed) + } + + /// Construct a new `Source` with the given `uri` and index it. + /// + /// This only indexes the `Source` struct, not the Podcast Feed. + pub fn from_url(uri: &str) -> Result { + NewSource::new(uri).into_source() + } +} + +// TODO: make ignore_etags an Enum for better ergonomics. +// #bools_are_just_2variant_enmus +fn request_constructor( + s: &Source, + client: &Client>, + ignore_etags: bool, +) -> Box> { + // FIXME: remove unwrap somehow + let uri = Uri::from_str(&s.uri()).unwrap(); + let mut req = Request::new(Method::Get, uri); + + if !ignore_etags { + if let Some(foo) = s.http_etag() { + req.headers_mut().set(IfNoneMatch::Items(vec![ + EntityTag::new(true, foo.to_owned()), + ])); + } + + if let Some(foo) = s.last_modified() { + if let Ok(x) = foo.parse::() { + req.headers_mut().set(IfModifiedSince(x)); + } + } + } + + let work = client.request(req).map_err(From::from); + Box::new(work) +} + +fn response_to_channel(res: Response) -> Box> { + let chan = res.body() + .concat2() + .map(|x| x.into_iter()) + .map_err(From::from) + .and_then(|iter| { + let utf_8_bytes = iter.collect::>(); + let buf = String::from_utf8_lossy(&utf_8_bytes).into_owned(); + let chan = Channel::from_str(&buf).map_err(From::from); + chan + }); + Box::new(chan) +} + +// TODO match on more stuff +// 301: Moved Permanently +// 304: Up to date Feed, checked with the Etag +// 307: Temporary redirect of the url +// 308: Permanent redirect of the url +// 401: Unathorized +// 403: Forbidden +// 408: Timeout +// 410: Feed deleted +fn match_status(code: StatusCode) -> Result<()> { + match code { + StatusCode::NotModified => bail!("304: skipping.."), + StatusCode::TemporaryRedirect => debug!("307: Temporary Redirect."), + // TODO: Change the source uri to the new one + StatusCode::MovedPermanently | StatusCode::PermanentRedirect => { + warn!("Feed was moved permanently.") + } + StatusCode::Unauthorized => bail!("401: Unauthorized."), + StatusCode::Forbidden => bail!("403: Forbidden."), + StatusCode::NotFound => bail!("404: Not found."), + StatusCode::RequestTimeout => bail!("408: Request Timeout."), + StatusCode::Gone => bail!("410: Feed was deleted."), + _ => (), + }; + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use tokio_core::reactor::Core; + + use database::truncate_db; + + #[test] + fn test_into_future_feed() { + truncate_db().unwrap(); + + let mut core = Core::new().unwrap(); + let client = Client::configure() + .connector(HttpsConnector::new(4, &core.handle()).unwrap()) + .build(&core.handle()); + + let url = "http://www.newrustacean.com/feed.xml"; + let source = Source::from_url(url).unwrap(); + + let feed = source.into_fututre_feed(&client, true); + + assert!(core.run(feed).is_ok()); + } +} diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index 77e126f..ff1866e 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -8,7 +8,7 @@ use itertools::Itertools; use errors::*; use dbqueries; -use models::queryables::{EpisodeCleanerQuery, Podcast}; +use models::{EpisodeCleanerQuery, Podcast}; use xdg_dirs::DL_DIR; use std::path::Path; From 574cfae5c6b8c1ddca308137e63569bdf5156103 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 17 Jan 2018 08:57:02 +0200 Subject: [PATCH 205/278] rustfmt: enable reorder imports. --- hammond-data/benches/bench.rs | 2 +- hammond-data/src/database.rs | 4 ++-- hammond-data/src/dbqueries.rs | 12 ++++++------ hammond-data/src/errors.rs | 6 +++--- hammond-data/src/feed.rs | 11 +++++------ hammond-data/src/models/episode.rs | 7 +++---- hammond-data/src/models/mod.rs | 2 +- hammond-data/src/models/new_episode.rs | 7 +++---- hammond-data/src/models/new_podcast.rs | 10 +++++----- hammond-data/src/models/new_source.rs | 11 +++++------ hammond-data/src/models/podcast.rs | 6 ++---- hammond-data/src/models/source.rs | 13 ++++++------- hammond-data/src/parser.rs | 10 ++++++---- hammond-data/src/pipeline.rs | 9 +++++---- hammond-data/src/utils.rs | 10 +++++----- hammond-downloader/src/downloader.rs | 10 +++++----- hammond-downloader/src/errors.rs | 2 +- hammond-gtk/src/app.rs | 12 ++++++------ hammond-gtk/src/content.rs | 4 ++-- hammond-gtk/src/headerbar.rs | 2 +- hammond-gtk/src/manager.rs | 9 ++++----- hammond-gtk/src/utils.rs | 16 ++++++++-------- hammond-gtk/src/views/episodes.rs | 10 +++++----- hammond-gtk/src/views/shows.rs | 4 ++-- hammond-gtk/src/widgets/episode.rs | 12 ++++++------ hammond-gtk/src/widgets/show.rs | 12 ++++++------ rustfmt.toml | 6 ++++-- 27 files changed, 108 insertions(+), 111 deletions(-) diff --git a/hammond-data/benches/bench.rs b/hammond-data/benches/bench.rs index 9d3dcbc..8e665a0 100644 --- a/hammond-data/benches/bench.rs +++ b/hammond-data/benches/bench.rs @@ -12,8 +12,8 @@ extern crate test; use test::Bencher; use hammond_data::Source; -use hammond_data::feed::*; use hammond_data::database::truncate_db; +use hammond_data::feed::*; use std::io::BufReader; diff --git a/hammond-data/src/database.rs b/hammond-data/src/database.rs index d3bb36d..0e2320c 100644 --- a/hammond-data/src/database.rs +++ b/hammond-data/src/database.rs @@ -1,11 +1,11 @@ //! Database Setup. This is only public to help with some unit tests. -use r2d2_diesel::ConnectionManager; use diesel::prelude::*; use r2d2; +use r2d2_diesel::ConnectionManager; -use std::path::PathBuf; use std::io; +use std::path::PathBuf; use errors::*; diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index edc9603..0f36c10 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -1,12 +1,12 @@ //! Random CRUD helper functions. -use diesel::prelude::*; -use diesel; -use models::{Episode, EpisodeCleanerQuery, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; use chrono::prelude::*; -use errors::*; +use diesel; +use diesel::prelude::*; use database::connection; +use errors::*; +use models::{Episode, EpisodeCleanerQuery, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; pub fn get_sources() -> Result> { use schema::source::dsl::*; @@ -279,9 +279,9 @@ pub fn delete_podcast_episodes(con: &SqliteConnection, parent_id: i32) -> QueryR } pub fn podcast_exists(source_id_: i32) -> Result { - use schema::podcast::dsl::*; - use diesel::select; use diesel::dsl::exists; + use diesel::select; + use schema::podcast::dsl::*; let db = connection(); let con = db.get()?; diff --git a/hammond-data/src/errors.rs b/hammond-data/src/errors.rs index 3beb3f2..563a093 100644 --- a/hammond-data/src/errors.rs +++ b/hammond-data/src/errors.rs @@ -1,10 +1,10 @@ use diesel; use diesel_migrations::RunMigrationsError; -use rss; -use reqwest; -use r2d2; use hyper; use native_tls; +use r2d2; +use reqwest; +use rss; use std::io; diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 38d33a3..78c03eb 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -1,17 +1,16 @@ //! Index Feeds. -use rayon::prelude::*; use diesel::prelude::*; -use futures::prelude::*; use futures::future::*; +use futures::prelude::*; use rayon::iter::IntoParallelIterator; - +use rayon::prelude::*; use rss; -use dbqueries; -use models::{NewEpisode, NewPodcast, Podcast, Source}; use database::connection; +use dbqueries; use errors::*; +use models::{NewEpisode, NewPodcast, Podcast, Source}; // #[cfg(test)] // use models::queryables::Episode; @@ -149,9 +148,9 @@ pub fn index_all() -> Result<()> { #[cfg(test)] mod tests { + use database::truncate_db; use std::fs; use std::io::BufReader; - use database::truncate_db; use super::*; diff --git a/hammond-data/src/models/episode.rs b/hammond-data/src/models/episode.rs index 52d863a..2ae3796 100644 --- a/hammond-data/src/models/episode.rs +++ b/hammond-data/src/models/episode.rs @@ -1,13 +1,12 @@ use chrono::prelude::*; -use diesel::prelude::*; use diesel; - use diesel::SaveChangesDsl; +use diesel::prelude::*; -use schema::episode; -use errors::*; use database::connection; +use errors::*; use models::Podcast; +use schema::episode; #[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] #[table_name = "episode"] diff --git a/hammond-data/src/models/mod.rs b/hammond-data/src/models/mod.rs index 6e0972c..e121734 100644 --- a/hammond-data/src/models/mod.rs +++ b/hammond-data/src/models/mod.rs @@ -13,9 +13,9 @@ pub(crate) use self::new_podcast::NewPodcast; pub(crate) use self::new_source::NewSource; pub use self::episode::{Episode, EpisodeWidgetQuery}; +pub(crate) use self::episode::EpisodeCleanerQuery; pub use self::podcast::{Podcast, PodcastCoverQuery}; pub use self::source::Source; -pub(crate) use self::episode::EpisodeCleanerQuery; #[allow(dead_code)] enum IndexState { diff --git a/hammond-data/src/models/new_episode.rs b/hammond-data/src/models/new_episode.rs index bc12dd9..e0650a7 100644 --- a/hammond-data/src/models/new_episode.rs +++ b/hammond-data/src/models/new_episode.rs @@ -1,18 +1,17 @@ -use diesel::prelude::*; use diesel; +use diesel::prelude::*; use schema::episode; -use rss; use ammonia; use rfc822_sanitizer::parse_from_rfc2822_with_fallback as parse_rfc822; +use rss; use dbqueries; use errors::*; use models::{Insert, Update}; use models::Episode; - -use utils::{replace_extra_spaces, url_cleaner}; use parser; +use utils::{replace_extra_spaces, url_cleaner}; #[derive(Insertable, AsChangeset)] #[table_name = "episode"] diff --git a/hammond-data/src/models/new_podcast.rs b/hammond-data/src/models/new_podcast.rs index b3765c9..c47e855 100644 --- a/hammond-data/src/models/new_podcast.rs +++ b/hammond-data/src/models/new_podcast.rs @@ -1,15 +1,15 @@ -use diesel::prelude::*; use diesel; +use diesel::prelude::*; -use rss; use ammonia; +use rss; -use schema::podcast; -use models::Podcast; use models::{Insert, Update}; +use models::Podcast; +use schema::podcast; -use dbqueries; use database::connection; +use dbqueries; use utils::{replace_extra_spaces, url_cleaner}; use errors::*; diff --git a/hammond-data/src/models/new_source.rs b/hammond-data/src/models/new_source.rs index 33f320d..dc572cf 100644 --- a/hammond-data/src/models/new_source.rs +++ b/hammond-data/src/models/new_source.rs @@ -1,14 +1,13 @@ #![allow(unused_mut)] -use diesel::prelude::*; use diesel; +use diesel::prelude::*; -use schema::source; -use models::Source; -use models::{Insert, Update}; - -use dbqueries; use database::connection; +use dbqueries; +use models::{Insert, Update}; +use models::Source; +use schema::source; use errors::*; diff --git a/hammond-data/src/models/podcast.rs b/hammond-data/src/models/podcast.rs index 63554c7..b99b83c 100644 --- a/hammond-data/src/models/podcast.rs +++ b/hammond-data/src/models/podcast.rs @@ -1,11 +1,9 @@ use diesel::SaveChangesDsl; -// use futures::future::{ok, result}; - -use schema::podcast; -use errors::*; use database::connection; +use errors::*; use models::Source; +use schema::podcast; #[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] #[belongs_to(Source, foreign_key = "source_id")] diff --git a/hammond-data/src/models/source.rs b/hammond-data/src/models/source.rs index a65d6dc..b4245be 100644 --- a/hammond-data/src/models/source.rs +++ b/hammond-data/src/models/source.rs @@ -1,22 +1,21 @@ -use reqwest; use diesel::SaveChangesDsl; +use reqwest; use rss::Channel; use hyper; -use hyper::client::HttpConnector; use hyper::{Client, Method, Request, Response, StatusCode, Uri}; +use hyper::client::HttpConnector; use hyper::header::{ETag, EntityTag, HttpDate, IfModifiedSince, IfNoneMatch, LastModified}; use hyper_tls::HttpsConnector; use futures::prelude::*; // use futures::future::{ok, result}; -use schema::source; -use feed::Feed; -use errors::*; - -use models::NewSource; use database::connection; +use errors::*; +use feed::Feed; +use models::NewSource; +use schema::source; use std::io::Read; use std::str::FromStr; diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index a17c932..f8fb6cc 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -32,13 +32,15 @@ pub(crate) fn parse_itunes_duration(item: &Item) -> Option { #[cfg(test)] mod tests { - use std::fs::File; - use std::io::BufReader; - use rss::{Channel, ItemBuilder}; - use rss::extension::itunes::ITunesItemExtensionBuilder; use models::new_episode::{NewEpisode, NewEpisodeBuilder}; use models::new_podcast::{NewPodcast, NewPodcastBuilder}; + use rss::{Channel, ItemBuilder}; + use rss::extension::itunes::ITunesItemExtensionBuilder; + + use std::fs::File; + use std::io::BufReader; + use super::*; #[test] diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index 1e0c0cb..6454d33 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -1,14 +1,15 @@ // FIXME: //! Docs. -use tokio_core::reactor::Core; +use futures::future::*; +use futures::prelude::*; + use hyper::Client; use hyper_tls::HttpsConnector; -use futures::prelude::*; -use futures::future::*; +use tokio_core::reactor::Core; -use errors::*; use Source; +use errors::*; // use Feed; use std; diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index ff1866e..bf875e1 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -1,18 +1,18 @@ //! Helper utilities for accomplishing various tasks. -use rayon::prelude::*; use chrono::prelude::*; +use rayon::prelude::*; -use url::{Position, Url}; use itertools::Itertools; +use url::{Position, Url}; -use errors::*; use dbqueries; +use errors::*; use models::{EpisodeCleanerQuery, Podcast}; use xdg_dirs::DL_DIR; -use std::path::Path; use std::fs; +use std::path::Path; /// Scan downloaded `episode` entries that might have broken `local_uri`s and set them to `None`. fn download_checker() -> Result<()> { @@ -151,10 +151,10 @@ pub fn delete_show(pd: &Podcast) -> Result<()> { mod tests { extern crate tempdir; + use self::tempdir::TempDir; use super::*; use database::{connection, truncate_db}; use models::new_episode::NewEpisodeBuilder; - use self::tempdir::TempDir; use std::fs::File; use std::io::Write; diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 437624c..7acba68 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -1,13 +1,13 @@ -use reqwest; -use hyper::header::*; -use tempdir::TempDir; -use mime_guess; use glob::glob; +use hyper::header::*; +use mime_guess; +use reqwest; +use tempdir::TempDir; +use std::fs; use std::fs::{rename, DirBuilder, File}; use std::io::{BufWriter, Read, Write}; use std::path::Path; -use std::fs; use std::sync::{Arc, Mutex}; use errors::*; diff --git a/hammond-downloader/src/errors.rs b/hammond-downloader/src/errors.rs index 4b019c5..a87f2ca 100644 --- a/hammond-downloader/src/errors.rs +++ b/hammond-downloader/src/errors.rs @@ -1,5 +1,5 @@ -use reqwest; use hammond_data; +use reqwest; use std::io; error_chain! { diff --git a/hammond-gtk/src/app.rs b/hammond-gtk/src/app.rs index bc9890d..4f4e341 100644 --- a/hammond-gtk/src/app.rs +++ b/hammond-gtk/src/app.rs @@ -1,19 +1,19 @@ -use gtk; -use glib; use gio; -use gtk::prelude::*; use gio::{ApplicationExt, ApplicationExtManual}; +use glib; +use gtk; +use gtk::prelude::*; -use hammond_data::utils::checkup; use hammond_data::{Podcast, Source}; +use hammond_data::utils::checkup; -use headerbar::Header; use content::Content; +use headerbar::Header; use utils; use std::sync::Arc; -use std::time::Duration; use std::sync::mpsc::{channel, Receiver, Sender}; +use std::time::Duration; #[derive(Clone, Debug)] pub enum Action { diff --git a/hammond-gtk/src/content.rs b/hammond-gtk/src/content.rs index 10d3d79..a83a4b1 100644 --- a/hammond-gtk/src/content.rs +++ b/hammond-gtk/src/content.rs @@ -5,12 +5,12 @@ use gtk::prelude::*; use hammond_data::Podcast; use hammond_data::dbqueries; -use views::shows::ShowsPopulated; use views::empty::EmptyView; use views::episodes::EpisodesView; +use views::shows::ShowsPopulated; -use widgets::show::ShowWidget; use app::Action; +use widgets::show::ShowWidget; use std::sync::Arc; use std::sync::mpsc::Sender; diff --git a/hammond-gtk/src/headerbar.rs b/hammond-gtk/src/headerbar.rs index 82839a7..1c8fbda 100644 --- a/hammond-gtk/src/headerbar.rs +++ b/hammond-gtk/src/headerbar.rs @@ -3,8 +3,8 @@ use gtk::prelude::*; use hammond_data::Source; -use std::sync::mpsc::Sender; use std::sync::Arc; +use std::sync::mpsc::Sender; use app::Action; use content::Content; diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index fe9edd6..68b3132 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -1,7 +1,6 @@ // use hammond_data::Episode; use hammond_data::dbqueries; -use hammond_downloader::downloader::get_episode; -use hammond_downloader::downloader::DownloadProgress; +use hammond_downloader::downloader::{get_episode, DownloadProgress}; use app::Action; @@ -118,13 +117,13 @@ pub fn add(id: i32, directory: &str, sender: Sender) { mod tests { use super::*; - use hammond_data::database; - use hammond_data::utils::get_download_folder; use hammond_data::{Episode, Source}; + use hammond_data::database; use hammond_data::dbqueries; + use hammond_data::utils::get_download_folder; - use std::path::Path; use std::{thread, time}; + use std::path::Path; use std::sync::mpsc::channel; #[test] diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index f73230e..0cccde1 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -1,19 +1,19 @@ -use send_cell::SendCell; use gdk_pixbuf::Pixbuf; +use send_cell::SendCell; // use hammond_data::feed; -use hammond_data::pipeline; -use hammond_data::dbqueries; use hammond_data::{PodcastCoverQuery, Source}; +use hammond_data::dbqueries; +use hammond_data::pipeline; use hammond_downloader::downloader; -use std::thread; -use std::sync::mpsc::Sender; -use std::sync::{Arc, Mutex, RwLock}; use std::collections::HashMap; +use std::sync::{Arc, Mutex, RwLock}; +use std::sync::mpsc::Sender; +use std::thread; -use headerbar::Header; use app::Action; +use headerbar::Header; /// Update the rss feed(s) originating from `source`. /// If `source` is None, Fetches all the `Source` entries in the database and updates them. @@ -80,9 +80,9 @@ pub fn get_pixbuf_from_path(pd: &PodcastCoverQuery, size: u32) -> Option #[cfg(test)] mod tests { + use super::*; use hammond_data::Source; use hammond_data::dbqueries; - use super::*; #[test] // This test inserts an rss feed to your `XDG_DATA/hammond/hammond.db` so we make it explicit diff --git a/hammond-gtk/src/views/episodes.rs b/hammond-gtk/src/views/episodes.rs index dc36148..e32b4ae 100644 --- a/hammond-gtk/src/views/episodes.rs +++ b/hammond-gtk/src/views/episodes.rs @@ -1,16 +1,16 @@ +use chrono::prelude::*; use gtk; use gtk::prelude::*; -use chrono::prelude::*; -use hammond_data::dbqueries; use hammond_data::EpisodeWidgetQuery; +use hammond_data::dbqueries; -use widgets::episode::EpisodeWidget; -use utils::get_pixbuf_from_path; use app::Action; +use utils::get_pixbuf_from_path; +use widgets::episode::EpisodeWidget; -use std::sync::mpsc::Sender; use std::sync::Arc; +use std::sync::mpsc::Sender; #[derive(Debug, Clone)] enum ListSplit { diff --git a/hammond-gtk/src/views/shows.rs b/hammond-gtk/src/views/shows.rs index 72a5b1e..a0a0851 100644 --- a/hammond-gtk/src/views/shows.rs +++ b/hammond-gtk/src/views/shows.rs @@ -1,11 +1,11 @@ use gtk; use gtk::prelude::*; -use hammond_data::dbqueries; use hammond_data::Podcast; +use hammond_data::dbqueries; -use utils::get_pixbuf_from_path; use app::Action; +use utils::get_pixbuf_from_path; use std::sync::mpsc::Sender; diff --git a/hammond-gtk/src/widgets/episode.rs b/hammond-gtk/src/widgets/episode.rs index 2ecc4d6..d4da92e 100644 --- a/hammond-gtk/src/widgets/episode.rs +++ b/hammond-gtk/src/widgets/episode.rs @@ -1,23 +1,23 @@ use glib; use gtk; -use gtk::prelude::*; use chrono::prelude::*; +use gtk::prelude::*; -use open; use humansize::{file_size_opts as size_opts, FileSize}; +use open; -use hammond_data::dbqueries; use hammond_data::{EpisodeWidgetQuery, Podcast}; -use hammond_data::utils::get_download_folder; +use hammond_data::dbqueries; use hammond_data::errors::*; +use hammond_data::utils::get_download_folder; use app::Action; use manager; -use std::sync::mpsc::Sender; -use std::sync::{Arc, Mutex}; use std::path::Path; +use std::sync::{Arc, Mutex}; +use std::sync::mpsc::Sender; lazy_static! { static ref SIZE_OPTS: Arc = { diff --git a/hammond-gtk/src/widgets/show.rs b/hammond-gtk/src/widgets/show.rs index c67db1d..0573903 100644 --- a/hammond-gtk/src/widgets/show.rs +++ b/hammond-gtk/src/widgets/show.rs @@ -1,15 +1,15 @@ -use gtk::prelude::*; -use gtk; -use open; use dissolve; +use gtk; +use gtk::prelude::*; +use open; -use hammond_data::dbqueries; use hammond_data::Podcast; +use hammond_data::dbqueries; use hammond_data::utils::{delete_show, replace_extra_spaces}; -use widgets::episode::episodes_listbox; -use utils::get_pixbuf_from_path; use app::Action; +use utils::get_pixbuf_from_path; +use widgets::episode::episodes_listbox; use std::sync::mpsc::Sender; use std::thread; diff --git a/rustfmt.toml b/rustfmt.toml index c420ec1..b755324 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -6,8 +6,10 @@ wrap_comments = true tab_spaces = 4 hard_tabs = false newline_style = "Unix" -reorder_imports = false write_mode = "Overwrite" condense_wildcard_suffixes = false format_strings = true -normalize_comments = true \ No newline at end of file +normalize_comments = true +reorder_imports = true +reorder_imported_names = true +reorder_imports_in_group = true From 5d88998180c82fc4c0a7e4ddc25f0c918f8018c2 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Wed, 17 Jan 2018 10:21:16 +0200 Subject: [PATCH 206/278] hammond_data: Add an EpisodeMinimal Diesel model. --- hammond-data/src/models/episode.rs | 84 ++++++++++++++++++++++++++ hammond-data/src/models/mod.rs | 4 +- hammond-data/src/models/new_episode.rs | 33 ++++++++-- hammond-data/src/schema.rs | 2 + 4 files changed, 115 insertions(+), 8 deletions(-) diff --git a/hammond-data/src/models/episode.rs b/hammond-data/src/models/episode.rs index 2ae3796..10634c7 100644 --- a/hammond-data/src/models/episode.rs +++ b/hammond-data/src/models/episode.rs @@ -6,6 +6,7 @@ use diesel::prelude::*; use database::connection; use errors::*; use models::Podcast; +use models::new_episode::{NewEpisodeMinimal, NewEpisodeMinimalBuilder}; use schema::episode; #[derive(Queryable, Identifiable, AsChangeset, Associations, PartialEq)] @@ -411,3 +412,86 @@ impl EpisodeCleanerQuery { .execute(&*tempdb)?) } } + +#[derive(Queryable, AsChangeset, PartialEq)] +#[table_name = "episode"] +#[changeset_options(treat_none_as_null = "true")] +#[primary_key(title, podcast_id)] +#[derive(Debug, Clone)] +/// Diesel Model to be used for FIXME. +pub struct EpisodeMinimal { + rowid: i32, + title: String, + uri: Option, + epoch: i32, + duration: Option, + guid: Option, + podcast_id: i32, +} + +impl From for EpisodeMinimal { + fn from(e: Episode) -> Self { + EpisodeMinimal { + rowid: e.rowid, + title: e.title, + uri: e.uri, + guid: e.guid, + epoch: e.epoch, + duration: e.duration, + podcast_id: e.podcast_id, + } + } +} + +impl Into for EpisodeMinimal { + fn into(self) -> NewEpisodeMinimal { + NewEpisodeMinimalBuilder::default() + .title(self.title) + .uri(self.uri) + .guid(self.guid) + .epoch(self.epoch) + .duration(self.duration) + .podcast_id(self.podcast_id) + .build() + .unwrap() + } +} + +impl EpisodeMinimal { + /// Get the value of the sqlite's `ROW_ID` + pub fn rowid(&self) -> i32 { + self.rowid + } + + /// Get the value of the `title` field. + pub fn title(&self) -> &str { + &self.title + } + + /// Get the value of the `uri`. + /// + /// Represents the url(usually) that the media file will be located at. + pub fn uri(&self) -> Option<&str> { + self.uri.as_ref().map(|s| s.as_str()) + } + + /// Get the `epoch` value. + /// + /// Retrieved from the rss Item publish date. + /// Value is set to Utc whenever possible. + pub fn epoch(&self) -> i32 { + self.epoch + } + + /// Get the `duration` value. + /// + /// The number represents the duration of the item/episode in seconds. + pub fn duration(&self) -> Option { + self.duration + } + + /// `Podcast` table foreign key. + pub fn podcast_id(&self) -> i32 { + self.podcast_id + } +} diff --git a/hammond-data/src/models/mod.rs b/hammond-data/src/models/mod.rs index e121734..1d9a4e6 100644 --- a/hammond-data/src/models/mod.rs +++ b/hammond-data/src/models/mod.rs @@ -12,13 +12,13 @@ pub(crate) use self::new_episode::{NewEpisode, NewEpisodeMinimal}; pub(crate) use self::new_podcast::NewPodcast; pub(crate) use self::new_source::NewSource; -pub use self::episode::{Episode, EpisodeWidgetQuery}; +pub use self::episode::{Episode, EpisodeMinimal, EpisodeWidgetQuery}; pub(crate) use self::episode::EpisodeCleanerQuery; pub use self::podcast::{Podcast, PodcastCoverQuery}; pub use self::source::Source; #[allow(dead_code)] -enum IndexState { +pub enum IndexState { Index(T), Update(T), NotChanged, diff --git a/hammond-data/src/models/new_episode.rs b/hammond-data/src/models/new_episode.rs index e0650a7..1933de6 100644 --- a/hammond-data/src/models/new_episode.rs +++ b/hammond-data/src/models/new_episode.rs @@ -8,8 +8,7 @@ use rss; use dbqueries; use errors::*; -use models::{Insert, Update}; -use models::Episode; +use models::{Episode, Insert, Update}; use parser; use utils::{replace_extra_spaces, url_cleaner}; @@ -168,10 +167,8 @@ impl NewEpisodeMinimal { bail!("No url specified for the item.") }; - let date = parse_rfc822( - // Default to rfc2822 represantation of epoch 0. - item.pub_date().unwrap_or("Thu, 1 Jan 1970 00:00:00 +0000"), - ); + // Default to rfc2822 represantation of epoch 0. + let date = parse_rfc822(item.pub_date().unwrap_or("Thu, 1 Jan 1970 00:00:00 +0000")); // Should treat information from the rss feeds as invalid by default. // Case: Thu, 05 Aug 2016 06:00:00 -0400 <-- Actually that was friday. let epoch = date.map(|x| x.timestamp() as i32).unwrap_or(0); @@ -216,3 +213,27 @@ impl NewEpisodeMinimal { .unwrap() } } + +#[allow(dead_code)] +// Ignore the following getters. They are used in unit tests mainly. +impl NewEpisodeMinimal { + pub(crate) fn title(&self) -> &str { + self.title.as_ref() + } + + pub(crate) fn uri(&self) -> Option<&str> { + self.uri.as_ref().map(|s| s.as_str()) + } + + pub(crate) fn guid(&self) -> Option<&str> { + self.guid.as_ref().map(|s| s.as_str()) + } + + pub(crate) fn epoch(&self) -> i32 { + self.epoch + } + + pub(crate) fn podcast_id(&self) -> i32 { + self.podcast_id + } +} diff --git a/hammond-data/src/schema.rs b/hammond-data/src/schema.rs index d50a2f5..cf22457 100644 --- a/hammond-data/src/schema.rs +++ b/hammond-data/src/schema.rs @@ -38,3 +38,5 @@ table! { http_etag -> Nullable, } } + +allow_tables_to_appear_in_same_query!(episode, podcast, source,); From 93372a30d0d4b79835f3b03be4d00fd7343c7dd6 Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 18 Jan 2018 11:38:24 +0200 Subject: [PATCH 207/278] 1.21 Gigawatts. Remove non-future indexing loop. Tried to have a seperate futures loop but it's too confusign having too write a Trait2, functon2, etc version of everything and keep it together. Futures are functional sort of, so the synchronous versioun can be removed. It still needs a ton of work though to be ready, or even get near the perf of of the sync+rayon version. --- Cargo.lock | 5 + hammond-data/benches/bench.rs | 35 +------ hammond-data/src/database.rs | 2 +- hammond-data/src/dbqueries.rs | 21 +++- hammond-data/src/feed.rs | 128 ++++++------------------- hammond-data/src/models/mod.rs | 12 ++- hammond-data/src/models/new_episode.rs | 42 ++++---- hammond-data/src/models/new_podcast.rs | 23 +++-- hammond-data/src/models/new_source.rs | 24 ++--- hammond-data/src/models/source.rs | 66 +------------ hammond-data/src/parser.rs | 1 - hammond-data/src/pipeline.rs | 56 ++++++++++- hammond-data/src/utils.rs | 40 ++------ hammond-downloader/Cargo.toml | 4 + hammond-downloader/src/downloader.rs | 18 +++- hammond-downloader/src/lib.rs | 5 + hammond-gtk/Cargo.toml | 5 + hammond-gtk/src/main.rs | 7 ++ hammond-gtk/src/manager.rs | 26 ++--- hammond-gtk/src/utils.rs | 18 +++- 20 files changed, 246 insertions(+), 292 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 64d6542..4a16cb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -564,10 +564,12 @@ dependencies = [ "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "hammond-data 0.1.0", "hyper 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -584,6 +586,8 @@ dependencies = [ "hammond-data 0.1.0", "hammond-downloader 0.1.0", "humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.11.12 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "loggerv 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -591,6 +595,7 @@ dependencies = [ "rayon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "send-cell 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/hammond-data/benches/bench.rs b/hammond-data/benches/bench.rs index 8e665a0..d019282 100644 --- a/hammond-data/benches/bench.rs +++ b/hammond-data/benches/bench.rs @@ -32,25 +32,6 @@ static URLS: &[(&[u8], &str)] = &[ (LAS, "https://feeds2.feedburner.com/TheLinuxActionShow"), ]; -static URLS2: &[&str] = &[ - "https://www.pcper.com/rss/podcasts-mp3.rss", - "https://feeds.feedburner.com/InterceptedWithJeremyScahill", - "http://www.badvoltage.org/feed/ogg/", - "https://www.theguardian.com/news/series/the-audio-long-read/podcast.xml", - "http://feeds.feedburner.com/coderradiomp3", - "https://rss.art19.com/steal-the-stars", - "https://feeds.mozilla-podcasts.org/irl", - "http://economicupdate.libsyn.com/rss", - "http://feeds.feedburner.com/linuxunplugged", - "http://ubuntupodcast.org/feed/ogg/", - "http://www.newrustacean.com/feed.xml", - "http://feeds.propublica.org/propublica/podcast", - "https://rss.acast.com/thetipoff", - "http://feeds.soundcloud.com/users/soundcloud:users:277306156/sounds.rss", - "http://revolutionspodcast.libsyn.com/rss/", - "https://www.greaterthancode.com/feed/podcast", -]; - fn index_urls() { let feeds: Vec<_> = URLS.iter() .map(|&(buff, url)| { @@ -84,24 +65,10 @@ fn bench_index_unchanged_feeds(b: &mut Bencher) { }); } -#[bench] -fn bench_get_normal_feeds(b: &mut Bencher) { - // Index first so it will only bench the comparison test case. - truncate_db().unwrap(); - URLS2.iter().for_each(|url| { - Source::from_url(url).unwrap(); - }); - - b.iter(|| { - let sources = hammond_data::dbqueries::get_sources().unwrap(); - index_loop(sources); - }); -} - #[bench] fn bench_get_future_feeds(b: &mut Bencher) { truncate_db().unwrap(); - URLS2.iter().for_each(|url| { + URLS.iter().for_each(|&(_, url)| { Source::from_url(url).unwrap(); }); diff --git a/hammond-data/src/database.rs b/hammond-data/src/database.rs index 0e2320c..7cd3e6e 100644 --- a/hammond-data/src/database.rs +++ b/hammond-data/src/database.rs @@ -38,7 +38,7 @@ lazy_static! { } /// Get an r2d2 SqliteConnection. -pub fn connection() -> Pool { +pub(crate) fn connection() -> Pool { POOL.clone() } diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 0f36c10..1493ce0 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -6,7 +6,8 @@ use diesel::prelude::*; use database::connection; use errors::*; -use models::{Episode, EpisodeCleanerQuery, EpisodeWidgetQuery, Podcast, PodcastCoverQuery, Source}; +use models::{Episode, EpisodeCleanerQuery, EpisodeMinimal, EpisodeWidgetQuery, Podcast, + PodcastCoverQuery, Source}; pub fn get_sources() -> Result> { use schema::source::dsl::*; @@ -238,13 +239,29 @@ pub fn get_podcast_from_source_id(sid: i32) -> Result { .map_err(From::from) } -pub fn get_episode_from_pk(con: &SqliteConnection, title_: &str, pid: i32) -> QueryResult { +pub fn get_episode_from_pk(title_: &str, pid: i32) -> Result { use schema::episode::dsl::*; + let db = connection(); + let con = db.get()?; episode .filter(title.eq(title_)) .filter(podcast_id.eq(pid)) .get_result::(&*con) + .map_err(From::from) +} + +pub fn get_episode_minimal_from_pk(title_: &str, pid: i32) -> Result { + use schema::episode::dsl::*; + let db = connection(); + let con = db.get()?; + + episode + .select((rowid, title, uri, epoch, duration, guid, podcast_id)) + .filter(title.eq(title_)) + .filter(podcast_id.eq(pid)) + .get_result::(&*con) + .map_err(From::from) } pub fn remove_feed(pd: &Podcast) -> Result<()> { diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 78c03eb..63050ca 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -1,19 +1,13 @@ //! Index Feeds. -use diesel::prelude::*; use futures::future::*; -use futures::prelude::*; -use rayon::iter::IntoParallelIterator; +// use futures::prelude::*; +use errors::*; +use models::{NewEpisode, NewPodcast, Podcast}; use rayon::prelude::*; use rss; - -use database::connection; -use dbqueries; -use errors::*; -use models::{NewEpisode, NewPodcast, Podcast, Source}; - -// #[cfg(test)] -// use models::queryables::Episode; +// use models::{IndexState, Source}; +// use pipeline::*; #[derive(Debug)] /// Wrapper struct that hold a `Source` id and the `rss::Channel` @@ -24,11 +18,6 @@ pub struct Feed { } impl Feed { - /// Constructor that consumes a `Source` and returns the corresponding `Feed` struct. - pub fn from_source(s: &mut Source) -> Result { - s.into_feed(false) - } - /// Constructor that consumes a `Source` and a `rss::Channel` returns a `Feed` struct. pub fn from_channel_source(channel: rss::Channel, source_id: i32) -> Feed { Feed { channel, source_id } @@ -40,31 +29,15 @@ impl Feed { self.index_channel_items(&pd) } - /// Docs - // FIXME: docs - // FIXME: lifetime stuff - pub fn index_future(self) -> Box> { - let indx = self.parse_podcast_futture() - .and_then(|pd| pd.into_podcast()) - .and_then(move |pd| self.index_channel_items(&pd)); - - Box::new(indx) - } - // TODO: Refactor transcactions and find a way to do it in parallel. fn index_channel_items(&self, pd: &Podcast) -> Result<()> { let episodes = self.parse_channel_items(pd); - let db = connection(); - let con = db.get()?; - let _ = con.transaction::<(), Error, _>(|| { - episodes.into_iter().for_each(|x| { - if let Err(err) = x.index(&con) { - error!("Failed to index episode: {:?}.", x.title()); - error!("Error msg: {}", err); - }; - }); - Ok(()) + episodes.iter().for_each(|x| { + if let Err(err) = x.index() { + error!("Failed to index episode: {:?}.", x.title()); + error!("Error msg: {}", err); + }; }); Ok(()) } @@ -73,6 +46,7 @@ impl Feed { NewPodcast::new(&self.channel, self.source_id) } + #[allow(dead_code)] fn parse_podcast_futture(&self) -> Box> { Box::new(ok(self.parse_podcast())) } @@ -86,69 +60,28 @@ impl Feed { new_episodes } - - // This could also retrurn a FutureResult>, Error> Instead - #[allow(dead_code)] - fn parse_episodes_future(&self, pd: &Podcast) -> Box>> { - let episodes = self.channel - .items() - .par_iter() - .map(|item| result(NewEpisode::new(item, pd.id()))) - .collect(); - - Box::new(episodes) - } - - // #[cfg(test)] - // /// This returns only the episodes in the xml feed. - // fn get_episodes(&self) -> Result> { - // let pd = self.get_podcast()?; - // let eps = self.parse_channel_items(&pd); - - // let db = connection(); - // let con = db.get()?; - // let episodes: Vec<_> = eps.into_iter() - // .filter_map(|ep| ep.into_episode(&con).ok()) - // .collect(); - - // Ok(episodes) - // } } +// fn parse_channel_items2( +// &self, +// pd: &Podcast, +// ) -> (Vec>, Vec>) { +// let items = self.channel.items(); +// let (insert, update): (Vec<_>, Vec<_>) = items +// .into_iter() +// .filter_map(|item| glue(item, pd.id()).ok()) +// .filter(|&state| state == IndexState::NotChanged) +// .partition(|&state| state == IndexState::Index); -/// Index a "list" of `Source`s. -pub fn index_loop>(sources: S) { - sources - .into_par_iter() - .filter_map(|mut source| { - let foo = Feed::from_source(&mut source); - if let Err(err) = foo { - error!("Error: {}", err); - None - } else { - foo.ok() - } - }) - // Handle the indexing of a `Feed` into the Database. - .for_each(|feed| { - if let Err(err) = feed.index() { - error!("Error While trying to update the database."); - error!("Error msg: {}", err); - } - }); - - info!("Indexing done."); -} - -/// Retrieves all `Sources` from the database and updates/indexes them. -pub fn index_all() -> Result<()> { - let sources = dbqueries::get_sources()?; - index_loop(sources); - Ok(()) -} +// (insert, update) +// } +// } #[cfg(test)] mod tests { + use Source; use database::truncate_db; + use dbqueries; + use pipeline; use std::fs; use std::io::BufReader; @@ -169,11 +102,12 @@ mod tests { // Index the urls into the source table. Source::from_url(url).unwrap(); }); + let sources = dbqueries::get_sources().unwrap(); + pipeline::pipeline(sources, true).unwrap(); - index_all().unwrap(); - + let sources = dbqueries::get_sources().unwrap(); // Run again to cover Unique constrains erros. - index_all().unwrap(); + pipeline::pipeline(sources, true).unwrap() } #[test] diff --git a/hammond-data/src/models/mod.rs b/hammond-data/src/models/mod.rs index 1d9a4e6..b637ae0 100644 --- a/hammond-data/src/models/mod.rs +++ b/hammond-data/src/models/mod.rs @@ -6,7 +6,8 @@ pub(crate) mod episode; pub(crate) mod podcast; pub(crate) mod source; -use diesel::prelude::*; +// use futures::prelude::*; +// use futures::future::*; pub(crate) use self::new_episode::{NewEpisode, NewEpisodeMinimal}; pub(crate) use self::new_podcast::NewPodcast; @@ -17,17 +18,20 @@ pub(crate) use self::episode::EpisodeCleanerQuery; pub use self::podcast::{Podcast, PodcastCoverQuery}; pub use self::source::Source; +use errors::*; + #[allow(dead_code)] +#[derive(Debug, Clone, PartialEq)] pub enum IndexState { Index(T), - Update(T), + Update((T, i32)), NotChanged, } pub trait Insert { - fn insert(&self, &SqliteConnection) -> QueryResult; + fn insert(&self) -> Result<()>; } pub trait Update { - fn update(&self, &SqliteConnection, i32) -> QueryResult; + fn update(&self, i32) -> Result<()>; } diff --git a/hammond-data/src/models/new_episode.rs b/hammond-data/src/models/new_episode.rs index 1933de6..33f9561 100644 --- a/hammond-data/src/models/new_episode.rs +++ b/hammond-data/src/models/new_episode.rs @@ -1,11 +1,13 @@ -use diesel; use diesel::prelude::*; + +use diesel; use schema::episode; use ammonia; use rfc822_sanitizer::parse_from_rfc2822_with_fallback as parse_rfc822; use rss; +use database::connection; use dbqueries; use errors::*; use models::{Episode, Insert, Update}; @@ -44,43 +46,49 @@ impl From for NewEpisode { } impl Insert for NewEpisode { - fn insert(&self, con: &SqliteConnection) -> QueryResult { + fn insert(&self) -> Result<()> { use schema::episode::dsl::*; - diesel::insert_into(episode).values(self).execute(&*con) + let db = connection(); + let con = db.get()?; + + info!("Indexing {:?}", self.title); + diesel::insert_into(episode) + .values(self) + .execute(&*con) + .map_err(From::from) + .map(|_| ()) } } impl Update for NewEpisode { - fn update(&self, con: &SqliteConnection, episode_id: i32) -> QueryResult { + fn update(&self, episode_id: i32) -> Result<()> { use schema::episode::dsl::*; + let db = connection(); + let con = db.get()?; info!("Updating {:?}", self.title); diesel::update(episode.filter(rowid.eq(episode_id))) .set(self) .execute(&*con) + .map_err(From::from) + .map(|_| ()) } } impl NewEpisode { - #[allow(dead_code)] /// Parses an `rss::Item` into a `NewEpisode` Struct. pub(crate) fn new(item: &rss::Item, podcast_id: i32) -> Result { NewEpisodeMinimal::new(item, podcast_id).map(|ep| ep.into_new_episode(item)) } - // TODO: Refactor into batch indexes instead. #[allow(dead_code)] - pub(crate) fn into_episode(self, con: &SqliteConnection) -> Result { - self.index(con)?; - Ok(dbqueries::get_episode_from_pk( - con, - &self.title, - self.podcast_id, - )?) + pub(crate) fn into_episode(self) -> Result { + self.index()?; + dbqueries::get_episode_from_pk(&self.title, self.podcast_id) } - pub(crate) fn index(&self, con: &SqliteConnection) -> QueryResult<()> { - let ep = dbqueries::get_episode_from_pk(con, &self.title, self.podcast_id); + pub(crate) fn index(&self) -> Result<()> { + let ep = dbqueries::get_episode_from_pk(&self.title, self.podcast_id); match ep { Ok(foo) => { @@ -92,11 +100,11 @@ impl NewEpisode { || foo.uri() != self.uri.as_ref().map(|s| s.as_str()) || foo.duration() != self.duration { - self.update(con, foo.rowid())?; + self.update(foo.rowid())?; } } Err(_) => { - self.insert(con)?; + self.insert()?; } } Ok(()) diff --git a/hammond-data/src/models/new_podcast.rs b/hammond-data/src/models/new_podcast.rs index c47e855..7ba7068 100644 --- a/hammond-data/src/models/new_podcast.rs +++ b/hammond-data/src/models/new_podcast.rs @@ -29,20 +29,31 @@ pub(crate) struct NewPodcast { } impl Insert for NewPodcast { - fn insert(&self, con: &SqliteConnection) -> QueryResult { + fn insert(&self) -> Result<()> { use schema::podcast::dsl::*; - diesel::insert_into(podcast).values(self).execute(&*con) + let db = connection(); + let con = db.get()?; + + diesel::insert_into(podcast) + .values(self) + .execute(&*con) + .map(|_| ()) + .map_err(From::from) } } impl Update for NewPodcast { - fn update(&self, con: &SqliteConnection, podcast_id: i32) -> QueryResult { + fn update(&self, podcast_id: i32) -> Result<()> { use schema::podcast::dsl::*; + let db = connection(); + let con = db.get()?; info!("Updating {}", self.title); diesel::update(podcast.filter(id.eq(podcast_id))) .set(self) .execute(&*con) + .map(|_| ()) + .map_err(From::from) } } @@ -87,19 +98,17 @@ impl NewPodcast { pub(crate) fn index(&self) -> Result<()> { let pd = dbqueries::get_podcast_from_source_id(self.source_id); - let db = connection(); - let con = db.get()?; match pd { Ok(foo) => { if (foo.link() != self.link) || (foo.title() != self.title) || (foo.image_uri() != self.image_uri.as_ref().map(|x| x.as_str())) { info!("NewEpisode: {:?}\n OldEpisode: {:?}", self, foo); - self.update(&con, foo.id())?; + self.update(foo.id())?; } } Err(_) => { - self.insert(&con)?; + self.insert()?; } } Ok(()) diff --git a/hammond-data/src/models/new_source.rs b/hammond-data/src/models/new_source.rs index dc572cf..8e1fef3 100644 --- a/hammond-data/src/models/new_source.rs +++ b/hammond-data/src/models/new_source.rs @@ -5,7 +5,8 @@ use diesel::prelude::*; use database::connection; use dbqueries; -use models::{Insert, Update}; +// use models::{Insert, Update}; +use models::Insert; use models::Source; use schema::source; @@ -24,9 +25,14 @@ pub(crate) struct NewSource { } impl Insert for NewSource { - fn insert(&self, con: &SqliteConnection) -> QueryResult { + fn insert(&self) -> Result<()> { use schema::source::dsl::*; - diesel::insert_into(source).values(self).execute(&*con) + let db = connection(); + let con = db.get()?; + + // FIXME: Insert or ignore + let _ = diesel::insert_into(source).values(self).execute(&*con); + Ok(()) } } @@ -39,19 +45,9 @@ impl NewSource { } } - fn index(&self) -> Result<()> { - let db = connection(); - let con = db.get()?; - - // Throw away the result like `insert or ignore` - // Diesel deos not support `insert or ignore` yet. - let _ = self.insert(&con); - Ok(()) - } - // Look out for when tryinto lands into stable. pub(crate) fn into_source(self) -> Result { - self.index()?; + self.insert()?; dbqueries::get_source_from_uri(&self.uri) } } diff --git a/hammond-data/src/models/source.rs b/hammond-data/src/models/source.rs index b4245be..4843aaa 100644 --- a/hammond-data/src/models/source.rs +++ b/hammond-data/src/models/source.rs @@ -1,5 +1,4 @@ use diesel::SaveChangesDsl; -use reqwest; use rss::Channel; use hyper; @@ -17,7 +16,6 @@ use feed::Feed; use models::NewSource; use schema::source; -use std::io::Read; use std::str::FromStr; #[derive(Queryable, Identifiable, AsChangeset, PartialEq)] @@ -79,26 +77,8 @@ impl Source { /// Extract Etag and LastModifier from res, and update self and the /// corresponding db row. - fn update_etag(&mut self, res: &reqwest::Response) -> Result<()> { - let headers = res.headers(); - - let etag = headers.get::(); - let lmod = headers.get::(); - - if self.http_etag() != etag.map(|x| x.tag()) || self.last_modified != lmod.map(|x| { - format!("{}", x) - }) { - self.http_etag = etag.map(|x| x.tag().to_string().to_owned()); - self.last_modified = lmod.map(|x| format!("{}", x)); - self.save()?; - } - - Ok(()) - } - - /// Extract Etag and LastModifier from res, and update self and the - /// corresponding db row. - fn update_etag2(mut self, res: &Response) -> Result<()> { + // FIXME: With &mut self the closure is of type FnMut instead of FnOnce. + fn update_etag(mut self, res: &Response) -> Result<()> { let headers = res.headers(); let etag = headers.get::(); @@ -123,43 +103,7 @@ impl Source { /// /// Consumes `self` and Returns the corresponding `Feed` Object. // TODO: Refactor into TryInto once it lands on stable. - pub fn into_feed(&mut self, ignore_etags: bool) -> Result { - use reqwest::header::{EntityTag, Headers, HttpDate, IfModifiedSince, IfNoneMatch}; - - let mut headers = Headers::new(); - - if !ignore_etags { - if let Some(foo) = self.http_etag() { - headers.set(IfNoneMatch::Items(vec![ - EntityTag::new(true, foo.to_owned()), - ])); - } - - if let Some(foo) = self.last_modified() { - if let Ok(x) = foo.parse::() { - headers.set(IfModifiedSince(x)); - } - } - } - - let client = reqwest::Client::builder().referer(false).build()?; - let mut res = client.get(self.uri()).headers(headers).send()?; - - info!("GET to {} , returned: {}", self.uri(), res.status()); - - self.update_etag(&res)?; - match_status(res.status())?; - - let mut buf = String::new(); - res.read_to_string(&mut buf)?; - let chan = Channel::from_str(&buf)?; - - Ok(Feed::from_channel_source(chan, self.id)) - } - - // FIXME: - /// Docs - pub fn into_fututre_feed( + pub fn into_feed( self, client: &Client>, ignore_etags: bool, @@ -168,7 +112,7 @@ impl Source { let feed = request_constructor(&self, client, ignore_etags) .map_err(From::from) .and_then(move |res| { - self.update_etag2(&res)?; + self.update_etag(&res)?; Ok(res) }) .and_then(|res| -> Result { @@ -278,7 +222,7 @@ mod tests { let url = "http://www.newrustacean.com/feed.xml"; let source = Source::from_url(url).unwrap(); - let feed = source.into_fututre_feed(&client, true); + let feed = source.into_feed(&client, true); assert!(core.run(feed).is_ok()); } diff --git a/hammond-data/src/parser.rs b/hammond-data/src/parser.rs index f8fb6cc..a06b319 100644 --- a/hammond-data/src/parser.rs +++ b/hammond-data/src/parser.rs @@ -2,7 +2,6 @@ use rss::Item; /// Parses an Item Itunes extension and returns it's duration value in seconds. // FIXME: Rafactor -// TODO: Write tests #[allow(non_snake_case)] pub(crate) fn parse_itunes_duration(item: &Item) -> Option { let duration = item.itunes_ext().map(|s| s.duration())??; diff --git a/hammond-data/src/pipeline.rs b/hammond-data/src/pipeline.rs index 6454d33..41142f4 100644 --- a/hammond-data/src/pipeline.rs +++ b/hammond-data/src/pipeline.rs @@ -2,14 +2,19 @@ //! Docs. use futures::future::*; -use futures::prelude::*; +// use futures::prelude::*; use hyper::Client; use hyper_tls::HttpsConnector; use tokio_core::reactor::Core; +use rss; + use Source; +use dbqueries; use errors::*; +use models::{IndexState, Insert, NewEpisode, NewEpisodeMinimal, Update}; +// use models::new_episode::NewEpisodeMinimal; // use Feed; use std; @@ -32,7 +37,7 @@ pub fn pipeline>(sources: S, ignore_etags: bool) .into_iter() // FIXME: Make proper indexing futures instead of wrapping up existing // blocking functions - .map(|s| s.into_fututre_feed(&client, ignore_etags).map(|feed| feed.index_future())) + .map(|s| s.into_feed(&client, ignore_etags).and_then(|feed| feed.index())) .collect(); let f = core.run(collect_futures(list))?; @@ -43,9 +48,54 @@ pub fn pipeline>(sources: S, ignore_etags: bool) Ok(()) } +#[allow(dead_code)] +pub(crate) fn determine_episode_state( + ep: NewEpisodeMinimal, + item: &rss::Item, +) -> Result> { + // determine if feed exists + let exists = dbqueries::episode_exists(ep.title(), ep.podcast_id())?; + + if !exists { + return Ok(IndexState::Index(ep.into_new_episode(item))); + } else { + let old = dbqueries::get_episode_minimal_from_pk(ep.title(), ep.podcast_id())?; + let rowid = old.rowid(); + + if ep != old.into() { + return Ok(IndexState::Update((ep.into_new_episode(item), rowid))); + } else { + return Ok(IndexState::NotChanged); + } + } +} + +#[allow(dead_code)] +pub(crate) fn model_state(state: IndexState) -> Result<()> { + match state { + IndexState::NotChanged => Ok(()), + IndexState::Index(t) => t.insert(), + IndexState::Update((t, rowid)) => t.update(rowid), + } +} + +#[allow(dead_code)] +pub(crate) fn model_state_future( + state: IndexState, +) -> Box> { + Box::new(result(model_state(state))) +} + +#[allow(dead_code)] +pub(crate) fn glue(item: &rss::Item, id: i32) -> Result> { + let e = NewEpisodeMinimal::new(item, id)?; + determine_episode_state(e, &item) +} + // Weird magic from #rust irc channel // kudos to remexre -fn collect_futures( +/// docs +pub fn collect_futures( futures: Vec, ) -> Box>, Error = Error>> where diff --git a/hammond-data/src/utils.rs b/hammond-data/src/utils.rs index bf875e1..c75f1a2 100644 --- a/hammond-data/src/utils.rs +++ b/hammond-data/src/utils.rs @@ -153,7 +153,7 @@ mod tests { use self::tempdir::TempDir; use super::*; - use database::{connection, truncate_db}; + use database::truncate_db; use models::new_episode::NewEpisodeBuilder; use std::fs::File; use std::io::Write; @@ -169,14 +169,12 @@ mod tests { writeln!(tmp_file, "Foooo").unwrap(); // Setup episodes - let db = connection(); - let con = db.get().unwrap(); let n1 = NewEpisodeBuilder::default() .title("foo_bar".to_string()) .podcast_id(0) .build() .unwrap() - .into_episode(&con) + .into_episode() .unwrap(); let n2 = NewEpisodeBuilder::default() @@ -184,15 +182,14 @@ mod tests { .podcast_id(1) .build() .unwrap() - .into_episode(&con) + .into_episode() .unwrap(); - let mut ep1 = dbqueries::get_episode_from_pk(&con, n1.title(), n1.podcast_id()).unwrap(); - let mut ep2 = dbqueries::get_episode_from_pk(&con, n2.title(), n2.podcast_id()).unwrap(); + let mut ep1 = dbqueries::get_episode_from_pk(n1.title(), n1.podcast_id()).unwrap(); + let mut ep2 = dbqueries::get_episode_from_pk(n2.title(), n2.podcast_id()).unwrap(); ep1.set_local_uri(Some(valid_path.to_str().unwrap())); ep2.set_local_uri(Some(bad_path.to_str().unwrap())); - drop(con); ep1.save().unwrap(); ep2.save().unwrap(); @@ -214,24 +211,15 @@ mod tests { let _tmp_dir = helper_db(); download_checker().unwrap(); - let episode = { - let db = connection(); - let con = db.get().unwrap(); - dbqueries::get_episode_from_pk(&con, "bar_baz", 1).unwrap() - }; + let episode = dbqueries::get_episode_from_pk("bar_baz", 1).unwrap(); assert!(episode.local_uri().is_none()); } #[test] fn test_download_cleaner() { let _tmp_dir = helper_db(); - let mut episode: EpisodeCleanerQuery = { - let db = connection(); - let con = db.get().unwrap(); - dbqueries::get_episode_from_pk(&con, "foo_bar", 0) - .unwrap() - .into() - }; + let mut episode: EpisodeCleanerQuery = + dbqueries::get_episode_from_pk("foo_bar", 0).unwrap().into(); let valid_path = episode.local_uri().unwrap().to_owned(); delete_local_content(&mut episode).unwrap(); @@ -241,11 +229,7 @@ mod tests { #[test] fn test_played_cleaner_expired() { let _tmp_dir = helper_db(); - let mut episode = { - let db = connection(); - let con = db.get().unwrap(); - dbqueries::get_episode_from_pk(&con, "foo_bar", 0).unwrap() - }; + let mut episode = dbqueries::get_episode_from_pk("foo_bar", 0).unwrap(); let now_utc = Utc::now().timestamp() as i32; // let limit = now_utc - 172_800; let epoch = now_utc - 200_000; @@ -261,11 +245,7 @@ mod tests { #[test] fn test_played_cleaner_none() { let _tmp_dir = helper_db(); - let mut episode = { - let db = connection(); - let con = db.get().unwrap(); - dbqueries::get_episode_from_pk(&con, "foo_bar", 0).unwrap() - }; + let mut episode = dbqueries::get_episode_from_pk("foo_bar", 0).unwrap(); let now_utc = Utc::now().timestamp() as i32; // limit = 172_800; let epoch = now_utc - 20_000; diff --git a/hammond-downloader/Cargo.toml b/hammond-downloader/Cargo.toml index ada57e7..641a4d5 100644 --- a/hammond-downloader/Cargo.toml +++ b/hammond-downloader/Cargo.toml @@ -15,3 +15,7 @@ glob = "0.2.11" [dependencies.hammond-data] path = "../hammond-data" + +[dev-dependencies] +tokio-core = "0.1.12" +hyper-tls = "0.1.2" diff --git a/hammond-downloader/src/downloader.rs b/hammond-downloader/src/downloader.rs index 7acba68..821fbce 100644 --- a/hammond-downloader/src/downloader.rs +++ b/hammond-downloader/src/downloader.rs @@ -219,20 +219,28 @@ mod tests { use hammond_data::Source; use hammond_data::dbqueries; + use hyper::Client; + use hyper_tls::HttpsConnector; + use tokio_core::reactor::Core; + #[test] // This test inserts an rss feed to your `XDG_DATA/hammond/hammond.db` so we make it explicit // to run it. #[ignore] fn test_cache_image() { - let url = "http://www.newrustacean.com/feed.xml"; + let mut core = Core::new().unwrap(); + let client = Client::configure() + .connector(HttpsConnector::new(4, &core.handle()).unwrap()) + .build(&core.handle()); + let url = "http://www.newrustacean.com/feed.xml"; // Create and index a source - let mut source = Source::from_url(url).unwrap(); + let source = Source::from_url(url).unwrap(); // Copy it's id let sid = source.id(); - - // Convert Source it into a Feed and index it - let feed = source.into_feed(true).unwrap(); + // Convert Source it into a future Feed and index it + let future = source.into_feed(&client, true); + let feed = core.run(future).unwrap(); feed.index().unwrap(); // Get the Podcast diff --git a/hammond-downloader/src/lib.rs b/hammond-downloader/src/lib.rs index 197da0d..8612c72 100644 --- a/hammond-downloader/src/lib.rs +++ b/hammond-downloader/src/lib.rs @@ -13,3 +13,8 @@ extern crate tempdir; pub mod downloader; pub mod errors; + +#[cfg(test)] +extern crate hyper_tls; +#[cfg(test)] +extern crate tokio_core; diff --git a/hammond-gtk/Cargo.toml b/hammond-gtk/Cargo.toml index 0dc8267..78ac267 100644 --- a/hammond-gtk/Cargo.toml +++ b/hammond-gtk/Cargo.toml @@ -30,3 +30,8 @@ path = "../hammond-data" [dependencies.hammond-downloader] path = "../hammond-downloader" + +[dev-dependencies] +hyper-tls = "0.1.2" +tokio-core = "0.1.12" +hyper = "0.11.12" diff --git a/hammond-gtk/src/main.rs b/hammond-gtk/src/main.rs index 7f63acd..fdfd53a 100644 --- a/hammond-gtk/src/main.rs +++ b/hammond-gtk/src/main.rs @@ -21,6 +21,13 @@ extern crate regex; extern crate send_cell; // extern crate rayon; +#[cfg(test)] +extern crate hyper; +#[cfg(test)] +extern crate hyper_tls; +#[cfg(test)] +extern crate tokio_core; + // use rayon::prelude::*; use log::LogLevel; diff --git a/hammond-gtk/src/manager.rs b/hammond-gtk/src/manager.rs index 68b3132..476edd7 100644 --- a/hammond-gtk/src/manager.rs +++ b/hammond-gtk/src/manager.rs @@ -117,8 +117,11 @@ pub fn add(id: i32, directory: &str, sender: Sender) { mod tests { use super::*; + use hyper::Client; + use hyper_tls::HttpsConnector; + use tokio_core::reactor::Core; + use hammond_data::{Episode, Source}; - use hammond_data::database; use hammond_data::dbqueries; use hammond_data::utils::get_download_folder; @@ -133,25 +136,26 @@ mod tests { // THIS IS NOT A RELIABLE TEST // Just quick sanity check fn test_start_dl() { - let url = "http://www.newrustacean.com/feed.xml"; + let mut core = Core::new().unwrap(); + let client = Client::configure() + .connector(HttpsConnector::new(4, &core.handle()).unwrap()) + .build(&core.handle()); + let url = "http://www.newrustacean.com/feed.xml"; // Create and index a source - let mut source = Source::from_url(url).unwrap(); + let source = Source::from_url(url).unwrap(); // Copy it's id let sid = source.id(); - - // Convert Source it into a Feed and index it - let feed = source.into_feed(true).unwrap(); + // Convert Source it into a future Feed and index it + let future = source.into_feed(&client, true); + let feed = core.run(future).unwrap(); feed.index().unwrap(); // Get the Podcast let pd = dbqueries::get_podcast_from_source_id(sid).unwrap(); // Get an episode - let episode: Episode = { - let con = database::connection(); - dbqueries::get_episode_from_pk(&*con.get().unwrap(), "e000: Hello, world!", pd.id()) - .unwrap() - }; + let episode: Episode = + dbqueries::get_episode_from_pk("e000: Hello, world!", pd.id()).unwrap(); let (sender, _rx) = channel(); diff --git a/hammond-gtk/src/utils.rs b/hammond-gtk/src/utils.rs index 0cccde1..5f11ce7 100644 --- a/hammond-gtk/src/utils.rs +++ b/hammond-gtk/src/utils.rs @@ -84,20 +84,28 @@ mod tests { use hammond_data::Source; use hammond_data::dbqueries; + use hyper::Client; + use hyper_tls::HttpsConnector; + use tokio_core::reactor::Core; + #[test] // This test inserts an rss feed to your `XDG_DATA/hammond/hammond.db` so we make it explicit // to run it. #[ignore] fn test_get_pixbuf_from_path() { - let url = "http://www.newrustacean.com/feed.xml"; + let mut core = Core::new().unwrap(); + let client = Client::configure() + .connector(HttpsConnector::new(4, &core.handle()).unwrap()) + .build(&core.handle()); + let url = "http://www.newrustacean.com/feed.xml"; // Create and index a source - let mut source = Source::from_url(url).unwrap(); + let source = Source::from_url(url).unwrap(); // Copy it's id let sid = source.id(); - - // Convert Source it into a Feed and index it - let feed = source.into_feed(true).unwrap(); + // Convert Source it into a future Feed and index it + let future = source.into_feed(&client, true); + let feed = core.run(future).unwrap(); feed.index().unwrap(); // Get the Podcast From 098c5755b05da1470426cbd3148e28961d37e6bf Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 18 Jan 2018 13:47:40 +0200 Subject: [PATCH 208/278] hammond-data: Do batch indexing of new_episodes. --- hammond-data/Cargo.toml | 2 +- hammond-data/src/dbqueries.rs | 16 +++++++-- hammond-data/src/feed.rs | 61 +++++++++++++++++++++++------------ 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/hammond-data/Cargo.toml b/hammond-data/Cargo.toml index 13b6037..f360ede 100644 --- a/hammond-data/Cargo.toml +++ b/hammond-data/Cargo.toml @@ -10,7 +10,7 @@ chrono = "0.4.0" derive_builder = "0.5.1" dotenv = "0.10.1" error-chain = "0.11.0" -itertools = "0.7.4" +itertools = "0.7.6" lazy_static = "1.0.0" log = "0.3.8" r2d2 = "0.8.2" diff --git a/hammond-data/src/dbqueries.rs b/hammond-data/src/dbqueries.rs index 1493ce0..019f218 100644 --- a/hammond-data/src/dbqueries.rs +++ b/hammond-data/src/dbqueries.rs @@ -6,8 +6,8 @@ use diesel::prelude::*; use database::connection; use errors::*; -use models::{Episode, EpisodeCleanerQuery, EpisodeMinimal, EpisodeWidgetQuery, Podcast, - PodcastCoverQuery, Source}; +use models::{Episode, EpisodeCleanerQuery, EpisodeMinimal, EpisodeWidgetQuery, NewEpisode, + Podcast, PodcastCoverQuery, Source}; pub fn get_sources() -> Result> { use schema::source::dsl::*; @@ -322,6 +322,18 @@ pub fn episode_exists(title_: &str, podcast_id_: i32) -> Result { .map_err(From::from) } +pub(crate) fn index_new_episodes(eps: &[NewEpisode]) -> Result<()> { + use schema::episode::dsl::*; + let db = connection(); + let con = db.get()?; + + diesel::insert_into(episode) + .values(eps) + .execute(&*con) + .map_err(From::from) + .map(|_| ()) +} + pub fn update_none_to_played_now(parent: &Podcast) -> Result { use schema::episode::dsl::*; diff --git a/hammond-data/src/feed.rs b/hammond-data/src/feed.rs index 63050ca..515130e 100644 --- a/hammond-data/src/feed.rs +++ b/hammond-data/src/feed.rs @@ -1,13 +1,16 @@ //! Index Feeds. use futures::future::*; -// use futures::prelude::*; -use errors::*; -use models::{NewEpisode, NewPodcast, Podcast}; +use itertools::{Either, Itertools}; use rayon::prelude::*; use rss; -// use models::{IndexState, Source}; -// use pipeline::*; +// use futures::prelude::*; + +use dbqueries; +use errors::*; +use models::{IndexState, Update}; +use models::{NewEpisode, NewPodcast, Podcast}; +use pipeline::*; #[derive(Debug)] /// Wrapper struct that hold a `Source` id and the `rss::Channel` @@ -26,10 +29,11 @@ impl Feed { /// Index the contents of the RSS `Feed` into the database. pub fn index(&self) -> Result<()> { let pd = self.parse_podcast().into_podcast()?; - self.index_channel_items(&pd) + self.index_channel_items_sync(&pd) } // TODO: Refactor transcactions and find a way to do it in parallel. + #[allow(dead_code)] fn index_channel_items(&self, pd: &Podcast) -> Result<()> { let episodes = self.parse_channel_items(pd); @@ -42,6 +46,7 @@ impl Feed { Ok(()) } + #[allow(dead_code)] fn parse_podcast(&self) -> NewPodcast { NewPodcast::new(&self.channel, self.source_id) } @@ -51,6 +56,7 @@ impl Feed { Box::new(ok(self.parse_podcast())) } + #[allow(dead_code)] fn parse_channel_items(&self, pd: &Podcast) -> Vec { let items = self.channel.items(); let new_episodes: Vec<_> = items @@ -60,21 +66,36 @@ impl Feed { new_episodes } -} -// fn parse_channel_items2( -// &self, -// pd: &Podcast, -// ) -> (Vec>, Vec>) { -// let items = self.channel.items(); -// let (insert, update): (Vec<_>, Vec<_>) = items -// .into_iter() -// .filter_map(|item| glue(item, pd.id()).ok()) -// .filter(|&state| state == IndexState::NotChanged) -// .partition(|&state| state == IndexState::Index); -// (insert, update) -// } -// } + #[allow(dead_code)] + fn index_channel_items_sync(&self, pd: &Podcast) -> Result<()> { + let items = self.channel.items(); + let (insert, update): (Vec<_>, Vec<_>) = items + .into_iter() + .filter_map(|item| glue(item, pd.id()).ok()) + .filter(|state| match state { + &IndexState::NotChanged => false, + _ => true, + }) + .partition_map(|state| match state { + IndexState::Index(e) => Either::Left(e), + IndexState::Update(e) => Either::Right(e), + // How not to use the unimplemented macro... + IndexState::NotChanged => unimplemented!(), + }); + + dbqueries::index_new_episodes(insert.as_slice())?; + + update.par_iter().for_each(|&(ref ep, rowid)| { + if let Err(err) = ep.update(rowid) { + error!("Failed to index episode: {:?}.", ep.title()); + error!("Error msg: {}", err); + }; + }); + + Ok(()) + } +} #[cfg(test)] mod tests { From 1c96288178c2764d231680727c79ab881828409d Mon Sep 17 00:00:00 2001 From: Jordan Petridis Date: Thu, 18 Jan 2018 15:50:48 +0200 Subject: [PATCH 209/278] hammond_data: Add more benchmark cases. --- hammond-data/benches/bench.rs | 32 + .../benches/feeds/GreaterThanCode.xml | 15209 ++++++++++++++++ hammond-data/benches/feeds/StealTheStars.xml | 370 + 3 files changed, 15611 insertions(+) create mode 100644 hammond-data/benches/feeds/GreaterThanCode.xml create mode 100644 hammond-data/benches/feeds/StealTheStars.xml diff --git a/hammond-data/benches/bench.rs b/hammond-data/benches/bench.rs index d019282..5e58391 100644 --- a/hammond-data/benches/bench.rs +++ b/hammond-data/benches/bench.rs @@ -24,6 +24,12 @@ const RADIO: &[u8] = include_bytes!("feeds/coderradiomp3.xml"); const SNAP: &[u8] = include_bytes!("feeds/techsnapmp3.xml"); const LAS: &[u8] = include_bytes!("feeds/TheLinuxActionShow.xml"); +// This feed has HUGE descripion and summary fields which can be very +// very expensive to parse. +const CODE: &[u8] = include_bytes!("feeds/GreaterThanCode.xml"); +// Relative small feed +const STARS: &[u8] = include_bytes!("feeds/StealTheStars.xml"); + static URLS: &[(&[u8], &str)] = &[ (PCPER, "https://www.pcper.com/rss/podcasts-mp3.rss"), (UNPLUGGED, "http://feeds.feedburner.com/linuxunplugged"), @@ -77,3 +83,29 @@ fn bench_get_future_feeds(b: &mut Bencher) { hammond_data::pipeline::pipeline(sources, false).unwrap(); }) } + +#[bench] +fn bench_index_greater_than_code(b: &mut Bencher) { + let url = "https://www.greaterthancode.com/feed/podcast"; + + b.iter(|| { + let s = Source::from_url(url).unwrap(); + // parse it into a channel + let chan = rss::Channel::read_from(BufReader::new(CODE)).unwrap(); + let feed = Feed::from_channel_source(chan, s.id()); + feed.index().unwrap(); + }) +} + +#[bench] +fn bench_index_steal_the_stars(b: &mut Bencher) { + let url = "https://rss.art19.com/steal-the-stars"; + + b.iter(|| { + let s = Source::from_url(url).unwrap(); + // parse it into a channel + let chan = rss::Channel::read_from(BufReader::new(STARS)).unwrap(); + let feed = Feed::from_channel_source(chan, s.id()); + feed.index().unwrap(); + }) +} diff --git a/hammond-data/benches/feeds/GreaterThanCode.xml b/hammond-data/benches/feeds/GreaterThanCode.xml new file mode 100644 index 0000000..687c270 --- /dev/null +++ b/hammond-data/benches/feeds/GreaterThanCode.xml @@ -0,0 +1,15209 @@ + + + + + + Greater Than Code + + https://www.greaterthancode.com/ + A podcast about humans and technology. Panelists: Coraline Ada Ehmke, David Brady, Jessica Kerr, Jay Bobo, Astrid Countee and Sam Livingston-Gray. Brought to you by @therubyrep. + Wed, 17 Jan 2018 19:21:11 +0000 + en-US + © 2016 Greater Than Code + Because #PeopleMatter + Greater Than Code + Greater Than Code + mandy@greaterthancode.com + A podcast about humans and technology. Panelists: Coraline Ada Ehmke, David Brady, Jessica Kerr, Jay Bobo, Astrid Countee and Sam Livingston-Gray. Brought to you by @therubyrep. + A podcast about humans and technology. Panelists: Coraline Ada Ehmke, David Brady, Jessica Kerr, Jay Bobo, Astrid Countee and Sam Livingston-Gray. Brought to you by @therubyrep. + + Mandy Moore + mandy@greaterthancode.com + + clean + No + + + + http://www.greaterthancode.com/wp-content/uploads/2016/10/code1400-4.jpg + Greater Than Code + https://www.greaterthancode.com/ + + + + + + + + + https://wordpress.org/?v=4.9.2 + + 063: The Distribution of Brilliance and Opportunity with Rehema Wachira + https://www.greaterthancode.com/podcast/063-the-distribution-of-brilliance-and-opportunity-with-rehema-wachira/ + Wed, 17 Jan 2018 05:00:46 +0000 + Mandy Moore + http://www.greaterthancode.com/?post_type=podcast&p=1111 + + + Panelists:

    +

    Astrid Countee | Rein Henrichs | Jessica Kerr |
    +
    Sam Livingston-Gray | Janelle Klein

    +

    Guest Starring:

    +

    Rehema Wachira: @remy_stack | Andela

    +

    Join Our Slack Channel!
    +
    Support us via Patreon!

    +

    Are you Greater Than Code?
    +
    Submit guest blog posts to mandy@greaterthancode.com

    +

    Show Notes:

    +

    01:22 – Rehema’s Superpower: Empathy

    +

    02:53 – Rehema’s “Untypical” Origin Story

    +

    07:20 – Enjoying Coding Because of the Complexity Behind It

    +

    11:21 – Creating a “Culture of Saving”

    +

    14:52 – “Diversity of Thought” and Seeing the World Through Others’ Eyes

    +

    22:20 – Being Creators and Makers

    +

    Indie Hackers

    +

    30:28 – How Technology Empowers People

    +

    38:27 – The Distribution of Brilliance and Opportunity

    +

    47:01 – Freedom of Creative Expression

    +

    Reflections:

    +

    Astrid: Having to unlearn the need of being perfect.

    +

    Jessica: We want to speak to more guests on a global level! Please reach out!

    +

    Sam: Fixed vs growth mindset.

    +

    Rein: Diversity is not just good for ethical reasons, it also makes your organization more competent.

    +

    Janelle: Celebrating beautiful.

    +

    Rehema: A fundamental right to freedom.

    +

    Transcript:

    +

    ASTRID:  Hello everybody and welcome to Episode 63 of Greater Than Code. I’m Astrid Countee and I’m here with my friend, Rein Henrichs.

    +

    REIN:  Good morning, or whatever time it is when you’re listening to this. I am here with my friend, the colorfully-haired Jessica Kerr.

    +

    JESSICA:  Good morning! And I am thrilled to be here today with Sam Livingston-Gray!

    +

    SAM:  Woohoo! And I’m happy to introduce the prodigal Janelle Klein.

    +

    JANELLE:  And we’re here today with Rehema Wachira. And she doesn’t fit the typical profile of a software developer. She is a self-taught coder from Nairobi, Kenya whose passionate about making a positive impact on people’s lives through technology. She’s a graduate of the University of Virginia. And she first started her career working in advertising. And then after learning about product development, becoming intrigued with the complexities of coding, she began teaching herself the basics of Python. So, with only two months of coding experience under her belt, she applied and was accepted to Andela’s development program where she now creates code that’s used by companies every day. Welcome.

    +

    REHEMA:  Thank you. Thank you so much. I’m really happy to be here.

    +

    JANELLE:  We’re excited to have you here, too. So, the way we usually start this is by asking a question about your superhero powers. So, what would you say your superpower is and how did you acquire it?

    +

    REHEMA:  Hey, that’s an interesting question. I think for me, it would have to be empathy. I think. My mom used to work for nonprofits for most of her career. The majority of her career, actually. And she has a big heart. She cares a lot. And I think she would bring that home and that’s something that I would witness and sort of absorb as well. And it was really important and it made me good at my job when I was working at nonprofits and when I worked in advertising and communications.

    +

    I wasn’t so sure how it would apply to being a developer but I actually more and more am realizing just how important it is to have that empathy to see people not just the way you see them but to be able to see people the way they see themselves. And to be able to understand things from their perspective, really putting yourself in their shoes. It’s important just for everyday life but also when we’re building things. To me, code is a tool but it’s also always an expression of who you are and the way that you think in the way that you write the code. And so, being able to put yourself in a potentially user’s perspective I think adds more to the thing that you create at the end of the day. So yeah, I like thinking about empathy not just as a personality trait but as an actually really useful took for navigating the world, especially as it becomes more complex.

    +

    REIN:  Superheroes also usually have an origin story. Can we talk about origin stories in tech for a minute? I think that you said that you don’t have what you would consider to be a typical origin story for a developer. So, in my mind that’s the, for my generation it was you grew up with an Apple2e in your parents’ basement and you wrote BASIC when you were five or something. What was your origin story like? And how do you think that has given you maybe a different perspective than other people who are in the industry?

    +

    REHEMA:  Well to begin with, I’ve never had a basement. [Laughs] That’s not something that we have in Kenya.

    +

    SAM:  Well done.

    +

    [Laughter]

    +

    REHEMA:  But yeah. I always thought that I would do something with my life related to helping people and communities. Again, I think stemming from what my mom did. And I was one of those kids for whom school wasn’t that difficult. It was fun. I enjoyed learning things, especially the humanities and languages and all that good stuff. Good at the sciences as well but really terrible at math. And I just didn’t think that I was a logical thinker. This thing that we tell ourselves and we tell kids from a very early age of like, if you’re good with languages and humanities, then that’s how you think and that’s where you should stay. And then if you’re good at maths and science, then you’re logical and that’s a completely different thing. And we sort of put people into these different categories from very early on. So, I always thought I was going the humanities route. And even when I went to college, I studied political and social thought. My major literally was called Thought, something that my parents were not too happy about but they got over it. But essentially that was the way I was thinking about my life and my career, was in terms of how I help people and thinking about systems and the human systems that we build, really. Society, culture, all that good stuff.

    +

    But it wasn’t until I was working for a company, a telecommunications company in Kenya, the biggest one in East Africa, and they created a mobile money payment solution that is pretty revolutionary (and I can talk more about that because it’s really cool), way before you guys had Apple Pay and all that stuff. We’ve been sending and paying for things using our mobile phones for the last 10 years. So, I was just fascinated by the impact that that had, just seeing what it could do for communities for individuals and for financial inclusion. It just, it blew my mind. And I was like, “Okay. So, if you can create these things, if people can do this, then why can’t I also be one of the people that creates things.” I wanted to be more involved in actually shaping solutions and creating them.

    +

    So, I was interested in product, actually. I wanted to start building products. And I figure if I know a little bit of code, maybe that can help me be a better product manager. And when I started playing around in Codecademy and all that stuff, I realized, “Hey, wait. I actually really enjoy this. I’m writing stuff and things are happening.” [Chuckles] And that feeling really got me excited. And I just continued with that, trying to figure out how I could get better at it. And a short while later, found Andela and applied to join their program and yeah, and now here I am as a developer. And sometimes when I say even as introduction to other people like, “I’m a software developer,” it still sounds a bit funny to my own ears. But it’s cool. [Laughs]

    +

    SAM:  You said something interesting just now which was that you thought that learning to code could help you be a better product manager. And it’s funny how many programmers I don’t hear say things like, “You know, I thought that learning more about the humanities would make me a better developer.” And I feel like we do, just societally, we do such a tremendous disservice to kids who are good at math by not making them study more of the humanities. Because there’s so much out there that we could benefit from.

    +

    REHEMA:  Absolutely. Because at the end of the day, everything that we build is within a particular context, right? Whether business context or social context, we’re putting things out there that other people have to interact with. And if we don’t understand the human systems that affect those, then I think the solutions that we build can never really be true solutions. And it’s so important because I have met people who are so focused on the code and they’re like, “Just give me the specs and I’ll build the thing,” and I’m like, “But there’s a whole world that you have to build for and that your product will live in.” And if we don’t have a sense of what that means and then importance of it, then I think we’re missing out in a big way as developers.

    +

    JESSICA:  Yeah, and that world is full of human systems which are even more complex. I found it interesting in your bio that you enjoy coding because of the complexity of it?

    +

    REHEMA:  Yeah. It struck me as a field where when I started to think about a possible career in terms of getting into this and really looking at it for the long haul, it struck me as a space where I would continuously be learning. And that was really important to me as well, because at some point in some of my previous careers I was looking up the ladder and looking up the chain and thinking, “I don’t feel like excited by what’s in the future.” Like if I try and imagine myself five years down the line as a marketing manager or something like that there were parts of it that really excited me, things that got me into the field in the first place, but I wasn’t super excited about it. But when I think about a possible career as a developer, and not just as a developer but what it could mean as a product manager, as a person who creates things, hopefully also as an entrepreneur, the skillset and the fact that it’s a field that’s changing so often is what I find really exciting about it. And the fact that you also have to do a lot of deep work, a lot of deep thinking to really solve problems, the problems in front of you, that kind of complexity also I think is just really fascinating.

    +

    REIN:  So, when you say complexity, I’d like to maybe explore that for a minute. Because I get the feeling that you may not mean algorithmic complexity or cyclometric, like ‘how many branches there are in you code’ complexity. What do you mean by complexity?

    +

    REHEMA:  Yeah, so you’re absolutely correct. For me, the complexity is in, I always think about things in terms of what can this help solve in terms of a human need. So for me, complexity is in terms of ‘Are we able to build something? Are we able to build a product or a solution that can address things at various layers or various levels of understanding or reach or depth?’ essentially. So, if we’re looking at creating the mobile money solution for instance, in Kenya, if the problem is we need an easier way for people to be able to send money back and forth to each other because we don’t have the right banking systems that make banking accessible to the vast majority of the population, how do we make that happen?

    +

    So, one way of thinking about it is, “Oh, let’s just have this service where I can send money to you, you can send money to me. Done.” But what has happened in Kenya is that it’s gone way beyond that. It’s not just about sending money. It’s also about savings. How do you create a savings culture? How can you use technology to remind people or to prompt people to start planning their finances and thinking through long-term how they’re using their money and where it’s going and how they can better track and monitor it? How are they able to seize opportunities to get loans for small businesses and enterprises? And are we linking that back to financial education?

    +

    So, that’s why I mean by complexities. It’s more in terms of the human complexities that we live in and how we can use tech to address all of those different things. I think as I continue in my learning and in my career and as I continue to get deeper into trying to solve for those different problems, things like algorithms and things like how to optimize different kinds of systems, the nitty-gritty, I think that’ll start to become of more interest to me once I can relate it back to a bigger picture. Does that make sense?

    +

    REIN:  So, the complexity for you comes from the computers, that system interacting with other systems, usually humans, right?

    +

    REHEMA:  Exactly, exactly. Humans and the infrastructures that we create. So again, in the same thread of the financial systems, how do we integrate that back with banks and make sure that they are actually serving people in a way that’s meaningful to people but also useful for them as a business, right? So yeah, for me that’s the area of interest.

    +

    REIN:  Software would be a lot easier if we didn’t have requirements.

    +

    REHEMA:  [Laughs]

    +

    SAM:  Or people.

    +

    REIN:  Or people.

    +

    REHEMA:  Or people. [Laughs] It would also be a lot less fun. [Chuckles]

    +

    SAM:  This is true. So, you talked about creating a savings culture and I find that really interesting that you’re talking about using technology to affect the larger culture in that way. Is that something that you think is just something that you’re personally interested in? Or is that a major value of the culture that you’re in?

    +

    REHEMA:  Yeah, I think a culture of saving is important, and especially so in a country where traditionally banking has not been accessible to the majority of people. So, companies that are in this space and that are trying to create and promote a culture of savings obviously have their own personal interest, which is the more money you put with them, the more money that they make. But I think it also goes much deeper and much larger than that because it does affect people’s ability to pull themselves out of poverty, right? So, in Kenya right now there’s big talk about a growing middle income. And you can definitely see it. Kenya’s a country that’s going through a lot of changes and we’re the biggest economic powerhouse of East Africa. So, there’s a lot of activity happening here. But how do you make sure that that’s a tide that’s raising all boats? So, the way that people have access to and are able to understand and interact with their money is super important, super big part pf that.

    +

    ASTRID:  So Rehema, it almost sounds like your major that you talked about, that social and political thought, is actually…

    +

    REHEMA:  Yeah.

    +

    ASTRID:  The beginning of where you start thinking about these problems as opposed to the side-effect that you hope will happen in the end. And because of that, it looks like what you’re doing, well not just you obviously but other people who you’re working with, is that you’re creating a physical infrastructure by using technology instead of maybe augmenting or changing or even just adding to some other infrastructure that already exists. And that changes the way you ask questions. Do you think that some of what you’re doing can be translated to other systems that are not already set up to think about that stuff first? And how would you suggest somebody start changing the way that they solve these problems?

    +

    REHEMA:  That’s huge, right? So recently, I learned about civic tech as an area that I guess a lot of people and interestingly enough a lot of cities are getting into, at least in the west. So, I met somebody who worked for New York’s, I can’t remember if it was part of… I think it was part of the city’s push to start using data science more effectively, essentially. And they were creating or they were using different maps and applying different algorithms to them to try and figure out as the city grows and as different types of infrastructures pop up in different parts of the city, how do you optimize for the populations that are there? So, if you notice that a whole bunch of high-rises are coming up in one part of the city, then you can figure out if you need more buses. Or do you need to add more libraries or more public amenities? Things like that. So, a very smart way, literally smart as in, you know what I mean [Laughs]. Like a smart city, essentially.

    +

    But thinking about how you build right from the get go instead of using information that may be outdated or anything like that, you essentially have this data constantly at your fingertips. And so, city planners are able to tap into that and look at all this information and be able to make smart goals and smart planning based off of data, which I thought was really interesting. So, there’s lots of different ways in which this is happening all over the world. And even in Kenya, open information type of movements and all of that where we’re keeping better track of what government is doing and what the public sector is doing to empower people.

    +

    REIN:  Can I just mention that the phrase ‘diversity of thought’ has been sort of perverted to mean being able to be a bigot without consequence. But in my mind, this is what ‘diversity of thought’ really means. When someone like you approaches a problem, you may look at it from a way that no one else on your team looks at it. And that gives the whole team a better understanding of the problem.

    +

    REHEMA: Yeah. I think that’s the biggest argument for diversity, because at the end of the day, like I said earlier, what we build is an expression of ourselves. So, if I’m building and I’m thinking about the end user, then essentially I’m just thinking about myself, right? Because that’s the frame of mind in which I understand and interact with the world and that’s what I know best. So, it’s so important to have people from all different walks of life, different experiences. I think the challenge that a lot of companies have is, because this goes right through to hiring, to how the company talks about itself, to the type of people that it attracts. So, its’ one thing to talk the talk and say, “Yes, diversity is important for us,” and I think quite challenging for a lot of companies to actually figure out how to put that into practice. And making sure that as you’re sitting there in an interview with somebody across the table that you can somehow control for people’s biases, right? Because people have them and it’s like, how do you navigate past that? That’s a tricky one.

    +

    SAM:  Yeah. It’s very easy as a company to say “We value diversity,” but it’s a bigger commitment to actually value it with dollars or local currency of choice, right?

    +

    REIN:  [Laughs]

    +

    REHEMA:  Yeah.

    +

    REIN:  The other problem is hiring for diversity and then making everyone think the same way.

    +

    SAM:  Right.

    +

    REHEMA:  Yeah. I think that that’s also really fascinating, because you… I see this a lot in adverts or company profiles, especially in Silicon Valley where the descriptions all kind of tend to sound the same. “We’re super fun. We hang out all the time. We have lots of games and we all drink.” It always… they say they’re hiring for different people but you’re right. The culture always seems to be the same in every environment. So, the question is how do you create a world where within the company, a world where everybody can have their voice and be comfortable.

    +

    Something that I’ve been thinking about a lot that we discuss quite a bit here at Andela is extrovert versus introverts, and how the world is primed and built for extroverts. But how do we make sure that those of us whose energy comes from different places are also served just as well and feel comfortable in that environment?

    +

    JANELLE:  I’ve just been kicking back listening to you and taking all these notes. And there’s this theme that I hear emerging in the references you’re making of continuously taking the problem that you’re looking at and then zooming out and zooming out and zooming out and relating it to that bigger picture. And that bigger picture always comes back to culture. And when you started and talked about your superpower with empathy and you mentioned your mom, I have that in the back of my head. And then I’m thinking about where we went with this discussion to the meaning of diversity and diversity of thought specifically. And what I’ve come to really appreciate in different people is to learn how to see through their eyes and to listen to them and see ‘How is it that you see the world?’. And when you learn how to look at the world through another person’s eyes, that’s where you really get that diversity of thought coming together in synergy.

    +

    And so, the question on my mind that I wanted to ask you is you’ve got this rich culture that comes from your mom and from Kenya and this savings culture and everything that means. And that’s given you a current set of eyes. And so, when you look at the human system around you, what I’d like to ask you is just what are the major patterns that pop out to you? What do you see?

    +

    REHEMA:  Would this be specific to Kenya or just in general?

    +

    JANELLE:  I think contrasting those things. If you think about that upbringing and you look at the things around you, I’m guessing what you see is a lot of dissonance with that culture. Like savings culture and what that means. Here we promote the complete opposite. It’s a spending culture, right? And that contrast alone is very distinctive. And it’s also in that meaning of diversity, right? It all comes together in that human system. And I bet given the things you’ve bene talking about, you see a lot of contrast in that. But it is contrast at the same time, like the smart city movement is very much happening. It’s very much alive here, right? But there’s a lot of contrast to that, too, of people stuck in the weeds in their thinking where you’re like, “Bigger picture. Bigger picture. Bigger picture.” Like an echo.

    +

    REHEMA:  Yeah. So, when I’ve been fortunate enough to travel, I spent a bit of time in the US. And when I contrast these different places that I’ve been in and the different spaces I move through, I think one thing that always strikes me is how to some extent, people are fundamentally looking for the same things. It’s just how they go about actually getting them that tends to be very different, or even how they will talk about how they go about getting them. So, I don’t know. The interesting thing about comparing people in Nairobi specifically to people in for example New York City is there’s a very similar drive towards being active and active in terms of hustling. Like, I need to get to this next thing. I need to get this next gig. I need to push and push and push.

    +

    And I don’t know. It’s interesting how people will describe what they are doing, because here it’s very much like that’s the accepted thing. Whenever people from outside come to visit, they’re always fascinated by the fact that so many developers are doing other things completely unrelated sometimes to actually being developers. You have people who have farms. You have people who are like, raising livestock. You have people who are doing very different things. But here, it’s just part of the culture and the energy of the space. So, it gives the two cities very similar energies in terms of being very almost frenetic and high-speed. But at the end of the day what people are looking for is a sense of independence, a sense of control over their lives and their incomes in many ways. In Nairobi that’s very much geared towards ‘I need to do this because for me, but also because I need to support family’. In places like New York, it’s ‘I need to do this for me because I need to be at a certain level and have a certain level of accomplishment’.

    +

    So, people are sort of going after the same things in what seems to me to be increasingly similar ways, like the gig economy and all that stuff. But the way that they talk about it here, they’ll always try and frame it in terms of “I’m doing this because people need me to do this.” Or people often are the only breadwinners or have come from outside of Nairobi and therefore this is their one big break and if they don’t make it then the world falls apart. So, that’s been interesting to see. I don’t know if I’m really getting on, I’m really touching on what you’re asking in terms of the human systems. I don’t know. I might need to think about that a little bit more.

    +

    ASTRID:  It sounds like what you’re saying Rehema is that they’re doing the same sort of things but in the context of the values of wherever they’re from and what’s going to be rewarded. Is that right?

    +

    REHEMA:  Yeah, yeah. I think so. I think so.

    +

    ASTRID:  Earlier in the conversation you were talking about how people kind of get tracked into different routes, like you’re good at math and science, you’re more humanistic. And some of the things I’ve been thinking about lately are similar and to like, how do you stop making it about those specific traits and more about how people think? And you had also mentioned how the reason why you wanted to pick up more coding skills is because you wanted to be able to make things. And so, I wanted to ask you what you thought about creating and making as something that is more neutral in terms of you’re not really talking about how you’re doing it. And if people can start to think of themselves as wanting to be creators and if that can help them switch their mindset a little bit and give them more access to maybe something that they weren’t trained to do.

    +

    REHEMA:  Absolutely. That’s something that’s actually quite close to my heart [Laughs] as an area of discussion. So, like I mentioned, growing up school was fun for me. And I think I’m quite lucky for that, because I know for a number of people, it wasn’t. And I think for me it was fun because again I enjoyed learning. I enjoyed the process and act of learning. I did well in my studies and so I got a lot of positive feedback. “You’re smart. You’re clever. You’re intelligent. Good job.” That all fell apart once I got to college, actually. I started a bit late. I think I joined about a week after everybody else did. And I had put myself in this, I guess it was an accelerated intermediate Spanish class or something like that. I’d only done Spanish for three months before then, but I somehow tested into it. And I was excited. I loved learning languages, which probably also explains why I love being a developer. But I was excited and I joined the class and I realized that it was a week late but I figured, “Oh, I’ll just catch up.” And I never did. It was a four-credit class and I think I got a D by the end of it. So, this is first semester, first year, new country, university and all of that. And I was failing that class that had the most credits.

    +

    I think that was my first major experience with failure and I completely fell apart. I didn’t know what to do. My whole identity was built around this idea that I am clever, I am an intelligent person. Nothing should be too difficult for me. Failure shouldn’t happen. And I completely fell apart. And it took a while, probably the rest of my college career and a lot of time after that, to realize that essentially what they call the ‘growth mindset’ versus ‘fixed mindset’ of me believing that I was a certain way and it was therefore a fixed amount of intelligence that I had and I had surpassed it when I failed and realized that I had used up my quota of intelligence, so to speak. And that was that. But fortunately, over many sort of almost painful years of trying and failing and trying and failing, I got comfortable with the idea of failure. And reading about growth versus fixed mindsets and seeing people who are a lot more comfortable with experimenting and creating helped me realize that actually, I needed to change the way I think about things.

    +

    And it’s interesting because to me, being a creator, when you’re in the context of development it’s very specific. Like, yes there was nothing there and I built something and now there’s something there for somebody to interact with. But I think it applies to everything. Like, people who cook, people who make music, people who write, people who do haircuts. The idea of being a creator to me matters or integrates with the idea of a growth mindset because essentially what you’re saying is, “I’m going to take a blank page,” so to speak, “and I’m going to put something on it. And I’m going to see where that leads.” And it doesn’t have to be perfect from the get go. And even if it goes wrong, I can always fix it, change it, scrap it, start again, and create something else. So to me, that mindset of being comfortable, being a tinkerer, being comfortable with just playing almost with things and just to see where they lead, has been really important, like shift in my mindset.

    +

    When I started writing code, I was terrified of breaking anything. I always thought that to even begin writing the code I needed to know the exact right way to approach a particular problem. And I would spend hours trying to google and research and figure out, ‘What is the right way?’ before I would even begin. And it took me a lot of unlearning to get past that and to be comfortable making mistakes, essentially. Hopefully none that cost my company anything. [Chuckles] But being comfortable with that frame of mind. And I’m applying it to all different areas of my life. Learning how to play the ukulele, for instance. I’ve always loved music, always wanted to learn how to do something and how to play something. But I was always like, “If I’m not going to be perfect, then why begin?” which is a terrible way to go through life because essentially you never do anything. You never challenge yourself. So yeah, I’m all about thinking about myself and having other people think about themselves as creators.

    +

    REIN:  I think there’s a whole conversation we could have about the value of mistakes, per se. But I just wanted to mention this one neat trick that I learned from Virginia [Set] here, which is that whenever you catch yourself making a statement about who you are that comes from a fixed mindset, like ‘I don’t know how to write JavaScript’ what you do is you tack the word ‘yet’ at the end.

    +

    REHEMA: Mm.

    +

    REIN:  You say “I don’t know how to write JavaScript yet.”

    +

    REHEMA:  Yeah, yeah. I think that’s awesome. Actually, I’m going to start adding that to my mental lingo. [Laughs]

    +

    ASTRID:  I love that story, Rehema, because I feel like there are so many people who when they hear will be nodding and saying, “Oh my god, that’s me. Oh my god, that’s me.” And we don’t hear enough of it because there tends to be a lot of discussion about how amazing you are and how you got to be so amazing and how your amazing is so special that nobody can be amazing like you.

    +

    [Chuckles]

    +

    ASTRID:  And there’s not a lot of discussion about “Yeah, this was hard and I failed. And then I tried and I failed again. And I tried and I failed again.” Even in the “tech failure stories” it’s always like “Yeah, they gave me a hundred million dollars and then that company crashed and burned, but it’s okay because I took a vacation and I thought about things. And then when I came back from climbing that mountain, I realized I could do this other thing.” And that’s really not helpful for most people to try to take that next step forward. So, thank you so much for sharing that.

    +

    REHEMA:  Yeah, no problem. And one place that I really like to go to read stories about people who are still in the weeds and trying to figure that out, especially entrepreneurs, is Indie Hackers. I don’t know if you guys are familiar with that. They have a really good newsletter where people ask different questions but also a lot of people will just talk about their experiences trying to build something and the mistakes that they made. Which I think yeah, is important to hear that over and over again. And especially back now in my context of being in a developing country. We’re in a position where the majority of our leaders are a generation or two older than the majority of the population that they’re leading.

    +

    And I think the topic of empowerment is a difficult one. Because on one hand, you have a group of leaders who perhaps see things in a very different way and believe in a sort of “I’m going to tell you what to do so you should do it” type of mentality, the traditional teacher/student type of relationship where you don’t really have an opportunity to ask questions or at least in our context, you’re not really supposed to talk back to a teacher and question them or challenge them. And I see that a lot. We see that when we go and do mentoring or tutoring for kids in different schools. And you ask kids a question and everyone will be scared to respond, not because they don’t know the answer but because they haven’t been in an environment where they’re empowered to speak and to have their voices heard and that their thoughts are valid.

    +

    So, letting people know that it’s okay to make mistakes and it’s okay to try and to create and you have some agency in your world I think is such an important mindset to have, not just for us as we build things in our day-to-day lives, but in an entire population actually, of people who will become the next business owners and public leaders and all of that.

    +

    JANELLE: So, there’s no real right answer to this question. What I asked you was essentially ‘What do you see?’ because we were talking about this diversity of thought and perspective. And I wanted to be able to just see the things that stand out to you as a starting point. So, we got Nairobi versus New York City. Two cities, both very high-speed. And you’ve got this similar active drive and hustle, the similar culture in terms of push, push, push toward the next thing. And what you described as the importance of this is the sense of independence and control over your life, of your income, being able to choose your next goal, where you invest your energy, whether it be your money or your time. And at the core of this seems to be the essence of what it means to be a free human being. [Chuckles] And there’s constraints in terms of things that we shackle ourselves down with in terms of culture and shapes.

    +

    And we talked a little bit about identity and how we look at ourselves. And then you mentioned earlier about how technology has this role in shaping culture, in shaping that human system. And so, you’ve connected these things together. So, you’re always going big picture, big picture, big picture, right? And so, I’m wondering then, if these are the patterns you see at a societal level, how do you think technology has helped to shape those two systems similarly and differently?

    +

    REHEMA:  I think one thing that always stands out to me about a difference between the two societies that I’ve moved through, Kenya and the US, one of the things that always strikes me about the US and I think for any foreigner who visits especially if you’re coming from a developed country, is you can see the history of the place. America’s very good at, and has been very good at, telling a very unified story to the outside world, to the international community, about its origin story, going back to superheroes. Its origin story, its ethics, values, the people who made it great, the things that they’ve built. And you’ll see monuments to that and you’ll see all of this massive effort to preserve a particular narrative in the history, right? I know the US last year was having some trouble with that. [Chuckles] But from the outside it’s always seemed very unified. One thing that I struggle with as an African is where to find that at home in terms of where the monuments to the people who’ve made our countries and our continent great, where the monuments to the things that we have built that have stood the test of time.

    +

    So, one thing that Andela’s director, country director of Nigeria, our Nigeria campus, his name is Seni Sulyman, he loves to say “Africa may have missed the industrial revolution but we’re not going to miss the technology one.” And I think that’s the thought that I think is really important for a particular generation of Africans in terms of “How do we build things that will last?” And how do we build things that can become part of that conversation and part of the monuments to what makes this continent important and incredible and amazing? And they don’t have to match what has made the west and what has made America important and amazing. We’re trying to create our own narrative and our own story.

    +

    So, in terms of how technology can bring that about for us, because technology is in many ways such a huge force for democratization (if I’m saying that correctly), it’s an opportunity to really build something that could change the narrative around the entire continent, if that makes sense. So, I guess in some way, it very much ties into why I wanted to be part of Andela and what Andela is all about. It’s essentially founded on the belief that brilliance is evenly distributed but opportunity isn’t. So, how do we create that opportunity? How do we make it accessible? So, we’re about creating an entire network of technologists that will be not only the leaders for Africa but for the world as a whole, to be global technology leaders and creating solutions in a world and a space that is really moving forward in a more inclusive and supportive way.

    +

    So, that’s an area where I’ve seen so far has been a huge difference between the African context and for example the North American one, where there’s a history there and a narrative that continues to empower young people in the US telling them that if you’re going to build something, it’ll impact the world. And that’s very true in Silicon Valley, I think. That’s the narrative in Silicon Valley. But in the US as a whole, you build products for the United States but they impact the world. That’s something that I think we feel very strongly about here now in the African continent, that it’s now our turn to do that. And we’re empowering people to do that. We’re building solutions that may begin locally but will impact the world, essentially. Does that connect? [Laughs]

    +

    JANELLE:  Yeah, I thought that was great. There are so many great things in that of what I ultimately heard you coming to with technology empowers people.

    +

    REHEMA:  Yeah.

    +

    JANELLE:  And lets us have an impact, lets us not be invisible. And our narrative that we push forward as ourselves, this is the foundation of our identity. This is our story. And if you think about who I am, what it comes back to is, what is my story? What is the narrative I’m telling? And whether we’re telling that narrative as an individual, as a team, as a company, as a nation, there’s this echo of the same kind of human system that we’re talking about at all these different levels of abstraction, that bigger picture, bigger picture, bigger picture. That echo. And so, that’s kind of what I hear from you when you jump to these different tangents, is there’s essentially isomorphisms between these different contexts that are associated with identity.

    +

    REHEMA:  Very much so, with identity and the story we tell ourselves about what is possible. Because if our identity is built around the idea that we missed out in this revolution, we missed out on that revolution, we don’t hear or see or tell stories about the things that have made us as the African people uniquely powerful and uniquely fantastic. If we don’t hear enough of those stories, then our idea of what’s possible, what’s in the realm of possibility is therefore very small in comparison to the kinds of stories that in the US, that you are told and that you hear about yourselves as a people.

    +

    So for me, yeah exactly what you’re saying, identity is so important. Because if we continue to push the ideas of what is possible, if we change what the stereotypical developer is supposed to look like and I present myself as a developer and I’m saying “I’m from Kenya, born and bred. I’m female. I changed careers. I’d done all of these different things,” and there’s so many stories here of people who come from such different backgrounds who are creating and building such incredible things, I think that narrative is so important. And that’s why Andela is more than just a company. It’s really a movement, because we’re tapping into that and saying “This is possible. We are here. We are working out of our native countries. I don’t have to leave my home in order to have global impact.” And that’s so important to me.

    +

    JANELLE:  That’s beautiful. Because it basically echoes as a statement of identity “We’re just going to be superheroes. We’re going to choose to be superheroes and let technology empower us to make the world a better place.” That’s the identity statement.

    +

    REHEMA:  Yeah, exactly. [Chuckles]

    +

    JESSICA:  This goes back to something we wanted to talk to you about, which was you told us that sometimes you feel insecure about not having the traditional developer story?

    +

    REHEMA:  Yes, yeah.

    +

    JESSICA:  I love that ‘brilliance is evenly distributed but opportunity isn’t’ in relation to that. Because maybe it’s like we think of developers as having learned to program as children and been doing this their whole lives and they had computers as kids and this is how the grew up, and that’s the traditional getting into programming story. But maybe that’s not where brilliance is distributed. It’s where opportunity is distributed.

    +

    REHEMA:  Precisely. Exactly. [Laughs] You’d be surprised the number of people who started learning how to code on phones here. They saw games or whatnot and they were just like, “Hey, let me just try and figure out how to make a game.” The number of my colleagues who first interacted with computers when they were in high school or once they were in college didn’t even have laptops of their own, borrowed from friends, because they were just, they saw something. They saw somebody write something or they saw a game or they saw a website and they were like, “Hey, I’m really curious about that. Let me figure out how to do this thing.” And now they’re here working for companies like Viacom. They’re working for companies like Facebook. And it’s amazing, right? And I think that every single day that I come to work and I’m working with people and I’m interacting with them, that always come to mind as why it’s so important that we do provide and we do give people access to different kinds of opportunities. Because it’s not always going to come from the most traditional or the most obvious of places. And there’s the whole narrative, I think especially in startups about yeah, they went to university and then they dropped out. And here it’s like, “Well, some people didn’t even have that opportunity to get to university.” but here they are still creating incredible things.

    +

    REIN:  When you think about the global tech community culture, it is extremely anglocentric. And one of the outcomes of that is that work done by people that aren’t in the USA, Europe, especially people in the global south, is erased. We don’t know that it exists unless you go look for it. And even if you do, it can be hard to find. So, I wonder how many of our listeners knew that there was a system for mobile payments in Africa before Apple Pay was a thing. I wonder how many of our listeners knew that Chile in the early 70s had a cybernetic software-based system that managed their global economy that is the basis for a lot of work in cybernetics. It’s led to things like [Kybernetes] today. We don’t know that. If you go search…

    +

    JESSICA:  Wow.

    +

    REIN:   For that project, it’s called Project Cybersyn. If you search for it on Amazon, there are zero results and Amazon things you misspelled something else.

    +

    [Chuckles]

    +

    REIN:  So, this work around the world that’s getting done in various countries that don’t speak English, that aren’t primarily white, is erased. It’s hard to find. And That’s a tragedy as far as I’m concerned. And I’m wondering what we can do about that.

    +

    REHEMA:  Very true. I mean, even when you think about it essentially, to be able to code means to have to learn English. [Chuckles] Essentially.

    +

    SAM:  At least the 50 or so keywords that are used in most programming languages, right?

    +

    REHEMA:  [Laughs] Exactly. But even…

    +

    JESSICA:  But the documentation.

    +

    REHEMA:  Just to read documentation. Exactly, yeah. I was working with a developer from Albania and he was saying to me how when he started off it would take him an incredible amount of time because he had to, when he was looking something up [Chuckles] for every other word that he read, he would have to google that word. So forget just trying to understand documentation, which can be difficult enough in and of itself. He had to understand the language as well. And I never really thought about that because Kenya is predominantly, English is one of our national languages. So, it’s not something that I’d had to think about. And even then, you’d assume that because I’m coming from a country where we do speak a lot of other languages, that that’s something that I would be sensitive to. But it wasn’t until I met someone who was from somewhere where English isn’t even on the menu, he was like, “Yeah, that was actually a really big challenge.” But he’s grateful fro now the ability to learn the language because it’s helping him in other ways in terms of his education and his business opportunities and all fo that. But again…

    +

    SAM:  Thanks, colonialism.

    +

    REHEMA:  [Laughs] Exactly. Very anglocentric world that we’re living in. Yeah, I don’t know how we go about fixing that. I think part of it is telling these stories of people from different places and having their voices heard. The fact that you guys agreed to have me on here, I think that’s incredible because otherwise there isn’t much of an avenue for people from different parts of the world to tell their stories and have them heard on the global platforms. That’s quite tricky. But I do think that the tech world does it better than most though, even having said all of that. Because I think there is, okay with some caveats, I think if you’re working on things that are already deemed interesting by the Silicon Valley set, then yes, you’ll be able to maybe have your voice heard. If you’re working in spaces that are not directly related to the next Uber or the next e-commerce app, if you’re working on things that are more local to your context or even more focused on civic tech, then I think there is still more of a challenge there and we still need to highlight those projects because they’re just as important.

    +

    JESSICA:  Yeah. And that gets back to the empathy of, can you appreciate a solution to a problem that you don’t have?

    +

    REHEMA:  Right. [Laughs] Absolutely, yeah. I think that’s the biggest thing. I’m not entirely sure how that’s something that we can solve until we really appreciate what we were saying earlier about the importance of diversity and the importance of different people’s perspectives. Because at the end of the day, it might not be a problem that you have directly, but I think we should be able to appreciate and try to understand the difficulty that somebody else is having and how that solution then solves that. But yeah, that’s a tricky one. Because I think it means not just being able to imagine having a problem but to imagine how that problem then affects so many other aspects of somebody’s life, right?

    +

    So, I read about, sorry I watched a documentary actually about a coding competition for young girls in different parts of the world. And I think there was a group of girls from an Eastern European country. I don’t remember which one, but if I find it I’ll share it with you guys. And they had a problem where in their town, clean drinking water is very difficult to find. So, what these girls did is they built an app that basically pointed people to all of the wells in the surrounding neighborhoods and would have indicators for the level of cleanliness of the water or like at different times of the day or at different times of the month. I can’t remember. But essentially, a way for people to easily check and see which wells were most appropriate to go get clean drinking water. So, that’s a solution that’s very much tied into that particular area. But you’d also have to understand why, for you to understand how important their solution is, you’d have to understand how lack of access to sanitary drinking water can affect so many other aspects of their lives.

    +

    So, it’s not just about understanding a specific problem but understanding a whole context in which somebody lives. And that takes a lot of mental effort. [Chuckles] And I guess some people would find that to be too much work. But I think hopefully if we continue to tell the stories in a positive and inspiring way, more people would be interested, hopefully. And want to take part in those discussions. Because eventually, there will be some application or some learnings that they can take and bring back to their own context.

    +

    SAM:  I’m really encouraged by that particular example just because it tells me that the tools of programming and creation are accessible enough that they can be picked up and used by people who have such different contexts than somebody in my position does.

    +

    REHEMA:  Yeah. Technology as a tool is incredible, I really think. And so is the internet, which allows us to go and find out all of these things. But not everyone has access to [Laughs] internet easily. Which is again, another challenge. So, seeing stories like that and hearing about people who’ve been able to create solutions in that way is really inspiring but it’s also I feel like another reminder of just how important it is to make sure that these tools are actually more greatly accessible.

    +

    SAM:  Oh yeah. I didn’t mean to imply that we don’t have a lot further to go. But yeah, definitely.

    +

    REHEMA:  Yeah.

    +

    REIN:  We were talking earlier about access to opportunities being unequally distributed. I think in my mind there’s another thing that’s very important that’s also unequally distributed, which is freedom of creative expression. The ability to…

    +

    JESSICA:  Is that the ability to make mistakes?

    +

    REIN:  It’s the ability to create on your own terms without being dictated by other people.

    +

    REHEMA:  Can you give us an example?

    +

    REIN:  Yeah, so… and I wouldn’t be doing my job if I didn’t name-drop a philosopher on one of these shows.

    +

    [Laughter]

    +

    SAM:  Bring it.

    +

    REIN:  John Locke, the inventor of classical liberalism, said that the basic human rights were life, liberty, and ownership of property. Wilhelm von Humboldt a hundred years later said that the basic human rights were freedom of inquiry and freedom of creative expression. And the example he gave is that if a craftsperson makes a piece of art of a sculpture or something like that on their own terms, we generally respect their creative expression. If they were told to make a thing by someone else, if they made it for their boss, we can appreciate the thing they made but not respect the way it was made. So, access to freedom of creative expression is necessary for art and I think it’s necessary for a lot of human growth.

    +

    JANELLE:  I think this was the same thing I was seeing before in the contrast that I brought up freedom. And then Jessica made this funny face like, “What?”

    +

    [Chuckles]

    +

    JANELLE:  And I was sitting there thinking about well, how does this fit in? But it’s this theme that I see repeating with this idea of basic human rights and being able to see all this potential of what could be. And then being able to have the freedom to reach for your dreams and to express creatively. And in order to do that, to not have shackles that hold us from those things, we have to have knowledge distributed. We have to have the opportunity to be able to experience these things, to have the basis of knowledge so that we can participate in that. And once we’re empowered by technology which is awesome because it’s just, we’re empowered by the ability, the things that we learn, by things that are in our mind. They’re not things that we acquire. They’re not materialistic things. It’s the ability to create with our mind, the ability to do free, creative expression. Think about what you can do with software. It’s amazing. It’s like magic. We can create anything we can dream, right?

    +

    And so, if you think about the freedom of creative expression as something that’s core and fundamental to be what it means to be human, and you bring back this contrast in culture of movement, movement, movement. We’re always pushing forward toward the next thing. And then when you look at that system and how technology influences the culture, then you’re like, well what if this was the thing that we all looked at? What if we saw our potential? What if we imagine that we could build anything that we can imagine and we started working together to make that happen? What if we looked at the human system and started with smart cities you brought up? So, that’s sort of the similar theme i’m hearing, is there’s all this potential that we’re wasting because of our culture, essentially. Like barriers in our culture. And what if things like, we could tell our stories and identities and we could accept people for who they were and the way that they saw the world and their unique perspectives that they brought to the table? And you described those things at a team level, an individual level, and then at a national level too, which I thought was really interesting.

    +

    REHEMA:  Yeah. Because I think the world that you’re describing would be utopia, right? And I think that we can get closer to it, inching closer to it, in different ways and with different aspects. But you’re right. I think that’s such a profound way of looking at the whole idea of human potential, and through human potential achieving an incredible almost nationwide or continent-wide potential. I think for the context of the African continent, access to that kind of freedom is something that we have been sorely lacking. And what you’re seeing now is this huge resurgence in music and fashion and food and all of these different things that help to cement and celebrate different aspects of different cultures within these different countries. And it’s so fascinating to see that grow, because I think the more that we celebrate in the things that we are able to do, the more people’s minds open up. And the more they’re able to start thinking beyond what we currently have and think about the opportunities of the future and how they can make the best use of that.

    +

    What’s been really fun for me personally is, so currently Andela is based out of three countries in Africa. We’re in Lagos, Nigeria, Nairobi, Kenya (where I’m based), and Kampala, Uganda. So, we have a lot of exchanges where we’ll meet and hang out with folks from the Lagos office or from the Uganda office and it’s just so fascinating to see and to experience and enjoy everybody’s differences and the cultures. Because they’re all very different. And we all get to interact and share so much. And I think that really adds to and builds to everybody’s sense of what we’re doing and what we’re building might look slightly different in each country but it’s all moving towards the same ideas and goals of opportunity and what can we do and what can we make of this opportunities that we have? What can we build for each other? What can we share with each other to help continue to grow and cement this movement? And I think that’s such a cool, cool way of thinking about it, what freedom can do for lighting a fire essentially, towards achieving such incredible things. That’s so exciting. I hadn’t really thought about it in that way. But that’s really cool.

    +

    JESSICA:  Speaking of really cool, it’s now time for reflections. Who wants to go first?

    +

    ASTRID:  I can go. What I wanted to bring up was what you had said Rehema about you having to unlearn this need to wanting to be perfect or wanting to have the right solution first. Because I think it’s something that happens a lot. I know for me it’s something that still happens to me a lot except it’s more under the radar whereas before it was top of mind. But now it’s, “Why haven’t I done this yet? Oh, because I think I have to make it perfect.” Or I want it to be this way, instead of just starting. And I feel that it’s applicable to actually writing code. But I think it’s also applicable in other aspects of your life where it’s very uncomfortable to be uncomfortable so much and I think it makes you want to retreat back to what you know so that you can at least feel some sense of safety again. And you have to push yourself to take baby steps so that you’re not still in the same place month after month, year after year. So, I thought that was a really great thing to remind everybody about.

    +

    JESSICA: One thing that stood out to me was that Rehema, you said that people outside of the US don’t often get an opportunity like this podcast to speak to people globally. And I’m like, “Whoa, our podcast is global?”

    +

    [Laughter]

    +

    JESSICA:  But, but, but I think you have a great point there and we should seek out guests from all around the world and do this disparate timezone thing some more.

    +

    REHEMA:  Absolutely. There are so many stories out there that are just waiting for a mic. [Chuckles] It would be incredible just to hear from these different people, to hear so many different perspectives. Because it makes our worlds all that much richer for it. But also because there could be real sparks of inspiration from people’s stories and the things that they work with and the things that they’ve created. If you guys could create that kind of a platform, I think that would be incredible because I also think it would be very, very unique.

    +

    JESSICA:  Greater Than Code: The World Tour.

    +

    [Laughter]

    +

    REHEMA:  Do it. [Laughs]

    +

    ASTRID:  I like the sound of that, I really do.

    +

    SAM:  One thing that really stood out for me was Rehema, your story about failing in your first semester of Spanish and you were talking about the fixed versus growth mindset. And that really resonated for me because a lot of the frustration that I feel in life really does come from that place of feeling like I should be good at something from the get go. So, it was a really useful reminder to me and hopefully to our listeners as well that I need to be more gentle with myself, that I need to accept mistakes as being part of the learning process, and how you get good at something is by [chuckles] being bad at something first. And Rein, I’m going to take your reminder to heart to add the word ‘yet’ at the end of my sentences now. So, thank you all.

    +

    REIN:  I’m glad that we as a podcast are thinking about how we can add more diverse voices. I think we do better than most people or most podcasts in the game right now because our focus is on people and because we care about getting diverse viewpoints. But we’re still reaching into a really small pool. And there’s so much more that we could be doing.

    +

    And my other reflection would be that diversity is not just good for ethical reasons. It’s also a way to make your organization more competent. Because you need at least as much variety to solve problems as the variety of problems you have.

    +

    REHEMA:  Absolutely.

    +

    REIN:  And the way that you get that variety as an organization is through diversity of experiences, of viewpoints, of all sort.

    +

    SAM:  And you have more problems than you think you do.

    +

    [Chuckles]

    +

    REIN:  And so, if you want as an organization to solve harder problems, to become more competent, that’s where you should be looking.

    +

    REHEMA:  Absolutely.

    +

    JANELLE:  So, the thing that really struck me that I still got on my mind was right at the end you mentioned fashion. And so I’m thinking “Fashion? Where does fashion come into this?” But you brought up this idea of celebrating culture and celebrating our stories through fashion and how beautiful that was to be able to empower something like fashion. And when I started thinking about who I am and who we are and you start thinking about what matters to us, being able to express my soul, being able to express my art, that essence of creative freedom; and then I’m thinking about fashion and it’s the same kind of thing, right? We have all of our stories and all these things that we build which is the beauty that comes out of us. And that maybe if we just take a step back, that fundamental thing that we can do to influence the culture around us is just celebrating beautiful. And I think that’s ultimately the message I hear you echoing through all of the things that you’re saying when you’re admiring all these different cultures, when you’re admiring all these different people, is to celebrate beautiful.

    +

    REHEMA:  Yeah. I think that’s probably yeah, my reflection as well, my takeaway from this. Because I’m all about opportunity and I believe in it so much but I hadn’t, even I hadn’t thought about it in terms of fundamental right to freedom, which I think is such an incredible way to think about it. Because technology as a tool, like we said, it democratizes. It has so many applications. Like you said, it’s like magic, right? You can create entire worlds with it, which I think is what so many of us love about this. But if we do go slightly more bigger picture and we pull back and we’re looking at people’s fundamental rights to have freedom of thought, freedom of expression, and the ability to create, and the kind of mindset that allows them to see the world around them and want to, and feel like they have the ability to effect change and positive change hopefully on it, then opportunity isn’t something that somebody else has to provide. It becomes something that people are able to take and make for themselves. And that’s the big thing that I’ve taken away from this conversation. Thank you guys for directing that and for bringing that up because I think that’s really cool.

    +

    JESSICA:  Awesome. Rehema, thank you so much for coming on the show.

    +

    REHEMA:  Thank you guys for having me. This has been a blast. [Laughs]

    +

    JESSICA:  As a reminder to our listeners, if you like the show and you want to hear more of it, Greater Than Code is a listener-sponsored show. We are looking for a few really special companies to sponsor episodes but we’re pretty much listener-supported. And you can participate in that. And if you contribute to our Patreon in any amount, even $1 once, you get an invitation to the exclusive Greater Than Code Slack channel, which is my favorite Slack channel because it’s not very high volume and everyone is super nice. And especially, you get access to the overheard channel where I put things that Rein has said without attributing them.

    +

    [Laughter]

    +

    REIN:  Wait, what?

    +

    [Laughter]

    +

    JESSICA:  Go to GreaterThanCode.com to find out more!

    +

     

    +

    This episode was brought to you by @therubyrep of DevReps, LLC. To pledge your support and to join our awesome Slack community, visit patreon.com/greaterthancode.

    +

    To make a one-time donation so that we can continue to bring you more content like this, please do so at paypal.me/devreps. You will also get an invitation to our Slack community this way as well.

    +

    Amazon links may be affiliate links, which means you’re supporting the show when you purchase our recommendations. Thanks!

    +]]>
    + Panelists:

    +

    Astrid Countee | Rein Henrichs | Jessica Kerr |
    +
    Sam Livingston-Gray | Janelle Klein

    +

    Guest Starring:

    +

    Rehema Wachira: @remy_stack | Andela

    +

    Join Our Slack Channel!
    +
    Support us via Patreon!

    +

    Are you Greater Than Code?
    +
    Submit guest blog posts to mandy@greaterthancode.com

    +

    Show Notes:

    +

    01:22 – Rehema’s Superpower: Empathy

    +

    02:53 – Rehema’s “Untypical” Origin Story

    +

    07:20 – Enjoying Coding Because of the Complexity Behind It

    +

    11:21 – Creating a “Culture of Saving”

    +

    14:52 – “Diversity of Thought” and Seeing the World Through Others’ Eyes

    +

    22:20 – Being Creators and Makers

    +

    Indie Hackers

    +

    30:28 – How Technology Empowers People

    +

    38:27 – The Distribution of Brilliance and Opportunity

    +

    47:01 – Freedom of Creative Expression

    +

    Reflections:

    +

    Astrid: Having to unlearn the need of being perfect.

    +

    Jessica: We want to speak to more guests on a global level! Please reach out!

    +

    Sam: Fixed vs growth mindset.

    +

    Rein: Diversity is not just good for ethical reasons, it also makes your organization more competent.

    +

    Janelle: Celebrating beautiful.

    +

    Rehema: A fundamental right to freedom.

    +

    Transcript:

    +

    ASTRID:  Hello everybody and welcome to Episode 63 of Greater Than Code. I’m Astrid Countee and I’m here with my friend, Rein Henrichs.

    +

    REIN:  Good morning, or whatever time it is when you’re listening to this. I am here with my friend, the colorfully-haired Jessica Kerr.

    +

    JESSICA:  Good morning! And I am thrilled to be here today with Sam Livingston-Gray!

    +

    SAM:  ]]> + Panelists:

    +

    Astrid Countee | Rein Henrichs | Jessica Kerr |
    +
    Sam Livingston-Gray | Janelle Klein

    +

    Guest Starring:

    +

    Rehema Wachira: @remy_stack | Andela

    +

    Join Our Slack Channel!
    +
    Support us via Patreon!

    +

    Are you Greater Than Code?
    +
    Submit guest blog posts to mandy@greaterthancode.com

    +

    Show Notes:

    +

    01:22 – Rehema’s Superpower: Empathy

    +

    02:53 – Rehema’s “Untypical” Origin Story

    +

    07:20 – Enjoying Coding Because of the Complexity Behind It

    +

    11:21 – Creating a “Culture of Saving”

    +

    14:52 – “Diversity of Thought” and Seeing the World Through Others’ Eyes

    +

    22:20 – Being Creators and Makers

    +

    Indie Hackers

    +

    30:28 – How Technology Empowers People

    +

    38:27 – The Distribution of Brilliance and Opportunity

    +

    47:01 – Freedom of Creative Expression

    +

    Reflections:

    +

    Astrid: Having to unlearn the need of being perfect.

    +

    Jessica: We want to speak to more guests on a global level! Please reach out!

    +

    Sam: Fixed vs growth mindset.

    +

    Rein: Diversity is not just good for ethical reasons, it also makes your organization more competent.

    +

    Janelle: Celebrating beautiful.

    +

    Rehema: A fundamental right to freedom.

    +

    Transcript:

    +

    ASTRID:  Hello everybody and welcome to Episode 63 of Greater Than Code. I’m Astrid Countee and I’m here with my friend, Rein Henrichs.

    +

    REIN:  Good morning, or whatever time it is when you’re listening to this. I am here with my friend, the colorfully-haired Jessica Kerr.

    +

    JESSICA:  Good morning! And I am thrilled to be here today with Sam Livingston-Gray!

    +

    SAM:  ]]> + + + + clean + No + no + no + 01:00:57 + Mandy Moore + + + 062: The Beauty of Art and Technology with Jamey Hampton + https://www.greaterthancode.com/podcast/062-the-beauty-of-art-and-technology-with-jamey-hampton/ + Wed, 10 Jan 2018 05:00:31 +0000 + Mandy Moore + http://www.greaterthancode.com/?post_type=podcast&p=1100 + + + Panelists:

    +

    Jessica Kerr | Sam Livingston-Gray | Astrid Countee

    +

    Guest Starring:

    +

    Jamey Hampton: @jameybash | jameybash.com | Agrilyst |
    +
    Sugar City Arts Collaborative

    +

    Join Our Slack Channel!
    +
    Support us via Patreon!

    +

    Are you Greater Than Code?
    +
    Submit guest blog posts to mandy@greaterthancode.com

    +

    Show Notes:

    +

    01:22 – Jamey’s Superpower: “The Fharlanghn Sense”

    +

    02:40 – Working in Agriculture

    +

    04:03 – Theories on Automation

    +

    05:56 – Pivoting Into Computer Science and Software Development

    +

    10:35 – Feeling Like You Need to Know Everything

    +

    Stella Report from the SNAFUcatchers Workshop on Coping With Complexity

    +

    15:47 – ‘Zines and Being a ‘Zine Librarian

    +

    27:50 – The Beauty of Art and Technology and Forming Emotional Connections to Things

    +

    Floppy Music DUO – Imperial March

    +

    35:26 – The Death Star => Ethics in Technology and Taking Responsibility/Being Accountable for your Code

    +

    Malcolm Gladwell: The strange tale of the Norden bombsite

    + +

    +

    49:42 – Brilliance and Learning From Others Without Consent

    +

    54:49 – Advice for Channeling Your Own Inner Fharlanghn Sense

    +

    Transcript:

    +

    SAM:  Hello and welcome to Episode 62 of Greater Than Code. I am Sam Livingston-Gray and I am here to introduce my good friend, Jessica Kerr.

    +

    JESSICA:  Good morning. Thank you, Sam. I am excited about this episode of Greater Than Code because this is our first episode wherein we don’t have an extra guest and we get to grill one of our fellow panelists. So, thank you very much to Jamey Hampton for being the first panel target. I mean, guest.

    +

    Jamey is a non-binary adventurer from Buffalo, New York, who wishes they were immortal so they can have time to visit every coffee shop in the world! They’re an artist who turned into a programmer after one too many animation classes that was a Computer Science class in disguise. Currently, they’re working as a professional plant-liker and software engineer for Agrilyst, a data analysis platform for indoor agriculture. They’re also the zine librarian at Sugar City Arts Collaborative and, bet you wouldn’t have guessed this, a permanent panelist on the podcast, Greater Than Code!

    +

    SAM:  Woohoo!

    +

    JESSICA:  Jamey spends most of their free time camping and thinking about Star Wars, sometimes simultaneously. Jamey. So, the other day you came to St. Louis and visited me and it was fun and I learned about your superpower, which is to magically find the best place to go on a given night in a city you’ve never been in.

    +

    JAMEY:  Yes. I call it my Fharlanghn sense where Fharlanghn is the god of travel and roads from Dungeons and Dragons.

    +

    [Laughter]

    +

    JAMEY:  It’s a good superpower to have. It makes me very fun to travel with. So, if anyone ever wants to go on vacation with me, just hit me up.

    +

    JESSICA:  Yeah, if you’re adventurous, I guess. If you don’t like surprises, don’t go with Jamey.

    +

    JAMEY:  That’s true.

    +

    [Chuckles]

    +

    JAMEY:  I’ve thought about it. I’m like, I wish I could offer my superpower as a service…

    +

    JESSICA:  [Laughs]

    +

    JAMEY:  To other people, like have an app.

    +

    SAM:  [Laughs]

    +

    JAMEY:  That’s like me giving people advice on what to do. But I’m worried that if I tried to exploit it in that way, maybe it wouldn’t work the way I want, because it’s kind of fickle.

    +

    JESSICA:  It sounds like you would have to be there.

    +

    JAMEY:  I don’t think I could automate it. I think I would have to have a personal consultation with someone. I could do that. I’m quitting my day job. Hard pivot.

    +

    JESSICA:  [Laughs]

    +

    JAMEY:  Just kidding. I love working at Agrilyst. I like plants. And I like working with plants. And I like working with farmers and growers because they’re very interesting.

    +

    JESSICA:  I’m curious. So, I used to work at an agriculture-related company, too. And one thing I observed about the growers in that particular very corn-dominated agriculture segment is they’re all white males. Is that true in your customer base?

    +

    JAMEY:  That’s a little bit true. Agrilyst is actually, the founder of our company, her name is Allison. She’s the CEO, Allison Kopf, and she’s awesome. And she used to be a grower. She was an agronomist for an indoor farm and she actually did very similar to what I was just saying about my superpower where she was like, wow, not every farm can afford a me to have a personal agronomist to do this for them. So, what if I created myself as a service? And [chuckles] that’s kind of how Agrilyst happened. And so, she had this whole idea for how you could do the kind of management that she did with software. And I think that’s really cool. But also, the reason I brought it up is because she is a minority, for sure, in the agriculture industry. So, it’s an honor to work with her.

    +

    JESSICA:  Sweet. So, she is also in the process of automating herself.

    +

    JAMEY:  Yeah. It’s going well. [Laughs] Now every farm can have an Allison. It must be nice to be so important. I like that.

    +

    JESSICA:  Ah, that’s an interesting point. But the part about whether we’re important, that’s our decision, right? Is my work worth automating and spreading?

    +

    SAM:  You have to have the ability to do so as well, right?

    +

    JAMEY:  Yeah, I think…

    +

    JESSICA:  Yeah, not everything works.

    +

    JAMEY:  Some things need the personal touch, I think. Automation. There’s a lot of discussion about automation and what’s going to get automated. And we’re not going to have people doing jobs. I remember the first time I ever thought about that question. I used to work… when I was in high school I worked at a TV studio and I was really, really into it. And we got to tour a local news TV station one time. And I was so excited. And so, we show up there and we met the newscasters and it was super cool. And we watched as they were doing one of the news broadcasts and they had these really cool cameras that were on these robotic tripods and they moved around the studio on their own and focused on different things. And we were like, “These are so cool! These are amazing. We wish we had these in our studio.” And my boss was like, “I’m not saying that they’re not cool. But think about this. Because this is doing your job to the point where they don’t need you to do your job anymore.” And I was like, “Oh.” And that was the moment I first thought about that.

    +

    SAM:  [Laughs] Right.

    +

    JESSICA:  We think of… your job was to move the camera, but there’s so much of your job is deciding how and where to move the camera.

    +

    JAMEY:  That’s true.

    +

    SAM:  And somebody still does need to at least punch a button to tell it which move to make. But yeah, maybe you go from three camera operators to one.

    +

    JESSICA:  Or three and you just do more camera movement.

    +

    JAMEY:  That’s true. It freaked me out at the time because I was planning on going into TV production for my career at that point. And I was like, “Oh, it’s going to be so hard to find a job in TV production,” which was true. And it’s not what I do now. So… [Laughs]

    +

    JESSICA:  Yeah, so tell us about how you made that switch.

    +

    JAMEY:  I went to school for digital art, which was the closest that I had to film and TV production at the school that I went to. And because it wasn’t an actual film and TV production major, I took a lot of other miscellaneous art classes. They were basically like, “Take animation.” I’m like, “I don’t want to take animation. I don’t want to be an animator.” And they’re like, “Well just take one. One is required. And then if you hate it, you don’t have to take any more, ever.” So, I took some graphic design classes and I took some animation classes and some game design classes. And I found that specifically in animation and game design, there was a lot of actual strict writing code involved. [Chuckles] I learned ActionScript at that point. And everyone else in all of my classes was like, “This sucks. Why do I have to do this? This isn’t art. This is math. It’s stupid.”

    +

    SAM:  [Laughs] Wait, there’s a difference?

    +

    JAMEY:  [Laughs] Some people think so. But so, I was like, “This is great. I love writing ActionScript.” And everyone else seems to hate it, which makes me special for liking it, I guess. At least, in my digital art classes. So, I started studying computer science. And I got a minor in computer science. And then I decided that’s what I actually wanted to do instead of trying to move to the big city and make my big break or whatever I would have had to do to go into film production.

    +

    SAM:  So, I really want to ask you about that. But first, I have to mention that we have a surprise bonus panelist. Astrid Countee has just joined us.

    +

    JESSICA:  Yay.

    +

    SAM:  Welcome, Astrid.

    +

    JESSICA:  Thank you for coming.

    +

    JAMEY:  We’re glad you’re here.

    +

    ASTRID:  Yeah, I had to hear all about you, Jamey.

    +

    JAMEY:  That’s a lot of fresh [inaudible]. Sorry.

    +

    ASTRID:  [Laughs]

    +

    SAM:  So yeah, I had it on my list to ask you how you got into tech. And so, it sounds like you sort of discovered a love for it during college. What happened after you graduated? How’d you get your first tech job?

    +

    JAMEY:  I found my first tech job on Craigslist. That’s a true story. And it was this tiny startup, like locally to me, that did QR code generation and text message marketing using it.

    +

    SAM:  Oh yeah, I’ve seen one of those.

    +

    JAMEY:  I was the only developer. I learned Ruby on Rails while I was working there. So, they hired me. They were paying me $10 an hour to basically teach myself Ruby on Rails to the point where I was capable of running this software by myself. And I worked there as the only developer until essentially they ran out of money to pay me and they started cutting my hours. And I found another job at that point. But it was really, really interesting being the only developer at my first tech job because I did a little bit of mentorship because one of the owners is a very talented developer. He just wasn’t writing code for this project. So, he was there to answer some of my questions sometimes, although this was kind of his side-gig. But I learned a lot from him because he was really brilliant. But I worked for about a year on a codebase that I was the only person who touched, which was really interesting. Because I knew how everything worked and that is the last time I’ve ever worked on a project…

    +

    [Laughter]

    +

    JAMEY:  Where I knew how every single piece worked.

    +

    SAM:  Yeah.

    +

    JESSICA:  Yeah.

    +

    JAMEY:  I was the one who built everything. That’s not true, because it did work before I joined. But I touched everything in that year and I updated everything in that year. But also, then if something breaks, I didn’t learn that, “Oh, who broke this?” It was always me.

    +

    [Laughter]

    +

    JAMEY:  If something was great, I could pat myself on the back. And if something was broken, I could blame myself because there was nobody else. [Chuckles]

    +

    ASTRID:  I once went to a talk with somebody who was in a similar position where they are the only developer. It was a Rails app. And they had done it for, I think at that point, three or four years.

    +

    JAMEY:  Wow.

    +

    ASTRID:  And the talk was titled “Galapagos Rails” and they were talking about like…

    +

    SAM:  [Laughs]

    +

    ASTRID:  When you’re the only one and it’s only you and everything that breaks is your fault and you have to just figure stuff out. And how it made him into a better developer but that it also made him had way less patience for people who don’t fix their own problems.

    +

    SAM:  [Laughs] Yeah, because I guess in one year you could potentially make a bunch of problems and then leave and then let somebody else deal with them, or at least some of the bigger problems that you made, you could leave to somebody else. But in three years, you’re really going to have your face rubbed in it, huh?

    +

    ASTRID:  [Laughs] Yeah, yeah. He talked about that, about the really lonely nights where it’s all broken and you just can’t do it anymore. And you have to come back the next day because the whole company is depending on you.

    +

    JESSICA:  Wow.

    +

    ASTRID:  So, do you think it changed anything about your attitude about being a developer, Jamey? Like, having to do it by yourself?

    +

    JAMEY:  Yeah, I do. I think the hardest thing about going from being the only person to working with other people, and in fairness I’ve never worked at a big company. I’ve never worked on anything with more than a handful of developers, really. My next company after that, at our peak, there were about 10 of us. And at Agrilyst right now there’s, at our peak, there were probably five or six people touching the codebase. But even just from that jump from one to a few, the hardest thing was that I feel guilt about not understanding how something works. And if someone’s like, “Hey, do you know how our application does this?” and I have to be like, “No, I didn’t write that and I’ve never looked at it,” I feel guilt about saying that. I feel like I should know everything. And so, that’s kind of hard. And I still feel that way a little bit. I recognize that it’s kind of silly and that it’s reasonable not to know everything.

    +

    JESSICA:  It’s more than reasonable.

    +

    JAMEY:  [Chuckles]

    +

    JESSICA:  It is literally impossible to know everything. And if you try to know everything, you won’t get anything done. These systems scale bigger than our heads. Actually, there’s a paper on this in the [inaudible] report. It talks about our software systems are sufficiently complex that every model is always incomplete and out of date.

    +

    [Chuckles]

    +

    JESSICA:  The best we can do is collectively have enough accuracy over enough of the system to be able to keep it running and change it.

    +

    JAMEY:  I would agree with that. And I think the other thing that I got from being the only person is that a sense of, “Well, but I’ll figure it out,” because I was in a position where I had to figure it out. There was no other option. And so, that was kind of empowering. Because I remember, and that was my first job and I was very new. And there were a lot of times where I was like, “This is impossible. I don’t know how to do this. I can’t pawn it off on anyone else. [Chuckles] I just got to do it.” And every time I started a new big feature I’d be like, “This is impossible. I’m never going to be able to get this to work.” And somehow, I always did get it to work eventually. I’d have to learn new stuff. And I’d have to figure it out. But I did it. And so, after this cycle happened a few times, I started to be like, “Okay. I’m feeling that feeling where it feels like it’s impossible. But the last six or eight times I said that, it was possible. So maybe, that feeling is wrong.”

    +

    JESSICA:  So, one of those things that you learned at that first job where there wasn’t really anybody else was that you could figure it out?

    +

    JAMEY:  Definitely.

    +

    JESSICA:  And it is. [Sighs] I still feel that every day. I have this urge to understand the whole system. And I just have to let it go because if I try to keep up, it’s changing so fast and there are six other devs working on it. It changes so fast that if I tried to just keep up with what’s going on, I don’t have time to do anything. So, I’ve had to force myself to narrow my focus, not know how most of the backend works, and just move forward on relative frontend stuff.

    +

    JAMEY:  That makes sense to me. I think the two things are related. Because if you have confidence that you can figure it out if and when you need to, then you can let it go for now.

    +

    SAM:  Yeah.

    +

    JESSICA:  That’s a good point, yeah.

    +

    SAM:  Yeah, my strategy for that is to try to leave the code in a legible enough state that when I come back to it, some way down the road, that I’m confident that I can pick it back up again. Or whoever else touches it can pick it back up. And that’s why refactoring is important, kids.

    +

    [Laughter]

    +

    JAMEY:  Code politeness.

    +

    SAM:  [Laughs]

    +

    JESSICA:  Lately I find that the limiting resource is based in my head. So, I’ve become really stingy with what I keep in my head and started writing more stuff down and letting go of it.

    +

    JAMEY:  I write everything down. And I write it all down on paper. Everything has to go on paper. It’s like I don’t even know something until I write it down on paper. Because I can type without thinking about what I’m writing or reading what I type. [Chuckles] But I can’t do that with paper.

    +

    SAM:  Right. Well, the trade-off is you can search typed stuff easier. But writing it down with your hands on paper helps cement it more firmly in your brain.

    +

    JAMEY:  Yeah. A lot of times I don’t even go back and read the stuff I wrote. But just having written it down is so helpful.

    +

    ASTRID:  I’m totally like that. It’s like by writing it, now it’s in my brain so I don’t need it.

    +

    JESSICA:  Yeah. It’s almost like that. That puts it in a more built-in form of memory instead of some active memory that I feel like I’m expending RAM to remember this, until I write it down.

    +

    JAMEY:  I like that.

    +

    JESSICA:  Like deeper storage or something.

    +

    JAMEY:  I didn’t know you were a droid. But now I know.

    +

    [Laughter]

    +

    SAM:  Yeah, actually I think possibly a better metaphor would be registers in the CPU for working memory. Because I think most people have seven plus or minus two slots for holding onto things in their head.

    +

    JESSICA:  Yeah. Today I feel like I have three.

    +

    [Chuckles]

    +

    SAM:  That’s my usual.

    +

    [Chuckles]

    +

    ASTRID:  So Jamey, you’re a librarian. Can you tell us about that?

    +

    JAMEY:  I am. I get a little nervous about using the word librarian sometimes because there are actual librarians that had to study and learn a lot of things to be a professional and that is not what I do.

    +

    ASTRID:  Well, was is it you do that they’re not doing, or that you’re not doing that they are doing?

    +

    JAMEY:  I don’t know what they’re doing. I feel like they’re doing magic and I’m doing, I don’t know, volunteer work. But I work at a local collaborative art space called Sugar City and we have the zine library that people can donate zines to. And I take care of them and I keep them nice on the wall and I put them in the database. And I meet people who want to donate to us and I get zines from them. I take in donations from the mail and I keep track of all of it. And I love all the zines in our library and I take care of them lovingly. So, if people read them and they get ripped, I fix them.

    +

    ASTRID:  What kind of zines are they?

    +

    JAMEY:  We have any/every kind of zine you can imagine, because we take any kind of donations that anyone wants to give. So, we’ll often get someone donating their entire library because they’re like, “I’m moving,” and, “I don’t collect these anymore,” whatever.

    +

    SAM:  Wow.

    +

    JAMEY:  So, we’ll get a whole box of art zines or queer zines from the 90’s, which is cool. We have a ton of anarchist political zines because we’ll get full collections of those. So, it’s really cool. And then we put them on the wall. There’s no order or anything. So, you just have to browse. We do have a list of what we own and people can come in and read zines. And it’s very exciting and cool. And I run zine fairs where people can sell zines.

    +

    JESSICA:  Define zine.

    +

    JAMEY:  A zine, well it’s short for a magazine. This is like a 90’s thing that’s… I feel like it was very popular then and then it got less popular and now it’s research, which I’m really excited about. I feel like zines are very popular again. But it’s basically self-published magazines.

    +

    SAM:  So, I’m guessing something like something that a person would type up or draw and then take down to Kinko’s and make 20 copies of?

    +

    JAMEY:  A lot of them are like that. There as some that are a little bit more well-put-together than that. But that’s what I like so much about zines, is that anyone can do it. If you want to go big and do this whole production and do bookbinding and stuff, I know people who do that and it’s really cool. But if you don’t want to do that or you don’t know how to do that, or you don’t have the time or the skill, you can still do zines. There’s really no minimum skill required. If you have an idea that you want to put on paper, you can put it on paper and make it. And I love all zines. Some of my favorite zines are just these crappy Kinko’s copies that you can barely read. But the content of them is so important that I’m like, “Yes! I’m so glad that I have this on paper.” And it’s so different from the internet in some ways. Because the internet also has that extremely low barrier of entry. You don’t have to have any measurable skill in anything to go on the internet and post something. So in that way, it’s similar. But in every other conceivable way, it’s different.

    +

    [Chuckles]

    +

    SAM:  Yeah, it’s funny. You were talking about how they were really popular in the 90’s and then less so and then they experienced a resurgence. And being the sort of nerd that I am, I want to correlate that with a technical story about how in the 90’s publishing to the web kind of sucked. And then we got sites like LiveJournal and then later Tumblr and somewhere along the way WordPress. But that doesn’t really account for their recent resurgence. And maybe I’m totally off-base. What do you think? Why did they come back? Why did they go away?

    +

    JAMEY:  I think that they went away because people were like, “Oh, we can use the internet for this, but better.” I would agree with that. I’m not sure why they came back. I was doing zines in 2010-ish and people were making fun of me. And now, half the artists I know locally do zines. And so somewhere in between there it’s become a thing.

    +

    SAM:  Is the answer hipsters?

    +

    JAMEY:  I don’t think the answer is hipsters.

    +

    SAM:  [Laughs]

    +

    JAMEY:  I think if anything, the answer is like the punk scene. And I think the punk scene has, not that like… I’m not accusing punk of being dead at any point. But I think the punk scene has been more culturally relevant lately because of the political climate. I think that’s part of it. I think there’s been a nostalgia factor. Not just to, “Oh, remember when we had zines?” specifically, because I think some of these people are doing zines for the first time now. But like, the idea of holding something in your hand is very attractive to me and very different from the internet.

    +

    One of my favorite things about zines is that they travel organically and they can’t be censored or searched. So, they can’t be censored is kind of obvious. You make them yourself and you hand them out to people and nobody can stop you from doing that, which is cool. But I also think that you get very personal stories in zines that you wouldn’t get on the internet, because you have a lot more control in some ways about who gets that story. You can control who you pass these zines to. You can make 20 and then never make them again. And now it’s out there and maybe it was cathartic for you to do. And maybe you shared it with someone who really needed to be shared with, but nobody can go on Google and be like, ‘Jamey Hampton this, this, and this’, and get these personal stories that I’ve written in zines. Because they’re just not on the Internet in that way.

    +

    JESSICA:  So, you’re sharing your story and you have some control over who sees it but not full control. You don’t know where all those zines will end up but you have some idea how many. And it’s more localized?

    +

    JAMEY:  I like sending zines through the mail. Someone recently asked me if I would put my zines on Etsy and I was like, “No.” And they’re like, “Well, can I buy one?” And I was like, “Yes.” PayPal me money and I’ll mail it to you.

    +

    SAM:  [Laughs]

    +

    JAMEY:  But I’m not going to put it on Etsy. And I think that the reason that I’m against… I’m not against Etsy in theory for other people, but zines used to be like you would find an address on the back of another zine and you would mail them a dollar through the postal service. And they would mail you something hopefully, or they would steal your dollar. I don’t know. Hopefully they’ll mail you something. I don’t steal people’s dollars. I do mail them out. People are like, “Well, that’s kind of sketchy.” I’m like, “Well, you know what? It is a little sketchy but that’s how we’re doing it. So…” [Chuckles]

    +

    JESSICA:  Your two dollars are not PayPal-insured.

    +

    JAMEY:  [Chuckles]

    +

    SAM:  Yeah, so back in the 90’s I actually had a physical copy of a book that think was called ‘Weird Stuff by Mail’. And if I remember correctly, it was actually written by the same person who did the whole ‘Church of the SubGenius’ thing.

    +

    JAMEY:  Awesome.

    +

    SAM:  It was a printed book. So, by the time I got it, some of the stuff was already obsolete. But it was a list of just places that you could mail a couple of bucks and get back random, weird shit.

    +

    JAMEY:  I love that. I want to get that book and mail to people and see if any of them still exists.

    +

    SAM:  [Laughs] Right. Well, good luck finding the book. I’m sure it’s out of print. 

    +

    JAMEY:  Even the book doesn’t exist. It’s an enigma. Out of print is also another thing I think about with zines. Because a lot of them are really low printing numbers and I have zines. I got a zine when I was in France and it was four out of 15 on the back. And I was like, “15 copies of this exist.” And in France. And somehow I had one in Buffalo. Just the sheer randomness of the universe that put this zines into my possession. I love that.

    +

    ASTRID:  I also think, it seems to have something to do with art. The whole it started and then it moved to the internet and then now it’s coming back again because… I was just at the art museum this past week over the holiday break which was awesome, because I forgot how much I love going to art museums, because I’m always at science museums because I love science. But when you go to the art museums and you realize some things you just can’t experience the same unless you are holding, touching it, looking at it in person. It’s just different. Especially because part of the purpose of things that are creative and made to be artfully done are that you want to experience something. You can’t just always experience it online in the same way.

    +

    And I kind of feel like things that first moved to the internet like blogging, when that first moved there, it was a small community. It was like you could actually talk to people. And then it got to a place where everybody was online so, it’s like you’re shouting in a crowded room. It’s not the same intimate personal feeling, which is part of the reason why I think there’s starting to be a resurgence of the more tactile experience of things. And then there’s people like me. I love to buy Kindle books because I have a Kindle. It’s so easy to read that way. But then books that I really want or things I want to read again, I want the real book, because I want to touch it and smell the pages. And I think that’s happening with a lot of things.

    +

    JAMEY:  I’m a little bit materialist, too. I used to be very self-conscious about it. I wanted to be like, “I’m not materialistic.”

    +

    ASTRID:  Okay. [Inaudible]

    +

    JAMEY:  But I kind of am. And it’s because I feel safe when I physically surround myself with things that I really love.

    +

    ASTRID:  Mmhmm.

    +

    JAMEY:  And so, the idea of I really love this book and I want to put it on my bookshelf so it’s there is comforting to me.

    +

    ASTRID:  Yeah. It’s like when you see sci-fi movies that are supposed to be set in the near future. And everything is very sterile and there’s no personal or clutter-y because everything is just perfect, it feels so lonely. It doesn’t feel like a life you want to have.

    +

    JESSICA:  Yeah. There’s a quantity of information here, too, just like with our programming systems. You can’t read all the blogs but you can read all of the zines that are in your hand.

    +

    JAMEY:  At first I got a little overwhelmed by the fact that things were so limited edition. I was like, “There are so many that I’m never going to see.” And I’m like, “I mean, true. But there’s also so many that I am going to see that other people aren’t going to see. And I can share them, the ones I like.” I also collect cassette tapes from local bands and stuff, because I just really like things that other people made that I can hold and read and listen to and be like, “Somebody spent time doing this.” And they made creative decisions about how this is going to be. I listened to a cassette tape recently that was literally just static-y noise with beeps.

    +

    SAM:  [Chuckles]

    +

    JAMEY:  And I loved it so much, because I imagined the person who made it sitting there and changing the frequency of the beeps and being like, “No, this is wrong,” and then changing them and be like, “Yes. This is it. This is what’s going on the tape.”

    +

    SAM:  [Laughs]

    +

    JAMEY:  And I thought about, what feeling were they having that they were trying to evoke in me? It’s probably not the same feeling I’m actually feeling. But this idea of putting something together and being like, “Yes. This is it. This is the feeling and now I’m going to give it to someone else and see what happens.” That’s what art is to me. And it just makes me really happy. I feel like I have a connection with whoever this was that put the beeps on the tape.

    +

    JESSICA:  Yeah, that’s beautiful. And we are physical beings, so we do have a connection to physical objects that the interwebs can’t satisfy. You talked about the beauty of this art that’s created by someone and passed down. Do you find any beauty like that in your work?

    +

    JAMEY:  I think about code and art a lot. And I think the beauty of a lot of code is what it does. We talk about beautiful code and beautiful code is nice. I enjoy it. Aesthetically, it’s good to work with. But in essence, when you’re writing code, you’re not creating code to give to someone. You’re creating a program to give to someone. But I’ve thought some about playing with it. I had this idea. This is an art exhibit idea that I’ve had for a while and I haven’t done yet. But I’m like, what if I wrote some little applets in JavaScript and I wrote them normal and tested them, made sure they worked. And then I typed them out on a typewriter and framed them.

    +

    SAM:  [Laughs]

    +

    JAMEY:  Because [chuckles] I think it’s really funny to present things that are useful in a context where they are useless.

    +

    [Laughter]

    +

    JESSICA:  Yeah. You can get code embroidered, right?

    +

    SAM:  Mmhmm.

    +

    JAMEY:  I cross-stitched a QR code, once.

    +

    JESSICA:  Oh, cool. Wow!

    +

    SAM:  I actually saw something like that on Twitter yesterday.

    +

    JAMEY:  I saw something like that recently, too. But I used to do urban exploration. It was my big thing. And I ran a blog about urban exploration. And I had a backpack that I took with me. And so, I cross-stitched a QR code to my blog and put it on my backpack. [Chuckles]

    +

    SAM:  [Laughs] Nice.

    +

    JESSICA:  Oh, you just said you used to do urban exploration. And you didn’t tell us about that when we asked where your superpower came from?

    +

    [Laughter]

    +

    JESSICA:  It does seem like…

    +

    JAMEY:  It does seem related.

    +

    JESSICA:  Doing urban exploration would enhance your, what did you call it? Far-fig-newgan? No.

    +

    [Laughter]

    +

    JAMEY:  My Fharlanghn sense.

    +

    ASTRID:  So, Jamey when you were just talking about the beauty in code, it sort of made me think about something, this book I had to read when I was doing anthropology graduate study. And it was this book about why we buy. And there was this anthropologist who would watch people in the supermarket and see what they purchased. And some of the people, he would go home and see how they distributed their food items. And there was this interesting that he noticed where some people would purchase something, especially parents, and let’s say like a box of goldfish crackers. And they would go home and they would take it out of the box and they would put it into other little baggies or something for their kids. And he talked about how functionally, that doesn’t really do anything. But that it gave this impression that these are not the brand crackers. Like, these are mom and dad’s crackers for you. It created a connection to it that was beyond what it was purchased. It was about this function of somebody putting the time to put this into a small enough package for you to have so now it’s specialized for you.

    +

    And that might be a big leap, but it just made me think about how you were saying it’s not about… you’re not making code for someone. You’re making this program, but that’s what programs do. They have some sort of thing that they are supposed to complete or finish or do. And it’s almost like it’s a similar concept where it’s not about the thing. It’s about how well that thing was made, who it could have been made for, and how that affects someone, and what that could mean. It’s more abstract but when something is well-built and you’re using it, you feel that as a user. You feel like someone thought about what I was going to do. Someone thought about this choice. Someone gave me an option that I’ll always have. And it means something. And it reminded me of that same scenario where he noticed that it’s not really… it’s a strange thing to do functionally, to take something out of a box and put it in another box basically, but it’s being done to create a connection.

    +

    JAMEY:  I think that how we feel about things emotionally changes the meaning of them really profoundly, too, in the way that we form emotional connections to things. When I was talking about how I feel like I’m kind of materialistic, I’ve forgiven myself for it, I guess, because I form these really intense connections to things I own. But it’s not because like, “Oh, I have this valuable thing.” It’s like, “Somebody gave me this. And now it has meaning beyond what it just is, because it makes me think of this person or this thing that happened or this place I was.” It’s almost like you can take emotions about people or memories about the past and trap them in these things that you own.

    +

    JESSICA:  Oh, because even though it’s a thing, itself doesn’t contain the memory. The thing in combination with your brain has the memory.

    +

    SAM:  Yeah, because our brains are highly associative.

    +

    JAMEY:  It’s like cryptography, almost.

    +

    ASTRID:  Yeah.

    +

    JAMEY:  Like your brain has this key…

    +

    SAM:  [Chuckles]

    +

    JAMEY:  That makes these random letters into words. And your brain also has this key that makes these objects into like…

    +

    JESSICA:  It’s like we’re living in augmented reality.

    +

    [Laughter]

    +

    SAM:  But it’s only augmented for you.

    +

    [Laughter]

    +

    JESSICA:  Now if only we realized that.

    +

    JAMEY:  It’s personalized. It’s like the crackers.

    +

    SAM:  Yes.

    +

    ASTRID:  Yeah.

    +

    SAM:  [Chuckles]

    +

    JESSICA:  So then, if the beauty of the code is in what it does, and I completely agree with you there, then your work satisfaction is going to be less about what language you’re writing or how well-factored it is than what the software accomplishes?

    +

    JAMEY:  To me, the moment that makes me writing code is the moment when something that didn’t work before suddenly works. And I’m sure that other people feel this way. Like, they must, because it’s so satisfying.

    +

    JESSICA:  Mmhmm.

    +

    JAMEY:  [Laughs]

    +

    SAM:  There is definitely a magic in that moment.

    +

    JAMEY:  I remember the first time I ever really… I don’t work with a lot of hardware. But I was doing consulting and I was doing a project where I was working with printers. And it was a huge pain. It was just the worst. And there were all these restrictions. And so, I ended up sending information to printers via… I opened a bytestream from an Android phone and sent it directly to the printer via Bluetooth. It was such a pain. And it didn’t work for a long time and I was just days of, “Oh, I sent it and it didn’t work. It printed gibberish. Oh, I sent it and nothing happened.” And the first time that a piece of paper came out of that printer with real words on it I was like, “Oh my god.”

    +

    [Laughter]

    +

    JAMEY:  “I am the master. I control. The technology. I have so much power. I felt so powerful.” And I was like, “Ah, this why people like working with hardware.

    +

    [Laughter]

    +

    JESSICA: Right, right. It’s that changing the physical world thing.

    +

    SAM:  Oh my god, I made an LED blink. I’m so great.

    +

    JAMEY:  I’m a powerful technomancer.

    +

    [Laughter]

    +

    JAMEY:  I can make the LED blink whenever I want.

    +

    SAM:  And of course, at this point I absolutely have to share one of my favorite YouTube videos.

    +

    JAMEY:  [Chuckles]

    +

    SAM:  Which is of somebody who programmed two floppy disk drives to play The Imperial March from Star Wars.

    +

    JAMEY:  Oh my god.

    +

    [Laughter]

    +

    SAM:  And I will drop a link to that into the show notes. Because, oh my god, it is awesome.

    +

    JAMEY: I have a tattoo of the Death Star. Fun fact. Fun to me.

    +

    [Laughter]

    +

    JESSICA:  Really, Jamey. Is that ethical?

    +

    JAMEY:  It’s not at all. And that’s literally why I have it.

    +

    SAM:  [Chuckles] Yeah, because did you pay a copyright fee for that tattoo?

    +

    JAMEY:  That’s not why.

    +

    [Laughter]

    +

    JAMEY:  George Lucas doesn’t need any more of my money. I promise.

    +

    SAM:  [Laughs]

    +

    JAMEY:  He has so much of it. [Laughs] No. I think about the Death Star all the time. I think about the Death Star whenever I think about my career, to be honest. It sounds like a joke, but it’s actually kind of true. Because when I started thinking critically about the Death Star for the first time, which happened the first day that Rogue One came out, when I went to see Rogue One. I went to see this movie and I’m like, “Yeah, Star Wars. I love it. I’m going to go. I’m going to see this movie.” And I went with my fiancé and we were just like, “Yes, a Star Wars movie. We’re so excited.” And we got out and he was like, “What did you think of it?” And I imagine that I went super pale and I was like, “I’m worried about my career.” And he was like…

    +

    [Laughter]

    +

    JAMEY:  This is what you want to talk about? Don’t you want to talk about Star Wars? I’m like, “I am talking about Star Wars. I don’t know.”

    +

    [Chuckles]

    +

    JAMEY:  Because it really freaked me out to watch that movie and see the backstories of the engineers that worked on the Death Star. Because everyone wants to go to the movies and be like, “I’m the good guy. I’m a hero. I’m an action hero.” And I was like, “Oh, I’m like an old white man in a white coat that works for the Empire.” Like, that’s who I relate to in Rogue One, because they didn’t know that they were building a super-weapon. They were just engineers who want to build something cool. And they did. And then it was the Death Star. And they all got killed. Spoilers.

    +

    ASTRID:  I feel like that’s so relevant to our current life and times in technology.

    +

    JAMEY:  Yes, yes. I think about it a lot and it’s like, if you don’t think about ethics when you’re building something, that’s dangerous. Because I was like, “I wouldn’t work on the Death Star. No way.” But you can’t prevent yourself from working on something like that unless you stop to consider what it actually is. I’m lucky because I’ve worked on projects pretty much my whole career that I actually do feel really strongly like, “This is a good thing.” But there’s a lot of stuff that seems just not immoral but amoral. Like, unrelated to morality. And I think if you are too quick to be like, “Well, my work is amoral. It has nothing to do with morality,” you put yourself in a situation where you could be doing something that’s really immoral actually and you don’t really realize it. And I think that’s what happened in Rogue One.

    +

    ASTRID:  Or it could be used in a way after the fact.

    +

    JAMEY:  Yes.

    +

    ASTRID:  That is not the way it was intended when it was being built.

    +

    JAMEY:  Definitely.

    +

    JESSICA:  Or have effects that it wasn’t designed for.

    +

    ASTRID:  Mmhmm.

    +

    JESSICA:  What if you get really good at growing indoor plants and then the plants take over and eat you?

    +

    ASTRID:  Little Shop of Horrors.

    +

    JAMEY:  I’m not as worried about that as other things.

    +

    [Chuckles]

    +

    JAMEY:  But I’m glad we’re talking about it.

    +

    [Laughter]

    +

    SAM:  I feel like a lot of us look at the Volkswagen thing where they were deliberately spoofing emissions tests. We look at that and we think, “Well, I wouldn’t ever write something like that.” But a surprising number of us might write something like that if it’s where money was coming from, if that’s how we’re feeding our family. And [sighs] there are a lot of other cases in our industry that are a lot less clear-cut even than that is. And that I think a lot of people just don’t really think about, because they don’t really want to think about them. Because you don’t really want to face the possibility that you might be even to some small degree a monster.

    +

    JAMEY: I’m working on a talk about this right now actually. And I was researching the other day people who regret their inventions.

    +

    SAM:  Mmhmm.

    +

    JAMEY:  Because I was talking about… like a well-known example is Einstein’s contributions that ended up being related to the atomic bomb, even though he wasn’t personally the person who did that. He was very regretful of his involvement. And I was looking up other examples. And the person who developed pepper spray didn’t do so to make it a biological… it was supposed to be a weapon. It wasn’t something that wasn’t going to be a weapon. But now, the way people are using it, the way that police use it and stuff, he’s like, “This is just so… I’ve never seen such irresponsible uses of chemicals.” So, he has regrets about that. The person who invented the AK-47, there’s a really interesting quote that I found where he was debating, “Am I responsible for people who died with this gun or not? Sometimes I think I am. Sometimes I feel like I didn’t force anyone to do this.” But, on his deathbed or something, he had this quote where it was like, “I wish I just could have used that energy doing something else. I wish instead of inventing the AK-47 I could have invented something that could help people do their jobs, like farmers or something.” And I read that and I was like, “That’s what I do.”

    +

    [Laughter]

    +

    JAMEY:  But another example I used is the person who invented the cubicle, because he was like, “Yeah, the cubicle is great. It’s going to be flexible. It’s going to let people have a better work environment than offices,” and then people used it to just pack people in because it was cost-efficient. And he was like, “No, that’s not what I meant.” But it’s too late.

    +

    SAM:  Right.

    +

    JAMEY:  Because he already invented it.

    +

    SAM:  But it was in many ways better than what came before, which was a giant, open, floorplan with a bunch of people at desks just making noise.

    +

    ASTRID:  You mean like now?

    +

    SAM:  Well, but now it looks different.

    +

    [Laughter]

    +

    SAM:  Now it’s IKEA furniture, right?

    +

    ASTRID:  Exactly. So, there’s this talk that Malcolm Gladwell does in a similar topic and it’s about the Norden bombsight. Have you seen that, Jamey?

    +

    JAMEY:  No. Tell me about it.

    +

    ASTRID:  Okay, so you’ll probably like this for the research you’re doing. It’s about a person who was, he makes this device to make bombing more accurate. Because what he’s thinking is that if we can make the bombing more accurate then we can have less death and then war can be over faster. Because he assumed, “I’m not going to stop war. But maybe if I can make war more efficient, then we won’t lose as many people.” And he tells a very interesting tale about how it works. But at the end of the day, it ended up being used to drop the atomic bombs. So, even though his intention was to try to make the loss of life as small as possible, it ended up being used completely outside of its intention of being accurate, because you don’t have to be accurate so much if you’re dropping an atomic bomb, to hurt and kill so many people.

    +

    And that’s like what we’re talking about where sometimes you’re building something because you think it’s going to do something that could be good. But then it could be used in a completely different capacity in a way that you never expected or intended. And unfortunately, especially with science and technology, oftentimes the money that you get to build things, when they will fund you to build all kinds of things and let you learn all kinds of science, it’s usually to be used in some way that’s going to exert power from one people over another people. And it’s like, how do you deal with that Faustian bargain of we’re going to advance science but it’s going to be at this cost that we may not be able to quantify? And it seems like it always happens that way.

    +

    JAMEY:  It’s hard because once you’ve put something out there, you kind of lose control over it and how it’s used. And I think that’s what a lot of the stories that we just told are about. And I also think that as programmers, we’re at a particular risk of that, because code doesn’t know what it’s doing. So, repurposing code is very easy in many ways. The example I like to use of this is AR technology, which is really interesting, and like facial recognition. So, people are like, “Yeah, AR video games.” It’s a big thing. And it’s cool and it’s interesting and it’s new and it’s futuristic or whatever. But if you write facial recognition software, the software doesn’t know whose faces it’s recognizing or why. And then if they repurpose that code to say, try to find protesters to arrest them; that would be easy to do with that code. And if you wrote it, there’s nothing you can do about it. You can’t stop them from doing that once they’re doing it.

    +

    [Sigh] So, I think it’s just really hard because there’s no way that we can anticipate all of the ways that our code could be repurposed. But I do think we have to take some sort of responsibility for what else could be done with it that isn’t what we originally meant. And I’m not sure where the line is between, “I’m afraid that my stuff’s going to get repurposed so now I just can’t write anything, ever,” which is also not realistic.

    +

    JESSICA:  Yeah. The world is a complex system and when we create something or learn something, we change that system. And we can’t know how that’s going to affect things. But we can influence the system in various ways to hold people in power accountable for their pepper spray actions.

    +

    ASTRID:  You know Jessica, sometimes I wonder if maybe we could just start thinking about… like, I try to think about code like a tool. In anthropology, especially when you’re learning about hominids, what you learn is that the tools that we make are extensions of us. So, an axe is an extension of our ability to use our arm with force. And cars are an extension of us to be able to run. Something like that. So in that case, then code is like an extension of what we could use our brain to do, or use a connection of brains to do, in one instance. And so, it’s like you wouldn’t give young kids sharp objects and then leave the room. Because you would expect that something bad could happen. So maybe it might be possible for us to think more about, “Okay, this type of code could be utilized in a bad way or in a destructive way by those who are uneducated about what to do with it or not capable of understanding how to use it.” We should know that. And maybe there are things we can do around that to help it be used properly.

    +

    Because I think it’s not so much that you can make things without any type of morality. But, tools are tools. They’re just there until somebody picks them up. And you can use hammers to build a house for somebody or you can use them to destroy something. So, it’s really not, should you not make a hammer? It’s like, how do you teach people to use hammers and why would you have hammers? And who should be around if somebody doesn’t know how to use a hammer so that they can teach them the right way. And maybe we should be thinking around those questions and less so about, should we make this or not?

    +

    SAM:  I feel like there are some tools that are a little bit more single-purpose than others. Like it’s hard to imagine a use for a gun that isn’t destroying something. Which is not to say that we shouldn’t make guns, but it’s maybe a little bit less balanced of an example than a hammer.

    +

    ASTRID:  I was just reading a book about somebody who was doing research in the rainforest and having a shotgun was really important because there was anacondas and there were jaguars. And you needed it. That’s totally different than if you take that same gun and point it towards a person in the rainforest.

    +

    JESSICA:  Yeah.

    +

    ASTRID:  Because you don’t need to shoot a person unless they are seriously [inaudible]. So, it’s really about understanding… you know a gun is a powerful tool. So, you should understand when you’re using it, what the implications of what you’re doing with it could be.

    +

    JAMEY:  I think the more powerful a tool is, the more respect you have to have for it. And I think the tough thing here is I can control how much respect I have. And I can try to encourage and teach other people to have respect. But I can’t force other people to respect something the way I respect it, or think it should be respected. You know what I mean?

    +

    ASTRID:  Yeah.

    +

    JAMEY:  I like what you’re saying though. And I think that with software, what you’re describing, we already do a lot in a… not a moral way, but in a mundane way. When we build something as engineers, we say like, “Okay. How are users going to break this? How are they going to screw this up and do it wrong? And what safeguards can I put in so that they don’t do it wrong?”

    +

    JESSICA:  Mmhmm.

    +

    JAMEY:  I think that’s a huge part of our jobs. But I think you’re right. I think extending that to be about morality and not just usability is important. I just have to figure out how to do it. It’s not just my job to figure it out. We can all think about it.

    +

    ASTRID:  Well, I think it helps to just ask the question.

    +

    JAMEY:  I agree.

    +

    JESSICA:  Yeah.

    +

    JAMEY:  I think getting people thinking about it is a huge thing. Because I had never thought about this, really, before I saw Rogue One, like I said. And it was scary, because I’m like, “I’m a good person. I wouldn’t purposely do something that I think is wrong.” But until you’ve asked the question and thought about it, you never know what you’re going to do, I guess. And at that moment, I felt like I didn’t know what I would do in that situation. And now that I’ve asked the question and talked to people about it and thought about it, I feel like I do know what I would do. And so, I feel much less anxiety about it now. And I feel like the more I talk about it, maybe other people will think about it, too. Hopefully.

    +

    JESSICA:  I had two things I wanted to follow up on. Your first job. You said one of the owners was a developer and even though he didn’t have a lot of time, you said I learned a lot from him because he was really brilliant. Does brilliance cause someone to be able to learn from you? Or is there some intermediate step? Or something different?

    +

    JAMEY:  I think brilliance does allow someone to learn from you. I think being a good teacher definitely, obviously, helps someone to learn from you, even if you’re not a genius, which this person was. But I think if you really want to learn from someone who’s a genius, you can learn from them without their consent. [Chuckles] Like if you just observe things that they do that are really brilliant and think about why are they doing these things and how can I emulate these things? There’s stuff to be learned there. Obviously if someone is also a good teacher, that’s a great combo. And he did teach me some stuff. It wasn’t that he was a bad teacher. It was just that he didn’t have the time to devote to me all the time that I would like. But I think picking out people who you look up to in that regard and just watching them very intently and observantly, you can learn things from them, even if they’re not trying. If you’re trying. At least one person has to be trying.

    +

    JESSICA:  Interesting.

    +

    JAMEY:  Do you agree with that?

    +

    JESSICA:  Yeah. At the time you were inexperienced. So, there was an infinite amount of stuff to learn. And you had the energy to devote to that careful learning. I wonder if there are some people that we think are brilliant that if we put the effort into learning from what they do, we’d find out they aren’t.

    +

    ASTRID:  I agree.

    +

    SAM:  [Chuckles]

    +

    ASTRID:  I think we slap that label on people because they’re doing something that feels like we don’t know how to do that. And then we miss the people who are doing what they’re doing so amazingly that it’s so seamless we can’t even see it, unless you’re really looking.

    +

    JESSICA:  Yeah, the real genius makes it look simple.

    +

    ASTRID:  Yeah.

    +

    JESSICA:  But then if you look closely, you will learn.

    +

    ASTRID:  Yes, of course. But I think part of it is just, I feel like sometimes our culture has this idea about genius, like some people have it and some people don’t. And genius are these people that do things that nobody can do. And I think sometimes it’s like, when you see them, it’s the combination of a lot of things they’ve gotten really good at and that’s why they seem so otherworldly. And then we kind of confuse that with people who are just loud about what they do.

    +

    JESSICA:  Mm.

    +

    ASTRID:  You know, like, “I’m awesome. You have to love me.” And then we’re like, “You must be a genius.” And then they’re really not.

    +

    JAMEY:  I think if you want… I agree with you. But I think that if you want to be critical about that, that’s a pretty easy thing to be critical about. I think that kind of genius façade that you’re describing is a façade that kind of crumbles pretty quickly once you look closer at what someone is doing.

    +

    ASTRID:  Yeah, I agree. I just don’t know how much time we spend to look for those little things anymore.

    +

    JAMEY:  That’s true.

    +

    JESSICA:  That is the limitation, the time we have to process the information. There’s so much more that we… more zines than we can possibly read. [Chuckles]

    +

    SAM:  Yup.

    +

    JESSICA:  And yeah, and more blogs and more people that we could possibly learn from than we can possibly learn from.

    +

    [Laughter]

    +

    JESSICA:  There’s one other thing you said early, Jamey, that I thought was important. You were in your animation classes and there was a lot of code. And you said you loved it and everyone else seemed to hate it. So, you recognized that that made you special and ran with it.

    +

    SAM:  Yeah, that’s not a reaction that a lot of people would have. They would think, “What’s wrong with me? Maybe I shouldn’t love this.”

    +

    JESSICA:  Yeah. If you can see that thing that is different that makes you different from other people, then that’s where you can find your special job that’s actually fulfilling.

    +

    JAMEY:  I think there are some kinds of people that are afraid of being different from other people. And then there are some kinds of people that are afraid of being the same as other people.

    +

    JESSICA:  That’s so true. That’s like welcoming of difference is easier for some people than others.

    +

    JAMEY:  But I even think, originally I was going to say some people are afraid of being different and some people like being different. But I decided to… I think it’s even more than that. I think that some people who like being different are actually afraid of being similar. And I feel that in myself, sometimes, I think.

    +

    SAM:  I feel like there’s a Portlandia sketch about that.

    +

    JAMEY:  There’s a Portlandia sketch, I feel about everything, every episode we talk about. We could just… in fact, you could just watch Portlandia instead of listening to Greater Than Code.

    +

    [Laughter]

    +

    SAM:  You could, but please don’t.

    +

    JESSICA:  No, no. Our podcast is good.

    +

    JAMEY:  I’m just kidding. Don’t do that.

    +

    [Laughter]

    +

    JESSICA:  So, I wanted to bring it back to your superpower. And how can you share your superpower which does not transfer to an app. What is one piece of advice that you would give people who find themselves in a new city with options about where to go that evening?

    +

    JAMEY:  Okay. I’m going to give away part of the secret.

    +

    JESSICA:  Ooh, goody.

    +

    JAMEY:  And it’s great because it’s related to what we were talking about. But the way that the Fharlanghn sense works is being very observant. I’ve had people say to me something like, “You’re cheating. You’re not really using the superpower. You heard about this place from someone else who went to Montreal four years ago and that’s how you know about it.” And I’m like, “Yeah. And the fact that I remember what somebody else said about a place in Montreal four years ago and remembered it enough to look it up and go to it, that is what the superpower is.” [Chuckles]

    +

    SAM:  Right. To somebody like me with memory problems, that is a freaking superpower.

    +

    [Chuckles]

    +

    JAMEY:  But like I catalog information about places that I’ve heard people say are cool or read about or a stranger told me about. I catalog that information and I’m observant about what sounds like it would be fun. And then I remember it. And I think that what Astrid was saying about, are we observant about things in our lives? Do we have time or whatever? You don’t have the time and energy and mental RAM to be observant and catalog information about everything that you ever hear from anybody. You have to prioritize what’s important to you. And to me, this is what’s important to me. And so, I categorize it. And then it coagulated into the superpower.

    +

    JESSICA:  So, to turn the question to our readers, what do you want to be a genius about?

    +

    JAMEY:  And what kind of information do you have to catalog to get there?

    +

    JESSICA:  We can’t all hold it all so we each get to be special with the piece we…

    +

    JAMEY:  [Chuckles]

    +

    JESSICA: Focus on. What do you love that other people don’t love quite as much?

    +

    SAM:  And thank you listeners. We’ll end it there. We will be back at you soon with a new episode. Meanwhile, if you like the sort of things that we do, the conversations that we have here, please support us on Patreon. We all as panelists do this show for free because we love it. But the production costs are not insignificant. It takes money to pay Mandy to do the wonderful editing that she does so that you get the interesting bits without all the uhm’s and ah’s. And it takes a bit of money to pay for transcriptionists so that our show is searchable and accessible. So, if you’d like to help us with those costs, go to Patreon.com/GreaterThanCode and help us out. And any donation will get you into our Slack community as well where we have a couple of hundred people being really, really nice to each other. Anyway, thanks very much. We’ll be back at you soon.

    +

     

    +

    This episode was brought to you by @therubyrep of DevReps, LLC. To pledge your support and to join our awesome Slack community, visit patreon.com/greaterthancode.

    +

    To make a one-time donation so that we can continue to bring you more content like this, please do so at paypal.me/devreps. You will also get an invitation to our Slack community this way as well.

    +

    Amazon links may be affiliate links, which means you’re supporting the show when you purchase our recommendations. Thanks!

    +]]> + Panelists:

    +

    Jessica Kerr | Sam Livingston-Gray | Astrid Countee

    +

    Guest Starring:

    +

    Jamey Hampton: @jameybash | jameybash.com | Agrilyst |
    +
    Sugar City Arts Collaborative

    +

    Join Our Slack Channel!
    +
    Support us via Patreon!

    +

    Are you Greater Than Code?
    +
    Submit guest blog posts to mandy@greaterthancode.com

    +

    Show Notes:

    +

    01:22 – Jamey’s Superpower: “The Fharlanghn Sense”

    +

    02:40 – Working in Agriculture

    +

    04:03 – Theories on Automation

    +

    05:56 – Pivoting Into Computer Science and Software Development

    +

    10:35 – Feeling Like You Need to Know Everything

    +

    Stella Report from the SNAFUcatchers Workshop on Coping With Complexity

    +

    15:47 – ‘Zines and Being a ‘Zine Librarian

    +

    27:50 – The Beauty of Art and Technology and Forming Emotional Connections to Things

    +

    Floppy Music DUO – Imperial March

    +

    35:26 – The Death Star => Ethics in Technology and Taking Responsibility/Being Accountable for your Code

    +

    Malcolm Gladwell: The strange tale of the Norden bombsite

    + +

    +

    49:42 – Brilliance and Learning From Others Without Consent

    +

    54:49 – Adv]]> + Panelists:

    +

    Jessica Kerr | Sam Livingston-Gray | Astrid Countee

    +

    Guest Starring:

    +

    Jamey Hampton: @jameybash | jameybash.com | Agrilyst |
    +
    Sugar City Arts Collaborative

    +

    Join Our Slack Channel!
    +
    Support us via Patreon!

    +

    Are you Greater Than Code?
    +
    Submit guest blog posts to mandy@greaterthancode.com

    +

    Show Notes:

    +

    01:22 – Jamey’s Superpower: “The Fharlanghn Sense”

    +

    02:40 – Working in Agriculture

    +

    04:03 – Theories on Automation

    +

    05:56 – Pivoting Into Computer Science and Software Development

    +

    10:35 – Feeling Like You Need to Know Everything

    +

    Stella Report from the SNAFUcatchers Workshop on Coping With Complexity

    +

    15:47 – ‘Zines and Being a ‘Zine Librarian

    +

    27:50 – The Beauty of Art and Technology and Forming Emotional Connections to Things

    +

    Floppy Music DUO – Imperial March

    +

    35:26 – The Death Star => Ethics in Technology and Taking Responsibility/Being Accountable for your Code

    +

    Malcolm Gladwell: The strange tale of the Norden bombsite

    + +

    +

    49:42 – Brilliance and Learning From Others Without Consent

    +

    54:49 – Adv]]> + + + + clean + No + no + no + 58:44 + Mandy Moore + + + 061: Destruction-Focused Development with Safia Abdalla + https://www.greaterthancode.com/podcast/061-destruction-focused-development-with-safia-abdalla/ + Wed, 03 Jan 2018 05:00:07 +0000 + Mandy Moore + http://www.greaterthancode.com/?post_type=podcast&p=1083 + + + Panelists:

    +

    Jasmine Greenaway | Jessica Kerr | Coraline Ada Ehmke

    +

    Guest Starring:

    +

    Safia Abdalla: @captainsafia | safia.rocks | Zarf | Tanmu Labs

    +

    Join Our Slack Channel!
    +
    Support us via Patreon!

    +

    Are you Greater Than Code?
    +
    Submit guest blog posts to mandy@greaterthancode.com

    +

    Show Notes:

    +

    00:53 – Safia’s Superpower: Sight

    +

    03:04 – Learning Languages — Both Human and Programming

    +

    The Sapir Whorf Hypothesis

    +

    07:56 – Being Empathetic in an International Perspective and Building Universal and Approachable Tech

    +

    11:19 – What does success look like for minorities in the Silicon Valley monoculture?; Being Tokenized

    +

    Admiral Grace Hopper

    +

    21:59 – Accepting Speaking Engagements Because of Who You Are (i.e. as a woman, minority, etc.)

    +

    24:07 – Writing Things Down to Balance Prioritizing Decisions

    +

    30:46 – Defining “Happy” and Always Feeling the Need to Do More

    +

    37:02 – Destruction-Focused Development

    + +

    +

    43:58 – Safia’s Early Coding “Shenanigans”

    +

    Reflections:

    +

    Coraline: Being thoughtful about planning finite energy and labor. Also being content vs being happy.

    + +

    +

    Jasmine: Exploring feelings about being represented at events.

    +

    Jessica: Broadening perspectives that most of us were born into.

    +

    Safia: Talking about the Silicon Valley monoculture, being content vs happy, and tokenism.

    +

    Transcript:

    +

    JASMINE:  Hi and welcome to Greater Than Code Episode 61. My name is Jasmine. And with us on the panel today we have Jessica.

    +

    JESSICA:  Good morning. I’m Jessitron and I am thrilled to be here today with Coraline Ada Ehmke.

    +

    CORALINE:  Hi, everybody. And I’m happy to introduce our guest, Safia Abdalla. Safia started building HTML websites when she was 11 and writing Python and JavaScript since she was 13. For a little under a decade, she’s been a curious young technologist using computers to make cool things and share them. Now, she can be found speaking at conferences, blogging, contributing to open source, and working on her startup. Safia, so happy to have you here. Welcome.

    +

    SAFIA:  Thank you so much for having me.

    +

    CORALINE:  Our standard question that we start every podcast with is, what is your superpower and when and how did you discover it?

    +

    SAFIA:  I would say my superpower is sight. One of the things that I pride myself in is being the kind of person who can just sit back and observe a room and look at people’s interactions and see how they’re talking with each other and what they’re sharing, and use that to inform my interactions or solve problems or work with them. So, I would say just having this empathy and this ability to feel and observe things and watch people would be my superpower. It’s not as cool as being invisible or being able to fly, but it works.

    +

    CORALINE:  Cool. And were you always able to read a room like that and understand where people were coming from, or is that something you developed over time?

    +

    SAFIA:  So, I think it kind of relates really strongly to my background as an immigrant. My family moved to the United States when I was seven years old. And when I moved here I didn’t really know any English. I had a lot of trouble interacting with people and making friends. And so, one of the ways that I would figure out what was going on in a place was just to sit back in the corner and watch what people were doing and see if I can gather some sort of understanding of what was going on around me. I think it started from there, from trying to just understand this new setting I was in and learn what was going on and evolved to me just reading a space and figuring out what I can do to make myself useful to the people in it, or figuring out how to interact with those people.

    +

    CORALINE:  That’s so cool. That kind of reminds me, about 10 years ago I went with my grandmother to Germany and Poland. She hadn’t been back to Poland, where she grew up, since World War II. So, I took her on this trip to go back to her home. And all of the relatives we were traveling with, only one of them spoke any English at all. And my German is extremely rudimentary. I can talk in first-person present and that’s about it. So, I did a lot of sitting around listening to people speaking German which I could kind of follow what they were saying, but yeah, you’re right. That did give me a lot of time to observe their interactions and step back and see what they were saying without saying anything.

    +

    SAFIA:  Yeah. I agree. And I think you brought up something really interesting about learning different human languages. So, German, Spanish, French, et cetera. That I think has been useful is, as someone who’s been programming for a long time I’ve kind of gotten to the point where learning a new language is second nature to me. I pretty much understand all of the ropes. It’s just learning the syntax. And I think one way that I’ve learned to empathize with people who are completely new to the industry who are just starting to learn how to code is thinking about my experiences learning new human languages. Because I think that’s the best way to understand what it’s like to come into tech and not know Ruby or Python or JavaScript or anything and have to learn that from scratch. It helps me just relate to people better. So, I can definitely understand you having to use German in a setting that was not normal to you and what that was like.

    +

    CORALINE:  I think it’s so valuable too, with programming languages to know more than one language, because I think what happens is you start to understand underlying concepts outside of syntax. And I think that makes people better developers long-term, because you’re thinking about solving problems in the abstract and then translating them into syntax, instead of just trying to look for the canonical solution in the language that you happen to be working in.

    +

    JASMINE:  Yeah, I agree. And I would also say, just different languages that have different characteristics and different sayings and just different ways of looking at how we communicate, I would say that programming languages are the same way. The way we actually write the code, the way that we… I guess just difference in style and how we target solving different problems can differ between languages.

    +

    JESSICA:  Yeah, it’s one thing to learn the syntax of a language and another thing to learn how to think in it, because they do each make you think differently. So yeah, I thought it was interesting that you compare learning a new human language to learning your first programming language. As in, that’s a whole lot harder than learning your second or third programming language.

    +

    SAFIA:  Yeah, because I think part of learning your first language is learning things like if statements and while loops and for loops, and the concepts that underpin, this might be a fancy way to say it, but just the algorithmic thinking around writing software. And then once you figure that out, it’s just about learning, what is the special way that this language does for loops? What is the special way that this language addresses an issue that another language solves poorly? Whereas when you transition to learning a new human language, it involves learning a new set of grammar, a new way of thinking about the world almost. I think there’s a close connection between what we speak and how we see the world. And the transition into learning a new human language and the way it affects the way you see the world is very similar to learning your first programming language, learning algorithmic thinking and problem solving and how that changes the way you see the world and approach problems.

    +

    CORALINE:  Language definitely influences the way that we see the world. There’s been a lot of studies on that. And there’s this thing called Sapir-Whorf hypothesis which explicitly states that the words that we use influence the way we interpret things and events and people around us. There’s a great example of that. There was a bridge built in Europe. I can’t remember. I think it connects Spain, maybe Spain and France. And it’s the tallest bridge in the world. And the word for bridge in French is masculine. And someone did a study of the newspaper reports of the construction and finishing of this bridge. And in French, all of the words that were used to describe the bridge emphasized its mass and its strength and its material. Whereas in German, the word bridge, ‘die Brücke’, is feminine. And the German reporters use words like weightless and it floats above the clouds, and they emphasized its gracefulness. So, I thought that was a really poignant example of how language was… they’re looking at the same bridge and they’re seeing completely different things.

    +

    SAFIA:  Yeah, so fascinating. And I think just a great way to showcase something that I’ve been experiencing as I’ve started to adopt a more international focus with my writing and speaking in tech. it’s just the ways that developers in Germany or India or France see things differently from developers in the US. And I’ll admit that I kind of mostly lean towards presenting and blogging towards an American audience. But just recognizing and hearing back from people across the globe who read my work and realizing that they pick up on different things or that they interpret my tone in different ways has been really interesting. And that’s one of the things that I’ve made a personal focus recently, is becoming more empathetic in an international perspective. Because I would say that for the first part of my life, moving to America and having to learn English, it was a lot about conforming to American culture and fitting into the standard. And now I’m realizing that I kind of need to go back and connect more with the outside world, now that I’ve figured out how to speak English and how to live in America and how to interact with people in America. It’s just learning how to do that for people in other countries.

    +

    JESSICA:  Oh, that’s beautiful. Can you give us some examples of ways that developers outside of the US think differently?

    +

    SAFIA:  So, one of the big things that come to mind when I think about how developers outside the US think a little bit differently than developers who are local is the attention to linguistic diversity that European developers have. And I think that comes as a consequence of the fact that Europe is about, I think smaller than the land mass of the United States but within that small area you have lots of different languages and lots of different cultures interacting with each other. So, one thing that I’ve found that is a little bit more common in developers in Europe is just a stronger focus or a bigger awareness of differences in culture within a particular region, or differences in language within a particular region. And I think that developers in America haven’t totally figured out because we’re used to looking at the world from the perspective of a Silicon Valley startup or from our tech hubs. Whereas if you’re in Europe and other places around the world, you’re more attentive to the nuances in language and thinking that occur even within a small region of the world. [Inaudible]

    +

    CORALINE: I would argue that Silicon Valley companies do the same sort of thing except without that awareness. They’re influenced by the culture of a small geographic area because they think of their users as being exactly like them, right? And that doesn’t apply even across all of America. My dad expressed a little frustration. He lives in a very rural part of the country and doesn’t have high-speed internet. He has satellite internet which is throttled and metered. And so, a lot of the applications, the web apps that people develop assume a broadband connection when the significant portion of the country doesn’t have access to that. And as people in a bubble in Silicon Valley just assuming that everyone across America is just like them, then we see the same thing when those companies try and go international. They assume American culture, and specifically Silicon Valley culture, exists everywhere else in the world, too.

    +

    SAFIA:  Yeah, that’s a great way of putting what I was trying to say. Everyone seems to think that, or I think most developers in Silicon Valley and our country think that everyone’s got the newest iPhone at a high-speed data connection with great internet at home. And the uncomfortable reality is that most of Silicon Valley isn’t like that. Not everyone in San Francisco has those kinds of resources. Certainly not everyone in America. So, building universal and approachable tech is really difficult.

    +

    JASMINE:  So, you know, this [inaudible] culture that we have in Silicon Valley, what is it like? What’s the experience like for somebody who doesn’t fit in that norm and their norm, or Silicon Valley’s norm? And what does success look for somebody who is trying to work their way up in that industry?

    +

    SAFIA:  To kind of establish to those who are listening or might not know me, as mentioned earlier I’m an immigrant. I’m a woman of color. So, I exist at the intersection of a couple of minority labels or minority identities. And I’ve been involved in tech for a little under a decade if you include all of my youthful shenanigans that I pulled when I was 11 and 12. But I’ve been directly engaged with different companies and different conferences and at events for probably six years now. And I’ve been this different person who doesn’t look like the “norm” in tech. And one of the things that I’ve seen in other successful minorities in tech and just in myself as I try to establish a career in the industry and develop something for myself in the industry is the fact that so often people who are not the norm in tech end up being tokenized a little bit.

    +

    One example that I think of, and I think this is going to be a popular example that everyone can relate to, is Admiral Grace Hopper. That name is probably recognized by pretty much everyone in the industry. There are conferences named after her. Her name gets used a lot as an example of a successful woman in tech. But one of the things I struggle with is of all of the people who know her name and know that she was a female computer scientist and one of the first, how many actually know what she accomplished? Grace Hopper had the courage to bring up the idea of a compiler in her time. This notion that instead of writing everything in low-level machine code and it being painstaking and difficult to debug, you can create compilers that could translate code in a language that a human could understand much more easily to something that a machine can process. And that idea was revolutionary. It’s the reason that we have things like startups. it’s the reason that we can even talk about people learning to code at home or at bootcamps or at universities, is because she reduced that barrier to entry. But I think so often when we talk about her, she’s tokenized for being a woman in computer science, that the intellectual and technical value of her work is overshadowed.

    +

    And that’s something that I think a lot of minority individuals struggle with. And something that I’m trying to struggle with is I don’t want to be remembered for being a woman of color who is an engineer. I want to be remembered as an engineer who happens to be a woman of color. And it’s so difficult because when you’re different from the mono-culture or from the norm, people want to focus on your differences, not how you’re the same. So,people want to focus on how I’m a woman of color and how that is something unique about me and not necessarily the fact that I’m a pretty darn good engineer and that I’m really great at maintaining open source projects. And that’s one thing that I’ve tried to think about a lot and dictates a lot of my interactions recently in tech, is I don’t want to be remembered for being a great woman in tech. I just want to be remembered for being a great engineer, a great business person, who happens to be a woman of color.

    +

    I’m sure that there’s more examples beyond Grace Hopper of people who have experienced similar tokenizations, I would say, where who they were and their identity quickly overshadowed what they did. And it’s tough to balance, because I definitely… who I am is a big part of my identity but it’s not all I am. So, playing this balancing act where I am comfortable with who I am and I recognize that it’s part of my journey, but it’s not my entire self. And I don’t want people to see me as that.

    +

    CORALINE:  I think that’s such a difficult balance too, because you want… I don’t want to project onto you. I want to open the way for other women in tech. I want to open the way for other transgender women in tech. I want to be a role model in some kind of way and I want to inspire people who are like me to succeed and show them, you can do these things and who you are isn’t a barrier. But like you, I don’t want to be, “Oh, Coraline’s a great transgender female engineer,” right? That’s not my identity, but it is part of who I am. And I think the struggle is being your whole self without erasing part of your identity or overemphasizing part of your identity. And that’s so difficult to navigate.

    +

    JESSICA:  Yeah, you just want it to be so that there are enough transgender women in tech that that’s not the first thing people notice.

    +

    CORALINE:  Yeah, exactly.

    +

    SAFIA:  I agree with that. And I would say this is a problem that uniquely falls on individuals who are underrepresented minorities. And I think that’s something important for people to recognize when they want to be maybe good allies or just good friends and colleagues of underrepresented individuals, that we do have this kind of emotional burden that we’re carrying about how we move around the industry. Do we want to be seen as a woman of color? Is now the time to showcase the fact that we’re a strong engineer? Do we emphasize this part of our identity now or this other part? And that’s just an emotional and intellectual burden that is constantly on our minds that might not be a primary focus for somebody who is part of the norm or doesn’t have to struggle with being underrepresented in the industry.

    +

    CORALINE:  I’m really curious about how that intersects with your conference speaking, because I know for me myself, I get a lot of invitations to speak at what I call unicorn talks where it’s like, “Oh hey, come be on this panel about women in tech,” or, “Hey, come be on this panel about X or Y.” And that’s like a hyper-focus on identity issues. I think it was Sandi Metz who said that she’ll know that the industry has changed when women in tech can go on stage talking about something other than being a woman in tech. Have you had that same kind of experience? And do you talk about your identity as part of your conference talks? Or what do you prefer to talk about?

    +

    SAFIA:  Yeah. So, I haven’t had any direct experiences, and I might just not be recalling them at the moment, where I’ve been invited to speak specifically about being a woman in tech. But I can tell there have been instances where a conference just realized that a majority of their speakers were white men and it’s kind of rushing to invite minority speakers. So, I’ve never been in situations where I’ve had to speak about being a woman of color. But I have been in a lot of situations where I could tell that I was invited because I was a woman of color. And those are always really hard for me to navigate, because it’s like, “Okay, do I accept this invitation because I know it will push forward my career? It’ll help expose me to a new audience. It’ll be another speaking engagement that I could use to lead into a job or some sort of other opportunity.” Or, the fact that you know somebody invited you not necessarily because of what you did or your accomplishments but because of who you are, it kind of leaves a bad taste in your mouth going into the talk.

    +

    And I’ve learned to just take the opportunities regardless of the reasons that I’m invited. But I definitely think that when I am invited to speak because I’m a woman of color, even if I get to propose my own topic or speak about what I like, there is an expectation by the conference organizers sometimes that I will perform a certain amount of emotional labor and discuss the issues of diversity and inclusion. And it’s not an over-explicit expectation. But it’s definitely there, that we want you to tie this topic into your talk in some way because you are of a minority identity. And sometimes I will discuss it. I think the fact that I was an immigrant is a big part of my experience in tech. But oftentimes I try to avoid it and just focus on the fact that I have been in this industry for a while. I’m curious. I’m passionate. I like to build things. I have all of these attributes that we correlate with “good engineers”. And it doesn’t really matter who I am at the end of the day. It’s what I am. Such a weird way to phrase it.

    +

    And I think the fact that I’m struggling to convey what I mean right now is a big part of the problem. There’s just this emotional burden and this intellectual burden around my identity and who I want to be and how I want to present myself. And I’m constantly thinking about it. And I don’t think this is just an issue in tech in particular. I think anyone who is an underrepresented individual attempting to navigate career or social life or anything is going to struggle with this. I’m not like everybody else. It affects everything I do and I always have to think about it, so how do I manage that? I didn’t answer your question at all, I think. But I think the reason I can’t answer it is because this is still an ongoing journey for me. I’m still trying to figure out what my identity is and who I want to be represented as. And am I a woman of color first? Am I a startup founder or am I an engineer? What label do I want to put on myself? Because although labels suck, our culture at large is very obsessed with them and everyone needs to have a tag on them for you to be understood.

    +

    JASMINE:  I myself also struggle with that. And for the first time, I listened to somebody who pretty much drew their line on the sand when it came to that. So, I was listening to a podcast and Neil deGrass Tyson was on it. And the interviewer pretty much asked him, “How do you feel about being one of the very few people of color in astrophysics?” And it sounded like he was frustrated. It sound like the question’s been asked a lot. And he sounded frustrated. And from what I understand, I think he said something along the lines that, “At the end of the day, I’m a scientist. And that’s what I want to be remembered and known as. And my knowledge is there for everybody. And I want to influence everybody.” And I had some feelings about that but for me it was just not my place to judge because like you said, everyone’s on their own journey. everyone’s still trying to figure it out.

    +

    And personally, I think that there’s so much value in conferences where yes, they might be reaching out because they see that you’re somebody in their… let’s just be honest about it, there’s space, who was different. And the fact that they find having that representation is… I guess in my opinion, is valuable, but also is valuable to you, like you’re saying. It’s a career booster. It opens you up to different audiences. And also, it opens you up to, just your presence in general, that somebody who is interested in maybe your technologies or somebody who maybe also identifies as a person of color, a woman of color, wants to explore something that you’re talking about and they’re excited about it. So, just being present can be just as important as a career booster. It can influence other people.

    +

    SAFIA:  Yeah. And I think, I talked a little bit about how it’s an emotional and intellectual burden for me personally to navigate the world as an underrepresented minority. I’ve also tried to manage the chaos that comes into my head when I address those topics by just having a mindful approach to living. And this is for my personal life and for my career as well. Starting to be really introspective about my own goals. And am I doing something because I think it’ll align with the status quo or it’ll make me look more normal in this industry where I’m not normal? Am I doing something for me or am I doing it as a representative of a larger identity or group? And just sitting down and having really honest and sometimes hard to have conversations with myself about why I’m doing what I do and what part of it is for me and what part of it is for people who are like me who will follow me in the future. And what part of it is just to conform and to not feel like I’m different all the time. I’ve been trying to work on that a little bit more and I’ve developed techniques for just existing in this industry, this chaotic, always moving, always busy industry, in a more mindful way.

    +

    JASMINE:  Do you have any tips for us that you’re willing to share?

    +

    SAFIA:  For those of you who follow me on Twitter, you probably know that I am totally obsessed with notebooks and paper and writing things down. And that’s just because I think, especially for us as technologists, we’re so busy just clackety-clacking away on a keyboard and regurgitating a lot of our thoughts very quickly to a machine, which is great in some cases. But sometimes I think it’s good to grab a pen and paper and just slowly write out your ideas. And I find that it’s been very therapeutic, because that kind of buffer or that lag between you having an idea and you writing it down on paper slows down your mind a little bit and helps organize information. So usually, I say that as a precursor, that a lot of my tips will involve writing things  down, just because I find that it helps slow my mind down and clear my thinking as opposed to typing things in an email or notepad or something like that.

    +

    And I would say one of the first things that I’ve started to do recently,, and this is when it comes to big career decisions, for me a big career decision is like I’m invited to give a keynote talk at a really interesting conference or I’m invited to a residency program for my startup or I’m given a job offer, the one thing I like to sit and do is sit down and draw a quad diagram. And it’ll have two columns. And the columns will be me and others. For me, ‘others’ is the people that I prioritize in my life. So, it’s my family, It’s my immediate circle of friends. My immediate circle of mentors and associates. And then me is just, what is this, it’s me. And then I’ll have multiple rows and the rows will be 6 months, 1 year, 1 and a half years, and 2 years. So, just time. And I’ll write out, in six months, assuming that I take this offer or I do the best I can at this job or I speak at this conference and it turns out lending itself lots of other opportunities, what will this do to make me happy and what will this do to make others happy?

    +

    And I’ve found that this is a great way for me to balance prioritizing my own feelings versus the feelings of others, because one of the big things that I struggle with especially as a young person is I have a lot of mentors and friends and family who want me to do things that I don’t want to do. So, physically writing down how something will make me happy versus how it’ll make others happy helps me manage those distinctions. And then I’ll go through and I’ll fill out that chart and I’ll think about the total value of my own happiness and success versus the happiness and success that others might derive from my actions. And I’ll just have a conversation with myself. Do I care about the fact that if I do this, other people will be happy but I won’t? Do I care about the fact that I’ll be happy but others will be maybe a little bit upset? And  just sit down and have that conversation about how my choice affects not just me but others long-term. So, that’s one of the techniques that I utilize especially when I’m faced with decisions. Things like referrals where somebody referred me to a position or things like a job offer where my entire family wants me to take it but I don’t want to take it. Or things where my friends really want me to do something that I don’t want to do and vice versa where I can be very stubborn and headstrong and want to do something that other people don’t necessarily support or totally believe in, and just managing those distinct things.

    +

    So yeah, that’s one technique I utilize. And that’s more structured and chart-based. Others, I think it’s just really useful to write out your feelings sometimes. And I think that’s advice that’s been given a lot to a lot of people. And I think it’s because it genuinely works. Just grabbing a pen and paper and writing it all out. And if it helps, if it’s something negative that you want to take it out of your mind or your head space, just burn it at the end. But just trying as much as I can to take a lot of the conversations that I have about myself and my career, where I want to go, from my head to a physical medium like paper.

    +

    JASMINE:  That’s a great perspective. I just recently started my first journal ever. And it’s really been a great exploration into the things that I’m feeling. And for a bit it was a little bit scary to write those things down, because I’m like, “This is me. This is mine. Why do I want to put this in this book?” But it’s really just therapeutic and it just feels really good to just get it out and get it there on paper and just being honest with myself. And that’s a great, great tip.

    +

    CORALINE:  I did journaling a lot when I was younger. And when I wanted to start again, I found writing on paper very frustrating because I was thinking much faster than I could write. Plus my handwriting is super bad. So, I actually did video journaling for a while. I would just literally open up Photo Booth and start recording and take 5 or 10 minutes to express what I was going through and what had happened. And I found I could discover more things that were actually on my mind that way, because I didn’t feel like I had to have a narrative flow. I had random access as opposed to sequential access to memories. And get it out really quickly and skim over details if I wanted to without feeling the need to explain them. So, I think that’s an alternative, too. But I definitely see the value of putting things down on paper, too.

    +

    SAFIA:  I can really relate to the taking video journals. I think it’s a really great alternative to people who think writing is too slow. One of the things that I actually did when I was working on building out the product for my startup, Zarf, was do a weekly podcast where it was kind of like an audio journal of what I’d worked on that week and what was on my mind. And I would just sit down in my bedroom, usually, at 10pm on a Friday, and I would just record what was going on, what I’d done, what was on my mind. And I would share it out with everyone on the internet. And there were quite a few people who were listening. There was that intimidating component that I was actually being heard when I spoke, that it wasn’t just this direct contact between myself. But I agree that audio and video are great ways if you want to just dump and not necessarily have to structure.

    +

    And I think sometimes, that’s another thing you have to be mindful about is, do I want to structure and take things slow and really think slowly about what’s going on in my head? Or do I want to release? That’s a choice that we have to make. So yeah, I think that video journal idea is really good. And I should probably start it up again. I’ll definitely try that.

    +

    JESSICA:  You mentioned the very conscious definition of success. And you defined it as you being happy and others being happy in the medium and long-term. How do you define happy? Is it like warm, fuzzy feelings? What does success mean beyond feelings of “woo!”?

    +

    SAFIA:  So, I might get really dark here, but I don’t think true internal happiness exists, that there will ever be a case where you’re just satisfied with everything in your life. I think what I strive for is general ‘contentness’ in the things that matter to me. And I have some big life priorities that I want to accomplish. Some of them are personal so I can’t share them here, but some of them are career-oriented. Like I want to one day run a small tech company that has a diverse, dedicated, inclusive, and empathetic staff of engineers, designers, managers, et cetera. And that’s just a personal goal for me. And ‘contentness’ in that goal is once I’ve achieved it and just checked off all of the boxes in that goal. And then there are some things that are a bit less defined, like not very specific vision that I just laid out. But maybe I want to grow my technical skills in a particular language or framework.

    +

    And for me, ‘contentness’ is just, it’s so hard to explain because it’s, I would say it’s a deep sense of self-satisfaction, of being okay with yourself. And that’s such a hard thing I think for a lot of people to get or to achieve. It’s just being okay with who you are as things are and not striving for more. One of the things that I struggle with when I think about success and my vision of being content with the way things are is I’m a bit of a perfectionist. And I’m the kind of person who will check off one thing and immediately want to do the next. And I have this to-do list mentality that most people I think glamorize and think is the pinnacle of productivity. But for me, I’m just never going to be happy with what I’ve done. I’m always going to want to do more. So, success for me along that dimension is just getting to a point where I don’t feel like I need to do more, where I’ve conquered the intellectual and mental tick that I have that is always wanting to do something else.

    +

    JESSICA:  But, would you even be you if you didn’t want to do more?

    +

    SAFIA:  Oh my goodness. That’s a great question, because I struggle with this all the time. Like, “But wait. Is this aspect of my identity where I’m always a do more kind of person, is it me? Is it all I am? Am I going to eventually just hurt myself with my obsession of always doing more?” And it’s so difficult because I think with something like my need to always check things off a list and to always do the next thing, it’s great. Because I can be really productive. I can accomplish a lot. I can be a very dedicated and motivated person. But I can also just be consistently deeply unsatisfied with the way things are. And it’s this double-edged sword that I have to navigate. And like I was saying earlier,  this is another thing that I’m working through in my journey of mindfulness. It’s just figuring out, am I this to-do list checker always doing the next thing kind of person? Or is there going to be a point where I can say, “Safia, enough. Be happy. Be content with what you’ve done.” And yes, it’s [Laughs] so difficult to figure out. But I’m working on it.

    +

    JESSICA:  Gosh, I can’t imagine being content with what I’ve done. But I do find myself content in the doing.

    +

    SAFIA:  Yeah, I can relate to that. I’m definitely the kind of person who is most  satisfied when I’m intellectually, physically, and mentally busy or occupied. But I can’t spend the rest of my life like that. Or can I? I have no idea. I’m also only 21 years old. So, I’m sure I’ve got several [Laughs] more years to figure this out. And I think one of the tough things is I do have that part of my personality that is very motivated and checklist-oriented and wants to make lists for everything and do the next thing. And I think the hard thing is I have that personality on my own but I also exist in an industry that ‘fetishizes’ it and treats it as this holy grail of productivity and success, is you’re just the person  who always make lists and wants to do the next thing. I don’t know, Jessica. Do you feel like you are also… it seems like we’re the same kind of person where we’re always looking to do the next thing. Can you relate to that?

    +

    JESSICA:  Yes, yes. And it’s never done. And yeah, I work at a startup now and I’ve just come to realize that there are many things that are not okay. This piece of documentation, not okay. This particular bug, not okay. This missing feature. It’s just, how can we even? But now, it is okay. We can’t do everything at once. The fact is we’re doing it and we’re looking around for information on which particular piece is affecting people and is most important right now. And so, I can be happy within the process. But I really have to be content with, “we are working on making the important things okay,” because it’s never going to be totally okay. It’s never going to be up to my standards. And if it ever is, I better raise my standards.

    +

    SAFIA:  Yeah. And I really like the point that you made there, that I think ‘contentness’ is far more elusive than happiness to find. Being content is for me personally far more satisfying than being happy.

    +

    JESSICA:  Yeah, happiness is like a fleeting feeling of ‘woo!’. It’s supposed to come and go.

    +

    SAFIA:  Yeah. That’s a great way to put it.

    +

    JESSICA:  Yeah. And one reason that I can never be content with the software that we have is because we don’t yet know what’s the most useful thing for it to do. And if we knew that, then we would already have written it. And then if I wanted to get it actually right, I would have to go back and write it again.

    +

    SAFIA:  Yeah, I agree. And this is something that I had a really extensive experience with when I was working on launching my startup product. And I actually ended up building it in four iterations before it officially launched the beta. And as of this recording, I’m working on doing yet another rebuild of the product. And I kind of tweeted a little bit about this before that I think it’s very healthy to rebuild things. And there is a part of me that from a philosophical and emotional perspective is really into destroying things I make and making them again. I don’t know what that says about me. But I’m definitely gone to a point where I’m comfortable building an entire app, deleting everything (don’t worry it’s backed up on GitHub) and then starting to build it again.

    +

    This has two effects for me. The first is I don’t become obsessed with the code. I think it’s more important when you’re building a product to become obsessed with what it means for your users and how it’s going to solve a particular problem than the actual characters that you write in a text file and execute or run. And that helps me be the kind of engineer who’s more focused on the problem than the particular solution they’ve crafted. And another thing I think it’s helped me do is the process of rewriting something helps me get a better sense of the problem with each iteration. Like in the destruction of the first iteration of an app or the first build, there is this process of learning that you can bring into the next version.

    +

    I know I’m kind of presenting this really huge scary situation where I build an entire app and then I start over again. But I also try and do it in small iterations. And this is something that was inspired by my friend Corey Haines, who’s on Twitter @CoreyHaines. And he talked a little bit to me about one of the development philosophies that his startup uses, which is they have feature branches that only last for a day. So, you have a day to get the code in for the particular feature or fix that you’re looking to implement and then it’s cleared out at the end of the day. And the effect is that A, you get to iteratively learn and be able to start from scratch every day and not have this branch that hangs around for three weeks that you’re working on (which I think we’ve all had experiences with). And the next is you start to think more about building things smaller and smaller. And eventually getting into a big feature or a big fix. And I think that’s the holy grail for me as an engineer is getting to a point where I can look at a problem and break it down to the smallest possible parts it can be and then work on those independently.

    +

    CORALINE:  That’s so important. And I’ve been in this industry for over 20 years now and when I started we did a lot of prototyping. And the rule with the prototype is that you would write it and throw it away. The prototype was your learning exercise and it allowed you to explore different options for how to solve a given problem. And when you were done with it you literally threw it away. And we did it. And I think that with Agile, that’s something we’ve lost. Because we’re constantly thinking in two-week iterations. And you can’t spend the next sprint rebuilding what you did last sprint because that has to be done. It has to be cumulative, right? And I love the idea of throwing code away. It’s so freeing. And knowing that it’s okay to experiment and knowing that it’s okay to get it wrong because this isn’t what the code’s going to look like in its final form, I think that is so valuable. I wish we were more free in this industry to do things like that. Partly I think we don’t do it because we’re afraid. Partly because we get attached to the things that we create. And partly because our development methodologies don’t support it.

    +

    SAFIA:  Yeah. I think you just did a great job laying out all of the reasons that I think this happens. And I’m hoping that at some point I’ll have the chance to write a little bit more about my, let’s call it destruction-focused development. [Chuckles] But just the idea of being comfortable deleting things and not being attached to code is really difficult to manage, especially when your label is software engineer and that is what you do. And maybe not the ‘summarity’ of your existence as job but a big part of it.

    +

    CORALINE:  So Safia, when you destroy a branch, when you destroy the app and build it again, how tempted are you to hold onto precious parts of the code where you’re like, “This was really, really hard. I don’t want to have to write that again. I’ll just copy that one piece over.”

    +

    SAFIA:  Oh, I actually do that quite a bit, I’ll admit. So, it’s not completely destructive. But I would say it’s largely for things that are boilerplate or just logic that I know I’m going to need elsewhere that I can just copy over, which I’m comfortable with. But there are definitely times when I’ve had to write a lot of logic for something and then copy it over. And there are cases where it worked out well, where I was able to progress successfully with the new iteration of the app. And then there were cases where by bringing along that code, it actually brought all of the baggage that was needed to make it possible.

    +

    And I think that’s one thing I try to be mindful of, is every line of code has baggage no matter how insignificant. And when you bring it into a codebase, you’re bringing all of its baggage. Sometimes baggage is okay and sometimes it’s not. And I’ve definitely shot myself in the foot sometimes when I’ve brought a piece of code over and then I had to bring in the database migration and bring in this configuration and bring in all of this other stuff. It was just like, “Oh, come on. I could have just written this in a different way or taken this opportunity to think a little bit more about it.” But I would say in general I try to make sure that whenever I rewrite something, at least 80% of it is new, whether it’s using a different framework or focusing on different feature sets or fixing different bugs and letting other things slide. So yes, you caught me, Coraline. I am definitely guilty.

    +

    CORALINE:  [Laughs]

    +

    SAFIA:  Of copying things over. [Laughs]

    +

    CORALINE:  I am reminded of part of the process that I use when I’m writing music. Sometimes a song will get to a point where I don’t like it anymore. There’s something fundamental that isn’t working about the way it’s been structured or the way the parts are coming together. So, I’ll start over. And there’s a lot of temptation to say, “That guitar part was so hard to play. I’ll just bring over that one guitar part.” And I don’t do it typically. And what I try to tell myself is that the important parts of the song are the ones that I’m going to remember. And if I remember them, I can do them again. And if I don’t remember them, they weren’t important.

    +

    SAFIA:  That was so profound. I might need a couple of minutes to process it.

    +

    [Laughter]

    +

    JASMINE:  So, in the beginning when we just started to chat, you mentioned that you had some shenanigans back when you started coding. Can you explain or tell us about one of those shenanigans?

    +

    SAFIA:  Yeah. Coraline mentioned during my intro that I started to code when I was 11 years old. And I think one of the big things for me in my journey as a young technologist, young being tween to teenager, is just I had this moment where I realized I could control the machine. The machine wasn’t controlling me. And it was a huge transition in the way that I approached software because I now saw the computer as this thing that would respond to what I told it to do, not just where I would go to play Neopets and Miniclip games and whatever it is I was doing when I was 11. And you know, I miss those days so much because I was just gleefully hacking and I wasn’t doing it for work or to close issues or anything like that. One of the stories that I tell a lot and I think about it because it’s very funny is I kind of taught myself HTML. And my goal there was to make my Neopets page super awesome and glittery and the best thing ever. So, I picked up HTML and CSS. And I tinkered a lot with the visual elements of software. I did some stuff in Photoshop and InDesign and a lot of digital media type stuff.

    +

    But it was the summer before I started high school, I was watching a documentary series about the history of computers and it talked about Charles Babbage’s analytical engine and the ENIAC and early IBM computers, and just the entire history of the field. And the last episode talked about Larry Page and Sergey Brin and how they build Google and what that experience was like for them. And mind you, at this point I could write HTML and CSS. I was familiar with Photoshop. I knew that you could code computers or write software for them but I’ve never actually written a computer program. So, after watching that episode about Google and Larry and Sergey I thought, “I’m going to build a search engine,” because at that point in time I thought this was a trivial thing to do. So, I spent a lot of high school just in my spare time after school, on the weekends, during breaks, learning about search engines and machine learning and AI and how we manage information.

    +

    In this age, I built a silly toy search engine. I did a lot of machine learning related projects. I read a lot of books. And those were the best times in my career as a person in tech because I didn’t really have a goal. I wasn’t looking to be hired by a company. I wasn’t looking to get an offer to speak somewhere or to contribute to a project. I was just doing it because I thought it was fun and it made me happy. And I call those kinds of things shenanigans because there was no point to them. They were just fun and joyful. And I feel like I have lost a little bit of that sense of joy and play around what I build and how I build it that I’m kind of trying to bring back into the way I write software. But yeah, it’s been a while since I’ve been able to just have fun and do something pointless on a computer.

    +

    CORALINE:  It’s amazing what you can accomplish when you don’t know what the impossible is.

    +

    SAFIA:  Yeah. That’s a great way to phrase it. That was definitely my head space at the time.

    +

    JESSICA:  And you said there was no point to them, but didn’t we already establish that the whole point was making ourselves and others happy? [Laughs]

    +

    SAFIA:  Oh, yeah. I would say [inaudible]

    +

    JESSICA:  So in a way that it was direct. [Laughs]

    +

    SAFIA:  I would say this was… So, all of this was before I really started to think seriously about my life. I was doing this stuff when I was 14 and 15. And I was just a very self-centered teenager. [Laughs] So, the point for me was just to sit at a computer and do fun things and build cool things and not think a lot about why I was doing it or if I was going to make money off of it or if anyone was going to hire me. And I think as much as it is sometimes good to find things that make you happy or content, sometimes it’s good just to do things for the heck of it and for no reason at all other than it brings you joy at the time, as temporary as that time is.

    +

    CORALINE:  That’s so wonderful, Safia. We like to end every show with reflections, thinking back on the conversation we’ve had and picking out certain points or topics or ideas that were really meaningful to us. A couple of things that struck me about our conversation today Safia is first of all, the grid you described where you laid out these quadrants of what’s going to make you happy, what’s going to make someone else happy, and being really thoughtful about planning your finite energy and labor around those sorts of goals. I often find that I feel like I’m not doing enough and I haven’t defined what enough is. And I haven’t defined why I do the things that I do. So, I’d like to try that approach and see if that makes me more mindful about what my own success criteria are.

    +

    The other thing that struck me is the idea of being content versus being happy. And I don’t have an opinion on whether I think it’s more important to be content or to be happy. I’m actually afraid of being happy. I don’t know how I feel about being content. [Chuckles] So, that’s definitely something I want to think about some more. So, thank you for that.

    +

    SAFIA:  Awesome.

    +

    JASMINE:  I want to thank you for diving into your feelings around representation, specifically in public events like conferences and speaking and things like that. It’s something also that I’ve struggled with when an organizer reaches out to me and asks, “Hey, can you do this? Because we need more women,” or they’ll explicitly say that. And I’m like, “I understand but it also feels almost like,” you were mentioning ‘ingenuine’ in a way. And it’s really great to know that that’s not… that’s a common feeling and that I feel like I can really explore those thoughts without feeling… that’s not unique. It’s something that we all struggle with. And so, thank you for that.

    +

    JESSICA:  For the record, I don’t have any problem when conferences ask me, and I know they’re asking me because I’m a woman. Because I’m like, “I’m glad that y’all noticed that you needed more women speakers. And I’m glad conferences do this.” But I also don’t feel bad at all if I’m like, “No, sorry. Busy.” But my reflection from this episode goes back to something you said pretty early. You said that when you came to the US at 7 you learned to conform to standards and that now you’re returning to a more international focus. You’re able to, your phrase I think was go back and widen. You’re able to broaden your perspective because you remember reaching the perspective that most of us were born into. And that’s wonderful. That’s its own power that you came by through a lot of effort and continued effort. And the rest of us can gain that breadth too of both being able to meet American standards and understand and work with people outside of the US. We have to put in a lot of effort for that and I hope we do.

    +

    SAFIA:  So, I guess in chronological order, I think it was really great that we had the chance to talk a little bit about the fact that the Silicon Valley mono-culture doesn’t capture everything. And as connected as we think we are with the internet and social media and all that, there are still experiences that we don’t capture, even within our own borders in the states, that we need to think about. I also like Coraline thought our discussion about content versus happy was really great. And Jessica, you did a great job of just making me feel better about what I was going through and showing me that I was not alone and just expressing some of the ideas that I had in different and interesting ways. And finally, I thought our discussion about tokenism was really great and addressed the difficulty of the conversation for underrepresented individuals. And that it’s an ongoing journey for me and I’m sure many others. So yeah, thank you for an awesome conversation, everybody.

    +

    CORALINE:  Thank you, Safia. It was so wonderful to have you on the show today.

    +

    JESSICA:  Thank you, Safia.

    +

    JASMINE:  Thank you.

    +

    CORALINE:  I want to remind our listeners that we are listener-supported. And if you want to support conversations like the one we’ve had today with Safia, go to Patreon.com/GreaterThanCode, pledge at any level, and get access to our exclusive patron-only Slack community, which is a wonderful, wonderful, wonderful place to continue conversations and have conversations like this. So, please think about supporting this. If your company wants to support us, we have a prospectus for sponsorship on our website at GreaterThanCode.com. And thank you all and we will talk to you again very soon.

    +

     

    +

    This episode was brought to you by @therubyrep of DevReps, LLC. To pledge your support and to join our awesome Slack community, visit patreon.com/greaterthancode.

    +

    To make a one-time donation so that we can continue to bring you more content like this, please do so at paypal.me/devreps. You will also get an invitation to our Slack community this way as well.

    +

    Amazon links may be affiliate links, which means you’re supporting the show when you purchase our recommendations. Thanks!

    +]]> + Panelists:

    +

    Jasmine Greenaway | Jessica Kerr | Coraline Ada Ehmke

    +

    Guest Starring:

    +

    Safia Abdalla: @captainsafia | safia.rocks | Zarf | Tanmu Labs

    +

    Join Our Slack Channel!
    +
    Support us via Patreon!

    +

    Are you Greater Than Code?
    +
    Submit guest blog posts to mandy@greaterthancode.com

    +

    Show Notes:

    +

    00:53 – Safia’s Superpower: Sight

    +

    03:04 – Learning Languages — Both Human and Programming

    +

    The Sapir Whorf Hypothesis

    +

    07:56 – Being Empathetic in an International Perspective and Building Universal and Approachable Tech

    +

    11:19 – What does success look like for minorities in the Silicon Valley monoculture?; Being Tokenized

    +

    Admiral Grace Hopper

    +

    21:59 – Accepting Speaking Engagements Because of Who You Are (i.e. as a woman, minority, etc.)

    +

    24:07 – Writing Things Down to Balance Prioritizing Decisions

    +

    30:46 – Defining “Happy” and Always Feeling the Need to Do More

    +

    37:02 – Destruction-Focused Development

    + +

    +

    43:58 – Safia’s Early Coding “Shenanigans”

    +

    Reflections:

    +

    Coraline: Being thoughtful about planning finite energy and labor. Also being content vs being happy.

    +

    2sI94mC{rb=I&d*Ht{uDdi_q_jn22gSS*J`gd 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

%CO996);K`QMm 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 z zEZZitxQJ<*Jow;4=(^6x=oqi=e5HN=zKLIG5Cj}Lc#x&cBEusiH?1AFIut%9)i>Dq zSd7i#&+^tcmoLB4b;Oc-oul&4X;Qf4a*;@sE!(yc4qv>l{{e1A)PU^i1TYiOG*+ZQ zKloNpdC~+c|Ko8^S((B|Fol7{Kx%|Cf4@z2bF>#o}d`IiCQ6c1qustovSY%Md`< zG3x%J(5hKPvxd3^0R$j}D=?Ier6HPZGgvoWHhJqp(-mWDeHzse)zXbheY^IsWS-5H ze@{an;CS>WZ#WUu(|V1G`j>yG%DpaxQ_<}JnrIuYvGg%hq zs|<|4YPzc)LswT?|C4^tZ(!)4@m0CR@k?16y>c(#t2}K0SRD@)A981>_Lc|6y321MWf2%T$aqj9P8Gv=YdBb zV!2)+k&M%DN~HUeB^Kv0B$Hi?k4+LYEJpP>2$=WkH1vRe zEkcK3^Wo05tm+=d)pfqnm}0S7BGRmbu2XiZEZ6fy-8h{cDMZboGIe8LjlRm2^ zCb{RHd-G zJ>A^@zymj+Wj7Y__`A#T>h%Uvo~c!`EbD^C*RJcHqxjQxok%2d`hBC(IL9OCW}r>P z9L7drBHA2;3G{GP1W>TzM$`5H3ZMe2a<;@p0@IkdnAn6_*1{M%~O0M!2+8r|DKkXBx5~%-AltJYhR?VwF66*uIqko7o4r~36#Gwlic>`(KHQR z*HJ5_T2d*bx=5tDy3GAYfri%h??DmBwz;zk6k#ijhDIO)T+cndkMn1=l~M%wlezXizSe=;`VrWa|v9s#0F^IsTer{Ej+H!3l~p z5n{bV`S&kT(~YlhzLBySvRud>O`Cxm4&_7UF+zWyqkJ#Ki%nNQt57Vvy16W zjaXb`?$A7P-D>PRK0Y8t9*h%o4zsi3akT6)+MA~TL))0# zvjc zigKw+L=RynbxNUcQS)CU(%e9#djB=JsxA&`>?3Yfi0L*uQIv|Hn<0#lhVKQKx{hUs zNTf_OJwj(aO|#VG?v6*n3y7O>Chhg;nnA%Uu;5Ko42o1#1wnv9pn#Ta(x6U&N1*)n z)hYx^_(-9*%P&7r09`Tq`};9W1H&-*=*OPsv%mUl+_7crX>(Y|aoE3q-v!szG>tWD z*YU)YALW@J`4LvHUUN~eo?5L&A)ljAEK({KY1Hdfs}=hD`zaI(fa37sLwxza{S_l4 zW5i-HKK$g9OiWDDYPBwCYI~zltyXyJjn{eP(Z_C@7t!s8zKIB*`{PZNvo1Tomf@@a z`q*{d-+e!4^Jm}sEoL)^uXr7$6zkV-U}*ULN9>(#+I$M<^ReffJD4~-D&~6>u#Ce3i)6`Cmo;K<8x(f5P)Z=g z3^qO?40Hr^0E1lB`Sy{g{g#3tfO!Gct53D^%sej^eutf<6qAvUT=&wjH_Cs)vBr0C zg0|xD{A=V|RUKT&AILPXeQENoMF9OE#f(=0Q7<9f#^o1OAf-arF5wjfXz6~WCQvt* zG`|g?NOlHv4+`d|wD-mNvSf)-=j)6*-=LxQlMUU)T=*k2^-GhBmxCQ-8FIc$xBC{6 zV37~V#Y>}o1D5Bc_nmqfLZDWjVp0Yu)h;`IueHd~{ubO;i@H-sTj^j$42y^r!F64n zmUB8<{zCA4kFr~))~I3EZIT^HlJO2YqEQ^TNu^w-)@Yyv*Ixb# zt0#t7HU49CCN&bV4ExJjOtVQg>#%#NOlNPJcux$3!qh|HHPH-7ES#XPCy8Np6S93; z&1Fz^oJRh1ikhxzShhiDI!0e#fji4Ly_kdJSbgibbGu^i z;VIrY^bW^otMnwo`R~)6>Y`a|B9z2+ z8caYH^2LD*|2HT1(gKzb8|fZ z{pZ;A&fCn+&QPz_Xfzxg$H8-3rz7EmAi#B9=4NO4!{7fs>~I(>WMPMG{_@ZMjPX^g z_&wZ)Z`gftor8jZ`3b9~>w<|QWA z1}D*}5h8^Js4fs!X%*%pkt?J`5cqIRpc>~B5*aLtnDh_=L=2eVDoddhKJ6sgKuN@m zK%M8_AP^))lDqZ0c|<vdN+#2B2!aSSG7;zg37xKCHY+~ZW#i|_ii}<(^df0 ziXy<$+x>bF4Jz_o%R5-c$4EHLVPoj` z#G+B+9Wh+jYsVo6E`bb?3Q%V{8B&u-CGi}Oic`ljOwx%Yv1pX!&@is&k}s90Hmb}n zEm3bY2xK40?m^ZJcQe1RM8l~dU5z)s>#=rIg|Ssla-v2kmE!TI2eCzhWGaF32RUZ! zBWM=r>s!molQYatFEZ5Eff3RPg(HNF6r-c}a`5N@=B9RIhb?9@GraoRQFL7(Jw->{ zVq~<3SQwfujsEmHqLE?j-U(DtBcFc_VVuOW+xN>vBE;xOl7YTBnrN5d#mok(b{LOE zCI-Ujp-H4v>^{_Dp_t)UeqosI2giAR*A$5V|?^}cI^Ew zW}(V(hsj*g=SaRm@8&G4dXs$Vc!3BGwp*nzJxxsc^rSjj&`)q;_d#Mkoith=^>Ud& z1kiHX{rnDkhsH?7I>{MXe9xm;E>b8L=}o5j#gBc84LzNx(H{Qu3$Nh&9^2Am2umQP zkEX+f>Y{fdfnRngG;4&-FoRuvw0sv=N?NrBvQR>pCX1D2yr6~KYT>#~ln^K>ab=EN zdX`Y^JG81T!gLd(mpH>jjUg=6i7w-a6)n3`9#YisDWfPNM1`i7Bj|M~J0)t_GPV}R zRyMxxAy!iMjF5(Am^iH}QNn1-L=zS&(2=Sw`tI`w8IFuIXpWF$k+j{78??}MjhL1o z9E#8v>S29&GbfwJnRbqG!aYnzE#P9~Nf&{Su7OYjQ-v^uO^6WjTQrUFRz$p`gWvj> z{~KTW;(sL^iQxM_i;D~V{j=ZU5C7oz$>(wxdRc+5`6>266O$5y&F?&mpgj0K|RP)_U0&hQxv@8l)M>g z!7_n5Qz98>=&~g8wIZ1>v>kb^PSRPpWeA|)W(0aDiB??Ta_-Y@HNoXKC(=VV(8c=p zho&h;R!f=<4X4igQrw~|mq@TcBv_!^ee-5F=Y5A$H_A&9h^PMM%YZ;Agc1m$BWTAI zYeH+Q`*gEiCdNvvd*GiTgHQ+og0`wiLu->oryPc)q}r&VYdWTB5)Os2EQ?4o(w_PD zJ({jdv*i%@0jz8fwXziv(DDP8^2?Me79H_8=~SAbz7Z;o9F=Mnt+PsWi$z?E6F0l? zLt*@mDq|y6-g&)%8w6nbc!5qfyUfx2GV3P?ncCAy*i17#xRGi-i!}OJT$*QW)aJyT z&mGk|vnO7lR*w^?G^X9jnhkg2IR*OlCZ$q?O0mIR4@`jYP*Nk_5hff8aGfbaMun(7 zPD`42T8i$038JNCYK397(&zkv*|;)UmraUzqXcW{_; ztx7iEA`}YYc`k=%i{uK+Se8z`zLCD(b&O3e@pw$aQncIJY zs#6C~BNQ@;m^Ou0nf&}5T6cn)=2EU^sW!_<6t*5Fp(k+tCWXQPQbDc0G>Oh`nqHN@ zu+Ea3VP3sKRErb06Nsk5GQwDzi6%AV$}=vcbPS4BO zc=8z{MvR7E2Lxl`wRD=j^fiZB@Mc)_=g4^(N@Q_qp{o#K5u-z-h-e)o=;9b}U(egi z`wEXd`WTNq`WTIRov(f6%Y5xCUt;&JU9?&)Ow(k`wrwb-c;~IR&gpC(K6H?Md-u}Q z)5FUz?cn8?cJRh)uQD?;gHj4z*BM{6io3So!}<;D>Fw~ig z^Yi}&^1EH z*65pv&^Hlb-G`!l?X7>oJ4cV)&^FwC@4dw19XE8JHwvAd?`8w4)#^DVB;j!Q9B-df zXti3@YPHkvbzMIvR=!rNo#PR7v!GEXM3yikSUT)nf=U3# zdDpzXz(Hdc6WZ$Wp%oJ7s-O`gK?iZttxlpxqu@bAi_kCnStC}nS>3@lxsA1I9o<$p z+K7Okq5Zl_0?Gqsk<5~3o>}U}I($i>GQsKbmqregB2fl0bzm*+__eEmi-t#li;FBu zm{V-M0}>sO&%^R{vJeYYi?TmU*`MX4^YZoC$#uYm6sT9?9rRvt%Md`m&y6PlltRnR zv}fhTrPV#b6-2?S&H>O(@NWK1^L9ZjAsL$RnLcRXd+%0re1H#dDV!Yxf5s5{;#$H} z%e0+FBtZayXqPMLhK{Zq7zi*-q>?x-=S*4IsTMI zA7kUXK2}c-(PdTGxVDMVYJB~RC8A-8*H9?A$eJ~ERI|i#&SL9^^+bCnS6lj8YYybkET6Hf+ zPgck*)EFP0q<8BBoSZvII_c2e-+>AQb~H^S8bUX7ZE`?B!q8}$9?!q@3fMMx+_|0S zUwM(fsLz_oD4G<6bb)YT>d;~IRss9I2dQMm( zequ6;G&V9-RRrOH{=P+`;RO3;YiwN==i58?5_OVH_KmVprU{#~=vIhONHI6N2#G2i z?s|Z^!w#L@o%C+n#NoZWD9p}LP#%j*3rxgf^o)$KaN-2M@2@CD0~Y6I=p7lO*r)^T z&ZFjfJa^=6YU69zu2#_(im=*_aiG48ZkohKdvUZDn;w0L@BELyXWf?djBZ-R^qWV} zka&Sdxn3sUC{a@`c0eLw)c2S_P-b>}Pme_!~Iyz%;LRI61? z(`4V`yZU=f3wn_U_q(uIogjF;-8mW^`-}DHZEC zY`B4E{4$S_PEdgzhsVxW2};6icI z=PLz#-@o8;=MN~AQs*ppvkjn6L8FPqayy#bpiP3DR|553t49J18Y>DQRa9*sp7S6G zuvx-J64rFYFjq~4L@{`Z$9b50`F#EJ`11jpCO`-*5yFx-9eM|0%WjvtZ38|<+w}RW z$tPF_W(YXWGV^j4xl_XTIfwkxsbi4G01S)v`Myf~86SZQxXMK>D<}%~o`kNhHUad* zgexiKx{w#%^&n$!83HKqZcccXmOZ&rmT_?cNGXL{NfWx%O-5KzNcKRcc8R4vz}XN& z(cLd`YLfXW?R}{N`T*Atr+j|eH`VslDWyDJX>~C|u}$W*pL&4`2!i%oP3V}K*)~HI z5Vma$-5`(wzVG9C9-7eF#FJ`A7oXMviL(r;@d+e&O_yr3fuZX}?Ff-@jF4f|+Y`l? z0ZyZV<2Got8u)(O1ou?`+6#OZi;EmyXfZlC#7DQUqUa}?x8^yxYk|X48Tub6v2Q-X z@Wwb>`_~dQo4k{lV|Fe}&rpqM2MB!1wLFQG;H7t5?!Rv{xl$*3c#`c~Be>0@1WFN) zh1j$)#s2*{oW>zar3gZg(Ahacx#p4X8KTy(NTve(R)D65(6sg|pP%96i7B#~DuM6O z-`~mj=p<`bk7HYT0%wtUJVqpHque~YCeU1oZ$z5vx`e?d*Tja9c835 z&(HqoS{93SDzzq+VvGFTo225BXlj6M_dH1?`X+C`HN}y+BGqP#XCCh6qjx9RedsWO z*3DzjJi+{Yfy2Asp>HHYR>A5)gY3)_Ll4|bXxj)+j(0M3XohmwVz#Bo9?7C@U81u) z%>zIFG@0ch`@Z>2Y$XZMsrfDkj~?cp4I7!5Sk3H-DLl7{FBGoll3AEzptB#LS{PDM z4ScfADt%6wkAx%q*4@wGFBf5cKL;uqw1aup-LVdTsZMaRK=PpuG7IwvCGmWpe7Q=w zSz)0y%Nu?{y18P&0%Mn<>^@h$47|(2M3{t z3F|iLSeU>T)XO#EDoj+5f(BKmhM^2%MubGH3o~TWm54LjSmbEsI89k6qGC9$8Y(nK zIEdi}9=b3wGy`4ffI^o#C`F(G4wQD`o05nge9%}n7+hnlRR zi3qk4p)2U85|n5JH9YC!`x4O5l!lZNU)_Z0(AyZ*YL(yo{BJNja}vWe*?h+qo_gjP zKJzm_cRF%5n_VUp3Y}9H@B2RU^YaM6Fij>VC%N~&`}x$Tf0E6c@3(cIdP3z_rn2AR}72?6mx=l z`GXR=4{+r;Wwb1WKobT+2y{(DiT3p>rF>5vR;gs$Zzb^1glLmLT7YSUh*(jiDX|O- zUDvTq8$&Zr-}L2KKV9wAO-+CzAdr%ZQ=#hAv9%Cp#2_At)7jO*)(0Qpt)2TQWGfV^ z1(d50mPWWwBa#Ty@Ewk3j*&PHcW&rmjlPIt4v3be9C1YRb*=CeE%W-budwy5J4x#X@s1dx=`x8R z*VIu+YEx5muUX6B_!yaE$7o0o2ymPl@n(&5caoM4rqGFN8l$F#=KJ)nUd8e1Ui$lb zScr76=k<5Ed+ZT1hfmNSi_zEHLvA659};V4nGJ;_Vm(~PO*4$7Ne=5X%NvM zq}vD-Q8SDoLinu~v7Q)Zr_9{!Jg(~!h_->IAx(r5pcGR1n92kMLTOmSCeS1aErqRF z6ezPv-$<9$Pf6xE(%jF88YMy)4;KRi%jm#XQ3}mG0X~*)kswW!7%k0ddkDy&O$G@c zL%a5=81HA8rpd(W)y&SG~{48^`Gc0G8$z`+Tayg2n0#hfBOdYxbYr~ea{ZDE=w zhOU#(<(N8toJT+WI6XbR*Y#Xn3i*7Fy?b`C{qDQpm&U<26C)!dtXaE`J-c^Z_k9T= zSiNQqW8T;Q^NFDjrG8cl3mgZTh2;rfb zcAI#*mLujA?L@CSZGy#G`9BOIO}otP8j27zzzN_aHBQK51TVR$?VfjO9X+nZ$Q0c zsC_S7+eZEnAY>`V*ZUmZZPIFrnnTyC2I zioo~&fA-!p$gcBF^ZUIg-W)sUMx&95NDw4JQ4}Q&MP=>m>}Yo-+vS<@e()EUUEbQV z*Y?zUZCCAl*x>PcW=E@?+2B!F&5XhXC6W>oNRY@t1C7q{cK6Nk!kJN+c2?lgxsYxSosSw*N^fk+^SK zRFPK(MGvb;&8KDi_)0){P^0EmIQp6WXehk$^D|Vd7HZZ<%lOobRk9;VauYR{%d2cj zD(Lkz{mDV<85J$Q#?C_y0|y*5yM`Nb!OJn08D(onCxMbAY!+!|E2xG~HZjhLbMt7C zX$)OQ$X=4MZB$bcoWcsptc@)pm5$Ii5M_O>!OJhbMpt(h$0_mBD`kZGF-C@W(APIa zr98#Oi}TFP7im}$P%uP5IvybvZ=s6`q?^Eu?4jvqIevPbQn|_6${Y_J=;G)j+gZ-9 zP+TqZg->;274n=pzs~vC3_bk=#Nwlv=`GZP1wzq0ecciT57+jvN^?{-8=GO`+5N2K z1CCE0V>GJ~4n@dxSWHY7P-Kge6K2=JM`<<&F)Fh>|MCL6dNf`Bui&VRY$OHnvQeye|F-G?vG9n$$#%x>LZ3DlFKOOgAra zAoeiB<_H=J2%U;o;g!lSaeRmUsUsMHj^lf%sDO%xh9Z30vYWQq_IXz>Cm&f1!{G4Y zBfNU-WjeAQY#rYQv~P4LE}Z9&zxfS*`r{vCU8mGM6bkc?fA^p8g)e^T8h--EaVQlF zOixeq!VACTm(M=S>dGpv=i<2@zVG4t{@a9jDJ8#n?it`sCjF{PEFLG20bl)lfB$Yi z6*t7TZC*QmoUi=)-zJ^DP50CLTthmO;nAZ7$zahz)^8iWvZcfTRL*6a0aJc2$bG&BrqgmF=$+B+H&zZ;FB zT>%uw4ZOB1vUUA8lMoiVY@!?ScNCu9GZEkb*H#{hJA8~y>TFj3NSG8k3ahh-{~!r+ z!P_dI6a<1IhV)PpI^1HA=sO8;lC}qsO`MkBt^ktmukM?-X_^cS46wMk__le75Q46* zuD7+UmP)0&Qt5fm2tZP{lfd5p0|zLDMS|Fkt<~G}$6L^tJ4ZIR`PF@azc(bwH1v)H zEKVtHQ}Fvw;eFl(Z}tItbNu_2f9(`Mi3}uxkVqM9iZyJuZ@s+?_)2@1K;n1~fn(t~ zHeTS-vRc@7tL+=4X@tWOgb?la6wf9I0({@c4m<)sKq``fj}0-fwTJRb5zWvUIXKAL z%qo!)lWaOhc0Nh6l3;K=O`+N#=&3XONQ_8gk>1@3lgmYVV=eYPHN=kk7|Zn#YsF>i zHNn8BLOs_aXxdCE=lJWNYQ$s@*;o(z_w6JWa}lCOKDWR_4~AJ?zlf>l2)s_*z+`x2 z51N+2@t0W3)d-s=@wi9Pci70+34$_qSCg|BG&Ex$=~N2K%Ft+4@thT0r-7yjqA`|)P?9%X1C!OUD0*8|O|Q(2#3 zHMh>(`~clONup|vM93v+w!LLE&Btq&uv%3TeM9Wtet-vd`y}*bdb>4rCBek`I*Ksp z4c93xPSU@1J2JhC%%a7 zeHVKkJ;GAQ4AZC1L&HW$foogjr)KCJ+k(|>;N;g(fmk-p;Fb}La+9z0Y{9i!Joncx za!i%@TOVS0|9*!&%8)XkD#g=mtHu9Yle{>X}p+DOvD&WbmRIihe!4j zNS{i*OmDP{oriW%?PxH3YM6st4k3Jn?o2n9^m(XzKL;K@#B;AbPt|E)HGFgn^3FQa z_OYaeBW+Af0ue<~RYJmSd)^7qgo5eo=voBfLtKyJ%K%NNn3%-XIGUmnRU_?K_CRvH z@FGukJxxf9q6!r+aA`@GrduMdb|IMNnabaw;*-_7FhrQJh|zFs*wUim)QKojRMhtV zioo-IG~u^bV5CBTkD>EZ<6{r0!{(GR}Q#>V