chore: 略微推进

This commit is contained in:
amtoaer
2024-03-23 19:46:18 +08:00
parent 8fa5172d41
commit ab20b85b39
6 changed files with 133 additions and 84 deletions

View File

@@ -9,5 +9,5 @@ pub use analyzer::{
};
pub use client::{BiliClient, Client};
pub use credential::Credential;
pub use favorite_list::FavoriteList;
pub use favorite_list::{FavoriteList, FavoriteListInfo, VideoInfo};
pub use video::Video;

View File

@@ -1,80 +0,0 @@
use std::path::Path;
use std::sync::Arc;
use entity::*;
use futures_util::{pin_mut, StreamExt};
use migration::OnConflict;
use sea_orm::entity::prelude::*;
use sea_orm::ActiveValue::Set;
use crate::bilibili::{BiliClient, FavoriteList};
use crate::Result;
pub async fn handle_favorite(
bili_client: Arc<BiliClient>,
fid: i32,
connection: Arc<DatabaseConnection>,
) -> Result<()> {
let favorite_list = FavoriteList::new(bili_client.clone(), fid.to_string());
let info = favorite_list.get_info().await?;
let favorite_obj = favorite::Entity::insert(favorite::ActiveModel {
f_id: Set(fid),
name: Set(info.title),
path: Set("/home/amtoaer/Documents/code/rust/bili-sync/video".to_string()),
enabled: Set(true),
..Default::default()
})
.on_conflict(
OnConflict::column(favorite::Column::FId)
.update_column(favorite::Column::Name)
.update_column(favorite::Column::Path)
.update_column(favorite::Column::Enabled)
.to_owned(),
)
.exec_with_returning(connection.as_ref())
.await?;
println!(
"Hi there! I'm going to scan this favorite: {:?}",
favorite_obj
);
let video_stream = favorite_list.into_video_stream();
pin_mut!(video_stream);
while let Some(v) = video_stream.next().await {
let not_exists = video::Entity::find()
.filter(
video::Column::Bvid
.eq(&v.bvid)
.and(video::Column::FavoriteId.eq(fid)),
)
.count(connection.as_ref())
.await
.is_ok_and(|x| x == 0);
if !not_exists {
break;
}
let _video_obj = video::Entity::insert(video::ActiveModel {
favorite_id: Set(fid),
bvid: Set(v.bvid),
path: Set(Path::new(favorite_obj.path.as_str())
.join(&v.title)
.to_str()
.unwrap()
.to_string()),
name: Set(v.title),
category: Set(v.vtype.to_string()),
intro: Set(v.intro),
cover: Set(v.cover),
ctime: Set(v.ctime.to_string()),
pubtime: Set(v.pubtime.to_string()),
favtime: Set(v.fav_time.to_string()),
downloaded: Set(false),
valid: Set(true),
tags: Set("[]".to_string()),
single_page: Set(false),
..Default::default()
})
.exec_with_returning(connection.as_ref())
.await?;
}
Ok(())
}

128
src/core/command.rs Normal file
View File

