Mangadex code cleanup

This commit is contained in:
Jobobby04 2021-01-15 22:29:57 -05:00
parent ae15a178e5
commit 37787f040c
6 changed files with 63 additions and 58 deletions

View File

@ -114,9 +114,9 @@ fun OkHttpClient.newCallWithProgress(request: Request, listener: ProgressListene
return progressClient.newCall(request)
}
inline fun <reified T> Response.parseAs(): T {
inline fun <reified T> Response.parseAs(/* SY --> */ json: Json = Injekt.getInstance(fullType<Json>().type) /* SY <-- */): T {
// Avoiding Injekt.get<Json>() due to compiler issues
val json = Injekt.getInstance<Json>(fullType<Json>().type)
// val json = Injekt.getInstance<Json>(fullType<Json>().type)
this.use {
val responseBody = it.body?.string().orEmpty()
return json.decodeFromString(responseBody)

View File

@ -56,12 +56,14 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Request
import okhttp3.Response
import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
import kotlin.reflect.KClass
@Suppress("OverridingDeprecatedMember")
class MangaDex(delegate: HttpSource, val context: Context) :
DelegatedHttpSource(delegate),
MetadataSource<MangaDexSearchMetadata, Response>,
@ -112,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
val id = uri.pathSegments.getOrNull(1)?.toIntOrNull() ?: return null
return MdUtil.oldApiChapter + id
}
@ -134,6 +136,10 @@ class MangaDex(delegate: HttpSource, val context: Context) :
return MangaHandler(client, headers, mdLang, preferences.mangaDexForceLatestCovers().get()).fetchChapterListObservable(manga)
}
override suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
return MangaHandler(client, headers, mdLang, preferences.mangaDexForceLatestCovers().get()).getChapterList(manga)
}
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
return if (chapter.scanlator == "MangaPlus") {
client.newCall(mangaPlusPageListRequest(chapter))

View File

@ -10,6 +10,7 @@ import eu.kanade.tachiyomi.source.online.RandomMangaSource
import eu.kanade.tachiyomi.ui.base.controller.BaseController
import eu.kanade.tachiyomi.ui.base.controller.withFadeTransaction
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceController
import eu.kanade.tachiyomi.util.lang.withIOContext
import exh.md.follows.MangaDexFollowsController
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@ -38,9 +39,10 @@ class MangaDexFabHeaderAdapter(val controller: BaseController<*>, val source: Ca
}
binding.mangadexRandom.clicks()
.onEach {
(source as? RandomMangaSource)?.fetchRandomMangaUrl()?.let { randomMangaId ->
controller.router.replaceTopController(BrowseSourceController(source, randomMangaId).withFadeTransaction())
val randomMangaUrl = withIOContext {
(source as? RandomMangaSource)?.fetchRandomMangaUrl()
}
controller.router.replaceTopController(BrowseSourceController(source, randomMangaUrl).withFadeTransaction())
}.launchIn(controller.viewScope)
}
}

View File

