Added Junmei tu (#10411)

* Init

* init

* Added Junmei Tu
This commit is contained in:
jopejoe1 2022-01-10 08:35:29 +13:00 committed by GitHub
parent 6b38a0b299
commit 47423f7ab3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 225 additions and 0 deletions

View File

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.extension" />

View File

@ -0,0 +1,12 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
extName = 'Junmei tu'
pkgNameSuffix = 'all.junmeitu'
extClass = '.JunmeiTu'
extVersionCode = 1
isNsfw = true
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View File

@ -0,0 +1,211 @@
package eu.kanade.tachiyomi.extension.all.junmeitu
import android.app.Application
import android.content.SharedPreferences
import androidx.preference.ListPreference
import androidx.preference.PreferenceScreen
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.ConfigurableSource
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.Request
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class JunmeiTu() : ConfigurableSource, ParsedHttpSource() {
override val lang = "all"
override val name = "Junmei tu"
override val supportsLatest = true
// Preference
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_$id", 0x0000)
}
override val baseUrl: String = getMirrorPref()!!
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val mirrorPref = ListPreference(screen.context).apply {
key = "${MIRROR_PREF_KEY}_$lang"
title = MIRROR_PREF_TITLE
entries = MIRROR_PREF_ENTRIES
entryValues = MIRROR_PREF_ENTRY_VALUES
setDefaultValue(MIRROR_PREF_DEFAULT_VALUE)
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
val selected = newValue as String
val index = findIndexOfValue(selected)
val entry = entryValues[index] as String
preferences.edit().putString("${MIRROR_PREF_KEY}_$lang", entry).commit()
}
}
screen.addPreference(mirrorPref)
}
private fun getMirrorPref(): String? = preferences.getString("${MIRROR_PREF_KEY}_$lang", MIRROR_PREF_DEFAULT_VALUE)
companion object {
private const val MIRROR_PREF_KEY = "MIRROR"
private const val MIRROR_PREF_TITLE = "Mirror"
private val MIRROR_PREF_ENTRIES = arrayOf("Junmeitu.com", "Meijuntu.com")
private val MIRROR_PREF_ENTRY_VALUES = arrayOf("https://junmeitu.com", "https://meijuntu.com")
private val MIRROR_PREF_DEFAULT_VALUE = MIRROR_PREF_ENTRY_VALUES[0]
}
// Latest
override fun latestUpdatesFromElement(element: Element): SManga {
val manga = SManga.create()
manga.thumbnail_url = element.select("img").attr("abs:src")
manga.title = element.select("p").text()
manga.setUrlWithoutDomain(element.select("a").attr("abs:href"))
return manga
}
override fun latestUpdatesNextPageSelector() = "span + a + a"
override fun latestUpdatesRequest(page: Int): Request {
return GET("$baseUrl/beauty/index-$page.html")
}
override fun latestUpdatesSelector() = ".pic-list > ul > li"
// Popular
override fun popularMangaFromElement(element: Element) = latestUpdatesFromElement(element)
override fun popularMangaNextPageSelector() = latestUpdatesNextPageSelector()
override fun popularMangaRequest(page: Int): Request {
return GET("$baseUrl/beauty/hot-$page.html")
}
override fun popularMangaSelector() = latestUpdatesSelector()
// Search
override fun searchMangaFromElement(element: Element) = latestUpdatesFromElement(element)
override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector()
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val tagFilter = filters.findInstance<TagFilter>()
val modelFilter = filters.findInstance<ModelFilter>()
val groupFilter = filters.findInstance<GroupFilter>()
val categoryFilter = filters.findInstance<CategoryFilter>()
val sortFilter = filters.findInstance<SortFilter>()
return when {
query.isNotEmpty() -> GET("$baseUrl/search/$query-$page.html")
tagFilter!!.state.isNotEmpty() -> GET("$baseUrl/tags/${tagFilter.state}-${categoryFilter!!.selected}-$page.html")
modelFilter!!.state.isNotEmpty() -> GET("$baseUrl/model/${modelFilter.state}-$page.html")
groupFilter!!.state.isNotEmpty() -> GET("$baseUrl/xzjg/${groupFilter.state}-$page.html")
categoryFilter!!.state != 0 -> GET("$baseUrl/${categoryFilter.slug}/${sortFilter!!.selected}-$page.html")
sortFilter!!.state != 0 -> GET("$baseUrl/${categoryFilter.slug}/${sortFilter.selected}-$page.html")
else -> latestUpdatesRequest(page)
}
}
override fun searchMangaSelector() = latestUpdatesSelector()
// Details
override fun mangaDetailsParse(document: Document): SManga {
val manga = SManga.create()
manga.title = document.selectFirst(".news-title,.title").text()
manga.description = document.select(".news-info,.picture-details").text() + "\n" + document.select(".introduce").text()
val genres = mutableListOf<String>()
document.select(".relation_tags > a").forEach {
genres.add(it.text())
}
manga.genre = genres.joinToString(", ")
return manga
}
override fun chapterFromElement(element: Element): SChapter {
val chapter = SChapter.create()
chapter.setUrlWithoutDomain(element.select(".position a:last-child").first().attr("abs:href"))
chapter.chapter_number = 0F
chapter.name = element.select(".news-title,.title").text()
return chapter
}
override fun chapterListSelector() = "html"
// Pages
override fun pageListParse(document: Document): List<Page> {
val numPages = document.select(".pages > a:nth-last-of-type(2)").text().toIntOrNull()
var url = document.select(".position a:last-child").first().attr("abs:href")
val pages = mutableListOf<Page>()
var count = 0
if (numPages != null) {
url = url.substringBeforeLast(".")
while (numPages != count) {
count += 1
val doc = when (count) {
1 -> document
else -> client.newCall(GET("$url-$count.html")).execute().asJsoup()
}
doc.select(".pictures img,.news-body img").forEachIndexed() { index, it ->
val imgUrl = when {
it.hasAttr("data-original") -> it.attr("abs:data-original")
it.hasAttr("data-src") -> it.attr("abs:data-src")
it.hasAttr("data-lazy-src") -> it.attr("abs:data-lazy-src")
else -> it.attr("abs:src")
}
pages.add(Page(index, imgUrl, imgUrl))
}
}
} else {
document.select(".pictures img,.news-body img").forEachIndexed() { index, it ->
val imgUrl = when {
it.hasAttr("data-original") -> it.attr("abs:data-original")
it.hasAttr("data-src") -> it.attr("abs:data-src")
it.hasAttr("data-lazy-src") -> it.attr("abs:data-lazy-src")
else -> it.attr("abs:src")
}
pages.add(Page(index, imgUrl, imgUrl))
}
}
return pages
}
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
// Filters
override fun getFilterList(): FilterList = FilterList(
Filter.Header("NOTE: Ignored if using text search!"),
Filter.Header("NOTE: Filter are weird for this extension!"),
Filter.Separator(),
TagFilter(),
ModelFilter(),
GroupFilter(),
CategoryFilter(getCategoryFilter(), 0),
SortFilter(getSortFilter(), 0)
)
class SelectFilterOption(val name: String, val value: String = name)
abstract class SelectFilter(name: String, private val options: List<SelectFilterOption>, default: Int = 0) : Filter.Select<String>(name, options.map { it.name }.toTypedArray(), default) {
val selected: String
get() = options[state].value
val slug: String
get() = options[state].name
}
class TagFilter : Filter.Text("Tag")
class ModelFilter : Filter.Text("Model")
class GroupFilter : Filter.Text("Group")
class CategoryFilter(options: List<SelectFilterOption>, default: Int) : SelectFilter("Category", options, default)
class SortFilter(options: List<SelectFilterOption>, default: Int) : SelectFilter("Sort", options, default)
private fun getCategoryFilter() = listOf(
SelectFilterOption("beauty", "6"),
SelectFilterOption("handsome", "5"),
SelectFilterOption("news", "30"),
SelectFilterOption("street", "32"),
)
private fun getSortFilter() = listOf(
SelectFilterOption("default", "index"),
SelectFilterOption("hot"),
)
private inline fun <reified T> Iterable<*>.findInstance() = find { it is T } as? T
}