ArgosScan: Fix Unexpected JSON token error (#9193)

* Fix

* Change contains value

* Fixes
This commit is contained in:
Chopper 2025-06-14 05:49:58 -03:00 committed by Draff
parent 0c3f9f2736
commit 6022ef39be
Signed by: Draff
GPG Key ID: E8A89F3211677653
3 changed files with 40 additions and 19 deletions

View File

@ -1,7 +1,7 @@
ext { ext {
extName = 'Argos Scan' extName = 'Argos Scan'
extClass = '.ArgosScan' extClass = '.ArgosScan'
extVersionCode = 25 extVersionCode = 26
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

View File

@ -19,6 +19,7 @@ import org.jsoup.nodes.Element
import java.io.IOException import java.io.IOException
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
import java.util.concurrent.TimeUnit
class ArgosScan : ParsedHttpSource() { class ArgosScan : ParsedHttpSource() {
@ -31,14 +32,8 @@ class ArgosScan : ParsedHttpSource() {
override val supportsLatest = false override val supportsLatest = false
override val client: OkHttpClient = network.cloudflareClient.newBuilder() override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.addInterceptor { chain -> .connectTimeout(1, TimeUnit.MINUTES)
val response = chain.proceed(chain.request()) .readTimeout(1, TimeUnit.MINUTES)
if (response.request.url.pathSegments.any { it.equals("login", true) }) {
throw IOException("Faça login na WebView")
}
response
}
.build() .build()
// Website changed custom CMS. // Website changed custom CMS.
@ -52,7 +47,12 @@ class ArgosScan : ParsedHttpSource() {
override fun popularMangaNextPageSelector() = null override fun popularMangaNextPageSelector() = null
override fun popularMangaParse(response: Response): MangasPage { override fun popularMangaParse(response: Response): MangasPage {
val script = response.asJsoup().selectFirst("script:containsData(projects)")!!.data() val document = response.asJsoup()
if (document.select("a[href*='auth/discord']").isNotEmpty()) {
throw IOException("Faça login na WebView")
}
val script = document.selectFirst("script:containsData(projects)")!!.data()
val mangas = POPULAR_REGEX.find(script)?.groups?.get(1)?.value?.let { val mangas = POPULAR_REGEX.find(script)?.groups?.get(1)?.value?.let {
it.parseAs<List<MangaDto>>() it.parseAs<List<MangaDto>>()
@ -90,6 +90,12 @@ class ArgosScan : ParsedHttpSource() {
// ============================ Details ===================================== // ============================ Details =====================================
override fun getMangaUrl(manga: SManga) = "$baseUrl/projeto/${manga.getProjectId()}"
override fun mangaDetailsRequest(manga: SManga): Request = GET(getMangaUrl(manga), headers)
private fun SManga.getProjectId() = url.replace("/", "").substringAfter(ENTRY_URL_REGEX)
override fun mangaDetailsParse(document: Document) = SManga.create().apply { override fun mangaDetailsParse(document: Document) = SManga.create().apply {
with(document) { with(document) {
title = selectFirst(".content h2")!!.text() title = selectFirst(".content h2")!!.text()
@ -100,17 +106,25 @@ class ArgosScan : ParsedHttpSource() {
} }
genre = select("h6:contains(Tags) + h6 > span").joinToString { it.text() } genre = select("h6:contains(Tags) + h6 > span").joinToString { it.text() }
} }
setUrlWithoutDomain(document.location())
} }
// ============================ Chapter ===================================== // ============================ Chapter =====================================
override fun chapterListRequest(manga: SManga) = mangaDetailsRequest(manga)
override fun chapterListParse(response: Response): List<SChapter> {
return super.chapterListParse(response).sortedByDescending(SChapter::chapter_number)
}
override fun chapterListSelector() = ".manga-chapter" override fun chapterListSelector() = ".manga-chapter"
override fun chapterFromElement(element: Element) = SChapter.create().apply { override fun chapterFromElement(element: Element) = SChapter.create().apply {
name = element.selectFirst("h5")!!.text() name = element.selectFirst("h5")!!.ownText()
element.selectFirst("h6")?.let { element.selectFirst("h6")?.let {
date_upload = dateFormat.tryParse(it.text()) date_upload = dateFormat.tryParse(it.text())
SIMPLE_NUMBER_REGEX.find(name)?.groups?.get(0)?.value?.toFloat()?.let {
chapter_number = it
}
} }
setUrlWithoutDomain(element.selectFirst("a")!!.absUrl("href")) setUrlWithoutDomain(element.selectFirst("a")!!.absUrl("href"))
} }
@ -127,8 +141,13 @@ class ArgosScan : ParsedHttpSource() {
// ============================== Utilities ================================== // ============================== Utilities ==================================
private fun String.substringAfter(regex: Regex): String =
regex.find(this)?.value?.let(::substringAfter) ?: this
companion object { companion object {
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.ROOT) private val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.ROOT)
val POPULAR_REGEX = """projects\s?=\s+([^;]+)""".toRegex() private val POPULAR_REGEX = """projects(?:\s+)?=(?:\s+)?(.+\]);""".toRegex()
private val SIMPLE_NUMBER_REGEX = """\d+(\.?\d+)?""".toRegex()
private val ENTRY_URL_REGEX = """projetos?""".toRegex()
} }
} }

View File

@ -11,15 +11,16 @@ class MangaDto(
@SerialName("cover_image_url") @SerialName("cover_image_url")
val thumbnailUrl: String, val thumbnailUrl: String,
val id: String, val id: String,
val type: String,
) { ) {
val type get() = details.type
fun toSManga(baseUrl: String) = SManga.create().apply { fun toSManga(baseUrl: String) = SManga.create().apply {
title = details.title.values.first() title = details.title.values.first()
description = details.description.values.first() description = details.description.values.firstOrNull()
genre = details.genres.joinToString() genre = details.genres.get("genre")?.let(List<String>::joinToString)
thumbnail_url = "$baseUrl/$thumbnailUrl" thumbnail_url = "$baseUrl/$thumbnailUrl"
status = details.status.toStatus() status = details.status.toStatus()
url = "/projetos/${this@MangaDto.id}" url = this@MangaDto.id
initialized = true initialized = true
} }
} }
@ -38,5 +39,6 @@ class DetailsDto(
val description: Map<String, String> = emptyMap(), val description: Map<String, String> = emptyMap(),
val status: String, val status: String,
@SerialName("tags") @SerialName("tags")
val genres: List<String> = emptyList(), val genres: Map<String, List<String>> = emptyMap(),
val type: String,
) )