mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 06:34:54 +08:00
@@ -80,7 +80,7 @@ use translation_query::{
|
||||
};
|
||||
use workflow_commands::{
|
||||
run_parse_clear_cache, run_parse_once, run_publish_localized, run_repack, run_translate_once,
|
||||
run_translation_set, run_translation_validate,
|
||||
run_translation_set, run_translation_task_update, run_translation_validate,
|
||||
};
|
||||
|
||||
const EXIT_ERROR: i32 = 1;
|
||||
@@ -209,6 +209,10 @@ fn run() -> anyhow::Result<i32> {
|
||||
run_translation_set(&options)?;
|
||||
Ok(0)
|
||||
}
|
||||
CliCommand::TranslationTaskUpdate => {
|
||||
run_translation_task_update(&options)?;
|
||||
Ok(0)
|
||||
}
|
||||
CliCommand::Repack => {
|
||||
run_repack(&options)?;
|
||||
Ok(0)
|
||||
@@ -356,6 +360,8 @@ struct CliOptions {
|
||||
translation_id: Option<String>,
|
||||
translation_text: Option<String>,
|
||||
translation_text_file: Option<PathBuf>,
|
||||
translation_failure_reason: Option<String>,
|
||||
translation_provider_run_id: Option<String>,
|
||||
localized_release_id: Option<String>,
|
||||
repack_spec: Option<PathBuf>,
|
||||
schedule_group: Option<String>,
|
||||
@@ -439,6 +445,8 @@ impl Default for CliOptions {
|
||||
translation_id: None,
|
||||
translation_text: None,
|
||||
translation_text_file: None,
|
||||
translation_failure_reason: None,
|
||||
translation_provider_run_id: None,
|
||||
localized_release_id: None,
|
||||
repack_spec: None,
|
||||
schedule_group: None,
|
||||
@@ -519,6 +527,7 @@ enum CliCommand {
|
||||
Translate,
|
||||
TranslationValidate,
|
||||
TranslationSet,
|
||||
TranslationTaskUpdate,
|
||||
Repack,
|
||||
PublishLocalized,
|
||||
ScheduleList,
|
||||
@@ -6621,6 +6630,12 @@ fn parse_args_with_env(
|
||||
options.translation_text_file =
|
||||
Some(PathBuf::from(next_option_value(&mut args, &flag)?));
|
||||
}
|
||||
"--failure-reason" | "--reason" => {
|
||||
options.translation_failure_reason = Some(next_option_value(&mut args, &flag)?);
|
||||
}
|
||||
"--provider-run-id" => {
|
||||
options.translation_provider_run_id = Some(next_option_value(&mut args, &flag)?);
|
||||
}
|
||||
"--localized-release-id" => {
|
||||
options.localized_release_id = Some(next_option_value(&mut args, &flag)?);
|
||||
}
|
||||
@@ -7202,6 +7217,60 @@ fn parse_args_with_env(
|
||||
options.progress = false;
|
||||
options.banner = false;
|
||||
}
|
||||
CliCommand::TranslationTaskUpdate => {
|
||||
if options.watch || options.daemon || options.daemon_child {
|
||||
return Err(anyhow::anyhow!("i18n task update 只支持单次执行"));
|
||||
}
|
||||
if options.config.force
|
||||
|| options.config.dry_run
|
||||
|| options.run_count.is_some()
|
||||
|| options.sync_option_explicit
|
||||
|| options.output_explicit
|
||||
|| options.proxy_option_explicit
|
||||
|| tools_are_non_default(&options.config, &options.env_baseline_config)
|
||||
{
|
||||
return Err(anyhow::anyhow!(
|
||||
"i18n task update 只接受 --state-dir、--json/--human 和翻译任务参数"
|
||||
));
|
||||
}
|
||||
if options.resource_root.is_some()
|
||||
|| options.translation_file.is_some()
|
||||
|| options.translation_id.is_some()
|
||||
|| options.translation_text.is_some()
|
||||
|| options.translation_text_file.is_some()
|
||||
|| options.localized_release_id.is_some()
|
||||
|| options.repack_spec.is_some()
|
||||
|| options.query_offset != 0
|
||||
|| options.query_limit != 100
|
||||
|| options.query_resource_type.is_some()
|
||||
|| options.query_hash.is_some()
|
||||
|| options.query_path_pattern.is_some()
|
||||
|| options.query_official_release_id.is_some()
|
||||
|| options.query_platform.is_some()
|
||||
|| options.query_destination.is_some()
|
||||
|| options.query_bundle_path.is_some()
|
||||
|| options.query_archive_entry.is_some()
|
||||
|| options.query_worker_status.is_some()
|
||||
|| options.query_parse_status.is_some()
|
||||
|| options.query_path_id.is_some()
|
||||
|| options.query_class_id.is_some()
|
||||
|| options.query_field_path.is_some()
|
||||
|| options.query_format.is_some()
|
||||
|| options.query_has_reason.is_some()
|
||||
|| options.query_has_failure_reason.is_some()
|
||||
{
|
||||
return Err(anyhow::anyhow!(
|
||||
"i18n task update 只接受 --task-id、--task-status、--failure-reason 和 --provider-run-id"
|
||||
));
|
||||
}
|
||||
if options.query_task_id.is_none() || options.query_task_status.is_none() {
|
||||
return Err(anyhow::anyhow!(
|
||||
"i18n task update 必须同时指定 --task-id 和 --task-status"
|
||||
));
|
||||
}
|
||||
options.progress = false;
|
||||
options.banner = false;
|
||||
}
|
||||
CliCommand::ScheduleList
|
||||
| CliCommand::ScheduleAdd
|
||||
| CliCommand::ScheduleUpdate
|
||||
@@ -7389,6 +7458,9 @@ fn parse_translation_command(
|
||||
options: &mut CliOptions,
|
||||
) -> anyhow::Result<()> {
|
||||
let action = next_option_value(args, "translation")?;
|
||||
if action == "task" {
|
||||
return parse_translation_task_command(args, options);
|
||||
}
|
||||
let command = match action.as_str() {
|
||||
"run" => CliCommand::Translate,
|
||||
"export" => CliCommand::Translate,
|
||||
@@ -7409,6 +7481,21 @@ fn parse_translation_command(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_translation_task_command(
|
||||
args: &mut impl Iterator<Item = String>,
|
||||
options: &mut CliOptions,
|
||||
) -> anyhow::Result<()> {
|
||||
let action = next_option_value(args, "translation task")?;
|
||||
let command = match action.as_str() {
|
||||
"update" => CliCommand::TranslationTaskUpdate,
|
||||
"list" | "status" => CliCommand::TranslationTasks,
|
||||
other => return Err(anyhow::anyhow!("未知 translation task 二级命令:{other}")),
|
||||
};
|
||||
ensure_command_not_set(options.command, &format!("translation task {action}"))?;
|
||||
options.command = command;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_schedule_command(
|
||||
args: &mut impl Iterator<Item = String>,
|
||||
options: &mut CliOptions,
|
||||
@@ -7520,6 +7607,7 @@ fn print_usage(binary: &str) {
|
||||
eprintln!(" i18n export Export an editable translation workbench");
|
||||
eprintln!(" i18n set Update one translation workbench entry");
|
||||
eprintln!(" i18n validate Validate workbench against the current official release");
|
||||
eprintln!(" i18n task update Update one provider worker task status");
|
||||
eprintln!(" i18n publish Publish a localized release");
|
||||
eprintln!(" i18n schedule Manage translation schedules");
|
||||
eprintln!(" refresh Run one update check, or ask a live daemon to refresh");
|
||||
@@ -7602,6 +7690,8 @@ fn print_usage(binary: &str) {
|
||||
eprintln!(" --translation-id <ID> TextUnit ID for i18n set");
|
||||
eprintln!(" --translated-text <TEXT> Inline translation for i18n set");
|
||||
eprintln!(" --translated-file <PATH> UTF-8 translation file for i18n set");
|
||||
eprintln!(" --failure-reason <TEXT> Provider failure reason for i18n task update");
|
||||
eprintln!(" --provider-run-id <ID> Provider run ID for i18n task update");
|
||||
eprintln!(" --localized-release-id <ID> Explicit localized publication ID");
|
||||
eprintln!(" --repack-spec <PATH> UnityFS batch repack JSON spec");
|
||||
eprintln!();
|
||||
|
||||
@@ -228,6 +228,65 @@ fn grouped_workflow_commands_use_short_top_level_aliases() {
|
||||
])
|
||||
.unwrap();
|
||||
assert_eq!(options.command, CliCommand::TranslationValidate);
|
||||
|
||||
let options = parse(&[
|
||||
"bat",
|
||||
"i18n",
|
||||
"task",
|
||||
"update",
|
||||
"--state-dir",
|
||||
"/tmp/bat-state",
|
||||
"--task-id",
|
||||
"textunit/v-current/TextAssets/Scenario.json",
|
||||
"--task-status",
|
||||
"failed",
|
||||
"--failure-reason",
|
||||
"provider rejected payload",
|
||||
"--provider-run-id",
|
||||
"provider-run-1",
|
||||
])
|
||||
.unwrap();
|
||||
assert_eq!(options.command, CliCommand::TranslationTaskUpdate);
|
||||
assert_eq!(
|
||||
options.query_task_id.as_deref(),
|
||||
Some("textunit/v-current/TextAssets/Scenario.json")
|
||||
);
|
||||
assert_eq!(options.query_task_status.as_deref(), Some("failed"));
|
||||
assert_eq!(
|
||||
options.translation_failure_reason.as_deref(),
|
||||
Some("provider rejected payload")
|
||||
);
|
||||
assert_eq!(
|
||||
options.translation_provider_run_id.as_deref(),
|
||||
Some("provider-run-1")
|
||||
);
|
||||
assert!(parse(&["bat", "i18n", "task", "update", "--task-id", "task-only",]).is_err());
|
||||
assert!(parse(&[
|
||||
"bat",
|
||||
"i18n",
|
||||
"task",
|
||||
"update",
|
||||
"--task-id",
|
||||
"task",
|
||||
"--task-status",
|
||||
"running",
|
||||
"--worker-status",
|
||||
"failed",
|
||||
])
|
||||
.is_err());
|
||||
assert!(parse(&[
|
||||
"bat",
|
||||
"i18n",
|
||||
"task",
|
||||
"update",
|
||||
"--task-id",
|
||||
"task",
|
||||
"--task-status",
|
||||
"running",
|
||||
"--translation-file",
|
||||
"/tmp/workbench.json",
|
||||
])
|
||||
.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -156,6 +156,35 @@ pub(super) fn run_translation_set(options: &CliOptions) -> anyhow::Result<()> {
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn run_translation_task_update(options: &CliOptions) -> anyhow::Result<()> {
|
||||
let task_id = options
|
||||
.query_task_id
|
||||
.as_deref()
|
||||
.ok_or_else(|| anyhow::anyhow!("i18n task update 必须指定 --task-id"))?;
|
||||
let status = options
|
||||
.query_task_status
|
||||
.as_deref()
|
||||
.ok_or_else(|| anyhow::anyhow!("i18n task update 必须指定 --task-status"))?;
|
||||
let mut params = serde_json::Map::from_iter([
|
||||
("task_id".to_string(), serde_json::json!(task_id)),
|
||||
("status".to_string(), serde_json::json!(status)),
|
||||
]);
|
||||
if let Some(reason) = options.translation_failure_reason.as_deref() {
|
||||
params.insert("failure_reason".to_string(), serde_json::json!(reason));
|
||||
}
|
||||
if let Some(provider_run_id) = options.translation_provider_run_id.as_deref() {
|
||||
params.insert(
|
||||
"provider_run_id".to_string(),
|
||||
serde_json::json!(provider_run_id),
|
||||
);
|
||||
}
|
||||
let report = update_translation_task_status_report(
|
||||
&options.state_dir,
|
||||
Some(&serde_json::Value::Object(params)),
|
||||
)?;
|
||||
print_json_value(options.output_format, &report)
|
||||
}
|
||||
|
||||
pub(super) fn run_repack(options: &CliOptions) -> anyhow::Result<()> {
|
||||
let spec = options
|
||||
.repack_spec
|
||||
|
||||
Reference in New Issue
Block a user