Koitharu 1 year ago
parent 9baba17692
commit 9ec62f0be0
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -1,10 +1,15 @@
package org.koitharu.kotatsu.parsers.site.mangareader.id package org.koitharu.kotatsu.parsers.site.mangareader.id
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import org.jsoup.nodes.Element
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.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.model.MangaParserSource
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.*
@MangaSourceParser("MANHWAINDO", "ManhwaIndo", "id") @MangaSourceParser("MANHWAINDO", "ManhwaIndo", "id")
@ -16,23 +21,26 @@ internal class ManhwaIndoParser(context: MangaLoaderContext) :
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> { override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val chapterUrl = chapter.url.toAbsoluteUrl(domain) val chapterUrl = chapter.url.toAbsoluteUrl(domain)
val docs = webClient.httpGet(chapterUrl).parseHtml() val docs = webClient.httpGet(chapterUrl).parseHtml()
return docs.select(selectPage).mapNotNull { img -> return coroutineScope {
val url = img.attr("data-src").takeIf { it.isNotBlank() }?.toRelativeUrl(domain) ?: return@mapNotNull null docs.select(selectPage).map { img ->
try { async { fetchPage(img) }
val response = webClient.httpHead(url) }.awaitAll().filterNotNull()
if (response.headers["Content-Type"]?.startsWith("image/") == true) { }
MangaPage( }
id = generateUid(url),
url = url, private suspend fun fetchPage(img: Element): MangaPage? = runCatchingCancellable {
preview = null, val url = img.attrAsRelativeUrlOrNull("data-src") ?: return@runCatchingCancellable null
source = source, webClient.httpHead(url).use { response ->
) if (response.mimeType?.startsWith("image/") == true) {
} else { MangaPage(
null id = generateUid(url),
} url = url,
} catch (e: Exception) { preview = null,
source = source,
)
} else {
null null
} }
} }
} }.getOrNull()
} }

