Fix Chapter Parsing and Content Extraction in Syosetu plugin (#1337)

Fix chapter content extraction in Syosetu plugin
This commit is contained in:
jacktheripper19
2024-11-27 10:25:13 +01:00
committed by GitHub
parent 26f1bac78d
commit c858f11ce9
+30 -64
View File
@@ -77,7 +77,7 @@ class Syosetu implements Plugin.PluginBase {
const body = await result.text(); const body = await result.text();
const loadedCheerio = loadCheerio(body, { decodeEntities: false }); const loadedCheerio = loadCheerio(body, { decodeEntities: false });
// create novel object // Create novel object with basic metadata
const novel: Plugin.SourceNovel = { const novel: Plugin.SourceNovel = {
path: novelPath, path: novelPath,
name: loadedCheerio('.novel_title').text(), name: loadedCheerio('.novel_title').text(),
@@ -85,67 +85,28 @@ class Syosetu implements Plugin.PluginBase {
cover: defaultCover, cover: defaultCover,
}; };
// Get all the chapters // Get summary if available
const cqGetChapters = loadedCheerio('.novel_sublist2'); novel.summary = loadedCheerio('#novel_ex').text().trim();
if (cqGetChapters.length !== 0) {
// has more than 1 chapter
novel.summary = loadedCheerio('#novel_ex')
.text()
.replace(/<\s*br.*?>/g, '\n');
cqGetChapters.each((_, e) => {
const chapterA = loadedCheerio(e).find('a');
const [chapterName, releaseDate, chapterUrl] = [
// set the variables
chapterA.text(),
loadedCheerio(e)
.find('dt') // get title
.text() // get text
.replace(/(.)/g, '') // remove "(edited)" mark
.trim(), // trim spaces
chapterA.attr('href'),
];
if (chapterUrl) {
chapters.push({
name: chapterName,
releaseTime: releaseDate,
path: chapterUrl,
});
}
});
} else {
/**
* Because there are oneshots on the site, they have to be treated with special care
* that's what pisses me off in Shosetsu app. They have this extension,
* but every oneshot is set as "there are no chapters" and all contents are thrown into the description!!
*/
// get summary for oneshot chapter
const nameResult = await fetchApi( // Parse chapters using the correct selectors
this.searchUrl() + `&word=${novel.name}`, loadedCheerio('.p-eplist__sublist').each((_, element) => {
{ const chapterLink = loadedCheerio(element).find('a');
headers: this.headers, const chapterUrl = chapterLink.attr('href');
}, const chapterName = chapterLink.text().trim();
); const releaseDate = loadedCheerio(element)
const nameBody = await nameResult.text(); .find('.p-eplist__update')
const summaryQuery = loadCheerio(nameBody, {
decodeEntities: false,
});
const foundText = summaryQuery('.searchkekka_box')
.first()
.find('.ex')
.text() .text()
.replace(/\s{2,}/g, '\n'); .trim();
novel.summary = foundText;
if (chapterUrl) {
chapters.push({
name: chapterName,
releaseTime: releaseDate,
path: chapterUrl.replace(this.novelPrefix, ''),
});
}
});
// add single chapter
chapters.push({
name: 'Oneshot',
releaseTime: loadedCheerio('head')
.find("meta[name='WWWC']")
.attr('content'), // get date from metadata
path: novelPath, // set chapterUrl to oneshot so that chapterScraper knows it's a one-shot,
});
}
novel.chapters = chapters; novel.chapters = chapters;
return novel; return novel;
} }
@@ -155,15 +116,20 @@ class Syosetu implements Plugin.PluginBase {
}); });
const body = await result.text(); const body = await result.text();
// create cheerioQuery
const cheerioQuery = loadCheerio(body, { const cheerioQuery = loadCheerio(body, {
decodeEntities: false, decodeEntities: false,
}); });
const chapterText = // Get the novel text content and process it
cheerioQuery('#novel_honbun') // get chapter text const chapterContent = cheerioQuery('.p-novel__body .js-novel-text')
.html() || ''; .find('p')
return chapterText; .map((_, element) => {
return cheerioQuery(element).text();
})
.get()
.join('\n');
return chapterContent || '';
} }
async searchNovels( async searchNovels(
searchTerm: string, searchTerm: string,