dmzj: add apiv1 search (#8749)

* dmzj: add apiv1 search

* dmzj: remove old text search
This commit is contained in:
zhongfly 2025-05-07 23:28:39 +08:00 committed by Draff
parent adbfe86669
commit d50732286a
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
3 changed files with 41 additions and 19 deletions

View File

@ -1,7 +1,7 @@
ext {
extName = 'DMZJ'
extClass = '.Dmzj'
extVersionCode = 45
extVersionCode = 46
}
apply from: "$rootDir/common.gradle"

View File

@ -3,40 +3,62 @@ package eu.kanade.tachiyomi.extension.zh.dmzj
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Response
object ApiSearch {
fun textSearchUrl(query: String) =
"http://sacg.idmzj.com/comicsum/search.php".toHttpUrl().newBuilder()
.addQueryParameter("s", query)
fun searchUrlV1(page: Int, query: String) =
"https://manhua.idmzj.com/api/v1/comic2/search".toHttpUrl().newBuilder()
.addQueryParameter("page", page.toString())
.addQueryParameter("size", "30")
.addQueryParameter("keyword", query)
.toString()
fun parsePage(response: Response): MangasPage {
fun parsePageV1(response: Response): MangasPage {
if (!response.isSuccessful) {
response.close()
return MangasPage(emptyList(), false)
}
// "var g_search_data = [...];"
val js = response.body.string().run { substring(20, length - 1) }
val data: List<MangaDto> = json.decodeFromString(js)
return MangasPage(data.map { it.toSManga() }, false)
val result = response.parseAs<ResponseDto<SearchResultDto?>>()
if (result.errmsg.isNotBlank()) {
throw Exception(result.errmsg)
} else {
val url = response.request.url
val page = url.queryParameter("page")?.toInt()
val size = url.queryParameter("size")?.toInt()
return if (result.data != null) {
MangasPage(result.data.comicList.map { it.toSManga() }, page!! * size!! < result.data.totalNum)
} else {
MangasPage(emptyList(), false)
}
}
}
@Serializable
class MangaDto(
class MangaDtoV1(
private val id: Int,
private val comic_name: String,
private val comic_author: String,
private val comic_cover: String,
private val name: String,
private val authors: String,
private val cover: String,
) {
fun toSManga() = SManga.create().apply {
url = getMangaUrl(id.toString())
title = comic_name
author = comic_author.formatList()
thumbnail_url = comic_cover
title = name
author = authors
thumbnail_url = cover
}
}
@Serializable
class SearchResultDto(
val comicList: List<MangaDtoV1>,
val totalNum: Int,
)
@Serializable
class ResponseDto<T>(
val errmsg: String = "",
val data: T,
)
}

View File

@ -107,11 +107,11 @@ class Dmzj : ConfigurableSource, HttpSource() {
val id = query.removePrefix(PREFIX_ID_SEARCH).removeSuffix(".html")
Observable.fromCallable { searchMangaById(id) }
} else {
val request = GET(ApiSearch.textSearchUrl(query), headers)
val request = GET(ApiSearch.searchUrlV1(page, query), headers)
Observable.fromCallable {
// this API fails randomly, and might return empty list
repeat(5) {
val result = ApiSearch.parsePage(client.newCall(request).execute())
val result = ApiSearch.parsePageV1(client.newCall(request).execute())
if (result.mangas.isNotEmpty()) return@fromCallable result
}
throw Exception("搜索出错或无结果")