Gmanga: fix search request and chapter parsing (#10686)
* Gmanga: fix search request and chapter parsing * Ignore HTTP 103 in fetchMangaDetails * [skip ci] attempt fix 'Sequence contains no items' * [skip ci] revert HTTP 103 changes * Improve chapter sort
This commit is contained in:
parent
2a180832e7
commit
77c3906e2c
|
@ -6,7 +6,7 @@ ext {
|
|||
extName = 'GMANGA'
|
||||
pkgNameSuffix = 'ar.gmanga'
|
||||
extClass = '.Gmanga'
|
||||
extVersionCode = 8
|
||||
extVersionCode = 9
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
|
@ -2,7 +2,10 @@ package eu.kanade.tachiyomi.extension.ar.gmanga
|
|||
|
||||
import androidx.preference.PreferenceScreen
|
||||
import eu.kanade.tachiyomi.extension.ar.gmanga.GmangaPreferences.Companion.PREF_CHAPTER_LISTING
|
||||
import eu.kanade.tachiyomi.extension.ar.gmanga.GmangaPreferences.Companion.PREF_CHAPTER_LISTING_SHOW_ALL
|
||||
import eu.kanade.tachiyomi.extension.ar.gmanga.GmangaPreferences.Companion.PREF_CHAPTER_LISTING_SHOW_POPULAR
|
||||
import eu.kanade.tachiyomi.extension.ar.gmanga.dto.TableDto
|
||||
import eu.kanade.tachiyomi.extension.ar.gmanga.dto.asChapterList
|
||||
import eu.kanade.tachiyomi.lib.ratelimit.RateLimitInterceptor
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
|
@ -16,14 +19,12 @@ import eu.kanade.tachiyomi.source.online.HttpSource
|
|||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonArray
|
||||
import kotlinx.serialization.json.JsonObject
|
||||
import kotlinx.serialization.json.contentOrNull
|
||||
import kotlinx.serialization.json.float
|
||||
import kotlinx.serialization.json.decodeFromJsonElement
|
||||
import kotlinx.serialization.json.jsonArray
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
import kotlinx.serialization.json.long
|
||||
import okhttp3.Headers
|
||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||
import okhttp3.OkHttpClient
|
||||
|
@ -65,41 +66,35 @@ class Gmanga : ConfigurableSource, HttpSource() {
|
|||
return GET("$baseUrl/api/mangas/$mangaId/releases", headers)
|
||||
}
|
||||
|
||||
@ExperimentalStdlibApi
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
val data = decryptResponse(response)
|
||||
|
||||
val chapters: List<JsonArray> = buildList {
|
||||
val allChapters: ArrayList<JsonArray> = ArrayList()
|
||||
data["rows"]!!.jsonArray[0].jsonObject["rows"]!!.jsonArray.forEach { release ->
|
||||
val chapter = data["rows"]!!.jsonArray[2].jsonObject["rows"]!!.jsonArray.filter { it.jsonArray[0] == release.jsonArray[4] }
|
||||
allChapters.addAll(chapter.map { it.jsonArray })
|
||||
val team = data["rows"]!!.jsonArray[1].jsonObject["rows"]!!.jsonArray.filter { it.jsonArray[0] == release.jsonArray[5] }
|
||||
allChapters.addAll(team.map { it.jsonArray })
|
||||
allChapters.add(release.jsonArray)
|
||||
}
|
||||
val table = json.decodeFromJsonElement<TableDto>(data)
|
||||
val chapterList = table.asChapterList()
|
||||
|
||||
when (preferences.getString(PREF_CHAPTER_LISTING)) {
|
||||
PREF_CHAPTER_LISTING_SHOW_POPULAR -> addAll(
|
||||
allChapters.groupBy { it.jsonArray[4].jsonPrimitive.float }
|
||||
.map { (_: Float, versions: List<JsonArray>) -> versions.maxByOrNull { it[5].jsonPrimitive.float }!! }
|
||||
)
|
||||
else -> addAll(allChapters)
|
||||
}
|
||||
val releases = when (preferences.getString(PREF_CHAPTER_LISTING)) {
|
||||
PREF_CHAPTER_LISTING_SHOW_POPULAR ->
|
||||
chapterList.releases
|
||||
.groupBy { release -> release.chapterizationId }
|
||||
.mapNotNull { (_, releases) -> releases.maxByOrNull { it.views } }
|
||||
PREF_CHAPTER_LISTING_SHOW_ALL -> chapterList.releases
|
||||
else -> emptyList()
|
||||
}
|
||||
|
||||
return chapters.map {
|
||||
return releases.map { release ->
|
||||
SChapter.create().apply {
|
||||
chapter_number = it[8].jsonPrimitive.float
|
||||
val chapter = chapterList.chapters.first { it.id == release.chapterizationId }
|
||||
val team = chapterList.teams.firstOrNull { it.id == release.teamId }
|
||||
|
||||
val chapterName = it[10].jsonPrimitive.content.let { if (it.trim() != "") " - $it" else "" }
|
||||
url = "/r/${release.id}"
|
||||
chapter_number = chapter.chapter
|
||||
date_upload = release.timestamp * 1000
|
||||
scanlator = team?.name
|
||||
|
||||
url = "/r/${it[0]}"
|
||||
val chapterName = chapter.title.let { if (it.trim() != "") " - $it" else "" }
|
||||
name = "${chapter_number.let { if (it % 1 > 0) it else it.toInt() }}$chapterName"
|
||||
date_upload = it[2].jsonPrimitive.long * 1000
|
||||
scanlator = it[13].jsonPrimitive.content
|
||||
}
|
||||
}
|
||||
}.sortedWith(compareBy({ -it.chapter_number }, { -it.date_upload }))
|
||||
}
|
||||
|
||||
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
|
||||
|
|
|
@ -39,10 +39,12 @@ class GmangaFilters() {
|
|||
|
||||
return buildJsonObject {
|
||||
oneShotFilter.state.first().let {
|
||||
when {
|
||||
it.isIncluded() -> put("oneshot", true)
|
||||
it.isExcluded() -> put("oneshot", false)
|
||||
else -> put("oneshot", JsonNull)
|
||||
putJsonObject("oneshot") {
|
||||
when {
|
||||
it.isIncluded() -> put("value", true)
|
||||
it.isExcluded() -> put("value", false)
|
||||
else -> put("value", JsonNull)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package eu.kanade.tachiyomi.extension.ar.gmanga.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ChapterDto(
|
||||
val id: Int,
|
||||
val chapter: Float,
|
||||
val volume: Int,
|
||||
val title: String,
|
||||
@SerialName("time_stamp") val timestamp: Long,
|
||||
)
|
|
@ -0,0 +1,10 @@
|
|||
package eu.kanade.tachiyomi.extension.ar.gmanga.dto
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ChapterListDto(
|
||||
val releases: List<ReleaseDto>,
|
||||
val teams: List<TeamDto>,
|
||||
val chapters: List<ChapterDto>,
|
||||
)
|
|
@ -0,0 +1,15 @@
|
|||
package eu.kanade.tachiyomi.extension.ar.gmanga.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ReleaseDto(
|
||||
val id: Int,
|
||||
@SerialName("created_at") val createdAt: String,
|
||||
@SerialName("timestamp") val timestamp: Long,
|
||||
val views: Int,
|
||||
@SerialName("chapterization_id") val chapterizationId: Int,
|
||||
@SerialName("team_id") val teamId: Int,
|
||||
val teams: List<Int>,
|
||||
)
|
|
@ -0,0 +1,61 @@
|
|||
package eu.kanade.tachiyomi.extension.ar.gmanga.dto
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
import kotlinx.serialization.json.decodeFromJsonElement
|
||||
import kotlinx.serialization.json.float
|
||||
import kotlinx.serialization.json.int
|
||||
import kotlinx.serialization.json.jsonArray
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
import kotlinx.serialization.json.long
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
@Serializable
|
||||
data class TableDto(
|
||||
val cols: List<String>,
|
||||
val rows: List<JsonElement>,
|
||||
val isCompact: Boolean,
|
||||
val maxLevel: Int,
|
||||
val isArray: Boolean? = null,
|
||||
val isObject: Boolean? = null,
|
||||
)
|
||||
|
||||
private val json: Json by injectLazy()
|
||||
|
||||
private fun TableDto.get(key: String): TableDto? {
|
||||
isObject ?: return null
|
||||
|
||||
val index = cols.indexOf(key)
|
||||
return json.decodeFromJsonElement(rows[index])
|
||||
}
|
||||
|
||||
fun TableDto.asChapterList() = ChapterListDto(
|
||||
// YOLO
|
||||
get("releases")!!.rows.map {
|
||||
ReleaseDto(
|
||||
it.jsonArray[0].jsonPrimitive.int,
|
||||
it.jsonArray[1].jsonPrimitive.content,
|
||||
it.jsonArray[2].jsonPrimitive.long,
|
||||
it.jsonArray[3].jsonPrimitive.int,
|
||||
it.jsonArray[4].jsonPrimitive.int,
|
||||
it.jsonArray[5].jsonPrimitive.int,
|
||||
it.jsonArray[6].jsonArray.map { it.jsonPrimitive.int },
|
||||
)
|
||||
},
|
||||
get("teams")!!.rows.map {
|
||||
TeamDto(
|
||||
it.jsonArray[0].jsonPrimitive.int,
|
||||
it.jsonArray[1].jsonPrimitive.content,
|
||||
)
|
||||
},
|
||||
get("chapterizations")!!.rows.map {
|
||||
ChapterDto(
|
||||
it.jsonArray[0].jsonPrimitive.int,
|
||||
it.jsonArray[1].jsonPrimitive.float,
|
||||
it.jsonArray[2].jsonPrimitive.int,
|
||||
it.jsonArray[3].jsonPrimitive.content,
|
||||
it.jsonArray[4].jsonPrimitive.long,
|
||||
)
|
||||
},
|
||||
)
|
|
@ -0,0 +1,9 @@
|
|||
package eu.kanade.tachiyomi.extension.ar.gmanga.dto
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class TeamDto(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
)
|
Loading…
Reference in New Issue