feat(subtitles): 字幕站(SubHD、字幕库)在线搜索与下载;rar / 7z 解压;验证码与页面解析在沙箱里
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
92d456d123
commit
59b3680f35
32 files changed
+1704
-166
No files matched your search
@@ -69,6 +69,9 @@ export const SubtitleParsedItem = z.object({
|
||||
content: z.string(),
|
||||
/** 建议的视频位置 */
|
||||
targetLocationId: Id.nullable(),
|
||||
/** 在线下载的:字幕站与条目地址(写入时记进历史) */
|
||||
source: SubtitleSource.optional(),
|
||||
sourceRef: z.string().optional(),
|
||||
});
|
||||
export type SubtitleParsedItem = z.infer<typeof SubtitleParsedItem>;
|
||||
|
||||
@@ -91,6 +94,8 @@ export const SubtitleApplyRequest = z.object({
|
||||
targetLocationId: Id,
|
||||
/** 在线来源的条目地址 */
|
||||
sourceRef: z.string().max(1000).optional(),
|
||||
/** 这一项的来源(不给用整批的 source) */
|
||||
source: SubtitleSource.optional(),
|
||||
}),
|
||||
)
|
||||
.min(1)
|
||||
@@ -140,3 +145,53 @@ export const SubtitleWriteRow = z.object({
|
||||
|
||||
export const SubtitleWritesQuery = z.object({ entityId: Id });
|
||||
export const SubtitleWritesResponse = z.object({ items: z.array(SubtitleWriteView) });
|
||||
|
||||
// ── 在线(字幕站:SubHD、字幕库) ──
|
||||
|
||||
export const SubtitleSearchRequest = z.object({
|
||||
entityId: Id,
|
||||
/** 剧集:只要这一季(集)的字幕;不给 = 全部 */
|
||||
season: z.number().int().min(0).optional(),
|
||||
episode: z.number().int().min(0).optional(),
|
||||
/** 额外的搜索词(作品名搜不到时手动填) */
|
||||
keyword: z.string().trim().max(100).optional(),
|
||||
});
|
||||
export type SubtitleSearchRequest = z.infer<typeof SubtitleSearchRequest>;
|
||||
|
||||
export const SubtitleSearchResult = z.object({
|
||||
siteId: Id,
|
||||
siteKey: z.string(),
|
||||
siteName: z.string(),
|
||||
/** 站内引用(下载时原样提交) */
|
||||
ref: z.string(),
|
||||
title: z.string(),
|
||||
pageUrl: z.string(),
|
||||
languages: z.array(z.string()),
|
||||
format: z.string().nullable(),
|
||||
downloads: z.number().int().nullable(),
|
||||
uploader: z.string().nullable(),
|
||||
publishedAt: z.string().nullable(),
|
||||
season: z.number().int().nullable(),
|
||||
episode: z.number().int().nullable(),
|
||||
score: z.number(),
|
||||
});
|
||||
export type SubtitleSearchResult = z.infer<typeof SubtitleSearchResult>;
|
||||
|
||||
export const SubtitleSearchResponse = z.object({
|
||||
results: z.array(SubtitleSearchResult),
|
||||
/** 用到的搜索词 */
|
||||
keywords: z.array(z.string()),
|
||||
/** 各站出错 / 需要人工处理 */
|
||||
errors: z.array(z.object({ siteName: z.string(), reason: z.string() })),
|
||||
/** 没有启用的字幕站 */
|
||||
noSites: z.boolean(),
|
||||
});
|
||||
export type SubtitleSearchResponse = z.infer<typeof SubtitleSearchResponse>;
|
||||
|
||||
export const SubtitleFetchRequest = z.object({
|
||||
entityId: Id,
|
||||
siteId: Id,
|
||||
ref: z.string().min(1).max(500),
|
||||
title: z.string().max(500).default(""),
|
||||
});
|
||||
export type SubtitleFetchRequest = z.input<typeof SubtitleFetchRequest>;
|
||||
Reference in new issue
Block a user