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 2eece60e..f8892de1 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 @@ -75,7 +75,7 @@ internal class BentomangaParser(context: MangaLoaderContext) : PagedMangaParser( ?.div(10f) ?: RATING_UNKNOWN, isNsfw = div.selectFirst(".badge-adult_content") != null, - coverUrl = div.selectFirstOrThrow("img").src(), + coverUrl = div.selectFirstOrThrow("img").src().assertNotNull("src").orEmpty(), tags = div.selectFirst(".component-manga-categories") .assertNotNull("tags") ?.select("a") @@ -223,14 +223,4 @@ internal class BentomangaParser(context: MangaLoaderContext) : PagedMangaParser( calendar.add(calendarUnit, -count) return calendar.timeInMillis } - - private fun Element.src(): String { - return attrAsAbsoluteUrlOrNull("data-cfsrc") - ?: attrAsAbsoluteUrlOrNull("src") - ?: attrAsAbsoluteUrlOrNull("data-src") - ?: run { - assert(false) { "Image src not found" } - "" - } - } } 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 3e82266a..d7bd6971 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 @@ -540,13 +540,6 @@ internal abstract class MadaraParser( } } - protected fun Element.src(): String? { - var result = absUrl("data-src") - if (result.isEmpty()) result = absUrl("data-cfsrc") - if (result.isEmpty()) result = absUrl("src") - return result.ifEmpty { null } - } - private companion object { private fun createRequestTemplate() = 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 cc17baa0..29b37941 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 @@ -204,13 +204,4 @@ internal abstract class Manga18Parser( ) } } - - - protected fun Element.src(): String? { - var result = absUrl("data-src") - if (result.isEmpty()) result = absUrl("data-cfsrc") - if (result.isEmpty()) result = absUrl("src") - return result.ifEmpty { null } - } - } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt index fe77fddc..1186eb14 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt @@ -1,23 +1,11 @@ -package org.koitharu.kotatsu.parsers.site.madara.en +package org.koitharu.kotatsu.parsers.site.manga18.en import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.ContentType -import org.koitharu.kotatsu.parsers.model.Manga -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.model.MangaTag -import org.koitharu.kotatsu.parsers.model.RATING_UNKNOWN -import org.koitharu.kotatsu.parsers.model.SortOrder +import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.site.manga18.Manga18Parser -import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrl -import org.koitharu.kotatsu.parsers.util.domain -import org.koitharu.kotatsu.parsers.util.generateUid -import org.koitharu.kotatsu.parsers.util.host -import org.koitharu.kotatsu.parsers.util.parseHtml -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow -import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl -import org.koitharu.kotatsu.parsers.util.urlEncoded +import org.koitharu.kotatsu.parsers.util.* @MangaSourceParser("HENTAI3ZCC", "Hentai3z Cc", "en", ContentType.HENTAI) 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 10b5e6f8..97a37650 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 @@ -27,11 +27,4 @@ internal class LelManga(context: MangaLoaderContext) : ) } } - - private fun Element.src(): String? { - var result = absUrl("data-src") - if (result.isEmpty()) result = absUrl("data-cfsrc") - if (result.isEmpty()) result = absUrl("src") - return result.ifEmpty { null } - } } 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 37948641..d5334049 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 @@ -3,7 +3,6 @@ package org.koitharu.kotatsu.parsers.site.mmrcms import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import org.jsoup.nodes.Document -import org.jsoup.nodes.Element import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey @@ -248,13 +247,4 @@ internal abstract class MmrcmsParser( ) } } - - - protected fun Element.src(): String? { - var result = absUrl("data-src") - if (result.isEmpty()) result = absUrl("data-cfsrc") - if (result.isEmpty()) result = absUrl("src") - return result.ifEmpty { null } - } - } 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 a155fb62..acd3f771 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/util/Jsoup.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/util/Jsoup.kt @@ -23,7 +23,7 @@ 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 */ -fun Element.attrOrNull(attributeKey: String) = attr(attributeKey).takeUnless { it.isEmpty() } +fun Element.attrOrNull(attributeKey: String) = attr(attributeKey).takeUnless { it.isBlank() }?.trim() /** @@ -43,7 +43,7 @@ fun Element.attrOrThrow(attributeKey: String): String = if (hasAttr(attributeKey * @see attrAsAbsoluteUrl */ fun Element.attrAsRelativeUrlOrNull(attributeKey: String): String? { - val attr = attr(attributeKey).trim() + val attr = attrOrNull(attributeKey) ?: return null if (attr.isEmpty() || attr.startsWith("data:")) { return null } @@ -74,7 +74,7 @@ fun Element.attrAsRelativeUrl(attributeKey: String): String { * @see attrAsRelativeUrlOrNull */ fun Element.attrAsAbsoluteUrlOrNull(attributeKey: String): String? { - val attr = attr(attributeKey).trim() + val attr = attrOrNull(attributeKey) ?: return null if (attr.isEmpty() || attr.startsWith("data:")) { return null } @@ -140,3 +140,27 @@ fun Element.selectFirstParent(query: String): Element? { selector.matches(root, it) } } + +/** + * Return a first non-empty attribute value of [names] or null if it is missing or empty + */ +fun Element.attrOrNull(vararg names: String): String? { + for (name in names) { + val value = attr(name) + if (value.isNotEmpty()) { + return value.trim() + } + } + return null +} + +@JvmOverloads +fun Element.src(names: Array = arrayOf("data-src", "data-cfsrc", "src")): String? { + for (name in names) { + val value = attrAsAbsoluteUrlOrNull(name) + if (value != null) { + return value + } + } + return null +}