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,);