diff --git a/crates/bili_sync/src/adapter/watch_later.rs b/crates/bili_sync/src/adapter/watch_later.rs index 6a071bc..3f8e214 100644 --- a/crates/bili_sync/src/adapter/watch_later.rs +++ b/crates/bili_sync/src/adapter/watch_later.rs @@ -103,7 +103,7 @@ impl VideoListModel for watch_later::Model { .and(video::Column::Bvid.is_in(bvids)), ) .select_only() - .columns([video::Column::Bvid, video::Column::Pubtime]) + .columns([video::Column::Bvid, video::Column::Favtime]) .into_tuple() .all(connection) .await? @@ -136,18 +136,15 @@ impl VideoListModel for watch_later::Model { ) -> Result<()> { for video_model in videos_model { let video = Video::new(bili_clent, video_model.bvid.clone()); - let info: Result<_> = async { Ok((video.get_tags().await?, video.get_view_info().await?)) }.await; + let info: Result<_> = async { Ok((video.get_tags().await?, video.get_pages().await?)) }.await; match info { - Ok((tags, view_info)) => { - let VideoInfo::View { pages, .. } = &view_info else { - unreachable!("view_info must be VideoInfo::View") - }; + Ok((tags, pages_info)) => { let txn = connection.begin().await?; // 将分页信息写入数据库 - create_video_pages(pages, &video_model, &txn).await?; + create_video_pages(&pages_info, &video_model, &txn).await?; // 将页标记和 tag 写入数据库 - let mut video_active_model = self.video_model_by_info(&view_info, Some(video_model)); - video_active_model.single_page = Set(Some(pages.len() == 1)); + let mut video_active_model: video::ActiveModel = video_model.into(); + video_active_model.single_page = Set(Some(pages_info.len() == 1)); video_active_model.tags = Set(Some(serde_json::to_value(tags).unwrap())); video_active_model.save(&txn).await?; txn.commit().await?; diff --git a/crates/bili_sync/src/bilibili/mod.rs b/crates/bili_sync/src/bilibili/mod.rs index 56d261f..cdb1f4f 100644 --- a/crates/bili_sync/src/bilibili/mod.rs +++ b/crates/bili_sync/src/bilibili/mod.rs @@ -83,6 +83,24 @@ pub enum VideoInfo { pubtime: DateTime, attr: i32, }, + /// 从稍后再看中获取的视频信息 + WatchLater { + title: String, + bvid: String, + #[serde(rename = "desc")] + intro: String, + #[serde(rename = "pic")] + cover: String, + #[serde(rename = "owner")] + upper: Upper, + #[serde(with = "ts_seconds")] + ctime: DateTime, + #[serde(rename = "add_at", with = "ts_seconds")] + fav_time: DateTime, + #[serde(rename = "pubdate", with = "ts_seconds")] + pubtime: DateTime, + state: i32, + }, /// 从视频列表中获取的视频信息 Simple { bvid: String, @@ -97,11 +115,11 @@ pub enum VideoInfo { #[cfg(test)] mod tests { - use futures::StreamExt; - use tokio::pin; + use futures::{pin_mut, StreamExt}; use super::*; + #[ignore = "only for manual test"] #[tokio::test] async fn assert_video_info() { let bili_client = BiliClient::new(); @@ -114,15 +132,16 @@ mod tests { }; let collection = Collection::new(&bili_client, &collection_item); let stream = collection.into_simple_video_stream(); - pin!(stream); + pin_mut!(stream); assert!(matches!(stream.next().await, Some(VideoInfo::Simple { .. }))); let favorite = FavoriteList::new(&bili_client, "3084505258".to_string()); let stream = favorite.into_video_stream(); - pin!(stream); + pin_mut!(stream); assert!(matches!(stream.next().await, Some(VideoInfo::Detail { .. }))); let watch_later = WatchLater::new(&bili_client); let stream = watch_later.into_video_stream(); - pin!(stream); - assert!(matches!(stream.next().await, Some(VideoInfo::Simple { .. }))); + pin_mut!(stream); + println!("{:?}", stream.next().await); + assert!(matches!(stream.next().await, Some(VideoInfo::WatchLater { .. }))); } } diff --git a/crates/bili_sync/src/main.rs b/crates/bili_sync/src/main.rs index d170d55..bacaa19 100644 --- a/crates/bili_sync/src/main.rs +++ b/crates/bili_sync/src/main.rs @@ -65,6 +65,7 @@ async fn main() { error!("处理稍后再看时遇到非预期的错误:{e}"); } } + info!("稍后再看处理完毕"); info!("本轮任务执行完毕,等待下一轮执行"); tokio::time::sleep(std::time::Duration::from_secs(CONFIG.interval)).await; } diff --git a/crates/bili_sync/src/utils/convert.rs b/crates/bili_sync/src/utils/convert.rs index 399936f..99a0191 100644 --- a/crates/bili_sync/src/utils/convert.rs +++ b/crates/bili_sync/src/utils/convert.rs @@ -90,6 +90,34 @@ impl VideoInfo { upper_face: Set(upper.face.clone()), ..base_model }, + VideoInfo::WatchLater { + title, + bvid, + intro, + cover, + upper, + ctime, + fav_time, + pubtime, + state, + } => bili_sync_entity::video::ActiveModel { + bvid: Set(bvid.clone()), + name: Set(title.clone()), + category: Set(2), // 稍后再看里的内容类型肯定是视频 + intro: Set(intro.clone()), + cover: Set(cover.clone()), + ctime: Set(ctime.naive_utc()), + pubtime: Set(pubtime.naive_utc()), + favtime: Set(fav_time.naive_utc()), + download_status: Set(0), + valid: Set(*state == 0), + tags: Set(None), + single_page: Set(None), + upper_id: Set(upper.mid), + upper_name: Set(upper.name.clone()), + upper_face: Set(upper.face.clone()), + ..base_model + }, } } @@ -108,6 +136,12 @@ impl VideoInfo { "upper_name": &upper.name, "upper_mid": &upper.mid, })), + VideoInfo::WatchLater { title, bvid, upper, .. } => Some(json!({ + "bvid": &bvid, + "title": &title, + "upper_name": &upper.name, + "upper_mid": &upper.mid, + })), } } @@ -116,6 +150,7 @@ impl VideoInfo { // 对于合集没有 fav_time,只能用 pubtime 代替 VideoInfo::Simple { bvid, pubtime, .. } => id_time_key(bvid, pubtime), VideoInfo::Detail { bvid, fav_time, .. } => id_time_key(bvid, fav_time), + VideoInfo::WatchLater { bvid, fav_time, .. } => id_time_key(bvid, fav_time), // 详情接口返回的数据仅用于填充详情,不会被作为 video_key _ => unreachable!(), } @@ -125,6 +160,7 @@ impl VideoInfo { match self { VideoInfo::Simple { bvid, .. } => bvid, VideoInfo::Detail { bvid, .. } => bvid, + VideoInfo::WatchLater { bvid, .. } => bvid, // 同上 _ => unreachable!(), }