Remove redundant trim and mapNotNullToSet usage
This commit is contained in:
@@ -210,7 +210,7 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser(
|
|||||||
.requireElementById("mainer")
|
.requireElementById("mainer")
|
||||||
val details = root.selectFirstOrThrow(".detail-set")
|
val details = root.selectFirstOrThrow(".detail-set")
|
||||||
val attrs = details.selectFirst(".attr-main")?.select(".attr-item")?.associate {
|
val attrs = details.selectFirst(".attr-main")?.select(".attr-item")?.associate {
|
||||||
it.child(0).text().trim() to it.child(1)
|
it.child(0).text() to it.child(1)
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
title = root.selectFirst("h3.item-title")?.text() ?: manga.title,
|
title = root.selectFirst("h3.item-title")?.text() ?: manga.title,
|
||||||
@@ -227,7 +227,7 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser(
|
|||||||
"Hiatus" -> MangaState.PAUSED
|
"Hiatus" -> MangaState.PAUSED
|
||||||
else -> manga.state
|
else -> manga.state
|
||||||
},
|
},
|
||||||
author = attrs["Authors:"]?.text()?.trim() ?: manga.author,
|
author = attrs["Authors:"]?.textOrNull() ?: manga.author,
|
||||||
chapters = root.selectFirst(".episode-list")
|
chapters = root.selectFirst(".episode-list")
|
||||||
?.selectFirst(".main")
|
?.selectFirst(".main")
|
||||||
?.children()
|
?.children()
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ internal abstract class MangaFireParser(
|
|||||||
coverUrl = document.selectFirstOrThrow("div.manga-detail div.poster img")
|
coverUrl = document.selectFirstOrThrow("div.manga-detail div.poster img")
|
||||||
.attrAsAbsoluteUrl("src"),
|
.attrAsAbsoluteUrl("src"),
|
||||||
tags = document.select("div.meta a[href*=/genre/]").mapNotNullToSet {
|
tags = document.select("div.meta a[href*=/genre/]").mapNotNullToSet {
|
||||||
val tag = it.ownText().trim()
|
val tag = it.ownText()
|
||||||
if (tag == "Hentai" || tag == "Ecchi") {
|
if (tag == "Hentai" || tag == "Ecchi") {
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
@@ -189,7 +189,7 @@ internal abstract class MangaFireParser(
|
|||||||
},
|
},
|
||||||
isNsfw = isNsfw,
|
isNsfw = isNsfw,
|
||||||
state = document.selectFirst(".info > p")?.ownText()?.let {
|
state = document.selectFirst(".info > p")?.ownText()?.let {
|
||||||
when (it.lowercase().trim()) {
|
when (it.lowercase()) {
|
||||||
"releasing" -> MangaState.ONGOING
|
"releasing" -> MangaState.ONGOING
|
||||||
"completed" -> MangaState.FINISHED
|
"completed" -> MangaState.FINISHED
|
||||||
"discontinued" -> MangaState.ABANDONED
|
"discontinued" -> MangaState.ABANDONED
|
||||||
@@ -199,7 +199,7 @@ internal abstract class MangaFireParser(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
author = document.select("div.meta a[href*=/author/]")
|
author = document.select("div.meta a[href*=/author/]")
|
||||||
.joinToString { it.ownText().trim() },
|
.joinToString { it.ownText() },
|
||||||
description = document.selectFirstOrThrow("#synopsis div.modal-content").html(),
|
description = document.selectFirstOrThrow("#synopsis div.modal-content").html(),
|
||||||
chapters = getChapters(manga.url, document),
|
chapters = getChapters(manga.url, document),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ internal class MangaReaderToParser(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
document.select("div.f-genre-item").map {
|
document.select("div.f-genre-item").map {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
title = it.ownText().trim(),
|
title = it.ownText().toTitleCase(sourceLocale),
|
||||||
key = it.attr("data-id"),
|
key = it.attr("data-id"),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
@@ -176,7 +176,7 @@ internal class MangaReaderToParser(context: MangaLoaderContext) :
|
|||||||
?.text()?.toFloatOrNull()?.div(10) ?: RATING_UNKNOWN,
|
?.text()?.toFloatOrNull()?.div(10) ?: RATING_UNKNOWN,
|
||||||
coverUrl = document.selectFirst(".manga-poster > img")!!.attr("src"),
|
coverUrl = document.selectFirst(".manga-poster > img")!!.attr("src"),
|
||||||
tags = document.select("div.genres > a[href*=/genre/]").mapNotNullToSet {
|
tags = document.select("div.genres > a[href*=/genre/]").mapNotNullToSet {
|
||||||
val tag = it.ownText().trim()
|
val tag = it.ownText()
|
||||||
if (tag == "Hentai" || tag == "Ecchi") {
|
if (tag == "Hentai" || tag == "Ecchi") {
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ internal abstract class AnimeBootstrapParser(
|
|||||||
}
|
}
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('='),
|
key = a.attr("href").substringAfterLast('='),
|
||||||
title = a.text().toTitleCase().replace(",", ""),
|
title = a.text().toTitleCase().replace(",", ""),
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ internal class PapScan(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain$listUrl").parseHtml()
|
val doc = webClient.httpGet("https://$domain$listUrl").parseHtml()
|
||||||
return doc.select("a.category ").mapNotNullToSet { a ->
|
return doc.select("a.category ").mapToSet { a ->
|
||||||
val key = a.attr("href").substringAfterLast('=')
|
val key = a.attr("href").substringAfterLast('=')
|
||||||
val name = a.text()
|
val name = a.text()
|
||||||
MangaTag(
|
MangaTag(
|
||||||
@@ -103,7 +103,7 @@ internal class PapScan(context: MangaLoaderContext) :
|
|||||||
MangaState.ONGOING
|
MangaState.ONGOING
|
||||||
}
|
}
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ internal class FlixScans(context: MangaLoaderContext) : PagedMangaParser(context
|
|||||||
val doc = webClient.httpGet("https://$domain/search/advance").parseHtml()
|
val doc = webClient.httpGet("https://$domain/search/advance").parseHtml()
|
||||||
val json = JSONArray(doc.requireElementById("__NUXT_DATA__").data())
|
val json = JSONArray(doc.requireElementById("__NUXT_DATA__").data())
|
||||||
val tagsList = json.getJSONArray(3).toString().replace("[", "").replace("]", "").split(",")
|
val tagsList = json.getJSONArray(3).toString().replace("[", "").replace("]", "").split(",")
|
||||||
return tagsList.mapNotNullToSet { idTag ->
|
return tagsList.mapToSet { idTag ->
|
||||||
val id = idTag.toInt()
|
val id = idTag.toInt()
|
||||||
val idKey = json.getJSONObject(id).getInt("id")
|
val idKey = json.getJSONObject(id).getInt("id")
|
||||||
val key = json.getInt(idKey).toString()
|
val key = json.getInt(idKey).toString()
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
return manga.copy(
|
return manga.copy(
|
||||||
altTitle = null,
|
altTitle = null,
|
||||||
state = null,
|
state = null,
|
||||||
tags = root.select(".flex-wrap a").mapNotNullToSet { a ->
|
tags = root.select(".flex-wrap a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('/'),
|
key = a.attr("href").substringAfterLast('/'),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/series").parseHtml()
|
val doc = webClient.httpGet("https://$domain/series").parseHtml()
|
||||||
return doc.requireElementById("select_genre").select("option").mapNotNullToSet {
|
return doc.requireElementById("select_genre").select("option").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("value"),
|
key = it.attr("value"),
|
||||||
title = it.text().toTitleCase(sourceLocale),
|
title = it.text().toTitleCase(sourceLocale),
|
||||||
@@ -155,7 +155,7 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
"متوقف" -> MangaState.ABANDONED
|
"متوقف" -> MangaState.ABANDONED
|
||||||
else -> null
|
else -> null
|
||||||
},
|
},
|
||||||
tags = doc.select(".review-author-info a").mapNotNullToSet { a ->
|
tags = doc.select(".review-author-info a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast("="),
|
key = a.attr("href").substringAfterLast("="),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -126,9 +126,9 @@ internal abstract class CupFoxParser(
|
|||||||
return manga.copy(
|
return manga.copy(
|
||||||
altTitle = doc.selectFirst(selectMangaDetailsAltTitle)?.text()?.substringAfter(":"),
|
altTitle = doc.selectFirst(selectMangaDetailsAltTitle)?.text()?.substringAfter(":"),
|
||||||
state = null,
|
state = null,
|
||||||
tags = doc.select(selectMangaDetailsTags).mapNotNullToSet { a ->
|
tags = doc.select(selectMangaDetailsTags).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
@@ -198,9 +198,9 @@ internal abstract class CupFoxParser(
|
|||||||
protected open suspend fun fetchAvailableTags(): Set<MangaTag> {
|
protected open suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/category/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/category/").parseHtml()
|
||||||
return doc.select(selectAvailableTags)
|
return doc.select(selectAvailableTags)
|
||||||
.mapNotNullToSet { a ->
|
.mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ internal class BeeToon(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
||||||
return doc.requireElementById("menu-item-3").select("ul.sub-menu li a").mapNotNullToSet {
|
return doc.requireElementById("menu-item-3").select("ul.sub-menu li a").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = it.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = it.text(),
|
title = it.text(),
|
||||||
@@ -106,7 +106,7 @@ internal class BeeToon(context: MangaLoaderContext) :
|
|||||||
return manga.copy(
|
return manga.copy(
|
||||||
description = doc.getElementById("desc")?.text().orEmpty(),
|
description = doc.getElementById("desc")?.text().orEmpty(),
|
||||||
rating = doc.selectFirst(".counter")?.text()?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN,
|
rating = doc.selectFirst(".counter")?.text()?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN,
|
||||||
tags = doc.body().select(".info .genre a").mapNotNullToSet {
|
tags = doc.body().select(".info .genre a").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = it.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = it.text(),
|
title = it.text(),
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/popular-comic").parseHtml()
|
val doc = webClient.httpGet("https://$domain/popular-comic").parseHtml()
|
||||||
return doc.select("li.tag-item a").mapNotNullToSet { a ->
|
return doc.select("li.tag-item a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('/'),
|
key = a.attr("href").substringAfterLast('/'),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
@@ -133,9 +133,9 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex
|
|||||||
"Completed" -> MangaState.FINISHED
|
"Completed" -> MangaState.FINISHED
|
||||||
else -> null
|
else -> null
|
||||||
},
|
},
|
||||||
tags = doc.select("dt.movie-dt:contains(Genres:) + dd a").mapNotNullToSet { a ->
|
tags = doc.select("dt.movie-dt:contains(Genres:) + dd a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast("/"),
|
key = a.attr("href").substringAfterLast('/'),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ internal class DynastyScans(context: MangaLoaderContext) :
|
|||||||
rating = RATING_UNKNOWN,
|
rating = RATING_UNKNOWN,
|
||||||
isNsfw = false,
|
isNsfw = false,
|
||||||
coverUrl = "",
|
coverUrl = "",
|
||||||
tags = div.select("span.tags a").mapNotNullToSet { a ->
|
tags = div.select("span.tags a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -4,11 +4,7 @@ import kotlinx.coroutines.async
|
|||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import org.koitharu.kotatsu.parsers.Broken
|
import org.koitharu.kotatsu.parsers.*
|
||||||
import org.koitharu.kotatsu.parsers.ErrorMessages
|
|
||||||
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.config.ConfigKey
|
||||||
import org.koitharu.kotatsu.parsers.model.*
|
import org.koitharu.kotatsu.parsers.model.*
|
||||||
import org.koitharu.kotatsu.parsers.util.*
|
import org.koitharu.kotatsu.parsers.util.*
|
||||||
@@ -115,7 +111,7 @@ internal class FlixScansOrg(context: MangaLoaderContext) :
|
|||||||
val doc = webClient.httpGet("https://$domain/search/advance").parseHtml()
|
val doc = webClient.httpGet("https://$domain/search/advance").parseHtml()
|
||||||
val json = JSONArray(doc.requireElementById("__NUXT_DATA__").data())
|
val json = JSONArray(doc.requireElementById("__NUXT_DATA__").data())
|
||||||
val tagsList = json.getJSONArray(3).toString().replace("[", "").replace("]", "").split(",")
|
val tagsList = json.getJSONArray(3).toString().replace("[", "").replace("]", "").split(",")
|
||||||
return tagsList.mapNotNullToSet { idTag ->
|
return tagsList.mapToSet { idTag ->
|
||||||
val id = idTag.toInt()
|
val id = idTag.toInt()
|
||||||
val idKey = json.getJSONObject(id).getInt("id")
|
val idKey = json.getJSONObject(id).getInt("id")
|
||||||
val key = json.getInt(idKey).toString()
|
val key = json.getInt(idKey).toString()
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/browse-comics/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/browse-comics/").parseHtml()
|
||||||
return doc.selectFirstOrThrow("div.genre-select-i").select("label").mapNotNullToSet { label ->
|
return doc.selectFirstOrThrow("div.genre-select-i").select("label").mapToSet { label ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = label.selectFirstOrThrow("input").attr("value"),
|
key = label.selectFirstOrThrow("input").attr("value"),
|
||||||
title = label.text(),
|
title = label.text(),
|
||||||
@@ -115,9 +115,9 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context
|
|||||||
"Completed" -> MangaState.FINISHED
|
"Completed" -> MangaState.FINISHED
|
||||||
else -> null
|
else -> null
|
||||||
},
|
},
|
||||||
tags = doc.select(".categories ul li a").mapNotNullToSet { a ->
|
tags = doc.select(".categories ul li a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast("="),
|
key = a.attr("href").substringAfterLast('='),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ internal class MangaKawaiiEn(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/manga-list/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/manga-list/").parseHtml()
|
||||||
return doc.select("ul li a.category").mapNotNullToSet { a ->
|
return doc.select("ul li a.category").mapToSet { a ->
|
||||||
val name = a.text()
|
val name = a.text()
|
||||||
val key = name.lowercase().replace(" ", "-").replace("é", "e").replace("è", "e")
|
val key = name.lowercase().replace(" ", "-").replace("é", "e").replace("è", "e")
|
||||||
MangaTag(
|
MangaTag(
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ internal class MangaTownParser(context: MangaLoaderContext) :
|
|||||||
"completed" -> MangaState.FINISHED
|
"completed" -> MangaState.FINISHED
|
||||||
else -> null
|
else -> null
|
||||||
},
|
},
|
||||||
tags = li.selectFirst("p.keyWord")?.select("a")?.mapNotNullToSet tags@{ x ->
|
tags = li.selectFirst("p.keyWord")?.select("a")?.mapToSet tags@{ x ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
title = x.attr("title").toTitleCase(),
|
title = x.attr("title").toTitleCase(),
|
||||||
key = x.attr("href").substringAfter("/directory/0-").substringBefore("-0-"),
|
key = x.attr("href").substringAfter("/directory/0-").substringBefore("-0-"),
|
||||||
|
|||||||
@@ -119,8 +119,8 @@ internal class Mangaowl(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/10-genres").parseHtml()
|
val doc = webClient.httpGet("https://$domain/10-genres").parseHtml()
|
||||||
return doc.select("div.genres-container span.genre-item a").mapNotNullToSet { a ->
|
return doc.select("div.genres-container span.genre-item a").mapToSet { a ->
|
||||||
val key = a.attr("href").removeSuffix('/').substringAfterLast('/').substringBefore("-")
|
val key = a.attr("href").removeSuffix('/').substringAfterLast('/').substringBefore('-')
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = key,
|
key = key,
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
@@ -133,9 +133,9 @@ internal class Mangaowl(context: MangaLoaderContext) :
|
|||||||
val fullUrl = manga.url.toAbsoluteUrl(domain)
|
val fullUrl = manga.url.toAbsoluteUrl(domain)
|
||||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select("div.comic-attrs div.column.my-2:contains(Genres) a").mapNotNullToSet { a ->
|
tags = doc.body().select("div.comic-attrs div.column.my-2:contains(Genres) a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/').substringBefore("-"),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/').substringBefore('-'),
|
||||||
title = a.text().toTitleCase().replace(",", ""),
|
title = a.text().toTitleCase().replace(",", ""),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -99,9 +99,9 @@ internal class ManhwasMen(context: MangaLoaderContext) :
|
|||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val tags = webClient.httpGet("https://$domain/manga-list").parseHtml()
|
val tags = webClient.httpGet("https://$domain/manga-list").parseHtml()
|
||||||
.selectLastOrThrow(".filter-bx .form-group select.custom-select").select("option").drop(1)
|
.selectLastOrThrow(".filter-bx .form-group select.custom-select").select("option").drop(1)
|
||||||
return tags.mapNotNullToSet { option ->
|
return tags.mapToSet { option ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = option.attr("value").substringAfterLast("="),
|
key = option.attr("value").substringAfterLast('='),
|
||||||
title = option.text(),
|
title = option.text(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
@@ -112,7 +112,7 @@ internal class ManhwasMen(context: MangaLoaderContext) :
|
|||||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||||
val simpleDateFormat = SimpleDateFormat("dd/MM/yyyy", sourceLocale)
|
val simpleDateFormat = SimpleDateFormat("dd/MM/yyyy", sourceLocale)
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
tags = doc.body().select(".genres a").mapNotNullToSet { a ->
|
tags = doc.body().select(".genres a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('='),
|
key = a.attr("href").substringAfterLast('='),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ internal class Pururin(context: MangaLoaderContext) :
|
|||||||
manga.copy(
|
manga.copy(
|
||||||
description = doc.selectFirst("p.mb-2")?.text().orEmpty(),
|
description = doc.selectFirst("p.mb-2")?.text().orEmpty(),
|
||||||
rating = doc.selectFirst("td span.rating")?.attr("content")?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN,
|
rating = doc.selectFirst("td span.rating")?.attr("content")?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN,
|
||||||
tags = doc.body().select("tr:contains(Contents) ul.list-inline a").mapNotNullToSet {
|
tags = doc.body().select("tr:contains(Contents) ul.list-inline a").mapToSet {
|
||||||
val href = it.attr("href").substringAfterLast("content/").substringBeforeLast('/')
|
val href = it.attr("href").substringAfterLast("content/").substringBeforeLast('/')
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = href,
|
key = href,
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ internal class VyManga(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/search").parseHtml()
|
val doc = webClient.httpGet("https://$domain/search").parseHtml()
|
||||||
return doc.select("#advance-search .check-genre .d-flex").mapNotNullToSet {
|
return doc.select("#advance-search .check-genre .d-flex").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.selectFirstOrThrow(".checkbox-genre").attr("data-value"),
|
key = it.selectFirstOrThrow(".checkbox-genre").attr("data-value"),
|
||||||
title = it.selectFirstOrThrow("label").text(),
|
title = it.selectFirstOrThrow("label").text(),
|
||||||
@@ -133,7 +133,7 @@ internal class VyManga(context: MangaLoaderContext) :
|
|||||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||||
val simpleDateFormat = SimpleDateFormat("MMM dd, yyy", sourceLocale)
|
val simpleDateFormat = SimpleDateFormat("MMM dd, yyy", sourceLocale)
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
tags = doc.select("div.col-md-7 p a[href*=genre]").mapNotNullToSet { a ->
|
tags = doc.select("div.col-md-7 p a[href*=genre]").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('/'),
|
key = a.attr("href").substringAfterLast('/'),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -176,9 +176,9 @@ internal class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaPars
|
|||||||
val contents = doc.body().selectFirstOrThrow("section.element-header-content")
|
val contents = doc.body().selectFirstOrThrow("section.element-header-content")
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
description = contents.selectFirst("p.element-description")?.html(),
|
description = contents.selectFirst("p.element-description")?.html(),
|
||||||
tags = contents.select("h6 a").mapNotNullToSet { a ->
|
tags = contents.select("h6 a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringBefore("&").substringAfterLast("="),
|
key = a.attr("href").substringBefore('&').substringAfterLast('='),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
@@ -342,7 +342,7 @@ internal class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaPars
|
|||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/library", getRequestHeaders()).parseHtml()
|
val doc = webClient.httpGet("https://$domain/library", getRequestHeaders()).parseHtml()
|
||||||
val elements = doc.body().select("div#books-genders > div > div")
|
val elements = doc.body().select("div#books-genders > div > div")
|
||||||
return elements.mapNotNullToSet { element ->
|
return elements.mapToSet { element ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
title = element.select("label").text(),
|
title = element.select("label").text(),
|
||||||
key = element.select("input").attr("value"),
|
key = element.select("input").attr("value"),
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ internal abstract class FmreaderParser(
|
|||||||
|
|
||||||
protected open suspend fun fetchAvailableTags(): Set<MangaTag> {
|
protected open suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||||
return doc.select(selectBodyTag).mapNotNullToSet { a ->
|
return doc.select(selectBodyTag).mapToSet { a ->
|
||||||
val href = a.attr("href").substringAfter(tagPrefix).substringBeforeLast(".html")
|
val href = a.attr("href").substringAfter(tagPrefix).substringBeforeLast(".html")
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = href,
|
key = href,
|
||||||
@@ -192,7 +192,7 @@ internal abstract class FmreaderParser(
|
|||||||
val alt = doc.body().selectFirst(selectAlt)?.text()?.replace("Other names", "")
|
val alt = doc.body().selectFirst(selectAlt)?.text()?.replace("Other names", "")
|
||||||
val auth = doc.body().selectFirst(selectAut)?.text()
|
val auth = doc.body().selectFirst(selectAut)?.text()
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfter(tagPrefix).substringBeforeLast(".html"),
|
key = a.attr("href").substringAfter(tagPrefix).substringBeforeLast(".html"),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ internal class LegacyScansParser(context: MangaLoaderContext) :
|
|||||||
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.FRENCH)
|
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.FRENCH)
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
altTitle = null,
|
altTitle = null,
|
||||||
tags = root.select("div.serieGenre span").mapNotNullToSet { span ->
|
tags = root.select("div.serieGenre span").mapToSet { span ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = span.text(),
|
key = span.text(),
|
||||||
title = span.text(),
|
title = span.text(),
|
||||||
@@ -221,7 +221,7 @@ internal class LegacyScansParser(context: MangaLoaderContext) :
|
|||||||
val script = doc.requireElementById("__NUXT_DATA__").data()
|
val script = doc.requireElementById("__NUXT_DATA__").data()
|
||||||
.substringAfterLast("\"genres\"").substringBeforeLast("\"comics\"")
|
.substringAfterLast("\"genres\"").substringBeforeLast("\"comics\"")
|
||||||
.split("\",\"").drop(1)
|
.split("\",\"").drop(1)
|
||||||
return script.mapNotNullToSet { tag ->
|
return script.mapToSet { tag ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = tag.substringBeforeLast("\",{"),
|
key = tag.substringBeforeLast("\",{"),
|
||||||
title = tag.substringBeforeLast("\",{"),
|
title = tag.substringBeforeLast("\",{"),
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context,
|
|||||||
else -> null
|
else -> null
|
||||||
},
|
},
|
||||||
tags = root.select("ul.pmovie__list li:contains(Genre:)").text()
|
tags = root.select("ul.pmovie__list li:contains(Genre:)").text()
|
||||||
.replace("Genre:", "").split(" / ").mapNotNullToSet { tag ->
|
.replace("Genre:", "").split(" / ").mapToSet { tag ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = tag.lowercase(),
|
key = tag.lowercase(),
|
||||||
title = tag,
|
title = tag,
|
||||||
@@ -142,7 +142,7 @@ internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context,
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
||||||
return doc.select(".nav-menu li a").mapNotNullToSet { a ->
|
return doc.select(".nav-menu li a").mapToSet { a ->
|
||||||
val key = a.attr("href").removeSuffix('/').substringAfterLast("manga/", "")
|
val key = a.attr("href").removeSuffix('/').substringAfterLast("manga/", "")
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = key,
|
key = key,
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ internal class MangaKawaii(context: MangaLoaderContext) : PagedMangaParser(conte
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/manga-list/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/manga-list/").parseHtml()
|
||||||
return doc.select("ul li a.category").mapNotNullToSet { a ->
|
return doc.select("ul li a.category").mapToSet { a ->
|
||||||
val name = a.text()
|
val name = a.text()
|
||||||
val key = name.lowercase().replace(" ", "-").replace("é", "e").replace("è", "e")
|
val key = name.lowercase().replace(" ", "-").replace("é", "e").replace("è", "e")
|
||||||
MangaTag(
|
MangaTag(
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ internal class MangaMana(context: MangaLoaderContext) : PagedMangaParser(context
|
|||||||
isNsfw = isNsfw,
|
isNsfw = isNsfw,
|
||||||
coverUrl = img.orEmpty(),
|
coverUrl = img.orEmpty(),
|
||||||
description = div.selectFirst(".mangalist_item_description")?.text().orEmpty(),
|
description = div.selectFirst(".mangalist_item_description")?.text().orEmpty(),
|
||||||
tags = div.select("div.mb-1 a").mapNotNullToSet {
|
tags = div.select("div.mb-1 a").mapToSet {
|
||||||
val key = it.attr("href").substringAfterLast('=')
|
val key = it.attr("href").substringAfterLast('=')
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = key,
|
key = key,
|
||||||
@@ -246,7 +246,7 @@ internal class MangaMana(context: MangaLoaderContext) : PagedMangaParser(context
|
|||||||
author = doc.selectFirst("div.show_details span[itemprop=author]")?.text().orEmpty(),
|
author = doc.selectFirst("div.show_details span[itemprop=author]")?.text().orEmpty(),
|
||||||
description = doc.selectFirst("dd[itemprop=description]")?.text(),
|
description = doc.selectFirst("dd[itemprop=description]")?.text(),
|
||||||
rating = doc.getElementById("avgrating")?.ownText()?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN,
|
rating = doc.getElementById("avgrating")?.ownText()?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN,
|
||||||
tags = doc.select("ul.list-unstyled li a.category").mapNotNullToSet {
|
tags = doc.select("ul.list-unstyled li a.category").mapToSet {
|
||||||
val key = it.attr("href").substringAfterLast('=')
|
val key = it.attr("href").substringAfterLast('=')
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = key,
|
key = key,
|
||||||
@@ -333,7 +333,7 @@ internal class MangaMana(context: MangaLoaderContext) : PagedMangaParser(context
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/liste-mangas").parseHtml()
|
val doc = webClient.httpGet("https://$domain/liste-mangas").parseHtml()
|
||||||
return doc.select("select.selectpicker option").drop(1).mapNotNullToSet {
|
return doc.select("select.selectpicker option").drop(1).mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("value"),
|
key = it.attr("value"),
|
||||||
title = it.text(),
|
title = it.text(),
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ internal class ScansMangasMe(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/tous-nos-mangas/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/tous-nos-mangas/").parseHtml()
|
||||||
return doc.select("ul.genre li").mapNotNullToSet { li ->
|
return doc.select("ul.genre li").mapToSet { li ->
|
||||||
val key = li.selectFirstOrThrow("a").attr("href").removeSuffix('/').substringAfterLast('/')
|
val key = li.selectFirstOrThrow("a").attr("href").removeSuffix('/').substringAfterLast('/')
|
||||||
val name = li.selectFirstOrThrow("a").text()
|
val name = li.selectFirstOrThrow("a").text()
|
||||||
MangaTag(
|
MangaTag(
|
||||||
@@ -116,7 +116,7 @@ internal class ScansMangasMe(context: MangaLoaderContext) :
|
|||||||
val alt = doc.body().select("div.infox span.alter").text()
|
val alt = doc.body().select("div.infox span.alter").text()
|
||||||
val aut = doc.select("div.spe span")[2].text().replace("Auteur:", "")
|
val aut = doc.select("div.spe span")[2].text().replace("Auteur:", "")
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.select("div.spe span:contains(Genres) a").mapNotNullToSet { a ->
|
tags = doc.select("div.spe span:contains(Genres) a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ internal class ScantradUnion(context: MangaLoaderContext) :
|
|||||||
"Terminé", "Abondonné", "One Shot" -> MangaState.FINISHED
|
"Terminé", "Abondonné", "One Shot" -> MangaState.FINISHED
|
||||||
else -> null
|
else -> null
|
||||||
},
|
},
|
||||||
tags = root.select("div.project-details a[href*=tag]").mapNotNullToSet { a ->
|
tags = root.select("div.project-details a[href*=tag]").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ internal abstract class FuzzyDoodleParser(
|
|||||||
},
|
},
|
||||||
author = doc.selectFirst(selectAuthor)?.text().orEmpty(),
|
author = doc.selectFirst(selectAuthor)?.text().orEmpty(),
|
||||||
description = doc.select(selectDescription).text(),
|
description = doc.select(selectDescription).text(),
|
||||||
tags = doc.select(selectTagManga).mapNotNullToSet {
|
tags = doc.select(selectTagManga).mapToSet {
|
||||||
val key = it.attr("href").substringAfterLast('=')
|
val key = it.attr("href").substringAfterLast('=')
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = key,
|
key = key,
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ internal class NHentaiParser(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
private suspend fun fetchMangaTitle(url: String): String {
|
private suspend fun fetchMangaTitle(url: String): String {
|
||||||
val doc = webClient.httpGet(url).parseHtml()
|
val doc = webClient.httpGet(url).parseHtml()
|
||||||
return doc.selectFirstOrThrow("h1.title").text().trim()
|
return doc.selectFirstOrThrow("h1.title").text()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun parseMangaList(doc: Document): List<Manga> {
|
override fun parseMangaList(doc: Document): List<Manga> {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ internal class HentaiCrot(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.select("ul.megamenu li").mapNotNullToSet { li ->
|
return doc.select("ul.megamenu li").mapToSet { li ->
|
||||||
val key = li.selectFirstOrThrow("a").attr("href").removeSuffix('/').substringAfterLast('/')
|
val key = li.selectFirstOrThrow("a").attr("href").removeSuffix('/').substringAfterLast('/')
|
||||||
val name = li.selectFirstOrThrow("a").text()
|
val name = li.selectFirstOrThrow("a").text()
|
||||||
MangaTag(
|
MangaTag(
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ internal class PixHentai(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.select("ul.megamenu li").mapNotNullToSet { li ->
|
return doc.select("ul.megamenu li").mapToSet { li ->
|
||||||
val key = li.selectFirstOrThrow("a").attr("href").removeSuffix('/').substringAfterLast('/')
|
val key = li.selectFirstOrThrow("a").attr("href").removeSuffix('/').substringAfterLast('/')
|
||||||
val name = li.selectFirstOrThrow("a").text()
|
val name = li.selectFirstOrThrow("a").text()
|
||||||
MangaTag(
|
MangaTag(
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ internal class NicovideoSeigaParser(context: MangaLoaderContext) :
|
|||||||
tags = item.getElementsByAttributeValueContaining("href", "?category=").mapToSet { a ->
|
tags = item.getElementsByAttributeValueContaining("href", "?category=").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('='),
|
key = a.attr("href").substringAfterLast('='),
|
||||||
title = a.ownText().trim(),
|
title = a.ownText(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -187,7 +187,7 @@ internal class NicovideoSeigaParser(context: MangaLoaderContext) :
|
|||||||
url = href,
|
url = href,
|
||||||
publicUrl = href.toAbsoluteUrl(item.host ?: domain),
|
publicUrl = href.toAbsoluteUrl(item.host ?: domain),
|
||||||
title = item.selectFirst(".search_result__item__info > .search_result__item__info--title > a")
|
title = item.selectFirst(".search_result__item__info > .search_result__item__info--title > a")
|
||||||
?.text()?.trim() ?: return@mapNotNull null,
|
?.textOrNull() ?: return@mapNotNull null,
|
||||||
altTitle = null,
|
altTitle = null,
|
||||||
author = null,
|
author = null,
|
||||||
tags = emptySet(),
|
tags = emptySet(),
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ internal abstract class KeyoappParser(
|
|||||||
title = div.selectFirstOrThrow("h3").text().orEmpty(),
|
title = div.selectFirstOrThrow("h3").text().orEmpty(),
|
||||||
altTitle = null,
|
altTitle = null,
|
||||||
rating = RATING_UNKNOWN,
|
rating = RATING_UNKNOWN,
|
||||||
tags = div.select("div.gap-1 a").mapNotNullToSet { a ->
|
tags = div.select("div.gap-1 a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('='),
|
key = a.attr("href").substringAfterLast('='),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
@@ -169,7 +169,7 @@ internal abstract class KeyoappParser(
|
|||||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||||
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
|
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('='),
|
key = a.attr("href").substringAfterLast('='),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -127,9 +127,9 @@ internal abstract class LikeMangaParser(
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/genres/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/genres/").parseHtml()
|
||||||
return doc.select("ul.nav-genres li:not(.text-center) a").mapNotNullToSet { a ->
|
return doc.select("ul.nav-genres li:not(.text-center) a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
@@ -152,9 +152,9 @@ internal abstract class LikeMangaParser(
|
|||||||
return manga.copy(
|
return manga.copy(
|
||||||
altTitle = doc.selectFirstOrThrow(".list-info li.othername h2").text(),
|
altTitle = doc.selectFirstOrThrow(".list-info li.othername h2").text(),
|
||||||
state = null,
|
state = null,
|
||||||
tags = doc.select("li.kind a").mapNotNullToSet { a ->
|
tags = doc.select("li.kind a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -508,7 +508,7 @@ internal abstract class MadaraParser(
|
|||||||
val keySet = HashSet<String>(list.size)
|
val keySet = HashSet<String>(list.size)
|
||||||
return list.mapNotNullToSet { li ->
|
return list.mapNotNullToSet { li ->
|
||||||
val a = li.selectFirst("a") ?: return@mapNotNullToSet null
|
val a = li.selectFirst("a") ?: return@mapNotNullToSet null
|
||||||
val href = a.attr("href").removeSuffix("/").substringAfterLast(tagPrefix, "")
|
val href = a.attr("href").removeSuffix('/').substringAfterLast(tagPrefix, "")
|
||||||
if (href.isEmpty() || !keySet.add(href)) {
|
if (href.isEmpty() || !keySet.add(href)) {
|
||||||
return@mapNotNullToSet null
|
return@mapNotNullToSet null
|
||||||
}
|
}
|
||||||
@@ -560,12 +560,12 @@ internal abstract class MadaraParser(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val alt = doc.body().select(selectAlt).firstOrNull()?.tableValue()?.text()?.trim()
|
val alt = doc.body().select(selectAlt).firstOrNull()?.tableValue()?.textOrNull()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
url = href,
|
url = href,
|
||||||
publicUrl = href.toAbsoluteUrl(domain),
|
publicUrl = href.toAbsoluteUrl(domain),
|
||||||
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
|
tags = doc.body().select(selectGenre).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ internal class Manga18Fx(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = href,
|
key = href,
|
||||||
title = a.ownText().trim().ifEmpty {
|
title = a.ownText().ifEmpty {
|
||||||
a.selectFirst(".menu-image-title")?.text()?.trim() ?: return@mapNotNullToSet null
|
a.selectFirst(".menu-image-title")?.text() ?: return@mapNotNullToSet null
|
||||||
}.toTitleCase(),
|
}.toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -100,8 +100,8 @@ internal class Manhwa18Cc(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = href,
|
key = href,
|
||||||
title = a.ownText().trim().ifEmpty {
|
title = a.ownText().ifEmpty {
|
||||||
a.selectFirst(".menu-image-title")?.text()?.trim() ?: return@mapNotNullToSet null
|
a.selectFirst(".menu-image-title")?.text() ?: return@mapNotNullToSet null
|
||||||
}.toTitleCase(),
|
}.toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import org.koitharu.kotatsu.parsers.model.*
|
|||||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||||
import org.koitharu.kotatsu.parsers.util.*
|
import org.koitharu.kotatsu.parsers.util.*
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Base64
|
import java.util.*
|
||||||
|
|
||||||
@MangaSourceParser("ADULT_WEBTOON", "AdultWebtoon", "en", ContentType.HENTAI)
|
@MangaSourceParser("ADULT_WEBTOON", "AdultWebtoon", "en", ContentType.HENTAI)
|
||||||
internal class AdultWebtoon(context: MangaLoaderContext) :
|
internal class AdultWebtoon(context: MangaLoaderContext) :
|
||||||
@@ -106,11 +106,11 @@ internal class AdultWebtoon(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val alt =
|
val alt =
|
||||||
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
|
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()
|
||||||
?.trim()
|
?.textOrNull()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
|
tags = doc.body().select(selectGenre).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -100,13 +100,13 @@ internal class HentaiManga(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val alt =
|
val alt =
|
||||||
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
|
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()
|
||||||
?.trim()
|
?.textOrNull()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
|
tags = doc.body().select(selectGenre).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -100,13 +100,13 @@ internal class HentaiWebtoon(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val alt =
|
val alt =
|
||||||
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
|
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()
|
||||||
?.trim()
|
?.textOrNull()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
|
tags = doc.body().select(selectGenre).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ internal class IsekaiScan(context: MangaLoaderContext) :
|
|||||||
)
|
)
|
||||||
}.orEmpty(),
|
}.orEmpty(),
|
||||||
author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
|
author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
|
||||||
state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()?.trim()
|
state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()
|
||||||
?.lowercase()) {
|
?.lowercase()) {
|
||||||
"ongoing" -> MangaState.ONGOING
|
"ongoing" -> MangaState.ONGOING
|
||||||
"completed " -> MangaState.FINISHED
|
"completed " -> MangaState.FINISHED
|
||||||
|
|||||||
@@ -123,12 +123,13 @@ internal class MangaDass(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val alt =
|
val alt =
|
||||||
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
|
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()
|
||||||
?.trim() ?: doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content")
|
?.textOrNull()
|
||||||
.firstOrNull()?.tableValue()?.text()?.trim()
|
?: doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content")
|
||||||
|
.firstOrNull()?.tableValue()?.textOrNull()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
|
tags = doc.body().select(selectGenre).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -116,14 +116,15 @@ internal class MangaDna(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val alt =
|
val alt =
|
||||||
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
|
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()
|
||||||
?.trim() ?: doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content")
|
?.textOrNull()
|
||||||
.firstOrNull()?.tableValue()?.text()?.trim()
|
?: doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content")
|
||||||
|
.firstOrNull()?.tableValue()?.textOrNull()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
|
tags = doc.body().select(selectGenre).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ internal class MangaPure(context: MangaLoaderContext) :
|
|||||||
)
|
)
|
||||||
}.orEmpty(),
|
}.orEmpty(),
|
||||||
author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
|
author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
|
||||||
state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()?.trim()
|
state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()
|
||||||
?.lowercase()) {
|
?.lowercase()) {
|
||||||
"ongoing" -> MangaState.ONGOING
|
"ongoing" -> MangaState.ONGOING
|
||||||
"completed" -> MangaState.FINISHED
|
"completed" -> MangaState.FINISHED
|
||||||
|
|||||||
@@ -54,12 +54,13 @@ internal class ManhwaHentai(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val alt =
|
val alt =
|
||||||
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
|
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()
|
||||||
?.trim() ?: doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content")
|
?.textOrNull()
|
||||||
.firstOrNull()?.tableValue()?.text()?.trim()
|
?: doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content")
|
||||||
|
.firstOrNull()?.tableValue()?.textOrNull()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
|
tags = doc.body().select(selectGenre).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -103,11 +103,11 @@ internal class ManyToon(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val alt =
|
val alt =
|
||||||
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
|
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()
|
||||||
?.trim()
|
?.textOrNull()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
|
tags = doc.body().select(selectGenre).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -6,12 +6,7 @@ import org.jsoup.nodes.Document
|
|||||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||||
import org.koitharu.kotatsu.parsers.exception.ParseException
|
import org.koitharu.kotatsu.parsers.exception.ParseException
|
||||||
import org.koitharu.kotatsu.parsers.model.Manga
|
import org.koitharu.kotatsu.parsers.model.*
|
||||||
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.model.MangaState
|
|
||||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
|
||||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||||
import org.koitharu.kotatsu.parsers.util.*
|
import org.koitharu.kotatsu.parsers.util.*
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
@@ -26,9 +21,9 @@ internal class MangasNoSekai(context: MangaLoaderContext) :
|
|||||||
val body = doc.body()
|
val body = doc.body()
|
||||||
val chaptersDeferred = async { loadChapters(manga.url, doc) }
|
val chaptersDeferred = async { loadChapters(manga.url, doc) }
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select("#section-sinopsis a[href*=genre]").mapNotNullToSet { a ->
|
tags = doc.body().select("#section-sinopsis a[href*=genre]").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ internal class ManhwaHub(context: MangaLoaderContext) :
|
|||||||
val href = a.attr("href").removeSuffix("/").substringAfterLast(tagPrefix, "")
|
val href = a.attr("href").removeSuffix("/").substringAfterLast(tagPrefix, "")
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = href,
|
key = href,
|
||||||
title = a.ownText().trim().ifEmpty {
|
title = a.ownText().ifEmpty {
|
||||||
a.selectFirst(".menu-image-title")?.text()?.trim() ?: return@mapNotNullToSet null
|
a.selectFirst(".menu-image-title")?.text() ?: return@mapNotNullToSet null
|
||||||
}.toTitleCase(),
|
}.toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -139,14 +139,15 @@ internal class Saytruyenhay(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val alt =
|
val alt =
|
||||||
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
|
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()
|
||||||
?.trim() ?: doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content")
|
?.textOrNull()
|
||||||
.firstOrNull()?.tableValue()?.text()?.trim()
|
?: doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content")
|
||||||
|
.firstOrNull()?.tableValue()?.textOrNull()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
|
tags = doc.body().select(selectGenre).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ internal abstract class MadthemeParser(
|
|||||||
title = div.selectFirst("div.meta")?.selectFirst("div.title")?.text().orEmpty(),
|
title = div.selectFirst("div.meta")?.selectFirst("div.title")?.text().orEmpty(),
|
||||||
altTitle = null,
|
altTitle = null,
|
||||||
rating = div.selectFirst("div.meta span.score")?.ownText()?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN,
|
rating = div.selectFirst("div.meta span.score")?.ownText()?.toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN,
|
||||||
tags = doc.body().select("div.meta div.genres span").mapNotNullToSet { span ->
|
tags = doc.body().select("div.meta div.genres span").mapToSet { span ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = span.attr("class"),
|
key = span.attr("class"),
|
||||||
title = span.text().toTitleCase(),
|
title = span.text().toTitleCase(),
|
||||||
@@ -179,7 +179,7 @@ internal abstract class MadthemeParser(
|
|||||||
val nsfw = doc.getElementById("adt-warning") != null
|
val nsfw = doc.getElementById("adt-warning") != null
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase().replace(",", ""),
|
title = a.text().toTitleCase().replace(",", ""),
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ internal abstract class Manga18Parser(
|
|||||||
val alt = body.selectFirst(selectAlt)?.text().takeIf { it != "Updating" || it.isNotEmpty() }
|
val alt = body.selectFirst(selectAlt)?.text().takeIf { it != "Updating" || it.isNotEmpty() }
|
||||||
val author = body.selectFirst(selectAuthor)?.text().takeIf { it != "Updating" }
|
val author = body.selectFirst(selectAuthor)?.text().takeIf { it != "Updating" }
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ internal abstract class MangaboxParser(
|
|||||||
protected open suspend fun fetchAvailableTags(): Set<MangaTag> {
|
protected open suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||||
val tags = doc.select(selectTagMap).drop(1) // remove all tags
|
val tags = doc.select(selectTagMap).drop(1) // remove all tags
|
||||||
return tags.mapNotNullToSet { a ->
|
return tags.mapToSet { a ->
|
||||||
val key = a.attr("href").removeSuffix('/').substringAfterLast('/')
|
val key = a.attr("href").removeSuffix('/').substringAfterLast('/')
|
||||||
val name = a.attr("title").replace(" Manga", "")
|
val name = a.attr("title").replace(" Manga", "")
|
||||||
MangaTag(
|
MangaTag(
|
||||||
@@ -177,7 +177,7 @@ internal abstract class MangaboxParser(
|
|||||||
val alt = doc.body().select(selectAlt).text().replace("Alternative : ", "")
|
val alt = doc.body().select(selectAlt).text().replace("Alternative : ", "")
|
||||||
val aut = doc.body().select(selectAut).eachText().joinToString()
|
val aut = doc.body().select(selectAut).eachText().joinToString()
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast("category=").substringBefore("&"),
|
key = a.attr("href").substringAfterLast("category=").substringBefore("&"),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ internal class Mangairo(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/$listUrl/type-latest/ctg-all/state-all/page-1").parseHtml()
|
val doc = webClient.httpGet("https://$domain/$listUrl/type-latest/ctg-all/state-all/page-1").parseHtml()
|
||||||
return doc.select("div.panel_category a:not(.ctg_select)").mapNotNullToSet { a ->
|
return doc.select("div.panel_category a:not(.ctg_select)").mapToSet { a ->
|
||||||
val key = a.attr("href").substringAfterLast("ctg-").substringBefore("/")
|
val key = a.attr("href").substringAfterLast("ctg-").substringBefore("/")
|
||||||
val name = a.attr("title").replace("Category ", "")
|
val name = a.attr("title").replace("Category ", "")
|
||||||
MangaTag(
|
MangaTag(
|
||||||
@@ -139,7 +139,7 @@ internal class Mangairo(context: MangaLoaderContext) :
|
|||||||
val alt = doc.body().select(selectAlt).text().replace("Alternative : ", "")
|
val alt = doc.body().select(selectAlt).text().replace("Alternative : ", "")
|
||||||
val aut = doc.body().select(selectAut).eachText().joinToString()
|
val aut = doc.body().select(selectAut).eachText().joinToString()
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href")
|
key = a.attr("href")
|
||||||
.substringAfterLast("page-"), // Yes the site, it's crashing between page is tag id
|
.substringAfterLast("page-"), // Yes the site, it's crashing between page is tag id
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ internal class Mangakakalot(context: MangaLoaderContext) :
|
|||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||||
val tags = doc.select("ul.tag li a").drop(1)
|
val tags = doc.select("ul.tag li a").drop(1)
|
||||||
return tags.mapNotNullToSet { a ->
|
return tags.mapToSet { a ->
|
||||||
val key = a.attr("href").substringAfterLast("category=").substringBefore("&")
|
val key = a.attr("href").substringAfterLast("category=").substringBefore("&")
|
||||||
val name = a.attr("title").replace(" Manga", "")
|
val name = a.attr("title").replace(" Manga", "")
|
||||||
MangaTag(
|
MangaTag(
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ internal class MangakakalotTv(context: MangaLoaderContext) :
|
|||||||
val alt = doc.body().select(selectAlt).text().replace("Alternative : ", "")
|
val alt = doc.body().select(selectAlt).text().replace("Alternative : ", "")
|
||||||
val aut = doc.body().select(selectAut).eachText().joinToString()
|
val aut = doc.body().select(selectAut).eachText().joinToString()
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast("category=").substringBefore("&"),
|
key = a.attr("href").substringAfterLast("category=").substringBefore("&"),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
@@ -131,7 +131,7 @@ internal class MangakakalotTv(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||||
return doc.select(selectTagMap).mapNotNullToSet { a ->
|
return doc.select(selectTagMap).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast("category=").substringBefore("&"),
|
key = a.attr("href").substringAfterLast("category=").substringBefore("&"),
|
||||||
title = a.attr("title"),
|
title = a.attr("title"),
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ internal class TuManhwas(context: MangaLoaderContext) :
|
|||||||
state = mangaState,
|
state = mangaState,
|
||||||
author = null,
|
author = null,
|
||||||
isNsfw = manga.isNsfw || nsfw,
|
isNsfw = manga.isNsfw || nsfw,
|
||||||
tags = docs.select(".wd-full .mgen > a").mapNotNullToSet { a ->
|
tags = docs.select(".wd-full .mgen > a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('='),
|
key = a.attr("href").substringAfterLast('='),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ internal abstract class MangaWorldParser(
|
|||||||
return doc.select(".comics-grid .entry").map { div ->
|
return doc.select(".comics-grid .entry").map { div ->
|
||||||
val href = div.selectFirstOrThrow("a.thumb").attrAsRelativeUrl("href")
|
val href = div.selectFirstOrThrow("a.thumb").attrAsRelativeUrl("href")
|
||||||
val tags = div.select(".genres a[href*=/archive?genre=]")
|
val tags = div.select(".genres a[href*=/archive?genre=]")
|
||||||
.mapNotNullToSet { MangaTag(it.ownText().toTitleCase(sourceLocale), it.attr("href"), source) }
|
.mapToSet { MangaTag(it.ownText().toTitleCase(sourceLocale), it.attr("href"), source) }
|
||||||
Manga(
|
Manga(
|
||||||
id = generateUid(href),
|
id = generateUid(href),
|
||||||
url = href,
|
url = href,
|
||||||
@@ -155,13 +155,13 @@ internal abstract class MangaWorldParser(
|
|||||||
tags = tags,
|
tags = tags,
|
||||||
author = div.selectFirst(".author a")?.text(),
|
author = div.selectFirst(".author a")?.text(),
|
||||||
state =
|
state =
|
||||||
when (div.selectFirst(".status a")?.text()?.lowercase()) {
|
when (div.selectFirst(".status a")?.text()?.lowercase()) {
|
||||||
"in corso" -> MangaState.ONGOING
|
"in corso" -> MangaState.ONGOING
|
||||||
"finito" -> MangaState.FINISHED
|
"finito" -> MangaState.FINISHED
|
||||||
"droppato" -> MangaState.ABANDONED
|
"droppato" -> MangaState.ABANDONED
|
||||||
"in pausa" -> MangaState.PAUSED
|
"in pausa" -> MangaState.PAUSED
|
||||||
else -> null
|
else -> null
|
||||||
},
|
},
|
||||||
source = source,
|
source = source,
|
||||||
isNsfw = isNsfwSource,
|
isNsfw = isNsfwSource,
|
||||||
)
|
)
|
||||||
@@ -171,7 +171,7 @@ internal abstract class MangaWorldParser(
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
||||||
return doc.select("div[aria-labelledby=genresDropdown] a").mapNotNullToSet {
|
return doc.select("div[aria-labelledby=genresDropdown] a").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("href").substringAfterLast('='),
|
key = it.attr("href").substringAfterLast('='),
|
||||||
title = it.text().toTitleCase(sourceLocale),
|
title = it.text().toTitleCase(sourceLocale),
|
||||||
@@ -184,30 +184,30 @@ internal abstract class MangaWorldParser(
|
|||||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
altTitle =
|
altTitle =
|
||||||
doc.selectFirst(".meta-data .font-weight-bold:contains(Titoli alternativi:)")
|
doc.selectFirst(".meta-data .font-weight-bold:contains(Titoli alternativi:)")
|
||||||
?.parent()
|
?.parent()
|
||||||
?.ownText()
|
?.ownText()
|
||||||
?.substringAfter(": ")
|
?.substringAfter(": ")
|
||||||
?.trim(),
|
?.trim(),
|
||||||
description = doc.getElementById("noidungm")?.text().orEmpty(),
|
description = doc.getElementById("noidungm")?.text().orEmpty(),
|
||||||
chapters =
|
chapters =
|
||||||
doc.select(".chapters-wrapper .chapter a").mapChapters(reversed = true) { i, a ->
|
doc.select(".chapters-wrapper .chapter a").mapChapters(reversed = true) { i, a ->
|
||||||
val url = a.attrAsRelativeUrl("href").toAbsoluteUrl(domain)
|
val url = a.attrAsRelativeUrl("href").toAbsoluteUrl(domain)
|
||||||
MangaChapter(
|
MangaChapter(
|
||||||
id = generateUid(url),
|
id = generateUid(url),
|
||||||
name = a.selectFirst("span.d-inline-block")?.text() ?: "Chapter : ${i + 1f}",
|
name = a.selectFirst("span.d-inline-block")?.text() ?: "Chapter : ${i + 1f}",
|
||||||
number = i + 1f,
|
number = i + 1f,
|
||||||
volume = 0,
|
volume = 0,
|
||||||
url = "$url?style=list",
|
url = "$url?style=list",
|
||||||
scanlator = null,
|
scanlator = null,
|
||||||
uploadDate =
|
uploadDate =
|
||||||
SimpleDateFormat("dd MMMM yyyy", Locale.ITALIAN).tryParse(
|
SimpleDateFormat("dd MMMM yyyy", Locale.ITALIAN).tryParse(
|
||||||
a.selectFirst(".chap-date")?.text(),
|
a.selectFirst(".chap-date")?.text(),
|
||||||
),
|
),
|
||||||
branch = null,
|
branch = null,
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ internal abstract class MmrcmsParser(
|
|||||||
val auth = doc.body().selectFirst(selectAut)?.nextElementSibling()?.text()
|
val auth = doc.body().selectFirst(selectAut)?.nextElementSibling()?.text()
|
||||||
val tags = doc.body().selectFirst(selectTag)?.nextElementSibling()?.select("a") ?: emptySet()
|
val tags = doc.body().selectFirst(selectTag)?.nextElementSibling()?.select("a") ?: emptySet()
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = tags.mapNotNullToSet { a ->
|
tags = tags.mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ internal class Onma(context: MangaLoaderContext) :
|
|||||||
val auth = doc.body().selectFirst(selectAut)?.text()
|
val auth = doc.body().selectFirst(selectAut)?.text()
|
||||||
val tags = doc.body().selectFirst(selectTag)?.select("a") ?: emptySet()
|
val tags = doc.body().selectFirst(selectTag)?.select("a") ?: emptySet()
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = tags.mapNotNullToSet { a ->
|
tags = tags.mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ internal abstract class NepnepParser(
|
|||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
},
|
},
|
||||||
tags = doc.select(".list-group-item:contains(Genre(s):) a").mapNotNullToSet { a ->
|
tags = doc.select(".list-group-item:contains(Genre(s):) a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('='),
|
key = a.attr("href").substringAfterLast('='),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -127,8 +127,8 @@ internal abstract class OtakuSanctuaryParser(
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/Home/LoadingGenresMenu").parseHtml()
|
val doc = webClient.httpGet("https://$domain/Home/LoadingGenresMenu").parseHtml()
|
||||||
return doc.select(selectBodyTag).mapNotNullToSet { a ->
|
return doc.select(selectBodyTag).mapToSet { a ->
|
||||||
val href = a.attr("href").substringAfterLast("/").substringBefore("?")
|
val href = a.attr("href").substringAfterLast('/').substringBefore('?')
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = href,
|
key = href,
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
@@ -165,8 +165,8 @@ internal abstract class OtakuSanctuaryParser(
|
|||||||
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
|
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
val href = a.attr("href").substringAfterLast("/").substringBefore("?")
|
val href = a.attr("href").substringAfterLast('/').substringBefore('?')
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = href,
|
key = href,
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ internal class BrMangas(context: MangaLoaderContext) : PagedMangaParser(context,
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/lista-de-generos-de-manga/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/lista-de-generos-de-manga/").parseHtml()
|
||||||
return doc.select(".genres_page a").mapNotNullToSet { a ->
|
return doc.select(".genres_page a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
@@ -124,7 +124,7 @@ internal class BrMangas(context: MangaLoaderContext) : PagedMangaParser(context,
|
|||||||
return manga.copy(
|
return manga.copy(
|
||||||
altTitle = null,
|
altTitle = null,
|
||||||
state = null,
|
state = null,
|
||||||
tags = doc.select("div.serie-infos li:contains(Categorias:) a").mapNotNullToSet { a ->
|
tags = doc.select("div.serie-infos li:contains(Categorias:) a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -103,9 +103,9 @@ internal class LerManga(context: MangaLoaderContext) : PagedMangaParser(context,
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml().requireElementById("menu-header")
|
val doc = webClient.httpGet("https://$domain").parseHtml().requireElementById("menu-header")
|
||||||
return doc.select("#menu-item:contains(GÊNERO) ul li a").mapNotNullToSet { a ->
|
return doc.select("#menu-item:contains(GÊNERO) ul li a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast("/"),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
@@ -117,9 +117,9 @@ internal class LerManga(context: MangaLoaderContext) : PagedMangaParser(context,
|
|||||||
val dateFormat = SimpleDateFormat("dd-MM-yyyy", sourceLocale)
|
val dateFormat = SimpleDateFormat("dd-MM-yyyy", sourceLocale)
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
description = doc.selectFirstOrThrow("div.boxAnimeSobreLast p").html(),
|
description = doc.selectFirstOrThrow("div.boxAnimeSobreLast p").html(),
|
||||||
tags = doc.selectFirst("ul.genre-list")?.select("li a")?.mapNotNullToSet { a ->
|
tags = doc.selectFirst("ul.genre-list")?.select("li a")?.mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast("/"),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
source = source,
|
source = source,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ internal class LerMangaOnline(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/").parseHtml().requireElementById("sub-menu")
|
val doc = webClient.httpGet("https://$domain/").parseHtml().requireElementById("sub-menu")
|
||||||
return doc.select("ul.container li a").mapNotNullToSet { a ->
|
return doc.select("ul.container li a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removePrefix("/"),
|
key = a.attr("href").removePrefix("/"),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ internal class MangaOnline(context: MangaLoaderContext) : PagedMangaParser(conte
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/generos/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/generos/").parseHtml()
|
||||||
return doc.select(".wp-content p a").mapNotNullToSet { a ->
|
return doc.select(".wp-content p a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast("/", ""),
|
key = a.attr("href").removeSuffix("/").substringAfterLast("/", ""),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
@@ -98,7 +98,7 @@ internal class MangaOnline(context: MangaLoaderContext) : PagedMangaParser(conte
|
|||||||
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.ROOT)
|
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.ROOT)
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
description = doc.selectLast(".data p")?.html(),
|
description = doc.selectLast(".data p")?.html(),
|
||||||
tags = doc.selectFirst(".sgeneros")?.select("a")?.mapNotNullToSet { a ->
|
tags = doc.selectFirst(".sgeneros")?.select("a")?.mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast("/", ""),
|
key = a.attr("href").removeSuffix("/").substringAfterLast("/", ""),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ internal class MuitoHentai(context: MangaLoaderContext) : PagedMangaParser(conte
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/generos-dos-mangas/").parseHtml()
|
val doc = webClient.httpGet("https://$domain/generos-dos-mangas/").parseHtml()
|
||||||
return doc.select("div.content a.profileSideBar").mapNotNullToSet { a ->
|
return doc.select("div.content a.profileSideBar").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast("/"),
|
key = a.attr("href").removeSuffix("/").substringAfterLast("/"),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
@@ -92,7 +92,7 @@ internal class MuitoHentai(context: MangaLoaderContext) : PagedMangaParser(conte
|
|||||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
description = doc.selectFirstOrThrow(".backgroundpost:contains(Sinopse)").html(),
|
description = doc.selectFirstOrThrow(".backgroundpost:contains(Sinopse)").html(),
|
||||||
tags = doc.select("a.genero_btn").mapNotNullToSet { a ->
|
tags = doc.select("a.genero_btn").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast("/"),
|
key = a.attr("href").removeSuffix("/").substringAfterLast("/"),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -493,7 +493,7 @@ internal abstract class GroupleParser(
|
|||||||
?: throw ParseException("Genres filter element not found", url)
|
?: throw ParseException("Genres filter element not found", url)
|
||||||
val result = MutableScatterMap<String, String>(properties.size)
|
val result = MutableScatterMap<String, String>(properties.size)
|
||||||
properties.forEach { li ->
|
properties.forEach { li ->
|
||||||
val name = li.text().trim().lowercase()
|
val name = li.text().lowercase()
|
||||||
val id = li.selectFirstOrThrow("input").id()
|
val id = li.selectFirstOrThrow("input").id()
|
||||||
result[name] = id
|
result[name] = id
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ internal class YaoiChanParser(context: MangaLoaderContext) : ChanParser(context,
|
|||||||
val href = a.attrAsRelativeUrl("href")
|
val href = a.attrAsRelativeUrl("href")
|
||||||
MangaChapter(
|
MangaChapter(
|
||||||
id = generateUid(href),
|
id = generateUid(href),
|
||||||
name = a.text().trim(),
|
name = a.text(),
|
||||||
number = i + 1f,
|
number = i + 1f,
|
||||||
volume = 0,
|
volume = 0,
|
||||||
url = href,
|
url = href,
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ internal abstract class SinmhParser(
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||||
return doc.select(".filter-item:contains(按剧情) li a:not(.active)").mapNotNullToSet { a ->
|
return doc.select(".filter-item:contains(按剧情) li a:not(.active)").mapToSet { a ->
|
||||||
val href = a.attr("href").removeSuffix('/').substringAfterLast('/')
|
val href = a.attr("href").removeSuffix('/').substringAfterLast('/')
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = href,
|
key = href,
|
||||||
@@ -152,7 +152,7 @@ internal abstract class SinmhParser(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
|
tags = doc.body().select(selectGenre).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ internal class TrWebtoon(context: MangaLoaderContext) :
|
|||||||
val tags =
|
val tags =
|
||||||
webClient.httpGet("https://$domain/webtoon-listesi").parseHtml().requireElementById("collapseExample")
|
webClient.httpGet("https://$domain/webtoon-listesi").parseHtml().requireElementById("collapseExample")
|
||||||
.select(".pt-12 a").drop(1)
|
.select(".pt-12 a").drop(1)
|
||||||
return tags.mapNotNullToSet { a ->
|
return tags.mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast("genre=").substringBefore("&sort"),
|
key = a.attr("href").substringAfterLast("genre=").substringBefore("&sort"),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
@@ -162,7 +162,7 @@ internal class TrWebtoon(context: MangaLoaderContext) :
|
|||||||
override suspend fun getDetails(manga: Manga): Manga {
|
override suspend fun getDetails(manga: Manga): Manga {
|
||||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
tags = doc.body().select("li.movie__year a").mapNotNullToSet { a ->
|
tags = doc.body().select("li.movie__year a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast('='),
|
key = a.attr("href").substringAfterLast('='),
|
||||||
title = a.text(),
|
title = a.text(),
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ internal class BlogTruyenParser(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
val tagMap = availableTags().associateBy { it.title }
|
val tagMap = availableTags().associateBy { it.title }
|
||||||
val tags = descriptionElement.select("p > span.category").mapNotNullToSet {
|
val tags = descriptionElement.select("p > span.category").mapNotNullToSet {
|
||||||
val tagName = it.selectFirst("a")?.text()?.trim() ?: return@mapNotNullToSet null
|
val tagName = it.selectFirst("a")?.textOrNull() ?: return@mapNotNullToSet null
|
||||||
tagMap[tagName]
|
tagMap[tagName]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,8 +135,8 @@ internal class BlogTruyenVN(context: MangaLoaderContext) :
|
|||||||
val tagItems = doc.select("li[data-id]")
|
val tagItems = doc.select("li[data-id]")
|
||||||
val tagMap = ArrayMap<String, MangaTag>(tagItems.size)
|
val tagMap = ArrayMap<String, MangaTag>(tagItems.size)
|
||||||
for (tag in tagItems) {
|
for (tag in tagItems) {
|
||||||
val title = tag.text().trim()
|
val title = tag.text()
|
||||||
tagMap[tag.text().trim()] = MangaTag(
|
tagMap[title] = MangaTag(
|
||||||
title = title,
|
title = title,
|
||||||
key = tag.attr("data-id"),
|
key = tag.attr("data-id"),
|
||||||
source = source,
|
source = source,
|
||||||
@@ -173,7 +173,7 @@ internal class BlogTruyenVN(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
val tags = cacheTags.getOrNull()?.let { tagMap ->
|
val tags = cacheTags.getOrNull()?.let { tagMap ->
|
||||||
descriptionElement.select("p > span.category").mapNotNullToSet {
|
descriptionElement.select("p > span.category").mapNotNullToSet {
|
||||||
val tagName = it.selectFirst("a")?.text()?.trim() ?: return@mapNotNullToSet null
|
val tagName = it.selectFirst("a")?.textOrNull() ?: return@mapNotNullToSet null
|
||||||
tagMap[tagName]
|
tagMap[tagName]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,8 +122,8 @@ internal class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
rating = docs.selectFirst("div.page_like")?.let {
|
rating = docs.selectFirst("div.page_like")?.let {
|
||||||
val like = it.selectFirst("div.but_like")?.text()?.trim()?.toIntOrNull() ?: return@let null
|
val like = it.selectFirst("div.but_like")?.text()?.toIntOrNull() ?: return@let null
|
||||||
val dislike = it.selectFirst("div.but_unlike")?.text()?.trim()?.toIntOrNull() ?: return@let null
|
val dislike = it.selectFirst("div.but_unlike")?.text()?.toIntOrNull() ?: return@let null
|
||||||
when {
|
when {
|
||||||
like == 0 && dislike == 0 -> RATING_UNKNOWN
|
like == 0 && dislike == 0 -> RATING_UNKNOWN
|
||||||
else -> like.toFloat() / (like + dislike)
|
else -> like.toFloat() / (like + dislike)
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
|||||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||||
import org.koitharu.kotatsu.parsers.PagedMangaParser
|
import org.koitharu.kotatsu.parsers.PagedMangaParser
|
||||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
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.model.*
|
||||||
|
import org.koitharu.kotatsu.parsers.network.UserAgents
|
||||||
import org.koitharu.kotatsu.parsers.util.*
|
import org.koitharu.kotatsu.parsers.util.*
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -146,7 +146,7 @@ internal class TruyenQQ(context: MangaLoaderContext) : PagedMangaParser(context,
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/tim-kiem-nang-cao.html").parseHtml()
|
val doc = webClient.httpGet("https://$domain/tim-kiem-nang-cao.html").parseHtml()
|
||||||
return doc.select(".advsearch-form div.genre-item").mapNotNullToSet {
|
return doc.select(".advsearch-form div.genre-item").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.selectFirstOrThrow("span").attr("data-id"),
|
key = it.selectFirstOrThrow("span").attr("data-id"),
|
||||||
title = it.text(),
|
title = it.text(),
|
||||||
@@ -160,7 +160,7 @@ internal class TruyenQQ(context: MangaLoaderContext) : PagedMangaParser(context,
|
|||||||
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH)
|
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH)
|
||||||
return manga.copy(
|
return manga.copy(
|
||||||
altTitle = doc.selectFirst("h2.other-name")?.text(),
|
altTitle = doc.selectFirst("h2.other-name")?.text(),
|
||||||
tags = doc.select("ul.list01 li").mapNotNullToSet {
|
tags = doc.select("ul.list01 li").mapToSet {
|
||||||
val key = it.attr("href").substringAfterLast("-").substringBeforeLast(".")
|
val key = it.attr("href").substringAfterLast("-").substringBeforeLast(".")
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = key,
|
key = key,
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ internal abstract class VmpParser(
|
|||||||
|
|
||||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||||
return doc.select("div.tagcloud a").mapNotNullToSet { a ->
|
return doc.select("div.tagcloud a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast(geneUrl, ""),
|
key = a.attr("href").removeSuffix("/").substringAfterLast(geneUrl, ""),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
@@ -112,7 +112,7 @@ internal abstract class VmpParser(
|
|||||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.select("div.tax_box div.links ul:not(.post-categories) li a").mapNotNullToSet { a ->
|
tags = doc.select("div.tax_box div.links ul:not(.post-categories) li a").mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix("/").substringAfterLast(geneUrl, ""),
|
key = a.attr("href").removeSuffix("/").substringAfterLast(geneUrl, ""),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ internal class XoxoComics(context: MangaLoaderContext) :
|
|||||||
}
|
}
|
||||||
val aut = doc.body().select(selectAut).text()
|
val aut = doc.body().select(selectAut).text()
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ internal abstract class ZeistMangaParser(
|
|||||||
|
|
||||||
protected open suspend fun fetchAvailableTags(): Set<MangaTag> {
|
protected open suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.selectFirstOrThrow("div.filter").select("ul li").mapNotNullToSet {
|
return doc.selectFirstOrThrow("div.filter").select("ul li").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.selectFirstOrThrow("input").attr("value"),
|
key = it.selectFirstOrThrow("input").attr("value"),
|
||||||
title = it.selectFirstOrThrow("label").text().toTitleCase(sourceLocale),
|
title = it.selectFirstOrThrow("label").text().toTitleCase(sourceLocale),
|
||||||
@@ -225,7 +225,7 @@ internal abstract class ZeistMangaParser(
|
|||||||
val chaptersDeferred = async { loadChapters(manga.url, doc) }
|
val chaptersDeferred = async { loadChapters(manga.url, doc) }
|
||||||
manga.copy(
|
manga.copy(
|
||||||
author = author?.text(),
|
author = author?.text(),
|
||||||
tags = doc.select(selectTags).mapNotNullToSet { a ->
|
tags = doc.select(selectTags).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").substringAfterLast("label/").substringBefore("?"),
|
key = a.attr("href").substringAfterLast("label/").substringBefore("?"),
|
||||||
title = a.text().toTitleCase(),
|
title = a.text().toTitleCase(),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
||||||
import org.koitharu.kotatsu.parsers.util.domain
|
import org.koitharu.kotatsu.parsers.util.domain
|
||||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
import org.koitharu.kotatsu.parsers.util.mapToSet
|
||||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||||
import org.koitharu.kotatsu.parsers.util.requireElementById
|
import org.koitharu.kotatsu.parsers.util.requireElementById
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ internal class MangaAiLand(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.requireElementById("LinkList1").select("ul li a").mapNotNullToSet {
|
return doc.requireElementById("LinkList1").select("ul li a").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("href").substringBefore("?").substringAfterLast('/'),
|
key = it.attr("href").substringBefore("?").substringAfterLast('/'),
|
||||||
title = it.text(),
|
title = it.text(),
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ internal class MangaHub(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.requireElementById("Genre").select("div.items-center").mapNotNullToSet {
|
return doc.requireElementById("Genre").select("div.items-center").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.selectFirstOrThrow("input").attr("value"),
|
key = it.selectFirstOrThrow("input").attr("value"),
|
||||||
title = it.selectFirstOrThrow("label").text().substringBefore(')').toTitleCase(sourceLocale),
|
title = it.selectFirstOrThrow("label").text().substringBefore(')').toTitleCase(sourceLocale),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
||||||
import org.koitharu.kotatsu.parsers.util.domain
|
import org.koitharu.kotatsu.parsers.util.domain
|
||||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
import org.koitharu.kotatsu.parsers.util.mapToSet
|
||||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||||
import org.koitharu.kotatsu.parsers.util.requireElementById
|
import org.koitharu.kotatsu.parsers.util.requireElementById
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ internal class KlManhua(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.requireElementById("LinkList1").select("ul li a").mapNotNullToSet {
|
return doc.requireElementById("LinkList1").select("ul li a").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("href").substringBefore("?").substringAfterLast('/'),
|
key = it.attr("href").substringBefore("?").substringAfterLast('/'),
|
||||||
title = it.text(),
|
title = it.text(),
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ internal class Mikoroku(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.requireElementById("Genre").select("div.items-center").mapNotNullToSet {
|
return doc.requireElementById("Genre").select("div.items-center").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.selectFirstOrThrow("input").attr("value"),
|
key = it.selectFirstOrThrow("input").attr("value"),
|
||||||
title = it.selectFirstOrThrow("label").text().substringBefore('('),
|
title = it.selectFirstOrThrow("label").text().substringBefore('('),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
||||||
import org.koitharu.kotatsu.parsers.util.domain
|
import org.koitharu.kotatsu.parsers.util.domain
|
||||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
import org.koitharu.kotatsu.parsers.util.mapToSet
|
||||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||||
|
|
||||||
@MangaSourceParser("SHIYURASUB", "ShiyuraSub", "id")
|
@MangaSourceParser("SHIYURASUB", "ShiyuraSub", "id")
|
||||||
@@ -17,7 +17,7 @@ internal class ShiyuraSub(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.select("div.list-label-widget-content ul li a").mapNotNullToSet {
|
return doc.select("div.list-label-widget-content ul li a").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = it.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||||
title = it.html().substringBefore("<span"),
|
title = it.html().substringBefore("<span"),
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ internal class ToonCubus(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/p/genre-list.html").parseHtml()
|
val doc = webClient.httpGet("https://$domain/p/genre-list.html").parseHtml()
|
||||||
return doc.select(".dzdes-genre ul li a").mapNotNullToSet {
|
return doc.select(".dzdes-genre ul li a").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("href").removeSuffix("/").substringAfterLast("/"),
|
key = it.attr("href").removeSuffix("/").substringAfterLast("/"),
|
||||||
title = it.selectFirstOrThrow("span").text(),
|
title = it.selectFirstOrThrow("span").text(),
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ internal class AnimeXNovel(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.requireElementById("LinkList1").select("ul li a").mapNotNullToSet {
|
return doc.requireElementById("LinkList1").select("ul li a").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("href").removeSuffix("/").substringAfterLast('/'),
|
key = it.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||||
title = it.text(),
|
title = it.text(),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
||||||
import org.koitharu.kotatsu.parsers.util.domain
|
import org.koitharu.kotatsu.parsers.util.domain
|
||||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
import org.koitharu.kotatsu.parsers.util.mapToSet
|
||||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||||
import org.koitharu.kotatsu.parsers.util.requireElementById
|
import org.koitharu.kotatsu.parsers.util.requireElementById
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ internal class GuildaTierDraw(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.requireElementById("LinkList2").select("ul li a").mapNotNullToSet {
|
return doc.requireElementById("LinkList2").select("ul li a").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("href").substringBefore("?").substringAfterLast('/'),
|
key = it.attr("href").substringBefore("?").substringAfterLast('/'),
|
||||||
title = it.text(),
|
title = it.text(),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
||||||
import org.koitharu.kotatsu.parsers.util.domain
|
import org.koitharu.kotatsu.parsers.util.domain
|
||||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
import org.koitharu.kotatsu.parsers.util.mapToSet
|
||||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||||
import org.koitharu.kotatsu.parsers.util.requireElementById
|
import org.koitharu.kotatsu.parsers.util.requireElementById
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ internal class EpikMan(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
return doc.requireElementById("LinkList1").select("ul li a").mapNotNullToSet {
|
return doc.requireElementById("LinkList1").select("ul li a").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.attr("href").substringBefore("?").substringAfterLast('/'),
|
key = it.attr("href").substringBefore("?").substringAfterLast('/'),
|
||||||
title = it.text(),
|
title = it.text(),
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
||||||
import org.koitharu.kotatsu.parsers.util.domain
|
import org.koitharu.kotatsu.parsers.util.domain
|
||||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
import org.koitharu.kotatsu.parsers.util.mapToSet
|
||||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||||
import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow
|
import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ internal class Mikrokosmosfb(context: MangaLoaderContext) :
|
|||||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||||
val tags = doc.selectFirstOrThrow("script:containsData(label: )").data()
|
val tags = doc.selectFirstOrThrow("script:containsData(label: )").data()
|
||||||
.substringAfter("label: [").substringBefore("]").replace("\"", "").split(", ")
|
.substringAfter("label: [").substringBefore("]").replace("\"", "").split(", ")
|
||||||
return tags.mapNotNullToSet {
|
return tags.mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it,
|
key = it,
|
||||||
title = it,
|
title = it,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
|||||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||||
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
||||||
import org.koitharu.kotatsu.parsers.util.domain
|
import org.koitharu.kotatsu.parsers.util.domain
|
||||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
import org.koitharu.kotatsu.parsers.util.mapToSet
|
||||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||||
import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow
|
import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ internal class SnscoeurTurkey(context: MangaLoaderContext) :
|
|||||||
|
|
||||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||||
val doc = webClient.httpGet("https://$domain/p/gelismis-arama.html").parseHtml()
|
val doc = webClient.httpGet("https://$domain/p/gelismis-arama.html").parseHtml()
|
||||||
return doc.selectFirstOrThrow("div.filter").select("ul li").mapNotNullToSet {
|
return doc.selectFirstOrThrow("div.filter").select("ul li").mapToSet {
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = it.selectFirstOrThrow("input").attr("value"),
|
key = it.selectFirstOrThrow("input").attr("value"),
|
||||||
title = it.selectFirstOrThrow("label").text(),
|
title = it.selectFirstOrThrow("label").text(),
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ internal abstract class ZMangaParser(
|
|||||||
altTitle = null,
|
altTitle = null,
|
||||||
rating = div.selectFirstOrThrow("div.info div.score").ownText().toFloatOrNull()?.div(10f)
|
rating = div.selectFirstOrThrow("div.info div.score").ownText().toFloatOrNull()?.div(10f)
|
||||||
?: RATING_UNKNOWN,
|
?: RATING_UNKNOWN,
|
||||||
tags = doc.body().select("div.genres a").mapNotNullToSet { span ->
|
tags = doc.body().select("div.genres a").mapToSet { span ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = span.attr("class"),
|
key = span.attr("class"),
|
||||||
title = span.text().toTitleCase(),
|
title = span.text().toTitleCase(),
|
||||||
@@ -225,7 +225,7 @@ internal abstract class ZMangaParser(
|
|||||||
val aut = doc.body().select(selectAut).text()
|
val aut = doc.body().select(selectAut).text()
|
||||||
|
|
||||||
manga.copy(
|
manga.copy(
|
||||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
tags = doc.body().select(selectTag).mapToSet { a ->
|
||||||
MangaTag(
|
MangaTag(
|
||||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||||
title = a.text().toTitleCase().replace(",", ""),
|
title = a.text().toTitleCase().replace(",", ""),
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public inline fun <T, R> Collection<T>.mapToSet(transform: (T) -> R): Set<R> {
|
|||||||
return mapTo(ArraySet(size), transform)
|
return mapTo(ArraySet(size), transform)
|
||||||
}
|
}
|
||||||
|
|
||||||
public inline fun <T, R> Collection<T>.mapNotNullToSet(transform: (T) -> R?): Set<R> {
|
public inline fun <T, R : Any> Collection<T>.mapNotNullToSet(transform: (T) -> R?): Set<R> {
|
||||||
val destination = ArraySet<R>(size)
|
val destination = ArraySet<R>(size)
|
||||||
for (item in this) {
|
for (item in this) {
|
||||||
destination.add(transform(item) ?: continue)
|
destination.add(transform(item) ?: continue)
|
||||||
|
|||||||
Reference in New Issue
Block a user