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::Manual,
subscriptions::SubscriptionCategory::Bangumi,
],
)
.await?;

View File

@ -4,12 +4,12 @@ use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(
Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, Serialize, Deserialize, DeriveDisplay,
Clone, Debug, PartialEq, Eq, EnumIter, DeriveActiveEnum, Serialize, Deserialize, DeriveDisplay,
)]
#[sea_orm(
rs_type = "String",
db_type = "Enum",
enum_name = "subscription_category"
rs_type = "String",
db_type = "Enum",
enum_name = "subscription_category"
)]
#[serde(rename_all = "snake_case")]
pub enum SubscriptionCategory {
@ -17,8 +17,6 @@ pub enum SubscriptionCategory {
Mikan,
#[sea_orm(string_value = "manual")]
Manual,
#[sea_orm(string_value = "bangumi")]
Bangumi,
}
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
@ -41,9 +39,9 @@ pub struct Model {
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::subscribers::Entity",
from = "Column::SubscriberId",
to = "super::subscribers::Column::Id"
belongs_to = "super::subscribers::Entity",
from = "Column::SubscriberId",
to = "super::subscribers::Column::Id"
)]
Subscriber,
#[sea_orm(has_many = "super::bangumi::Entity")]

View File

@ -1,67 +1,91 @@
use std::collections::HashMap;
use sea_orm::{prelude::*, ActiveValue, Condition, QuerySelect, SelectColumns};
use sea_orm::{prelude::*, ActiveValue, Condition, QuerySelect, QueryOrder};
use sea_orm::sea_query::OnConflict;
use crate::models::_entities::downloads::*;
use crate::models::prelude::{SubscriptionCategory, subscriptions};
use crate::subscriptions::mikan::MikanSubscriptionEngine;
use crate::subscriptions::mikan::{MikanSubscriptionEngine, MikanSubscriptionItem};
#[async_trait::async_trait]
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 {
pub async fn pull_subscription(
db: &DatabaseConnection,
item: &subscriptions::Model,
) -> eyre::Result<()> {
) -> eyre::Result<Vec<i32>> {
match &item.category {
SubscriptionCategory::Mikan => {
let items =
MikanSubscriptionEngine::subscription_items_from_rss_url(&item.source_url).
await?;
let items = items.collect::<Vec<_>>();
let mut all_items = items
.into_iter()
.map(|item| (item.url.clone(), item))
.collect::<HashMap<_, _>>();
let all_items = items.collect::<Vec<_>>();
let existed_items = {
let last_old_id = {
Entity::find()
.filter(
Condition::all()
.add(Column::SubscriptionId.eq(item.id))
.add(Column::Url.is_in(all_items.keys().cloned()))
)
.select_only()
.select_column(Column::Url)
.all(db).await?
};
.column(Column::Id)
.order_by_desc(Column::Id)
.filter(Column::SubscriptionId.eq(item.id))
.one(db).await?
}.map(|i| i.id);
for dl in existed_items {
all_items.remove(&dl.url as &str);
if all_items.is_empty() {
return Ok(vec![]);
}
let new_items = all_items.into_values().map(|i| {
ActiveModel {
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()
}
let new_items = all_items.into_iter().map(|i| {
ActiveModel::from_mikan_subscription_item(i, item.id)
});
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)
.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")
}
}
Ok(())
}
}