Add support for Azuki Manga and MangaHot Chapters in Mangadex (#506)

* Update MangaDex.kt

* Add Azuki and MangaHot Handlers
This commit is contained in:
jopejoe1 2022-01-16 11:59:13 +13:00 committed by GitHub
parent bf7075629c
commit dc60352bd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 106 additions and 0 deletions

View File

@ -28,10 +28,12 @@ import exh.md.MangaDexFabHeaderAdapter
import exh.md.dto.MangaDto import exh.md.dto.MangaDto
import exh.md.dto.StatisticsMangaDto import exh.md.dto.StatisticsMangaDto
import exh.md.handlers.ApiMangaParser import exh.md.handlers.ApiMangaParser
import exh.md.handlers.AzukiHandler
import exh.md.handlers.BilibiliHandler import exh.md.handlers.BilibiliHandler
import exh.md.handlers.ComikeyHandler import exh.md.handlers.ComikeyHandler
import exh.md.handlers.FollowsHandler import exh.md.handlers.FollowsHandler
import exh.md.handlers.MangaHandler import exh.md.handlers.MangaHandler
import exh.md.handlers.MangaHotHandler
import exh.md.handlers.MangaPlusHandler import exh.md.handlers.MangaPlusHandler
import exh.md.handlers.PageHandler import exh.md.handlers.PageHandler
import exh.md.handlers.SimilarHandler import exh.md.handlers.SimilarHandler
@ -122,6 +124,12 @@ class MangaDex(delegate: HttpSource, val context: Context) :
private val bilibiliHandler by lazy { private val bilibiliHandler by lazy {
BilibiliHandler(network.cloudflareClient) BilibiliHandler(network.cloudflareClient)
} }
private val azukHandler by lazy {
AzukiHandler(network.client)
}
private val mangaHotHandler by lazy {
MangaHotHandler(network.client)
}
private val pageHandler by lazy { private val pageHandler by lazy {
PageHandler( PageHandler(
headers, headers,
@ -129,6 +137,8 @@ class MangaDex(delegate: HttpSource, val context: Context) :
mangaPlusHandler, mangaPlusHandler,
comikeyHandler, comikeyHandler,
bilibiliHandler, bilibiliHandler,
azukHandler,
mangaHotHandler,
preferences, preferences,
mdList mdList
) )

View File

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

View File

@ -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<Page> {
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<Page> {
return Json.parseToJsonElement(response.body!!.string())
.jsonObject["content"]!!.jsonObject["contentUrls"]!!
.jsonArray.mapIndexed { index, element ->
val url = element.jsonPrimitive.content
Page(index, url, url)
}
}
}

View File

@ -25,6 +25,8 @@ class PageHandler(
private val mangaPlusHandler: MangaPlusHandler, private val mangaPlusHandler: MangaPlusHandler,
private val comikeyHandler: ComikeyHandler, private val comikeyHandler: ComikeyHandler,
private val bilibiliHandler: BilibiliHandler, private val bilibiliHandler: BilibiliHandler,
private val azukiHandler: AzukiHandler,
private val mangaHotHandler: MangaHotHandler,
private val preferences: PreferencesHelper, private val preferences: PreferencesHelper,
private val mdList: MdList, private val mdList: MdList,
) { ) {
@ -45,6 +47,12 @@ class PageHandler(
chapterResponse.data.attributes.externalUrl, chapterResponse.data.attributes.externalUrl,
chapterResponse.data.attributes.chapter.toString() 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 -> throw Exception("${chapter.scanlator} not supported")
} }
} else { } else {
@ -116,6 +124,14 @@ class PageHandler(
bilibiliHandler.client.newCall(GET(page.imageUrl!!, bilibiliHandler.headers)) bilibiliHandler.client.newCall(GET(page.imageUrl!!, bilibiliHandler.headers))
.asObservableSuccess() .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) else -> superMethod(page)
} }
} }