feat: 支持删除视频源 (#525)

This commit is contained in:
ᴀᴍᴛᴏᴀᴇʀ
2025-11-07 15:15:03 +08:00
committed by GitHub
parent 854d39cf88
commit a871db655f
8 changed files with 148 additions and 3 deletions

View File

@@ -110,4 +110,9 @@ impl VideoSource for collection::Model {
.await?;
Ok((updated_model.into(), Box::pin(collection.into_video_stream())))
}
async fn delete_from_db(self, conn: &impl ConnectionTrait) -> Result<()> {
self.delete(conn).await?;
Ok(())
}
}

View File

@@ -73,4 +73,9 @@ impl VideoSource for favorite::Model {
.await?;
Ok((updated_model.into(), Box::pin(favorite.into_video_stream())))
}
async fn delete_from_db(self, conn: &impl ConnectionTrait) -> Result<()> {
self.delete(conn).await?;
Ok(())
}
}

View File

@@ -121,6 +121,8 @@ pub trait VideoSource {
})?;
Ok(())
}
async fn delete_from_db(self, conn: &impl ConnectionTrait) -> Result<()>;
}
pub enum _ActiveModel {

View File

@@ -114,4 +114,9 @@ impl VideoSource for submission::Model {
};
Ok((updated_model.into(), video_stream))
}
async fn delete_from_db(self, conn: &impl ConnectionTrait) -> Result<()> {
self.delete(conn).await?;
Ok(())
}
}

View File

@@ -58,4 +58,9 @@ impl VideoSource for watch_later::Model {
let watch_later = WatchLater::new(bili_client, credential);
Ok((self.into(), Box::pin(watch_later.into_video_stream())))
}
async fn delete_from_db(self, conn: &impl ConnectionTrait) -> Result<()> {
self.delete(conn).await?;
Ok(())
}
}

View File

@@ -9,9 +9,9 @@ use bili_sync_entity::*;
use bili_sync_migration::Expr;
use sea_orm::ActiveValue::Set;
use sea_orm::entity::prelude::*;
use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, QuerySelect, TransactionTrait};
use sea_orm::{ColumnTrait, DatabaseConnection, EntityTrait, QuerySelect, QueryTrait, TransactionTrait};
use crate::adapter::_ActiveModel;
use crate::adapter::{_ActiveModel, VideoSource as _, VideoSourceEnum};
use crate::api::error::InnerApiError;
use crate::api::request::{
DefaultPathRequest, InsertCollectionRequest, InsertFavoriteRequest, InsertSubmissionRequest,
@@ -33,7 +33,10 @@ pub(super) fn router() -> Router {
"/video-sources/{type}/default-path",
get(get_video_sources_default_path),
) // 仅用于前端获取默认路径
.route("/video-sources/{type}/{id}", put(update_video_source))
.route(
"/video-sources/{type}/{id}",
put(update_video_source).delete(remove_video_source),
)
.route("/video-sources/{type}/{id}/evaluate", post(evaluate_video_source))
.route("/video-sources/favorites", post(insert_favorite))
.route("/video-sources/collections", post(insert_collection))
@@ -242,6 +245,43 @@ pub async fn update_video_source(
Ok(ApiResponse::ok(UpdateVideoSourceResponse { rule_display }))
}
pub async fn remove_video_source(
Path((source_type, id)): Path<(String, i32)>,
Extension(db): Extension<DatabaseConnection>,
) -> Result<ApiResponse<bool>, ApiError> {
// 不允许删除稍后再看
let video_source: Option<VideoSourceEnum> = match source_type.as_str() {
"collections" => collection::Entity::find_by_id(id).one(&db).await?.map(Into::into),
"favorites" => favorite::Entity::find_by_id(id).one(&db).await?.map(Into::into),
"submissions" => submission::Entity::find_by_id(id).one(&db).await?.map(Into::into),
_ => return Err(InnerApiError::BadRequest("Invalid video source type".to_string()).into()),
};
let Some(video_source) = video_source else {
return Err(InnerApiError::NotFound(id).into());
};
let txn = db.begin().await?;
page::Entity::delete_many()
.filter(
page::Column::VideoId.in_subquery(
video::Entity::find()
.filter(video_source.filter_expr())
.select_only()
.column(video::Column::Id)
.as_query()
.to_owned(),
),
)
.exec(&txn)
.await?;
video::Entity::delete_many()
.filter(video_source.filter_expr())
.exec(&txn)
.await?;
video_source.delete_from_db(&txn).await?;
txn.commit().await?;
Ok(ApiResponse::ok(true))
}
pub async fn evaluate_video_source(
Path((source_type, id)): Path<(String, i32)>,
Extension(db): Extension<DatabaseConnection>,