91 lines
3.1 KiB
Rust
91 lines
3.1 KiB
Rust
use loco_rs::app::AppContext;
|
|
use sea_orm::{prelude::*, sea_query::OnConflict, ActiveValue, Condition, QueryOrder, QuerySelect};
|
|
|
|
pub use crate::models::entities::downloads::*;
|
|
use crate::{
|
|
models::subscriptions::{self, SubscriptionCategory},
|
|
parsers::mikan::{parse_mikan_rss_items_from_rss_link, MikanRssItem},
|
|
};
|
|
|
|
#[async_trait::async_trait]
|
|
impl ActiveModelBehavior for ActiveModel {}
|
|
|
|
impl ActiveModel {
|
|
pub fn from_mikan_rss_item(m: MikanRssItem, subscription_id: i32) -> Self {
|
|
let _ = Self {
|
|
origin_name: ActiveValue::Set(m.title.clone()),
|
|
display_name: ActiveValue::Set(m.title),
|
|
subscription_id: ActiveValue::Set(subscription_id),
|
|
status: ActiveValue::Set(DownloadStatus::Pending),
|
|
mime: ActiveValue::Set(DownloadMime::BitTorrent),
|
|
url: ActiveValue::Set(m.url),
|
|
curr_size: ActiveValue::Set(m.content_length.as_ref().map(|_| 0)),
|
|
all_size: ActiveValue::Set(m.content_length),
|
|
homepage: ActiveValue::Set(m.homepage),
|
|
..Default::default()
|
|
};
|
|
todo!()
|
|
}
|
|
}
|
|
|
|
impl Model {
|
|
pub async fn pull_subscription(
|
|
ctx: AppContext,
|
|
item: &subscriptions::Model,
|
|
) -> eyre::Result<Vec<i32>> {
|
|
let db = &ctx.db;
|
|
match &item.category {
|
|
SubscriptionCategory::Mikan => {
|
|
let items = parse_mikan_rss_items_from_rss_link(&item.source_url).await?;
|
|
let all_items = items.collect::<Vec<_>>();
|
|
|
|
let last_old_id = {
|
|
Entity::find()
|
|
.select_only()
|
|
.column(Column::Id)
|
|
.order_by_desc(Column::Id)
|
|
.filter(Column::SubscriptionId.eq(item.id))
|
|
.one(db)
|
|
.await?
|
|
}
|
|
.map(|i| i.id);
|
|
|
|
if all_items.is_empty() {
|
|
return Ok(vec![]);
|
|
}
|
|
|
|
let new_items = all_items
|
|
.into_iter()
|
|
.map(|i| ActiveModel::from_mikan_rss_item(i, item.id));
|
|
|
|
let insert_result = Entity::insert_many(new_items)
|
|
.on_conflict(OnConflict::column(Column::Url).do_nothing().to_owned())
|
|
.exec(db)
|
|
.await?;
|
|
|
|
let insert_ids = Entity::find()
|
|
.select_only()
|
|
.column(Column::Id)
|
|
.filter({
|
|
let mut cond = Condition::all()
|
|
.add(Column::SubscriptionId.eq(item.id))
|
|
.add(Column::Id.lte(insert_result.last_insert_id));
|
|
|
|
if let Some(last_old_id) = last_old_id {
|
|
cond = cond.add(Column::Id.gt(last_old_id))
|
|
}
|
|
|
|
cond
|
|
})
|
|
.all(db)
|
|
.await?;
|
|
|
|
Ok(insert_ids.into_iter().map(|i| i.id).collect::<Vec<_>>())
|
|
}
|
|
_ => {
|
|
todo!("other subscription categories")
|
|
}
|
|
}
|
|
}
|
|
}
|