mirror of
https://github.com/semaphoreui/semaphore.git
synced 2024-11-23 20:35:24 +01:00
feat: add translation script
This commit is contained in:
parent
0a92e7c571
commit
2580c0b2bf
1
.gitignore
vendored
1
.gitignore
vendored
@ -30,3 +30,4 @@ node_modules/
|
|||||||
.vscode
|
.vscode
|
||||||
__debug_bin*
|
__debug_bin*
|
||||||
.task/
|
.task/
|
||||||
|
/web/.env
|
61
web/gulp-gpt-translate.js
Normal file
61
web/gulp-gpt-translate.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
const through = require('through2');
|
||||||
|
const PluginError = require('plugin-error');
|
||||||
|
const { OpenAI } = require('openai');
|
||||||
|
|
||||||
|
const PLUGIN_NAME = 'gulp-gpt-translate';
|
||||||
|
|
||||||
|
function gptTranslate(options) {
|
||||||
|
if (!options || !options.apiKey) {
|
||||||
|
throw new PluginError(PLUGIN_NAME, 'An OpenAI API key is required.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.targetLanguage) {
|
||||||
|
throw new PluginError(PLUGIN_NAME, 'A target language must be specified.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const openai = new OpenAI();
|
||||||
|
|
||||||
|
return through.obj(function (file, enc, cb) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
if (file.isNull()) {
|
||||||
|
return cb(null, file); // Pass along if no contents
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.isStream()) {
|
||||||
|
self.emit('error', new PluginError(PLUGIN_NAME, 'Streaming not supported.'));
|
||||||
|
return cb();
|
||||||
|
}
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const content = file.contents.toString(enc);
|
||||||
|
|
||||||
|
console.log(`****** translating file ${file.path} ******`);
|
||||||
|
|
||||||
|
const response = await openai.chat.completions.create({
|
||||||
|
model: options.model || 'gpt-4o-mini',
|
||||||
|
temperature: 0,
|
||||||
|
messages: [
|
||||||
|
{
|
||||||
|
role: 'system',
|
||||||
|
content: `You are a helpful assistant that translates text to ${options.targetLanguage}. `,
|
||||||
|
},
|
||||||
|
...(options.messages || []).map((m) => ({ role: 'user', content: m })),
|
||||||
|
{ role: 'user', content },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
file.contents = Buffer.from(response.choices[0].message.content, enc);
|
||||||
|
|
||||||
|
self.push(file);
|
||||||
|
cb();
|
||||||
|
} catch (err) {
|
||||||
|
self.emit('error', new PluginError(PLUGIN_NAME, err.message));
|
||||||
|
cb(err);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = gptTranslate;
|
35
web/gulpfile.js
Normal file
35
web/gulpfile.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
const { src, dest } = require('gulp');
|
||||||
|
const rename = require('gulp-rename');
|
||||||
|
require('dotenv').config();
|
||||||
|
const gptTranslate = require('./gulp-gpt-translate');
|
||||||
|
|
||||||
|
const LANG_NAMES = {
|
||||||
|
en: 'English',
|
||||||
|
ru: 'Russian',
|
||||||
|
es: 'Spanish',
|
||||||
|
fr: 'French',
|
||||||
|
de: 'German',
|
||||||
|
it: 'Italian',
|
||||||
|
ja: 'Japanese',
|
||||||
|
ko: 'Korean',
|
||||||
|
pt: 'Portuguese',
|
||||||
|
zh: 'Chinese',
|
||||||
|
};
|
||||||
|
|
||||||
|
function tr() {
|
||||||
|
return Object.keys(LANG_NAMES).filter((lang) => lang !== 'en').map((lang) => src('src/lang/en.js')
|
||||||
|
.pipe(gptTranslate({
|
||||||
|
apiKey: process.env.OPENAI_API_KEY,
|
||||||
|
targetLanguage: LANG_NAMES[lang],
|
||||||
|
messages: [
|
||||||
|
'This content contains Ansible Semaphore strings.',
|
||||||
|
'Do not wrap result to any formatting tags. Result must be valid json file.',
|
||||||
|
],
|
||||||
|
}))
|
||||||
|
.pipe(rename({ basename: lang }))
|
||||||
|
.pipe(dest('src/lang')));
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
tr,
|
||||||
|
};
|
2454
web/package-lock.json
generated
2454
web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -32,17 +32,24 @@
|
|||||||
"@vue/test-utils": "^1.3.0",
|
"@vue/test-utils": "^1.3.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
"chai": "^4.3.6",
|
"chai": "^4.3.6",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
"eslint": "^7.32.0",
|
"eslint": "^7.32.0",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"eslint-plugin-vue": "^9.1.1",
|
"eslint-plugin-vue": "^9.1.1",
|
||||||
"eslint-plugin-vuejs-accessibility": "^1.2.0",
|
"eslint-plugin-vuejs-accessibility": "^1.2.0",
|
||||||
"glob-parent": ">=5.1.2",
|
"glob-parent": ">=5.1.2",
|
||||||
|
"gulp": "^5.0.0",
|
||||||
|
"gulp-cli": "^3.0.0",
|
||||||
|
"gulp-rename": "^2.0.0",
|
||||||
"nanoid": ">=3.1.31",
|
"nanoid": ">=3.1.31",
|
||||||
"nyc": "^15.1.0",
|
"nyc": "^15.1.0",
|
||||||
|
"openai": "^4.65.0",
|
||||||
|
"plugin-error": "^2.0.1",
|
||||||
"sass": "~1.32.12",
|
"sass": "~1.32.12",
|
||||||
"sass-loader": "^13.0.0",
|
"sass-loader": "^13.0.0",
|
||||||
"stylus": "^0.54.8",
|
"stylus": "^0.54.8",
|
||||||
"stylus-loader": "^3.0.2",
|
"stylus-loader": "^3.0.2",
|
||||||
|
"through2": "^4.0.2",
|
||||||
"vue-cli-plugin-vuetify": "~2.0.7",
|
"vue-cli-plugin-vuetify": "~2.0.7",
|
||||||
"vue-template-compiler": "^2.6.14",
|
"vue-template-compiler": "^2.6.14",
|
||||||
"vuetify-loader": "^1.8.0"
|
"vuetify-loader": "^1.8.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user