@ -1,5 +1,6 @@
package exh.md.handlers
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.model.Page
import exh.md.handlers.serializers.ApiChapterSerializer
import exh.md.utils.MdUtil
@ -11,22 +12,18 @@ import kotlinx.serialization.json.jsonPrimitive
import okhttp3.Response
class ApiChapterParser {
// Only used in [PageHandler], which means its currently unused, kept for reference
fun pageListParse(response: Response): List<Page> {
val jsonData = response.body!!.string()
val networkApiChapter = MdUtil.jsonParser.decodeFromString<ApiChapterSerializer>(jsonData)
val pages = mutableListOf<Page>()
val networkApiChapter = response.parseAs<ApiChapterSerializer>(MdUtil.jsonParser)
val hash = networkApiChapter.data.hash
val pageArray = networkApiChapter.data.pages
val server = networkApiChapter.data.server
pageArray.forEach {
val url = "$hash/$it"
pages.add(Page(pages.size, "$server,${response.request.url},${System.currentTimeMillis()}", url))
return pageArray.mapIndexed { index, page ->
val url = "$hash/$page"
Page(index, "$server,${response.request.url},${System.currentTimeMillis()}", url)
}
return pages
}
fun externalParse(response: Response): String {

View File

@ -3,7 +3,7 @@ package exh.md.handlers
import com.elvishew.xlog.XLog
import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup
import exh.md.handlers.serializers.ApiMangaSerializer
@ -26,6 +26,7 @@ import kotlinx.serialization.json.jsonPrimitive
import okhttp3.Response
import rx.Completable
import rx.Single
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -94,7 +95,7 @@ class ApiMangaParser(private val lang: String) {
fun parseIntoMetadata(metadata: MangaDexSearchMetadata, input: Response, coverUrls: List<String>) {
with(metadata) {
try {
val networkApiManga = MdUtil.jsonParser.decodeFromString<ApiMangaSerializer>(input.body!!.string())
val networkApiManga = input.parseAs<ApiMangaSerializer>(MdUtil.jsonParser)
val networkManga = networkApiManga.data.manga
mdId = MdUtil.getMangaId(input.request.url.toString())
mdUrl = input.request.url.toString()
@ -222,13 +223,12 @@ class ApiMangaParser(private val lang: String) {
return MdUtil.getMangaId(randMangaUrl)
}
fun chapterListParse(response: Response): List<SChapter> {
return chapterListParse(response.body!!.string())
fun chapterListParse(response: Response): List<ChapterInfo> {
return chapterListParse(response.parseAs<ApiMangaSerializer>(MdUtil.jsonParser))
}
fun chapterListParse(jsonData: String): List<SChapter> {
fun chapterListParse(networkApiManga: ApiMangaSerializer): List<ChapterInfo> {
val now = System.currentTimeMillis()
val networkApiManga = MdUtil.jsonParser.decodeFromString<ApiMangaSerializer>(jsonData)
val networkManga = networkApiManga.data.manga
val networkChapters = networkApiManga.data.chapters
val groups = networkApiManga.data.groups.mapNotNull {
@ -245,10 +245,10 @@ class ApiMangaParser(private val lang: String) {
// Skip chapters that don't match the desired language, or are future releases
val chapLangs = MdLang.values().filter { lang == it.dexLang }
val chapLang = MdLang.values().firstOrNull { lang == it.dexLang }
return networkChapters.asSequence()
.filter { lang == it.language && (it.timestamp * 1000) <= now }
.map { mapChapter(it, finalChapterNumber, status, chapLangs, networkChapters.size, groups) }.toList()
.map { mapChapter(it, finalChapterNumber, status, chapLang, networkChapters.size, groups) }.toList()
}
fun chapterParseForMangaId(response: Response): Int {
@ -271,14 +271,14 @@ class ApiMangaParser(private val lang: String) {
networkChapter: ChapterSerializer,
finalChapterNumber: String?,
status: Int,
chapLangs: List<MdLang>,
chapLang: MdLang?,
totalChapterCount: Int,
groups: Map<Long, String>
): SChapter {
val chapter = SChapter.create()
chapter.url = MdUtil.oldApiChapter + networkChapter.id
val chapterName = mutableListOf<String>()
): ChapterInfo {
val key = MdUtil.oldApiChapter + networkChapter.id
// Build chapter name
val chapterName = mutableListOf<String>()
if (!networkChapter.volume.isNullOrBlank()) {
val vol = "Vol." + networkChapter.volume
@ -315,19 +315,24 @@ class ApiMangaParser(private val lang: String) {
}
}
chapter.name = MdUtil.cleanString(chapterName.joinToString(" "))
val name = MdUtil.cleanString(chapterName.joinToString(" "))
// Convert from unix time
chapter.date_upload = networkChapter.timestamp * 1000
val dateUpload = networkChapter.timestamp * 1000
val scanlatorName = mutableSetOf<String>()
networkChapter.groups.mapNotNull { groups[it] }.forEach { scanlatorName.add(it) }
chapter.scanlator = MdUtil.cleanString(MdUtil.getScanlatorString(scanlatorName))
val scanlator = MdUtil.cleanString(MdUtil.getScanlatorString(scanlatorName))
// chapter.mangadex_chapter_id = MdUtil.getChapterId(chapter.url)
// val mangadexChapterId = MdUtil.getChapterId(chapter.url)
// chapter.language = chapLangs.firstOrNull { it.dexLang == networkChapter.language }?.name
// val language = chapLang?.name
return chapter
return ChapterInfo(
key = key,
name = name,
dateUpload = dateUpload,
scanlator = scanlator
)
}
}

View File

@ -1,6 +1,5 @@
package exh.md.handlers
import com.elvishew.xlog.XLog
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.network.await
@ -8,45 +7,41 @@ import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.toMangaInfo
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.util.lang.runAsObservable
import eu.kanade.tachiyomi.util.lang.withIOContext
import exh.md.handlers.serializers.ApiCovers
import exh.md.handlers.serializers.ApiMangaSerializer
import exh.md.utils.MdUtil
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import rx.Observable
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: String, val forceLatestCovers: Boolean = false) {
// TODO make use of this
suspend fun fetchMangaAndChapterDetails(manga: MangaInfo, sourceId: Long): Pair<MangaInfo, List<SChapter>> {
suspend fun fetchMangaAndChapterDetails(manga: MangaInfo, sourceId: Long): Pair<MangaInfo, List<ChapterInfo>> {
return withIOContext {
val response = client.newCall(apiRequest(manga.toSManga())).await()
val apiNetworkManga = client.newCall(apiRequest(manga)).await().parseAs<ApiMangaSerializer>()
val covers = getCovers(manga, forceLatestCovers)
val parser = ApiMangaParser(lang)
val jsonData = withIOContext { response.body!!.string() }
if (response.code != 200) {
XLog.tag("MangaHandler").enableStackTrace(2).e("error from MangaDex with response code ${response.code} \n body: \n$jsonData")
throw Exception("Error from MangaDex Response code ${response.code} ")
}
// TODO fix this
/*val mangaInfo = parser.parseToManga(manga, response, covers, sourceId)
val chapterList = parser.chapterListParse(apiNetworkManga)
parser.parseToManga(manga, response, covers, sourceId)
val chapterList = parser.chapterListParse(jsonData)
Pair(
manga,
chapterList
)
mangaInfo to chapterList*/
manga to emptyList()
}
}
suspend fun getCovers(manga: MangaInfo, forceLatestCovers: Boolean): List<String> {
return if (forceLatestCovers) {
val covers = client.newCall(coverRequest(manga.toSManga())).await().parseAs<ApiCovers>()
val covers = client.newCall(coverRequest(manga)).await().parseAs<ApiCovers>(MdUtil.jsonParser)
covers.data.map { it.url }
} else {
emptyList()
@ -63,14 +58,14 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: Str
suspend fun getMangaDetails(manga: MangaInfo, sourceId: Long): MangaInfo {
return withIOContext {
val response = client.newCall(apiRequest(manga.toSManga())).await()
val response = client.newCall(apiRequest(manga)).await()
val covers = getCovers(manga, forceLatestCovers)
ApiMangaParser(lang).parseToManga(manga, response, covers, sourceId)
}
}
fun fetchMangaDetailsObservable(manga: SManga): Observable<SManga> {
return client.newCall(apiRequest(manga))
return client.newCall(apiRequest(manga.toMangaInfo()))
.asObservableSuccess()
.flatMap { response ->
runAsObservable({
@ -91,14 +86,14 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: Str
}
fun fetchChapterListObservable(manga: SManga): Observable<List<SChapter>> {
return client.newCall(apiRequest(manga))
return client.newCall(apiRequest(manga.toMangaInfo()))
.asObservableSuccess()
.map { response ->
ApiMangaParser(lang).chapterListParse(response)
ApiMangaParser(lang).chapterListParse(response).map { it.toSChapter() }
}
}
suspend fun fetchChapterList(manga: SManga): List<SChapter> {
suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
return withIOContext {
val response = client.newCall(apiRequest(manga)).await()
ApiMangaParser(lang).chapterListParse(response)
@ -124,11 +119,11 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: Str
return GET(MdUtil.baseUrl + MdUtil.randMangaPage, cache = CacheControl.Builder().noCache().build())
}
private fun apiRequest(manga: SManga): Request {
return GET(MdUtil.apiUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.url) + MdUtil.includeChapters, headers, CacheControl.FORCE_NETWORK)
private fun apiRequest(manga: MangaInfo): Request {
return GET(MdUtil.apiUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.key) + MdUtil.includeChapters, headers, CacheControl.FORCE_NETWORK)
}
private fun coverRequest(manga: SManga): Request {
return GET(MdUtil.apiUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.url) + MdUtil.apiCovers, headers, CacheControl.FORCE_NETWORK)
private fun coverRequest(manga: MangaInfo): Request {
return GET(MdUtil.apiUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.key) + MdUtil.apiCovers, headers, CacheControl.FORCE_NETWORK)
}
}