Add Comic Meteor (#1320)

This commit is contained in:
beerpsi 2024-02-17 15:52:51 +07:00 committed by GitHub
parent 9e51c6f4c2
commit 1ba5dd036c
7 changed files with 164 additions and 0 deletions

View File

@ -0,0 +1,11 @@
ext {
extName = "Comic Meteor"
extClass = ".ComicMeteor"
extVersionCode = 1
}
apply from: "$rootDir/common.gradle"
dependencies {
implementation(project(":lib:speedbinb"))
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,153 @@
package eu.kanade.tachiyomi.extension.ja.comicmeteor
import eu.kanade.tachiyomi.lib.speedbinb.SpeedBinbInterceptor
import eu.kanade.tachiyomi.lib.speedbinb.SpeedBinbReader
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.json.Json
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request
import okhttp3.Response
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class ComicMeteor : ParsedHttpSource() {
override val name = "COMICメテオ"
override val baseUrl = "https://comic-meteor.jp"
override val lang = "ja"
override val supportsLatest = false
private val json = Injekt.get<Json>()
override val client = network.client.newBuilder()
.addInterceptor(SpeedBinbInterceptor(json))
.apply {
val interceptors = interceptors()
val index = interceptors.indexOfFirst { "Brotli" in it.javaClass.simpleName }
if (index >= 0) {
interceptors.add(interceptors.removeAt(index))
}
}
.build()
override fun headersBuilder() = super.headersBuilder()
.add("Referer", "$baseUrl/")
override fun popularMangaRequest(page: Int) = GET(
"$baseUrl/wp-admin/admin-ajax.php?action=get_flex_titles_for_toppage&page=$page&get_num=16",
headers,
)
override fun popularMangaParse(response: Response): MangasPage {
val document = Jsoup.parseBodyFragment(response.body.string(), baseUrl)
val manga = document.select(popularMangaSelector()).map { popularMangaFromElement(it) }
val hasNextPage = manga.size == 16
return MangasPage(manga, hasNextPage)
}
override fun popularMangaSelector() = ".update_work_size .update_work_info_img a"
override fun popularMangaFromElement(element: Element) = SManga.create().apply {
setUrlWithoutDomain(element.attr("href"))
element.selectFirst("img")!!.let {
title = it.attr("alt")
thumbnail_url = it.absUrl("src")
}
}
override fun popularMangaNextPageSelector() = throw UnsupportedOperationException()
override fun latestUpdatesRequest(page: Int) = throw UnsupportedOperationException()
override fun latestUpdatesSelector() = throw UnsupportedOperationException()
override fun latestUpdatesFromElement(element: Element) = throw UnsupportedOperationException()
override fun latestUpdatesNextPageSelector() = throw UnsupportedOperationException()
private lateinit var directory: List<Element>
override fun fetchSearchManga(
page: Int,
query: String,
filters: FilterList,
): Observable<MangasPage> {
return if (page == 1) {
client.newCall(searchMangaRequest(page, query, filters))
.asObservableSuccess()
.map { searchMangaParse(it) }
} else {
Observable.just(parseDirectory(page))
}
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = baseUrl.toHttpUrl().newBuilder()
.addPathSegment("comicsearch")
.addPathSegment("")
.addQueryParameter("search", query)
.build()
return GET(url, headers)
}
override fun searchMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
directory = document.select(searchMangaSelector())
return parseDirectory(1)
}
private fun parseDirectory(page: Int): MangasPage {
val endRange = minOf(page * 24, directory.size)
val manga = directory.subList((page - 1) * 24, endRange).map { searchMangaFromElement(it) }
val hasNextPage = endRange < directory.lastIndex
return MangasPage(manga, hasNextPage)
}
override fun searchMangaSelector() = ".read_comic_size .read_comic_info_img a"
override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element)
override fun searchMangaNextPageSelector() = throw UnsupportedOperationException()
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
title = document.selectFirst("h2.h2ttl")!!.text()
author = document.selectFirst(".work_author_intro_name")
?.text()
?.substringAfter("著者 ")
description = document.selectFirst(".work_story_txt")?.text()
genre = document.select(".category_link_box a").joinToString { it.text() }
thumbnail_url = document.selectFirst(".latest_info_img img")?.absUrl("src")
}
override fun chapterListSelector() = ".work_episode_box .work_episode_table:has(.work_episode_link_orange)"
override fun chapterFromElement(element: Element) = SChapter.create().apply {
setUrlWithoutDomain(element.selectFirst("a")!!.attr("href"))
name = element.selectFirst(".work_episode_txt")!!.ownText()
}
private val reader by lazy { SpeedBinbReader(client, headers, json) }
override fun pageListParse(document: Document) =
reader.pageListParse(document)
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException()
}