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 82f766976..357bd2f7f 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 @@ -31,6 +31,7 @@ import exh.md.handlers.FollowsHandler import exh.md.handlers.MangaHandler import exh.md.handlers.MangaHotHandler import exh.md.handlers.MangaPlusHandler +import exh.md.handlers.NamicomiHandler import exh.md.handlers.PageHandler import exh.md.handlers.SimilarHandler import exh.md.network.MangaDexLoginHelper @@ -123,6 +124,9 @@ class MangaDex(delegate: HttpSource, val context: Context) : private val mangaHotHandler by lazy { MangaHotHandler(network.client, network.defaultUserAgentProvider()) } + private val namicomiHandler by lazy { + NamicomiHandler(network.client, network.defaultUserAgentProvider()) + } private val pageHandler by lazy { PageHandler( headers, @@ -132,6 +136,7 @@ class MangaDex(delegate: HttpSource, val context: Context) : bilibiliHandler, azukHandler, mangaHotHandler, + namicomiHandler, trackPreferences, mdList, ) diff --git a/app/src/main/java/exh/md/handlers/NamicomiHandler.kt b/app/src/main/java/exh/md/handlers/NamicomiHandler.kt new file mode 100644 index 000000000..41e098cf4 --- /dev/null +++ b/app/src/main/java/exh/md/handlers/NamicomiHandler.kt @@ -0,0 +1,49 @@ +package exh.md.handlers + +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.awaitSuccess +import eu.kanade.tachiyomi.source.model.Page +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 NamicomiHandler(currentClient: OkHttpClient, userAgent: String) { + private val apiUrl = "https://api.namicomi.com" + + private val headers = Headers.Builder() + .add("User-Agent", userAgent) + .build() + + val client: OkHttpClient = currentClient + + suspend fun fetchPageList(externalUrl: String, dataSaver: Boolean): List { + val chapterId = externalUrl.substringBefore("?").substringAfterLast("/") + val request = + GET( + "$apiUrl/images/chapter/$chapterId?newQualities=true", + headers, + ) + return pageListParse(client.newCall(request).awaitSuccess(), chapterId, dataSaver) + } + + private fun pageListParse(response: Response, chapterId: String, dataSaver: Boolean): List { + val data = Json.parseToJsonElement(response.body.string()).jsonObject["data"]!! + val baseUrl = data.jsonObject["baseUrl"]!!.jsonPrimitive.content + val hash = data.jsonObject["hash"]!!.jsonPrimitive.content + + /* Available quality levels: source, high, medium, low */ + val quality = if(dataSaver) "low" else "high" + + return data + .jsonObject[quality]!! + .jsonArray.mapIndexed { index, element -> + val fileName = element.jsonObject["filename"]!!.jsonPrimitive.content + val url = "$baseUrl/chapter/$chapterId/$hash/$quality/$fileName" + 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 f5ef987cd..300ae999f 100644 --- a/app/src/main/java/exh/md/handlers/PageHandler.kt +++ b/app/src/main/java/exh/md/handlers/PageHandler.kt @@ -27,6 +27,7 @@ class PageHandler( private val bilibiliHandler: BilibiliHandler, private val azukiHandler: AzukiHandler, private val mangaHotHandler: MangaHotHandler, + private val namicomiHandler: NamicomiHandler, private val preferences: TrackPreferences, private val mdList: MdList, ) { @@ -54,6 +55,10 @@ class PageHandler( chapter.scanlator.equals("mangahot", true) -> mangaHotHandler.fetchPageList( chapterResponse.data.attributes.externalUrl, ) + chapter.scanlator.equals("namicomi", true) -> namicomiHandler.fetchPageList( + chapterResponse.data.attributes.externalUrl, + dataSaver = dataSaver, + ) else -> throw Exception("${chapter.scanlator} not supported") } } else { @@ -122,6 +127,9 @@ class PageHandler( page.imageUrl?.contains("mangahot", true) == true -> { mangaHotHandler.client.newCachelessCallWithProgress(GET(page.imageUrl!!, mangaHotHandler.headers), page) } + page.imageUrl?.contains("namicomi", true) == true -> { + mangaHotHandler.client.newCachelessCallWithProgress(GET(page.imageUrl!!, mangaHotHandler.headers), page) + } else -> null } }