hammond-data: Do batch indexing of new_episodes.
This commit is contained in:
parent
93372a30d0
commit
098c5755b0
@ -10,7 +10,7 @@ chrono = "0.4.0"
|
|||||||
derive_builder = "0.5.1"
|
derive_builder = "0.5.1"
|
||||||
dotenv = "0.10.1"
|
dotenv = "0.10.1"
|
||||||
error-chain = "0.11.0"
|
error-chain = "0.11.0"
|
||||||
itertools = "0.7.4"
|
itertools = "0.7.6"
|
||||||
lazy_static = "1.0.0"
|
lazy_static = "1.0.0"
|
||||||
log = "0.3.8"
|
log = "0.3.8"
|
||||||
r2d2 = "0.8.2"
|
r2d2 = "0.8.2"
|
||||||
|
|||||||
@ -6,8 +6,8 @@ use diesel::prelude::*;
|
|||||||
|
|
||||||
use database::connection;
|
use database::connection;
|
||||||
use errors::*;
|
use errors::*;
|
||||||
use models::{Episode, EpisodeCleanerQuery, EpisodeMinimal, EpisodeWidgetQuery, Podcast,
|
use models::{Episode, EpisodeCleanerQuery, EpisodeMinimal, EpisodeWidgetQuery, NewEpisode,
|
||||||
PodcastCoverQuery, Source};
|
Podcast, PodcastCoverQuery, Source};
|
||||||
|
|
||||||
pub fn get_sources() -> Result<Vec<Source>> {
|
pub fn get_sources() -> Result<Vec<Source>> {
|
||||||
use schema::source::dsl::*;
|
use schema::source::dsl::*;
|
||||||
@ -322,6 +322,18 @@ pub fn episode_exists(title_: &str, podcast_id_: i32) -> Result<bool> {
|
|||||||
.map_err(From::from)
|
.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<usize> {
|
pub fn update_none_to_played_now(parent: &Podcast) -> Result<usize> {
|
||||||
use schema::episode::dsl::*;
|
use schema::episode::dsl::*;
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
//! Index Feeds.
|
//! Index Feeds.
|
||||||
|
|
||||||
use futures::future::*;
|
use futures::future::*;
|
||||||
// use futures::prelude::*;
|
use itertools::{Either, Itertools};
|
||||||
use errors::*;
|
|
||||||
use models::{NewEpisode, NewPodcast, Podcast};
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use rss;
|
use rss;
|
||||||
// use models::{IndexState, Source};
|
// use futures::prelude::*;
|
||||||
// use pipeline::*;
|
|
||||||
|
use dbqueries;
|
||||||
|
use errors::*;
|
||||||
|
use models::{IndexState, Update};
|
||||||
|
use models::{NewEpisode, NewPodcast, Podcast};
|
||||||
|
use pipeline::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// Wrapper struct that hold a `Source` id and the `rss::Channel`
|
/// 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.
|
/// Index the contents of the RSS `Feed` into the database.
|
||||||
pub fn index(&self) -> Result<()> {
|
pub fn index(&self) -> Result<()> {
|
||||||
let pd = self.parse_podcast().into_podcast()?;
|
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.
|
// TODO: Refactor transcactions and find a way to do it in parallel.
|
||||||
|
#[allow(dead_code)]
|
||||||
fn index_channel_items(&self, pd: &Podcast) -> Result<()> {
|
fn index_channel_items(&self, pd: &Podcast) -> Result<()> {
|
||||||
let episodes = self.parse_channel_items(pd);
|
let episodes = self.parse_channel_items(pd);
|
||||||
|
|
||||||
@ -42,6 +46,7 @@ impl Feed {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn parse_podcast(&self) -> NewPodcast {
|
fn parse_podcast(&self) -> NewPodcast {
|
||||||
NewPodcast::new(&self.channel, self.source_id)
|
NewPodcast::new(&self.channel, self.source_id)
|
||||||
}
|
}
|
||||||
@ -51,6 +56,7 @@ impl Feed {
|
|||||||
Box::new(ok(self.parse_podcast()))
|
Box::new(ok(self.parse_podcast()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn parse_channel_items(&self, pd: &Podcast) -> Vec<NewEpisode> {
|
fn parse_channel_items(&self, pd: &Podcast) -> Vec<NewEpisode> {
|
||||||
let items = self.channel.items();
|
let items = self.channel.items();
|
||||||
let new_episodes: Vec<_> = items
|
let new_episodes: Vec<_> = items
|
||||||
@ -60,21 +66,36 @@ impl Feed {
|
|||||||
|
|
||||||
new_episodes
|
new_episodes
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// fn parse_channel_items2(
|
|
||||||
// &self,
|
|
||||||
// pd: &Podcast,
|
|
||||||
// ) -> (Vec<IndexState<NewEpisode>>, Vec<IndexState<NewEpisode>>) {
|
|
||||||
// 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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user