From e02b563bf41597eb6a8aabe100abaa2ce8b06edb Mon Sep 17 00:00:00 2001 From: Koitharu Date: Thu, 21 Nov 2024 09:14:55 +0200 Subject: [PATCH] [AsuraComic] Fix pages parsing --- .../kotatsu/parsers/site/all/ImHentai.kt | 2 +- .../kotatsu/parsers/site/ar/MangaStorm.kt | 2 +- .../kotatsu/parsers/site/ar/TeamXNovel.kt | 2 +- .../parsers/site/cupfox/CupFoxParser.kt | 2 +- .../parsers/site/en/AsuraScansParser.kt | 8 ++-- .../kotatsu/parsers/site/en/BeeToon.kt | 2 +- .../kotatsu/parsers/site/en/ComicExtra.kt | 2 +- .../kotatsu/parsers/site/en/MangaGeko.kt | 2 +- .../kotatsu/parsers/site/en/ManhwasMen.kt | 2 +- .../kotatsu/parsers/site/en/Pururin.kt | 2 +- .../kotatsu/parsers/site/en/VyManga.kt | 2 +- .../kotatsu/parsers/site/es/TempleScanEsp.kt | 2 +- .../parsers/site/fmreader/FmreaderParser.kt | 2 +- .../parsers/site/fmreader/es/OlimpoScans.kt | 2 +- .../kotatsu/parsers/site/fmreader/ja/Klz9.kt | 2 +- .../parsers/site/fmreader/ja/WeLoveManga.kt | 2 +- .../kotatsu/parsers/site/fr/FuryoSociety.kt | 2 +- .../parsers/site/fr/LegacyScansParser.kt | 2 +- .../site/fuzzydoodle/FuzzyDoodleParser.kt | 2 +- .../site/galleryadults/GalleryAdultsParser.kt | 2 +- .../site/galleryadults/all/DoujinDesuUk.kt | 2 +- .../parsers/site/galleryadults/all/Hentai3.kt | 2 +- .../site/galleryadults/all/HentaiForce.kt | 2 +- .../site/galleryadults/all/NHentaiParser.kt | 2 +- .../parsers/site/gattsu/GattsuParser.kt | 2 +- .../parsers/site/gattsu/pt/UniversoHentai.kt | 2 +- .../kotatsu/parsers/site/heancms/HeanCms.kt | 2 +- .../parsers/site/heancmsalt/HeanCmsAlt.kt | 2 +- .../parsers/site/hotcomics/HotComicsParser.kt | 2 +- .../kotatsu/parsers/site/id/HentaiCrot.kt | 2 +- .../kotatsu/parsers/site/id/PixHentai.kt | 2 +- .../kotatsu/parsers/site/iken/IkenParser.kt | 2 +- .../parsers/site/keyoapp/KeyoappParser.kt | 2 +- .../parsers/site/likemanga/LikeMangaParser.kt | 4 +- .../parsers/site/madara/MadaraParser.kt | 2 +- .../parsers/site/madara/all/Manhwa18Cc.kt | 2 +- .../parsers/site/madara/en/AdultWebtoon.kt | 2 +- .../parsers/site/madara/en/DarkScans.kt | 14 ++---- .../parsers/site/madara/en/MangaDass.kt | 2 +- .../parsers/site/madara/en/MangaDna.kt | 2 +- .../parsers/site/madara/en/Manhuaplus.kt | 2 +- .../parsers/site/madara/en/Manhwaden.kt | 2 +- .../parsers/site/madara/es/DoujinHentaiNet.kt | 2 +- .../parsers/site/madara/es/MangasNoSekai.kt | 2 +- .../parsers/site/madara/es/TmoManga.kt | 2 +- .../kotatsu/parsers/site/madara/fr/FrScan.kt | 2 +- .../parsers/site/madara/th/RhPlusManga.kt | 2 +- .../parsers/site/madara/vi/HentaiCube.kt | 2 +- .../parsers/site/madara/vi/Quaanhdaocuteo.kt | 2 +- .../parsers/site/madtheme/MadthemeParser.kt | 2 +- .../parsers/site/mangabox/MangaboxParser.kt | 4 +- .../site/mangareader/MangaReaderParser.kt | 2 +- .../site/mangareader/es/CatharsisFantasy.kt | 2 +- .../parsers/site/mangareader/fr/LelManga.kt | 2 +- .../parsers/site/mangareader/id/Komikcast.kt | 2 +- .../site/mangaworld/MangaWorldParser.kt | 2 +- .../parsers/site/mmrcms/MmrcmsParser.kt | 2 +- .../parsers/site/onemanga/OneMangaParser.kt | 2 +- .../otakusanctuary/OtakuSanctuaryParser.kt | 2 +- .../kotatsu/parsers/site/pt/LerMangaOnline.kt | 2 +- .../kotatsu/parsers/site/pt/MangaOnline.kt | 2 +- .../kotatsu/parsers/site/ru/AComics.kt | 2 +- .../kotatsu/parsers/site/tr/MangaAy.kt | 2 +- .../kotatsu/parsers/site/tr/SadScans.kt | 2 +- .../kotatsu/parsers/site/tr/TrWebtoon.kt | 2 +- .../kotatsu/parsers/site/vi/HentaiVNParser.kt | 2 +- .../kotatsu/parsers/site/vi/TruyenGG.kt | 33 ++++++------- .../kotatsu/parsers/site/vi/TruyenQQ.kt | 2 +- .../kotatsu/parsers/site/vmp/VmpParser.kt | 2 +- .../parsers/site/wpcomics/WpComicsParser.kt | 2 +- .../site/zeistmanga/ZeistMangaParser.kt | 2 +- .../parsers/site/zmanga/ZMangaParser.kt | 2 +- .../koitharu/kotatsu/parsers/util/Jsoup.kt | 47 +++++++++++++------ .../kotatsu/parsers/MangaParserTest.kt | 2 +- 74 files changed, 128 insertions(+), 118 deletions(-) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ImHentai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ImHentai.kt index d1546e3cf..fbdb9dc76 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ImHentai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ImHentai.kt @@ -235,6 +235,6 @@ internal class ImHentai(context: MangaLoaderContext) : override suspend fun getPageUrl(page: MangaPage): String { val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml() val img = doc.body().requireElementById("gimg") - return img.src() ?: doc.parseFailed("Cannot find image src") + return img.requireSrc() } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/MangaStorm.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/MangaStorm.kt index 800361247..c0692973a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/MangaStorm.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/MangaStorm.kt @@ -120,7 +120,7 @@ internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(contex val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml().requireElementById("content") return doc.select("div.text-center .img-fluid").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt index 10e2d47e2..c4817c682 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt @@ -212,7 +212,7 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(".image_list img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/cupfox/CupFoxParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/cupfox/CupFoxParser.kt index 9f1f1ebe6..c094eeda8 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/cupfox/CupFoxParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/cupfox/CupFoxParser.kt @@ -183,7 +183,7 @@ internal abstract class CupFoxParser( val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPages).map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/AsuraScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/AsuraScansParser.kt index ef4269c9b..e007b2573 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/AsuraScansParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/AsuraScansParser.kt @@ -115,7 +115,7 @@ internal class AsuraScansParser(context: MangaLoaderContext) : rating = a.selectFirst("div.block label.ml-1")?.text()?.toFloatOrNull()?.div(10f) ?: RATING_UNKNOWN, tags = emptySet(), author = null, - state = when (a.selectLast("span.status")?.text().orEmpty()) { + state = when (a.selectLast("span.status")?.text()) { "Ongoing" -> MangaState.ONGOING "Completed" -> MangaState.FINISHED "Hiatus" -> MangaState.PAUSED @@ -147,7 +147,7 @@ internal class AsuraScansParser(context: MangaLoaderContext) : ) } tagCache = tagMap - return@withLock tagMap + tagMap } private val regexDate = """(\d+)(st|nd|rd|th)""".toRegex() @@ -185,8 +185,8 @@ internal class AsuraScansParser(context: MangaLoaderContext) : override suspend fun getPages(chapter: MangaChapter): List { val doc = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml() - return doc.select("div > img[alt*=chapter]").map { img -> - val urlPage = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + return doc.selectOrThrow("div.w-full > img.object-cover").map { img -> + val urlPage = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(urlPage), url = urlPage, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/BeeToon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/BeeToon.kt index ceda30673..9006a1b42 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/BeeToon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/BeeToon.kt @@ -135,7 +135,7 @@ internal class BeeToon(context: MangaLoaderContext) : override suspend fun getPages(chapter: MangaChapter): List { val doc = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml() return doc.select(".chapter-content-inner center img").map { img -> - val urlPage = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val urlPage = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(urlPage), url = urlPage, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ComicExtra.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ComicExtra.kt index 878efd6bc..97a472743 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ComicExtra.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ComicExtra.kt @@ -167,7 +167,7 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(".chapter-container img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaGeko.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaGeko.kt index d083ce608..b822194e4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaGeko.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaGeko.kt @@ -158,7 +158,7 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context val doc = webClient.httpGet(fullUrl).parseHtml() return doc.requireElementById("chapter-reader").select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ManhwasMen.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ManhwasMen.kt index 5b44b12e2..0b2b41bf1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ManhwasMen.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ManhwasMen.kt @@ -171,7 +171,7 @@ internal class ManhwasMen(context: MangaLoaderContext) : override suspend fun getPages(chapter: MangaChapter): List { val doc = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml().requireElementById("chapter_imgs") return doc.select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Pururin.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Pururin.kt index ff5139772..6c8650008 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Pururin.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Pururin.kt @@ -187,7 +187,7 @@ internal class Pururin(context: MangaLoaderContext) : val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(".gallery-preview img").map { url -> - val img = url.src()?.toRelativeUrl(domain) ?: url.parseFailed("Image src not found") + val img = url.requireSrc().toRelativeUrl(domain) val urlImage = img.replace("t.", ".") MangaPage( id = generateUid(urlImage), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/VyManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/VyManga.kt index 40ac23f75..51b51560f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/VyManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/VyManga.kt @@ -194,7 +194,7 @@ internal class VyManga(context: MangaLoaderContext) : override suspend fun getPages(chapter: MangaChapter): List { val doc = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml() return doc.select("img.d-block").map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt index c0974de4d..28b7b31d1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt @@ -85,7 +85,7 @@ internal class TempleScanEsp(context: MangaLoaderContext) : val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select("main.contenedor img.readChapter_image__450v_").map { url -> - val img = url.src()?.toRelativeUrl(domain) ?: url.parseFailed("Image src not found") + val img = url.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(img), url = img, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt index 5c4b65e94..151a1b3b0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt @@ -239,7 +239,7 @@ internal abstract class FmreaderParser( val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/es/OlimpoScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/es/OlimpoScans.kt index 89109a0ae..4830f94ea 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/es/OlimpoScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/es/OlimpoScans.kt @@ -19,7 +19,7 @@ internal class OlimpoScans(context: MangaLoaderContext) : val fullUrl = ("/" + chapter.url).toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPage).map { img -> - val url = ("/proxy.php?link=" + img.src()).toRelativeUrl(domain) + val url = ("/proxy.php?link=" + img.requireSrc()).toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/Klz9.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/Klz9.kt index eb5d3497c..c293b796c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/Klz9.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/Klz9.kt @@ -85,7 +85,7 @@ internal class Klz9(context: MangaLoaderContext) : val cid = doc.selectFirstOrThrow("#chapter").attr("value") val docLoad = webClient.httpGet("https://$domain/app/manga/controllers/cont.listImg.php?cid=$cid").parseHtml() return docLoad.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/WeLoveManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/WeLoveManga.kt index 86bdc0645..1eaaa1e69 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/WeLoveManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/WeLoveManga.kt @@ -45,7 +45,7 @@ internal class WeLoveManga(context: MangaLoaderContext) : val cid = doc.selectFirstOrThrow("#chapter").attr("value") val docLoad = webClient.httpGet("https://$domain/app/manga/controllers/cont.listImg.php?cid=$cid").parseHtml() return docLoad.select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt index 18d160b6b..4b219deac 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt @@ -120,7 +120,7 @@ internal class FuryoSociety(context: MangaLoaderContext) : val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select("div.main-img img").map { url -> - val img = url.src()?.toRelativeUrl(domain) ?: url.parseFailed("Image src not found") + val img = url.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(img), url = img, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LegacyScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LegacyScansParser.kt index 17497c542..671011dcc 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LegacyScansParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LegacyScansParser.kt @@ -206,7 +206,7 @@ internal class LegacyScansParser(context: MangaLoaderContext) : val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select("div.readerComics img").map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/FuzzyDoodleParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/FuzzyDoodleParser.kt index 531d12b49..26c0c94c4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/FuzzyDoodleParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/FuzzyDoodleParser.kt @@ -260,7 +260,7 @@ internal abstract class FuzzyDoodleParser( val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPages).map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt index 21b5a9074..da2ed22a2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt @@ -209,7 +209,7 @@ internal abstract class GalleryAdultsParser( override suspend fun getPageUrl(page: MangaPage): String { val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml() - return doc.requireElementById(idImg).src() ?: doc.parseFailed("Image src not found") + return doc.requireElementById(idImg).requireSrc() } protected fun String.cleanupTitle() = replace(regexBrackets, "") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/DoujinDesuUk.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/DoujinDesuUk.kt index 45daf881c..f7c72072c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/DoujinDesuUk.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/DoujinDesuUk.kt @@ -58,7 +58,7 @@ internal class DoujinDesuUk(context: MangaLoaderContext) : override suspend fun getPageUrl(page: MangaPage): String { val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml() val root = doc.body() - return root.requireElementById(idImg).selectFirstOrThrow("img").src() ?: root.parseFailed("Image src not found") + return root.requireElementById(idImg).selectFirstOrThrow("img").requireSrc() } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/Hentai3.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/Hentai3.kt index 69a57475d..16e998f0d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/Hentai3.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/Hentai3.kt @@ -94,7 +94,7 @@ internal class Hentai3(context: MangaLoaderContext) : override suspend fun getPageUrl(page: MangaPage): String { val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml() - return doc.selectFirstOrThrow(idImg).src() ?: doc.parseFailed("Image src not found") + return doc.selectFirstOrThrow(idImg).requireSrc() } private fun buildQuery(tags: Collection, language: Locale?): String { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/HentaiForce.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/HentaiForce.kt index 5a39fb099..c48a65848 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/HentaiForce.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/HentaiForce.kt @@ -50,7 +50,7 @@ internal class HentaiForce(context: MangaLoaderContext) : override suspend fun getPageUrl(page: MangaPage): String { val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml() - return doc.selectFirstOrThrow(idImg).src() ?: doc.parseFailed("Image src not found") + return doc.selectFirstOrThrow(idImg).requireSrc() } override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/NHentaiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/NHentaiParser.kt index c8a7ef32d..57ed5fc5e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/NHentaiParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/NHentaiParser.kt @@ -107,7 +107,7 @@ internal class NHentaiParser(context: MangaLoaderContext) : override suspend fun getPageUrl(page: MangaPage): String { val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml() val root = doc.body() - return root.requireElementById(idImg).selectFirstOrThrow("img").src() ?: root.parseFailed("Image src not found") + return root.requireElementById(idImg).selectFirstOrThrow("img").requireSrc() } override fun Element.parseTags() = select("a").mapToSet { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt index a8ac3c87e..c66f854e0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt @@ -152,6 +152,6 @@ internal abstract class GattsuParser( override suspend fun getPageUrl(page: MangaPage): String { val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml() - return doc.selectFirstOrThrow("div.galeria-foto img").src() ?: doc.parseFailed("Image src not found") + return doc.selectFirstOrThrow("div.galeria-foto img").requireSrc() } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/pt/UniversoHentai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/pt/UniversoHentai.kt index 950f19d48..4861fce8b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/pt/UniversoHentai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/pt/UniversoHentai.kt @@ -42,7 +42,7 @@ internal class UniversoHentai(context: MangaLoaderContext) : val images = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml().requireElementById("galeria") .select(".galeria-foto img") return images.map { img -> - val urlImages = img.src() ?: img.parseFailed("Image src not found") + val urlImages = img.requireSrc() MangaPage( id = generateUid(urlImages), url = urlImages, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt index 2dd507b23..48417f58c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt @@ -178,7 +178,7 @@ internal abstract class HeanCms( val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPages).map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt index 70d496876..674239f5f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt @@ -119,7 +119,7 @@ internal abstract class HeanCmsAlt( val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/hotcomics/HotComicsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/hotcomics/HotComicsParser.kt index 3edebb76f..c00c2bf41 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/hotcomics/HotComicsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/hotcomics/HotComicsParser.kt @@ -167,7 +167,7 @@ internal abstract class HotComicsParser( val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPages).map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/HentaiCrot.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/HentaiCrot.kt index 77ef80cae..ba6f9ec9c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/HentaiCrot.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/HentaiCrot.kt @@ -120,7 +120,7 @@ internal class HentaiCrot(context: MangaLoaderContext) : val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(".thumbnail img, figure.gallery-item img").map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/PixHentai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/PixHentai.kt index cfb31772b..6c2a5173b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/PixHentai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/PixHentai.kt @@ -120,7 +120,7 @@ internal class PixHentai(context: MangaLoaderContext) : val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(".thumbnail img, figure.gallery-item img").map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/iken/IkenParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/iken/IkenParser.kt index 744780547..62ca74dcc 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/iken/IkenParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/iken/IkenParser.kt @@ -164,7 +164,7 @@ internal abstract class IkenParser( val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPages).map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/KeyoappParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/KeyoappParser.kt index 8206b09e5..f74ab8a9c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/KeyoappParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/KeyoappParser.kt @@ -233,7 +233,7 @@ internal abstract class KeyoappParser( ?.also { return it } return doc.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/LikeMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/LikeMangaParser.kt index 3320b246f..7dab501bc 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/LikeMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/LikeMangaParser.kt @@ -116,7 +116,7 @@ internal abstract class LikeMangaParser( publicUrl = href.toAbsoluteUrl(domain), rating = RATING_UNKNOWN, isNsfw = false, - coverUrl = div.selectFirstOrThrow("img").src()?.toAbsoluteUrl(domain).orEmpty(), + coverUrl = div.selectFirstOrThrow("img").src().orEmpty(), tags = emptySet(), state = null, author = null, @@ -269,7 +269,7 @@ internal abstract class LikeMangaParser( } else { return doc.select(".reading-detail img").map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt index 256ee4426..1d2e64ea5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt @@ -684,7 +684,7 @@ internal abstract class MadaraParser( ) return root.select(selectPage).flatMap { div -> div.selectOrThrow("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/Manhwa18Cc.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/Manhwa18Cc.kt index 713bf6077..5af2ce15e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/Manhwa18Cc.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/Manhwa18Cc.kt @@ -113,7 +113,7 @@ internal class Manhwa18Cc(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val root = doc.body().selectFirstOrThrow(selectBodyPage) return root.select("img").map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AdultWebtoon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AdultWebtoon.kt index 0721c1f83..600cefc6a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AdultWebtoon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AdultWebtoon.kt @@ -168,7 +168,7 @@ internal class AdultWebtoon(context: MangaLoaderContext) : ) return root.select(selectPage).map { div -> val img = div.selectFirstOrThrow("img") - val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url.replace("http:", "https:"), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/DarkScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/DarkScans.kt index 8c1c4d66e..6cfab8f74 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/DarkScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/DarkScans.kt @@ -9,16 +9,8 @@ import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaPage import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -import org.koitharu.kotatsu.parsers.util.CryptoAES -import org.koitharu.kotatsu.parsers.util.domain -import org.koitharu.kotatsu.parsers.util.generateUid -import org.koitharu.kotatsu.parsers.util.parseFailed -import org.koitharu.kotatsu.parsers.util.parseHtml -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow -import org.koitharu.kotatsu.parsers.util.src -import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl -import org.koitharu.kotatsu.parsers.util.toRelativeUrl -import java.util.Base64 +import org.koitharu.kotatsu.parsers.util.* +import java.util.* @MangaSourceParser("DARK_SCANS", "DarkScans", "en") internal class DarkScans(context: MangaLoaderContext) : @@ -40,7 +32,7 @@ internal class DarkScans(context: MangaLoaderContext) : ) return root.select(selectPage).map { div -> val img = div.selectFirstOrThrow("img") - val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url.replace("http:", "https:"), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt index 0cb703d24..08e574365 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt @@ -174,7 +174,7 @@ internal class MangaDass(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val root = doc.body().selectFirstOrThrow("div.read-manga").selectFirstOrThrow("div.read-content") return root.select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDna.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDna.kt index 8dca01b66..71385fe80 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDna.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDna.kt @@ -167,7 +167,7 @@ internal class MangaDna(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val root = doc.body().selectFirstOrThrow("div.read-manga").selectFirstOrThrow("div.read-content") return root.select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuaplus.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuaplus.kt index 9d099e30e..0cc103c41 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuaplus.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuaplus.kt @@ -19,7 +19,7 @@ internal class Manhuaplus(context: MangaLoaderContext) : val root = doc.body().selectFirst("div.main-col-inner")?.selectFirst("div.reading-content") ?: throw ParseException("Root not found", fullUrl) return root.select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwaden.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwaden.kt index 1f50d481a..ae2ca55d2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwaden.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwaden.kt @@ -20,7 +20,7 @@ internal class Manhwaden(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val root = doc.body().selectFirstOrThrow(selectBodyPage) return root.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/DoujinHentaiNet.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/DoujinHentaiNet.kt index 353e9d64b..b563417c9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/DoujinHentaiNet.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/DoujinHentaiNet.kt @@ -27,7 +27,7 @@ internal class DoujinHentaiNet(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPage).map { div -> val img = div.selectFirstOrThrow("img") - val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MangasNoSekai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MangasNoSekai.kt index 324c54a29..bda97b4d7 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MangasNoSekai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MangasNoSekai.kt @@ -81,7 +81,7 @@ internal class MangasNoSekai(context: MangaLoaderContext) : ?: throw ParseException("No image found, try to log in", fullUrl) return root.select(selectPage).map { div -> val img = div.selectFirstOrThrow("img") - val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TmoManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TmoManga.kt index 008e9af40..97c5abc9e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TmoManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TmoManga.kt @@ -108,7 +108,7 @@ internal class TmoManga(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val root = doc.body().requireElementById("images_chapter") return root.select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain).orEmpty() + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/FrScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/FrScan.kt index 64dfbbbb4..55144ed0c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/FrScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/FrScan.kt @@ -33,7 +33,7 @@ internal class FrScan(context: MangaLoaderContext) : } else { return doc.body().selectFirstOrThrow(selectBodyPage).select(selectPage).map { div -> val img = div.selectFirstOrThrow("img") - val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/RhPlusManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/RhPlusManga.kt index 4624705bf..df97b7b06 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/RhPlusManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/RhPlusManga.kt @@ -19,7 +19,7 @@ internal class RhPlusManga(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val root = doc.body().selectFirstOrThrow("div.main-col-inner").selectFirstOrThrow("div.reading-content") return root.select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/HentaiCube.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/HentaiCube.kt index 0bf661e3d..1922b636f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/HentaiCube.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/HentaiCube.kt @@ -27,7 +27,7 @@ internal class HentaiCube(context: MangaLoaderContext) : val root = doc.body().selectFirst("div.main-col-inner")?.selectFirst("div.reading-content") ?: throw ParseException("Root not found", fullUrl) return root.select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Quaanhdaocuteo.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Quaanhdaocuteo.kt index c8a9cdc5b..475d93263 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Quaanhdaocuteo.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Quaanhdaocuteo.kt @@ -20,7 +20,7 @@ internal class Quaanhdaocuteo(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val root = doc.body().selectFirstOrThrow(selectBodyPage) return root.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt index 8fd66c816..7ffcfa54c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt @@ -233,7 +233,7 @@ internal abstract class MadthemeParser( val result = ArrayList() // html parisng doc.select(selectPage).forEach { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) if (known.add(url)) { result += MangaPage( id = generateUid(url), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/MangaboxParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/MangaboxParser.kt index 894f1a114..023ed43c0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/MangaboxParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/MangaboxParser.kt @@ -233,7 +233,7 @@ internal abstract class MangaboxParser( val doc2 = webClient.httpGet(fullUrl2).parseHtml() return doc2.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), @@ -244,7 +244,7 @@ internal abstract class MangaboxParser( } } else { return doc.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt index 8c957f0ba..3f681b89a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt @@ -297,7 +297,7 @@ internal abstract class MangaReaderParser( val test = docs.select(selectTestScript) if (test.isNullOrEmpty() and !encodedSrc) { return docs.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/CatharsisFantasy.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/CatharsisFantasy.kt index 73c4618cf..e5d4b266c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/CatharsisFantasy.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/CatharsisFantasy.kt @@ -30,7 +30,7 @@ internal class CatharsisFantasy(context: MangaLoaderContext) : val test = docs.select(selectTestScript) if (test.isNullOrEmpty() and !encodedSrc) { return docs.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/LelManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/LelManga.kt index db51bb7fe..2a58156bd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/LelManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/LelManga.kt @@ -20,7 +20,7 @@ internal class LelManga(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val root = doc.body().selectFirstOrThrow("div.maincontent").requireElementById("readerarea") return root.select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt index 5a662a756..1a1e3b97c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt @@ -158,7 +158,7 @@ internal class Komikcast(context: MangaLoaderContext) : val test = docs.select("script:containsData(ts_reader)") if (test.isNullOrEmpty()) { return docs.select("div#chapter_body img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangaworld/MangaWorldParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangaworld/MangaWorldParser.kt index 5c8e6661b..041611b8e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangaworld/MangaWorldParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangaworld/MangaWorldParser.kt @@ -217,7 +217,7 @@ internal abstract class MangaWorldParser( val selectMangaPages = "img.img-fluid" val imgSelector = if (doc.select(selectWebtoonPages).isNotEmpty()) selectWebtoonPages else selectMangaPages return doc.select(imgSelector).map { img -> - val urlPage = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val urlPage = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(urlPage), url = urlPage, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt index 41f0abf53..d8b433428 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt @@ -242,7 +242,7 @@ internal abstract class MmrcmsParser( val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPage).map { url -> - val img = url.src()?.toRelativeUrl(domain) ?: url.parseFailed("Image src not found") + val img = url.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(img), url = img, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/onemanga/OneMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/onemanga/OneMangaParser.kt index 4f645007b..78a449573 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/onemanga/OneMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/onemanga/OneMangaParser.kt @@ -79,7 +79,7 @@ internal abstract class OneMangaParser( val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select("div.elementor-widget-container img").map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/otakusanctuary/OtakuSanctuaryParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/otakusanctuary/OtakuSanctuaryParser.kt index 20753d363..4b5d1e8cd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/otakusanctuary/OtakuSanctuaryParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/otakusanctuary/OtakuSanctuaryParser.kt @@ -228,7 +228,7 @@ internal abstract class OtakuSanctuaryParser( } } else { return doc.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerMangaOnline.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerMangaOnline.kt index c11f2fd1a..cbcf2e046 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerMangaOnline.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerMangaOnline.kt @@ -140,7 +140,7 @@ internal class LerMangaOnline(context: MangaLoaderContext) : val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(".images img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MangaOnline.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MangaOnline.kt index f11ab9a61..678d28424 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MangaOnline.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MangaOnline.kt @@ -152,7 +152,7 @@ internal class MangaOnline(context: MangaLoaderContext) : PagedMangaParser(conte val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(".content p img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/AComics.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/AComics.kt index aaa4974e1..6d78fb384 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/AComics.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/AComics.kt @@ -177,6 +177,6 @@ internal class AComics(context: MangaLoaderContext) : override suspend fun getPageUrl(page: MangaPage): String { val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml() - return doc.requireElementById("mainImage").src() ?: doc.parseFailed("Image src not found") + return doc.requireElementById("mainImage").requireSrc() } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/MangaAy.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/MangaAy.kt index ff2d6899b..21e28e928 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/MangaAy.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/MangaAy.kt @@ -177,7 +177,7 @@ internal class MangaAy(context: MangaLoaderContext) : PagedMangaParser(context, val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select("div.mt-2 img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/SadScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/SadScans.kt index 1179f4369..7e653cbc9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/SadScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/SadScans.kt @@ -96,7 +96,7 @@ internal class SadScans(context: MangaLoaderContext) : SinglePageMangaParser(con val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(".swiper-slide img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt index 50ed1f46b..19d14bbd0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt @@ -227,7 +227,7 @@ internal class TrWebtoon(context: MangaLoaderContext) : override suspend fun getPages(chapter: MangaChapter): List { val doc = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml().requireElementById("images") return doc.select("img").map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt index 5c9860484..437fcfbd6 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt @@ -136,7 +136,7 @@ internal class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context override suspend fun getPages(chapter: MangaChapter): List { val docs = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml() return docs.select("#image > img").map { - val pageUrl = it.src() ?: it.parseFailed("Image src not found") + val pageUrl = it.requireSrc() MangaPage( id = generateUid(pageUrl), url = pageUrl, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenGG.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenGG.kt index 84b0b443b..748f9d026 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenGG.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenGG.kt @@ -14,11 +14,11 @@ import java.util.* @MangaSourceParser("TRUYENGG", "TruyenGG", "vi") internal class TruyenGG(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.TRUYENGG, 42) { - override val configKeyDomain = ConfigKey.Domain("truyengg.com") + override val configKeyDomain = ConfigKey.Domain("truyengg.com") override fun onCreateConfig(keys: MutableCollection>) { - super.onCreateConfig(keys) - keys.add(userAgentKey) + super.onCreateConfig(keys) + keys.add(userAgentKey) } override val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_DESKTOP) @@ -62,6 +62,7 @@ internal class TruyenGG(context: MangaLoaderContext) : PagedMangaParser(context, append(filter.query.urlEncoded()) } } + else -> { buildString { append("https://") @@ -147,11 +148,11 @@ internal class TruyenGG(context: MangaLoaderContext) : PagedMangaParser(context, override suspend fun getDetails(manga: Manga): Manga { val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH) - + return manga.copy( altTitle = doc.selectFirst("h2.other-name")?.text(), author = doc.select("p:contains(Tác Giả) + p").joinToString { it.text() }.takeUnless { it.isEmpty() }, - tags = doc.select("a.clblue").mapToSet { + tags = doc.select("a.clblue").mapToSet { MangaTag( key = it.attr("href").substringAfterLast('-').substringBeforeLast('.'), title = it.text(), @@ -188,7 +189,7 @@ internal class TruyenGG(context: MangaLoaderContext) : PagedMangaParser(context, val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(".content_detail img").map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, @@ -198,14 +199,14 @@ internal class TruyenGG(context: MangaLoaderContext) : PagedMangaParser(context, } } - private suspend fun fetchAvailableTags(): Set { - val doc = webClient.httpGet("https://$domain/tim-kiem-nang-cao.html").parseHtml() - return doc.select(".advsearch-form div.genre-item").mapToSet { - MangaTag( - key = it.selectFirstOrThrow("span").attr("data-id"), - title = it.text(), - source = source, - ) - } - } + private suspend fun fetchAvailableTags(): Set { + val doc = webClient.httpGet("https://$domain/tim-kiem-nang-cao.html").parseHtml() + return doc.select(".advsearch-form div.genre-item").mapToSet { + MangaTag( + key = it.selectFirstOrThrow("span").attr("data-id"), + title = it.text(), + source = source, + ) + } + } } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenQQ.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenQQ.kt index 056b79cdc..94315a483 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenQQ.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyenQQ.kt @@ -201,7 +201,7 @@ internal class TruyenQQ(context: MangaLoaderContext) : PagedMangaParser(context, val root = doc.body().selectFirstOrThrow(".chapter_content") return root.select("div.page-chapter").map { div -> val img = div.selectFirstOrThrow("img") - val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vmp/VmpParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vmp/VmpParser.kt index afe57c31c..3465909f4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vmp/VmpParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vmp/VmpParser.kt @@ -144,7 +144,7 @@ internal abstract class VmpParser( val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select("div.wp-content img").map { div -> val img = div.selectFirstOrThrow("img") - val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/WpComicsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/WpComicsParser.kt index ce97ed8b1..36dd3b92d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/WpComicsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/WpComicsParser.kt @@ -268,7 +268,7 @@ internal abstract class WpComicsParser( val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPage).map { url -> - val img = url.src()?.toRelativeUrl(domain) ?: url.parseFailed("Image src not found") + val img = url.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(img), url = img, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt index 6548aa31e..6eebd3ae2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt @@ -341,7 +341,7 @@ internal abstract class ZeistMangaParser( } else { doc.select(selectPage).map { img -> - val url = img.src() ?: img.parseFailed("Image src not found") + val url = img.requireSrc() MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt index 2c36b2a17..9419d6287 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt @@ -275,7 +275,7 @@ internal abstract class ZMangaParser( val doc = webClient.httpGet(fullUrl).parseHtml() return doc.select(selectPage).map { img -> - val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + val url = img.requireSrc().toRelativeUrl(domain) MangaPage( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/util/Jsoup.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/util/Jsoup.kt index 0f2f37a37..7739976ab 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/util/Jsoup.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/util/Jsoup.kt @@ -9,6 +9,7 @@ import org.jsoup.select.QueryParser import org.jsoup.select.Selector import org.koitharu.kotatsu.parsers.InternalParsersApi import org.koitharu.kotatsu.parsers.exception.ParseException +import kotlin.contracts.contract public val Element.host: String? get() { @@ -24,8 +25,7 @@ public val Element.host: String? * Return an attribute value or null if it is missing or empty * @see [Element.attr] which returns empty string instead of null */ -public fun Element.attrOrNull(attributeKey: String) = attr(attributeKey).takeUnless { it.isBlank() }?.trim() - +public fun Element.attrOrNull(attributeKey: String): String? = attr(attributeKey).takeUnless { it.isBlank() }?.trim() /** * Return an attribute value or throw an exception if it is missing @@ -48,7 +48,7 @@ public fun Element.attrAsRelativeUrlOrNull(attributeKey: String): String? { if (attr.isEmpty() || attr.startsWith("data:")) { return null } - if (attr.startsWith("/")) { + if (attr.startsWith('/')) { return attr } val host = baseUri().toHttpUrlOrNull()?.host ?: return null @@ -90,7 +90,7 @@ public fun Element.attrAsAbsoluteUrlOrNull(attributeKey: String): String? { * @see attrAsRelativeUrlOrNull */ public fun Element.attrAsAbsoluteUrl(attributeKey: String): String { - return requireNotNull(attrAsAbsoluteUrlOrNull(attributeKey)) { + return parseNotNull(attrAsAbsoluteUrlOrNull(attributeKey)) { "Cannot get absolute url for $attributeKey: \"${attr(attributeKey)}\"" } } @@ -107,8 +107,8 @@ public fun Element.styleValueOrNull(property: String): String? { /** * Like a `expectFirst` but with detailed error message */ -public fun Element.selectFirstOrThrow(cssQuery: String): Element { - return Selector.selectFirst(cssQuery, this) ?: throw ParseException("Cannot find \"$cssQuery\"", baseUri()) +public fun Element.selectFirstOrThrow(cssQuery: String): Element = parseNotNull(Selector.selectFirst(cssQuery, this)) { + "Cannot find \"$cssQuery\"" } public fun Element.selectOrThrow(cssQuery: String): Elements { @@ -117,16 +117,14 @@ public fun Element.selectOrThrow(cssQuery: String): Elements { } } -public fun Element.requireElementById(id: String): Element { - return getElementById(id) ?: throw ParseException("Cannot find \"#$id\"", baseUri()) +public fun Element.requireElementById(id: String): Element = parseNotNull(getElementById(id)) { + "Cannot find \"#$id\"" } -public fun Element.selectLast(cssQuery: String): Element? { - return select(cssQuery).lastOrNull() -} +public fun Element.selectLast(cssQuery: String): Element? = select(cssQuery).lastOrNull() -public fun Element.selectLastOrThrow(cssQuery: String): Element { - return selectLast(cssQuery) ?: throw ParseException("Cannot find \"$cssQuery\"", baseUri()) +public fun Element.selectLastOrThrow(cssQuery: String): Element = parseNotNull(selectLast(cssQuery)) { + "Cannot find \"$cssQuery\"" } public fun Element.textOrNull(): String? = text().takeUnless { it.isEmpty() } @@ -142,8 +140,9 @@ public fun Element.selectFirstParent(query: String): Element? { } } -public fun Element.selectFirstParentOrThrow(query: String): Element = - selectFirstParent(query) ?: throw ParseException("Cannot find parent \"$query\"", baseUri()) +public fun Element.selectFirstParentOrThrow(query: String): Element = parseNotNull(selectFirstParent(query)) { + "Cannot find parent \"$query\"" +} /** * Return a first non-empty attribute value of [names] or null if it is missing or empty @@ -183,6 +182,11 @@ public fun Element.src( return null } +@InternalParsersApi +public fun Element.requireSrc(): String = parseNotNull(src()) { + "Image src not found" +} + public fun Element.metaValue(itemprop: String): String? = getElementsByAttributeValue("itemprop", itemprop) .firstNotNullOfOrNull { element -> element.attrOrNull("content") @@ -200,3 +204,16 @@ public fun String.cssUrl(): String? { substring(fromIndex + 4, toIndex).trim() } } + +internal inline fun Element.parseNotNull(value: T?, lazyMessage: () -> String): T { + contract { + returns() implies (value != null) + } + + if (value == null) { + val message = lazyMessage() + throw ParseException(message, baseUri()) + } else { + return value + } +} diff --git a/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaParserTest.kt b/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaParserTest.kt index c41168bbb..7ca225976 100644 --- a/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaParserTest.kt +++ b/src/test/kotlin/org/koitharu/kotatsu/parsers/MangaParserTest.kt @@ -190,7 +190,7 @@ internal class MangaParserTest { fun favicon(source: MangaParserSource) = runTest(timeout = timeout) { val parser = context.newParserInstance(source) val favicons = parser.getFavicons() - val types = setOf("png", "svg", "ico", "gif", "jpg", "jpeg") + val types = setOf("png", "svg", "ico", "gif", "jpg", "jpeg", "webp", "avif") assert(favicons.isNotEmpty()) favicons.forEach { assert(it.url.isUrlAbsolute()) { "Favicon url is not absolute: ${it.url}" }