chore: 略微推进
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
128
src/core/command.rs
Normal 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
1
src/core/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod command;
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::error;
|
||||
|
||||
pub mod bilibili;
|
||||
pub mod command;
|
||||
pub mod core;
|
||||
pub mod database;
|
||||
pub mod downloader;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user