|
|
|
@ -186,31 +186,36 @@ internal class DamCoNuong(context: MangaLoaderContext) :
|
|
|
|
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
|
|
|
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
|
|
|
val doc = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml()
|
|
|
|
val doc = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml()
|
|
|
|
|
|
|
|
|
|
|
|
val scriptContent = doc.selectFirst("script:containsData(window.encryptionConfig)")
|
|
|
|
doc.selectFirst("script:containsData(window.encryptionConfig)")?.data()?.let { scriptContent ->
|
|
|
|
?.data()
|
|
|
|
|
|
|
|
?: throw ParseException("Không tìm thấy script 'window.encryptionConfig'.", chapter.url)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val fallbackUrlsRegex = Regex(""""fallbackUrls"\s*:\s*(\[.*?\])""")
|
|
|
|
val fallbackUrlsRegex = Regex(""""fallbackUrls"\s*:\s*(\[.*?\])""")
|
|
|
|
val arrayString = fallbackUrlsRegex.find(scriptContent)?.groupValues?.get(1)
|
|
|
|
val arrayString = fallbackUrlsRegex.find(scriptContent)?.groupValues?.get(1) ?: return@let
|
|
|
|
?: throw ParseException("Không tìm thấy mảng 'fallbackUrls' trong script.", chapter.url)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val urlRegex = Regex("""(https?:\\?/\\?[^"]+\.(?:jpg|jpeg|png|webp|gif))""")
|
|
|
|
val urlRegex = Regex("""(https?:\\?/\\?[^"]+\.(?:jpg|jpeg|png|webp|gif))""")
|
|
|
|
val imageUrls = urlRegex.findAll(arrayString).map {
|
|
|
|
val scriptImages = urlRegex.findAll(arrayString).map {
|
|
|
|
it.groupValues[1].replace("\\/", "/")
|
|
|
|
it.groupValues[1].replace("\\/", "/")
|
|
|
|
}.toList()
|
|
|
|
}.toList()
|
|
|
|
|
|
|
|
|
|
|
|
if (imageUrls.isEmpty()) {
|
|
|
|
if (scriptImages.isNotEmpty()) {
|
|
|
|
throw ParseException("Không tìm thấy URL ảnh hợp lệ nào trong 'fallbackUrls'.", chapter.url)
|
|
|
|
return scriptImages.map { url ->
|
|
|
|
|
|
|
|
MangaPage(id = generateUid(url), url = url, preview = null, source = source)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return imageUrls.map { url ->
|
|
|
|
val tagImagePages = doc.select("div#chapter-content img").mapNotNull { img ->
|
|
|
|
MangaPage(
|
|
|
|
val imageUrl = (img.attr("abs:src").takeIf { it.isNotBlank() }
|
|
|
|
id = generateUid(url),
|
|
|
|
?: img.attr("abs:data-src").takeIf { it.isNotBlank() })
|
|
|
|
url = url,
|
|
|
|
?.trim()
|
|
|
|
preview = null,
|
|
|
|
|
|
|
|
source = source,
|
|
|
|
imageUrl?.let {
|
|
|
|
)
|
|
|
|
MangaPage(id = generateUid(it), url = it, preview = null, source = source)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (tagImagePages.isNotEmpty()) {
|
|
|
|
|
|
|
|
return tagImagePages
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
throw ParseException("Không tìm thấy bất kỳ nguồn ảnh nào (đã thử cả script và thẻ img).", chapter.url)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private fun parseChapterDate(date: String?): Long {
|
|
|
|
private fun parseChapterDate(date: String?): Long {
|
|
|
|
|