feat: enhance devil fruit extraction logic to support multiple data sources and clean up text
Build Docker Image / build (push) Successful in 1m29s

This commit is contained in:
2026-07-10 20:36:54 +02:00
parent dac084a75e
commit 63951df5a7
+27 -8
View File
@@ -704,12 +704,20 @@ function extractEpithets($: cheerio.CheerioAPI): string[] {
* Returns both normalized ID and URL * Returns both normalized ID and URL
*/ */
async function extractDevilFruit($: cheerio.CheerioAPI, lang: 'en' | 'fr'): Promise<DevilFruitData | null> { async function extractDevilFruit($: cheerio.CheerioAPI, lang: 'en' | 'fr'): Promise<DevilFruitData | null> {
// dfname or dfename are used as data-source for devil fruit in the infobox, we check both to be safe // dfname, dfename, or dfnomf may be used depending on the wiki language and page format.
const fruit = $('[data-source="dfname"] .pi-data-value, [data-source="dfename"] .pi-data-value').first(); const fruit = $(
const link = fruit.find('a').first(); lang === 'fr'
if (link.length === 0) return null; ? '[data-source="dfnomf"] .pi-data-value, [data-source="dfname"] .pi-data-value, [data-source="dfename"] .pi-data-value'
: '[data-source="dfname"] .pi-data-value, [data-source="dfename"] .pi-data-value, [data-source="dfnomf"] .pi-data-value'
).first();
if (fruit.length === 0) return null;
let fruitTitle = fruit.text().trim().toLowerCase().includes('smile') ? fruit.text().trim() : link.text().trim(); const fruitClone = fruit.clone();
fruitClone.find('sup, s, del, strike').remove();
const fruitText = fruitClone.text().replace(/\s+/g, ' ').trim();
const link = fruit.find('a').first();
let fruitTitle = link.length > 0 ? link.text().trim() : fruitText;
if (!fruitTitle) return null; if (!fruitTitle) return null;
let translatedName = null; let translatedName = null;
@@ -717,17 +725,28 @@ async function extractDevilFruit($: cheerio.CheerioAPI, lang: 'en' | 'fr'): Prom
if (lang === 'en') { if (lang === 'en') {
const translatedNameBox = $('[data-source="dfename"] .pi-data-value').first(); const translatedNameBox = $('[data-source="dfename"] .pi-data-value').first();
if (translatedNameBox.length > 0) { if (translatedNameBox.length > 0) {
translatedName = translatedNameBox.text().trim(); const translatedClone = translatedNameBox.clone();
translatedClone.find('sup, s, del, strike').remove();
translatedName = translatedClone.text().replace(/\s+/g, ' ').trim();
} }
} else if (lang === 'fr') { } else if (lang === 'fr') {
const translatedNameBox = $('[data-source="dfnomf"] .pi-data-value').first(); const translatedNameBox = $('[data-source="dfnomf"] .pi-data-value').first();
if (translatedNameBox.length > 0) { if (translatedNameBox.length > 0) {
translatedName = translatedNameBox.text().trim(); const translatedClone = translatedNameBox.clone();
translatedClone.find('sup, s, del, strike').remove();
translatedName = translatedClone.text().replace(/\s+/g, ' ').trim();
} }
} }
const href = link.attr('href'); const href = link.attr('href');
if (!href || !href.startsWith('/wiki/')) return null; if (!href || !href.startsWith('/wiki/')) {
return {
devilFruitId: normalizeId(fruitTitle),
devilFruitTitle: fruitTitle,
devilFruitTranslatedName: translatedName || null,
devilFruitUrl: ''
};
}
const cleanUrl = href.replace('/wiki/', ''); const cleanUrl = href.replace('/wiki/', '');