diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProject.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProject.kt index efae4a9b8..df51fecba 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProject.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProject.kt @@ -62,7 +62,7 @@ abstract class MangasProject( } override fun popularMangaParse(response: Response): MangasPage { - val result = json.decodeFromString(response.body!!.string()) + val result = response.parseAs() val popularMangas = result.mostRead.map(::popularMangaFromObject) @@ -82,7 +82,7 @@ abstract class MangasProject( } override fun latestUpdatesParse(response: Response): MangasPage { - val result = json.decodeFromString(response.body!!.string()) + val result = response.parseAs() val latestMangas = result.releases.map(::latestMangaFromObject) @@ -111,7 +111,7 @@ abstract class MangasProject( } override fun searchMangaParse(response: Response): MangasPage { - val result = json.decodeFromString(response.body!!.string()) + val result = response.parseAs() // If "series" have boolean false value, then it doesn't have results. if (result.series is JsonPrimitive) @@ -203,24 +203,33 @@ abstract class MangasProject( var page = 1 var chapterListRequest = chapterListRequestPaginated(mangaUrl, mangaId, page) - var result = client.newCall(chapterListRequest).execute().let { - json.decodeFromString(it.body!!.string()) - } + var chapterListResult = client.newCall(chapterListRequest).execute() + .parseAs() - if (result.chapters is JsonPrimitive) + if (chapterListResult.chapters is JsonPrimitive) return emptyList() - val chapters = mutableListOf() + val chapters = json.decodeFromJsonElement>(chapterListResult.chapters) + .flatMap(::chaptersFromObject) + .toMutableList() - while (result.chapters is JsonArray) { - chapters += json.decodeFromJsonElement>(result.chapters) + // If the result has less than the default per page, return right away + // to prevent extra API calls to get the chapters that does not exist. + if (chapters.size < 30) { + return chapters + } + + // Otherwise, call the next pages of the API endpoint. + chapterListRequest = chapterListRequestPaginated(mangaUrl, mangaId, ++page) + chapterListResult = client.newCall(chapterListRequest).execute().parseAs() + + while (chapterListResult.chapters is JsonArray) { + chapters += json.decodeFromJsonElement>(chapterListResult.chapters) .flatMap(::chaptersFromObject) .toMutableList() chapterListRequest = chapterListRequestPaginated(mangaUrl, mangaId, ++page) - result = client.newCall(chapterListRequest).execute().let { - json.decodeFromString(it.body!!.string()) - } + chapterListResult = client.newCall(chapterListRequest).execute().parseAs() } return chapters @@ -270,9 +279,8 @@ abstract class MangasProject( val chapterUrl = getChapterUrl(response) val apiRequest = pageListApiRequest(chapterUrl, readerToken) - val apiResponse = client.newCall(apiRequest).execute().let { - json.decodeFromString(it.body!!.string()) - } + val apiResponse = client.newCall(apiRequest).execute() + .parseAs() return apiResponse.images .filter { it.startsWith("http") } @@ -303,6 +311,18 @@ abstract class MangasProject( return GET(page.imageUrl!!, newHeaders) } + private inline fun Response.parseAs(): T { + val responseBody = body?.string().orEmpty() + + val errorResult = json.decodeFromString(responseBody) + + if (errorResult.message.isNullOrEmpty().not()) { + throw Exception(errorResult.message) + } + + return json.decodeFromString(responseBody) + } + private fun String.toDate(): Long { return try { DATE_FORMATTER.parse(this)?.time ?: 0L diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProjectDto.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProjectDto.kt index 10ac63a70..68c09b693 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProjectDto.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProjectDto.kt @@ -4,6 +4,12 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonElement +@Serializable +data class MangasProjectErrorDto( + val code: Int? = null, + val message: String? = null +) + @Serializable data class MangasProjectMostReadDto( @SerialName("most_read") val mostRead: List = emptyList() diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProjectGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProjectGenerator.kt index 41ae250f3..7c846f1a1 100644 --- a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProjectGenerator.kt +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/mangasproject/MangasProjectGenerator.kt @@ -9,12 +9,12 @@ class MangasProjectGenerator : ThemeSourceGenerator { override val themeClass = "MangasProject" - override val baseVersionCode: Int = 4 + override val baseVersionCode: Int = 6 override val sources = listOf( - SingleLang("Leitor.net", "https://leitor.net", "pt-BR", className = "LeitorNet", isNsfw = true, overrideVersionCode = 1), - SingleLang("Mangá Livre", "https://mangalivre.net", "pt-BR", className = "MangaLivre", isNsfw = true, overrideVersionCode = 1), - SingleLang("Toonei", "https://toonei.net", "pt-BR", isNsfw = true, overrideVersionCode = 1), + SingleLang("Leitor.net", "https://leitor.net", "pt-BR", className = "LeitorNet", isNsfw = true), + SingleLang("Mangá Livre", "https://mangalivre.net", "pt-BR", className = "MangaLivre", isNsfw = true), + SingleLang("Toonei", "https://toonei.net", "pt-BR", isNsfw = true), ) companion object {