Add multisrc theme SinMH (#11947)
* Add multisrc theme SinMH * SinMH: optimize assets * SinMH: add run configuration
|
@ -0,0 +1,17 @@
|
|||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="SinMHGenerator" type="JetRunConfigurationType" nameIsGenerated="true">
|
||||
<module name="tachiyomi-extensions.multisrc" />
|
||||
<option name="VM_PARAMETERS" value="" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
<option name="ALTERNATIVE_JRE_PATH" />
|
||||
<option name="PASS_PARENT_ENVS" value="true" />
|
||||
<option name="MAIN_CLASS_NAME" value="eu.kanade.tachiyomi.multisrc.sinmh.SinMHGenerator" />
|
||||
<option name="WORKING_DIRECTORY" value="" />
|
||||
<method v="2">
|
||||
<option name="Make" enabled="true" />
|
||||
<option name="Gradle.BeforeRunTask" enabled="true" tasks="ktFormat" externalProjectPath="$PROJECT_DIR$/multisrc" vmOptions="" scriptParameters="" />
|
||||
<option name="Gradle.BeforeRunTask" enabled="true" tasks="ktLint" externalProjectPath="$PROJECT_DIR$/multisrc" vmOptions="" scriptParameters="" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 92 KiB |
|
@ -0,0 +1,25 @@
|
|||
package eu.kanade.tachiyomi.extension.zh.imitui
|
||||
|
||||
import eu.kanade.tachiyomi.multisrc.sinmh.SinMH
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.source.model.Page
|
||||
import eu.kanade.tachiyomi.source.model.SChapter
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
import org.jsoup.nodes.Document
|
||||
|
||||
class Imitui : SinMH("爱米推漫画", "https://www.imitui.com") {
|
||||
private val mobileUrl = "https://m.imitui.com"
|
||||
|
||||
override fun chapterListRequest(manga: SManga) = GET(mobileUrl + manga.url, headers)
|
||||
|
||||
override fun pageListRequest(chapter: SChapter) = GET(mobileUrl + chapter.url, headers)
|
||||
|
||||
override fun pageListParse(document: Document): List<Page> {
|
||||
val pageCount = document.select("div.image-content > p").text().removePrefix("1/").toInt()
|
||||
val prefix = document.location().removeSuffix(".html")
|
||||
return (0 until pageCount).map { Page(it, "$prefix-${it + 1}.html") }
|
||||
}
|
||||
|
||||
override fun imageUrlParse(document: Document): String =
|
||||
document.select("div.image-content > img#image").attr("src")
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
package eu.kanade.tachiyomi.multisrc.sinmh
|
||||
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
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.ParsedHttpSource
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.Headers
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
/**
|
||||
* 圣樱漫画CMS https://gitee.com/shenl/SinMH-2.0-Guide
|
||||
* ref: https://github.com/kanasimi/CeJS/tree/master/application/net/work_crawler/sites
|
||||
* https://github.com/kanasimi/work_crawler/blob/master/document/README.cmn-Hant-TW.md
|
||||
*/
|
||||
abstract class SinMH(
|
||||
override val name: String,
|
||||
_baseUrl: String,
|
||||
override val lang: String = "zh",
|
||||
) : ParsedHttpSource() {
|
||||
override val baseUrl = _baseUrl
|
||||
override val supportsLatest = true
|
||||
|
||||
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
||||
.add("Referer", baseUrl)
|
||||
|
||||
protected open val nextPageSelector = "ul.pagination > li.next:not(.disabled)"
|
||||
protected open val comicItemSelector = "#contList > li"
|
||||
protected open val comicItemTitleSelector = "p > a"
|
||||
protected open fun mangaFromElement(element: Element) =
|
||||
SManga.create().apply {
|
||||
val titleElement = element.select(comicItemTitleSelector)
|
||||
title = titleElement.text()
|
||||
setUrlWithoutDomain(titleElement.attr("abs:href"))
|
||||
thumbnail_url = element.select("img").attr("abs:src")
|
||||
}
|
||||
|
||||
// Popular
|
||||
|
||||
override fun popularMangaRequest(page: Int) = GET("$baseUrl/list/click/?page=$page", headers)
|
||||
override fun popularMangaNextPageSelector(): String? = nextPageSelector
|
||||
override fun popularMangaSelector() = comicItemSelector
|
||||
override fun popularMangaFromElement(element: Element) = mangaFromElement(element)
|
||||
|
||||
// Latest
|
||||
|
||||
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/list/update/?page=$page", headers)
|
||||
override fun latestUpdatesNextPageSelector(): String? = nextPageSelector
|
||||
override fun latestUpdatesSelector() = comicItemSelector
|
||||
override fun latestUpdatesFromElement(element: Element) = mangaFromElement(element)
|
||||
|
||||
// Search
|
||||
|
||||
override fun searchMangaNextPageSelector(): String? = nextPageSelector
|
||||
override fun searchMangaSelector(): String = comicItemSelector
|
||||
override fun searchMangaFromElement(element: Element) = mangaFromElement(element)
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) =
|
||||
if (query.isNotBlank()) {
|
||||
GET("$baseUrl/search/?keywords=$query&page=$page", headers)
|
||||
} else {
|
||||
val categories = filters.filterIsInstance<UriPartFilter>()
|
||||
.joinToString("-", transform = UriPartFilter::toUriPart) + "-"
|
||||
GET("$baseUrl/list/$categories/", headers)
|
||||
}
|
||||
|
||||
// Details
|
||||
|
||||
override fun mangaDetailsParse(document: Document) = SManga.create().apply {
|
||||
title = document.select(".book-title > h1 > span").text()
|
||||
author = document.select(".detail-list strong:contains(作者) + a").text()
|
||||
description = document.select("#intro-all").text().trim()
|
||||
.removePrefix("漫画简介:").trim()
|
||||
.removePrefix("漫画简介:").trim() // some sources have double prefix
|
||||
genre = document.select(".detail-list strong:contains(类型) + a").text() + ", " +
|
||||
document.select(".breadcrumb-bar a[href*=/list/]").joinToString(", ") { it.text() }
|
||||
status = when (document.select(".detail-list strong:contains(状态) + a").text()) {
|
||||
"连载中" -> SManga.ONGOING
|
||||
"已完结" -> SManga.COMPLETED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
thumbnail_url = document.select("p.cover > img").attr("abs:src")
|
||||
// TODO: can use 更新时间:2022-05-23 to set default upload date
|
||||
}
|
||||
|
||||
// Chapters
|
||||
|
||||
override fun chapterListSelector() = ".chapter-body li > a:not([href*=/comic/app/])"
|
||||
override fun chapterListParse(response: Response) = super.chapterListParse(response).reversed()
|
||||
override fun chapterFromElement(element: Element) = SChapter.create().apply {
|
||||
setUrlWithoutDomain(element.attr("abs:href"))
|
||||
name = element.text()
|
||||
}
|
||||
|
||||
// Pages
|
||||
|
||||
override fun pageListParse(document: Document): List<Page> {
|
||||
val script = document.select("script:containsData(chapterImages)").html()
|
||||
val images = script.substringAfter("chapterImages = [\"").substringBefore("\"]").split("\",\"")
|
||||
val path = script.substringAfter("chapterPath = \"").substringBefore("\";")
|
||||
// assume cover images are on the same server
|
||||
val server = script.substringAfter("pageImage = \"").substringBefore("/images/cover")
|
||||
return images.mapIndexed { i, image -> Page(i, "", "$server/$path/$image") }
|
||||
}
|
||||
|
||||
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not Used.")
|
||||
|
||||
protected class UriPartFilter(displayName: String, values: Array<String>, private val uriParts: Array<String>) :
|
||||
Filter.Select<String>(displayName, values) {
|
||||
fun toUriPart(): String = uriParts[state]
|
||||
}
|
||||
|
||||
protected data class Category(val name: String, val values: Array<String>, val uriParts: Array<String>) {
|
||||
fun toUriPartFilter() = UriPartFilter(name, values, uriParts)
|
||||
}
|
||||
|
||||
private lateinit var categories: List<Category>
|
||||
|
||||
protected open fun fetchCategories() {
|
||||
val document = client.newCall(GET("$baseUrl/list/", headers)).execute().asJsoup()
|
||||
categories = document.select(".page-main .filter-nav > .filter-item").map { element ->
|
||||
val name = element.select("label").text()
|
||||
val tags = element.select("a")
|
||||
val values = tags.map { it.text() }.toTypedArray()
|
||||
val uriParts = tags.map { it.attr("href").removePrefix("/list/").removeSuffix("/") }.toTypedArray()
|
||||
Category(name, values, uriParts)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
thread {
|
||||
fetchCategories()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getFilterList() =
|
||||
if (::categories.isInitialized) FilterList(
|
||||
Filter.Header("如果使用文本搜索,将会忽略分类筛选"),
|
||||
*categories.map(Category::toUriPartFilter).toTypedArray()
|
||||
) else FilterList(
|
||||
Filter.Header("分类尚未获取,请返回上一页后重试")
|
||||
)
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package eu.kanade.tachiyomi.multisrc.sinmh
|
||||
|
||||
import generator.ThemeSourceData.SingleLang
|
||||
import generator.ThemeSourceGenerator
|
||||
|
||||
class SinMHGenerator : ThemeSourceGenerator {
|
||||
override val themeClass = "SinMH"
|
||||
override val themePkg = "sinmh"
|
||||
override val baseVersionCode = 1
|
||||
override val sources = listOf(
|
||||
SingleLang(
|
||||
name = "Gufeng Manhua", baseUrl = "https://www.gufengmh9.com", lang = "zh",
|
||||
className = "Gufengmh", sourceName = "古风漫画网", overrideVersionCode = 5
|
||||
),
|
||||
SingleLang(
|
||||
name = "Imitui Manhua", baseUrl = "https://www.imitui.com", lang = "zh",
|
||||
className = "Imitui", sourceName = "爱米推漫画", overrideVersionCode = 2
|
||||
)
|
||||
)
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
SinMHGenerator().createAll()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="eu.kanade.tachiyomi.extension" />
|
|
@ -1,12 +0,0 @@
|
|||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
ext {
|
||||
extName = 'Gufeng Manhua'
|
||||
pkgNameSuffix = 'zh.gufengmh'
|
||||
extClass = '.Gufengmh'
|
||||
extVersionCode = 5
|
||||
}
|
||||
|
||||
|
||||
apply from: "$rootDir/common.gradle"
|
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 9.6 KiB |
Before Width: | Height: | Size: 46 KiB |
|
@ -1,436 +0,0 @@
|
|||
package eu.kanade.tachiyomi.extension.zh.gufengmh
|
||||
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
import eu.kanade.tachiyomi.source.model.FilterList
|
||||
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.ParsedHttpSource
|
||||
import okhttp3.Headers
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
|
||||
class Gufengmh : ParsedHttpSource() {
|
||||
override val name: String = "古风漫画网"
|
||||
override val lang: String = "zh"
|
||||
override val supportsLatest: Boolean = true
|
||||
override val baseUrl: String = "https://m.gufengmh9.com"
|
||||
|
||||
override fun headersBuilder(): Headers.Builder = Headers.Builder()
|
||||
.add("Referer", baseUrl)
|
||||
|
||||
// Popular
|
||||
|
||||
override fun popularMangaRequest(page: Int): Request {
|
||||
return GET("$baseUrl/list/click/?page=$page", headers)
|
||||
}
|
||||
override fun popularMangaNextPageSelector(): String? = "li.next"
|
||||
override fun popularMangaSelector(): String = "li.list-comic"
|
||||
override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
|
||||
title = element.select("a.txtA").text()
|
||||
setUrlWithoutDomain(element.select("a.txtA").attr("abs:href"))
|
||||
thumbnail_url = element.select("mip-img").attr("abs:src")
|
||||
}
|
||||
|
||||
// Latest
|
||||
|
||||
override fun latestUpdatesRequest(page: Int): Request {
|
||||
return GET("$baseUrl/list/update/?page=$page", headers)
|
||||
}
|
||||
override fun latestUpdatesNextPageSelector(): String? = popularMangaNextPageSelector()
|
||||
override fun latestUpdatesSelector(): String = popularMangaSelector()
|
||||
override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element)
|
||||
|
||||
// Search
|
||||
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
val uri = Uri.parse(baseUrl).buildUpon()
|
||||
if (query.isNotBlank()) {
|
||||
uri.appendPath("search")
|
||||
.appendEncodedPath("")
|
||||
.appendQueryParameter("keywords", query)
|
||||
.appendQueryParameter("page", page.toString())
|
||||
} else {
|
||||
uri.appendPath("list")
|
||||
val pathBuilder = Uri.Builder()
|
||||
filters.forEach {
|
||||
if (it is UriFilter)
|
||||
it.addToUri(pathBuilder)
|
||||
}
|
||||
val filterPath = pathBuilder.toString().replace("/", "-").removePrefix("-")
|
||||
uri.appendEncodedPath(filterPath)
|
||||
.appendEncodedPath("")
|
||||
}
|
||||
|
||||
return GET(uri.toString(), headers)
|
||||
}
|
||||
|
||||
override fun searchMangaNextPageSelector(): String? = popularMangaNextPageSelector()
|
||||
override fun searchMangaSelector(): String = "div.itemBox, li.list-comic"
|
||||
override fun searchMangaFromElement(element: Element): SManga = SManga.create().apply {
|
||||
title = element.select("a.title, a.txtA").text()
|
||||
setUrlWithoutDomain(element.select("a.title, a.txtA").attr("abs:href"))
|
||||
thumbnail_url = element.select("mip-img").attr("abs:src")
|
||||
}
|
||||
|
||||
// Details
|
||||
|
||||
override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply {
|
||||
title = document.select("h1.title").text()
|
||||
thumbnail_url = document.select("div#Cover mip-img").attr("abs:src")
|
||||
author = document.select("dt:contains(作者) + dd").text()
|
||||
artist = author
|
||||
genre = document.select("dt:contains(类别) + dd").text()
|
||||
description = document.select("p.txtDesc").text()
|
||||
}
|
||||
|
||||
// Chapters
|
||||
|
||||
override fun chapterListSelector(): String = "div.list li"
|
||||
override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
|
||||
url = element.select("a").attr("href")
|
||||
name = element.select("span").text()
|
||||
}
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
return super.chapterListParse(response).reversed()
|
||||
}
|
||||
|
||||
// Pages
|
||||
|
||||
override fun pageListParse(document: Document): List<Page> = mutableListOf<Page>().apply {
|
||||
val script = document.select("script:containsData(chapterImages )").html()
|
||||
val images = script.substringAfter("chapterImages = [\"").substringBefore("\"]").split("\",\"")
|
||||
val path = script.substringAfter("chapterPath = \"").substringBefore("\";")
|
||||
val server = script.substringAfter("pageImage = \"").substringBefore("/images/cover")
|
||||
images.forEach {
|
||||
add(Page(size, "", "$server/$path/$it"))
|
||||
}
|
||||
}
|
||||
override fun imageUrlParse(document: Document): String = throw Exception("Not Used")
|
||||
|
||||
// Filters
|
||||
|
||||
override fun getFilterList(): FilterList {
|
||||
return FilterList(
|
||||
Filter.Header("如果使用文本搜索"),
|
||||
Filter.Header("过滤器将被忽略"),
|
||||
typefilter(),
|
||||
regionfilter(),
|
||||
genrefilter(),
|
||||
letterfilter(),
|
||||
statusfilter()
|
||||
)
|
||||
}
|
||||
|
||||
private class typefilter : UriSelectFilterPath(
|
||||
"按类型",
|
||||
"filtertype",
|
||||
arrayOf(
|
||||
Pair("", "全部"),
|
||||
Pair("shaonian", "少年漫画"),
|
||||
Pair("shaonv", "少女漫画"),
|
||||
Pair("qingnian", "青年漫画"),
|
||||
Pair("zhenrenmanhua", "真人漫画")
|
||||
)
|
||||
)
|
||||
|
||||
private class regionfilter : UriSelectFilterPath(
|
||||
"按地区",
|
||||
"filterregion",
|
||||
arrayOf(
|
||||
Pair("", "全部"),
|
||||
Pair("ribenmanhua", "日本漫画"),
|
||||
Pair("guochanmanhua", "国产漫画"),
|
||||
Pair("gangtaimanhua", "港台漫画"),
|
||||
Pair("oumeimanhua", "欧美漫画"),
|
||||
Pair("hanguomanhua", "韩国漫画")
|
||||
)
|
||||
)
|
||||
|
||||
private class genrefilter : UriSelectFilterPath(
|
||||
"按剧情",
|
||||
"filtergenre",
|
||||
arrayOf(
|
||||
Pair("", "全部"),
|
||||
Pair("maoxian", "冒险"),
|
||||
Pair("mofa", "魔法"),
|
||||
Pair("kehuan", "科幻"),
|
||||
Pair("kongbu", "恐怖"),
|
||||
Pair("lishi", "历史"),
|
||||
Pair("jingji", "竞技"),
|
||||
Pair("huanlexiang", "欢乐向"),
|
||||
Pair("xifangmohuan", "西方魔幻"),
|
||||
Pair("aiqing", "爱情"),
|
||||
Pair("xuanyi", "悬疑"),
|
||||
Pair("qihuan", "奇幻"),
|
||||
Pair("qingxiaoshuo", "轻小说"),
|
||||
Pair("sige", "四格"),
|
||||
Pair("shengui", "神鬼"),
|
||||
Pair("zhiyu", "治愈"),
|
||||
Pair("xiaoyuan", "校园"),
|
||||
Pair("weiniang", "伪娘"),
|
||||
Pair("danmei", "耽美"),
|
||||
Pair("hougong", "后宫"),
|
||||
Pair("mohuan", "魔幻"),
|
||||
Pair("wuxia", "武侠"),
|
||||
Pair("zhichang", "职场"),
|
||||
Pair("zhentan", "侦探"),
|
||||
Pair("meishi", "美食"),
|
||||
Pair("gedou", "格斗"),
|
||||
Pair("lizhi", "励志"),
|
||||
Pair("yinyuewudao", "音乐舞蹈"),
|
||||
Pair("rexue", "热血"),
|
||||
Pair("zhanzheng", "战争"),
|
||||
Pair("gaoxiao", "搞笑"),
|
||||
Pair("shenghuo", "生活"),
|
||||
Pair("baihe", "百合"),
|
||||
Pair("mengji", "萌系"),
|
||||
Pair("jiecao", "节操"),
|
||||
Pair("xingzhuanhuan", "性转换"),
|
||||
Pair("yanyi", "颜艺"),
|
||||
Pair("gufeng", "古风"),
|
||||
Pair("xianxia", "仙侠"),
|
||||
Pair("zhaiji", "宅系"),
|
||||
Pair("juqing", "剧情"),
|
||||
Pair("shenmo", "神魔"),
|
||||
Pair("xuanhuan", "玄幻"),
|
||||
Pair("chuanyue", "穿越"),
|
||||
Pair("qita", "其他"),
|
||||
Pair("huanxiang", "幻想"),
|
||||
Pair("motong", "墨瞳"),
|
||||
Pair("maimeng", "麦萌"),
|
||||
Pair("manman", "漫漫"),
|
||||
Pair("manhuadao", "漫画岛"),
|
||||
Pair("tuili", "推理"),
|
||||
Pair("dongfang", "东方"),
|
||||
Pair("kuaikan", "快看"),
|
||||
Pair("jizhan", "机战"),
|
||||
Pair("gaoqingdanxing", "高清单行"),
|
||||
Pair("xinzuo", "新作"),
|
||||
Pair("tougao", "投稿"),
|
||||
Pair("richang", "日常"),
|
||||
Pair("shougong", "手工"),
|
||||
Pair("yundong", "运动"),
|
||||
Pair("weimei", "唯美"),
|
||||
Pair("dushi", "都市"),
|
||||
Pair("jingxian", "惊险"),
|
||||
Pair("jiangshi", "僵尸"),
|
||||
Pair("lianai", "恋爱"),
|
||||
Pair("nuexin", "虐心"),
|
||||
Pair("chunai", "纯爱"),
|
||||
Pair("fuchou", "复仇"),
|
||||
Pair("dongzuo", "动作"),
|
||||
Pair("qita2", "其它"),
|
||||
Pair("egao", "恶搞"),
|
||||
Pair("mingxing", "明星"),
|
||||
Pair("zhenhan", "震撼"),
|
||||
Pair("anhei", "暗黑"),
|
||||
Pair("naodong", "脑洞"),
|
||||
Pair("xuexing", "血腥"),
|
||||
Pair("youyaoqi", "有妖气"),
|
||||
Pair("jijia", "机甲"),
|
||||
Pair("qingchun", "青春"),
|
||||
Pair("lingyi", "灵异"),
|
||||
Pair("tongren", "同人"),
|
||||
Pair("langman", "浪漫"),
|
||||
Pair("quanmou", "权谋"),
|
||||
Pair("shehui", "社会"),
|
||||
Pair("gongdou", "宫斗"),
|
||||
Pair("baoxiao", "爆笑"),
|
||||
Pair("tiyu", "体育"),
|
||||
Pair("lanmu", "栏目"),
|
||||
Pair("caihong", "彩虹"),
|
||||
Pair("zhentantuili", "侦探推理"),
|
||||
Pair("shaonuaiqing", "少女爱情"),
|
||||
Pair("gaoxiaoxiju", "搞笑喜剧"),
|
||||
Pair("kongbulingyi", "恐怖灵异"),
|
||||
Pair("kehuanmohuan", "科幻魔幻"),
|
||||
Pair("jingjitiyu", "竞技体育"),
|
||||
Pair("wuxiagedou", "武侠格斗"),
|
||||
Pair("jianniang", "舰娘"),
|
||||
Pair("danmeiBL", "耽美BL"),
|
||||
Pair("xiee", "邪恶"),
|
||||
Pair("zongheqita", "综合其它"),
|
||||
Pair("qingnian", "青年"),
|
||||
Pair("zhainan", "宅男"),
|
||||
Pair("zazhi", "杂志"),
|
||||
Pair("yinyue", "音乐"),
|
||||
Pair("quancai", "全彩"),
|
||||
Pair("heidao", "黑道"),
|
||||
Pair("lianaidanmei", "恋爱耽美"),
|
||||
Pair("rexuemaoxian", "热血冒险"),
|
||||
Pair("funv", "腐女"),
|
||||
Pair("gushi", "故事"),
|
||||
Pair("shaonv", "少女"),
|
||||
Pair("zongcai", "总裁"),
|
||||
Pair("baoxiaoxiju", "爆笑喜剧"),
|
||||
Pair("qitamanhua", "其他漫画"),
|
||||
Pair("lianaishenghuo", "恋爱生活"),
|
||||
Pair("kongbuxuanyi", "恐怖悬疑"),
|
||||
Pair("danmeirensheng", "耽美人生"),
|
||||
Pair("chongwu", "宠物"),
|
||||
Pair("zhandou", "战斗"),
|
||||
Pair("zhaohuanshou", "召唤兽"),
|
||||
Pair("yineng", "异能"),
|
||||
Pair("zhuangbi", "装逼"),
|
||||
Pair("yishijie", "异世界"),
|
||||
Pair("zhengju", "正剧"),
|
||||
Pair("wenxin", "温馨"),
|
||||
Pair("jingqi", "惊奇"),
|
||||
Pair("jiakong", "架空"),
|
||||
Pair("qingsong", "轻松"),
|
||||
Pair("weilai", "未来"),
|
||||
Pair("keji", "科技"),
|
||||
Pair("shaonao", "烧脑"),
|
||||
Pair("gaoxiaoegao", "搞笑恶搞"),
|
||||
Pair("mhuaquan", "mhuaquan"),
|
||||
Pair("shaonian", "少年"),
|
||||
Pair("sigeduoge", "四格多格"),
|
||||
Pair("bazong", "霸总"),
|
||||
Pair("xiuzhen", "修真"),
|
||||
Pair("gushimanhua", "故事漫画"),
|
||||
Pair("huiben", "绘本"),
|
||||
Pair("youxi", "游戏"),
|
||||
Pair("zhenren", "真人"),
|
||||
Pair("jingsong", "惊悚"),
|
||||
Pair("manhua", "漫画"),
|
||||
Pair("weizhongquan", "微众圈"),
|
||||
Pair("yujie", "御姐"),
|
||||
Pair("xiaoshuogaibian", "小说改编"),
|
||||
Pair("luoli", "萝莉"),
|
||||
Pair("1024manhua", "1024manhua"),
|
||||
Pair("jiating", "家庭"),
|
||||
Pair("shenhua", "神话"),
|
||||
Pair("shishi", "史诗"),
|
||||
Pair("moshi", "末世"),
|
||||
Pair("yulequan", "娱乐圈"),
|
||||
Pair("gandong", "感动"),
|
||||
Pair("lunli", "伦理"),
|
||||
Pair("zazhiquanben", "杂志全本"),
|
||||
Pair("zhiyu2", "致郁"),
|
||||
Pair("shangzhan", "商战"),
|
||||
Pair("zhupu", "主仆"),
|
||||
Pair("manhuaquan", "漫画圈"),
|
||||
Pair("lianaijuqingmanhua", "恋爱、剧情漫画"),
|
||||
Pair("hunai", "婚爱"),
|
||||
Pair("haomen", "豪门"),
|
||||
Pair("neihan", "内涵"),
|
||||
Pair("xingzhuan", "性转"),
|
||||
Pair("xiangcun", "乡村"),
|
||||
Pair("gongting", "宫廷"),
|
||||
Pair("duanzi", "段子"),
|
||||
Pair("chunaimanhua", "纯爱漫画"),
|
||||
Pair("nixi", "逆袭"),
|
||||
Pair("hunyin", "婚姻"),
|
||||
Pair("baihenvxing", "百合女性"),
|
||||
Pair("shenghuomanhua", "生活漫画"),
|
||||
Pair("ertong", "儿童"),
|
||||
Pair("wudao", "舞蹈"),
|
||||
Pair("tianchong", "甜宠"),
|
||||
Pair("wengai", "文改"),
|
||||
Pair("dujia", "独家"),
|
||||
Pair("biaoqian", "标签"),
|
||||
Pair("zhaifumanhua", "宅腐漫画"),
|
||||
Pair("qinggan", "情感"),
|
||||
Pair("mingkatong", "茗卡通"),
|
||||
Pair("jiujie", "纠结"),
|
||||
Pair("lianaimaoxiangaoxiao", "恋爱冒险搞笑"),
|
||||
Pair("xiuzhenlianaijiakong", "修真恋爱架空"),
|
||||
Pair("lianaigaoxiaohougong", "恋爱搞笑后宫"),
|
||||
Pair("xuanyikongbu", "悬疑恐怖"),
|
||||
Pair("lianaixiaoyuanshenghuo", "恋爱校园生活"),
|
||||
Pair("xiuzhenlianaigufeng", "修真恋爱古风"),
|
||||
Pair("shenghuoxuanyilingyi", "生活悬疑灵异"),
|
||||
Pair("qingnianmanhua", "青年漫画"),
|
||||
Pair("lishimanhua", "历史漫画"),
|
||||
Pair("meishaonv", "美少女"),
|
||||
Pair("shuangliu", "爽流"),
|
||||
Pair("qiangwei", "蔷薇"),
|
||||
Pair("gaozhishang", "高智商"),
|
||||
Pair("xuanyituili", "悬疑推理"),
|
||||
Pair("jizhi", "机智"),
|
||||
Pair("donghua", "动画"),
|
||||
Pair("rexuedongzuo", "热血动作"),
|
||||
Pair("xiuji", "秀吉"),
|
||||
Pair("AA", "AA"),
|
||||
Pair("gaibian", "改编"),
|
||||
Pair("juwei", "橘味")
|
||||
)
|
||||
)
|
||||
|
||||
private class letterfilter : UriSelectFilterPath(
|
||||
"按字母",
|
||||
"filterletter",
|
||||
arrayOf(
|
||||
Pair("", "全部"),
|
||||
Pair("a", "A"),
|
||||
Pair("b", "B"),
|
||||
Pair("c", "C"),
|
||||
Pair("d", "D"),
|
||||
Pair("e", "E"),
|
||||
Pair("f", "F"),
|
||||
Pair("g", "G"),
|
||||
Pair("h", "H"),
|
||||
Pair("i", "I"),
|
||||
Pair("j", "J"),
|
||||
Pair("k", "K"),
|
||||
Pair("l", "L"),
|
||||
Pair("m", "M"),
|
||||
Pair("n", "N"),
|
||||
Pair("o", "O"),
|
||||
Pair("p", "P"),
|
||||
Pair("q", "Q"),
|
||||
Pair("r", "R"),
|
||||
Pair("s", "S"),
|
||||
Pair("t", "T"),
|
||||
Pair("u", "U"),
|
||||
Pair("v", "V"),
|
||||
Pair("w", "W"),
|
||||
Pair("x", "X"),
|
||||
Pair("y", "Y"),
|
||||
Pair("z", "Z"),
|
||||
Pair("1", "其他")
|
||||
)
|
||||
)
|
||||
|
||||
private class statusfilter : UriSelectFilterPath(
|
||||
"按进度",
|
||||
"filterstatus",
|
||||
arrayOf(
|
||||
Pair("", "全部"),
|
||||
Pair("wanjie", "已完结"),
|
||||
Pair("lianzai", "连载中")
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* Class that creates a select filter. Each entry in the dropdown has a name and a display name.
|
||||
* If an entry is selected it is appended as a query parameter onto the end of the URI.
|
||||
* If `firstIsUnspecified` is set to true, if the first entry is selected, nothing will be appended on the the URI.
|
||||
*/
|
||||
// vals: <name, display>
|
||||
private open class UriSelectFilterPath(
|
||||
displayName: String,
|
||||
val uriParam: String,
|
||||
val vals: Array<Pair<String, String>>,
|
||||
val firstIsUnspecified: Boolean = true,
|
||||
defaultValue: Int = 0
|
||||
) :
|
||||
Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray(), defaultValue), UriFilter {
|
||||
override fun addToUri(uri: Uri.Builder) {
|
||||
if (state != 0 || !firstIsUnspecified)
|
||||
uri.appendPath(vals[state].first)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a filter that is able to modify a URI.
|
||||
*/
|
||||
private interface UriFilter {
|
||||
fun addToUri(uri: Uri.Builder)
|
||||
}
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest package="eu.kanade.tachiyomi.extension" />
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
ext {
|
||||
extName = 'Imitui Manhua'
|
||||
pkgNameSuffix = 'zh.imitui'
|
||||
extClass = '.Imitui'
|
||||
extVersionCode = 2
|
||||
}
|
||||
|
||||
|
||||
apply from: "$rootDir/common.gradle"
|
Before Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 182 KiB |
|
@ -1,543 +0,0 @@
|
|||
package eu.kanade.tachiyomi.extension.zh.imitui
|
||||
|
||||
import android.net.Uri
|
||||
import eu.kanade.tachiyomi.network.GET
|
||||
import eu.kanade.tachiyomi.source.model.Filter
|
||||
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.ParsedHttpSource
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
|
||||
class Imitui : ParsedHttpSource() {
|
||||
override val name: String = "爱米推漫画"
|
||||
override val lang: String = "zh"
|
||||
override val supportsLatest: Boolean = true
|
||||
override val baseUrl: String = "https://m.imitui.com"
|
||||
|
||||
// Popular
|
||||
|
||||
// Override to set hasNextPage according to page number
|
||||
override fun popularMangaParse(response: Response): MangasPage {
|
||||
val document = response.asJsoup()
|
||||
|
||||
val mangas = document.select(popularMangaSelector()).map { element ->
|
||||
popularMangaFromElement(element)
|
||||
}
|
||||
|
||||
val totalPage = document.select("input#total-page").attr("value").toInt()
|
||||
val index = document.location().lastIndexOf("page=") + 5
|
||||
val currentPage = document.location().substring(index).toInt()
|
||||
val hasNextPage = currentPage < totalPage
|
||||
|
||||
return MangasPage(mangas, hasNextPage)
|
||||
}
|
||||
|
||||
override fun popularMangaRequest(page: Int) = GET("$baseUrl/list/click/?page=$page", headers)
|
||||
override fun popularMangaNextPageSelector(): String? = throw UnsupportedOperationException("Not used.")
|
||||
override fun popularMangaSelector(): String = "ul#comic-items > li.list-comic"
|
||||
override fun popularMangaFromElement(element: Element): SManga = SManga.create().apply {
|
||||
title = element.select("a.txtA").text()
|
||||
setUrlWithoutDomain(element.select("a.txtA").attr("href"))
|
||||
thumbnail_url = element.select("a.ImgA > img").attr("src")
|
||||
}
|
||||
|
||||
// Latest
|
||||
|
||||
override fun latestUpdatesParse(response: Response): MangasPage = popularMangaParse(response)
|
||||
override fun latestUpdatesRequest(page: Int) = GET("$baseUrl/list/update/?page=$page", headers)
|
||||
override fun latestUpdatesNextPageSelector(): String? = throw UnsupportedOperationException("Not used.")
|
||||
override fun latestUpdatesSelector(): String = popularMangaSelector()
|
||||
override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element)
|
||||
|
||||
// Search
|
||||
|
||||
// Override to set hasNextPage according to page number
|
||||
override fun searchMangaParse(response: Response): MangasPage {
|
||||
val document = response.asJsoup()
|
||||
|
||||
val mangas = document.select(searchMangaSelector()).map { element ->
|
||||
searchMangaFromElement(element)
|
||||
}
|
||||
|
||||
val totalPage = document.select("input#total-page").attr("value").toInt()
|
||||
val index = document.location().lastIndexOf("page=") + 5
|
||||
val currentPage = document.location().substring(index).toInt()
|
||||
val hasNextPage = currentPage < totalPage
|
||||
|
||||
return MangasPage(mangas, hasNextPage)
|
||||
}
|
||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||
val uri = Uri.parse(baseUrl).buildUpon()
|
||||
if (query.isNotBlank()) {
|
||||
uri.appendPath("search")
|
||||
.appendEncodedPath("")
|
||||
.appendQueryParameter("keywords", query)
|
||||
.appendQueryParameter("page", page.toString())
|
||||
} else {
|
||||
uri.appendPath("list")
|
||||
val pathBuilder = Uri.Builder()
|
||||
filters.forEach {
|
||||
if (it is UriSelectFilterPath)
|
||||
it.addToUri(pathBuilder)
|
||||
}
|
||||
val filterPath = pathBuilder.toString().replace("/", "-").removePrefix("-")
|
||||
uri.appendEncodedPath(filterPath)
|
||||
.appendEncodedPath("")
|
||||
.appendQueryParameter("page", page.toString())
|
||||
}
|
||||
return GET(uri.toString(), headers)
|
||||
}
|
||||
|
||||
override fun searchMangaNextPageSelector(): String? = throw UnsupportedOperationException("Not used.")
|
||||
override fun searchMangaSelector(): String = "div.itemBox, li.list-comic"
|
||||
override fun searchMangaFromElement(element: Element): SManga = SManga.create().apply {
|
||||
title = element.select("a.title, a.txtA").text()
|
||||
setUrlWithoutDomain(element.select("a.title, a.txtA").attr("href"))
|
||||
thumbnail_url = element.select("div.itemImg > a > img, a.ImgA > img").attr("src")
|
||||
}
|
||||
|
||||
// Details
|
||||
|
||||
override fun mangaDetailsParse(document: Document): SManga = SManga.create().apply {
|
||||
title = document.select("div#comicName").text()
|
||||
thumbnail_url = document.select("div#Cover > img").attr("abs:src")
|
||||
author = document.select("div.sub_r > p:nth-child(1)").text()
|
||||
artist = author
|
||||
// Sometimes there is one a tag with href="/list/" and empty text, exclude it
|
||||
val genreElement = document.select("div.sub_r > p.txtItme > a").not("[href=/list/]")
|
||||
genre = genreElement.text().replace(" ", ", ")
|
||||
description = if (document.select("p#full-des").isEmpty())
|
||||
document.select("p#simple-des").text()
|
||||
else
|
||||
document.select("p#full-des").text()
|
||||
status = when {
|
||||
!document.select("p.txtItme > a[href=/list/lianzai/]").isEmpty() -> SManga.ONGOING
|
||||
!document.select("p.txtItme > a[href=/list/wanjie/]").isEmpty() -> SManga.COMPLETED
|
||||
else -> SManga.UNKNOWN
|
||||
}
|
||||
}
|
||||
|
||||
// Chapters
|
||||
|
||||
// The last element is not a real chapter, so exclude it
|
||||
override fun chapterListSelector(): String = "ul#chapter-list-1 > li:nth-last-child(n+2)"
|
||||
override fun chapterFromElement(element: Element): SChapter = SChapter.create().apply {
|
||||
setUrlWithoutDomain(element.select("a").attr("href"))
|
||||
name = element.select("span").text()
|
||||
}
|
||||
override fun chapterListParse(response: Response): List<SChapter> {
|
||||
return super.chapterListParse(response).reversed()
|
||||
}
|
||||
|
||||
// Pages
|
||||
|
||||
override fun pageListParse(document: Document): List<Page> = mutableListOf<Page>().apply {
|
||||
val totalPage = document.select("div.image-content > p").text().substring(2)
|
||||
val location = document.location()
|
||||
add(Page(size, location))
|
||||
|
||||
val insertIndex = location.lastIndexOf(".html")
|
||||
for (i in 2..totalPage.toInt()) {
|
||||
add(Page(size, location.replaceRange(insertIndex, insertIndex, "-$i")))
|
||||
}
|
||||
}
|
||||
|
||||
override fun imageUrlParse(document: Document): String =
|
||||
document.select("div.image-content > img#image").attr("src")
|
||||
|
||||
// Some images need referer to load
|
||||
override fun imageRequest(page: Page): Request {
|
||||
val newHeader = headers.newBuilder().add("Referer: https://m.imitui.com/").build()
|
||||
return GET(page.imageUrl!!, newHeader)
|
||||
}
|
||||
|
||||
// Filters
|
||||
|
||||
override fun getFilterList() = FilterList(
|
||||
Filter.Header("如果使用文本搜索"),
|
||||
Filter.Header("过滤器将被忽略"),
|
||||
GenreFilter(),
|
||||
ReaderFilter(),
|
||||
StatusFilter(),
|
||||
RegionFilter()
|
||||
)
|
||||
|
||||
private class GenreFilter : UriSelectFilterPath(
|
||||
"题材",
|
||||
arrayOf(
|
||||
Pair("", "全部"),
|
||||
Pair("rexue", "热血"),
|
||||
Pair("xuanhuan", "玄幻"),
|
||||
Pair("xiuzhen", "修真"),
|
||||
Pair("gufeng", "古风"),
|
||||
Pair("lianai", "恋爱"),
|
||||
Pair("chuanyue", "穿越"),
|
||||
Pair("dushi", "都市"),
|
||||
Pair("bazong", "霸总"),
|
||||
Pair("xuanyi", "悬疑"),
|
||||
Pair("gaoxiao", "搞笑"),
|
||||
Pair("qihuan", "奇幻"),
|
||||
Pair("zongcai", "总裁"),
|
||||
Pair("richang", "日常"),
|
||||
Pair("maoxian", "冒险"),
|
||||
Pair("kehuan", "科幻"),
|
||||
Pair("chunai", "纯爱"),
|
||||
Pair("mohuan", "魔幻"),
|
||||
Pair("zhanzheng", "战争"),
|
||||
Pair("qiangwei", "蔷薇"),
|
||||
Pair("wuxia", "武侠"),
|
||||
Pair("shenghuo", "生活"),
|
||||
Pair("dongzuo", "动作"),
|
||||
Pair("hougong", "后宫"),
|
||||
Pair("youxi", "游戏"),
|
||||
Pair("kongbu", "恐怖"),
|
||||
Pair("mangai", "漫改"),
|
||||
Pair("zhenren", "真人"),
|
||||
Pair("xiaoyuan", "校园"),
|
||||
Pair("juqing", "剧情"),
|
||||
Pair("lingyi", "灵异"),
|
||||
Pair("shaonian", "少年"),
|
||||
Pair("tuili", "推理"),
|
||||
Pair("huaijiu", "怀旧"),
|
||||
Pair("qinggan", "情感"),
|
||||
Pair("ouxiang", "偶像"),
|
||||
Pair("shaonv", "少女"),
|
||||
Pair("dujia", "独家"),
|
||||
Pair("nuexin", "虐心"),
|
||||
Pair("baoxiao", "爆笑"),
|
||||
Pair("lizhi", "励志"),
|
||||
Pair("meishi", "美食"),
|
||||
Pair("fuchou", "复仇"),
|
||||
Pair("caihong", "彩虹"),
|
||||
Pair("weimei", "唯美"),
|
||||
Pair("zhiyu", "治愈"),
|
||||
Pair("mingxing", "明星"),
|
||||
Pair("naodong", "脑洞"),
|
||||
Pair("mofa", "魔法"),
|
||||
Pair("xiuxian", "修仙"),
|
||||
Pair("zhongsheng", "重生"),
|
||||
Pair("xianxia", "仙侠"),
|
||||
Pair("moshi", "末世"),
|
||||
Pair("yineng", "异能"),
|
||||
Pair("nvzun", "女尊"),
|
||||
Pair("qita", "其它"),
|
||||
Pair("yanqing", "言情"),
|
||||
Pair("danmei", "耽美"),
|
||||
Pair("yundong", "运动"),
|
||||
Pair("gongdou", "宫斗"),
|
||||
Pair("guzhuang", "古装"),
|
||||
Pair("meishaonv", "美少女"),
|
||||
Pair("shenmo", "神魔"),
|
||||
Pair("lishi", "历史"),
|
||||
Pair("jingxian", "惊险"),
|
||||
Pair("jingji", "竞技"),
|
||||
Pair("mengxi", "萌系"),
|
||||
Pair("tiyu", "体育"),
|
||||
Pair("gedou", "格斗"),
|
||||
Pair("jijia", "机甲"),
|
||||
Pair("nuelian", "虐恋"),
|
||||
Pair("shuang", "爽"),
|
||||
Pair("fuli", "福利"),
|
||||
Pair("qita2", "其他"),
|
||||
Pair("xiaojiangshi", "小僵尸"),
|
||||
Pair("jiangshi", "僵尸"),
|
||||
Pair("langman", "浪漫"),
|
||||
Pair("jinshouzhi", "金手指"),
|
||||
Pair("yujie", "御姐"),
|
||||
Pair("zhandou", "战斗"),
|
||||
Pair("egao", "恶搞"),
|
||||
Pair("shehui", "社会"),
|
||||
Pair("quanmou", "权谋"),
|
||||
Pair("qingchun", "青春"),
|
||||
Pair("luoli", "萝莉"),
|
||||
Pair("tongren", "同人"),
|
||||
Pair("zhenhan", "震撼"),
|
||||
Pair("riman", "日漫"),
|
||||
Pair("junfa", "军阀"),
|
||||
Pair("minguo", "民国"),
|
||||
Pair("tegong", "特工"),
|
||||
Pair("meinv", "美女"),
|
||||
Pair("jiandie", "间谍"),
|
||||
Pair("anhei", "暗黑"),
|
||||
Pair("jiecao", "节操"),
|
||||
Pair("jingdian", "经典"),
|
||||
Pair("youmo", "幽默"),
|
||||
Pair("tianchong", "甜宠"),
|
||||
Pair("shenhua", "神话"),
|
||||
Pair("riben", "日本"),
|
||||
Pair("yijiyuan", "翼纪元"),
|
||||
Pair("tiaoman", "条漫"),
|
||||
Pair("LOL", "LOL"),
|
||||
Pair("zhongtian", "种田"),
|
||||
Pair("duanpian", "短篇"),
|
||||
Pair("jingsong", "惊悚"),
|
||||
Pair("sige", "四格"),
|
||||
Pair("guoman", "国漫"),
|
||||
Pair("youqudao", "有趣岛"),
|
||||
Pair("mengchong", "萌宠"),
|
||||
Pair("renxing", "人性"),
|
||||
Pair("chonghun", "宠婚"),
|
||||
Pair("xinqi", "新妻"),
|
||||
Pair("xixiegui", "吸血鬼"),
|
||||
Pair("shenjiemanhua", "神界漫画"),
|
||||
Pair("xueyuehua", "雪月花"),
|
||||
Pair("mengqishi", "梦骑士"),
|
||||
Pair("shouer", "兽耳"),
|
||||
Pair("shaoer", "少儿"),
|
||||
Pair("baihe", "百合"),
|
||||
Pair("chiji", "吃鸡"),
|
||||
Pair("qiangzhan", "枪战"),
|
||||
Pair("tezhongbing", "特种兵"),
|
||||
Pair("xiongdi", "兄弟"),
|
||||
Pair("yishi", "异世"),
|
||||
Pair("xiongmei", "兄妹"),
|
||||
Pair("sanciyuan", "三次元"),
|
||||
Pair("meixing", "美型"),
|
||||
Pair("haomen", "豪门"),
|
||||
Pair("hunchong", "婚宠"),
|
||||
Pair("kaigua", "开挂"),
|
||||
Pair("xuexing", "血腥"),
|
||||
Pair("qingsong", "轻松"),
|
||||
Pair("yangcheng", "养成"),
|
||||
Pair("tishen", "替身"),
|
||||
Pair("nanshen", "男神"),
|
||||
Pair("qingqingshu", "青青树"),
|
||||
Pair("yishijie", "异世界"),
|
||||
Pair("nanchuannv", "男穿女"),
|
||||
Pair("hunchuan", "魂穿"),
|
||||
Pair("yinan", "阴暗"),
|
||||
Pair("dujitang", "毒鸡汤"),
|
||||
Pair("pianyu", "片玉"),
|
||||
Pair("manhuahui", "漫画会"),
|
||||
Pair("longren", "龙刃"),
|
||||
Pair("xihuan", "喜欢"),
|
||||
Pair("zhaohuan", "召唤"),
|
||||
Pair("yijie", "异界"),
|
||||
Pair("henxiyou", "狠西游"),
|
||||
Pair("xiyouji", "西游记"),
|
||||
Pair("jianghu", "江湖"),
|
||||
Pair("duantoudao", "断头岛"),
|
||||
Pair("hanman", "韩漫"),
|
||||
Pair("bingjiao", "病娇"),
|
||||
Pair("changpian", "长篇"),
|
||||
Pair("chenlan", "陈岚"),
|
||||
Pair("aiqing", "爱情"),
|
||||
Pair("nvqiang", "女强"),
|
||||
Pair("ranxiang", "燃向"),
|
||||
Pair("tianshangkong", "天上空"),
|
||||
Pair("duzhiniao", "渡之鸟"),
|
||||
Pair("xuezu", "血族"),
|
||||
Pair("mowang", "魔王"),
|
||||
Pair("keai", "可爱"),
|
||||
Pair("gongting", "宫廷"),
|
||||
Pair("hunlian", "婚恋"),
|
||||
Pair("meng", "萌"),
|
||||
Pair("ashuai", "阿衰"),
|
||||
Pair("sanjiaolian", "三角恋"),
|
||||
Pair("qianshi", "前世"),
|
||||
Pair("lunhui", "轮回"),
|
||||
Pair("jingqi", "惊奇"),
|
||||
Pair("zhentan", "侦探"),
|
||||
Pair("huanlexiang", "欢乐向"),
|
||||
Pair("zhichang", "职场"),
|
||||
Pair("gandong", "感动"),
|
||||
Pair("jiakong", "架空"),
|
||||
Pair("qingxiaoshuo", "轻小说"),
|
||||
Pair("yanyi", "颜艺"),
|
||||
Pair("xingzhuanhuan", "性转换"),
|
||||
Pair("dongfang", "东方"),
|
||||
Pair("danmeiBL", "耽美BL"),
|
||||
Pair("qingsonggaoxiao", "轻松搞笑"),
|
||||
Pair("tongrenmanhua", "同人漫画"),
|
||||
Pair("xiaoyuangaoxiaoshenghuo", "校园搞笑生活"),
|
||||
Pair("shaonvaiqing", "少女爱情"),
|
||||
Pair("zhengju", "正剧"),
|
||||
Pair("shaonao", "烧脑"),
|
||||
Pair("zhuangbi", "装逼"),
|
||||
Pair("shengui", "神鬼"),
|
||||
Pair("weiniang", "伪娘"),
|
||||
Pair("gaoqingdanxing", "高清单行"),
|
||||
Pair("gushimanhua", "故事漫画"),
|
||||
Pair("lianaishenghuoxuanhuan", "恋爱生活玄幻"),
|
||||
Pair("xifangmohuan", "西方魔幻"),
|
||||
Pair("jianniang", "舰娘"),
|
||||
Pair("zhaixi", "宅系"),
|
||||
Pair("shangzhan", "商战"),
|
||||
Pair("shuangliu", "爽流"),
|
||||
Pair("rexuemaoxian", "热血冒险"),
|
||||
Pair("keji", "科技"),
|
||||
Pair("wenxin", "温馨"),
|
||||
Pair("jiating", "家庭"),
|
||||
Pair("hunyin", "婚姻"),
|
||||
Pair("duanzi", "段子"),
|
||||
Pair("neihan", "内涵"),
|
||||
Pair("jizhan", "机战"),
|
||||
Pair("yulequan", "娱乐圈"),
|
||||
Pair("weilai", "未来"),
|
||||
Pair("chongwu", "宠物"),
|
||||
Pair("bazonglianaixuanhuan", "霸总恋爱玄幻"),
|
||||
Pair("gushi", "故事"),
|
||||
Pair("yinyuewudao", "音乐舞蹈"),
|
||||
Pair("nixi", "逆袭"),
|
||||
Pair("zhaohuanshou", "召唤兽"),
|
||||
Pair("kehuanmohuan", "科幻魔幻"),
|
||||
Pair("jiujie", "纠结"),
|
||||
Pair("lunli", "伦理"),
|
||||
Pair("lianaishenghuo", "恋爱生活"),
|
||||
Pair("xinzuo", "新作"),
|
||||
Pair("lishimanhua", "历史漫画"),
|
||||
Pair("ertong", "儿童"),
|
||||
Pair("zhentantuili", "侦探推理"),
|
||||
Pair("xiuzhenlianaijiakong", "修真恋爱架空"),
|
||||
Pair("shougong", "手工"),
|
||||
Pair("qingnian", "青年"),
|
||||
Pair("qitamanhua", "其他漫画"),
|
||||
Pair("zhiyu2", "致郁"),
|
||||
Pair("shishi", "史诗"),
|
||||
Pair("xiuji", "秀吉"),
|
||||
Pair("xiangcun", "乡村"),
|
||||
Pair("xingzhuan", "性转"),
|
||||
Pair("hunai", "婚爱"),
|
||||
Pair("siwang", "死亡"),
|
||||
Pair("sishen", "死神"),
|
||||
Pair("shaonan", "少男"),
|
||||
Pair("xuanyijingsong", "悬疑、惊悚"),
|
||||
Pair("baoxiaoxiju", "爆笑喜剧"),
|
||||
Pair("dongzuogedou", "动作格斗"),
|
||||
Pair("gaibian", "改编"),
|
||||
Pair("AA", "AA"),
|
||||
Pair("lianaidanmei", "恋爱耽美"),
|
||||
Pair("heidao", "黑道"),
|
||||
Pair("guiguai", "鬼怪"),
|
||||
Pair("sangshi", "丧尸"),
|
||||
Pair("zhupu", "主仆"),
|
||||
Pair("zhiyinmanke", "知音漫客"),
|
||||
Pair("maimeng", "麦萌"),
|
||||
Pair("nizhuan", "逆转"),
|
||||
Pair("danvzhu", "大女主"),
|
||||
Pair("aimei", "暧昧"),
|
||||
Pair("shenghua", "生化"),
|
||||
Pair("qiwen", "奇闻"),
|
||||
Pair("zhaidou", "宅斗"),
|
||||
Pair("lanmu", "栏目"),
|
||||
Pair("guaitan", "怪谈"),
|
||||
Pair("chongai", "宠爱"),
|
||||
Pair("huanxiang", "幻想"),
|
||||
Pair("yizu", "异族"),
|
||||
Pair("tanan", "探案"),
|
||||
Pair("panni", "叛逆"),
|
||||
Pair("juwei", "橘味"),
|
||||
Pair("yinv", "乙女"),
|
||||
Pair("lieqi", "猎奇"),
|
||||
Pair("rigeng", "日更"),
|
||||
Pair("manman", "漫漫"),
|
||||
Pair("zhidou", "智斗"),
|
||||
Pair("zhengnengliang", "正能量"),
|
||||
Pair("manhuayifan", "漫画一番"),
|
||||
Pair("nvwangdiankeng", "女王点坑"),
|
||||
Pair("mankezhan", "漫客栈"),
|
||||
Pair("samanhua", "飒漫画"),
|
||||
Pair("xiaoshuogaibian", "小说改编"),
|
||||
Pair("shenshi", "绅士"),
|
||||
Pair("kongbuxuanyi", "恐怖悬疑"),
|
||||
Pair("huiben", "绘本"),
|
||||
Pair("yinyue", "音乐"),
|
||||
Pair("huxian", "狐仙"),
|
||||
Pair("sihoushijie", "死后世界"),
|
||||
Pair("motong", "墨瞳"),
|
||||
Pair("manhua", "漫画"),
|
||||
Pair("mori", "末日"),
|
||||
Pair("xitong", "系统"),
|
||||
Pair("shenxian", "神仙"),
|
||||
Pair("youyaoqi", "有妖气"),
|
||||
Pair("guaiwu", "怪物"),
|
||||
Pair("yaoguai", "妖怪"),
|
||||
Pair("shenhao", "神豪"),
|
||||
Pair("bazongdushi", "霸总.都市"),
|
||||
Pair("gaotian", "高甜"),
|
||||
Pair("xianzhiji", "限制级"),
|
||||
Pair("dianjing", "电竞"),
|
||||
Pair("unknown", "ゆり"),
|
||||
Pair("xiongdiqing", "兄弟情"),
|
||||
Pair("nuanmeng", "暖萌"),
|
||||
Pair("haokuai", "豪快"),
|
||||
Pair("wanjie", "完结"),
|
||||
Pair("nvsheng", "女生"),
|
||||
Pair("lianzai", "连载"),
|
||||
Pair("nansheng", "男生"),
|
||||
Pair("futa", "扶她"),
|
||||
Pair("bianshenlongyurentishiyanshenghuaweiji", "变身;龙鱼;人体实验;生化危机"),
|
||||
Pair("shenghuomanhua", "生活漫画"),
|
||||
Pair("huanxi", "欢喜"),
|
||||
Pair("beiou", "北欧"),
|
||||
Pair("fuhei", "腹黑"),
|
||||
Pair("xihuan2", "西幻"),
|
||||
Pair("qinqing", "亲情"),
|
||||
Pair("gudai", "古代"),
|
||||
Pair("jifu", "基腐"),
|
||||
Pair("langmanaiqing", "浪漫爱情"),
|
||||
Pair("BL", "BL"),
|
||||
Pair("qihuanmaoxian", "奇幻冒险"),
|
||||
Pair("youmogaoxiao", "幽默搞笑"),
|
||||
Pair("gufengchuanyue", "古风穿越"),
|
||||
Pair("zongheqita", "综合其它"),
|
||||
Pair("TS", "TS")
|
||||
)
|
||||
)
|
||||
|
||||
private class ReaderFilter : UriSelectFilterPath(
|
||||
"读者",
|
||||
arrayOf(
|
||||
Pair("", "全部"),
|
||||
Pair("ertong", "儿童漫画"),
|
||||
Pair("shaonian", "少年漫画"),
|
||||
Pair("shaonv", "少女漫画"),
|
||||
Pair("qingnian", "青年漫画")
|
||||
)
|
||||
)
|
||||
|
||||
private class StatusFilter : UriSelectFilterPath(
|
||||
"进度",
|
||||
arrayOf(
|
||||
Pair("", "全部"),
|
||||
Pair("wanjie", "已完结"),
|
||||
Pair("lianzai", "连载中")
|
||||
)
|
||||
)
|
||||
|
||||
private class RegionFilter : UriSelectFilterPath(
|
||||
"地区",
|
||||
arrayOf(
|
||||
Pair("", "全部"),
|
||||
Pair("riben", "日本"),
|
||||
Pair("dalu", "大陆"),
|
||||
Pair("hongkong", "香港"),
|
||||
Pair("taiwan", "台湾"),
|
||||
Pair("oumei", "欧美"),
|
||||
Pair("hanguo", "韩国"),
|
||||
Pair("qita", "其他")
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* Class that creates a select filter. Each entry in the dropdown has a name and a display name.
|
||||
* If an entry is selected it is appended as a query parameter onto the end of the URI.
|
||||
*/
|
||||
// vals: <name, display>
|
||||
private open class UriSelectFilterPath(
|
||||
displayName: String,
|
||||
val vals: Array<Pair<String, String>>
|
||||
) : Filter.Select<String>(displayName, vals.map { it.second }.toTypedArray()) {
|
||||
fun addToUri(uri: Uri.Builder) {
|
||||
if (state != 0)
|
||||
uri.appendPath(vals[state].first)
|
||||
}
|
||||
}
|
||||
}
|