fix: 修复视频标签名称解析 (#742)

This commit is contained in:
ᴀᴍᴛᴏᴀᴇʀ
2026-08-21 13:17:12 +08:00
committed by GitHub
parent c7d9fa9b9d
commit 0e5778b6cb
4 changed files with 48 additions and 6 deletions
+12 -4
View File
@@ -1,4 +1,4 @@
use anyhow::{Context, Result, ensure};
use anyhow::{Context, Result, bail, ensure};
use futures::TryStreamExt;
use futures::stream::FuturesUnordered;
use prost::Message;
@@ -101,12 +101,20 @@ impl<'a> Video<'a> {
.json::<serde_json::Value>()
.await?
.validate()?;
Ok(res["data"]
res["data"]
.as_array_mut()
.context("tags is not an array")?
.iter_mut()
.filter_map(|v| if let Value::String(s) = v.take() { Some(s) } else { None })
.collect())
.map(|v| {
if let Some(tag) = v.get_mut("tag_name")
&& let Value::String(s) = tag.take()
{
Ok(s)
} else {
bail!("tag_name is not a string");
}
})
.collect()
}
pub async fn get_danmaku_writer(&self, page: &'a PageInfo) -> Result<DanmakuWriter<'a>> {
+15 -2
View File
@@ -219,7 +219,7 @@ pub async fn download_unprocessed_videos(
let unhandled_videos_pages = filter_unhandled_video_pages(video_source.filter_expr(), connection).await?;
let mut assigned_upper_ids = HashSet::new();
let tasks = stream::iter(unhandled_videos_pages)
.map(|(video_model, pages_model)| {
.map(|(mut video_model, pages_model)| {
// 这里按理说是可以直接拿到 assigned_uppers 的,但rust 会错误地认为它引用了 local variable
// 导致编译出错,暂时先这样单独提取出一个 owned 的 upper id 列表,再在任务内部筛选
let task_uids = video_model
@@ -227,7 +227,19 @@ pub async fn download_unprocessed_videos(
.map(|u| u.mid)
.filter(|uid| assigned_upper_ids.insert(*uid))
.collect::<Vec<_>>();
download_video_pages(video_model, pages_model, task_uids, cx)
async move {
// b 站接口调整导致一段时间内的 tag 被错误保存为 [],迁移文件会将当前的 [] 更新为 None
// 此处在下载前发现 None 的 tag 尝试重新填充以修复错误
if video_model.tags.is_none() {
video_model.tags = Some(
Video::new(cx.bili_client, video_model.bvid.as_str(), &cx.config.credential)
.get_tags()
.await?
.into(),
);
}
download_video_pages(video_model, pages_model, task_uids, cx).await
}
})
.buffer_unordered(config.concurrent_limit.video);
let mut risk_control_related_error = None;
@@ -359,6 +371,7 @@ pub async fn download_video_pages(
}
}
let mut video_active_model: video::ActiveModel = video_model.into();
video_active_model.tags.reset();
video_active_model.download_status = Set(status.into());
video_active_model.path = Set(base_path.to_string_lossy().to_string());
Ok(video_active_model)
+2
View File
@@ -12,6 +12,7 @@ mod m20250903_094454_add_rule_and_should_download;
mod m20251009_123713_add_use_dynamic_api;
mod m20260324_055217_add_staff;
mod m20260712_123205_add_filter_option;
mod m20260821_025000_mark_empty_tags_for_refetch;
pub struct Migrator;
@@ -31,6 +32,7 @@ impl MigratorTrait for Migrator {
Box::new(m20251009_123713_add_use_dynamic_api::Migration),
Box::new(m20260324_055217_add_staff::Migration),
Box::new(m20260712_123205_add_filter_option::Migration),
Box::new(m20260821_025000_mark_empty_tags_for_refetch::Migration),
]
}
}
@@ -0,0 +1,19 @@
use sea_orm_migration::prelude::*;
#[derive(DeriveMigrationName)]
pub struct Migration;
#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.get_connection()
.execute_unprepared("UPDATE video SET tags = NULL WHERE tags = '[]'")
.await?;
Ok(())
}
async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> {
Ok(())
}
}