use rss::Channel; use sea_orm::{ ColumnTrait, EntityTrait, JoinType, Order, QueryFilter, QueryOrder, QuerySelect, RelationTrait, }; use url::Url; use crate::{ app::AppContextTrait, errors::{RecorderError, RecorderResult}, models::{ episodes, feeds::{self, FeedSource, RssFeedTrait, SubscriptionEpisodesFeed}, subscription_episode, subscriptions, }, }; pub enum Feed { SubscritpionEpisodes(SubscriptionEpisodesFeed), } impl Feed { pub async fn from_model(ctx: &dyn AppContextTrait, m: feeds::Model) -> RecorderResult { match m.feed_source { FeedSource::SubscriptionEpisode => { let db = ctx.db(); let (subscription, episodes) = if let Some(subscription_id) = m.subscription_id && let Some(subscription) = subscriptions::Entity::find() .filter(subscriptions::Column::Id.eq(subscription_id)) .one(db) .await? { let episodes = episodes::Entity::find() .join( JoinType::InnerJoin, episodes::Relation::SubscriptionEpisode.def(), ) .join( JoinType::InnerJoin, subscription_episode::Relation::Subscription.def(), ) .filter(subscriptions::Column::Id.eq(subscription_id)) .order_by(episodes::Column::EnclosurePubDate, Order::Desc) .all(db) .await?; (subscription, episodes) } else { return Err(RecorderError::from_model_not_found("Subscription")); }; Ok(Feed::SubscritpionEpisodes( SubscriptionEpisodesFeed::from_model(m, subscription, episodes), )) } } } pub fn into_rss_channel( self, ctx: &dyn AppContextTrait, api_base: &Url, ) -> RecorderResult { match self { Self::SubscritpionEpisodes(feed) => feed.into_channel(ctx, api_base), } } }