@@ -0,0 +1,128 @@
use std::collections::HashSet;
use std::path::Path;
use std::sync::Arc;
use entity::*;
use futures_util::{pin_mut, StreamExt};
use migration::OnConflict;
use sea_orm::entity::prelude::*;
use sea_orm::ActiveValue::Set;
use sea_orm::QuerySelect;
use crate::bilibili::{BiliClient, FavoriteList, FavoriteListInfo, VideoInfo};
use crate::Result;
pub async fn process_favorite(
bili_client: Arc<BiliClient>,
fid: i32,
connection: Arc<DatabaseConnection>,
) -> Result<()> {
let favorite_list = FavoriteList::new(bili_client.clone(), fid.to_string());
let info = favorite_list.get_info().await?;
let favorite_obj = handle_favorite_info(&info, connection.as_ref()).await?;
println!(
"Hi there! I'm going to scan this favorite: {:?}",
favorite_obj
);
let video_stream = favorite_list.into_video_stream().chunks(10);
pin_mut!(video_stream);
while let Some(videos_info) = video_stream.next().await {
let exist_bvids_pubtimes =
exists_bvids_favtime(&videos_info, fid, connection.as_ref()).await?;
let video_info_to_create = videos_info
.iter()
.filter(|v| !exist_bvids_pubtimes.contains(&(v.bvid.clone(), v.fav_time.to_string())))
.collect::<Vec<&VideoInfo>>();
let len = video_info_to_create.len();
if !video_info_to_create.is_empty() {
create_videos(video_info_to_create, &favorite_obj, connection.as_ref()).await?;
}
if videos_info.len() != len {
break;
}
}
Ok(())
}
// 根据获得的收藏夹信息,插入或更新数据库中的收藏夹,并返回收藏夹对象
async fn handle_favorite_info(
info: &FavoriteListInfo,
connection: &DatabaseConnection,
) -> Result<favorite::Model> {
Ok(favorite::Entity::insert(favorite::ActiveModel {
f_id: Set(info.id as i32),
name: Set(info.title.to_string()),
path: Set("/home/amtoaer/Documents/code/rust/bili-sync/video".to_string()),
enabled: Set(true),
..Default::default()
})
.on_conflict(
OnConflict::column(favorite::Column::FId)
.update_column(favorite::Column::Name)
.update_column(favorite::Column::Path)
.update_column(favorite::Column::Enabled)
.to_owned(),
)
.exec_with_returning(connection)
.await?)
}
// 获取数据库中存在的与该视频 favorite_id 和 bvid 重合的视频
async fn exists_bvids_favtime(
videos_info: &[VideoInfo],
fid: i32,
connection: &DatabaseConnection,
) -> Result<HashSet<(String, String)>> {
let bvids = videos_info
.iter()
.map(|v| v.bvid.clone())
.collect::<Vec<String>>();
let exist_bvid_favtime = video::Entity::find()
.filter(
video::Column::FavoriteId
.eq(fid)
.and(video::Column::Bvid.is_in(bvids)),
)
.select_only()
.columns([video::Column::Bvid, video::Column::Favtime])
.all(connection)
.await?
.into_iter()
.map(|v| (v.bvid, v.favtime))
.collect::<HashSet<(String, String)>>();
Ok(exist_bvid_favtime)
}
async fn create_videos(
videos_info: Vec<&VideoInfo>,
favorite_obj: &favorite::Model,
connection: &DatabaseConnection,
) -> Result<u64> {
let video_models = videos_info
.iter()
.map(move |v| video::ActiveModel {
favorite_id: Set(favorite_obj.id),
bvid: Set(v.bvid.clone()),
path: Set(Path::new(favorite_obj.path.as_str())
.join(&v.title)
.to_str()
.unwrap()
.to_string()),
name: Set(v.title.clone()),
category: Set(v.vtype.to_string()),
intro: Set(v.intro.clone()),
cover: Set(v.cover.clone()),
ctime: Set(v.ctime.to_string()),
pubtime: Set(v.pubtime.to_string()),
favtime: Set(v.fav_time.to_string()),
downloaded: Set(false),
valid: Set(true),
tags: Set("[]".to_string()),
single_page: Set(false),
..Default::default()
})
.collect::<Vec<video::ActiveModel>>();
Ok(video::Entity::insert_many(video_models)
.exec_without_returning(connection)
.await?)
}

1
src/core/mod.rs Normal file
View File

@@ -0,0 +1 @@
pub mod command;

View File

@@ -1,7 +1,7 @@
use std::error;
pub mod bilibili;
pub mod command;
pub mod core;
pub mod database;
pub mod downloader;

View File

@@ -1,7 +1,7 @@
use std::sync::Arc;
use bili_sync::bilibili::BiliClient;
use bili_sync::command::handle_favorite;
use bili_sync::core::command::process_favorite;
use bili_sync::database::database_connection;
#[tokio::main]
@@ -10,7 +10,7 @@ async fn main() -> ! {
let bili_client = Arc::new(BiliClient::new(None));
loop {
for fid in [52642258] {
let _ = handle_favorite(bili_client.clone(), fid, connection.clone()).await;
let _ = process_favorite(bili_client.clone(), fid, connection.clone()).await;
}
tokio::time::sleep(std::time::Duration::from_secs(60)).await;
}