* adjustments * Run generator * Remove multisrc project * add lib dependencies * Remove multisrc from build scripts * Remove build condition
132 lines
5.2 KiB
Kotlin
132 lines
5.2 KiB
Kotlin
package eu.kanade.tachiyomi.multisrc.mccms
|
|
|
|
import eu.kanade.tachiyomi.network.GET
|
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
|
import eu.kanade.tachiyomi.network.interceptor.rateLimitHost
|
|
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.json.Json
|
|
import kotlinx.serialization.json.decodeFromStream
|
|
import okhttp3.Headers
|
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
|
import okhttp3.Request
|
|
import okhttp3.Response
|
|
import rx.Observable
|
|
import uy.kohesive.injekt.injectLazy
|
|
import java.net.URLEncoder
|
|
|
|
/**
|
|
* 漫城CMS http://mccms.cn/
|
|
*/
|
|
open class MCCMS(
|
|
override val name: String,
|
|
override val baseUrl: String,
|
|
override val lang: String = "zh",
|
|
private val config: MCCMSConfig = MCCMSConfig(),
|
|
) : HttpSource() {
|
|
override val supportsLatest = true
|
|
|
|
private val json: Json by injectLazy()
|
|
|
|
override val client by lazy {
|
|
network.client.newBuilder()
|
|
.rateLimitHost(baseUrl.toHttpUrl(), 2)
|
|
.build()
|
|
}
|
|
|
|
override fun headersBuilder() = Headers.Builder()
|
|
.add("User-Agent", System.getProperty("http.agent")!!)
|
|
.add("Referer", baseUrl)
|
|
|
|
override fun popularMangaRequest(page: Int): Request =
|
|
GET("$baseUrl/api/data/comic?page=$page&size=$PAGE_SIZE&order=hits", headers)
|
|
|
|
override fun popularMangaParse(response: Response): MangasPage {
|
|
val list: List<MangaDto> = response.parseAs()
|
|
return MangasPage(list.map { it.toSManga() }, list.size >= PAGE_SIZE)
|
|
}
|
|
|
|
override fun latestUpdatesRequest(page: Int): Request =
|
|
GET("$baseUrl/api/data/comic?page=$page&size=$PAGE_SIZE&order=addtime", headers)
|
|
|
|
override fun latestUpdatesParse(response: Response) = popularMangaParse(response)
|
|
|
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
|
val queries = buildList {
|
|
add("page=$page")
|
|
add("size=$PAGE_SIZE")
|
|
val isTextSearch = query.isNotBlank()
|
|
if (isTextSearch) add("key=" + URLEncoder.encode(query, "UTF-8"))
|
|
for (filter in filters) if (filter is MCCMSFilter) {
|
|
if (isTextSearch && filter.isTypeQuery) continue
|
|
val part = filter.query
|
|
if (part.isNotEmpty()) add(part)
|
|
}
|
|
}
|
|
val url = buildString {
|
|
append(baseUrl).append("/api/data/comic?")
|
|
queries.joinTo(this, separator = "&")
|
|
}
|
|
return GET(url, headers)
|
|
}
|
|
|
|
override fun searchMangaParse(response: Response) = popularMangaParse(response)
|
|
|
|
override fun getMangaUrl(manga: SManga) = baseUrl + manga.url
|
|
|
|
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
|
|
val url = "$baseUrl/api/data/comic".toHttpUrl().newBuilder()
|
|
.addQueryParameter("key", manga.title)
|
|
.toString()
|
|
val mangaUrl = manga.url
|
|
return client.newCall(GET(url, headers))
|
|
.asObservableSuccess().map { response ->
|
|
val list = response.parseAs<List<MangaDto>>()
|
|
list.first { it.cleanUrl == mangaUrl }.toSManga()
|
|
}
|
|
}
|
|
|
|
override fun mangaDetailsParse(response: Response): SManga = throw UnsupportedOperationException()
|
|
|
|
override fun fetchChapterList(manga: SManga): Observable<List<SChapter>> = Observable.fromCallable {
|
|
val id = manga.thumbnail_url!!.substringAfterLast('#', missingDelimiterValue = "").ifEmpty { throw Exception("请刷新漫画") }
|
|
val dataResponse = client.newCall(GET("$baseUrl/api/data/chapter?mid=$id", headers)).execute()
|
|
val dataList: List<ChapterDataDto> = dataResponse.parseAs() // unordered
|
|
val dateMap = HashMap<Int, Long>(dataList.size * 2)
|
|
dataList.forEach { dateMap[it.id.toInt()] = it.date }
|
|
val response = client.newCall(GET("$baseUrl/api/comic/chapter?mid=$id", headers)).execute()
|
|
val list: List<ChapterDto> = response.parseAs()
|
|
val result = list.map { it.toSChapter(date = dateMap[it.id.toInt()] ?: 0) }.asReversed()
|
|
result
|
|
}
|
|
|
|
override fun chapterListParse(response: Response): List<SChapter> = throw UnsupportedOperationException()
|
|
|
|
override fun pageListRequest(chapter: SChapter): Request =
|
|
GET(baseUrl + chapter.url, if (config.useMobilePageList) headers else pcHeaders)
|
|
|
|
override fun getChapterUrl(chapter: SChapter) = baseUrl + chapter.url
|
|
|
|
override fun pageListParse(response: Response): List<Page> {
|
|
return config.pageListParse(response)
|
|
}
|
|
|
|
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException()
|
|
|
|
// Don't send referer
|
|
override fun imageRequest(page: Page) = GET(page.imageUrl!!, pcHeaders)
|
|
|
|
private inline fun <reified T> Response.parseAs(): T = use {
|
|
json.decodeFromStream<ResultDto<T>>(it.body.byteStream()).data
|
|
}
|
|
|
|
override fun getFilterList(): FilterList {
|
|
val genreData = config.genreData.also { it.fetchGenres(this) }
|
|
return getFilters(genreData)
|
|
}
|
|
}
|