feat: add bulkTranslate
This commit is contained in:
@@ -39,6 +39,11 @@ module.exports = createCoreController('api::parole.parole', ({strapi}) => ({
|
||||
ctx.body = lines.join('\n')
|
||||
},
|
||||
|
||||
async bulkTranslate(ctx) {
|
||||
const result = await strapi.service('api::parole.parole').bulkTranslateMissing()
|
||||
return ctx.send(result)
|
||||
},
|
||||
|
||||
async findOne(documentId) {
|
||||
const parole = await strapi.documents('api::parole.parole').findOne({
|
||||
documentId,
|
||||
|
||||
@@ -42,6 +42,8 @@ function suspectFrench(text) {
|
||||
return frCount / words.length > 0.04
|
||||
}
|
||||
|
||||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
|
||||
|
||||
class Translator {
|
||||
constructor() {
|
||||
this.deeplApi = process.env.DEEPL_URL || 'api-free.deepl.com'
|
||||
@@ -196,6 +198,77 @@ module.exports = createCoreService('api::parole.parole', ({strapi}) => ({
|
||||
return { metadata, pairs }
|
||||
},
|
||||
|
||||
async bulkTranslateMissing() {
|
||||
const TARGET_LANGS = [
|
||||
{ lang: 'en', field: 'anglais', deeplTarget: 'EN', suffix: '\n\n(Translated by DeepL)' },
|
||||
{ lang: 'es', field: 'espagnol', deeplTarget: 'ES', suffix: '\n\n(Traducido por DeepL)' },
|
||||
{ lang: 'de', field: 'allemand', deeplTarget: 'DE', suffix: '\n\n(Übersetzt von DeepL)' },
|
||||
{ lang: 'it', field: 'italien', deeplTarget: 'IT', suffix: '\n\n(Tradotto da DeepL)' },
|
||||
]
|
||||
|
||||
const pageSize = 100
|
||||
let start = 0
|
||||
const all = []
|
||||
while (true) {
|
||||
const batch = await strapi.documents('api::parole.parole').findMany({
|
||||
status: 'published',
|
||||
populate: ['traductions'],
|
||||
fields: ['documentId', 'slug', 'titre', 'transcription', 'langueSource'],
|
||||
limit: pageSize,
|
||||
start,
|
||||
})
|
||||
all.push(...batch)
|
||||
if (batch.length < pageSize) break
|
||||
start += pageSize
|
||||
}
|
||||
|
||||
const translator = new Translator()
|
||||
const translated = []
|
||||
const skipped = []
|
||||
const errors = []
|
||||
|
||||
for (const parole of all) {
|
||||
const sourceFR = parole.traductions?.francais
|
||||
|| (parole.langueSource === 'fr' ? parole.transcription : null)
|
||||
|
||||
if (!sourceFR) { skipped.push(parole.slug); continue }
|
||||
|
||||
const missing = TARGET_LANGS.filter(({ field }) => !parole.traductions?.[field])
|
||||
if (missing.length === 0) { skipped.push(parole.slug); continue }
|
||||
|
||||
const { id: _id, ...tradData } = parole.traductions || {}
|
||||
const updatedTrad = { ...tradData }
|
||||
const addedLangs = []
|
||||
|
||||
for (const { lang, field, deeplTarget, suffix } of missing) {
|
||||
try {
|
||||
await sleep(700)
|
||||
const result = await translator.get('FR', deeplTarget, sourceFR)
|
||||
const text = result?.translations?.[0]?.text
|
||||
if (text) {
|
||||
updatedTrad[field] = text + suffix
|
||||
addedLangs.push(lang)
|
||||
}
|
||||
} catch (err) {
|
||||
errors.push({ slug: parole.slug, lang: deeplTarget, error: err.message })
|
||||
}
|
||||
}
|
||||
|
||||
if (addedLangs.length > 0) {
|
||||
await strapi.documents('api::parole.parole').update({
|
||||
documentId: parole.documentId,
|
||||
data: { traductions: updatedTrad },
|
||||
})
|
||||
await strapi.documents('api::parole.parole').publish({
|
||||
documentId: parole.documentId,
|
||||
})
|
||||
translated.push({ slug: parole.slug, langs: addedLangs })
|
||||
}
|
||||
}
|
||||
|
||||
return { translated, skipped, errors }
|
||||
},
|
||||
|
||||
parolesDiff(titre = '', oldString, newString) {
|
||||
const patch = Diff.createPatch(titre, oldString, newString, 'supprimée', 'ajoutée')
|
||||
const parsePatch = Diff.parsePatch(patch)
|
||||
|
||||
Reference in New Issue
Block a user