chore: 跑一遍 auto-correct (#468)
This commit is contained in:
@@ -32,7 +32,7 @@ pub async fn get_created_favorites(
|
||||
let bili_favorites = me.get_created_favorites().await?;
|
||||
|
||||
let favorites = if let Some(bili_favorites) = bili_favorites {
|
||||
// b 站收藏夹相关接口使用的所谓 “fid” 其实是该处的 id,即 fid + mid 后两位
|
||||
// b 站收藏夹相关接口使用的所谓“fid”其实是该处的 id,即 fid + mid 后两位
|
||||
let bili_fids: Vec<_> = bili_favorites.iter().map(|fav| fav.id).collect();
|
||||
|
||||
let subscribed_fids: Vec<i64> = favorite::Entity::find()
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct DanmakuOption {
|
||||
pub bottom_percentage: f64,
|
||||
/// 透明度(0-255)
|
||||
pub opacity: u8,
|
||||
/// 是否加粗,1代表是,0代表否
|
||||
/// 是否加粗,1 代表是,0 代表否
|
||||
pub bold: bool,
|
||||
/// 描边
|
||||
pub outline: f64,
|
||||
|
||||
@@ -39,7 +39,7 @@ pub struct Danmu {
|
||||
impl Danmu {
|
||||
/// 计算弹幕的“像素长度”,会乘上一个缩放因子
|
||||
///
|
||||
/// 汉字算一个全宽,英文算2/3宽
|
||||
/// 汉字算一个全宽,英文算 2/3 宽
|
||||
pub fn length(&self, config: &CanvasConfig<'_>) -> f64 {
|
||||
let pts = config.danmaku_option.font_size
|
||||
* self
|
||||
|
||||
@@ -29,7 +29,7 @@ pub struct SubTitleItem {
|
||||
impl SubTitleInfo {
|
||||
pub fn is_ai_sub(&self) -> bool {
|
||||
// ai: aisubtitle.hdslb.com/bfs/ai_subtitle/xxxx
|
||||
// 非 ai: aisubtitle.hdslb.com/bfs/subtitle/xxxx
|
||||
// 非 ai:aisubtitle.hdslb.com/bfs/subtitle/xxxx
|
||||
self.subtitle_url.contains("ai_subtitle")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ mod tests {
|
||||
"test_truncate",
|
||||
&json!({"title": "你说得对,但是 Rust 是由 Mozilla 自主研发的一款全新的编译期格斗游戏。\
|
||||
编译将发生在一个被称作「Cargo」的构建系统中。在这里,被引用的指针将被授予「生命周期」之力,导引对象安全。\
|
||||
你将扮演一位名为「Rustacean」的神秘角色, 在与「Rustc」的搏斗中邂逅各种骨骼惊奇的傲娇报错。\
|
||||
你将扮演一位名为「Rustacean」的神秘角色,在与「Rustc」的搏斗中邂逅各种骨骼惊奇的傲娇报错。\
|
||||
征服她们、通过编译同时,逐步发掘「C++」程序崩溃的真相。"})
|
||||
)
|
||||
.unwrap(),
|
||||
|
||||
@@ -34,7 +34,7 @@ pub async fn http_server(
|
||||
let listener = tokio::net::TcpListener::bind(&config.bind_address)
|
||||
.await
|
||||
.context("bind address failed")?;
|
||||
info!("开始运行管理页: http://{}", config.bind_address);
|
||||
info!("开始运行管理页:http://{}", config.bind_address);
|
||||
Ok(axum::serve(listener, ServiceExt::<Request>::into_make_service(app)).await?)
|
||||
}
|
||||
|
||||
|
||||
@@ -143,14 +143,14 @@ mod tests {
|
||||
let test_cases = vec![
|
||||
(
|
||||
Rule(vec![vec![RuleTarget::Title(Condition::Contains("唐氏".to_string()))]]),
|
||||
"「(标题包含“唐氏”)」",
|
||||
"「(标题包含“唐氏”)」",
|
||||
),
|
||||
(
|
||||
Rule(vec![vec![
|
||||
RuleTarget::Title(Condition::Prefix("街霸".to_string())),
|
||||
RuleTarget::Tags(Condition::Contains("套路".to_string())),
|
||||
]]),
|
||||
"「(标题以“街霸”开头)且(标签包含“套路”)」",
|
||||
"「(标题以“街霸”开头)且(标签包含“套路”)」",
|
||||
),
|
||||
(
|
||||
Rule(vec![
|
||||
@@ -168,14 +168,14 @@ mod tests {
|
||||
)),
|
||||
],
|
||||
]),
|
||||
"「(标题包含“Rust”)且(视频分页数量大于“5”)」或「(标签以“入门”结尾)且(发布时间大于“2023-01-01 00:00:00”)」",
|
||||
"「(标题包含“Rust”)且(视频分页数量大于“5”)」或「(标签以“入门”结尾)且(发布时间大于“2023-01-01 00:00:00”)」",
|
||||
),
|
||||
(
|
||||
Rule(vec![vec![
|
||||
RuleTarget::Not(Box::new(RuleTarget::Title(Condition::Contains("广告".to_string())))),
|
||||
RuleTarget::PageCount(Condition::LessThan(10)),
|
||||
]]),
|
||||
"「(标题不包含“广告”)且(视频分页数量小于“10”)」",
|
||||
"「(标题不包含“广告”)且(视频分页数量小于“10”)」",
|
||||
),
|
||||
(
|
||||
Rule(vec![vec![
|
||||
@@ -189,12 +189,14 @@ mod tests {
|
||||
.and_hms_opt(23, 59, 59)
|
||||
.unwrap(),
|
||||
)),
|
||||
// autocorrect-disable
|
||||
RuleTarget::Tags(Condition::MatchesRegex(
|
||||
"技术|教程".to_string(),
|
||||
regex::Regex::new("技术|教程").unwrap(),
|
||||
)),
|
||||
]]),
|
||||
"「(收藏时间在“2023-06-01 00:00:00”和“2023-12-31 23:59:59”之间)且(标签匹配“技术|教程”)」",
|
||||
"「(收藏时间在“2023-06-01 00:00:00”和“2023-12-31 23:59:59”之间)且(标签匹配“技术|教程”)」",
|
||||
// autocorrect-enable
|
||||
),
|
||||
];
|
||||
|
||||
@@ -243,7 +245,7 @@ mod tests {
|
||||
(
|
||||
video::ActiveModel {
|
||||
name: Set(
|
||||
"万字怒扒网易《归唐》底裤!中国首款大厂买断制单机,靠谱吗?——全网最全!官方非独家幕后!关于《归唐》PV的所有秘密~都在这里了~".to_owned(),
|
||||
"万字怒扒网易《归唐》底裤!中国首款大厂买断制单机,靠谱吗?——全网最全!官方非独家幕后!关于《归唐》PV 的所有秘密~都在这里了~".to_owned(),
|
||||
),
|
||||
..Default::default()
|
||||
},
|
||||
|
||||
@@ -288,12 +288,12 @@ pub async fn download_video_pages(
|
||||
ExecutionStatus::Succeeded => info!("处理视频「{}」{}成功", &video_model.name, task_name),
|
||||
ExecutionStatus::Ignored(e) => {
|
||||
error!(
|
||||
"处理视频「{}」{}出现常见错误,已忽略: {:#}",
|
||||
"处理视频「{}」{}出现常见错误,已忽略:{:#}",
|
||||
&video_model.name, task_name, e
|
||||
)
|
||||
}
|
||||
ExecutionStatus::Failed(e) | ExecutionStatus::FixedFailed(_, e) => {
|
||||
error!("处理视频「{}」{}失败: {:#}", &video_model.name, task_name, e)
|
||||
error!("处理视频「{}」{}失败:{:#}", &video_model.name, task_name, e)
|
||||
}
|
||||
});
|
||||
if let ExecutionStatus::Failed(e) = results.into_iter().nth(4).context("page download result not found")?
|
||||
@@ -478,12 +478,12 @@ pub async fn download_page(
|
||||
),
|
||||
ExecutionStatus::Ignored(e) => {
|
||||
error!(
|
||||
"处理视频「{}」第 {} 页{}出现常见错误,已忽略: {:#}",
|
||||
"处理视频「{}」第 {} 页{}出现常见错误,已忽略:{:#}",
|
||||
&video_model.name, page_model.pid, task_name, e
|
||||
)
|
||||
}
|
||||
ExecutionStatus::Failed(e) | ExecutionStatus::FixedFailed(_, e) => error!(
|
||||
"处理视频「{}」第 {} 页{}失败: {:#}",
|
||||
"处理视频「{}」第 {} 页{}失败:{:#}",
|
||||
&video_model.name, page_model.pid, task_name, e
|
||||
),
|
||||
});
|
||||
|
||||
@@ -94,7 +94,7 @@ impl Display for Rule {
|
||||
.0
|
||||
.iter()
|
||||
.map(|group| {
|
||||
let conditions: Vec<String> = group.iter().map(|target| format!("({})", target)).collect();
|
||||
let conditions: Vec<String> = group.iter().map(|target| format!("({})", target)).collect();
|
||||
format!("「{}」", conditions.join("且"))
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
EMBY 的一般结构是: `媒体库 - 文件夹 - 电影/电视剧 - 分季/分集`,方便起见,我采用了如下的对应关系:
|
||||
|
||||
1. **文件夹**:对应 b 站的 video source;
|
||||
2. **电视剧**: 对应 b 站的 video;
|
||||
2. **电视剧**:对应 b 站的 video;
|
||||
3. **第一季的所有分集**:对应 b 站的 page。
|
||||
|
||||
特别的,当 video 仅有一个 page 时,为了避免过多的层级,bili-sync 会将 page 展开到第二层级,变成与电视剧同级的电影。
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
在[程序发布页](https://github.com/amtoaer/bili-sync/releases)选择最新版本中对应机器架构的压缩包,解压后会获取一个名为 `bili-sync-rs` 的可执行文件,直接双击执行。
|
||||
|
||||
### 其二: 使用 Docker Compose 运行
|
||||
### 其二:使用 Docker Compose 运行
|
||||
|
||||
Linux/amd64 与 Linux/arm64 两个平台可直接使用 Docker 或 Docker Compose 运行,此处以 Compose 为例:
|
||||
> 请注意其中的注释,有不清楚的地方可以先继续往下看。
|
||||
@@ -88,9 +88,9 @@ Jul 12 16:11:10 INFO 开始运行管理页: http://0.0.0.0:12345
|
||||
|
||||
认证后会看到一系列的配置,除绑定地址外的选项**基本都会实时生效**。为避免意料外的情况,建议将配置文件一次修改完毕后再点击保存。
|
||||
|
||||
如无特殊需求,一般仅需修改“B站认证”与“视频质量”两个标签下的配置。
|
||||
如无特殊需求,一般仅需修改“B 站认证”与“视频质量”两个标签下的配置。
|
||||
|
||||
其中“B站认证”在一次填写后即可忽略,程序会在**每日第一次运行视频下载任务**时检查认证状态,并在有必要时自动刷新。
|
||||
其中“B 站认证”在一次填写后即可忽略,程序会在**每日第一次运行视频下载任务**时检查认证状态,并在有必要时自动刷新。
|
||||
|
||||
对于这些设置项的含义,请参考[配置说明](./configuration.md),可善用右侧导航在不同配置项间跳转。
|
||||
|
||||
@@ -98,7 +98,7 @@ Jul 12 16:11:10 INFO 开始运行管理页: http://0.0.0.0:12345
|
||||
|
||||
配置完毕后,我们便可以随时添加视频源订阅。
|
||||
|
||||
用户在正确填写“B站认证”后可以在“快捷订阅”部分查看自己创建的收藏夹、关注的合集与 UP 主一键订阅,也可以在“视频源”页手动添加并管理。
|
||||
用户在正确填写“B 站认证”后可以在“快捷订阅”部分查看自己创建的收藏夹、关注的合集与 UP 主一键订阅,也可以在“视频源”页手动添加并管理。
|
||||
|
||||
对于手动添加的视频源,可参考如下页面获取所需的参数:
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ from pathlib import Path
|
||||
|
||||
def main():
|
||||
if len(sys.argv) <= 1:
|
||||
print("用法: python 2.0.3_add_fanart.py <path1> <path2> ...")
|
||||
print("用法:python 2.0.3_add_fanart.py <path1> <path2> ...")
|
||||
exit(1)
|
||||
paths = [Path(path) for path in sys.argv[1:]]
|
||||
for path in paths:
|
||||
|
||||
@@ -60,7 +60,7 @@ class ApiClient {
|
||||
clearAuthToken() {
|
||||
delete this.defaultHeaders['Authorization'];
|
||||
localStorage.removeItem('authToken');
|
||||
// 断开WebSocket连接,因为token已经无效
|
||||
// 断开 WebSocket 连接,因为 token 已经无效
|
||||
wsManager.disconnect();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
export let onsubmit: (request: UpdateVideoStatusRequest) => void;
|
||||
|
||||
// 视频任务名称(与后端 VideoStatus 对应)
|
||||
const videoTaskNames = ['视频封面', '视频信息', 'UP主头像', 'UP主信息', '分页下载'];
|
||||
const videoTaskNames = ['视频封面', '视频信息', 'UP 主头像', 'UP 主信息', '分页下载'];
|
||||
|
||||
// 分页任务名称(与后端 PageStatus 对应)
|
||||
const pageTaskNames = ['视频封面', '视频内容', '视频信息', '视频弹幕', '视频字幕'];
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
case 'collection':
|
||||
return '合集';
|
||||
case 'upper':
|
||||
return 'UP主';
|
||||
return 'UP 主';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
let customPath = '';
|
||||
let loading = false;
|
||||
|
||||
// 根据类型和item生成默认路径
|
||||
// 根据类型和 item 生成默认路径
|
||||
function generateDefaultPath(): string {
|
||||
if (!item) return '';
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
}
|
||||
case 'upper': {
|
||||
const upper = item as UpperWithSubscriptionStatus;
|
||||
return `UP主/${upper.uname}`;
|
||||
return `UP 主/${upper.uname}`;
|
||||
}
|
||||
default:
|
||||
return '';
|
||||
@@ -63,7 +63,7 @@
|
||||
case 'collection':
|
||||
return '合集';
|
||||
case 'upper':
|
||||
return 'UP主';
|
||||
return 'UP 主';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
@@ -145,7 +145,7 @@
|
||||
open = false;
|
||||
}
|
||||
|
||||
// 当对话框打开时重置path
|
||||
// 当对话框打开时重置 path
|
||||
$: if (open && item) {
|
||||
customPath = generateDefaultPath();
|
||||
}
|
||||
|
||||
@@ -137,7 +137,7 @@ export interface CollectionsResponse {
|
||||
total: number;
|
||||
}
|
||||
|
||||
// UP主相关类型
|
||||
// UP 主相关类型
|
||||
export interface UpperWithSubscriptionStatus {
|
||||
mid: number;
|
||||
uname: string;
|
||||
|
||||
@@ -122,7 +122,7 @@ export class WebSocketManager {
|
||||
} catch (error) {
|
||||
console.error('Failed to parse WebSocket message:', error, event.data);
|
||||
toast.error('解析 WebSocket 消息失败', {
|
||||
description: `消息内容: ${event.data}\n错误信息: ${error instanceof Error ? error.message : String(error)}`
|
||||
description: `消息内容:${event.data}\n错误信息:${error instanceof Error ? error.message : String(error)}`
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -137,7 +137,7 @@ export class WebSocketManager {
|
||||
} catch (error) {
|
||||
console.error('Failed to send message:', error);
|
||||
toast.error('发送 WebSocket 消息失败', {
|
||||
description: `消息内容: ${JSON.stringify(message)}\n错误信息: ${error instanceof Error ? error.message : String(error)}`
|
||||
description: `消息内容:${JSON.stringify(message)}\n错误信息:${error instanceof Error ? error.message : String(error)}`
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
const response = await api.getDashboard();
|
||||
dashboardData = response.data;
|
||||
} catch (error) {
|
||||
console.error('加载仪表盘数据失败:', error);
|
||||
console.error('加载仪表盘数据失败:', error);
|
||||
toast.error('加载仪表盘数据失败', {
|
||||
description: (error as ApiError).message
|
||||
});
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
async function loadCollections(page: number = 0) {
|
||||
loading = true;
|
||||
try {
|
||||
const response = await api.getFollowedCollections(page + 1, pageSize); // API使用1基索引
|
||||
const response = await api.getFollowedCollections(page + 1, pageSize); // API 使用 1 基索引
|
||||
collections = response.data.collections;
|
||||
totalCount = response.data.total;
|
||||
} catch (error) {
|
||||
console.error('加载合集失败:', error);
|
||||
console.error('加载合集失败:', error);
|
||||
toast.error('加载合集失败', {
|
||||
description: (error as ApiError).message
|
||||
});
|
||||
@@ -92,7 +92,7 @@
|
||||
<div class="flex items-center justify-center py-12">
|
||||
<div class="space-y-2 text-center">
|
||||
<p class="text-muted-foreground">暂无合集数据</p>
|
||||
<p class="text-muted-foreground text-sm">请先在B站关注一些合集,或检查账号配置</p>
|
||||
<p class="text-muted-foreground text-sm">请先在 B 站关注一些合集,或检查账号配置</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
const response = await api.getCreatedFavorites();
|
||||
favorites = response.data.favorites;
|
||||
} catch (error) {
|
||||
console.error('加载收藏夹失败:', error);
|
||||
console.error('加载收藏夹失败:', error);
|
||||
toast.error('加载收藏夹失败', {
|
||||
description: (error as ApiError).message
|
||||
});
|
||||
@@ -73,7 +73,7 @@
|
||||
<div class="flex items-center justify-center py-12">
|
||||
<div class="space-y-2 text-center">
|
||||
<p class="text-muted-foreground">暂无收藏夹数据</p>
|
||||
<p class="text-muted-foreground text-sm">请先在B站创建收藏夹,或检查账号配置</p>
|
||||
<p class="text-muted-foreground text-sm">请先在 B 站创建收藏夹,或检查账号配置</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
async function loadUppers(page: number = 0) {
|
||||
loading = true;
|
||||
try {
|
||||
const response = await api.getFollowedUppers(page + 1, pageSize); // API使用1基索引
|
||||
const response = await api.getFollowedUppers(page + 1, pageSize); // API 使用 1 基索引
|
||||
uppers = response.data.uppers;
|
||||
totalCount = response.data.total;
|
||||
} catch (error) {
|
||||
console.error('加载UP主失败:', error);
|
||||
toast.error('加载UP主失败', {
|
||||
console.error('加载 UP 主失败:', error);
|
||||
toast.error('加载 UP 主失败', {
|
||||
description: (error as ApiError).message
|
||||
});
|
||||
} finally {
|
||||
@@ -92,8 +92,8 @@
|
||||
{:else}
|
||||
<div class="flex items-center justify-center py-12">
|
||||
<div class="space-y-2 text-center">
|
||||
<p class="text-muted-foreground">暂无UP主数据</p>
|
||||
<p class="text-muted-foreground text-sm">请先在B站关注一些UP主,或检查账号配置</p>
|
||||
<p class="text-muted-foreground">暂无 UP 主数据</p>
|
||||
<p class="text-muted-foreground text-sm">请先在 B 站关注一些 UP 主,或检查账号配置</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
async function loadVideoDetail() {
|
||||
const videoId = parseInt($page.params.id);
|
||||
if (isNaN(videoId)) {
|
||||
error = '无效的视频ID';
|
||||
toast.error('无效的视频ID');
|
||||
error = '无效的视频 ID';
|
||||
toast.error('无效的视频 ID');
|
||||
return;
|
||||
}
|
||||
loading = true;
|
||||
@@ -35,7 +35,7 @@
|
||||
const result = await api.getVideo(videoId);
|
||||
videoData = result.data;
|
||||
} catch (error) {
|
||||
console.error('加载视频详情失败:', error);
|
||||
console.error('加载视频详情失败:', error);
|
||||
toast.error('加载视频详情失败', {
|
||||
description: (error as ApiError).message
|
||||
});
|
||||
@@ -79,7 +79,7 @@
|
||||
toast.error('状态更新失败');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('状态更新失败:', error);
|
||||
console.error('状态更新失败:', error);
|
||||
toast.error('状态更新失败', {
|
||||
description: (error as ApiError).message
|
||||
});
|
||||
@@ -161,7 +161,7 @@
|
||||
}}
|
||||
mode="detail"
|
||||
showActions={false}
|
||||
taskNames={['视频封面', '视频信息', 'UP主头像', 'UP主信息', '分页下载']}
|
||||
taskNames={['视频封面', '视频信息', 'UP 主头像', 'UP 主信息', '分页下载']}
|
||||
bind:resetDialogOpen
|
||||
bind:resetting
|
||||
onReset={async (forceReset: boolean) => {
|
||||
@@ -225,8 +225,8 @@
|
||||
{:else}
|
||||
<div class="py-12 text-center">
|
||||
<div class="space-y-2">
|
||||
<p class="text-muted-foreground">暂无分P数据</p>
|
||||
<p class="text-muted-foreground text-sm">该视频可能为单P视频</p>
|
||||
<p class="text-muted-foreground">暂无分 P 数据</p>
|
||||
<p class="text-muted-foreground text-sm">该视频可能为单 P 视频</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
const result = await api.getVideos(params);
|
||||
videosData = result.data;
|
||||
} catch (error) {
|
||||
console.error('加载视频失败:', error);
|
||||
console.error('加载视频失败:', error);
|
||||
toast.error('加载视频失败', {
|
||||
description: (error as ApiError).message
|
||||
});
|
||||
@@ -111,7 +111,7 @@
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('重置失败:', error);
|
||||
console.error('重置失败:', error);
|
||||
toast.error('重置失败', {
|
||||
description: (error as ApiError).message
|
||||
});
|
||||
@@ -133,7 +133,7 @@
|
||||
toast.info('没有需要重置的视频');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('重置失败:', error);
|
||||
console.error('重置失败:', error);
|
||||
toast.error('重置失败', {
|
||||
description: (error as ApiError).message
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user