mirror of
https://github.com/amtoaer/bili-sync.git
synced 2026-08-28 03:28:05 +08:00
feat: 简单写个运行框架
This commit is contained in:
@@ -0,0 +1,80 @@
|
|||||||
|
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(())
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
use sea_orm::{ConnectOptions, Database, DatabaseConnection};
|
||||||
|
|
||||||
|
use crate::Result;
|
||||||
|
pub async fn database_connection() -> Result<DatabaseConnection> {
|
||||||
|
let opt = ConnectOptions::new("sqlite://./data.sqlite?mode=rwc");
|
||||||
|
Ok(Database::connect(opt).await?)
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
use std::error;
|
use std::error;
|
||||||
|
|
||||||
pub mod bilibili;
|
pub mod bilibili;
|
||||||
|
pub mod command;
|
||||||
|
pub mod database;
|
||||||
pub mod downloader;
|
pub mod downloader;
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, Box<dyn error::Error>>;
|
type Result<T> = std::result::Result<T, Box<dyn error::Error>>;
|
||||||
|
|||||||
+11
-63
@@ -1,69 +1,17 @@
|
|||||||
use std::path::Path;
|
use std::sync::Arc;
|
||||||
use std::rc::Rc;
|
|
||||||
|
|
||||||
use bili_sync::bilibili::{
|
use bili_sync::bilibili::BiliClient;
|
||||||
AudioQuality, BestStream, BiliClient, FavoriteList, FilterOption, Video, VideoCodecs,
|
use bili_sync::command::handle_favorite;
|
||||||
VideoQuality,
|
use bili_sync::database::database_connection;
|
||||||
};
|
|
||||||
use bili_sync::downloader::Downloader;
|
|
||||||
use futures_util::{pin_mut, StreamExt};
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() -> ! {
|
||||||
let bili_client = Rc::new(BiliClient::new(None));
|
let connection = Arc::new(database_connection().await.unwrap());
|
||||||
let favorite_list = FavoriteList::new(bili_client.clone(), "52642258".to_string());
|
let bili_client = Arc::new(BiliClient::new(None));
|
||||||
dbg!(favorite_list.get_info().await.unwrap());
|
loop {
|
||||||
|
for fid in [52642258] {
|
||||||
let video_stream = favorite_list.into_video_stream();
|
let _ = handle_favorite(bili_client.clone(), fid, connection.clone()).await;
|
||||||
// from doc: https://docs.rs/async-stream/latest/async_stream/
|
|
||||||
pin_mut!(video_stream);
|
|
||||||
|
|
||||||
let third_video_info = dbg!(video_stream.skip(2).next().await.unwrap());
|
|
||||||
let third_video = Video::new(bili_client.clone(), third_video_info.bvid);
|
|
||||||
dbg!(third_video.get_tags().await.unwrap());
|
|
||||||
|
|
||||||
let pages = dbg!(third_video.get_pages().await.unwrap());
|
|
||||||
let best_stream = dbg!(third_video
|
|
||||||
.get_page_analyzer(&pages[0])
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.best_stream(&FilterOption {
|
|
||||||
video_max_quality: VideoQuality::QualityDolby,
|
|
||||||
video_min_quality: VideoQuality::Quality360p,
|
|
||||||
audio_max_quality: AudioQuality::QualityDolby,
|
|
||||||
audio_min_quality: AudioQuality::Quality64k,
|
|
||||||
codecs: Rc::new(vec![VideoCodecs::HEV, VideoCodecs::AVC]),
|
|
||||||
no_dolby_video: false,
|
|
||||||
no_dolby_audio: false,
|
|
||||||
no_hdr: false,
|
|
||||||
no_hires: false,
|
|
||||||
}))
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let downloader = Downloader::default();
|
|
||||||
let base = Path::new("./");
|
|
||||||
let output_path = base.join(format!("{}.mp4", third_video_info.title));
|
|
||||||
|
|
||||||
match best_stream {
|
|
||||||
BestStream::Mixed(stream) => {
|
|
||||||
let url = dbg!(stream.url());
|
|
||||||
downloader.fetch(url, &output_path).await.unwrap();
|
|
||||||
}
|
|
||||||
BestStream::VideoAudio { video, audio } => {
|
|
||||||
let url = dbg!(video.url());
|
|
||||||
let Some(audio) = audio else {
|
|
||||||
downloader.fetch(url, &output_path).await.unwrap();
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
let video_path = base.join(format!("{}_video_tmp", third_video_info.title));
|
|
||||||
downloader.fetch(url, &video_path).await.unwrap();
|
|
||||||
let url = dbg!(audio.url());
|
|
||||||
let audio_path = base.join(format!("{}_audio_tmp", third_video_info.title));
|
|
||||||
downloader.fetch(url, &audio_path).await.unwrap();
|
|
||||||
downloader
|
|
||||||
.merge(&video_path, &audio_path, &output_path)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
|
tokio::time::sleep(std::time::Duration::from_secs(60)).await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user