mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 03:26:37 +08:00
146 lines
4.5 KiB
TypeScript
146 lines
4.5 KiB
TypeScript
import { api } from './client'
|
|
import type { ScrapeOptions } from './library'
|
|
|
|
// toolsAPI groups admin-only endpoints that don't fit the other domain
|
|
// modules: organizing media files into the canonical naming layout, and
|
|
// dispatching a test notification through the configured channels.
|
|
// OrganizeOverrides are optional single-request overrides for an organize
|
|
// action. Empty fields fall back to the system settings.
|
|
// source_path = 源目录(待整理文件所在),dest_path = 目的地目录(整理输出到哪里)。
|
|
export interface OrganizeOverrides {
|
|
source_path?: string
|
|
dest_path?: string
|
|
transfer_mode?: string
|
|
media_type?: string
|
|
media_category?: string
|
|
scan_after?: boolean
|
|
scrape_after?: boolean
|
|
library_id?: string
|
|
dry_run?: boolean
|
|
}
|
|
|
|
// OrganizeSource is a selectable organize source directory (e.g. the download
|
|
// directory) surfaced so operators can organize an arbitrary directory and not
|
|
// only registered libraries.
|
|
export interface OrganizeSource {
|
|
label: string
|
|
path: string
|
|
kind: string
|
|
}
|
|
|
|
export interface OrganizeResultSummary {
|
|
organized?: number
|
|
skipped?: number
|
|
replaced?: number
|
|
reclassified?: number
|
|
source_path?: string
|
|
dest_path?: string
|
|
errors?: string[]
|
|
dry_run?: boolean
|
|
items?: Array<{
|
|
source: string
|
|
target?: string
|
|
action: string
|
|
reason?: string
|
|
media_type?: string
|
|
category?: string
|
|
title?: string
|
|
}>
|
|
scans?: Array<{
|
|
library_id: string
|
|
name: string
|
|
path: string
|
|
visited: number
|
|
added: number
|
|
updated: number
|
|
removed: number
|
|
error?: string
|
|
}>
|
|
scrapes?: Array<{
|
|
library_id: string
|
|
name: string
|
|
path: string
|
|
matched: number
|
|
skipped?: boolean
|
|
reason?: string
|
|
error?: string
|
|
}>
|
|
}
|
|
|
|
export interface FFmpegToolInfo {
|
|
installed: boolean
|
|
path?: string
|
|
version?: string
|
|
}
|
|
|
|
export interface FFmpegToolsStatus {
|
|
installing?: boolean
|
|
message?: string
|
|
error?: string
|
|
started_at?: string
|
|
finished_at?: string
|
|
install_dir?: string
|
|
target?: { os?: string; arch?: string; label?: string }
|
|
ffmpeg?: FFmpegToolInfo
|
|
ffprobe?: FFmpegToolInfo
|
|
}
|
|
|
|
export const toolsAPI = {
|
|
organizeMedia: (mediaID: string, opts?: OrganizeOverrides) =>
|
|
api
|
|
.post<{ path: string; scans?: unknown[]; scrapes?: unknown[] }>(`/admin/media/${mediaID}/organize`, opts ?? {})
|
|
.then((r) => r.data),
|
|
|
|
organizeLibrary: (libraryID: string, opts?: OrganizeOverrides) =>
|
|
api
|
|
.post<OrganizeResultSummary>(
|
|
`/admin/libraries/${libraryID}/organize`,
|
|
opts ?? {},
|
|
)
|
|
.then((r) => r.data),
|
|
|
|
// organizeSources lists selectable source directories (download/media dir).
|
|
organizeSources: () =>
|
|
api
|
|
.get<{ sources: OrganizeSource[] }>('/admin/organize/sources')
|
|
.then((r) => r.data.sources ?? []),
|
|
|
|
// organizeDirectory organizes an arbitrary source directory (e.g. downloads)
|
|
// into the destination with dedup + 洗版 (resolution replacement).
|
|
organizeDirectory: (opts: OrganizeOverrides) =>
|
|
api
|
|
.post<OrganizeResultSummary>(
|
|
'/admin/organize/source',
|
|
opts,
|
|
)
|
|
.then((r) => r.data),
|
|
|
|
notifyTest: (title: string, body: string) =>
|
|
api
|
|
.post<{ message: string }>('/admin/notify/test', { title, body })
|
|
.then((r) => r.data),
|
|
|
|
// ffToolsStatus 查询 ffmpeg/ffprobe 的安装状态(路径/版本/是否正在安装)。
|
|
ffToolsStatus: () =>
|
|
api.get<FFmpegToolsStatus>('/admin/tools/ffmpeg/status').then((r) => r.data),
|
|
|
|
// installFFTools 触发后台下载安装 ffmpeg/ffprobe(自动匹配当前平台)。
|
|
installFFTools: () =>
|
|
api.post<FFmpegToolsStatus>('/admin/tools/ffmpeg/install').then((r) => r.data),
|
|
|
|
// repairAndRescrapeAll 触发「全库修复+重刮」:先从媒体路径中的
|
|
// {tmdb-N}/{bangumi-N} 占位符回填缺失/错误的外部 ID,再批量重刮整库。
|
|
// 后端异步执行,立即返回;进度通过 WS "scrape" topic 推送。
|
|
repairAndRescrapeAll: (options?: ScrapeOptions) =>
|
|
api
|
|
.post<{ status: string }>('/admin/media/repair-rescrape', options ?? {})
|
|
.then((r) => r.data),
|
|
|
|
// repairAndRescrapeLibrary 触发「单库修复+重刮」:只对指定媒体库回填占位符
|
|
// 外部 ID 并重刮,不影响其它库。后端异步执行,进度通过 WS "scrape" topic 推送。
|
|
repairAndRescrapeLibrary: (libraryID: string, options?: ScrapeOptions) =>
|
|
api
|
|
.post<{ status: string }>(`/admin/libraries/${libraryID}/repair-rescrape`, options ?? {})
|
|
.then((r) => r.data),
|
|
}
|