Move tolgee downloader into this repository and refactor translation storage architecture
This commit is contained in:
parent
c052c438eb
commit
990f75d9ba
95 changed files with 80964 additions and 43454 deletions
221
downloader/index.ts
Normal file
221
downloader/index.ts
Normal file
|
@ -0,0 +1,221 @@
|
|||
import * as fs from 'node:fs';
|
||||
import * as path from 'node:path';
|
||||
|
||||
import axios from 'axios';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config({ path: '.env' }).parsed;
|
||||
|
||||
const prepareLuaWithFemaleVersion = (quest: Quest, type: keyof Quest, key: string) => {
|
||||
let text = '';
|
||||
const value = quest[type] as string;
|
||||
text += '\t' + key + 'Male = "' + (value?.[0]?.replace(/\n/g, '\\n') ?? '').replace(/"/g, "'") + '", \n';
|
||||
text += '\t' + key + 'Female = "' + (value?.[1]?.replace(/\n/g, '\\n') ?? '').replace(/"/g, "'") + '", \n';
|
||||
return text;
|
||||
};
|
||||
|
||||
const callTolgee = async <R>(
|
||||
method: 'GET' | 'POST' | 'PUT' | 'DELETE' = 'GET',
|
||||
path: string,
|
||||
params?: any,
|
||||
data?: any,
|
||||
) => {
|
||||
const args = process.argv.slice(2);
|
||||
const projectId = args[1];
|
||||
try {
|
||||
return await axios<R>(`https://translate.romanjaros.local/v2/projects/${projectId}${path}`, {
|
||||
method,
|
||||
data,
|
||||
params,
|
||||
headers: {
|
||||
'X-API-KEY': process.env.TOLGEE_PAT as string,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
|
||||
function makeChunks(input: AddonData, chunkSize: number = 1000) {
|
||||
const keys = Object.keys(input);
|
||||
const result = [];
|
||||
|
||||
for (let i = 0; i < keys.length; i += chunkSize) {
|
||||
const chunk = keys.slice(i, i + chunkSize).reduce((acc: AddonData, key) => {
|
||||
acc[key] = input[key];
|
||||
return acc;
|
||||
}, {});
|
||||
result.push(chunk);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const args = process.argv.slice(2);
|
||||
const addonDir = path.join(process.cwd(), `../Quests/Data/${args[0]}`);
|
||||
|
||||
const addonData: Record<string, Quest> = {};
|
||||
let pageNumber = 0;
|
||||
|
||||
try {
|
||||
// load all data from tolgee
|
||||
while (true) {
|
||||
const response = await callTolgee<TolgeeTranslationsResponse>('GET', `/translations`, {
|
||||
filterTranslatedInLang: 'cs',
|
||||
languages: 'cs,csf',
|
||||
size: 2000,
|
||||
page: pageNumber,
|
||||
});
|
||||
const translations = response.data?._embedded?.keys ?? [];
|
||||
if (response.data?.page.totalPages > response.data?.page.number) {
|
||||
pageNumber++;
|
||||
|
||||
// for each page from tolgee
|
||||
for (const tolgeeKey of translations) {
|
||||
addonData[tolgeeKey.keyName] = {
|
||||
...addonData[tolgeeKey.keyName],
|
||||
...(tolgeeKey.keyNamespace === 'name' && {
|
||||
names: [
|
||||
tolgeeKey.translations.cs.text,
|
||||
tolgeeKey.translations.cs.text === tolgeeKey.translations.csf.text
|
||||
? null
|
||||
: tolgeeKey.translations.csf.text,
|
||||
],
|
||||
}),
|
||||
...(tolgeeKey.keyNamespace === 'objective' && {
|
||||
objectives: [
|
||||
tolgeeKey.translations.cs.text,
|
||||
tolgeeKey.translations.cs.text === tolgeeKey.translations.csf.text
|
||||
? null
|
||||
: tolgeeKey.translations.csf.text,
|
||||
],
|
||||
}),
|
||||
...(tolgeeKey.keyNamespace === 'description' && {
|
||||
descriptions: [
|
||||
tolgeeKey.translations.cs.text,
|
||||
tolgeeKey.translations.cs.text === tolgeeKey.translations.csf.text
|
||||
? null
|
||||
: tolgeeKey.translations.csf.text,
|
||||
],
|
||||
}),
|
||||
...(tolgeeKey.keyNamespace === 'progress' && {
|
||||
progresses: [
|
||||
tolgeeKey.translations.cs.text,
|
||||
tolgeeKey.translations.cs.text === tolgeeKey.translations.csf.text
|
||||
? null
|
||||
: tolgeeKey.translations.csf.text,
|
||||
],
|
||||
}),
|
||||
...(tolgeeKey.keyNamespace === 'completion' && {
|
||||
completions: [
|
||||
tolgeeKey.translations.cs.text,
|
||||
tolgeeKey.translations.cs.text === tolgeeKey.translations.csf.text
|
||||
? null
|
||||
: tolgeeKey.translations.csf.text,
|
||||
],
|
||||
}),
|
||||
name: tolgeeKey.keyDescription,
|
||||
id: tolgeeKey.keyName.replace('q', '').replace('i', ''),
|
||||
questItem: tolgeeKey.keyName.startsWith('i'),
|
||||
};
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// split into chunks
|
||||
const chunks = makeChunks(addonData);
|
||||
|
||||
// build addon file
|
||||
chunks.forEach((chunk, index) => {
|
||||
const fileName = path.join(addonDir, `${index++}.lua`);
|
||||
try {
|
||||
fs.unlinkSync(fileName);
|
||||
} catch (e) {}
|
||||
for (const [, czechQuest] of Object.entries(chunk)) {
|
||||
// prepare variables
|
||||
let variableTable = 'quest';
|
||||
let variableId = czechQuest.id;
|
||||
|
||||
// if quest is quest item witch pages, store it inside item table
|
||||
if (czechQuest.questItem) {
|
||||
variableTable = 'item';
|
||||
const page = czechQuest.id.split('_page')?.[1] ?? null;
|
||||
variableId = `"${czechQuest.name}${page ? `__${page}` : ''}"`;
|
||||
}
|
||||
|
||||
let luaQuestRecord = '';
|
||||
luaQuestRecord += `CzechQuestsAddon.data.${variableTable}[${variableId}] = {\n`;
|
||||
luaQuestRecord += prepareLuaWithFemaleVersion(czechQuest, 'names', 'title');
|
||||
luaQuestRecord += prepareLuaWithFemaleVersion(czechQuest, 'objectives', 'objective');
|
||||
luaQuestRecord += prepareLuaWithFemaleVersion(czechQuest, 'descriptions', 'description');
|
||||
luaQuestRecord += prepareLuaWithFemaleVersion(czechQuest, 'progresses', 'progress');
|
||||
luaQuestRecord += prepareLuaWithFemaleVersion(czechQuest, 'completions', 'completion');
|
||||
luaQuestRecord += `}\n`;
|
||||
fs.appendFileSync(fileName, luaQuestRecord, 'utf8');
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
})();
|
||||
|
||||
type AddonData = Record<string, Quest>;
|
||||
|
||||
type Quest = {
|
||||
id: string;
|
||||
name: string;
|
||||
names?: (string | null)[];
|
||||
description?: string;
|
||||
descriptions?: (string | null)[];
|
||||
progress?: string;
|
||||
progresses?: (string | null)[];
|
||||
completion?: string;
|
||||
completions?: (string | null)[];
|
||||
objective?: string;
|
||||
objectives?: (string | null)[];
|
||||
questItem: boolean;
|
||||
};
|
||||
|
||||
type TolgeeKeysData = {
|
||||
keyId: number;
|
||||
keyName: string;
|
||||
keyNamespace: string;
|
||||
keyDescription: string;
|
||||
keyTags: TolgeeTag[];
|
||||
translations: {
|
||||
en: {
|
||||
id: number;
|
||||
text: string;
|
||||
state: 'REVIEWED' | 'TRANSLATED';
|
||||
};
|
||||
cs: {
|
||||
id: number;
|
||||
text: string | null;
|
||||
state: 'REVIEWED' | 'TRANSLATED';
|
||||
};
|
||||
csf: {
|
||||
id: number;
|
||||
text: string | null;
|
||||
state: 'REVIEWED' | 'TRANSLATED';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
type TolgeeTag = {
|
||||
name: string;
|
||||
};
|
||||
|
||||
type TolgeeTranslationsResponse = {
|
||||
_embedded: {
|
||||
keys: TolgeeKeysData[];
|
||||
};
|
||||
page: {
|
||||
size: number;
|
||||
totalElements: number;
|
||||
totalPages: number;
|
||||
number: number;
|
||||
};
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue