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
This commit is contained in:
Carlos 2021-01-06 20:28:30 -05:00 committed by Jobobby04
parent ac2301e4be
commit c9062cc089
11 changed files with 68 additions and 42 deletions

View File

@ -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? {

View File

@ -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<Page> {
val jsonData = response.body!!.string()
val json = Json.decodeFromString<JsonObject>(jsonData)
val networkApiChapter = MdUtil.jsonParser.decodeFromString<ApiChapterSerializer>(jsonData)
val pages = mutableListOf<Page>()
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))
}

View File

@ -275,7 +275,7 @@ class ApiMangaParser(private val langs: List<String>) {
groups: Map<Long, String>
): SChapter {
val chapter = SChapter.create()
chapter.url = MdUtil.apiChapter + networkChapter.id
chapter.url = MdUtil.apiChapterOld + networkChapter.id
val chapterName = mutableListOf<String>()
// Build chapter name

View File

@ -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<SManga, MangaDexSearchMetadata> {
private fun followFromElement(result: FollowPage, lowQualityCovers: Boolean): Pair<SManga, MangaDexSearchMetadata> {
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
)

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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<String>,
val server: String
)

View File

@ -73,4 +73,4 @@ data class ChapterSerializer(
data class GroupSerializer(
val id: Long,
val name: String? = null
)
)

View File

@ -3,15 +3,15 @@ package exh.md.handlers.serializers
import kotlinx.serialization.Serializable
@Serializable
data class FollowsPageResult(
val result: List<Result> = emptyList()
data class FollowsPageSerializer(
val data: List<FollowPage>
)
@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
)

View File

@ -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"