mirror of
https://github.com/itdoginfo/podkop.git
synced 2025-12-06 11:36:50 +03:00
114 lines
3.6 KiB
JavaScript
114 lines
3.6 KiB
JavaScript
import fs from 'fs/promises';
|
|
import { execSync } from 'child_process';
|
|
|
|
const lang = process.argv[2];
|
|
if (!lang) {
|
|
console.error('❌ Укажи язык, например: node generate-po.js ru');
|
|
process.exit(1);
|
|
}
|
|
|
|
const callsPath = 'locales/calls.json';
|
|
const poPath = `locales/podkop.${lang}.po`;
|
|
|
|
function getGitUser() {
|
|
try {
|
|
return execSync('git config user.name').toString().trim();
|
|
} catch {
|
|
return 'Automatically generated';
|
|
}
|
|
}
|
|
|
|
function getHeader(lang) {
|
|
const now = new Date();
|
|
const date = now.toISOString().split('T')[0];
|
|
const time = now.toTimeString().split(' ')[0].slice(0, 5);
|
|
const tzOffset = (() => {
|
|
const offset = -now.getTimezoneOffset();
|
|
const sign = offset >= 0 ? '+' : '-';
|
|
const hours = String(Math.floor(Math.abs(offset) / 60)).padStart(2, '0');
|
|
const minutes = String(Math.abs(offset) % 60).padStart(2, '0');
|
|
return `${sign}${hours}${minutes}`;
|
|
})();
|
|
|
|
const translator = getGitUser();
|
|
const pluralForms = lang === 'ru'
|
|
? 'nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);'
|
|
: 'nplurals=2; plural=(n != 1);';
|
|
|
|
return [
|
|
`# ${lang.toUpperCase()} translations for PODKOP package.`,
|
|
`# Copyright (C) ${now.getFullYear()} THE PODKOP'S COPYRIGHT HOLDER`,
|
|
`# This file is distributed under the same license as the PODKOP package.`,
|
|
`# ${translator}, ${now.getFullYear()}.`,
|
|
'#',
|
|
'msgid ""',
|
|
'msgstr ""',
|
|
`"Project-Id-Version: PODKOP\\n"`,
|
|
`"Report-Msgid-Bugs-To: \\n"`,
|
|
`"POT-Creation-Date: ${date} ${time}${tzOffset}\\n"`,
|
|
`"PO-Revision-Date: ${date} ${time}${tzOffset}\\n"`,
|
|
`"Last-Translator: ${translator}\\n"`,
|
|
`"Language-Team: none\\n"`,
|
|
`"Language: ${lang}\\n"`,
|
|
`"MIME-Version: 1.0\\n"`,
|
|
`"Content-Type: text/plain; charset=UTF-8\\n"`,
|
|
`"Content-Transfer-Encoding: 8bit\\n"`,
|
|
`"Plural-Forms: ${pluralForms}\\n"`,
|
|
'',
|
|
];
|
|
}
|
|
|
|
function parsePo(content) {
|
|
const lines = content.split('\n');
|
|
const translations = new Map();
|
|
let msgid = null;
|
|
let msgstr = null;
|
|
for (const line of lines) {
|
|
if (line.startsWith('msgid ')) {
|
|
msgid = JSON.parse(line.slice(6));
|
|
} else if (line.startsWith('msgstr ') && msgid !== null) {
|
|
msgstr = JSON.parse(line.slice(7));
|
|
translations.set(msgid, msgstr);
|
|
msgid = null;
|
|
msgstr = null;
|
|
}
|
|
}
|
|
return translations;
|
|
}
|
|
|
|
function escapePoString(str) {
|
|
return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
}
|
|
|
|
async function generatePo() {
|
|
const [callsRaw, oldPoRaw] = await Promise.all([
|
|
fs.readFile(callsPath, 'utf8'),
|
|
fs.readFile(poPath, 'utf8').catch(() => ''),
|
|
]);
|
|
|
|
const calls = JSON.parse(callsRaw);
|
|
const oldTranslations = parsePo(oldPoRaw);
|
|
const header = getHeader(lang);
|
|
|
|
const body = calls
|
|
.map(({ key }) => {
|
|
const msgid = key;
|
|
const msgstr = oldTranslations.get(msgid) || '';
|
|
return [
|
|
`msgid "${escapePoString(msgid)}"`,
|
|
`msgstr "${escapePoString(msgstr)}"`,
|
|
''
|
|
].join('\n');
|
|
})
|
|
.join('\n');
|
|
|
|
const finalPo = header.join('\n') + '\n' + body;
|
|
|
|
await fs.writeFile(poPath, finalPo, 'utf8');
|
|
console.log(`✅ Файл ${poPath} успешно сгенерирован. Переведено ${[...oldTranslations.keys()].length}/${calls.length}`);
|
|
}
|
|
|
|
generatePo().catch((err) => {
|
|
console.error('Ошибка генерации PO файла:', err);
|
|
});
|