Update domain + Fixes (#1206)

* Update MaidScan.kt

* Update NetTruyenLL.kt

* Update Quaanhdaocuteo.kt

* Fixes
master
Draken 2 years ago committed by GitHub
parent 79e1d59482
commit ce4b4d06d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -8,6 +8,6 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MAIDSCAN", "MaidScan", "pt", ContentType.HENTAI) @MangaSourceParser("MAIDSCAN", "MaidScan", "pt", ContentType.HENTAI)
internal class MaidScan(context: MangaLoaderContext) : internal class MaidScan(context: MangaLoaderContext) :
MadaraParser(context, MangaParserSource.MAIDSCAN, "maidscans.com", 10) { MadaraParser(context, MangaParserSource.MAIDSCAN, "empreguetes.site", 10) {
override val datePattern: String = "dd/MM/yyyy" override val datePattern: String = "dd/MM/yyyy"
} }

@ -1,6 +1,5 @@
package org.koitharu.kotatsu.parsers.site.madara.vi package org.koitharu.kotatsu.parsers.site.madara.vi
import org.koitharu.kotatsu.parsers.Broken
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.ContentType import org.koitharu.kotatsu.parsers.model.ContentType
@ -10,10 +9,9 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource
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.*
@Broken
@MangaSourceParser("QUAANHDAOCUTEO", "Quaanhdaocuteo", "vi", ContentType.HENTAI) @MangaSourceParser("QUAANHDAOCUTEO", "Quaanhdaocuteo", "vi", ContentType.HENTAI)
internal class Quaanhdaocuteo(context: MangaLoaderContext) : internal class Quaanhdaocuteo(context: MangaLoaderContext) :
MadaraParser(context, MangaParserSource.QUAANHDAOCUTEO, "qadc.top") { MadaraParser(context, MangaParserSource.QUAANHDAOCUTEO, "qadc.xyz") {
override val datePattern = "dd/MM/yyyy" override val datePattern = "dd/MM/yyyy"
override val selectPage = "p img" override val selectPage = "p img"

@ -1,5 +1,6 @@
package org.koitharu.kotatsu.parsers.site.vi package org.koitharu.kotatsu.parsers.site.vi
import androidx.collection.arraySetOf
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.PagedMangaParser import org.koitharu.kotatsu.parsers.PagedMangaParser
@ -7,17 +8,12 @@ import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.network.UserAgents 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.util.* import java.util.*
import org.koitharu.kotatsu.parsers.Broken
@Broken @MangaSourceParser("LXMANGA", "LxManga", "vi", type = ContentType.HENTAI)
@MangaSourceParser("LXMANGA", "LxManga", "vi")
internal class LxManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.LXMANGA, 60) { internal class LxManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.LXMANGA, 60) {
override val configKeyDomain = ConfigKey.Domain("lxmanga.online") override val configKeyDomain = ConfigKey.Domain("lxmanga.site")
override val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_DESKTOP)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) { override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys) super.onCreateConfig(keys)
@ -32,14 +28,13 @@ internal class LxManga(context: MangaLoaderContext) : PagedMangaParser(context,
SortOrder.POPULARITY, SortOrder.POPULARITY,
) )
override val filterCapabilities: MangaListFilterCapabilities override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities( get() = MangaListFilterCapabilities(
isSearchSupported = true, isSearchSupported = true,
) )
override suspend fun getFilterOptions() = MangaListFilterOptions( override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(), availableTags = availableTags(),
availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED), availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED),
) )
@ -51,109 +46,138 @@ internal class LxManga(context: MangaLoaderContext) : PagedMangaParser(context,
when { when {
!filter.query.isNullOrEmpty() -> { !filter.query.isNullOrEmpty() -> {
val skey = "filter[name]=".urlEncoded() append("/tim-kiem")
append("/tim-kiem?$skey") append("?filter[name]=")
append(filter.query.urlEncoded()) append(filter.query.urlEncoded())
append("&page=")
append(page.toString()) if (page > 1) {
append("&page=")
append(page.toString())
}
append("&sort=")
append(when (order) {
SortOrder.POPULARITY -> "-views"
SortOrder.UPDATED -> "-updated_at"
SortOrder.NEWEST -> "-created_at"
SortOrder.ALPHABETICAL -> "name"
SortOrder.ALPHABETICAL_DESC -> "-name"
else -> "-updated_at"
})
} }
else -> { filter.tags.isNotEmpty() -> {
if (filter.tags.isNotEmpty()) { val tag = filter.tags.first()
filter.tags.oneOrThrowIfMany()?.let { append("/the-loai/")
append("/the-loai/") append(tag.key)
append(it.key)
}
} else {
append("/danh-sach")
}
append("?page=") append("?page=")
append(page.toString()) append(page)
}
if (filter.states.isNotEmpty()) {
append("&filter[status]=")
filter.states.forEach {
append(
when (it) {
MangaState.ONGOING -> "2,"
MangaState.FINISHED -> "1,"
else -> "1,2"
},
)
}
}
append("&sort=") else -> {
when (order) { append("/danh-sach")
SortOrder.POPULARITY -> append("-views") append("?sort=")
SortOrder.UPDATED -> append("-updated_at") append(when (order) {
SortOrder.NEWEST -> append("-created_at") SortOrder.POPULARITY -> "-views"
SortOrder.ALPHABETICAL -> append("name") SortOrder.UPDATED -> "-updated_at"
SortOrder.ALPHABETICAL_DESC -> append("-name") SortOrder.NEWEST -> "-created_at"
else -> append("-updated_at") SortOrder.ALPHABETICAL -> "name"
} SortOrder.ALPHABETICAL_DESC -> "-name"
else -> "-updated_at"
})
append("&page=")
append(page)
} }
} }
if (filter.query.isNullOrEmpty()) {
append("&sort=")
when (order) {
SortOrder.POPULARITY -> append("-views")
SortOrder.UPDATED -> append("-updated_at")
SortOrder.NEWEST -> append("-created_at")
SortOrder.ALPHABETICAL -> append("name")
SortOrder.ALPHABETICAL_DESC -> append("-name")
else -> append("-updated_at")
}
}
if (filter.states.isNotEmpty()) {
append("&filter[status]=")
filter.states.forEach {
append(
when (it) {
MangaState.ONGOING -> "2,"
MangaState.FINISHED -> "1,"
else -> "1,2"
},
)
}
}
} }
val doc = webClient.httpGet(url).parseHtml() val doc = webClient.httpGet(url).parseHtml()
return doc.select("div.grid div.manga-vertical") return doc.select("div.grid div.relative").map { div ->
.map { div -> val href = div.selectFirst("a[href^=/truyen/]")?.attr("href")
val href = div.selectFirstOrThrow("a").attr("href") ?: div.parseFailed("Không thể tìm thấy nguồn ảnh của Manga này!")
val img = div.selectFirstOrThrow(".cover").attr("style").substringAfter("url('").substringBefore("')") val coverStyle = div.select("div.cover").attr("data-bg")
Manga( val coverUrl = coverStyle.takeIf { it.isNotEmpty() } ?: div.select("div.cover").attr("style")
id = generateUid(href), .substringAfter("url('").substringBefore("')")
title = div.selectFirstOrThrow("a.text-ellipsis").text(), .replace("s3.lxmanga.top", domain)
altTitle = null,
url = href, Manga(
publicUrl = href.toAbsoluteUrl(domain), id = generateUid(href),
rating = RATING_UNKNOWN, title = div.select("div.p-2 a.text-ellipsis").text(),
isNsfw = true, altTitle = null,
coverUrl = img, url = href,
tags = setOf(), publicUrl = href.toAbsoluteUrl(domain),
state = null, rating = RATING_UNKNOWN,
author = null, isNsfw = true,
source = source, coverUrl = coverUrl,
) tags = setOf(),
} state = null,
author = null,
source = source,
)
}
} }
override suspend fun getDetails(manga: Manga): Manga { override suspend fun getDetails(manga: Manga): Manga {
val root = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() val root = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US)
return manga.copy( return manga.copy(
altTitle = root.select(".divider2:contains(Noms associés :)").firstOrNull()?.text(), altTitle = root.select("div.grow div:contains(Tên khác) span").lastOrNull()?.text(),
state = when (root.select("div.grow div.mt-2:contains(Tình trạng) a").first()!!.text()) { state = when (root.select("div.mt-2:contains(Tình trạng) span.text-blue-500").firstOrNull()?.text()?.trim()) {
"Đ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
else -> null else -> null
}, },
tags = root.select("div.grow div.mt-2:contains(Thể loại) span a").mapNotNullToSet { a -> tags = root.select("div.mt-2:contains(Thể loại) a.bg-gray-500").mapNotNullToSet { a ->
MangaTag( MangaTag(
key = a.attr("href").removeSuffix("/").substringAfterLast('/'), key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
title = a.text().toTitleCase(), title = a.text().trim(),
source = source, source = source,
) )
}, },
author = root.select("div.grow div.mt-2:contains(Tác giả) span a") author = root.select("div.mt-2:contains(Tác giả) span a").firstOrNull()?.text()?.trim(),
.joinToString { it.text().trim(',', ' ') }, description = root.select("meta[name=description]").firstOrNull()?.attr("content")?.trim(),
description = root.selectFirst("div.py-4.border-t")?.html(), chapters = root.select("div.justify-between ul.overflow-y-auto.overflow-x-hidden a")
chapters = root.select("ul.overflow-y-auto.overflow-x-hidden a")
.mapChapters(reversed = true) { i, a -> .mapChapters(reversed = true) { i, a ->
val href = a.attr("href") val href = a.attr("href")
val name = a.selectFirstOrThrow("span.text-ellipsis").text() val name = a.selectFirst("span.text-ellipsis")?.text() ?: ""
val date = a.selectFirstOrThrow("span.timeago").attr("datetime") val dateText = a.parent()?.selectFirst("span.timeago")?.attr("datetime") ?: ""
val scanlator = root.select("div.mt-2:contains(Nhóm dịch) span a").firstOrNull()?.text()?.trim()
MangaChapter( MangaChapter(
id = generateUid(href), id = generateUid(href),
name = name, name = name,
number = i.toFloat(), number = i.toFloat(),
volume = 0, volume = 0,
url = href, url = href,
scanlator = null, scanlator = scanlator,
uploadDate = dateFormat.tryParse(date), uploadDate = parseDateTime(dateText),
branch = null, branch = null,
source = source, source = source,
) )
@ -164,27 +188,113 @@ internal class LxManga(context: MangaLoaderContext) : PagedMangaParser(context,
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> { override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val fullUrl = chapter.url.toAbsoluteUrl(domain) val fullUrl = chapter.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml() val doc = webClient.httpGet(fullUrl).parseHtml()
return doc.select("div.text-center img.lazy-image").map { img -> return doc.select("div.text-center div.lazy")
val url = img.attrAsRelativeUrlOrNull("data-src") ?: img.attrAsRelativeUrlOrNull("src") .mapNotNull { div ->
?: img.parseFailed("Image src not found") val url = div.attr("data-src")
MangaPage( if (url.endsWith(".jpg", ignoreCase = true) ||
id = generateUid(url), url.endsWith(".png", ignoreCase = true)) {
url = url, MangaPage(
preview = null, id = generateUid(url),
source = source, url = url,
) preview = null,
} source = source,
)
} else null
}
} }
private suspend fun fetchAvailableTags(): Set<MangaTag> { private fun availableTags() = arraySetOf(
val doc = webClient.httpGet("https://$domain/").parseHtml() MangaTag("3D", "3d", source),
val body = doc.body() MangaTag("Adult", "adult", source),
return body.select("ul.absolute.w-full a").mapToSet { a -> MangaTag("Animal girl", "animal-girl", source),
MangaTag( MangaTag("Artist", "artist", source),
key = a.attr("href").removeSuffix("/").substringAfterLast('/'), MangaTag("Bạo Dâm", "bao-dam", source),
title = a.selectFirstOrThrow("span.text-ellipsis").text(), MangaTag("CG", "cg", source),
source = source, MangaTag("Chơi Hai Lỗ", "choi-hai-lo", source),
MangaTag("Côn Trùng", "con-trung", source),
MangaTag("Cosplay", "cosplay", source),
MangaTag("Creampie", "creampie", source),
MangaTag("Doujinshi", "doujinshi", source),
MangaTag("Drama", "drama", source),
MangaTag("Đam Mỹ", "dam-my", source),
MangaTag("Đồ Bơi", "do-boi", source),
MangaTag("Elf", "elf", source),
MangaTag("Fantasy", "fantasy", source),
MangaTag("Furry", "furry", source),
MangaTag("Gangbang", "gangbang", source),
MangaTag("Gender Bender", "gender-bender", source),
MangaTag("Giáo Viên", "giao-vien", source),
MangaTag("Girl love", "girl-love", source),
MangaTag("Group", "group", source),
MangaTag("Guro", "guro", source),
MangaTag("Hài Hước", "hai-huoc", source),
MangaTag("Hãm Hiếp", "ham-hiep", source),
MangaTag("Harem", "harem", source),
MangaTag("Hầu Gái", "hau-gai", source),
MangaTag("Hậu Môn", "hau-mon", source),
MangaTag("Housewife", "housewife", source),
MangaTag("Kinh Dị", "kinh-di", source),
MangaTag("Kogal", "kogal", source),
MangaTag("Lão Già Dâm", "lao-gia-dam", source),
MangaTag("Lãng Mạn", "lang-man", source),
MangaTag("Loạn Luân", "loan-luan", source),
MangaTag("Loli", "loli", source),
MangaTag("LXHENTAI", "lxhentai", source),
MangaTag("Mang Thai", "mang-thai", source),
MangaTag("Manhwa", "manhwa", source),
MangaTag("Mắt Kính", "mat-kinh", source),
MangaTag("Mature", "mature", source),
MangaTag("Milf", "milf", source),
MangaTag("Mind Break", "mind-break", source),
MangaTag("Mind Control", "mind-control", source),
MangaTag("Monster Girl", "monster-girl", source),
MangaTag("Nàng Dâu", "nang-dau", source),
MangaTag("Netorare", "netorare", source),
MangaTag("Ngực Lớn", "nguc-lon", source),
MangaTag("Ngực Nhỏ", "nguc-nho", source),
MangaTag("Nô Lệ", "no-le", source),
MangaTag("NTR", "ntr", source),
MangaTag("Nữ Sinh", "nu-sinh", source),
MangaTag("Office lady", "office-lady", source),
MangaTag("OneShot", "oneshot", source),
MangaTag("Quái Vật", "quai-vat", source),
MangaTag("Series", "series", source),
MangaTag("Shota", "shota", source),
MangaTag("Supernatural", "supernatural", source),
MangaTag("Swinging", "swinging", source),
MangaTag("Thể Thao", "the-thao", source),
MangaTag("Three some", "three-some", source),
MangaTag("Thú Vật", "thu-vat", source),
MangaTag("Trap", "trap", source),
MangaTag("Truyện Comic", "truyen-comic", source),
MangaTag("Truyện Không Che", "truyen-khong-che", source),
MangaTag("Truyện Màu", "truyen-mau", source),
MangaTag("Truyện Ngắn", "truyen-ngan", source),
MangaTag("Virgin", "virgin", source),
MangaTag("Xúc Tua", "xuc-tua", source),
MangaTag("Y Tá", "y-ta", source),
MangaTag("Yaoi", "yaoi", source),
MangaTag("Yuri", "yuri", source)
)
private fun parseDateTime(dateStr: String): Long {
return try {
val parts = dateStr.split(" ")
val dateParts = parts[0].split("-")
val timeParts = parts[1].split(":")
val calendar = Calendar.getInstance()
calendar.set(
dateParts[0].toInt(),
dateParts[1].toInt() - 1,
dateParts[2].toInt(),
timeParts[0].toInt(),
timeParts[1].toInt(),
timeParts[2].toInt()
) )
calendar.timeInMillis
} catch (e: Exception) {
System.currentTimeMillis()
} }
} }
} }

@ -12,7 +12,7 @@ import java.util.EnumSet
@MangaSourceParser("NETTRUYENLL", "NetTruyenLL", "vi") @MangaSourceParser("NETTRUYENLL", "NetTruyenLL", "vi")
internal class NetTruyenLL(context: MangaLoaderContext) : internal class NetTruyenLL(context: MangaLoaderContext) :
WpComicsParser(context, MangaParserSource.NETTRUYENLL, "nettruyenll.com", 20) { WpComicsParser(context, MangaParserSource.NETTRUYENLL, "nettruyenuu.com", 20) {
override val listUrl = "/tim-kiem-nang-cao" override val listUrl = "/tim-kiem-nang-cao"

Loading…
Cancel
Save