diff --git a/.run/SinMHGenerator.run.xml b/.run/SinMHGenerator.run.xml new file mode 100644 index 000000000..31c7d75f1 --- /dev/null +++ b/.run/SinMHGenerator.run.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/multisrc/overrides/sinmh/gufengmh/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/sinmh/gufengmh/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..ca8ced812 Binary files /dev/null and b/multisrc/overrides/sinmh/gufengmh/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/sinmh/gufengmh/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/sinmh/gufengmh/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..ed07a9292 Binary files /dev/null and b/multisrc/overrides/sinmh/gufengmh/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/sinmh/gufengmh/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/sinmh/gufengmh/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..73fc4e3db Binary files /dev/null and b/multisrc/overrides/sinmh/gufengmh/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/sinmh/gufengmh/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/sinmh/gufengmh/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..1a7ba3097 Binary files /dev/null and b/multisrc/overrides/sinmh/gufengmh/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/sinmh/gufengmh/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/sinmh/gufengmh/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..1ff80b15d Binary files /dev/null and b/multisrc/overrides/sinmh/gufengmh/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/sinmh/gufengmh/res/web_hi_res_512.png b/multisrc/overrides/sinmh/gufengmh/res/web_hi_res_512.png new file mode 100644 index 000000000..317212e48 Binary files /dev/null and b/multisrc/overrides/sinmh/gufengmh/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/sinmh/imitui/res/mipmap-hdpi/ic_launcher.png b/multisrc/overrides/sinmh/imitui/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..66eb5b99f Binary files /dev/null and b/multisrc/overrides/sinmh/imitui/res/mipmap-hdpi/ic_launcher.png differ diff --git a/multisrc/overrides/sinmh/imitui/res/mipmap-mdpi/ic_launcher.png b/multisrc/overrides/sinmh/imitui/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..0974201c4 Binary files /dev/null and b/multisrc/overrides/sinmh/imitui/res/mipmap-mdpi/ic_launcher.png differ diff --git a/multisrc/overrides/sinmh/imitui/res/mipmap-xhdpi/ic_launcher.png b/multisrc/overrides/sinmh/imitui/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..9564df603 Binary files /dev/null and b/multisrc/overrides/sinmh/imitui/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/sinmh/imitui/res/mipmap-xxhdpi/ic_launcher.png b/multisrc/overrides/sinmh/imitui/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..11a0425ca Binary files /dev/null and b/multisrc/overrides/sinmh/imitui/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/sinmh/imitui/res/mipmap-xxxhdpi/ic_launcher.png b/multisrc/overrides/sinmh/imitui/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..49a80c5e5 Binary files /dev/null and b/multisrc/overrides/sinmh/imitui/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/multisrc/overrides/sinmh/imitui/res/web_hi_res_512.png b/multisrc/overrides/sinmh/imitui/res/web_hi_res_512.png new file mode 100644 index 000000000..cb3aa0a47 Binary files /dev/null and b/multisrc/overrides/sinmh/imitui/res/web_hi_res_512.png differ diff --git a/multisrc/overrides/sinmh/imitui/src/Imitui.kt b/multisrc/overrides/sinmh/imitui/src/Imitui.kt new file mode 100644 index 000000000..b22967962 --- /dev/null +++ b/multisrc/overrides/sinmh/imitui/src/Imitui.kt @@ -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 { + 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") +} diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/sinmh/SinMH.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/sinmh/SinMH.kt new file mode 100644 index 000000000..a032cbb82 --- /dev/null +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/sinmh/SinMH.kt @@ -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() + .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 { + 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, private val uriParts: Array) : + Filter.Select(displayName, values) { + fun toUriPart(): String = uriParts[state] + } + + protected data class Category(val name: String, val values: Array, val uriParts: Array) { + fun toUriPartFilter() = UriPartFilter(name, values, uriParts) + } + + private lateinit var categories: List + + 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("分类尚未获取,请返回上一页后重试") + ) +} diff --git a/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/sinmh/SinMHGenerator.kt b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/sinmh/SinMHGenerator.kt new file mode 100644 index 000000000..27eb3c0fa --- /dev/null +++ b/multisrc/src/main/java/eu/kanade/tachiyomi/multisrc/sinmh/SinMHGenerator.kt @@ -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) { + SinMHGenerator().createAll() + } + } +} diff --git a/src/zh/gufengmh/AndroidManifest.xml b/src/zh/gufengmh/AndroidManifest.xml deleted file mode 100644 index 30deb7f79..000000000 --- a/src/zh/gufengmh/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/zh/gufengmh/build.gradle b/src/zh/gufengmh/build.gradle deleted file mode 100644 index a79a38d83..000000000 --- a/src/zh/gufengmh/build.gradle +++ /dev/null @@ -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" diff --git a/src/zh/gufengmh/res/mipmap-hdpi/ic_launcher.png b/src/zh/gufengmh/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 0ea26e4a8..000000000 Binary files a/src/zh/gufengmh/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/zh/gufengmh/res/mipmap-mdpi/ic_launcher.png b/src/zh/gufengmh/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 60513cee9..000000000 Binary files a/src/zh/gufengmh/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/zh/gufengmh/res/mipmap-xhdpi/ic_launcher.png b/src/zh/gufengmh/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 43e5aacbf..000000000 Binary files a/src/zh/gufengmh/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/zh/gufengmh/res/mipmap-xxhdpi/ic_launcher.png b/src/zh/gufengmh/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 6c012665f..000000000 Binary files a/src/zh/gufengmh/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/zh/gufengmh/res/mipmap-xxxhdpi/ic_launcher.png b/src/zh/gufengmh/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 04a89a9f5..000000000 Binary files a/src/zh/gufengmh/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/zh/gufengmh/res/web_hi_res_512.png b/src/zh/gufengmh/res/web_hi_res_512.png deleted file mode 100644 index 4ea4fa161..000000000 Binary files a/src/zh/gufengmh/res/web_hi_res_512.png and /dev/null differ diff --git a/src/zh/gufengmh/src/eu/kanade/tachiyomi/extension/zh/gufengmh/Gufengmh.kt b/src/zh/gufengmh/src/eu/kanade/tachiyomi/extension/zh/gufengmh/Gufengmh.kt deleted file mode 100644 index d6db6bd72..000000000 --- a/src/zh/gufengmh/src/eu/kanade/tachiyomi/extension/zh/gufengmh/Gufengmh.kt +++ /dev/null @@ -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 { - return super.chapterListParse(response).reversed() - } - - // Pages - - override fun pageListParse(document: Document): List = mutableListOf().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: - private open class UriSelectFilterPath( - displayName: String, - val uriParam: String, - val vals: Array>, - val firstIsUnspecified: Boolean = true, - defaultValue: Int = 0 - ) : - Filter.Select(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) - } -} diff --git a/src/zh/imitui/AndroidManifest.xml b/src/zh/imitui/AndroidManifest.xml deleted file mode 100644 index 30deb7f79..000000000 --- a/src/zh/imitui/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/src/zh/imitui/build.gradle b/src/zh/imitui/build.gradle deleted file mode 100644 index 791688f83..000000000 --- a/src/zh/imitui/build.gradle +++ /dev/null @@ -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" diff --git a/src/zh/imitui/res/mipmap-hdpi/ic_launcher.png b/src/zh/imitui/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 263e23c1d..000000000 Binary files a/src/zh/imitui/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/src/zh/imitui/res/mipmap-mdpi/ic_launcher.png b/src/zh/imitui/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 1197b770d..000000000 Binary files a/src/zh/imitui/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/src/zh/imitui/res/mipmap-xhdpi/ic_launcher.png b/src/zh/imitui/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index ecc2720d0..000000000 Binary files a/src/zh/imitui/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/src/zh/imitui/res/mipmap-xxhdpi/ic_launcher.png b/src/zh/imitui/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index dd5cd5f2a..000000000 Binary files a/src/zh/imitui/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/zh/imitui/res/mipmap-xxxhdpi/ic_launcher.png b/src/zh/imitui/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 25518a286..000000000 Binary files a/src/zh/imitui/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/src/zh/imitui/res/web_hi_res_512.png b/src/zh/imitui/res/web_hi_res_512.png deleted file mode 100644 index 107482731..000000000 Binary files a/src/zh/imitui/res/web_hi_res_512.png and /dev/null differ diff --git a/src/zh/imitui/src/eu/kanade/tachiyomi/extension/zh/imitui/Imitui.kt b/src/zh/imitui/src/eu/kanade/tachiyomi/extension/zh/imitui/Imitui.kt deleted file mode 100644 index 78858da80..000000000 --- a/src/zh/imitui/src/eu/kanade/tachiyomi/extension/zh/imitui/Imitui.kt +++ /dev/null @@ -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 { - return super.chapterListParse(response).reversed() - } - - // Pages - - override fun pageListParse(document: Document): List = mutableListOf().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: - private open class UriSelectFilterPath( - displayName: String, - val vals: Array> - ) : Filter.Select(displayName, vals.map { it.second }.toTypedArray()) { - fun addToUri(uri: Uri.Builder) { - if (state != 0) - uri.appendPath(vals[state].first) - } - } -}