diff --git a/src/zh/terrahistoricus/build.gradle b/src/zh/terrahistoricus/build.gradle index 13b0dd776..622f088ed 100644 --- a/src/zh/terrahistoricus/build.gradle +++ b/src/zh/terrahistoricus/build.gradle @@ -6,7 +6,7 @@ ext { extName = 'Terra Historicus' pkgNameSuffix = 'zh.terrahistoricus' extClass = '.TerraHistoricus' - extVersionCode = 1 + extVersionCode = 2 } apply from: "$rootDir/common.gradle" diff --git a/src/zh/terrahistoricus/src/eu/kanade/tachiyomi/extension/zh/terrahistoricus/TerraHistoricus.kt b/src/zh/terrahistoricus/src/eu/kanade/tachiyomi/extension/zh/terrahistoricus/TerraHistoricus.kt index bf2f8aebe..cb13d5346 100644 --- a/src/zh/terrahistoricus/src/eu/kanade/tachiyomi/extension/zh/terrahistoricus/TerraHistoricus.kt +++ b/src/zh/terrahistoricus/src/eu/kanade/tachiyomi/extension/zh/terrahistoricus/TerraHistoricus.kt @@ -6,6 +6,7 @@ import eu.kanade.tachiyomi.source.model.FilterList import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.online.HttpSource import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json @@ -21,43 +22,45 @@ class TerraHistoricus : HttpSource() { private val json: Json by injectLazy() - override fun popularMangaRequest(page: Int) = GET("$baseUrl/api/comic") + override fun popularMangaRequest(page: Int) = GET("$baseUrl/api/comic", headers) + override fun popularMangaParse(response: Response) = + MangasPage(response.parseAs>().map { it.toSManga() }, false) - override fun popularMangaParse(response: Response) = MangasPage( - json.decodeFromString>>(response.body!!.string()).data.map(THComic::toSManga), - false - ) + override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/api/recentUpdate", headers) + override fun latestUpdatesParse(response: Response) = + MangasPage(response.parseAs>().map { it.toSManga() }, false) - override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/api/recentUpdate") + override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable = + fetchPopularManga(page).map { mangasPage -> + val mangas = mangasPage.mangas.filter { it.title.contains(query) } + MangasPage(mangas, false) + } - override fun latestUpdatesParse(response: Response) = MangasPage( - json.decodeFromString>>(response.body!!.string()).data.map(THRecentUpdate::toSManga), - false - ) + override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = throw UnsupportedOperationException("Not used.") + override fun searchMangaParse(response: Response) = throw UnsupportedOperationException("Not used.") - override fun searchMangaRequest(page: Int, query: String, filters: FilterList) = - throw UnsupportedOperationException("没有搜索功能") + // navigate webview to webpage + override fun mangaDetailsRequest(manga: SManga) = GET(baseUrl + manga.url.removePrefix("/api"), headers) - override fun searchMangaParse(response: Response) = throw UnsupportedOperationException("没有搜索功能") + override fun fetchMangaDetails(manga: SManga): Observable = + client.newCall(chapterListRequest(manga)).asObservableSuccess() + .map { response -> mangaDetailsParse(response).apply { initialized = true } } - override fun mangaDetailsParse(response: Response) = - json.decodeFromString>(response.body!!.string()).data.toSManga() + override fun mangaDetailsParse(response: Response) = response.parseAs().toSManga() - override fun chapterListParse(response: Response) = - json.decodeFromString>(response.body!!.string()).data.toSChapterList().orEmpty() + override fun chapterListParse(response: Response) = response.parseAs().toSChapterList() - override fun fetchPageList(chapter: SChapter): Observable> { - return client.newCall(pageListRequest(chapter)) - .asObservableSuccess() - .map { response -> - (0 until json.decodeFromString>(response.body!!.string()).data.pageInfos!!.size).map { - Page(it, "$baseUrl${chapter.url}/page?pageNum=${it + 1}") - } + override fun fetchPageList(chapter: SChapter): Observable> = + client.newCall(pageListRequest(chapter)).asObservableSuccess().map { response -> + (0 until response.parseAs().pageInfos!!.size).map { + Page(it, "$baseUrl${chapter.url}/page?pageNum=${it + 1}") } - } + } override fun pageListParse(response: Response) = throw UnsupportedOperationException("Not used.") - override fun imageUrlParse(response: Response) = - json.decodeFromString>(response.body!!.string()).data.url + override fun imageUrlParse(response: Response) = response.parseAs().url + + private inline fun Response.parseAs() = + json.decodeFromString>(this.body!!.string()).data } diff --git a/src/zh/terrahistoricus/src/eu/kanade/tachiyomi/extension/zh/terrahistoricus/TerraHistoricusDto.kt b/src/zh/terrahistoricus/src/eu/kanade/tachiyomi/extension/zh/terrahistoricus/TerraHistoricusDto.kt index 85be93a25..6bfaddc46 100644 --- a/src/zh/terrahistoricus/src/eu/kanade/tachiyomi/extension/zh/terrahistoricus/TerraHistoricusDto.kt +++ b/src/zh/terrahistoricus/src/eu/kanade/tachiyomi/extension/zh/terrahistoricus/TerraHistoricusDto.kt @@ -1,5 +1,6 @@ package eu.kanade.tachiyomi.extension.zh.terrahistoricus +import eu.kanade.tachiyomi.AppInfo import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga import kotlinx.serialization.Serializable @@ -7,10 +8,11 @@ import kotlinx.serialization.Serializable @Serializable data class THResult(val code: Int, val msg: String, val data: T) +// https://web.hycdn.cn/comic/site/umi.dee612f8.js @Serializable data class THComic( val cid: String, -// val type: Int, + val type: Int, val cover: String, val title: String, val subtitle: String, @@ -23,30 +25,51 @@ data class THComic( ) { private fun getDescription(): String? { var result = "" - if (subtitle.isNotEmpty()) result += "「$subtitle」" + if (subtitle.isNotEmpty()) result += "「$subtitle」\n" if (introduction != null) result += introduction return result.ifEmpty { null } } + private fun getType() = when (type) { + 2 -> listOf("相簿") + 3 -> listOf("四格") + else -> emptyList() // 1 = Normal + } + fun toSManga() = SManga.create().apply { url = "/api/comic/$cid" title = this@THComic.title author = authors.joinToString("、") thumbnail_url = cover description = getDescription() - genre = keywords?.joinToString(",")?.replace(",", ", ") + genre = (getType() + keywords.orEmpty()).joinToString(", ").replace(",", ", ") } - fun toSChapterList() = episodes?.map { episode -> + fun toSChapterList() = episodes!!.map { episode -> SChapter.create().apply { url = "/api/comic/$cid/episode/${episode.cid!!}" - try { - chapter_number = episode.shortTitle?.toFloat() ?: chapter_number - name = episode.title - } catch (e: NumberFormatException) { - name = "${episode.shortTitle} ${episode.title}" + name = if (episode.type != 1) { + "${EPISODE_TYPES[episode.type]} ${episode.title}" + } else if (episode.shortTitle.isNullOrBlank()) { + episode.title + } else { + "${episode.shortTitle} ${episode.title}" } - date_upload = (updateTime ?: 0L) * 1000 + } + }.apply { + if (isNewDateLogic) { + this[0].date_upload = (updateTime ?: 0L) * 1000 + } + } + + companion object { + private val EPISODE_TYPES = arrayOf("", "正篇", "番外", "贺图", "公告") + private val isNewDateLogic = run { + val commitCount = AppInfo.getVersionName().substringAfter('-', "") + if (commitCount.isNotEmpty()) // Preview + commitCount.toInt() >= 4442 + else // Stable + AppInfo.getVersionCode() >= 81 } } } @@ -72,7 +95,7 @@ data class THRecentUpdate( @Serializable data class THEpisode( val cid: String? = null, -// val type: Int, + val type: Int, val shortTitle: String?, val title: String, // 作品信息中 // val likes: Int? = null,