Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b01132f104
|
@@ -57,4 +57,28 @@ describe('translateLyrics', () => {
|
|||||||
expect(result.anglais).toContain('traduit-EN');
|
expect(result.anglais).toContain('traduit-EN');
|
||||||
expect(result.espagnol).toBeUndefined();
|
expect(result.espagnol).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('traduit les langues africaines ajoutées, sans appeler DeepL pour le yoruba', async () => {
|
||||||
|
global.fetch = vi.fn(async (_url, options) => {
|
||||||
|
const {target_lang: target} = JSON.parse(options.body);
|
||||||
|
return fakeDeeplResponse(`traduit-${target}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const strapi = {
|
||||||
|
contentType: vi.fn(() => ({uid: 'api::parole.parole', kind: 'collectionType'})),
|
||||||
|
log: {error: vi.fn()}
|
||||||
|
};
|
||||||
|
const service = createService({strapi});
|
||||||
|
const result = await service.translateLyrics('Bonjour le monde');
|
||||||
|
|
||||||
|
expect(result.swahili).toContain('traduit-SW');
|
||||||
|
expect(result.lingala).toContain('traduit-LN');
|
||||||
|
expect(result.wolof).toContain('traduit-WO');
|
||||||
|
expect(result.hausa).toContain('traduit-HA');
|
||||||
|
expect(result.yoruba).toBeUndefined();
|
||||||
|
|
||||||
|
const calledTargets = global.fetch.mock.calls.map(([, options]) => JSON.parse(options.body).target_lang);
|
||||||
|
expect(calledTargets).not.toContain('YO');
|
||||||
|
expect(calledTargets).not.toContain(undefined);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,21 @@ const { ApplicationError } = require('@strapi/utils').errors;
|
|||||||
|
|
||||||
const LANG_MAP = {
|
const LANG_MAP = {
|
||||||
fr: { field: 'francais', targetLang: 'fr', userPrompt: 'Tradui an fransé' },
|
fr: { field: 'francais', targetLang: 'fr', userPrompt: 'Tradui an fransé' },
|
||||||
|
// Pas de code DeepL pour le yoruba : traduction manuelle uniquement.
|
||||||
|
yo: { field: 'yoruba', targetLang: 'yo', userPrompt: 'Translate to Yoruba' },
|
||||||
|
ln: { field: 'lingala', targetLang: 'ln', userPrompt: 'Translate to Lingala', deeplTarget: 'LN', suffix: '\n\n (DeepL)' },
|
||||||
|
wo: { field: 'wolof', targetLang: 'wo', userPrompt: 'Translate to Wolof', deeplTarget: 'WO', suffix: '\n\n (DeepL)' },
|
||||||
|
sw: { field: 'swahili', targetLang: 'sw', userPrompt: 'Translate to Swahili', deeplTarget: 'SW', suffix: '\n\n (DeepL)' },
|
||||||
|
ha: { field: 'hausa', targetLang: 'ha', userPrompt: 'Translate to Hausa', deeplTarget: 'HA', suffix: '\n\n (DeepL)' },
|
||||||
|
ar: { field: 'arabe', targetLang: 'ar', userPrompt: 'Translate to Arabic', deeplTarget: 'AR', suffix: '\n\n (DeepL)' },
|
||||||
|
om: { field: 'oromo', targetLang: 'om', userPrompt: 'Translate to Oromo', deeplTarget: 'OM', suffix: '\n\n (DeepL)' },
|
||||||
|
ig: { field: 'igbo', targetLang: 'ig', userPrompt: 'Translate to Igbo', deeplTarget: 'IG', suffix: '\n\n (DeepL)' },
|
||||||
|
zu: { field: 'zoulou', targetLang: 'zu', userPrompt: 'Translate to Zulu', deeplTarget: 'ZU', suffix: '\n\n (DeepL)' },
|
||||||
|
mg: { field: 'malgache', targetLang: 'mg', userPrompt: 'Translate to Malagasy', deeplTarget: 'MG', suffix: '\n\n (DeepL)' },
|
||||||
|
xh: { field: 'xhosa', targetLang: 'xh', userPrompt: 'Translate to Xhosa', deeplTarget: 'XH', suffix: '\n\n (DeepL)' },
|
||||||
|
tn: { field: 'tswana', targetLang: 'tn', userPrompt: 'Translate to Tswana', deeplTarget: 'TN', suffix: '\n\n (DeepL)' },
|
||||||
|
ts: { field: 'tsonga', targetLang: 'ts', userPrompt: 'Translate to Tsonga', deeplTarget: 'TS', suffix: '\n\n (DeepL)' },
|
||||||
|
st: { field: 'sesotho', targetLang: 'st', userPrompt: 'Translate to Sesotho', deeplTarget: 'ST', suffix: '\n\n (DeepL)' },
|
||||||
ja: { field: 'japonais', targetLang: 'ja', userPrompt: '日本語に翻訳して', deeplTarget: 'JA', suffix: '\n\n (DeepLによる翻訳)' },
|
ja: { field: 'japonais', targetLang: 'ja', userPrompt: '日本語に翻訳して', deeplTarget: 'JA', suffix: '\n\n (DeepLによる翻訳)' },
|
||||||
ko: { field: 'coreen', targetLang: 'ko', userPrompt: '한국어로 번역해줘', deeplTarget: 'KO', suffix: '\n\n (DeepL 번역)' },
|
ko: { field: 'coreen', targetLang: 'ko', userPrompt: '한국어로 번역해줘', deeplTarget: 'KO', suffix: '\n\n (DeepL 번역)' },
|
||||||
en: { field: 'anglais', targetLang: 'en', userPrompt: 'Translate to English', deeplTarget: 'EN', suffix: '\n\n (Translated by DeepL)' },
|
en: { field: 'anglais', targetLang: 'en', userPrompt: 'Translate to English', deeplTarget: 'EN', suffix: '\n\n (Translated by DeepL)' },
|
||||||
@@ -16,6 +31,8 @@ const LANG_MAP = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ALL_LANGS = Object.keys(LANG_MAP);
|
const ALL_LANGS = Object.keys(LANG_MAP);
|
||||||
|
// Langues suivies (schéma + export) mais sans traduction automatique DeepL.
|
||||||
|
const NO_AUTO_TRANSLATE = new Set(['fr', 'yo']);
|
||||||
|
|
||||||
function stripMarkdown(text) {
|
function stripMarkdown(text) {
|
||||||
if (!text) return '';
|
if (!text) return '';
|
||||||
@@ -88,7 +105,7 @@ module.exports = createCoreService('api::parole.parole', ({strapi}) => ({
|
|||||||
const result = { francais: parolesFR };
|
const result = { francais: parolesFR };
|
||||||
|
|
||||||
for (const lang of ALL_LANGS) {
|
for (const lang of ALL_LANGS) {
|
||||||
if (lang === 'fr') continue;
|
if (NO_AUTO_TRANSLATE.has(lang)) continue;
|
||||||
const { field, deeplTarget, suffix } = LANG_MAP[lang];
|
const { field, deeplTarget, suffix } = LANG_MAP[lang];
|
||||||
try {
|
try {
|
||||||
const translated = await this.translate('FR', deeplTarget, parolesFR);
|
const translated = await this.translate('FR', deeplTarget, parolesFR);
|
||||||
@@ -203,7 +220,7 @@ module.exports = createCoreService('api::parole.parole', ({strapi}) => ({
|
|||||||
|
|
||||||
async bulkTranslateMissing() {
|
async bulkTranslateMissing() {
|
||||||
const TARGET_LANGS = ALL_LANGS
|
const TARGET_LANGS = ALL_LANGS
|
||||||
.filter(lang => lang !== 'fr')
|
.filter(lang => !NO_AUTO_TRANSLATE.has(lang))
|
||||||
.map(lang => ({ lang, ...LANG_MAP[lang] }));
|
.map(lang => ({ lang, ...LANG_MAP[lang] }));
|
||||||
|
|
||||||
const pageSize = 100;
|
const pageSize = 100;
|
||||||
|
|||||||
@@ -10,6 +10,48 @@
|
|||||||
"francais": {
|
"francais": {
|
||||||
"type": "richtext"
|
"type": "richtext"
|
||||||
},
|
},
|
||||||
|
"yoruba": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"lingala": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"wolof": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"swahili": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"hausa": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"arabe": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"oromo": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"igbo": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"zoulou": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"malgache": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"xhosa": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"tswana": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"tsonga": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
|
"sesotho": {
|
||||||
|
"type": "richtext"
|
||||||
|
},
|
||||||
"japonais": {
|
"japonais": {
|
||||||
"type": "richtext"
|
"type": "richtext"
|
||||||
},
|
},
|
||||||
|
|||||||
Vendored
+14
@@ -109,12 +109,26 @@ export interface TradTraductions extends Struct.ComponentSchema {
|
|||||||
attributes: {
|
attributes: {
|
||||||
allemand: Schema.Attribute.RichText;
|
allemand: Schema.Attribute.RichText;
|
||||||
anglais: Schema.Attribute.RichText;
|
anglais: Schema.Attribute.RichText;
|
||||||
|
arabe: Schema.Attribute.RichText;
|
||||||
coreen: Schema.Attribute.RichText;
|
coreen: Schema.Attribute.RichText;
|
||||||
espagnol: Schema.Attribute.RichText;
|
espagnol: Schema.Attribute.RichText;
|
||||||
francais: Schema.Attribute.RichText;
|
francais: Schema.Attribute.RichText;
|
||||||
|
hausa: Schema.Attribute.RichText;
|
||||||
|
igbo: Schema.Attribute.RichText;
|
||||||
italien: Schema.Attribute.RichText;
|
italien: Schema.Attribute.RichText;
|
||||||
japonais: Schema.Attribute.RichText;
|
japonais: Schema.Attribute.RichText;
|
||||||
|
lingala: Schema.Attribute.RichText;
|
||||||
|
malgache: Schema.Attribute.RichText;
|
||||||
|
oromo: Schema.Attribute.RichText;
|
||||||
portugais: Schema.Attribute.RichText;
|
portugais: Schema.Attribute.RichText;
|
||||||
|
sesotho: Schema.Attribute.RichText;
|
||||||
|
swahili: Schema.Attribute.RichText;
|
||||||
|
tsonga: Schema.Attribute.RichText;
|
||||||
|
tswana: Schema.Attribute.RichText;
|
||||||
|
wolof: Schema.Attribute.RichText;
|
||||||
|
xhosa: Schema.Attribute.RichText;
|
||||||
|
yoruba: Schema.Attribute.RichText;
|
||||||
|
zoulou: Schema.Attribute.RichText;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user