From fc354f5792da74f3ce6ef9a9d5bd80b7f72273b8 Mon Sep 17 00:00:00 2001 From: Jobobby04 Date: Sun, 9 May 2021 17:37:19 -0400 Subject: [PATCH] Mangadex Api 5.0.4 --- .../tachiyomi/source/online/FollowsSource.kt | 2 +- .../tachiyomi/source/online/all/MangaDex.kt | 4 +- .../exh/md/follows/MangaDexFollowsPager.kt | 2 +- .../java/exh/md/handlers/ApiMangaParser.kt | 2 +- .../java/exh/md/handlers/FollowsHandler.kt | 99 +++++++++++-------- .../handlers/serializers/ChapterSerializer.kt | 2 +- .../handlers/serializers/MangaSerializer.kt | 13 ++- 7 files changed, 75 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt index a860af1f3..191038549 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/FollowsSource.kt @@ -8,7 +8,7 @@ import exh.md.utils.FollowStatus import exh.metadata.metadata.base.RaisedSearchMetadata interface FollowsSource : CatalogueSource { - suspend fun fetchFollows(): MangasPage + suspend fun fetchFollows(page: Int): MangasPage /** * Returns a list of all Follows retrieved by Coroutines diff --git a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt index e263e3d9d..2d3ab636d 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/source/online/all/MangaDex.kt @@ -161,8 +161,8 @@ class MangaDex(delegate: HttpSource, val context: Context) : ApiMangaParser(baseHttpClient, mdLang.lang).parseIntoMetadata(metadata, input, emptyList()) } - override suspend fun fetchFollows(): MangasPage { - return FollowsHandler(baseHttpClient, headers, preferences, mdLang.lang, useLowQualityThumbnail(), mdList).fetchFollows() + override suspend fun fetchFollows(page: Int): MangasPage { + return FollowsHandler(baseHttpClient, headers, preferences, mdLang.lang, useLowQualityThumbnail(), mdList).fetchFollows(page) } override val requiresLogin: Boolean = false diff --git a/app/src/main/java/exh/md/follows/MangaDexFollowsPager.kt b/app/src/main/java/exh/md/follows/MangaDexFollowsPager.kt index 06b679e35..aa9857b4f 100644 --- a/app/src/main/java/exh/md/follows/MangaDexFollowsPager.kt +++ b/app/src/main/java/exh/md/follows/MangaDexFollowsPager.kt @@ -14,7 +14,7 @@ import rx.schedulers.Schedulers class MangaDexFollowsPager(val source: MangaDex) : Pager() { override fun requestNext(): Observable { - return runAsObservable({ source.fetchFollows() }) + return runAsObservable({ source.fetchFollows(currentPage) }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .doOnNext { onPageReceived(it) } diff --git a/app/src/main/java/exh/md/handlers/ApiMangaParser.kt b/app/src/main/java/exh/md/handlers/ApiMangaParser.kt index d5d8c0668..f4b7fd281 100644 --- a/app/src/main/java/exh/md/handlers/ApiMangaParser.kt +++ b/app/src/main/java/exh/md/handlers/ApiMangaParser.kt @@ -219,7 +219,7 @@ class ApiMangaParser(val client: OkHttpClient, private val lang: String) { private fun parseStatus(status: String) = when (status) { "ongoing" -> SManga.ONGOING "complete" -> SManga.PUBLICATION_COMPLETE - "abandoned" -> SManga.CANCELLED + "cancelled" -> SManga.CANCELLED "hiatus" -> SManga.HIATUS else -> SManga.UNKNOWN } diff --git a/app/src/main/java/exh/md/handlers/FollowsHandler.kt b/app/src/main/java/exh/md/handlers/FollowsHandler.kt index b0afc38ab..a2e817827 100644 --- a/app/src/main/java/exh/md/handlers/FollowsHandler.kt +++ b/app/src/main/java/exh/md/handlers/FollowsHandler.kt @@ -14,15 +14,14 @@ import eu.kanade.tachiyomi.source.model.toSManga import eu.kanade.tachiyomi.util.lang.withIOContext import exh.md.handlers.serializers.MangaListResponse import exh.md.handlers.serializers.MangaResponse +import exh.md.handlers.serializers.MangaStatusListResponse +import exh.md.handlers.serializers.MangaStatusResponse import exh.md.handlers.serializers.UpdateReadingStatus import exh.md.utils.FollowStatus import exh.md.utils.MdUtil import exh.metadata.metadata.MangaDexSearchMetadata import exh.util.under import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.jsonObject -import kotlinx.serialization.json.jsonPrimitive import okhttp3.CacheControl import okhttp3.Headers import okhttp3.HttpUrl.Companion.toHttpUrl @@ -31,7 +30,6 @@ import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response -import tachiyomi.source.model.MangaInfo import java.util.Locale class FollowsHandler( @@ -44,28 +42,22 @@ class FollowsHandler( ) { /** - * fetch all follows + * fetch follows page */ - suspend fun fetchFollows(): MetadataMangasPage { + suspend fun fetchFollows(page: Int): MetadataMangasPage { return withIOContext { - val response = client.newCall(followsListRequest(0)).await() - + val response = client.newCall(followsListRequest(MdUtil.mangaLimit * page - 1)).await() val mangaListResponse = response.parseAs(MdUtil.jsonParser) - val results = mangaListResponse.results.toMutableList() - var hasMoreResults = mangaListResponse.limit + mangaListResponse.offset under mangaListResponse.total - var lastOffset = mangaListResponse.offset - - while (hasMoreResults) { - val offset = lastOffset + mangaListResponse.limit - val newMangaListResponse = client.newCall(followsListRequest(offset)).await() - .parseAs(MdUtil.jsonParser) - results.addAll(newMangaListResponse.results) - hasMoreResults = newMangaListResponse.limit + newMangaListResponse.offset under newMangaListResponse.total - lastOffset = newMangaListResponse.offset + if (mangaListResponse.results.isEmpty()) { + return@withIOContext MetadataMangasPage(emptyList(), false, emptyList()) } - val statusListResponse = client.newCall(statusListRequest()).await().parseAs() - followsParseMangaPage(results, statusListResponse) + + val hasMoreResults = mangaListResponse.limit + mangaListResponse.offset under mangaListResponse.total + val statusListResponse = client.newCall(mangaStatusListRequest(mangaListResponse.results)).await().parseAs() + val results = followsParseMangaPage(mangaListResponse.results, statusListResponse) + + MetadataMangasPage(results.map { it.first }, hasMoreResults, results.map { it.second }) } } @@ -73,25 +65,29 @@ class FollowsHandler( * Parse follows api to manga page * used when multiple follows */ - private fun followsParseMangaPage(response: List, statusListResponse: JsonObject): MetadataMangasPage { - val comparator = compareBy> { it.second.followStatus } + private fun followsParseMangaPage(response: List, statusListResponse: MangaStatusListResponse): List> { + val comparator = compareBy> { it.second.followStatus } .thenBy { it.first.title } - val result = response.map { - MdUtil.createMangaEntry(it, lang, useLowQualityCovers) to MangaDexSearchMetadata().apply { - followStatus = getFollowStatus(statusListResponse, it.data.id).int + + return response.map { + MdUtil.createMangaEntry( + it, + lang, + useLowQualityCovers + ).toSManga() to MangaDexSearchMetadata().apply { + followStatus = FollowStatus.fromDex(statusListResponse.statuses[it.data.id]).int } }.sortedWith(comparator) - - return MetadataMangasPage(result.map { it.first.toSManga() }, false, result.map { it.second }) } /** * fetch follow status used when fetching status for 1 manga */ - private fun followStatusParse(response: Response, statusListResponse: JsonObject): Track { + private fun followStatusParse(response: Response, sResponse: Response): Track { val mangaResponse = response.parseAs(MdUtil.jsonParser) + val statusResponse = sResponse.parseAs() val track = Track.create(TrackManager.MDLIST) - track.status = getFollowStatus(statusListResponse, mangaResponse.data.id).int + track.status = FollowStatus.fromDex(statusResponse.status).int track.tracking_url = MdUtil.baseUrl + "/manga/" + mangaResponse.data.id track.title = mangaResponse.data.attributes.title[lang] ?: mangaResponse.data.attributes.title["en"]!! @@ -197,30 +193,51 @@ class FollowsHandler( */ suspend fun fetchAllFollows(): List> { return withIOContext { - val metadata: List - fetchFollows().also { metadata = it.mangasMetadata.filterIsInstance() }.mangas.mapIndexed { index, manga -> - manga to metadata[index] + val response = client.newCall(followsListRequest(0)).await() + + val mangaListResponse = response.parseAs(MdUtil.jsonParser) + val results = mangaListResponse.results.toMutableList() + + if (results.isEmpty()) { + return@withIOContext emptyList() } + + var hasMoreResults = mangaListResponse.limit + mangaListResponse.offset under mangaListResponse.total + var lastOffset = mangaListResponse.offset + + while (hasMoreResults) { + val offset = lastOffset + mangaListResponse.limit + val newMangaListResponse = client.newCall(followsListRequest(offset)).await() + .parseAs(MdUtil.jsonParser) + results.addAll(newMangaListResponse.results) + hasMoreResults = newMangaListResponse.limit + newMangaListResponse.offset under newMangaListResponse.total + lastOffset = newMangaListResponse.offset + } + val statusListResponse = client.newCall(mangaStatusListRequest(results)).await().parseAs() + followsParseMangaPage(results, statusListResponse) } } suspend fun fetchTrackingInfo(url: String): Track { return withIOContext { - val statusListResponse = client.newCall(statusListRequest()).await().parseAs(MdUtil.jsonParser) + val mangaId = MdUtil.getMangaId(url) val request = GET( - MdUtil.mangaUrl + "/" + MdUtil.getMangaId(url), + MdUtil.mangaUrl + "/" + mangaId, + MdUtil.getAuthHeaders(headers, preferences, mdList), + CacheControl.FORCE_NETWORK + ) + val statusRequest = GET( + MdUtil.mangaUrl + "/" + mangaId + "/status", MdUtil.getAuthHeaders(headers, preferences, mdList), CacheControl.FORCE_NETWORK ) val response = client.newCall(request).await() - followStatusParse(response, statusListResponse) + val statusResponse = client.newCall(statusRequest).await() + followStatusParse(response, statusResponse) } } - private fun getFollowStatus(jsonObject: JsonObject, id: String) = - FollowStatus.fromDex(jsonObject["statuses"]?.jsonObject?.get(id)?.jsonPrimitive?.content) - - private fun statusListRequest(): Request { - return GET(MdUtil.mangaStatus, MdUtil.getAuthHeaders(headers, preferences, mdList), CacheControl.FORCE_NETWORK) + private fun mangaStatusListRequest(mangaListResponse: List): Request { + return GET(MdUtil.mangaStatus + "/" + mangaListResponse.joinToString("&ids[]=", "?ids[]=") { it.data.id }, MdUtil.getAuthHeaders(headers, preferences, mdList), CacheControl.FORCE_NETWORK) } } diff --git a/app/src/main/java/exh/md/handlers/serializers/ChapterSerializer.kt b/app/src/main/java/exh/md/handlers/serializers/ChapterSerializer.kt index 80a5fd14a..d1412fddd 100644 --- a/app/src/main/java/exh/md/handlers/serializers/ChapterSerializer.kt +++ b/app/src/main/java/exh/md/handlers/serializers/ChapterSerializer.kt @@ -27,7 +27,7 @@ data class NetworkChapter( @Serializable data class ChapterAttributes( val title: String?, - val volume: Int?, + val volume: String?, val chapter: String?, val translatedLanguage: String, val publishAt: String, diff --git a/app/src/main/java/exh/md/handlers/serializers/MangaSerializer.kt b/app/src/main/java/exh/md/handlers/serializers/MangaSerializer.kt index 2b9aed324..284ec37ac 100644 --- a/app/src/main/java/exh/md/handlers/serializers/MangaSerializer.kt +++ b/app/src/main/java/exh/md/handlers/serializers/MangaSerializer.kt @@ -27,14 +27,13 @@ data class NetworkMangaAttributes( val description: Map, val links: Map?, val originalLanguage: String, - val lastVolume: Int?, + val lastVolume: String?, val lastChapter: String, val contentRating: String?, val publicationDemographic: String?, val status: String?, val year: Int?, val tags: List - // val readingStatus: String? = null, ) @Serializable @@ -80,3 +79,13 @@ data class AuthorAttributes( data class UpdateReadingStatus( val status: String? ) + +@Serializable +data class MangaStatusResponse( + val status: String? +) + +@Serializable +data class MangaStatusListResponse( + val statuses: Map +)