From 6abcdd8d4bdb1d3463a2d1d47b9dbdcd182291ca Mon Sep 17 00:00:00 2001 From: Koitharu Date: Sun, 12 Jan 2025 19:16:46 +0200 Subject: [PATCH] Fix nullable strings usage --- .../parsers/site/all/ComickFunParser.kt | 4 +- .../parsers/site/all/ExHentaiParser.kt | 2 +- .../parsers/site/all/MangaFireParser.kt | 4 +- .../kotatsu/parsers/site/all/MangaPark.kt | 6 +- .../parsers/site/all/MangaReaderToParser.kt | 8 +-- .../site/all/NineNineNineHentaiParser.kt | 2 +- .../kotatsu/parsers/site/ar/MangaStorm.kt | 5 +- .../kotatsu/parsers/site/ar/TeamXNovel.kt | 4 +- .../parsers/site/cupfox/CupFoxParser.kt | 8 +-- .../kotatsu/parsers/site/en/ComicExtra.kt | 13 ++-- .../kotatsu/parsers/site/en/DynastyScans.kt | 7 +-- .../kotatsu/parsers/site/en/MangaGeko.kt | 4 +- .../kotatsu/parsers/site/en/MangaKawaiiEn.kt | 6 +- .../kotatsu/parsers/site/en/Manhwa18Com.kt | 4 +- .../kotatsu/parsers/site/en/Manhwa18Parser.kt | 4 +- .../kotatsu/parsers/site/en/Po2Scans.kt | 5 +- .../parsers/site/fmreader/FmreaderParser.kt | 4 +- .../parsers/site/foolslide/FoolSlideParser.kt | 6 +- .../parsers/site/foolslide/en/Seinagi.kt | 6 +- .../site/foolslide/es/Pzykosis666hFansub.kt | 6 +- .../site/foolslide/es/SeinagiAdulto.kt | 6 +- .../parsers/site/fr/BentomangaParser.kt | 2 +- .../parsers/site/fr/LegacyScansParser.kt | 5 +- .../kotatsu/parsers/site/fr/LireScan.kt | 8 ++- .../kotatsu/parsers/site/fr/LugnicaScans.kt | 6 +- .../kotatsu/parsers/site/fr/MangaKawaii.kt | 4 +- .../kotatsu/parsers/site/fr/ScansMangasMe.kt | 2 +- .../kotatsu/parsers/site/fr/ScantradUnion.kt | 4 +- .../site/fuzzydoodle/FuzzyDoodleParser.kt | 6 +- .../parsers/site/heancmsalt/HeanCmsAlt.kt | 2 +- .../parsers/site/heancmsalt/es/Brakeout.kt | 2 +- .../kotatsu/parsers/site/id/HentaiCrot.kt | 6 +- .../kotatsu/parsers/site/id/PixHentai.kt | 6 +- .../parsers/site/likemanga/LikeMangaParser.kt | 7 +-- .../parsers/site/madara/es/MangasNoSekai.kt | 8 +-- .../parsers/site/madtheme/MadthemeParser.kt | 4 +- .../parsers/site/manga18/Manga18Parser.kt | 6 +- .../site/mangadventure/MangAdventureParser.kt | 2 +- .../site/mangaworld/MangaWorldParser.kt | 59 ++++++++++--------- .../parsers/site/mmrcms/MmrcmsParser.kt | 6 +- .../kotatsu/parsers/site/mmrcms/ar/Onma.kt | 6 +- .../parsers/site/nepnep/NepnepParser.kt | 7 +-- .../otakusanctuary/OtakuSanctuaryParser.kt | 4 +- .../kotatsu/parsers/site/pt/BrMangas.kt | 4 +- .../kotatsu/parsers/site/pt/YugenMangas.kt | 7 ++- .../parsers/site/ru/rulib/LibSocialParser.kt | 2 +- .../kotatsu/parsers/site/scan/ScanParser.kt | 6 +- .../kotatsu/parsers/site/scan/fr/MangaFr.kt | 6 +- .../kotatsu/parsers/site/scan/it/ScanIta.kt | 6 +- .../kotatsu/parsers/site/tr/SadScans.kt | 5 +- .../kotatsu/parsers/site/vi/HentaiVNParser.kt | 5 +- .../kotatsu/parsers/site/vi/SayHentai.kt | 4 +- .../kotatsu/parsers/site/vi/TruyenGG.kt | 4 +- .../kotatsu/parsers/site/vi/TruyenQQ.kt | 2 +- .../kotatsu/parsers/site/vmp/VmpParser.kt | 4 -- .../parsers/site/wpcomics/WpComicsParser.kt | 6 +- .../parsers/site/wpcomics/en/XoxoComics.kt | 3 +- .../parsers/site/wpcomics/vi/NetTruyen.kt | 24 +++----- .../koitharu/kotatsu/parsers/util/Jsoup.kt | 2 + 59 files changed, 170 insertions(+), 196 deletions(-) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ComickFunParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ComickFunParser.kt index e957c4599..22f0041c7 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ComickFunParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ComickFunParser.kt @@ -182,7 +182,7 @@ internal class ComickFunParser(context: MangaLoaderContext) : var alt = "" comic.getJSONArray("md_titles").mapJSON { alt += it.getString("title") + " - " } return manga.copy( - altTitle = alt.ifEmpty { comic.getStringOrNull("title") }, + altTitle = alt.ifEmpty { comic.getStringOrNull("title") }?.nullIfEmpty(), contentRating = if (jo.getBooleanOrDefault("matureContent", false) || comic.getBooleanOrDefault("hentai", false) ) { @@ -199,7 +199,7 @@ internal class ComickFunParser(context: MangaLoaderContext) : source = source, ) }, - author = jo.getJSONArray("artists").optJSONObject(0)?.getString("name"), + author = jo.getJSONArray("artists").optJSONObject(0)?.getStringOrNull("name"), chapters = getChapters(comic.getString("hid")), ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt index 12fc6a006..f611d6919 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt @@ -197,7 +197,7 @@ internal class ExHentaiParser( return manga.copy( title = title?.getElementById("gn")?.text()?.cleanupTitle() ?: manga.title, - altTitle = title?.getElementById("gj")?.text()?.cleanupTitle() ?: manga.altTitle, + altTitle = (title?.getElementById("gj")?.text()?.cleanupTitle() ?: manga.altTitle)?.nullIfEmpty(), publicUrl = doc.baseUri().ifEmpty { manga.publicUrl }, rating = root.getElementById("rating_label")?.text() ?.substringAfterLast(' ') diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaFireParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaFireParser.kt index 6468a9748..84e36a6e5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaFireParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaFireParser.kt @@ -182,7 +182,7 @@ internal abstract class MangaFireParser( return manga.copy( title = document.selectFirstOrThrow(".info > h1").ownText(), - altTitle = document.selectFirst(".info > h6")?.ownText(), + altTitle = document.selectFirst(".info > h6")?.ownTextOrNull(), rating = document.selectFirst("div.rating-box")?.attr("data-score") ?.toFloatOrNull()?.div(10) ?: RATING_UNKNOWN, coverUrl = document.selectFirstOrThrow("div.manga-detail div.poster img") @@ -212,7 +212,7 @@ internal abstract class MangaFireParser( } }, author = document.select("div.meta a[href*=/author/]") - .joinToString { it.ownText() }, + .joinToString { it.ownText() }.nullIfEmpty(), description = document.selectFirstOrThrow("#synopsis div.modal-content").html(), chapters = getChapters(manga.url, document), ) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt index b15dde56c..292bc2a03 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt @@ -179,9 +179,9 @@ internal class MangaPark(context: MangaLoaderContext) : val nsfw = tags.any { t -> t.key == "hentai" || t.key == "adult" } val dateFormat = SimpleDateFormat("dd/MM/yyyy", sourceLocale) manga.copy( - altTitle = doc.selectFirst("div[q:key=tz_2]")?.text().orEmpty(), - author = doc.selectFirst("div[q:key=tz_4]")?.text().orEmpty(), - description = doc.selectFirst("react-island[q:key=0a_9]")?.html().orEmpty(), + altTitle = doc.selectFirst("div[q:key=tz_2]")?.textOrNull(), + author = doc.selectFirst("div[q:key=tz_4]")?.textOrNull(), + description = doc.selectFirst("react-island[q:key=0a_9]")?.html(), state = when (doc.selectFirst("span[q:key=Yn_5]")?.text()?.lowercase()) { "ongoing" -> MangaState.ONGOING "completed" -> MangaState.FINISHED diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaReaderToParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaReaderToParser.kt index 38f65e2b4..235876a42 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaReaderToParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaReaderToParser.kt @@ -172,10 +172,10 @@ internal class MangaReaderToParser(context: MangaLoaderContext) : return manga.copy( title = document.selectFirst("h2.manga-name")!!.ownText(), - altTitle = document.selectFirst("div.manga-name-or")?.ownText(), + altTitle = document.selectFirst("div.manga-name-or")?.ownTextOrNull(), rating = document.selectFirst("div.anisc-info .item:contains(score:) > .name") ?.text()?.toFloatOrNull()?.div(10) ?: RATING_UNKNOWN, - coverUrl = document.selectFirst(".manga-poster > img")!!.attr("src"), + coverUrl = document.selectFirst(".manga-poster > img")?.attrAsAbsoluteUrlOrNull("src"), tags = document.select("div.genres > a[href*=/genre/]").mapNotNullToSet { val tag = it.ownText() if (tag == "Hentai") { @@ -202,8 +202,8 @@ internal class MangaReaderToParser(context: MangaLoaderContext) : } }, author = document.select("div.anisc-info a[href*=/author/]") - .joinToString { it.ownText().replace(", ", " ") }, - description = document.select("div.description").text(), + .joinToString { it.ownText().replace(", ", " ") }.nullIfEmpty(), + description = document.select("div.description").html(), chapters = parseChapters(document), source = source, ) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineNineNineHentaiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineNineNineHentaiParser.kt index 8c136ed45..5928464b2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineNineNineHentaiParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineNineNineHentaiParser.kt @@ -269,7 +269,7 @@ internal class NineNineNineHentaiParser(context: MangaLoaderContext) : altTitle = name, coverUrl = cover.first, largeCoverUrl = cover.second, - author = tags?.filter { it.type == "artist" }?.joinToString { it.name.toCamelCase() }, + author = tags?.filter { it.type == "artist" }?.joinToString { it.name.toCamelCase() }?.nullIfEmpty(), contentRating = ContentRating.ADULT, tags = tags?.mapToSet { MangaTag( 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 c0692973a..e85b35346 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 @@ -88,8 +88,6 @@ internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(contex val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() val root = doc.selectFirstOrThrow(".card-body .col-lg-9") return manga.copy( - altTitle = null, - state = null, tags = root.select(".flex-wrap a").mapToSet { a -> MangaTag( key = a.attr("href").substringAfterLast('/'), @@ -97,8 +95,7 @@ internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(contex source = source, ) }, - author = null, - description = root.selectFirstOrThrow(".card-text").text(), + description = root.selectFirstOrThrow(".card-text").html(), chapters = doc.select(".card-body a.btn-fixed-width").mapChapters(reversed = true) { i, a -> val url = a.attrAsRelativeUrl("href") MangaChapter( 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 c4817c682..876bd023c 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 @@ -148,7 +148,6 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex } } return manga.copy( - altTitle = null, state = when (doc.selectFirstOrThrow(".full-list-info:contains(الحالة:) a").text()) { "مستمرة" -> MangaState.ONGOING "مكتمل" -> MangaState.FINISHED @@ -162,8 +161,7 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex source = source, ) }, - author = null, - description = doc.selectFirstOrThrow(".review-content").text(), + description = doc.selectFirstOrThrow(".review-content").html(), chapters = run { if (maxPageChapter == 1) { parseChapters(doc) 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 c094eeda8..17b3be28d 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 @@ -124,8 +124,7 @@ internal abstract class CupFoxParser( override suspend fun getDetails(manga: Manga): Manga { val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() return manga.copy( - altTitle = doc.selectFirst(selectMangaDetailsAltTitle)?.text()?.substringAfter(":"), - state = null, + altTitle = doc.selectFirst(selectMangaDetailsAltTitle)?.text()?.substringAfter(":")?.nullIfEmpty(), tags = doc.select(selectMangaDetailsTags).mapToSet { a -> MangaTag( key = a.attr("href").removeSuffix('/').substringAfterLast('/'), @@ -133,9 +132,8 @@ internal abstract class CupFoxParser( source = source, ) }, - author = doc.selectFirst(selectMangaDetailsAuthor)?.text()?.substringAfter(":"), - description = doc.selectFirst(selectMangaDescription) - ?.html(), + author = doc.selectFirst(selectMangaDetailsAuthor)?.text()?.substringAfter(":")?.nullIfEmpty(), + description = doc.selectFirst(selectMangaDescription)?.html(), chapters = doc.select(selectMangaChapters) .mapChapters { i, li -> val a = li.selectFirstOrThrow("a") 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 363472648..99fc790bf 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 @@ -1,6 +1,5 @@ package org.koitharu.kotatsu.parsers.site.en -import org.koitharu.kotatsu.parsers.ErrorMessages import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser @@ -96,7 +95,7 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex return doc.select("ul.lf-list li a").mapToSet { a -> MangaTag( key = a.attr("href").substringAfterLast('/'), - title = a.text(), + title = a.text().toTitleCase(sourceLocale), source = source, ) } @@ -105,7 +104,7 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex override suspend fun getDetails(manga: Manga): Manga { val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() return manga.copy( - altTitle = doc.selectFirstOrThrow("div.anime-top h1.title").text(), + altTitle = doc.selectFirstOrThrow("div.anime-top h1.title").textOrNull(), state = when (doc.selectFirstOrThrow("ul.anime-genres li.status a").text()) { "Ongoing" -> MangaState.ONGOING "Completed" -> MangaState.FINISHED @@ -114,14 +113,14 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex tags = doc.select("ul.anime-genres li a").mapToSet { a -> MangaTag( key = a.attr("href").substringAfterLast('/'), - title = a.text(), + title = a.text().toTitleCase(sourceLocale), source = source, ) }, - author = doc.selectFirst("table.full-table tr:contains(Author:) td:nth-child(2)")?.text(), - description = doc.selectFirstOrThrow("div.detail-desc-content p").text(), + author = doc.selectFirst("table.full-table tr:contains(Author:) td:nth-child(2)")?.textOrNull(), + description = doc.selectFirstOrThrow("div.detail-desc-content p").html(), chapters = doc.select("ul.basic-list li").let { elements -> - elements.mapChapters() { i, li -> + elements.mapChapters { i, li -> val a = li.selectFirstOrThrow("a.ch-name") val url = a.attrAsRelativeUrl("href") val name = a.text() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/DynastyScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/DynastyScans.kt index 6d45e8825..6c27a14d5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/DynastyScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/DynastyScans.kt @@ -144,7 +144,7 @@ internal class DynastyScans(context: MangaLoaderContext) : private fun Element.parseTags() = select("a").mapToSet { MangaTag( key = it.attr("href").removeSuffix('/').substringAfterLast('/'), - title = it.text(), + title = it.text().toTitleCase(sourceLocale), source = source, ) } @@ -157,7 +157,6 @@ internal class DynastyScans(context: MangaLoaderContext) : .find { it.ownText() == "This manga has been licensed" } ?.nextElementSibling()?.html() return manga.copy( - altTitle = null, state = when (root.select("h2.tag-title small").last()?.text()) { "— Ongoing" -> MangaState.ONGOING "— Completed", "— Completed and Licensed" -> MangaState.FINISHED @@ -165,10 +164,8 @@ internal class DynastyScans(context: MangaLoaderContext) : "— On Hiatus" -> MangaState.PAUSED else -> null }, - coverUrl = root.selectFirst("img.thumbnail")?.src() - .orEmpty(), // It is needed if the manga was found via the search. + coverUrl = root.selectFirst("img.thumbnail")?.src(), tags = root.selectFirstOrThrow("div.tag-tags").parseTags(), - author = null, description = licensedText, chapters = chapters, ) 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 b822194e4..bdfb6a85b 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 @@ -109,7 +109,7 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() val chaptersDeferred = async { loadChapters(manga.url) } manga.copy( - altTitle = doc.selectFirstOrThrow(".alternative-title").text(), + altTitle = doc.selectFirstOrThrow(".alternative-title").textOrNull(), state = when (doc.selectFirstOrThrow(".header-stats span:contains(Status) strong").text()) { "Ongoing" -> MangaState.ONGOING "Completed" -> MangaState.FINISHED @@ -122,7 +122,7 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context source = source, ) }, - author = doc.selectFirstOrThrow(".author").text(), + author = doc.selectFirstOrThrow(".author").textOrNull(), description = doc.selectFirstOrThrow(".description").html(), chapters = chaptersDeferred.await(), ) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaKawaiiEn.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaKawaiiEn.kt index 88e884078..7b563ee35 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaKawaiiEn.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaKawaiiEn.kt @@ -100,9 +100,9 @@ internal class MangaKawaiiEn(context: MangaLoaderContext) : val firstChapter = doc.selectFirst("tr[class*='volume-'] a")?.attr("href") val chaptersDeferred = async { loadChapters(firstChapter) } manga.copy( - description = doc.selectFirst("dd.text-justify.text-break")?.text().orEmpty(), - altTitle = doc.select("span[itemprop*=alternativeHeadline]").joinToString { ", " }, - author = doc.select("a[href*=author]").text(), + description = doc.selectFirst("dd.text-justify.text-break")?.html(), + altTitle = doc.select("span[itemprop*=alternativeHeadline]").joinToString { ", " }.nullIfEmpty(), + author = doc.select("a[href*=author]").textOrNull(), state = when (doc.selectFirst("span.badge.bg-success.text-uppercase")?.text()) { "Ongoing" -> MangaState.ONGOING "" -> MangaState.FINISHED diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Com.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Com.kt index 93a167b77..f957f62fe 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Com.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Com.kt @@ -147,6 +147,7 @@ internal class Manhwa18Com(context: MangaLoaderContext) : val author = cardInfoElement?.selectFirst(".info-name:contains(Author)")?.parent() ?.select("a") ?.joinToString(", ") { it.text() } + ?.nullIfEmpty() val availableTags = tagsMap.get() val tags = cardInfoElement?.selectFirst(".info-name:contains(Genre)")?.parent() ?.select("a") @@ -163,7 +164,8 @@ internal class Manhwa18Com(context: MangaLoaderContext) : } return manga.copy( - altTitle = cardInfoElement?.selectFirst("b:contains(Other names)")?.parent()?.ownText()?.removePrefix(": "), + altTitle = cardInfoElement?.selectFirst("b:contains(Other names)")?.parent()?.ownTextOrNull() + ?.removePrefix(": "), author = author, description = docs.selectFirst(".series-summary .summary-content")?.html(), tags = tags.orEmpty(), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt index 9f8c0fc8b..738c541a0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt @@ -147,6 +147,7 @@ internal class Manhwa18Parser(context: MangaLoaderContext) : val author = cardInfoElement?.selectFirst(".info-name:contains(Author)")?.parent() ?.select("a") ?.joinToString(", ") { it.text() } + ?.nullIfEmpty() val availableTags = tagsMap.get() val tags = cardInfoElement?.selectFirst(".info-name:contains(Genre)")?.parent() ?.select("a") @@ -163,7 +164,8 @@ internal class Manhwa18Parser(context: MangaLoaderContext) : } return manga.copy( - altTitle = cardInfoElement?.selectFirst("b:contains(Other names)")?.parent()?.ownText()?.removePrefix(": "), + altTitle = cardInfoElement?.selectFirst("b:contains(Other names)")?.parent()?.ownTextOrNull() + ?.removePrefix(": "), author = author, description = docs.selectFirst(".series-summary .summary-content")?.html(), tags = tags.orEmpty(), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Po2Scans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Po2Scans.kt index c9f450fe2..f68bae248 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Po2Scans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Po2Scans.kt @@ -63,15 +63,14 @@ internal class Po2Scans(context: MangaLoaderContext) : SinglePageMangaParser(con val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() val dateFormat = SimpleDateFormat("dd MMM, yy", Locale.ENGLISH) return manga.copy( - altTitle = null, state = when (doc.select(".status span").last()?.text()) { "Ongoing" -> MangaState.ONGOING "Done" -> MangaState.FINISHED else -> null }, tags = emptySet(), - author = doc.select(".author span").last()?.text(), - description = doc.selectFirstOrThrow(".summary").text(), + author = doc.selectLast(".author span")?.textOrNull(), + description = doc.selectFirstOrThrow(".summary").html(), chapters = doc.select(".chap-section .chap") .mapChapters(reversed = true) { i, div -> val a = div.selectFirstOrThrow("a") 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 151a1b3b0..bb2b89f55 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 @@ -189,8 +189,8 @@ internal abstract class FmreaderParser( else -> null } } - val alt = doc.body().selectFirst(selectAlt)?.text()?.replace("Other names", "") - val auth = doc.body().selectFirst(selectAut)?.text() + val alt = doc.body().selectFirst(selectAlt)?.text()?.replace("Other names", "")?.nullIfEmpty() + val auth = doc.body().selectFirst(selectAut)?.textOrNull() manga.copy( tags = doc.body().select(selectTag).mapToSet { a -> MangaTag( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/FoolSlideParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/FoolSlideParser.kt index 583a95612..343c90696 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/FoolSlideParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/FoolSlideParser.kt @@ -125,10 +125,8 @@ internal abstract class FoolSlideParser( } manga.copy( coverUrl = doc.selectFirst(".thumbnail img")?.src() ?: manga.coverUrl, - description = desc.orEmpty(), - altTitle = null, - author = author.orEmpty(), - state = null, + description = desc?.nullIfEmpty(), + author = author?.nullIfEmpty(), chapters = chapters, ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/en/Seinagi.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/en/Seinagi.kt index bce511164..137e085a2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/en/Seinagi.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/en/Seinagi.kt @@ -35,10 +35,8 @@ internal class Seinagi(context: MangaLoaderContext) : } manga.copy( coverUrl = doc.selectFirst(".thumbnail img")?.src() ?: manga.coverUrl, - description = desc, - altTitle = null, - author = author, - state = null, + description = desc?.nullIfEmpty(), + author = author?.nullIfEmpty(), chapters = chapters, ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/es/Pzykosis666hFansub.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/es/Pzykosis666hFansub.kt index ab208a128..ab087dd07 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/es/Pzykosis666hFansub.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/es/Pzykosis666hFansub.kt @@ -34,10 +34,8 @@ internal class Pzykosis666hFansub(context: MangaLoaderContext) : } manga.copy( coverUrl = doc.selectFirst(".thumbnail img")?.src() ?: manga.coverUrl, - description = desc.orEmpty(), - altTitle = null, - author = author.orEmpty(), - state = null, + description = desc?.nullIfEmpty(), + author = author?.nullIfEmpty(), chapters = chapters, ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/es/SeinagiAdulto.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/es/SeinagiAdulto.kt index e9047c110..42b102579 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/es/SeinagiAdulto.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/es/SeinagiAdulto.kt @@ -34,10 +34,8 @@ internal class SeinagiAdulto(context: MangaLoaderContext) : } manga.copy( coverUrl = doc.selectFirst(".thumbnail img")?.src().orEmpty(),// for manga result on search - description = desc.orEmpty(), - altTitle = null, - author = author.orEmpty(), - state = null, + description = desc?.nullIfEmpty(), + author = author?.nullIfEmpty(), chapters = chapters, ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt index 5a8260a90..469e63915 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt @@ -148,7 +148,7 @@ internal class BentomangaParser(context: MangaLoaderContext) : val root = webClient.httpGet(mangaUrl).parseHtml() .requireElementById("container_manga_show") return manga.copy( - altTitle = root.selectFirst(".component-manga-title_alt")?.text(), + altTitle = root.selectFirst(".component-manga-title_alt")?.textOrNull(), description = root.selectFirst(".datas_synopsis")?.html().assertNotNull("description") ?: manga.description, state = when (root.selectFirst(".datas_more-status-data")?.textOrNull().assertNotNull("status")) { 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 671011dcc..b4cbf8e96 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 @@ -171,7 +171,6 @@ internal class LegacyScansParser(context: MangaLoaderContext) : val root = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.FRENCH) return manga.copy( - altTitle = null, tags = root.select("div.serieGenre span").mapToSet { span -> MangaTag( key = span.text(), @@ -179,8 +178,8 @@ internal class LegacyScansParser(context: MangaLoaderContext) : source = source, ) }, - coverUrl = root.selectFirst("div.serieImg img")?.attr("src").orEmpty(), - author = root.select("div.serieAdd p:contains(Auteur:) strong").text(), + coverUrl = root.selectFirst("div.serieImg img")?.attr("src"), + author = root.select("div.serieAdd p:contains(Auteur:) strong").textOrNull(), description = root.selectFirst("div.serieDescription div")?.html(), chapters = root.select("div.chapterList a") .mapChapters(reversed = true) { i, a -> diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LireScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LireScan.kt index 35cb1fe9c..c62617c3b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LireScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LireScan.kt @@ -87,7 +87,7 @@ internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context, val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.FRANCE) return manga.copy( altTitle = root.select("ul.pmovie__list li:contains(Nom Alternatif:)").text() - .replace("Nom Alternatif:", ""), + .replace("Nom Alternatif:", "").nullIfEmpty(), state = when (root.select("ul.pmovie__list li:contains(Status:)").text()) { "Status: OnGoing", "Status: En cours" -> MangaState.ONGOING "Status: Fini" -> MangaState.FINISHED @@ -97,11 +97,13 @@ internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context, .replace("Genre:", "").split(" / ").mapToSet { tag -> MangaTag( key = tag.lowercase(), - title = tag, + title = tag.toTitleCase(sourceLocale), source = source, ) }, - author = root.select("ul.pmovie__list li:contains(Artist(s):)").text().replace("Artist(s):", ""), + author = root.select("ul.pmovie__list li:contains(Artist(s):)").text() + .replace("Artist(s):", "") + .nullIfEmpty(), description = root.selectFirst("div.pmovie__text")?.html(), chapters = root.select("ul li div.chapter") .mapChapters(reversed = true) { i, div -> diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt index ee3b0b353..1f04d9c10 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt @@ -10,6 +10,7 @@ import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.network.UserAgents import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.json.getFloatOrDefault +import org.koitharu.kotatsu.parsers.util.json.getStringOrNull import org.koitharu.kotatsu.parsers.util.json.mapJSON import java.text.SimpleDateFormat import java.util.* @@ -161,15 +162,14 @@ internal class LugnicaScans(context: MangaLoaderContext) : val slug = manga.url.substringAfterLast("/") val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.FRANCE) return manga.copy( - altTitle = null, state = when (jsonManga.getString("status")) { "0" -> MangaState.ONGOING "1" -> MangaState.FINISHED "3" -> MangaState.ABANDONED else -> null }, - author = jsonManga.getString("author"), - description = jsonManga.getString("description"), + author = jsonManga.getStringOrNull("author"), + description = jsonManga.getStringOrNull("description"), chapters = chapters.mapChapters { i, it -> val id = it.substringAfter("\"chapter\":").substringBefore(",") val url = "https://$domain/api/get/chapter/$slug/$id" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/MangaKawaii.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/MangaKawaii.kt index 8dc102613..18e5b5f85 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/MangaKawaii.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/MangaKawaii.kt @@ -99,8 +99,8 @@ internal class MangaKawaii(context: MangaLoaderContext) : PagedMangaParser(conte val firstChapter = doc.selectFirst("tr[class*='volume-'] a")?.attr("href") val chaptersDeferred = async { loadChapters(firstChapter) } manga.copy( - description = doc.selectFirst("dd.text-justify.text-break")?.text().orEmpty(), - altTitle = doc.select("span[itemprop*=alternativeHeadline]").joinToString { ", " }, + description = doc.selectFirst("dd.text-justify.text-break")?.html(), + altTitle = doc.select("span[itemprop*=alternativeHeadline]").joinToString { ", " }.nullIfEmpty(), author = doc.select("a[href*=author]").text(), state = when (doc.selectFirst("span.badge.bg-success.text-uppercase")?.text()) { "En Cours" -> MangaState.ONGOING diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScansMangasMe.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScansMangasMe.kt index fa4c032e6..6972afe37 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScansMangasMe.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScansMangasMe.kt @@ -113,7 +113,7 @@ internal class ScansMangasMe(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val chaptersDeferred = getChapters(doc) val desc = doc.selectFirstOrThrow("div.desc").html().nullIfEmpty() - val alt = doc.body().select("div.infox span.alter").text().nullIfEmpty() + val alt = doc.body().select("div.infox span.alter").textOrNull() val aut = doc.select("div.spe span")[2].text().replace("Auteur:", "").nullIfEmpty() manga.copy( tags = doc.select("div.spe span:contains(Genres) a").mapToSet { a -> diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt index 52ed44720..cd4628249 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt @@ -124,7 +124,7 @@ internal class ScantradUnion(context: MangaLoaderContext) : val dateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.FRANCE) return manga.copy( - altTitle = root.select(".divider2:contains(Noms associés :)").firstOrNull()?.text(), + altTitle = root.select(".divider2:contains(Noms associés :)").firstOrNull()?.textOrNull(), state = when (root.select(".label.label-primary")[2].text()) { "En cours" -> MangaState.ONGOING "Terminé", "Abondonné", "One Shot" -> MangaState.FINISHED @@ -137,7 +137,7 @@ internal class ScantradUnion(context: MangaLoaderContext) : source = source, ) }, - author = root.select("div.project-details a[href*=auteur]").text(), + author = root.select("div.project-details a[href*=auteur]").textOrNull(), description = root.selectFirst("p.sContent")?.html(), chapters = root.select("div.chapter-list li") .mapChapters(reversed = true) { i, li -> 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 26c0c94c4..d60886144 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 @@ -183,7 +183,7 @@ internal abstract class FuzzyDoodleParser( } manga.copy( - altTitle = doc.selectLast(selectAltTitle)?.text(), + altTitle = doc.selectLast(selectAltTitle)?.textOrNull(), state = when (doc.selectFirst(selectState)?.text()?.lowercase().orEmpty()) { in ongoing -> MangaState.ONGOING in finished -> MangaState.FINISHED @@ -191,8 +191,8 @@ internal abstract class FuzzyDoodleParser( in paused -> MangaState.PAUSED else -> null }, - author = doc.selectFirst(selectAuthor)?.text().orEmpty(), - description = doc.select(selectDescription).text(), + author = doc.selectFirst(selectAuthor)?.textOrNull(), + description = doc.select(selectDescription).html(), tags = doc.select(selectTagManga).mapToSet { val key = it.attr("href").substringAfterLast('=') MangaTag( 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 674239f5f..c2f944c89 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 @@ -89,7 +89,7 @@ internal abstract class HeanCmsAlt( val doc = webClient.httpGet(fullUrl).parseHtml() val dateFormat = SimpleDateFormat(datePattern, sourceLocale) return manga.copy( - altTitle = doc.selectFirst(selectAlt)?.text().orEmpty(), + altTitle = doc.selectFirst(selectAlt)?.textOrNull(), description = doc.selectFirst(selectDesc)?.html(), chapters = doc.select(selectChapter) .mapChapters(reversed = true) { i, a -> diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/es/Brakeout.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/es/Brakeout.kt index 572ddecb3..91016f794 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/es/Brakeout.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/es/Brakeout.kt @@ -25,7 +25,7 @@ internal class Brakeout(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val dateFormat = SimpleDateFormat(datePattern, sourceLocale) return manga.copy( - altTitle = doc.selectFirst(selectAlt)?.text().orEmpty(), + altTitle = doc.selectFirst(selectAlt)?.textOrNull(), description = doc.selectFirstOrThrow(selectDesc).html(), chapters = doc.select(selectChapter) .mapChapters(reversed = true) { i, div -> 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 ba6f9ec9c..16df73ad9 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 @@ -96,9 +96,9 @@ internal class HentaiCrot(context: MangaLoaderContext) : val fullUrl = manga.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return manga.copy( - description = doc.selectFirst("div.entry-content p")?.text().orEmpty(), - altTitle = doc.selectFirst("div.entry-content ul li:contains(Alternative Name(s) :) em")?.text().orEmpty(), - author = doc.selectFirst("div.entry-content ul li:contains(Artists :) em")?.text().orEmpty(), + description = doc.selectFirst("div.entry-content p")?.html(), + altTitle = doc.selectFirst("div.entry-content ul li:contains(Alternative Name(s) :) em")?.textOrNull(), + author = doc.selectFirst("div.entry-content ul li:contains(Artists :) em")?.textOrNull(), state = null, chapters = listOf( MangaChapter( 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 6c2a5173b..d597ec472 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 @@ -96,9 +96,9 @@ internal class PixHentai(context: MangaLoaderContext) : val fullUrl = manga.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() return manga.copy( - description = doc.selectFirst("div.entry-content p")?.text().orEmpty(), - altTitle = doc.selectFirst("div.entry-content ul li:contains(Alternative Name(s) :) em")?.text().orEmpty(), - author = doc.selectFirst("div.entry-content ul li:contains(Artists :) em")?.text().orEmpty(), + description = doc.selectFirst("div.entry-content p")?.html(), + altTitle = doc.selectFirst("div.entry-content ul li:contains(Alternative Name(s) :) em")?.textOrNull(), + author = doc.selectFirst("div.entry-content ul li:contains(Artists :) em")?.textOrNull(), state = null, chapters = listOf( MangaChapter( 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 7dab501bc..36826964b 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 @@ -150,8 +150,7 @@ internal abstract class LikeMangaParser( } } return manga.copy( - altTitle = doc.selectFirstOrThrow(".list-info li.othername h2").text(), - state = null, + altTitle = doc.selectFirst(".list-info li.othername h2")?.textOrNull(), tags = doc.select("li.kind a").mapToSet { a -> MangaTag( key = a.attr("href").removeSuffix('/').substringAfterLast('/'), @@ -159,8 +158,8 @@ internal abstract class LikeMangaParser( source = source, ) }, - author = doc.select("li.author p").last()?.text(), - description = doc.requireElementById("summary_shortened").text(), + author = doc.selectLast("li.author p")?.textOrNull(), + description = doc.requireElementById("summary_shortened").html(), chapters = run { if (maxPageChapter == 1) { parseChapters(doc) 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 bda97b4d7..401846261 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 @@ -28,11 +28,11 @@ internal class MangasNoSekai(context: MangaLoaderContext) : source = source, ) }, - author = doc.selectFirst("section#section-sinopsis div.d-flex:has(div:contains(Autor)) p a")?.text() - .orEmpty(), + author = doc.selectFirst("section#section-sinopsis div.d-flex:has(div:contains(Autor)) p a") + ?.textOrNull(), description = body.selectFirst("#section-sinopsis p")?.text().orEmpty(), - altTitle = doc.selectFirst("section#section-sinopsis div.d-flex:has(div:contains(Otros nombres)) p")?.text() - .orEmpty(), + altTitle = doc.selectFirst("section#section-sinopsis div.d-flex:has(div:contains(Otros nombres)) p") + ?.textOrNull(), state = body.selectFirst("section#section-sinopsis div.d-flex:has(div:contains(Estado)) p") ?.let { when (it.text()) { 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 1526edff8..4ddd47b41 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 @@ -186,8 +186,8 @@ internal abstract class MadthemeParser( source = source, ) }, - description = desc.orEmpty(), - altTitle = alt.orEmpty(), + description = desc?.nullIfEmpty(), + altTitle = alt.nullIfEmpty(), state = state, chapters = chaptersDeferred.await(), contentRating = if (nsfw || manga.isNsfw) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt index 2eaa4d1fa..4c0945e2c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt @@ -154,8 +154,8 @@ internal abstract class Manga18Parser( else -> null } } - val alt = body.selectFirst(selectAlt)?.text().takeIf { it != "Updating" || it.isNotEmpty() } - val author = body.selectFirst(selectAuthor)?.text().takeIf { it != "Updating" } + val alt = body.selectFirst(selectAlt)?.textOrNull().takeUnless { it == "Updating" } + val author = body.selectFirst(selectAuthor)?.textOrNull()?.takeUnless { it == "Updating" } manga.copy( tags = doc.body().select(selectTag).mapToSet { a -> MangaTag( @@ -164,7 +164,7 @@ internal abstract class Manga18Parser( source = source, ) }, - description = desc.orEmpty(), + description = desc?.nullIfEmpty(), altTitle = alt, author = author, state = state, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangadventure/MangAdventureParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangadventure/MangAdventureParser.kt index d4a8d329b..11b1d603a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangadventure/MangAdventureParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangadventure/MangAdventureParser.kt @@ -107,7 +107,7 @@ internal abstract class MangAdventureParser( .addEncodedQueryParameter("date_format", "timestamp").get() return manga.copy( description = details.getStringOrNull("description"), - altTitle = details.getJSONArray("aliases").joinToString(), + altTitle = details.getJSONArray("aliases").joinToString().nullIfEmpty(), author = buildString { val authors = details.getJSONArray("authors") val artists = details.getJSONArray("artists") 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 2ce871117..a86c1ccff 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 @@ -155,13 +155,13 @@ internal abstract class MangaWorldParser( tags = tags, author = div.selectFirst(".author a")?.text(), state = - when (div.selectFirst(".status a")?.text()?.lowercase()) { - "in corso" -> MangaState.ONGOING - "finito" -> MangaState.FINISHED - "droppato" -> MangaState.ABANDONED - "in pausa" -> MangaState.PAUSED - else -> null - }, + when (div.selectFirst(".status a")?.text()?.lowercase()) { + "in corso" -> MangaState.ONGOING + "finito" -> MangaState.FINISHED + "droppato" -> MangaState.ABANDONED + "in pausa" -> MangaState.PAUSED + else -> null + }, source = source, isNsfw = isNsfwSource, ) @@ -184,30 +184,31 @@ internal abstract class MangaWorldParser( val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() return manga.copy( altTitle = - doc.selectFirst(".meta-data .font-weight-bold:contains(Titoli alternativi:)") - ?.parent() - ?.ownText() - ?.substringAfter(": ") - ?.trim(), + doc.selectFirst(".meta-data .font-weight-bold:contains(Titoli alternativi:)") + ?.parent() + ?.ownText() + ?.substringAfter(": ") + ?.trim() + ?.nullIfEmpty(), description = doc.getElementById("noidungm")?.text().orEmpty(), chapters = - doc.select(".chapters-wrapper .chapter a").mapChapters(reversed = true) { i, a -> - val url = a.attrAsRelativeUrl("href").toAbsoluteUrl(domain) - MangaChapter( - id = generateUid(url), - name = a.selectFirst("span.d-inline-block")?.text() ?: "Chapter : ${i + 1f}", - number = i + 1f, - volume = 0, - url = "$url?style=list", - scanlator = null, - uploadDate = - SimpleDateFormat("dd MMMM yyyy", Locale.ITALIAN).tryParse( - a.selectFirst(".chap-date")?.text(), - ), - branch = null, - source = source, - ) - }, + doc.select(".chapters-wrapper .chapter a").mapChapters(reversed = true) { i, a -> + val url = a.attrAsRelativeUrl("href").toAbsoluteUrl(domain) + MangaChapter( + id = generateUid(url), + name = a.selectFirst("span.d-inline-block")?.text() ?: "Chapter : ${i + 1f}", + number = i + 1f, + volume = 0, + url = "$url?style=list", + scanlator = null, + uploadDate = + SimpleDateFormat("dd MMMM yyyy", Locale.ITALIAN).tryParse( + a.selectFirst(".chap-date")?.text(), + ), + branch = null, + source = source, + ) + }, ) } 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 d8b433428..6b6e51345 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 @@ -193,14 +193,14 @@ internal abstract class MmrcmsParser( else -> null } } - val alt = doc.body().selectFirst(selectAlt)?.nextElementSibling()?.text() - val auth = doc.body().selectFirst(selectAut)?.nextElementSibling()?.text() + val alt = doc.body().selectFirst(selectAlt)?.nextElementSibling()?.textOrNull() + val auth = doc.body().selectFirst(selectAut)?.nextElementSibling()?.textOrNull() val tags = doc.body().selectFirst(selectTag)?.nextElementSibling()?.select("a") ?: emptySet() manga.copy( tags = tags.mapToSet { a -> MangaTag( key = a.attr("href").removeSuffix('/').substringAfterLast('/'), - title = a.text().toTitleCase(), + title = a.text().toTitleCase(sourceLocale), source = source, ) }, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/ar/Onma.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/ar/Onma.kt index 0174ff4d5..5823b15cd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/ar/Onma.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/ar/Onma.kt @@ -57,14 +57,14 @@ internal class Onma(context: MangaLoaderContext) : else -> null } } - val alt = doc.body().selectFirst(selectAlt)?.text() - val auth = doc.body().selectFirst(selectAut)?.text() + val alt = doc.body().selectFirst(selectAlt)?.textOrNull() + val auth = doc.body().selectFirst(selectAut)?.textOrNull() val tags = doc.body().selectFirst(selectTag)?.select("a") ?: emptySet() manga.copy( tags = tags.mapToSet { a -> MangaTag( key = a.attr("href").removeSuffix('/').substringAfterLast('/'), - title = a.text().toTitleCase(), + title = a.text().toTitleCase(sourceLocale), source = source, ) }, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/nepnep/NepnepParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/nepnep/NepnepParser.kt index 525e3e55e..b518dc121 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/nepnep/NepnepParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/nepnep/NepnepParser.kt @@ -184,7 +184,6 @@ internal abstract class NepnepParser( val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:SS", sourceLocale) return manga.copy( - altTitle = null, state = when (doc.selectFirstOrThrow(".list-group-item:contains(Status:) a").text()) { "Ongoing (Scan)", "Ongoing (Publish)", -> MangaState.ONGOING @@ -204,12 +203,12 @@ internal abstract class NepnepParser( tags = doc.select(".list-group-item:contains(Genre(s):) a").mapToSet { a -> MangaTag( key = a.attr("href").substringAfterLast('='), - title = a.text(), + title = a.text().toTitleCase(sourceLocale), source = source, ) }, - author = doc.select(".list-group-item:contains(Author(s):) a").text(), - description = doc.selectFirstOrThrow(".top-5.Content").text(), + author = doc.select(".list-group-item:contains(Author(s):) a").textOrNull(), + description = doc.selectFirstOrThrow(".top-5.Content").textOrNull(), chapters = chapter.mapJSONIndexed { i, j -> val indexChapter = j.getString("Chapter")!! 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 4b5d1e8cd..a82cb3850 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 @@ -159,8 +159,8 @@ internal abstract class OtakuSanctuaryParser( } } - val alt = doc.body().selectFirst(selectAlt)?.text()?.replace("Other names", "") - val auth = doc.body().selectFirst(selectAut)?.text() + val alt = doc.body().selectFirst(selectAlt)?.textOrNull()?.replace("Other names", "")?.nullIfEmpty() + val auth = doc.body().selectFirst(selectAut)?.textOrNull() val dateFormat = SimpleDateFormat(datePattern, sourceLocale) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/BrMangas.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/BrMangas.kt index 058edde14..f0122a50f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/BrMangas.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/BrMangas.kt @@ -122,8 +122,6 @@ internal class BrMangas(context: MangaLoaderContext) : PagedMangaParser(context, override suspend fun getDetails(manga: Manga): Manga { val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() return manga.copy( - altTitle = null, - state = null, tags = doc.select("div.serie-infos li:contains(Categorias:) a").mapToSet { a -> MangaTag( key = a.attr("href").removeSuffix('/').substringAfterLast('/'), @@ -132,7 +130,7 @@ internal class BrMangas(context: MangaLoaderContext) : PagedMangaParser(context, ) }, author = doc.select("div.serie-infos li:contains(Autor:)").text().replace("Autor:", "").nullIfEmpty(), - description = doc.select(".serie-texto p").text(), + description = doc.select(".serie-texto p").html(), contentRating = if (doc.select("div.serie-infos li:contains(Categorias:)").text().contains("Hentai")) { ContentRating.ADULT } else { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/YugenMangas.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/YugenMangas.kt index 37cf61134..c9c01d984 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/YugenMangas.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/YugenMangas.kt @@ -7,6 +7,7 @@ import org.koitharu.kotatsu.parsers.SinglePageMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* +import org.koitharu.kotatsu.parsers.util.json.getStringOrNull import org.koitharu.kotatsu.parsers.util.json.mapJSON import java.text.DateFormat import java.text.SimpleDateFormat @@ -105,9 +106,9 @@ internal class YugenMangas(context: MangaLoaderContext) : return manga.copy( description = detailManga.getString("synopsis"), coverUrl = detailManga.getString("cover"), - altTitle = detailManga.getString("alternative_names"), - author = detailManga.getString("author"), - state = detailManga.getString("status")?.let { + altTitle = detailManga.getStringOrNull("alternative_names"), + author = detailManga.getStringOrNull("author"), + state = detailManga.getStringOrNull("status")?.let { when (it) { "ongoing" -> MangaState.ONGOING "completed" -> MangaState.FINISHED diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt index f2ceaa01b..ab80425ca 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt @@ -145,7 +145,7 @@ internal abstract class LibSocialParser( } manga.copy( title = json.getStringOrNull("rus_name") ?: manga.title, - altTitle = json.getString("name"), + altTitle = json.getStringOrNull("name"), tags = tagsSetOf(tags, genres), author = json.getJSONArray("authors").optJSONObject(0)?.getStringOrNull("name"), description = json.getString("summary").nl2br(), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt index 887172c58..e2636664e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt @@ -146,9 +146,9 @@ internal abstract class ScanParser( ?: RATING_UNKNOWN, tags = tags, author = doc.selectFirst(".card-series-detail .col-6:contains(Autore) div, .card-series-about .mb-3:contains(Autore) a") - ?.text(), - altTitle = doc.selectFirst(".card div.col-12.mb-4 h2, .card-series-about .h6")?.text().orEmpty(), - description = doc.selectFirst(".card div.col-12.mb-4 p, .card-series-desc .mb-4 p")?.html().orEmpty(), + ?.textOrNull(), + altTitle = doc.selectFirst(".card div.col-12.mb-4 h2, .card-series-about .h6")?.textOrNull(), + description = doc.selectFirst(".card div.col-12.mb-4 p, .card-series-desc .mb-4 p")?.html(), chapters = doc.select(".chapters-list .col-chapter, .card-list-chapter .col-chapter") .mapChapters(reversed = true) { i, div -> val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/fr/MangaFr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/fr/MangaFr.kt index 021c440e9..c644882d1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/fr/MangaFr.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/fr/MangaFr.kt @@ -25,9 +25,9 @@ internal class MangaFr(context: MangaLoaderContext) : ?: RATING_UNKNOWN, tags = emptySet(), author = doc.selectFirst(".card-series-detail .col-6:contains(Autore) div, .card-series-about .mb-3:contains(Autore) a") - ?.text(), - altTitle = doc.selectFirst(".card div.col-12.mb-4 h2, .card-series-about .h6")?.text().orEmpty(), - description = doc.selectFirst(".card div.col-12.mb-4 p, .card-series-desc .mb-4 p")?.html().orEmpty(), + ?.textOrNull(), + altTitle = doc.selectFirst(".card div.col-12.mb-4 h2, .card-series-about .h6")?.textOrNull(), + description = doc.selectFirst(".card div.col-12.mb-4 p, .card-series-desc .mb-4 p")?.html(), chapters = doc.select(".chapters-list .col-chapter, .card-list-chapter .col-chapter") .mapChapters(reversed = true) { i, div -> val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt index 6f47278df..ee5c1522b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt @@ -27,9 +27,9 @@ internal class ScanIta(context: MangaLoaderContext) : rating = doc.selectFirst(".card-series-detail .rate-value span")?.ownText()?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN, tags = tags, - author = doc.selectFirst(".card-series-detail .col-6:contains(Autore) div")?.text(), - altTitle = doc.selectFirst(".card div.col-12.mb-4 h2")?.text().orEmpty(), - description = doc.selectFirst(".card div.col-12.mb-4 p")?.html().orEmpty(), + author = doc.selectFirst(".card-series-detail .col-6:contains(Autore) div")?.textOrNull(), + altTitle = doc.selectFirst(".card div.col-12.mb-4 h2")?.textOrNull(), + description = doc.selectFirst(".card div.col-12.mb-4 p")?.html(), chapters = chaptersDeferred.await(), ) } 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 70eecf663..ccb6d26a2 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 @@ -64,15 +64,14 @@ internal class SadScans(context: MangaLoaderContext) : SinglePageMangaParser(con val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() val dateFormat = SimpleDateFormat("dd MMM, yy", Locale.ENGLISH) return manga.copy( - altTitle = null, state = when (doc.select(".status span").last()?.text()) { "Devam ediyor" -> MangaState.ONGOING "Tamamlandı" -> MangaState.FINISHED else -> null }, tags = emptySet(), - author = doc.select(".author span").last()?.text(), - description = doc.selectFirstOrThrow(".summary").text(), + author = doc.selectLast(".author span")?.textOrNull(), + description = doc.selectFirstOrThrow(".summary").html(), chapters = doc.select(".chap-section .chap") .mapChapters(reversed = true) { i, div -> val a = div.selectFirstOrThrow("a") 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 2069e821a..08d7e4955 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 @@ -112,8 +112,9 @@ internal class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context val stateDoc = stateDocDeferred.await() manga.copy( altTitle = infoEl.selectFirst("span.info:contains(Tên Khác:)")?.parent()?.select("span:not(.info) > a") - ?.joinToString { it.text() }, - author = infoEl.select("p:contains(Tác giả:) a").text(), + ?.joinToString { it.text() } + ?.nullIfEmpty(), + author = infoEl.select("p:contains(Tác giả:) a").textOrNull(), description = infoEl.select("p:contains(Nội dung:) + p").html(), tags = tags, state = stateDoc.select("p:contains(Tình Trạng:) a").firstOrNull()?.text()?.let { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/SayHentai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/SayHentai.kt index bb718e638..cf9e52e0a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/SayHentai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/SayHentai.kt @@ -87,8 +87,8 @@ internal class SayHentai(context: MangaLoaderContext) : PagedMangaParser(context override suspend fun getDetails(manga: Manga): Manga { val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() return manga.copy( - altTitle = doc.selectFirst("h2.other-name")?.text(), - author = doc.selectFirst("div.summary-heading:contains(Tác giả) + div.summary-content")?.text(), + altTitle = doc.selectFirst("h2.other-name")?.textOrNull(), + author = doc.selectFirst("div.summary-heading:contains(Tác giả) + div.summary-content")?.textOrNull(), tags = doc.select("div.genres-content a[rel=tag]").mapToSet { a -> MangaTag( key = a.attr("href").substringAfterLast('/'), 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 374e2d8da..e36af2c45 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 @@ -4,8 +4,8 @@ import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey -import org.koitharu.kotatsu.parsers.network.UserAgents import org.koitharu.kotatsu.parsers.model.* +import org.koitharu.kotatsu.parsers.network.UserAgents import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* @@ -149,7 +149,7 @@ internal class TruyenGG(context: MangaLoaderContext) : PagedMangaParser(context, val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH) return manga.copy( - altTitle = doc.selectFirst("h2.other-name")?.text(), + altTitle = doc.selectFirst("h2.other-name")?.textOrNull(), author = doc.select("p:contains(Tác Giả) + p").joinToString { it.text() }.nullIfEmpty(), tags = doc.select("a.clblue").mapToSet { MangaTag( 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 94315a483..8063929ae 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 @@ -159,7 +159,7 @@ internal class TruyenQQ(context: MangaLoaderContext) : PagedMangaParser(context, 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(), + altTitle = doc.selectFirst("h2.other-name")?.textOrNull(), tags = doc.select("ul.list01 li").mapToSet { val key = it.attr("href").substringAfterLast("-").substringBeforeLast(".") MangaTag( 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 3465909f4..eba126d6c 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 @@ -119,10 +119,6 @@ internal abstract class VmpParser( source = source, ) }, - description = null, - altTitle = null, - author = null, - state = null, chapters = listOf( MangaChapter( id = manga.id, 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 bfa537488..ac6b9cd92 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 @@ -216,9 +216,9 @@ internal abstract class WpComicsParser( val tagsElement = doc.select("li.kind p.col-xs-8 a") val mangaTags = tagsElement.mapNotNullToSet { tagMap[it.text()] } manga.copy( - description = doc.selectFirst(selectDesc)?.html().orEmpty(), - altTitle = doc.selectFirst("h2.other-name")?.text().orEmpty(), - author = doc.body().select(selectAut).text(), + description = doc.selectFirst(selectDesc)?.html(), + altTitle = doc.selectFirst("h2.other-name")?.textOrNull(), + author = doc.body().select(selectAut).textOrNull(), state = doc.selectFirst(selectState)?.let { when (it.text()) { in ongoing -> MangaState.ONGOING diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/en/XoxoComics.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/en/XoxoComics.kt index c0174fb56..5ddf2c16f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/en/XoxoComics.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/en/XoxoComics.kt @@ -128,7 +128,7 @@ internal class XoxoComics(context: MangaLoaderContext) : else -> null } } - val aut = doc.body().select(selectAut).text() + val aut = doc.body().select(selectAut).textOrNull() manga.copy( tags = doc.body().select(selectTag).mapToSet { a -> MangaTag( @@ -138,7 +138,6 @@ internal class XoxoComics(context: MangaLoaderContext) : ) }, description = desc, - altTitle = null, author = aut, state = state, chapters = chaptersDeferred.await(), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/NetTruyen.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/NetTruyen.kt index 5cbcfbeb8..173e845b5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/NetTruyen.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/NetTruyen.kt @@ -1,29 +1,23 @@ package org.koitharu.kotatsu.parsers.site.wpcomics.vi -import androidx.collection.ArrayMap -import androidx.collection.ArraySet import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey +import org.koitharu.kotatsu.parsers.model.Manga import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaState +import org.koitharu.kotatsu.parsers.model.RATING_UNKNOWN import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser -import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* -import java.text.DateFormat -import java.text.SimpleDateFormat -import java.util.* @MangaSourceParser("NETTRUYEN", "NetTruyen", "vi") internal class NetTruyen(context: MangaLoaderContext) : WpComicsParser(context, MangaParserSource.NETTRUYEN, "nettruyenrr.com", 44) { - - override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("nettruyenrr.com", "nettruyenww.com", "nettruyenx.com") + + override val configKeyDomain: ConfigKey.Domain = + ConfigKey.Domain("nettruyenrr.com", "nettruyenww.com", "nettruyenx.com") override suspend fun getDetails(manga: Manga): Manga = coroutineScope { val fullUrl = manga.url.toAbsoluteUrl(domain) @@ -33,9 +27,9 @@ internal class NetTruyen(context: MangaLoaderContext) : val tagsElement = doc.select("li.kind p.col-xs-8 a") val mangaTags = tagsElement.mapNotNullToSet { tagMap[it.text()] } manga.copy( - description = doc.selectFirst(selectDesc)?.html().orEmpty(), - altTitle = doc.selectFirst("h2.other-name")?.text().orEmpty(), - author = doc.body().select(selectAut).text(), + description = doc.selectFirst(selectDesc)?.html(), + altTitle = doc.selectFirst("h2.other-name")?.textOrNull(), + author = doc.body().select(selectAut).textOrNull(), state = doc.selectFirst(selectState)?.let { when (it.text()) { in ongoing -> MangaState.ONGOING 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 438547dd9..a0d7aa07c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/util/Jsoup.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/util/Jsoup.kt @@ -129,6 +129,8 @@ public fun Element.selectLastOrThrow(cssQuery: String): Element = parseNotNull(s public fun Element.textOrNull(): String? = text().nullIfEmpty() +public fun Elements.textOrNull(): String? = text().nullIfEmpty() + public fun Element.ownTextOrNull(): String? = ownText().nullIfEmpty() public fun Element.selectFirstParent(query: String): Element? {