komikku/app/src/main/java/exh/md/handlers/MangaHandler.kt

164 lines
6.4 KiB
Kotlin
Raw Normal View History

package exh.md.handlers
import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.mdlist.MdList
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.await
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
2021-01-16 04:29:57 +01:00
import eu.kanade.tachiyomi.source.model.toSChapter
import eu.kanade.tachiyomi.source.model.toSManga
import eu.kanade.tachiyomi.util.lang.runAsObservable
import eu.kanade.tachiyomi.util.lang.withIOContext
import exh.md.handlers.serializers.ChapterResponse
import exh.md.handlers.serializers.GroupListResponse
import exh.md.utils.MdUtil
2021-05-11 19:06:55 +02:00
import exh.md.utils.mdListCall
import exh.metadata.metadata.MangaDexSearchMetadata
import kotlinx.coroutines.async
import okhttp3.CacheControl
import okhttp3.Headers
import okhttp3.OkHttpClient
import okhttp3.Request
import rx.Observable
2021-01-16 04:29:57 +01:00
import tachiyomi.source.model.ChapterInfo
import tachiyomi.source.model.MangaInfo
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class MangaHandler(val client: OkHttpClient, val headers: Headers, private val lang: String, private val forceLatestCovers: Boolean = false) {
2021-01-16 04:29:57 +01:00
suspend fun fetchMangaAndChapterDetails(manga: MangaInfo, sourceId: Long): Pair<MangaInfo, List<ChapterInfo>> {
return withIOContext {
val response = client.newCall(mangaRequest(manga)).await()
val covers = getCovers(manga, forceLatestCovers)
val parser = ApiMangaParser(client, lang)
parser.parseToManga(manga, response, covers, sourceId) to getChapterList(manga)
}
}
suspend fun getCovers(manga: MangaInfo, forceLatestCovers: Boolean): List<String> {
/* if (forceLatestCovers) {
val covers = client.newCall(coverRequest(manga)).await().parseAs<ApiCovers>(MdUtil.jsonParser)
return covers.data.map { it.url }
} else {*/
return emptyList<String>()
// }
}
suspend fun getMangaIdFromChapterId(urlChapterId: String): String {
return withIOContext {
val request = GET(MdUtil.chapterUrl + urlChapterId)
2020-10-28 00:52:32 +01:00
val response = client.newCall(request).await()
ApiMangaParser(client, lang).chapterParseForMangaId(response)
}
}
suspend fun getMangaDetails(manga: MangaInfo, sourceId: Long): MangaInfo {
2021-05-10 05:27:18 +02:00
val response = withIOContext { client.newCall(mangaRequest(manga)).await() }
val covers = withIOContext { getCovers(manga, forceLatestCovers) }
return ApiMangaParser(client, lang).parseToManga(manga, response, covers, sourceId)
}
fun fetchMangaDetailsObservable(manga: SManga, sourceId: Long): Observable<SManga> {
2021-05-11 19:06:55 +02:00
return runAsObservable({
getMangaDetails(manga.toMangaInfo(), sourceId).toSManga()
})
}
2021-05-11 19:06:55 +02:00
fun fetchChapterListObservable(manga: SManga): Observable<List<SChapter>> = runAsObservable({
getChapterList(manga.toMangaInfo()).map { it.toSChapter() }
})
2021-01-16 04:29:57 +01:00
suspend fun getChapterList(manga: MangaInfo): List<ChapterInfo> {
return withIOContext {
2021-05-11 19:06:55 +02:00
val results = client.mdListCall<ChapterResponse> {
mangaFeedRequest(manga, it, lang)
}
val groupMap = getGroupMap(results)
ApiMangaParser(client, lang).chapterListParse(results, groupMap)
}
}
private suspend fun getGroupMap(results: List<ChapterResponse>): Map<String, String> {
val groupIds = results.asSequence()
2021-05-11 19:06:55 +02:00
.flatMap { chapter -> chapter.relationships }
.filter { it.type == "scanlation_group" }
.map { it.id }
2021-05-11 19:06:55 +02:00
.toSet()
return runCatching {
groupIds.chunked(100).flatMapIndexed { index, ids ->
val response = client.newCall(groupIdRequest(ids, 100 * index)).await()
if (response.code != 204) {
response
.parseAs<GroupListResponse>(MdUtil.jsonParser)
2021-05-11 19:06:55 +02:00
.results.map { group -> group.data.id to group.data.attributes.name }
} else {
emptyList()
}
}.toMap()
2021-05-11 19:06:55 +02:00
}.getOrNull().orEmpty()
}
2020-12-26 20:22:55 +01:00
suspend fun fetchRandomMangaId(): String {
return withIOContext {
val response = client.newCall(randomMangaRequest()).await()
ApiMangaParser(client, lang).randomMangaIdParse(response)
}
}
2021-05-07 19:41:33 +02:00
suspend fun getTrackingInfo(track: Track, useLowQualityCovers: Boolean, mdList: MdList): Pair<Track, MangaDexSearchMetadata?> {
return withIOContext {
val metadata = async {
val mangaUrl = "/manga/" + MdUtil.getMangaId(track.tracking_url)
val manga = MangaInfo(mangaUrl, track.title)
val response = client.newCall(mangaRequest(manga)).await()
val metadata = MangaDexSearchMetadata()
ApiMangaParser(client, lang).parseIntoMetadata(metadata, response, emptyList())
metadata
}
val remoteTrack = async {
FollowsHandler(
client,
headers,
Injekt.get(),
lang,
useLowQualityCovers,
mdList
).fetchTrackingInfo(track.tracking_url)
}
2021-05-07 19:41:33 +02:00
remoteTrack.await() to null
}
}
private fun randomMangaRequest(): Request {
return GET(MdUtil.randomMangaUrl, cache = CacheControl.FORCE_NETWORK)
}
private fun mangaRequest(manga: MangaInfo): Request {
return GET(MdUtil.mangaUrl + "/" + MdUtil.getMangaId(manga.key), headers, CacheControl.FORCE_NETWORK)
}
private fun mangaFeedRequest(manga: MangaInfo, offset: Int, lang: String): Request {
return GET(MdUtil.mangaFeedUrl(MdUtil.getMangaId(manga.key), offset, lang), headers, CacheControl.FORCE_NETWORK)
}
private fun groupIdRequest(id: List<String>, offset: Int): Request {
val urlSuffix = id.joinToString("&ids[]=", "?limit=100&offset=$offset&ids[]=")
return GET(MdUtil.groupUrl + urlSuffix, headers)
}
/* private fun coverRequest(manga: SManga): Request {
return GET(MdUtil.apiUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.url) + MdUtil.apiCovers, headers, CacheControl.FORCE_NETWORK)
}*/
companion object {
}
}