2020-08-21 02:50:37 +02:00
|
|
|
package exh.md.handlers
|
|
|
|
|
|
|
|
|
|
import com.elvishew.xlog.XLog
|
|
|
|
|
import eu.kanade.tachiyomi.network.GET
|
|
|
|
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
2020-09-12 05:12:13 +02:00
|
|
|
import eu.kanade.tachiyomi.network.await
|
2020-11-08 02:29:00 +01:00
|
|
|
import eu.kanade.tachiyomi.network.parseAs
|
2020-08-21 02:50:37 +02:00
|
|
|
import eu.kanade.tachiyomi.source.model.SChapter
|
|
|
|
|
import eu.kanade.tachiyomi.source.model.SManga
|
2020-11-08 02:29:00 +01:00
|
|
|
import eu.kanade.tachiyomi.source.model.toMangaInfo
|
2021-01-02 09:11:20 +01:00
|
|
|
import eu.kanade.tachiyomi.source.model.toSManga
|
2020-11-08 02:29:00 +01:00
|
|
|
import eu.kanade.tachiyomi.util.lang.runAsObservable
|
|
|
|
|
import exh.md.handlers.serializers.ApiCovers
|
2020-08-21 02:50:37 +02:00
|
|
|
import exh.md.utils.MdUtil
|
|
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
|
import kotlinx.coroutines.withContext
|
|
|
|
|
import okhttp3.CacheControl
|
|
|
|
|
import okhttp3.Headers
|
|
|
|
|
import okhttp3.OkHttpClient
|
|
|
|
|
import okhttp3.Request
|
|
|
|
|
import rx.Observable
|
2021-01-02 09:11:20 +01:00
|
|
|
import tachiyomi.source.model.MangaInfo
|
2020-08-21 02:50:37 +02:00
|
|
|
|
2020-09-12 05:12:13 +02:00
|
|
|
class MangaHandler(val client: OkHttpClient, val headers: Headers, val langs: List<String>, val forceLatestCovers: Boolean = false) {
|
2020-08-21 02:50:37 +02:00
|
|
|
|
|
|
|
|
// TODO make use of this
|
2020-11-08 02:29:00 +01:00
|
|
|
suspend fun fetchMangaAndChapterDetails(manga: MangaInfo, sourceId: Long): Pair<MangaInfo, List<SChapter>> {
|
2020-08-21 02:50:37 +02:00
|
|
|
return withContext(Dispatchers.IO) {
|
2020-11-08 02:29:00 +01:00
|
|
|
val response = client.newCall(apiRequest(manga.toSManga())).await()
|
|
|
|
|
val covers = getCovers(manga, forceLatestCovers)
|
2020-08-21 02:50:37 +02:00
|
|
|
val parser = ApiMangaParser(langs)
|
|
|
|
|
|
2020-10-28 00:52:32 +01:00
|
|
|
val jsonData = withContext(Dispatchers.IO) { response.body!!.string() }
|
2020-08-21 02:50:37 +02:00
|
|
|
if (response.code != 200) {
|
2020-11-25 21:57:05 +01:00
|
|
|
XLog.tag("MangaHandler").enableStackTrace(2).e("error from MangaDex with response code ${response.code} \n body: \n$jsonData")
|
2020-08-21 02:50:37 +02:00
|
|
|
throw Exception("Error from MangaDex Response code ${response.code} ")
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-08 02:29:00 +01:00
|
|
|
parser.parseToManga(manga, response, covers, sourceId)
|
2020-08-21 02:50:37 +02:00
|
|
|
val chapterList = parser.chapterListParse(jsonData)
|
|
|
|
|
Pair(
|
|
|
|
|
manga,
|
|
|
|
|
chapterList
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-08 02:29:00 +01:00
|
|
|
suspend fun getCovers(manga: MangaInfo, forceLatestCovers: Boolean): List<String> {
|
|
|
|
|
return if (forceLatestCovers) {
|
|
|
|
|
val covers = client.newCall(coverRequest(manga.toSManga())).await().parseAs<ApiCovers>()
|
|
|
|
|
covers.data.map { it.url }
|
|
|
|
|
} else {
|
|
|
|
|
emptyList()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-21 02:50:37 +02:00
|
|
|
suspend fun getMangaIdFromChapterId(urlChapterId: String): Int {
|
|
|
|
|
return withContext(Dispatchers.IO) {
|
2021-01-08 22:22:33 +01:00
|
|
|
val request = GET(MdUtil.apiUrl + MdUtil.newApiChapter + urlChapterId + MdUtil.apiChapterSuffix, headers, CacheControl.FORCE_NETWORK)
|
2020-10-28 00:52:32 +01:00
|
|
|
val response = client.newCall(request).await()
|
2020-08-21 02:50:37 +02:00
|
|
|
ApiMangaParser(langs).chapterParseForMangaId(response)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-02 09:11:20 +01:00
|
|
|
suspend fun getMangaDetails(manga: MangaInfo, sourceId: Long): MangaInfo {
|
|
|
|
|
return withContext(Dispatchers.IO) {
|
|
|
|
|
val response = client.newCall(apiRequest(manga.toSManga())).await()
|
2020-11-08 02:29:00 +01:00
|
|
|
val covers = getCovers(manga, forceLatestCovers)
|
|
|
|
|
ApiMangaParser(langs).parseToManga(manga, response, covers, sourceId)
|
2021-01-02 09:11:20 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-21 02:50:37 +02:00
|
|
|
fun fetchMangaDetailsObservable(manga: SManga): Observable<SManga> {
|
|
|
|
|
return client.newCall(apiRequest(manga))
|
|
|
|
|
.asObservableSuccess()
|
2020-11-08 02:29:00 +01:00
|
|
|
.flatMap { response ->
|
|
|
|
|
runAsObservable({
|
|
|
|
|
getCovers(manga.toMangaInfo(), forceLatestCovers)
|
|
|
|
|
}).map {
|
|
|
|
|
response to it
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-21 02:50:37 +02:00
|
|
|
.flatMap {
|
2020-11-08 02:29:00 +01:00
|
|
|
ApiMangaParser(langs).parseToManga(manga, it.first, it.second).andThen(
|
2020-08-21 02:50:37 +02:00
|
|
|
Observable.just(
|
|
|
|
|
manga.apply {
|
|
|
|
|
initialized = true
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun fetchChapterListObservable(manga: SManga): Observable<List<SChapter>> {
|
|
|
|
|
return client.newCall(apiRequest(manga))
|
|
|
|
|
.asObservableSuccess()
|
|
|
|
|
.map { response ->
|
|
|
|
|
ApiMangaParser(langs).chapterListParse(response)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
suspend fun fetchChapterList(manga: SManga): List<SChapter> {
|
|
|
|
|
return withContext(Dispatchers.IO) {
|
2020-10-28 00:52:32 +01:00
|
|
|
val response = client.newCall(apiRequest(manga)).await()
|
2020-08-21 02:50:37 +02:00
|
|
|
ApiMangaParser(langs).chapterListParse(response)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-12 05:12:13 +02:00
|
|
|
fun fetchRandomMangaIdObservable(): Observable<String> {
|
2020-08-21 02:50:37 +02:00
|
|
|
return client.newCall(randomMangaRequest())
|
|
|
|
|
.asObservableSuccess()
|
|
|
|
|
.map { response ->
|
|
|
|
|
ApiMangaParser(langs).randomMangaIdParse(response)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-26 20:22:55 +01:00
|
|
|
suspend fun fetchRandomMangaId(): String {
|
|
|
|
|
return withContext(Dispatchers.IO) {
|
2020-09-12 05:12:13 +02:00
|
|
|
val response = client.newCall(randomMangaRequest()).await()
|
2020-12-26 20:22:55 +01:00
|
|
|
ApiMangaParser(langs).randomMangaIdParse(response)
|
2020-09-12 05:12:13 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-21 02:50:37 +02:00
|
|
|
private fun randomMangaRequest(): Request {
|
2020-11-14 04:40:35 +01:00
|
|
|
return GET(MdUtil.baseUrl + MdUtil.randMangaPage, cache = CacheControl.Builder().noCache().build())
|
2020-08-21 02:50:37 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun apiRequest(manga: SManga): Request {
|
2021-01-07 02:28:30 +01:00
|
|
|
return GET(MdUtil.apiUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.url) + MdUtil.includeChapters, headers, CacheControl.FORCE_NETWORK)
|
2020-11-08 02:29:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private fun coverRequest(manga: SManga): Request {
|
2021-01-07 02:28:30 +01:00
|
|
|
return GET(MdUtil.apiUrl + MdUtil.apiManga + MdUtil.getMangaId(manga.url) + MdUtil.apiCovers, headers, CacheControl.FORCE_NETWORK)
|
2020-08-21 02:50:37 +02:00
|
|
|
}
|
|
|
|
|
}
|