Skip to content

Commit 462bf46

Browse files
committed
added ability to translate specific languages and/or sections through command yarn scripts
1 parent 3578a86 commit 462bf46

File tree

2 files changed

+47
-14
lines changed

2 files changed

+47
-14
lines changed

i18n/controllers/recurTranslate.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const MAXLEN = Number(process.env.MAX_LEN) || 3000;
3434
// change to true to avoid calling openai api, useful for troubleshooting
3535
// chunking logic
3636
const troubleshoot = false;
37+
let languageNames = new Intl.DisplayNames(["en"], { type: "language" });
3738

3839
// Centralized logging to prevent duplicate messages
3940
const errorMessages = new Set();
@@ -73,21 +74,29 @@ export function getFileErrors(): Record<
7374
const createParser = () =>
7475
(sax as any).createStream(false, { trim: false }, { strictEntities: true });
7576

76-
async function translate(language: string, filePath: string): Promise<void> {
77+
async function translate(langCode: string, filePath: string): Promise<void> {
7778
const startTime = new Date().getTime();
7879
let assistant;
7980

8081
try {
8182
// Use the provided file path directly without modification
8283
const input_path = filePath;
84+
const language = languageNames.of(langCode);
85+
86+
if (language === undefined) {
87+
throw new Error('Undefined language');
88+
}
8389

8490
if (!troubleshoot) assistant = await createAssistant(language, ai as any);
8591

92+
8693
// Generate output path by replacing "/en/" with "/cn/" in the path
8794
const output_path = filePath.replace(
8895
path.sep + "en" + path.sep,
89-
path.sep + "cn" + path.sep
96+
path.sep + langCode + path.sep
9097
);
98+
99+
91100

92101
const translated: string = await recursivelyTranslate(
93102
language,
@@ -112,7 +121,7 @@ async function translate(language: string, filePath: string): Promise<void> {
112121
});
113122
}
114123
const elapsed = new Date().getTime() - startTime;
115-
console.log(filePath + " took " + elapsed / 1000.0 + " seconds");
124+
console.log("Took " + elapsed / 1000.0 + " seconds");
116125
}
117126
}
118127

@@ -273,7 +282,7 @@ async function recursivelyTranslate(
273282

274283
try {
275284
await new Promise<void>((resolve, reject) => {
276-
console.log("Translating " + filePath + " at " + thread.id);
285+
console.log("Translating " + filePath + " to " + language + " at " + thread.id);
277286
// Variables to track current depth and segments.
278287
let currentDepth = 0;
279288
let currentSegment = "";
@@ -413,7 +422,7 @@ async function recursivelyTranslate(
413422
try {
414423
await ai.beta.threads.messages.create(thread.id, {
415424
role: "user",
416-
content: `<TRANSLATE> ${chunk} </TRANSLATE>`
425+
content: `Translate to ${language}: <TRANSLATE> ${chunk} </TRANSLATE>`
417426
});
418427

419428
const run = await ai.beta.threads.runs.createAndPoll(thread.id, {

i18n/index.ts

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
import PathGenerator from "./controllers/path.ts";
22
import translate, { getFileErrors } from "./controllers/recurTranslate.ts";
33
import fs from "fs";
4+
import util from "util";
45
import path from "path";
56
import { fileURLToPath } from "url";
67
import { dirname } from "path";
78
import OpenAI from "openai";
9+
import { permission } from "process";
810

911
// Get the directory name of the current module
1012
const __filename = fileURLToPath(import.meta.url);
1113
const __dirname = dirname(__filename);
1214

15+
const readdir = util.promisify(fs.readdir);
16+
const getDirectories = async source =>
17+
(await readdir(source, { withFileTypes: true }))
18+
.filter(dirent => dirent.isDirectory())
19+
.map(dirent => dirent.name);
20+
1321
// Global variables for tracking translation state
1422
// These need to be accessible by signal handlers
1523
let xmlFiles: string[] = [];
@@ -52,7 +60,7 @@ async function saveSummaryLog() {
5260
failedDel.push(file.id);
5361
}
5462
})
55-
).then(() => console.log("successfully deleted all files"))
63+
).then(() => console.log("successfully deleted all files"));
5664

5765
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
5866
let summaryLog = `
@@ -189,11 +197,11 @@ async function findAllXmlFiles(directory: string): Promise<string[]> {
189197
}
190198

191199
// Function to check if a file needs translation
192-
async function needsTranslation(enFilePath: string): Promise<boolean> {
200+
async function needsTranslation(enFilePath: string, lang: string): Promise<boolean> {
193201
// Generate the corresponding cn file path
194202
const cnFilePath = enFilePath.replace(
195203
path.sep + "en" + path.sep,
196-
path.sep + "cn" + path.sep
204+
path.sep + lang + path.sep
197205
);
198206

199207
try {
@@ -212,15 +220,29 @@ async function needsTranslation(enFilePath: string): Promise<boolean> {
212220
}
213221
}
214222

215-
export default async function fancyName(path: string) {
223+
export default async function fancyName(path: string, language: string) {
216224
const fullPath = PathGenerator(path);
217-
await translate("Chinese", fullPath);
225+
await translate(language, fullPath);
218226
}
219227

220228
(async () => {
221229
await setupCleanupHandlers();
222230

223231
try {
232+
if ((process.argv[2], process.argv[3])) {
233+
fancyName(process.argv[2], process.argv[3]);
234+
return;
235+
}
236+
237+
let languages: string[] = [];
238+
239+
if (process.argv[2] === "all") {
240+
languages = await getDirectories(path.join(__dirname, "../xml"));
241+
console.dir(languages);
242+
} else {
243+
languages.push(process.argv[2]);
244+
}
245+
224246
// Get the absolute path to the xml/en directory using proper path resolution
225247
const enDirPath = path.resolve(__dirname, "../xml/en");
226248

@@ -230,19 +252,20 @@ export default async function fancyName(path: string) {
230252
xmlFiles = await findAllXmlFiles(enDirPath);
231253

232254
console.log(`Found ${xmlFiles.length} XML files to check for translation`);
233-
255+
256+
for (const lang of languages) {
234257
// Filter files that need translation
235258
filesToTranslate = [];
236259
for (const file of xmlFiles) {
237-
if (await needsTranslation(file)) {
260+
if (await needsTranslation(file, lang)) {
238261
filesToTranslate.push(file as never);
239262
}
240263
}
241264

242265
console.log(`${filesToTranslate.length} files need translation`);
243266

244267
if (filesToTranslate.length === 0) {
245-
console.log("No files need translation. Exiting.");
268+
console.log(`No files need translation for ${lang}.`);
246269
return;
247270
}
248271

@@ -263,7 +286,7 @@ export default async function fancyName(path: string) {
263286
batch.map(async file => {
264287
try {
265288
console.log(`Starting translation for ${file}`);
266-
await translate("Chinese", file);
289+
await translate(lang, file);
267290
return { file, success: true };
268291
} catch (error) {
269292
// Return failure with error but don't log yet
@@ -325,6 +348,7 @@ export default async function fancyName(path: string) {
325348

326349
// Save a detailed summary to a log file
327350
await saveSummaryLog();
351+
}
328352
} catch (e) {
329353
console.error("Error during translation process:", e);
330354
}

0 commit comments

Comments
 (0)