feat: update

This commit is contained in:
master 2024-02-24 22:05:07 +08:00
parent 56a6190cc2
commit 686faaf060
3 changed files with 65 additions and 44 deletions

View File

@ -43,7 +43,6 @@ impl MigrationTrait for Migration {
&[ &[
subscriptions::SubscriptionCategory::Mikan, subscriptions::SubscriptionCategory::Mikan,
subscriptions::SubscriptionCategory::Manual, subscriptions::SubscriptionCategory::Manual,
subscriptions::SubscriptionCategory::Bangumi,
], ],
) )
.await?; .await?;

View File

@ -4,12 +4,12 @@ use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive( #[derive(
Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, Serialize, Deserialize, DeriveDisplay, Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, Serialize, Deserialize, DeriveDisplay,
)] )]
#[sea_orm( #[sea_orm(
rs_type = "String", rs_type = "String",
db_type = "Enum", db_type = "Enum",
enum_name = "subscription_category" enum_name = "subscription_category"
)] )]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum SubscriptionCategory { pub enum SubscriptionCategory {
@ -17,8 +17,6 @@ pub enum SubscriptionCategory {
Mikan, Mikan,
#[sea_orm(string_value = "manual")] #[sea_orm(string_value = "manual")]
Manual, Manual,
#[sea_orm(string_value = "bangumi")]
Bangumi,
} }
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)] #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]

View File

@ -1,67 +1,91 @@
use std::collections::HashMap; use sea_orm::{prelude::*, ActiveValue, Condition, QuerySelect, QueryOrder};
use sea_orm::{prelude::*, ActiveValue, Condition, QuerySelect, SelectColumns}; use sea_orm::sea_query::OnConflict;
use crate::models::_entities::downloads::*; use crate::models::_entities::downloads::*;
use crate::models::prelude::{SubscriptionCategory, subscriptions}; use crate::models::prelude::{SubscriptionCategory, subscriptions};
use crate::subscriptions::mikan::MikanSubscriptionEngine; use crate::subscriptions::mikan::{MikanSubscriptionEngine, MikanSubscriptionItem};
#[async_trait::async_trait] #[async_trait::async_trait]
impl ActiveModelBehavior for ActiveModel {} impl ActiveModelBehavior for ActiveModel {}
impl ActiveModel {
pub fn from_mikan_subscription_item(m: MikanSubscriptionItem, subscription_id: i32) -> Self {
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),
all_size: ActiveValue::Set(m.content_length.unwrap_or_default()),
curr_size: ActiveValue::Set(0),
..Default::default()
}
}
}
impl Model { impl Model {
pub async fn pull_subscription( pub async fn pull_subscription(
db: &DatabaseConnection, db: &DatabaseConnection,
item: &subscriptions::Model, item: &subscriptions::Model,
) -> eyre::Result<()> { ) -> eyre::Result<Vec<i32>> {
match &item.category { match &item.category {
SubscriptionCategory::Mikan => { SubscriptionCategory::Mikan => {
let items = let items =
MikanSubscriptionEngine::subscription_items_from_rss_url(&item.source_url). MikanSubscriptionEngine::subscription_items_from_rss_url(&item.source_url).
await?; await?;
let items = items.collect::<Vec<_>>(); let all_items = items.collect::<Vec<_>>();
let mut all_items = items
.into_iter()
.map(|item| (item.url.clone(), item))
.collect::<HashMap<_, _>>();
let existed_items = { let last_old_id = {
Entity::find() Entity::find()
.filter(
Condition::all()
.add(Column::SubscriptionId.eq(item.id))
.add(Column::Url.is_in(all_items.keys().cloned()))
)
.select_only() .select_only()
.select_column(Column::Url) .column(Column::Id)
.all(db).await? .order_by_desc(Column::Id)
}; .filter(Column::SubscriptionId.eq(item.id))
.one(db).await?
}.map(|i| i.id);
for dl in existed_items { if all_items.is_empty() {
all_items.remove(&dl.url as &str); return Ok(vec![]);
} }
let new_items = all_items.into_values().map(|i| { let new_items = all_items.into_iter().map(|i| {
ActiveModel { ActiveModel::from_mikan_subscription_item(i, item.id)
origin_name: ActiveValue::Set(i.title.clone()),
display_name: ActiveValue::Set(i.title),
subscription_id: ActiveValue::Set(item.id),
status: ActiveValue::Set(DownloadStatus::Pending),
mime: ActiveValue::Set(DownloadMime::BitTorrent),
url: ActiveValue::Set(i.url),
all_size: ActiveValue::Set(i.content_length.unwrap_or_default()),
curr_size: ActiveValue::Set(0),
..Default::default()
}
}); });
Entity::insert_many(new_items) let insert_result = Entity::insert_many(new_items)
.on_conflict(
OnConflict::column(Column::Url)
.do_nothing()
.to_owned()
)
.exec(db) .exec(db)
.await?; .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") todo!("other subscription categories")
} }
} }
Ok(())
} }
} }