@ -10,7 +10,11 @@ import java.text.SimpleDateFormat
import java.util.* import java.util.*
@MangaSourceParser("TRUYENTRANH3Q", "TruyenTranh3Q", "vi") @MangaSourceParser("TRUYENTRANH3Q", "TruyenTranh3Q", "vi")
internal class TruyenTranh3Q(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.TRUYENTRANH3Q, 42) { internal class TruyenTranh3Q(context: MangaLoaderContext) :
PagedMangaParser(context, MangaParserSource.TRUYENTRANH3Q, 42) {
private val relativeTimePattern = Regex("(\\d+)\\s*(phút|giờ|ngày|tuần) trước")
private val absoluteTimePattern = Regex("(\\d{2}-\\d{2}-\\d{4})")
override val configKeyDomain = ConfigKey.Domain("truyentranh3q.com") override val configKeyDomain = ConfigKey.Domain("truyentranh3q.com")
@ -45,9 +49,9 @@ internal class TruyenTranh3Q(context: MangaLoaderContext) : PagedMangaParser(con
append("https://") append("https://")
append(domain) append(domain)
append("/tim-kiem-nang-cao") append("/tim-kiem-nang-cao")
append("?") append("?")
if (page > 1) { if (page > 1) {
append("page=") append("page=")
append(page) append(page)
@ -68,38 +72,28 @@ internal class TruyenTranh3Q(context: MangaLoaderContext) : PagedMangaParser(con
SortOrder.POPULARITY -> "2" SortOrder.POPULARITY -> "2"
SortOrder.RATING -> "6" SortOrder.RATING -> "6"
else -> "0" else -> "0"
} },
) )
append("&status=") append("&status=")
if (filter.states.isNotEmpty()) { append(
filter.states.oneOrThrowIfMany()?.let { when (filter.states.oneOrThrowIfMany()) {
append( MangaState.ONGOING -> "1"
when (it) { MangaState.FINISHED -> "2"
MangaState.ONGOING -> "1" else -> "0"
MangaState.FINISHED -> "2" },
else -> "0" )
}
)
}
} else {
append("0")
}
append("&country=") append("&country=")
if (filter.types.isNotEmpty()) { append(
filter.types.oneOrThrowIfMany()?.let { when (filter.types.oneOrThrowIfMany()) {
append( ContentType.MANGA -> "manga"
when (it) { ContentType.MANHWA -> "manhwa"
ContentType.MANGA -> "manga" ContentType.MANHUA -> "manhua"
ContentType.MANHWA -> "manhwa" ContentType.OTHER -> "other"
ContentType.MANHUA -> "manhua" else -> "all"
ContentType.OTHER -> "other" },
else -> "all" )
}
)
}
} else append("all")
if (filter.tags.isNotEmpty()) { if (filter.tags.isNotEmpty()) {
append("&categories=") append("&categories=")
@ -112,25 +106,26 @@ internal class TruyenTranh3Q(context: MangaLoaderContext) : PagedMangaParser(con
val nsfwTags = setOf("18+", "Adult", "Ecchi", "16+", "NTR", "Smut") val nsfwTags = setOf("18+", "Adult", "Ecchi", "16+", "NTR", "Smut")
return doc.select("ul.list_grid.grid > li").map { element -> return doc.select("ul.list_grid.grid > li").map { element ->
val aTag = element.selectFirstOrThrow("h3 a") val aTag = element.selectFirstOrThrow("h3 a")
val tags = element.select(".genre-item").map { val tags = element.select(".genre-item").mapToSet {
MangaTag( MangaTag(
key = it.attr("href").substringAfterLast('-').substringBeforeLast('.'), key = it.attr("href").substringAfterLast('-').substringBeforeLast('.'),
title = it.text(), title = it.text().toTitleCase(sourceLocale),
source = source source = source,
) )
}.toSet() }
val isNsfw = if (tags.any { it.title in nsfwTags }) true else false val isNsfw = tags.any { it.title in nsfwTags }
val href = aTag.attrAsRelativeUrl("href")
Manga( Manga(
id = generateUid(aTag.attr("href")), id = generateUid(href),
title = aTag.text(), title = aTag.text(),
altTitle = null, altTitle = null,
url = aTag.attrAsRelativeUrl("href"), url = href,
publicUrl = aTag.attr("href").toAbsoluteUrl(domain), publicUrl = aTag.attrAsAbsoluteUrl("href"),
rating = RATING_UNKNOWN, rating = RATING_UNKNOWN,
isNsfw = isNsfw, isNsfw = isNsfw,
coverUrl = element.selectFirst(".book_avatar a img")?.src().orEmpty(), coverUrl = element.selectFirst(".book_avatar a img")?.src(),
tags = tags, tags = tags,
state = null, state = null,
author = null, author = null,
@ -144,16 +139,16 @@ internal class TruyenTranh3Q(context: MangaLoaderContext) : PagedMangaParser(con
val tags = doc.select("ul.list01 li").mapToSet { val tags = doc.select("ul.list01 li").mapToSet {
MangaTag( MangaTag(
key = it.attr("href").substringAfterLast('-').substringBeforeLast('.'), key = it.attr("href").substringAfterLast('-').substringBeforeLast('.'),
title = it.text(), title = it.text().toTitleCase(sourceLocale),
source = source, source = source,
) )
} }
return manga.copy( return manga.copy(
altTitle = doc.selectFirst("h2.other-name")?.textOrNull(), altTitle = doc.selectFirst("h2.other-name")?.textOrNull(),
author = doc.select("li.author a").text(), author = doc.selectFirst("li.author a")?.textOrNull(),
tags = tags, tags = tags,
description = doc.select("div.story-detail-info").text(), description = doc.selectFirst("div.story-detail-info")?.html(),
state = when (doc.selectFirst(".status p.col-xs-9")?.text()) { state = when (doc.selectFirst(".status p.col-xs-9")?.text()) {
"Đang tiến hành" -> MangaState.ONGOING "Đang tiến hành" -> MangaState.ONGOING
"Hoàn thành" -> MangaState.FINISHED "Hoàn thành" -> MangaState.FINISHED
@ -196,9 +191,6 @@ internal class TruyenTranh3Q(context: MangaLoaderContext) : PagedMangaParser(con
private fun parseChapterDate(dateText: String?): Long { private fun parseChapterDate(dateText: String?): Long {
if (dateText == null) return 0 if (dateText == null) return 0
val relativeTimePattern = Regex("(\\d+)\\s*(phút|giờ|ngày|tuần) trước")
val absoluteTimePattern = Regex("(\\d{2}-\\d{2}-\\d{4})")
return when { return when {
dateText.contains("phút trước") -> { dateText.contains("phút trước") -> {
val match = relativeTimePattern.find(dateText) val match = relativeTimePattern.find(dateText)
@ -244,8 +236,8 @@ internal class TruyenTranh3Q(context: MangaLoaderContext) : PagedMangaParser(con
return elements.mapIndexed { index, element -> return elements.mapIndexed { index, element ->
MangaTag( MangaTag(
key = (index + 1).toString(), key = (index + 1).toString(),
title = element.text(), title = element.text().toTitleCase(sourceLocale),
source = source source = source,
) )
}.toSet() }.toSet()
} }

Loading…
Cancel
Save