From c9062cc0898fd0f43b32b89c1d75c835fb81d78b Mon Sep 17 00:00:00 2001 From: Carlos <2092019+CarlosEsco@users.noreply.github.com> Date: Wed, 6 Jan 2021 20:28:30 -0500 Subject: [PATCH] switch to v2 and api server + old style chapter urls for delegation (cherry picked from commit b79c1572470fea4568708d3526f5170868a0c3c1) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/ApiChapterParser.kt # app/src/main/java/eu/kanade/tachiyomi/source/online/handlers/FollowsHandler.kt # app/src/main/java/exh/md/handlers/SearchHandler.kt --- .../tachiyomi/source/online/all/MangaDex.kt | 2 +- .../java/exh/md/handlers/ApiChapterParser.kt | 13 +++---- .../java/exh/md/handlers/ApiMangaParser.kt | 2 +- .../java/exh/md/handlers/FollowsHandler.kt | 36 +++++++++---------- .../main/java/exh/md/handlers/MangaHandler.kt | 6 ++-- .../main/java/exh/md/handlers/PageHandler.kt | 2 +- .../java/exh/md/handlers/SearchHandler.kt | 2 +- .../serializers/ApiChapterSerializer.kt | 23 ++++++++++++ .../serializers/ApiMangaSerializer.kt | 2 +- .../serializers/FollowsPageSerializer.kt | 12 +++---- app/src/main/java/exh/md/utils/MdUtil.kt | 10 +++--- 11 files changed, 68 insertions(+), 42 deletions(-) create mode 100644 app/src/main/java/exh/md/handlers/serializers/ApiChapterSerializer.kt 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 b00ea6bc1..3285500bc 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 @@ -114,7 +114,7 @@ class MangaDex(delegate: HttpSource, val context: Context) : override fun mapUrlToChapterUrl(uri: Uri): String? { if (!uri.pathSegments.firstOrNull().equals("chapter", true)) return null val id = uri.pathSegments.getOrNull(1) ?: return null - return MdUtil.apiChapter + id + return MdUtil.apiChapterOld + id } override suspend fun mapChapterUrlToMangaUrl(uri: Uri): String? { diff --git a/app/src/main/java/exh/md/handlers/ApiChapterParser.kt b/app/src/main/java/exh/md/handlers/ApiChapterParser.kt index 1ec40fe2e..58768979f 100644 --- a/app/src/main/java/exh/md/handlers/ApiChapterParser.kt +++ b/app/src/main/java/exh/md/handlers/ApiChapterParser.kt @@ -1,26 +1,27 @@ package exh.md.handlers import eu.kanade.tachiyomi.source.model.Page +import exh.md.handlers.serializers.ApiChapterSerializer +import exh.md.utils.MdUtil import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonPrimitive import okhttp3.Response class ApiChapterParser { fun pageListParse(response: Response): List { val jsonData = response.body!!.string() - val json = Json.decodeFromString(jsonData) + val networkApiChapter = MdUtil.jsonParser.decodeFromString(jsonData) val pages = mutableListOf() - val hash = json["hash"]!!.jsonPrimitive.content - val pageArray = json["page_array"]!!.jsonArray - val server = json["server"]!!.jsonPrimitive.content + val hash = networkApiChapter.data.hash + val pageArray = networkApiChapter.data.pages + val server = networkApiChapter.data.server pageArray.forEach { - val url = "$hash/${it.jsonPrimitive.content}" + val url = "$hash/$it" pages.add(Page(pages.size, "$server,${response.request.url},${System.currentTimeMillis()}", url)) } diff --git a/app/src/main/java/exh/md/handlers/ApiMangaParser.kt b/app/src/main/java/exh/md/handlers/ApiMangaParser.kt index 9fc86d208..3d1b466a0 100644 --- a/app/src/main/java/exh/md/handlers/ApiMangaParser.kt +++ b/app/src/main/java/exh/md/handlers/ApiMangaParser.kt @@ -275,7 +275,7 @@ class ApiMangaParser(private val langs: List) { groups: Map ): SChapter { val chapter = SChapter.create() - chapter.url = MdUtil.apiChapter + networkChapter.id + chapter.url = MdUtil.apiChapterOld + networkChapter.id val chapterName = mutableListOf() // Build chapter name diff --git a/app/src/main/java/exh/md/handlers/FollowsHandler.kt b/app/src/main/java/exh/md/handlers/FollowsHandler.kt index 8fd40b96a..26af252f5 100644 --- a/app/src/main/java/exh/md/handlers/FollowsHandler.kt +++ b/app/src/main/java/exh/md/handlers/FollowsHandler.kt @@ -10,8 +10,8 @@ import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MetadataMangasPage import eu.kanade.tachiyomi.source.model.SManga -import exh.md.handlers.serializers.FollowsPageResult -import exh.md.handlers.serializers.Result +import exh.md.handlers.serializers.FollowPage +import exh.md.handlers.serializers.FollowsPageSerializer import exh.md.utils.FollowStatus import exh.md.utils.MdUtil import exh.metadata.metadata.MangaDexSearchMetadata @@ -50,15 +50,15 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere ) } catch (e: Exception) { XLog.tag("FollowsHandler").enableStackTrace(2).e("error parsing follows", e) - FollowsPageResult() + FollowsPageSerializer(emptyList()) } - if (followsPageResult.result.isEmpty()) { + if (followsPageResult.data.isEmpty()) { return MetadataMangasPage(emptyList(), false, emptyList()) } val lowQualityCovers = if (forceHd) false else useLowQualityCovers - val follows = followsPageResult.result.map { + val follows = followsPageResult.data.map { followFromElement(it, lowQualityCovers) } @@ -80,19 +80,19 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere ) } catch (e: Exception) { XLog.tag("FollowsHandler").enableStackTrace(2).e("error parsing follows", e) - FollowsPageResult() + FollowsPageSerializer(emptyList()) } val track = Track.create(TrackManager.MDLIST) - if (followsPageResult.result.isEmpty()) { + if (followsPageResult.data.isEmpty()) { track.status = FollowStatus.UNFOLLOWED.int } else { - val follow = followsPageResult.result.first() - track.status = follow.follow_type - if (followsPageResult.result[0].chapter.isNotBlank()) { + val follow = followsPageResult.data.first() + track.status = follow.followType + if (followsPageResult.data[0].chapter.isNotBlank()) { track.last_chapter_read = follow.chapter.toFloat().floor() } - track.tracking_url = MdUtil.baseUrl + follow.manga_id.toString() - track.title = follow.title + track.tracking_url = MdUtil.baseUrl + follow.mangaId.toString() + track.title = follow.mangaTitle } return track } @@ -101,22 +101,22 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere * build Request for follows page */ private fun followsListRequest(): Request { - return GET("${MdUtil.baseUrl}${MdUtil.followsAllApi}", headers, CacheControl.FORCE_NETWORK) + return GET("${MdUtil.apiUrl}${MdUtil.followsAllApi}", headers, CacheControl.FORCE_NETWORK) } /** * Parse result element to manga */ - private fun followFromElement(result: Result, lowQualityCovers: Boolean): Pair { + private fun followFromElement(result: FollowPage, lowQualityCovers: Boolean): Pair { val manga = SManga.create() - manga.title = MdUtil.cleanString(result.title) - manga.url = "/manga/${result.manga_id}/" + manga.title = MdUtil.cleanString(result.mangaTitle) + manga.url = "/manga/${result.mangaId}/" manga.thumbnail_url = MdUtil.formThumbUrl(manga.url, lowQualityCovers) return manga to MangaDexSearchMetadata().apply { title = manga.title mdUrl = manga.url thumbnail_url = manga.thumbnail_url - follow_status = FollowStatus.fromInt(result.follow_type)?.int + follow_status = FollowStatus.fromInt(result.followType)?.int } } @@ -211,7 +211,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere suspend fun fetchTrackingInfo(url: String): Track { return withContext(Dispatchers.IO) { val request = GET( - "${MdUtil.baseUrl}${MdUtil.followsMangaApi}" + MdUtil.getMangaId(url), + "${MdUtil.apiUrl}${MdUtil.followsMangaApi}" + MdUtil.getMangaId(url), headers, CacheControl.FORCE_NETWORK ) diff --git a/app/src/main/java/exh/md/handlers/MangaHandler.kt b/app/src/main/java/exh/md/handlers/MangaHandler.kt index bdc8111cf..3bd1ea91b 100644 --- a/app/src/main/java/exh/md/handlers/MangaHandler.kt +++ b/app/src/main/java/exh/md/handlers/MangaHandler.kt @@ -56,7 +56,7 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val langs: Li suspend fun getMangaIdFromChapterId(urlChapterId: String): Int { return withContext(Dispatchers.IO) { - val request = GET(MdUtil.baseUrl + MdUtil.apiChapter + urlChapterId + MdUtil.apiChapterSuffix, headers, CacheControl.FORCE_NETWORK) + val request = GET(MdUtil.apiUrl + MdUtil.apiChapter + urlChapterId + MdUtil.apiChapterSuffix, headers, CacheControl.FORCE_NETWORK) val response = client.newCall(request).await() ApiMangaParser(langs).chapterParseForMangaId(response) } @@ -126,10 +126,10 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val langs: Li } private fun apiRequest(manga: SManga): Request { - return GET(MdUtil.baseUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.url) + MdUtil.includeChapters, headers, CacheControl.FORCE_NETWORK) + return GET(MdUtil.apiUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.url) + MdUtil.includeChapters, headers, CacheControl.FORCE_NETWORK) } private fun coverRequest(manga: SManga): Request { - return GET(MdUtil.baseUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.url) + MdUtil.apiCovers, headers, CacheControl.FORCE_NETWORK) + return GET(MdUtil.apiUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.url) + MdUtil.apiCovers, headers, CacheControl.FORCE_NETWORK) } } diff --git a/app/src/main/java/exh/md/handlers/PageHandler.kt b/app/src/main/java/exh/md/handlers/PageHandler.kt index 5d56c9c6f..ff6b43caf 100644 --- a/app/src/main/java/exh/md/handlers/PageHandler.kt +++ b/app/src/main/java/exh/md/handlers/PageHandler.kt @@ -32,6 +32,6 @@ class PageHandler(val client: OkHttpClient, val headers: Headers, private val im private fun pageListRequest(chapter: SChapter): Request { val chpUrl = chapter.url.substringBefore(MdUtil.apiChapterSuffix) - return GET("${MdUtil.baseUrl}${chpUrl}${MdUtil.apiChapterSuffix}&server=$imageServer&saver=$dataSaver", headers, CacheControl.FORCE_NETWORK) + return GET("${MdUtil.apiUrl}${chpUrl}${MdUtil.apiChapterSuffix}&server=$imageServer&saver=$dataSaver", headers, CacheControl.FORCE_NETWORK) } } diff --git a/app/src/main/java/exh/md/handlers/SearchHandler.kt b/app/src/main/java/exh/md/handlers/SearchHandler.kt index a112c349e..0ce230f20 100644 --- a/app/src/main/java/exh/md/handlers/SearchHandler.kt +++ b/app/src/main/java/exh/md/handlers/SearchHandler.kt @@ -193,7 +193,7 @@ class SearchHandler(val client: OkHttpClient, private val headers: Headers, val } private fun searchMangaByIdRequest(id: String): Request { - return GET(MdUtil.baseUrl + MdUtil.apiManga + id, headers, CacheControl.FORCE_NETWORK) + return GET(MdUtil.apiUrl + MdUtil.apiManga + id + MdUtil.includeChapters, headers, CacheControl.FORCE_NETWORK) } private fun searchMangaByGroupRequest(group: String): Request { diff --git a/app/src/main/java/exh/md/handlers/serializers/ApiChapterSerializer.kt b/app/src/main/java/exh/md/handlers/serializers/ApiChapterSerializer.kt new file mode 100644 index 000000000..a58e42c70 --- /dev/null +++ b/app/src/main/java/exh/md/handlers/serializers/ApiChapterSerializer.kt @@ -0,0 +1,23 @@ +package exh.md.handlers.serializers + +import kotlinx.serialization.Serializable + +/* + * Copyright (C) 2020 The Neko Manga Open Source Project + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +@Serializable +data class ApiChapterSerializer( + val data: ChapterPageSerializer +) + +@Serializable +data class ChapterPageSerializer( + val hash: String, + val pages: List, + val server: String +) diff --git a/app/src/main/java/exh/md/handlers/serializers/ApiMangaSerializer.kt b/app/src/main/java/exh/md/handlers/serializers/ApiMangaSerializer.kt index 528bd5228..35368630e 100644 --- a/app/src/main/java/exh/md/handlers/serializers/ApiMangaSerializer.kt +++ b/app/src/main/java/exh/md/handlers/serializers/ApiMangaSerializer.kt @@ -73,4 +73,4 @@ data class ChapterSerializer( data class GroupSerializer( val id: Long, val name: String? = null -) \ No newline at end of file +) diff --git a/app/src/main/java/exh/md/handlers/serializers/FollowsPageSerializer.kt b/app/src/main/java/exh/md/handlers/serializers/FollowsPageSerializer.kt index 1114f586c..1b8bb33a4 100644 --- a/app/src/main/java/exh/md/handlers/serializers/FollowsPageSerializer.kt +++ b/app/src/main/java/exh/md/handlers/serializers/FollowsPageSerializer.kt @@ -3,15 +3,15 @@ package exh.md.handlers.serializers import kotlinx.serialization.Serializable @Serializable -data class FollowsPageResult( - val result: List = emptyList() +data class FollowsPageSerializer( + val data: List ) @Serializable -data class Result( - val title: String, +data class FollowPage( + val mangaTitle: String, val chapter: String, - val follow_type: Int, - val manga_id: Int, + val followType: Int, + val mangaId: Int, val volume: String ) diff --git a/app/src/main/java/exh/md/utils/MdUtil.kt b/app/src/main/java/exh/md/utils/MdUtil.kt index 2f89adc0b..2db968111 100644 --- a/app/src/main/java/exh/md/utils/MdUtil.kt +++ b/app/src/main/java/exh/md/utils/MdUtil.kt @@ -23,13 +23,15 @@ class MdUtil { const val cdnUrl = "https://mangadex.org" // "https://s0.mangadex.org" const val baseUrl = "https://mangadex.org" const val randMangaPage = "/manga/" - const val apiManga = "/api/v2/manga/" + const val apiUrl = "https://api.mangadex.org" + const val apiManga = "/v2/manga/" const val includeChapters = "?include=chapters" - const val apiChapter = "/api/chapter/" + const val apiChapter = "/v2/chapter/" + const val apiChapterOld = "/api/chapter/" const val apiChapterSuffix = "?mark_read=0" const val groupSearchUrl = "$baseUrl/groups/0/1/" - const val followsAllApi = "/api/?type=manga_follows" - const val followsMangaApi = "/api/?type=manga_follows&manga_id=" + const val followsAllApi = "/v2/user/me/followed-manga" + const val followsMangaApi = "/v2/user/me/manga/" const val apiCovers = "/covers" const val reportUrl = "https://api.mangadex.network/report" const val imageUrl = "$baseUrl/data"