From ecc2776425d3ddba8f10173bf9eb1e83fa845ecc Mon Sep 17 00:00:00 2001 From: r1di <33724815+r1di@users.noreply.github.com> Date: Tue, 6 Aug 2024 18:22:44 +0200 Subject: [PATCH] New Source dreambigtl (Dream Big Translations) (#1112) * New Source dreambigtl (Dream Big Translations) * Apply suggestions from code review Co-authored-by: nyagami * Update dreambigtl.ts --------- Co-authored-by: Ridi Co-authored-by: nyagami --- public/static/src/en/dreambigtl/icon.png | Bin 0 -> 5649 bytes src/plugins/english/dreambigtl.ts | 188 +++++++++++++++++++++++ 2 files changed, 188 insertions(+) create mode 100644 public/static/src/en/dreambigtl/icon.png create mode 100644 src/plugins/english/dreambigtl.ts diff --git a/public/static/src/en/dreambigtl/icon.png b/public/static/src/en/dreambigtl/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..071ffa017f9dc26fb066ec194ba2a0fe6eff36fa GIT binary patch literal 5649 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 { + const url = `${this.site}p/disclaimer.html`; + + const response = await fetchApi(url); + const body = await response.text(); + const loadedCheerio = parseHTML(body); + const novels: Plugin.NovelItem[] = []; + const categories = ['New Novels', 'Ongoing Novels', 'Completed Novels']; + + loadedCheerio('#webify-pro-main-nav-menu > li.has-sub').each( + (_, categoryElem) => { + const categoryName = loadedCheerio(categoryElem) + .children('a') + .first() + .text() + .trim(); + + if (categories.includes(categoryName)) { + const subMenu = loadedCheerio(categoryElem).find('ul.sub-menu.m-sub'); + subMenu.find('li > a').each((_, novelElem) => { + const novelName = loadedCheerio(novelElem).text().trim(); + const novelUrl = loadedCheerio(novelElem).attr('href'); + + if (novelUrl) { + novels.push({ + name: novelName, + path: novelUrl.replace(this.site, ''), + cover: '', + }); + } + }); + } + }, + ); + + novels.forEach(novel => console.log('Novel:', novel.name, novel.path)); + + if (novels.length === 0) { + // Fallback: try to parse everything... + loadedCheerio('a').each((_, elem) => { + const href = loadedCheerio(elem).attr('href'); + if (href && href.includes('/p/') && !href.includes('disclaimer')) { + const novelName = loadedCheerio(elem).text().trim(); + novels.push({ + name: novelName, + path: href.replace(this.site, ''), + cover: '', + }); + } + }); + } + + if (showLatestNovels) { + novels.sort((a, b) => b.path.localeCompare(a.path)); + } + + return novels; + } + + async parseNovel(novelPath: string): Promise { + const url = this.site + novelPath; + const result = await fetchApi(url); + const body = await result.text(); + const loadedCheerio = parseHTML(body); + + const novel: Plugin.SourceNovel = { + path: novelPath, + name: loadedCheerio('h1.entry-title').text().trim(), + cover: loadedCheerio('.post-body img').first().attr('src') || '', + summary: loadedCheerio('.post-body p').first().text().trim(), + author: + loadedCheerio('.post-body') + .text() + .match(/Author:\s*(.+)/i)?.[1] + ?.trim() || 'Unknown', + status: this.getNovelStatus(novelPath), + chapters: await this.parseChapters(loadedCheerio), + }; + + return novel; + } + + async parseChapters( + loadedCheerio: CheerioAPI, + ): Promise { + const chapters: Plugin.ChapterItem[] = []; + // Parse "Free Tier" chapters + loadedCheerio('.chapter-panel').each((_, panel) => { + const panelTitle = loadedCheerio(panel).find('summary').text().trim(); + if (panelTitle === 'Free Tier') { + loadedCheerio(panel) + .find('ul li a') + .each((_, chapterEle) => { + const chapterName = loadedCheerio(chapterEle).text().trim(); + const chapterUrl = loadedCheerio(chapterEle).attr('href'); + if (chapterUrl) { + chapters.push({ + name: chapterName, + path: chapterUrl.replace(this.site, ''), + }); + } + }); + } + }); + + // Parse "List of Chapters" + if (chapters.length === 0) { + loadedCheerio( + 'h2:contains("List of Chapters"), span:contains("List of Chapters")', + ).each((_, header) => { + const chapterList = loadedCheerio(header).next('ul'); + chapterList.find('li a').each((_, chapterEle) => { + const chapterName = loadedCheerio(chapterEle).text().trim(); + const chapterUrl = loadedCheerio(chapterEle).attr('href'); + if (chapterUrl) { + chapters.push({ + name: chapterName, + path: chapterUrl.replace(this.site, ''), + }); + } + }); + }); + } + + return chapters.reverse(); + } + + getNovelStatus(novelPath: string): string { + if (novelPath.includes('completed')) return 'Completed'; + return 'Ongoing'; + } + + async parseChapter(chapterPath: string): Promise { + const url = this.site + chapterPath; + const result = await fetchApi(url); + const body = await result.text(); + const loadedCheerio = parseHTML(body); + + const chapterTitle = loadedCheerio('h1.entry-title').text().trim(); + const chapterContent = loadedCheerio('.post-body').html() || ''; + + return `

${chapterTitle}

${chapterContent}`; + } + + async searchNovels(searchTerm: string): Promise { + const url = `${this.site}search?q=${encodeURIComponent(searchTerm)}`; + const result = await fetchApi(url); + const body = await result.text(); + const loadedCheerio = parseHTML(body); + + const novels: Plugin.NovelItem[] = []; + + loadedCheerio( + '.blog-posts.index-post-wrap .blog-post.hentry.index-post', + ).each((_, ele) => { + const novelName = loadedCheerio(ele).find('.entry-title a').text().trim(); + const novelUrl = loadedCheerio(ele).find('.entry-title a').attr('href'); + const novelCover = + loadedCheerio(ele).find('.entry-image').attr('data-image') || ''; + + if (novelUrl) { + novels.push({ + name: novelName, + path: novelUrl.replace(this.site, ''), + cover: novelCover, + }); + } + }); + + return novels; + } +} + +export default new DreamBigTL();