Tachiyomi-Extensions/multisrc/overrides/wpmangastream/mihentai/src/Mihentai.kt

180 lines
6.7 KiB
Kotlin

package eu.kanade.tachiyomi.extension.en.mihentai
import eu.kanade.tachiyomi.multisrc.wpmangastream.WPMangaStream
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.SManga
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Request
import org.jsoup.nodes.Document
import uy.kohesive.injekt.injectLazy
import java.util.Locale
class Mihentai : WPMangaStream("Mihentai", "https://mihentai.com", "en") {
override fun popularMangaRequest(page: Int): Request {
return GET("$baseUrl/manga/page/$page/?order=popular", headers)
}
override fun latestUpdatesRequest(page: Int): Request {
return GET("$baseUrl/manga/page/$page/?order=update", headers)
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = "$baseUrl/manga/page/$page/".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("title", query)
filters.forEach { filter ->
when (filter) {
is StatusFilter -> url.addQueryParameter("status", filter.toUriPart())
is TypeFilter -> url.addQueryParameter("type", filter.toUriPart())
is SortByFilter -> url.addQueryParameter("order", filter.toUriPart())
is GenreListFilter -> {
filter.state
.filter { it.state != Filter.TriState.STATE_IGNORE }
.forEach { url.addQueryParameter("genre[]", it.id) }
}
}
}
return GET(url.build().toString(), headers)
}
override fun mangaDetailsParse(document: Document): SManga {
return SManga.create().apply {
document.select("div.bigcontent, div.animefull, div.main-info").firstOrNull()?.let { infoElement ->
status = parseStatus(infoElement.select("span:contains(Status:), .imptdt:contains(Status) i").firstOrNull()?.ownText())
thumbnail_url = infoElement.select("div.thumb img").imgAttr()
val genres = infoElement.select("span:contains(Tag) a")
.map { element -> element.text().toLowerCase(Locale.ROOT) }
.toMutableSet()
// add series type(manga/manhwa/manhua/other) thinggy to genre
document.select("span:contains(Type)").firstOrNull()?.ownText()?.let {
if (it.isEmpty().not() && genres.contains(it).not()) {
genres.add(it.toLowerCase(Locale.ROOT))
}
}
genre = genres.toList().joinToString(", ") { it.capitalize(Locale.ROOT) }
}
}
}
override fun parseStatus(element: String?): Int = when {
element == null -> SManga.UNKNOWN
listOf("ongoing", "publishing").any { it.contains(element, ignoreCase = true) } -> SManga.ONGOING
listOf("finished").any { it.contains(element, ignoreCase = true) } -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
private val json: Json by injectLazy()
override fun pageListParse(document: Document): List<Page> {
val htmlPages = document.select(pageSelector)
.filterNot { it.attr("abs:src").isNullOrEmpty() }
.mapIndexed { i, img ->
val pageUrl = img.attr("abs:src").substringAfter(baseUrl).prependIndent(baseUrl)
Page(i, "", pageUrl)
}
.toMutableList()
val docString = document.toString()
val imageListRegex = Regex("\\\"images.*?:.*?(\\[.*?\\])")
val imageListJson = imageListRegex.find(docString)?.destructured?.toList()?.get(0)
if (imageListJson != null) {
val imageList = json.parseToJsonElement(imageListJson).jsonArray
val baseResolver = baseUrl.toHttpUrl()
val scriptPages = imageList.mapIndexed { i, jsonEl ->
val imageUrl = jsonEl.jsonPrimitive.content
Page(i, "", baseResolver.resolve(imageUrl).toString())
}
if (htmlPages.size < scriptPages.size) {
htmlPages += scriptPages
}
}
countViews(document)
return htmlPages.distinctBy { it.imageUrl }
}
private class StatusFilter : UriPartFilter(
"Status",
arrayOf(
Pair("All", ""),
Pair("Publishing", "publishing"),
Pair("Finished", "finished"),
Pair("Dropped", "drop")
)
)
private class TypeFilter : UriPartFilter(
"Type",
arrayOf(
Pair("Default", ""),
Pair("Manga", "Manga"),
Pair("Manhwa", "Manhwa"),
Pair("Manhua", "Manhua"),
Pair("Webtoon", "webtoon"),
Pair("One-Shot", "One-Shot"),
Pair("Doujin", "doujin")
)
)
override fun getFilterList(): FilterList = FilterList(
listOf(
StatusFilter(),
TypeFilter(),
SortByFilter(),
GenreListFilter(getGenreList())
)
)
override fun getGenreList(): List<Genre> = listOf(
Genre("Adventure", "adventure"),
Genre("Ahego", "ahego"),
Genre("Anal", "anal"),
Genre("Battle", "battle"),
Genre("Big Breasts", "big-breasts"),
Genre("Blowjob", "blowjob"),
Genre("Comic 3D", "comic-3d"),
Genre("Doujin", "doujin"),
Genre("Dragon ball", "dragon-ball"),
Genre("Fingering", "fingering"),
Genre("Full color", "full-color"),
Genre("Futanari", "futanari"),
Genre("Girlfriend", "girlfriend"),
Genre("Grouped", "grouped"),
Genre("Handjob", "handjob"),
Genre("Hijab", "hijab"),
Genre("Incest", "incest"),
Genre("Kissing", "kissing"),
Genre("Mama", "mama"),
Genre("Manga", "manga"),
Genre("Masturbation", "masturbation"),
Genre("Milf", "milf"),
Genre("Mom & Son", "mom-son"),
Genre("Naruto", "naruto"),
Genre("One Piece", "one-piece"),
Genre("Pregnancy", "pregnancy"),
Genre("Rape", "rape"),
Genre("Romance", "romance"),
Genre("School", "school"),
Genre("Scooby-Doo", "scooby-doo"),
Genre("Sister", "sister"),
Genre("Stocking", "stocking"),
Genre("Sub Indo", "sub-indo"),
Genre("Threesome", "threesome"),
Genre("Uncensored", "uncensored"),
Genre("Western", "western"),
Genre("Yuri", "yuri")
)
}