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 f40a365fd..65115b46f 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 @@ -28,10 +28,12 @@ import exh.md.MangaDexFabHeaderAdapter import exh.md.dto.MangaDto import exh.md.dto.StatisticsMangaDto import exh.md.handlers.ApiMangaParser +import exh.md.handlers.AzukiHandler import exh.md.handlers.BilibiliHandler import exh.md.handlers.ComikeyHandler import exh.md.handlers.FollowsHandler import exh.md.handlers.MangaHandler +import exh.md.handlers.MangaHotHandler import exh.md.handlers.MangaPlusHandler import exh.md.handlers.PageHandler import exh.md.handlers.SimilarHandler @@ -122,6 +124,12 @@ class MangaDex(delegate: HttpSource, val context: Context) : private val bilibiliHandler by lazy { BilibiliHandler(network.cloudflareClient) } + private val azukHandler by lazy { + AzukiHandler(network.client) + } + private val mangaHotHandler by lazy { + MangaHotHandler(network.client) + } private val pageHandler by lazy { PageHandler( headers, @@ -129,6 +137,8 @@ class MangaDex(delegate: HttpSource, val context: Context) : mangaPlusHandler, comikeyHandler, bilibiliHandler, + azukHandler, + mangaHotHandler, preferences, mdList ) diff --git a/app/src/main/java/exh/md/handlers/AzukiHandler.kt b/app/src/main/java/exh/md/handlers/AzukiHandler.kt new file mode 100644 index 000000000..fb8fa891e --- /dev/null +++ b/app/src/main/java/exh/md/handlers/AzukiHandler.kt @@ -0,0 +1,43 @@ +package exh.md.handlers + +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.await +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.online.HttpSource +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import okhttp3.Headers +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response + +class AzukiHandler(currentClient: OkHttpClient) { + val baseUrl = "https://www.azuki.co" + private val apiUrl = "https://production.api.azuki.co" + val headers = Headers.Builder() + .add("User-Agent", HttpSource.DEFAULT_USER_AGENT) + .build() + + val client: OkHttpClient = currentClient + + suspend fun fetchPageList(externalUrl: String): List { + val chapterId = externalUrl.substringAfterLast("/").substringBefore("?") + val request = pageListRequest(chapterId) + return pageListParse(client.newCall(request).await()) + } + + private fun pageListRequest(chapterId: String): Request { + return GET("$apiUrl/chapter/$chapterId/pages/v0", headers) + } + + fun pageListParse(response: Response): List { + return Json.parseToJsonElement(response.body!!.string()) + .jsonObject["pages"]!! + .jsonArray.mapIndexed { index, element -> + val url = element.jsonObject["image_wm"]!!.jsonObject["webp"]!!.jsonArray[1].jsonObject["url"]!!.jsonPrimitive.content + Page(index, url, url) + } + } +} diff --git a/app/src/main/java/exh/md/handlers/MangaHotHandler.kt b/app/src/main/java/exh/md/handlers/MangaHotHandler.kt new file mode 100644 index 000000000..e750f5d03 --- /dev/null +++ b/app/src/main/java/exh/md/handlers/MangaHotHandler.kt @@ -0,0 +1,37 @@ +package exh.md.handlers + +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.await +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.online.HttpSource +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import okhttp3.Headers +import okhttp3.OkHttpClient +import okhttp3.Response + +class MangaHotHandler(currentClient: OkHttpClient) { + val baseUrl = "https://mangahot.jp" + private val apiUrl = "https://api.mangahot.jp" + val headers = Headers.Builder() + .add("User-Agent", HttpSource.DEFAULT_USER_AGENT) + .build() + + val client: OkHttpClient = currentClient + + suspend fun fetchPageList(externalUrl: String): List { + val request = GET(externalUrl.substringBefore("?").replace(baseUrl, apiUrl).replace("viewer", "v1/works/storyDetail"), headers) + return pageListParse(client.newCall(request).await()) + } + + fun pageListParse(response: Response): List { + return Json.parseToJsonElement(response.body!!.string()) + .jsonObject["content"]!!.jsonObject["contentUrls"]!! + .jsonArray.mapIndexed { index, element -> + val url = element.jsonPrimitive.content + Page(index, url, url) + } + } +} diff --git a/app/src/main/java/exh/md/handlers/PageHandler.kt b/app/src/main/java/exh/md/handlers/PageHandler.kt index 491818e4e..a345d0950 100644 --- a/app/src/main/java/exh/md/handlers/PageHandler.kt +++ b/app/src/main/java/exh/md/handlers/PageHandler.kt @@ -25,6 +25,8 @@ class PageHandler( private val mangaPlusHandler: MangaPlusHandler, private val comikeyHandler: ComikeyHandler, private val bilibiliHandler: BilibiliHandler, + private val azukiHandler: AzukiHandler, + private val mangaHotHandler: MangaHotHandler, private val preferences: PreferencesHelper, private val mdList: MdList, ) { @@ -45,6 +47,12 @@ class PageHandler( chapterResponse.data.attributes.externalUrl, chapterResponse.data.attributes.chapter.toString() ) + chapter.scanlator.equals("azuki manga", true) -> azukiHandler.fetchPageList( + chapterResponse.data.attributes.externalUrl + ) + chapter.scanlator.equals("mangahot", true) -> mangaHotHandler.fetchPageList( + chapterResponse.data.attributes.externalUrl + ) else -> throw Exception("${chapter.scanlator} not supported") } } else { @@ -116,6 +124,14 @@ class PageHandler( bilibiliHandler.client.newCall(GET(page.imageUrl!!, bilibiliHandler.headers)) .asObservableSuccess() } + page.imageUrl?.contains("azuki", true) == true -> { + azukiHandler.client.newCall(GET(page.imageUrl!!, azukiHandler.headers)) + .asObservableSuccess() + } + page.imageUrl?.contains("mangahot", true) == true -> { + mangaHotHandler.client.newCall(GET(page.imageUrl!!, mangaHotHandler.headers)) + .asObservableSuccess() + } else -> superMethod(page) } }