From 77c3906e2c6159d75b5845b046edfd11b591dd14 Mon Sep 17 00:00:00 2001 From: Vetle Ledaal Date: Fri, 4 Feb 2022 13:12:57 +0000 Subject: [PATCH] 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 --- src/ar/gmanga/build.gradle | 2 +- .../tachiyomi/extension/ar/gmanga/Gmanga.kt | 49 +++++++-------- .../extension/ar/gmanga/GmangaFilters.kt | 10 +-- .../extension/ar/gmanga/dto/ChapterDto.kt | 13 ++++ .../extension/ar/gmanga/dto/ChapterListDto.kt | 10 +++ .../extension/ar/gmanga/dto/ReleaseDto.kt | 15 +++++ .../extension/ar/gmanga/dto/TableDto.kt | 61 +++++++++++++++++++ .../extension/ar/gmanga/dto/TeamDto.kt | 9 +++ 8 files changed, 137 insertions(+), 32 deletions(-) create mode 100644 src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ChapterDto.kt create mode 100644 src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ChapterListDto.kt create mode 100644 src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ReleaseDto.kt create mode 100644 src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/TableDto.kt create mode 100644 src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/TeamDto.kt diff --git a/src/ar/gmanga/build.gradle b/src/ar/gmanga/build.gradle index 65a66eb81..6f88d00d7 100644 --- a/src/ar/gmanga/build.gradle +++ b/src/ar/gmanga/build.gradle @@ -6,7 +6,7 @@ ext { extName = 'GMANGA' pkgNameSuffix = 'ar.gmanga' extClass = '.Gmanga' - extVersionCode = 8 + extVersionCode = 9 } dependencies { diff --git a/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/Gmanga.kt b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/Gmanga.kt index d2329c11f..ba2209bf7 100644 --- a/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/Gmanga.kt +++ b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/Gmanga.kt @@ -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 { val data = decryptResponse(response) - val chapters: List = buildList { - val allChapters: ArrayList = 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(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) -> 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") diff --git a/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/GmangaFilters.kt b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/GmangaFilters.kt index b77f09532..40f323ae4 100644 --- a/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/GmangaFilters.kt +++ b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/GmangaFilters.kt @@ -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) + } } } diff --git a/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ChapterDto.kt b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ChapterDto.kt new file mode 100644 index 000000000..64e536fc4 --- /dev/null +++ b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ChapterDto.kt @@ -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, +) diff --git a/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ChapterListDto.kt b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ChapterListDto.kt new file mode 100644 index 000000000..4be58257f --- /dev/null +++ b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ChapterListDto.kt @@ -0,0 +1,10 @@ +package eu.kanade.tachiyomi.extension.ar.gmanga.dto + +import kotlinx.serialization.Serializable + +@Serializable +data class ChapterListDto( + val releases: List, + val teams: List, + val chapters: List, +) diff --git a/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ReleaseDto.kt b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ReleaseDto.kt new file mode 100644 index 000000000..d200c8a92 --- /dev/null +++ b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/ReleaseDto.kt @@ -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, +) diff --git a/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/TableDto.kt b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/TableDto.kt new file mode 100644 index 000000000..5ea91e079 --- /dev/null +++ b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/TableDto.kt @@ -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, + val rows: List, + 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, + ) + }, +) diff --git a/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/TeamDto.kt b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/TeamDto.kt new file mode 100644 index 000000000..0942c64a9 --- /dev/null +++ b/src/ar/gmanga/src/eu/kanade/tachiyomi/extension/ar/gmanga/dto/TeamDto.kt @@ -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, +)