Skip to content

Commit

Permalink
Support auto translate to english
Browse files Browse the repository at this point in the history
  • Loading branch information
huangdijia committed Dec 31, 2024
1 parent 988b767 commit ffebb3f
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 39 deletions.
35 changes: 34 additions & 1 deletion .github/workflows/docs-translate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- 'docs/**'

jobs:
translate:
translate-zh:
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand Down Expand Up @@ -48,3 +48,36 @@ jobs:
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Update docs and translate

translate-en:
runs-on: ubuntu-latest
env:
DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }}
steps:
- name: Checkout
uses: actions/checkout@v4

- uses: pnpm/action-setup@v4
name: Install pnpm
with:
version: 9
run_install: false

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'

- name: Install dependencies
run: pnpm install

- name: Start Translate
run: |
cp docs/index.md docs/en/index.md
pnpm run doc-translate
- name: Commit Updated
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Update docs and translate
52 changes: 52 additions & 0 deletions bin/doc-translate.github-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import OpenAI from "openai";
import { promises as fs } from 'fs';
import path from 'path';

const token = process.env["GITHUB_TOKEN"];
const endpoint = "https://models.inference.ai.azure.com";
const modelName = "o1-mini";

async function translateFiles() {
const client = new OpenAI({
baseURL: endpoint,
apiKey: token,
dangerouslyAllowBrowser: true
});

const docsPath = path.join(process.cwd(), 'docs/zh-cn');

async function translateFile(filePath) {
const content = await fs.readFile(filePath, 'utf8');
const response = await client.chat.completions.create({
messages: [
{ role: "user", content: "You are a professional translator. Translate the following Markdown content from Chinese to English. Preserve all Markdown formatting." },
{ role: "user", content: content }
],
model: modelName
});

const translatedContent = response.choices[0].message.content;
const englishPath = filePath.replace('/zh-cn/', '/en/');
await fs.mkdir(path.dirname(englishPath), { recursive: true });
await fs.writeFile(englishPath, translatedContent);
console.log(`Translated: ${filePath} -> ${englishPath}`);
}

async function processDirectory(dirPath) {
const files = await fs.readdir(dirPath, { withFileTypes: true });

for (const file of files) {
const fullPath = path.join(dirPath, file.name);

if (file.isDirectory()) {
await processDirectory(fullPath);
} else if (file.name.endsWith('.md')) {
await translateFile(fullPath);
}
}
}

await processDirectory(docsPath);
}

translateFiles().catch(console.error);
73 changes: 35 additions & 38 deletions bin/doc-translate.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,49 @@
import OpenAI from "openai";
import { promises as fs } from 'fs';
import { readdir, readFile, writeFile, mkdir } from 'fs/promises';
import path from 'path';

const token = process.env["GITHUB_TOKEN"];
const endpoint = "https://models.inference.ai.azure.com";
const modelName = "o1-mini";
const endpoint = "https://api.deepseek.com";
const token = process.env["DEEPSEEK_API_KEY"];

async function translateFiles() {
const client = new OpenAI({
const openai = new OpenAI({
baseURL: endpoint,
apiKey: token,
dangerouslyAllowBrowser: true
});

const docsPath = path.join(process.cwd(), 'docs/zh-cn');

async function translateFile(filePath) {
const content = await fs.readFile(filePath, 'utf8');
const response = await client.chat.completions.create({
messages: [
{ role: "user", content: "You are a professional translator. Translate the following Markdown content from Chinese to English. Preserve all Markdown formatting." },
{ role: "user", content: content }
],
model: modelName
});

async function translateContent(content) {
const completion = await openai.chat.completions.create({
messages: [
{ role: "system", content: "You are a professional translator. Translate the following Chinese markdown content to English. Keep all markdown formatting intact." },
{ role: "user", content: content }
],
model: "deepseek-chat",
});
return completion.choices[0].message.content;
}

const translatedContent = response.choices[0].message.content;
const englishPath = filePath.replace('/zh-cn/', '/en/');
await fs.mkdir(path.dirname(englishPath), { recursive: true });
await fs.writeFile(englishPath, translatedContent);
console.log(`Translated: ${filePath} -> ${englishPath}`);
}
async function translateFiles(srcDir, destDir) {
try {
const files = await readdir(srcDir, { recursive: true });

async function processDirectory(dirPath) {
const files = await fs.readdir(dirPath, { withFileTypes: true });
for (const file of files) {
if (!file.endsWith('.md')) continue;

for (const file of files) {
const fullPath = path.join(dirPath, file.name);
const srcPath = path.join(srcDir, file);
const destPath = path.join(destDir, file);
const destFolder = path.dirname(destPath);

if (file.isDirectory()) {
await processDirectory(fullPath);
} else if (file.name.endsWith('.md')) {
await translateFile(fullPath);
}
}
}
await mkdir(destFolder, { recursive: true });

await processDirectory(docsPath);
const content = await readFile(srcPath, 'utf8');
const translatedContent = await translateContent(content);
const finalContent = translatedContent.replace(/\/zh-cn\//g, '/en/');
await writeFile(destPath, finalContent);

console.log(`Translated: ${file}`);
}
} catch (error) {
console.error('Translation error:', error);
}
}

translateFiles().catch(console.error);
translateFiles('docs/zh-cn', 'docs/en');

0 comments on commit ffebb3f

Please sign in to comment.