mirror of
https://github.com/amtoaer/bili-sync.git
synced 2026-09-05 07:28:04 +08:00
refactor: 把循环拆分到外层,提取公共代码 (#151)
This commit is contained in:
@@ -11,12 +11,12 @@ use sea_orm::entity::prelude::*;
|
|||||||
use sea_orm::ActiveValue::Set;
|
use sea_orm::ActiveValue::Set;
|
||||||
use sea_orm::{DatabaseConnection, QuerySelect, TransactionTrait};
|
use sea_orm::{DatabaseConnection, QuerySelect, TransactionTrait};
|
||||||
|
|
||||||
use crate::adapter::VideoListModel;
|
use crate::adapter::{error_fetch_video_detail, VideoListModel};
|
||||||
use crate::bilibili::{BiliClient, BiliError, Collection, CollectionItem, CollectionType, Video, VideoInfo};
|
use crate::bilibili::{self, BiliClient, Collection, CollectionItem, CollectionType, VideoInfo};
|
||||||
use crate::config::{CONFIG, TEMPLATE};
|
use crate::config::TEMPLATE;
|
||||||
|
use crate::utils::id_time_key;
|
||||||
use crate::utils::model::create_video_pages;
|
use crate::utils::model::create_video_pages;
|
||||||
use crate::utils::status::Status;
|
use crate::utils::status::Status;
|
||||||
use crate::utils::{delay, id_time_key};
|
|
||||||
|
|
||||||
pub async fn collection_from<'a>(
|
pub async fn collection_from<'a>(
|
||||||
collection_item: &'a CollectionItem,
|
collection_item: &'a CollectionItem,
|
||||||
@@ -144,42 +144,30 @@ impl VideoListModel for collection::Model {
|
|||||||
|
|
||||||
async fn fetch_videos_detail(
|
async fn fetch_videos_detail(
|
||||||
&self,
|
&self,
|
||||||
bili_clent: &BiliClient,
|
video: bilibili::Video<'_>,
|
||||||
videos_model: Vec<video::Model>,
|
video_model: video::Model,
|
||||||
connection: &DatabaseConnection,
|
connection: &DatabaseConnection,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for video_model in videos_model {
|
let info: Result<_> = async { Ok((video.get_tags().await?, video.get_view_info().await?)) }.await;
|
||||||
let video = Video::new(bili_clent, video_model.bvid.clone());
|
match info {
|
||||||
let info: Result<_> = async { Ok((video.get_tags().await?, video.get_view_info().await?)) }.await;
|
Ok((tags, view_info)) => {
|
||||||
match info {
|
let VideoInfo::View { pages, .. } = &view_info else {
|
||||||
Ok((tags, view_info)) => {
|
unreachable!("view_info must be VideoInfo::View")
|
||||||
let VideoInfo::View { pages, .. } = &view_info else {
|
};
|
||||||
unreachable!("view_info must be VideoInfo::View")
|
let txn = connection.begin().await?;
|
||||||
};
|
// 将分页信息写入数据库
|
||||||
let txn = connection.begin().await?;
|
create_video_pages(pages, &video_model, &txn).await?;
|
||||||
// 将分页信息写入数据库
|
// 将页标记和 tag 写入数据库
|
||||||
create_video_pages(pages, &video_model, &txn).await?;
|
let mut video_active_model = self.video_model_by_info(&view_info, Some(video_model));
|
||||||
// 将页标记和 tag 写入数据库
|
video_active_model.single_page = Set(Some(pages.len() == 1));
|
||||||
let mut video_active_model = self.video_model_by_info(&view_info, Some(video_model));
|
video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap()));
|
||||||
video_active_model.single_page = Set(Some(pages.len() == 1));
|
video_active_model.save(&txn).await?;
|
||||||
video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap()));
|
txn.commit().await?;
|
||||||
video_active_model.save(&txn).await?;
|
}
|
||||||
txn.commit().await?;
|
Err(e) => {
|
||||||
}
|
error_fetch_video_detail(e, video_model, connection).await?;
|
||||||
Err(e) => {
|
}
|
||||||
error!(
|
};
|
||||||
"获取视频 {} - {} 的详细信息失败,错误为:{}",
|
|
||||||
&video_model.bvid, &video_model.name, e
|
|
||||||
);
|
|
||||||
if let Some(BiliError::RequestFailed(-404, _)) = e.downcast_ref::<BiliError>() {
|
|
||||||
let mut video_active_model: video::ActiveModel = video_model.into();
|
|
||||||
video_active_model.valid = Set(false);
|
|
||||||
video_active_model.save(connection).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
delay(CONFIG.delay.fetch_video_detail.as_ref()).await;
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ use sea_orm::entity::prelude::*;
|
|||||||
use sea_orm::ActiveValue::Set;
|
use sea_orm::ActiveValue::Set;
|
||||||
use sea_orm::{DatabaseConnection, QuerySelect, TransactionTrait};
|
use sea_orm::{DatabaseConnection, QuerySelect, TransactionTrait};
|
||||||
|
|
||||||
use crate::adapter::VideoListModel;
|
use crate::adapter::{error_fetch_video_detail, VideoListModel};
|
||||||
use crate::bilibili::{BiliClient, BiliError, FavoriteList, Video, VideoInfo};
|
use crate::bilibili::{self, BiliClient, FavoriteList, VideoInfo};
|
||||||
use crate::config::{CONFIG, TEMPLATE};
|
use crate::config::TEMPLATE;
|
||||||
|
use crate::utils::id_time_key;
|
||||||
use crate::utils::model::create_video_pages;
|
use crate::utils::model::create_video_pages;
|
||||||
use crate::utils::status::Status;
|
use crate::utils::status::Status;
|
||||||
use crate::utils::{delay, id_time_key};
|
|
||||||
|
|
||||||
pub async fn favorite_from<'a>(
|
pub async fn favorite_from<'a>(
|
||||||
fid: &str,
|
fid: &str,
|
||||||
@@ -134,39 +134,27 @@ impl VideoListModel for favorite::Model {
|
|||||||
|
|
||||||
async fn fetch_videos_detail(
|
async fn fetch_videos_detail(
|
||||||
&self,
|
&self,
|
||||||
bili_clent: &BiliClient,
|
video: bilibili::Video<'_>,
|
||||||
videos_model: Vec<video::Model>,
|
video_model: video::Model,
|
||||||
connection: &DatabaseConnection,
|
connection: &DatabaseConnection,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for video_model in videos_model {
|
let info: Result<_> = async { Ok((video.get_tags().await?, video.get_pages().await?)) }.await;
|
||||||
let video = Video::new(bili_clent, video_model.bvid.clone());
|
match info {
|
||||||
let info: Result<_> = async { Ok((video.get_tags().await?, video.get_pages().await?)) }.await;
|
Ok((tags, pages_info)) => {
|
||||||
match info {
|
let txn = connection.begin().await?;
|
||||||
Ok((tags, pages_info)) => {
|
// 将分页信息写入数据库
|
||||||
let txn = connection.begin().await?;
|
create_video_pages(&pages_info, &video_model, &txn).await?;
|
||||||
// 将分页信息写入数据库
|
// 将页标记和 tag 写入数据库
|
||||||
create_video_pages(&pages_info, &video_model, &txn).await?;
|
let mut video_active_model: video::ActiveModel = video_model.into();
|
||||||
// 将页标记和 tag 写入数据库
|
video_active_model.single_page = Set(Some(pages_info.len() == 1));
|
||||||
let mut video_active_model: video::ActiveModel = video_model.into();
|
video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap()));
|
||||||
video_active_model.single_page = Set(Some(pages_info.len() == 1));
|
video_active_model.save(&txn).await?;
|
||||||
video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap()));
|
txn.commit().await?;
|
||||||
video_active_model.save(&txn).await?;
|
}
|
||||||
txn.commit().await?;
|
Err(e) => {
|
||||||
}
|
error_fetch_video_detail(e, video_model, connection).await?;
|
||||||
Err(e) => {
|
}
|
||||||
error!(
|
};
|
||||||
"获取视频 {} - {} 的详细信息失败,错误为:{}",
|
|
||||||
&video_model.bvid, &video_model.name, e
|
|
||||||
);
|
|
||||||
if let Some(BiliError::RequestFailed(-404, _)) = e.downcast_ref::<BiliError>() {
|
|
||||||
let mut video_active_model: video::ActiveModel = video_model.into();
|
|
||||||
video_active_model.valid = Set(false);
|
|
||||||
video_active_model.save(connection).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
delay(CONFIG.delay.fetch_video_detail.as_ref()).await;
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,12 @@ use async_trait::async_trait;
|
|||||||
pub use collection::collection_from;
|
pub use collection::collection_from;
|
||||||
pub use favorite::favorite_from;
|
pub use favorite::favorite_from;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
|
use sea_orm::entity::prelude::*;
|
||||||
|
use sea_orm::ActiveValue::Set;
|
||||||
use sea_orm::DatabaseConnection;
|
use sea_orm::DatabaseConnection;
|
||||||
use watch_later::watch_later_from;
|
use watch_later::watch_later_from;
|
||||||
|
|
||||||
use crate::bilibili::{BiliClient, CollectionItem, VideoInfo};
|
use crate::bilibili::{self, BiliClient, BiliError, CollectionItem, VideoInfo};
|
||||||
|
|
||||||
pub enum Args<'a> {
|
pub enum Args<'a> {
|
||||||
Favorite { fid: &'a str },
|
Favorite { fid: &'a str },
|
||||||
@@ -35,6 +37,23 @@ pub async fn video_list_from<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn error_fetch_video_detail(
|
||||||
|
e: anyhow::Error,
|
||||||
|
video_model: bili_sync_entity::video::Model,
|
||||||
|
connection: &DatabaseConnection,
|
||||||
|
) -> Result<()> {
|
||||||
|
error!(
|
||||||
|
"获取视频 {} - {} 的详细信息失败,错误为:{}",
|
||||||
|
&video_model.bvid, &video_model.name, e
|
||||||
|
);
|
||||||
|
if let Some(BiliError::RequestFailed(-404, _)) = e.downcast_ref::<BiliError>() {
|
||||||
|
let mut video_active_model: bili_sync_entity::video::ActiveModel = video_model.into();
|
||||||
|
video_active_model.valid = Set(false);
|
||||||
|
video_active_model.save(connection).await?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait VideoListModel {
|
pub trait VideoListModel {
|
||||||
/* 逻辑相关 */
|
/* 逻辑相关 */
|
||||||
@@ -65,8 +84,8 @@ pub trait VideoListModel {
|
|||||||
/// 获取视频 model 中缺失的信息
|
/// 获取视频 model 中缺失的信息
|
||||||
async fn fetch_videos_detail(
|
async fn fetch_videos_detail(
|
||||||
&self,
|
&self,
|
||||||
bili_client: &BiliClient,
|
video: bilibili::Video<'_>,
|
||||||
videos_model: Vec<bili_sync_entity::video::Model>,
|
video_model: bili_sync_entity::video::Model,
|
||||||
connection: &DatabaseConnection,
|
connection: &DatabaseConnection,
|
||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ use sea_orm::entity::prelude::*;
|
|||||||
use sea_orm::ActiveValue::Set;
|
use sea_orm::ActiveValue::Set;
|
||||||
use sea_orm::{DatabaseConnection, QuerySelect, TransactionTrait};
|
use sea_orm::{DatabaseConnection, QuerySelect, TransactionTrait};
|
||||||
|
|
||||||
use crate::adapter::VideoListModel;
|
use crate::adapter::{error_fetch_video_detail, VideoListModel};
|
||||||
use crate::bilibili::{BiliClient, BiliError, Video, VideoInfo, WatchLater};
|
use crate::bilibili::{self, BiliClient, VideoInfo, WatchLater};
|
||||||
use crate::config::{CONFIG, TEMPLATE};
|
use crate::config::TEMPLATE;
|
||||||
|
use crate::utils::id_time_key;
|
||||||
use crate::utils::model::create_video_pages;
|
use crate::utils::model::create_video_pages;
|
||||||
use crate::utils::status::Status;
|
use crate::utils::status::Status;
|
||||||
use crate::utils::{delay, id_time_key};
|
|
||||||
|
|
||||||
pub async fn watch_later_from<'a>(
|
pub async fn watch_later_from<'a>(
|
||||||
path: &Path,
|
path: &Path,
|
||||||
@@ -130,39 +130,27 @@ impl VideoListModel for watch_later::Model {
|
|||||||
|
|
||||||
async fn fetch_videos_detail(
|
async fn fetch_videos_detail(
|
||||||
&self,
|
&self,
|
||||||
bili_clent: &BiliClient,
|
video: bilibili::Video<'_>,
|
||||||
videos_model: Vec<video::Model>,
|
video_model: video::Model,
|
||||||
connection: &DatabaseConnection,
|
connection: &DatabaseConnection,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for video_model in videos_model {
|
let info: Result<_> = async { Ok((video.get_tags().await?, video.get_pages().await?)) }.await;
|
||||||
let video = Video::new(bili_clent, video_model.bvid.clone());
|
match info {
|
||||||
let info: Result<_> = async { Ok((video.get_tags().await?, video.get_pages().await?)) }.await;
|
Ok((tags, pages_info)) => {
|
||||||
match info {
|
let txn = connection.begin().await?;
|
||||||
Ok((tags, pages_info)) => {
|
// 将分页信息写入数据库
|
||||||
let txn = connection.begin().await?;
|
create_video_pages(&pages_info, &video_model, &txn).await?;
|
||||||
// 将分页信息写入数据库
|
// 将页标记和 tag 写入数据库
|
||||||
create_video_pages(&pages_info, &video_model, &txn).await?;
|
let mut video_active_model: video::ActiveModel = video_model.into();
|
||||||
// 将页标记和 tag 写入数据库
|
video_active_model.single_page = Set(Some(pages_info.len() == 1));
|
||||||
let mut video_active_model: video::ActiveModel = video_model.into();
|
video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap()));
|
||||||
video_active_model.single_page = Set(Some(pages_info.len() == 1));
|
video_active_model.save(&txn).await?;
|
||||||
video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap()));
|
txn.commit().await?;
|
||||||
video_active_model.save(&txn).await?;
|
}
|
||||||
txn.commit().await?;
|
Err(e) => {
|
||||||
}
|
error_fetch_video_detail(e, video_model, connection).await?;
|
||||||
Err(e) => {
|
}
|
||||||
error!(
|
};
|
||||||
"获取视频 {} - {} 的详细信息失败,错误为:{}",
|
|
||||||
&video_model.bvid, &video_model.name, e
|
|
||||||
);
|
|
||||||
if let Some(BiliError::RequestFailed(-404, _)) = e.downcast_ref::<BiliError>() {
|
|
||||||
let mut video_active_model: video::ActiveModel = video_model.into();
|
|
||||||
video_active_model.valid = Set(false);
|
|
||||||
video_active_model.save(connection).await?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
delay(CONFIG.delay.fetch_video_detail.as_ref()).await;
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -75,9 +75,13 @@ pub async fn fetch_video_details(
|
|||||||
) -> Result<Box<dyn VideoListModel>> {
|
) -> Result<Box<dyn VideoListModel>> {
|
||||||
video_list_model.log_fetch_video_start();
|
video_list_model.log_fetch_video_start();
|
||||||
let videos_model = video_list_model.unfilled_videos(connection).await?;
|
let videos_model = video_list_model.unfilled_videos(connection).await?;
|
||||||
video_list_model
|
for video_model in videos_model {
|
||||||
.fetch_videos_detail(bili_client, videos_model, connection)
|
let video = Video::new(bili_client, video_model.bvid.clone());
|
||||||
.await?;
|
video_list_model
|
||||||
|
.fetch_videos_detail(video, video_model, connection)
|
||||||
|
.await?;
|
||||||
|
delay(CONFIG.delay.fetch_video_detail.as_ref()).await;
|
||||||
|
}
|
||||||
video_list_model.log_fetch_video_end();
|
video_list_model.log_fetch_video_end();
|
||||||
Ok(video_list_model)
|
Ok(video_list_model)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user