mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-03-19 19:46:55 +08:00
feat: 将部分逻辑移到后端,简化脚本
This commit is contained in:
@@ -149,6 +149,19 @@ class MoviePilotToolsManager:
|
|||||||
return True
|
return True
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_array_string(value: str, key: str, item_type: str = "string") -> list:
|
||||||
|
"""
|
||||||
|
将逗号分隔的字符串解析为列表,并根据 item_type 转换元素类型
|
||||||
|
"""
|
||||||
|
trimmed = value.strip()
|
||||||
|
if not trimmed:
|
||||||
|
return []
|
||||||
|
return [
|
||||||
|
MoviePilotToolsManager._normalize_scalar_value(item_type, item.strip(), key)
|
||||||
|
for item in trimmed.split(",") if item.strip()
|
||||||
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _normalize_arguments(tool_instance: Any, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
def _normalize_arguments(tool_instance: Any, arguments: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
@@ -185,6 +198,12 @@ class MoviePilotToolsManager:
|
|||||||
field_info = MoviePilotToolsManager._resolve_field_schema(properties[key])
|
field_info = MoviePilotToolsManager._resolve_field_schema(properties[key])
|
||||||
field_type = field_info.get("type")
|
field_type = field_info.get("type")
|
||||||
|
|
||||||
|
# 数组类型:将字符串解析为列表
|
||||||
|
if field_type == "array" and isinstance(value, str):
|
||||||
|
item_type = field_info.get("items", {}).get("type", "string")
|
||||||
|
normalized[key] = MoviePilotToolsManager._parse_array_string(value, key, item_type)
|
||||||
|
continue
|
||||||
|
|
||||||
# 根据类型进行转换
|
# 根据类型进行转换
|
||||||
normalized[key] = MoviePilotToolsManager._normalize_scalar_value(field_type, value, key)
|
normalized[key] = MoviePilotToolsManager._normalize_scalar_value(field_type, value, key)
|
||||||
|
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ function normalizeCommand(tool = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function request(method, targetUrl, headers = {}, body) {
|
function request(method, targetUrl, headers = {}, body, timeout = 120000) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let url;
|
let url;
|
||||||
try {
|
try {
|
||||||
@@ -180,6 +180,10 @@ function request(method, targetUrl, headers = {}, body) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
req.setTimeout(timeout, () => {
|
||||||
|
req.destroy(new Error(`Request timed out after ${timeout}ms`));
|
||||||
|
});
|
||||||
|
|
||||||
req.on('error', reject);
|
req.on('error', reject);
|
||||||
|
|
||||||
if (body !== undefined) {
|
if (body !== undefined) {
|
||||||
@@ -225,7 +229,7 @@ async function loadCommandJson(commandName) {
|
|||||||
|
|
||||||
if (statusCode === '404') {
|
if (statusCode === '404') {
|
||||||
console.error(`Error: command '${commandName}' not found`);
|
console.error(`Error: command '${commandName}' not found`);
|
||||||
console.error(`Run '${SCRIPT_NAME} list' to see available commands`);
|
console.error(`Run 'node ${SCRIPT_NAME} list' to see available commands`);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,80 +349,7 @@ async function cmdShow(commandName) {
|
|||||||
process.stdout.write(`\n${usageLabel} ${usageLine}${reqPart}${optPart}\n`);
|
process.stdout.write(`\n${usageLabel} ${usageLine}${reqPart}${optPart}\n`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseBoolean(value) {
|
function buildArguments(pairs) {
|
||||||
return value === 'true' || value === '1' || value === 'yes';
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseNumber(value, key) {
|
|
||||||
if (value === '') {
|
|
||||||
fail(`Error: invalid numeric value for '${key}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = Number(value);
|
|
||||||
if (Number.isNaN(result)) {
|
|
||||||
fail(`Error: invalid numeric value for '${key}': '${value}'`);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseScalarValue(value, key, type = 'string') {
|
|
||||||
if (type === 'integer' || type === 'number') {
|
|
||||||
return parseNumber(value, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type === 'boolean') {
|
|
||||||
return parseBoolean(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseArrayValue(value, key, itemType = 'string') {
|
|
||||||
const trimmed = value.trim();
|
|
||||||
if (!trimmed) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trimmed.startsWith('[')) {
|
|
||||||
let parsed;
|
|
||||||
try {
|
|
||||||
parsed = JSON.parse(trimmed);
|
|
||||||
} catch {
|
|
||||||
fail(`Error: invalid array value for '${key}': '${value}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Array.isArray(parsed)) {
|
|
||||||
fail(`Error: invalid array value for '${key}': '${value}'`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return parsed.map((item) => {
|
|
||||||
if (typeof item === 'string') {
|
|
||||||
return parseScalarValue(item.trim(), key, itemType);
|
|
||||||
}
|
|
||||||
if (itemType === 'integer' || itemType === 'number') {
|
|
||||||
if (typeof item !== 'number') {
|
|
||||||
fail(`Error: invalid numeric value for '${key}': '${item}'`);
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
if (itemType === 'boolean') {
|
|
||||||
if (typeof item !== 'boolean') {
|
|
||||||
fail(`Error: invalid boolean value for '${key}': '${item}'`);
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
return item;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return trimmed
|
|
||||||
.split(',')
|
|
||||||
.map((item) => item.trim())
|
|
||||||
.filter(Boolean)
|
|
||||||
.map((item) => parseScalarValue(item, key, itemType));
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildArguments(command, pairs) {
|
|
||||||
const args = { explanation: 'CLI invocation' };
|
const args = { explanation: 'CLI invocation' };
|
||||||
|
|
||||||
for (const kv of pairs) {
|
for (const kv of pairs) {
|
||||||
@@ -427,40 +358,20 @@ function buildArguments(command, pairs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const index = kv.indexOf('=');
|
const index = kv.indexOf('=');
|
||||||
const key = kv.slice(0, index);
|
args[kv.slice(0, index)] = kv.slice(index + 1);
|
||||||
const value = kv.slice(index + 1);
|
|
||||||
const field = command.fields.find((item) => item.name === key);
|
|
||||||
const fieldType = field?.type || 'string';
|
|
||||||
const itemType = field?.item_type || 'string';
|
|
||||||
|
|
||||||
if (fieldType === 'array') {
|
|
||||||
args[key] = parseArrayValue(value, key, itemType);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
args[key] = parseScalarValue(value, key, fieldType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function cmdRun(commandName, pairs) {
|
async function cmdRun(commandName, pairs) {
|
||||||
await loadCommandsJson();
|
|
||||||
|
|
||||||
if (!commandName) {
|
if (!commandName) {
|
||||||
fail(`Usage: ${SCRIPT_NAME} <command> [key=value ...]`);
|
fail(`Usage: ${SCRIPT_NAME} <command> [key=value ...]`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const command = commandsJson.find((item) => item.name === commandName);
|
|
||||||
if (!command) {
|
|
||||||
console.error(`Error: command '${commandName}' not found`);
|
|
||||||
console.error(`Run 'node ${SCRIPT_NAME} list' to see available commands`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestBody = JSON.stringify({
|
const requestBody = JSON.stringify({
|
||||||
tool_name: commandName,
|
tool_name: commandName,
|
||||||
arguments: buildArguments(command, pairs),
|
arguments: buildArguments(pairs),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { statusCode, body } = await request(
|
const { statusCode, body } = await request(
|
||||||
@@ -490,7 +401,7 @@ async function cmdRun(commandName, pairs) {
|
|||||||
try {
|
try {
|
||||||
printValue(JSON.parse(parsed.result));
|
printValue(JSON.parse(parsed.result));
|
||||||
} catch {
|
} catch {
|
||||||
printValue({ result: parsed.result });
|
printValue(parsed.result);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printValue(parsed.result);
|
printValue(parsed.result);
|
||||||
|
|||||||
Reference in New Issue
Block a user