diff --git a/plugins/english/wtrlab.ts b/plugins/english/wtrlab.ts index 84f4ce954..3b0e4cf7f 100644 --- a/plugins/english/wtrlab.ts +++ b/plugins/english/wtrlab.ts @@ -18,7 +18,7 @@ class WTRLAB implements Plugin.PluginBase { filters, }: Plugin.PopularNovelsOptions, ): Promise { - let link = this.site + this.sourceLang + 'novel-list?'; + let link = this.site + this.sourceLang + 'novel-list'; link += `orderBy=${filters.order.value}`; link += `&order=${filters.sort.value}`; link += `&filter=${filters.storyStatus.value}`; @@ -70,83 +70,99 @@ class WTRLAB implements Plugin.PluginBase { } } - async parseNovel(novelPath: string): Promise { - const body = await fetchApi(this.site + novelPath).then(res => res.text()); - const loadedCheerio = parseHTML(body); - - const novel: Plugin.SourceNovel = { - path: novelPath, - name: loadedCheerio('h1.text-uppercase').text(), - cover: loadedCheerio('.img-wrap > img').attr('src'), - summary: loadedCheerio('.lead').text().trim(), - }; - - novel.genres = loadedCheerio('td:contains("Genre")') - .next() - .find('a') - .map((i, el) => loadedCheerio(el).text()) - .toArray() - .join(','); - - novel.author = loadedCheerio('td:contains("Author")') - .next() - .text() - .replace(/[\t\n]/g, ''); - - novel.status = loadedCheerio('td:contains("Status")') - .next() - .text() - .replace(/[\t\n]/g, ''); - - const chapterJson = loadedCheerio('#__NEXT_DATA__').html() + ''; - const jsonData: NovelJson = JSON.parse(chapterJson); - - const chapters: Plugin.ChapterItem[] = - jsonData.props.pageProps.serie.chapters.map( - (jsonChapter, chapterIndex) => ({ - name: jsonChapter.title, - path: - this.sourceLang + - 'serie-' + - jsonData.props.pageProps.serie.serie_data.raw_id + - '/' + - jsonData.props.pageProps.serie.serie_data.slug + - '/chapter-' + - jsonChapter.order, // Assuming 'slug' is the intended path - releaseTime: ( - jsonChapter?.created_at || jsonChapter?.updated_at - )?.substring(0, 10), - chapterNumber: chapterIndex + 1, - }), - ); +async parseNovel(novelPath: string): Promise { + + const url = `${this.site}${novelPath}`; + const html = await fetchApi(url).then(res => res.text()); + + const $ = parseHTML(html); + const jsonText = $('#__NEXT_DATA__').html() ?? '{}'; + const jsonData: any = JSON.parse(jsonText); + + const serie = jsonData?.props?.pageProps?.serie ?? {}; + + const novel: Plugin.SourceNovel = { + path: novelPath, + name: serie.serie_data?.data?.title ?? '', + cover: serie.serie_data?.data?.image ?? '', + summary: serie.serie_data?.data?.description ?? '', + author: serie.serie_data?.data?.author ?? '', + genres: Array.isArray(serie.genres) ? serie.genres.join(', ') : '', + status: '', + }; + + const totalChapters = serie.serie_data.raw_chapter_count; + const rawId = serie.serie_data.raw_id; + const slug = serie.serie_data?.slug ?? ''; + const chapters: Plugin.ChapterItem[] = []; + + for (let i = 1; i <= totalChapters; i++) { + chapters.push({ + name: `Chapter ${i}`, + path: `${this.sourceLang}novel/${rawId}/${slug}/chapter-${i}`, + releaseTime: '', + chapterNumber: i, + }); + } - novel.chapters = chapters; + novel.chapters = chapters; + return novel; +} - return novel; - } - async parseChapter(chapterPath: string): Promise { - const body = await fetchApi(this.site + chapterPath).then(res => - res.text(), - ); - const loadedCheerio = parseHTML(body); - const chapterJson = loadedCheerio('#__NEXT_DATA__').html() + ''; - const jsonData: NovelJson = JSON.parse(chapterJson); - const chapterContent = JSON.stringify( - jsonData.props.pageProps.serie.chapter_data.data.body, - ); - const parsedArray = JSON.parse(chapterContent); - let htmlString = ''; - for (const text of parsedArray) { - htmlString += `

${text}

`; - } +async parseChapter(chapterPath: string): Promise { + const parts = chapterPath.split('/'); + const novelId = parts[parts.indexOf('novel') + 1]; + const chapterNoPart = parts[parts.length - 1]; + const chapterNo = parseInt(chapterNoPart.replace('chapter-', ''), 10); + + + const apiUrl = 'https://wtr-lab.com/api/reader/get'; + const body = { + translate: 'ai', + retry: false, + force_retry: false, + language: this.sourceLang.replace('/', ''), + raw_id: novelId, + chapter_no: chapterNo + }; + - return htmlString; + const res = await fetchApi(apiUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json;charset=UTF-8' + }, + body: JSON.stringify(body), + credentials: 'include' as any + }); + + const json = await res.json(); + const data = json?.data?.data; + if (!data || !Array.isArray(data.body)) { + return ''; + } + + let htmlString = ''; + let imgIndex = 0; + for (const item of data.body) { + if (item === '[image]') { + const src = data.images?.[imgIndex++] ?? ''; + if (src) htmlString += ``; + } else { + htmlString += `

${item}

`; + } } + return htmlString; +} + + + + async searchNovels(searchTerm: string): Promise { const response = await fetchApi(this.site + 'api/search', { headers: {