ZeistManga: Add popular tab and more manga details + add sources (#19031)

* Update ZeistManga

* Wrong order

* Add more sources

* Lint

* Add MikoRoku

* Lint again

* Finally fix search

* Finally fix search

* Use correct parser for search
This commit is contained in:
bapeey 2023-11-20 11:35:09 -05:00 committed by GitHub
parent 824c0e44fa
commit e1f29d314a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
74 changed files with 297 additions and 109 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

View File

@ -0,0 +1,41 @@
package eu.kanade.tachiyomi.extension.pt.animexnovel
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Response
class AnimeXNovel : ZeistManga("AnimeXNovel", "https://www.animexnovel.com", "pt-BR") {
override val mangaCategory: String = "Manga"
override fun popularMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
val mangas = document.select("div.PopularPosts div.grid > figure").map { element ->
SManga.create().apply {
thumbnail_url = element.selectFirst("img")!!.attr("abs:src")
title = element.selectFirst("figcaption > a")!!.text()
setUrlWithoutDomain(element.selectFirst("figcaption > a")!!.attr("href"))
}
}.filter { it.title.contains("[Mangá]") }
return MangasPage(mangas, false)
}
override val mangaDetailsSelectorDescription = "div.bc-fff.s1 > h3:contains(Sinopse) ~ div[style=text-align: justify;]"
private val chapterListSelector = "div:has(> .list-judul:contains(Lista de Capítulos)) div#latest ul > li, div.tab:has(> label:contains(Lista de Capítulos)) div.tab-content ul > li"
override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()
val chapters = document.select(chapterListSelector)
return chapters.map {
SChapter.create().apply {
name = it.select("a").text()
setUrlWithoutDomain(it.select("a").attr("href"))
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.pt.guildatierdraw
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
class GuildaTierDraw : ZeistManga("Guilda Tier Draw", "https://www.guildatierdraw.com", "pt-BR") {
override val mangaDetailsSelectorDescription = "#Sinopse"
}

View File

@ -2,12 +2,20 @@ package eu.kanade.tachiyomi.extension.ar.hijala
import eu.kanade.tachiyomi.multisrc.zeistmanga.Genre
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import eu.kanade.tachiyomi.source.model.MangasPage
import okhttp3.Request
import okhttp3.Response
class Hijala : ZeistManga("Hijala", "https://hijala.blogspot.com", "ar") {
override val hasFilters = true
override val hasLanguageFilter = false
override val supportsLatest = false
override fun popularMangaRequest(page: Int): Request = latestUpdatesRequest(page)
override fun popularMangaParse(response: Response): MangasPage = latestUpdatesParse(response)
override fun getGenreList(): List<Genre> = listOf(
Genre("أكشن", "Action"),
Genre("أثارة", "Thriller"),

View File

@ -7,12 +7,14 @@ import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistMangaDto
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistMangaIntl
import eu.kanade.tachiyomi.network.GET
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.util.asJsoup
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import okhttp3.Request
import okhttp3.Response
import org.jsoup.nodes.Document
import uy.kohesive.injekt.injectLazy
@ -30,6 +32,27 @@ class KomikRealm : ZeistManga(
override val chapterCategory = ""
override fun popularMangaRequest(page: Int): Request {
val url = apiUrl("Project")
.addQueryParameter("orderby", "updated")
.addQueryParameter("max-results", "12")
.build()
return GET(url, headers)
}
override fun popularMangaParse(response: Response): MangasPage {
val jsonString = response.body.string()
val result = json.decodeFromString<ZeistMangaDto>(jsonString)
val mangas = result.feed?.entry.orEmpty()
.filter { it.category.orEmpty().any { category -> category.term == "Series" } }
.filter { !it.category.orEmpty().any { category -> category.term == "Anime" } }
.map { it.toSManga(baseUrl) }
return MangasPage(mangas, false)
}
override fun mangaDetailsParse(response: Response): SManga {
val document = response.asJsoup()
val profileManga = document.select(".bigcontent")
@ -54,12 +77,6 @@ class KomikRealm : ZeistManga(
}
}
private fun parseStatus(element: String): Int = when (element.lowercase()) {
"ongoing" -> SManga.ONGOING
"completed" -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.ar.mangasoul
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
class MangaSoul : ZeistManga("Manga Soul", "https://www.manga-soul.com", "ar") {
override val mangaDetailsSelectorInfo = ".y6x11p, .y6x11p > b > span"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@ -0,0 +1,26 @@
package eu.kanade.tachiyomi.extension.id.mikoroku
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Response
class MikoRoku : ZeistManga("MikoRoku", "https://www.mikoroku.web.id", "id") {
override val popularMangaSelector = "div.PopularPosts article"
override val popularMangaSelectorTitle = ".post-title a"
override val popularMangaSelectorUrl = ".post-title a"
override val pageListSelector = "article#reader div.separator a"
override fun mangaDetailsParse(response: Response): SManga = SManga.create().apply {
val document = response.asJsoup()
with(document.selectFirst("div.section#main div.widget header")!!) {
thumbnail_url = selectFirst("img")!!.attr("abs:src")
genre = select("aside dl:has(dt:contains(Genre)) dd a")
.joinToString { it.text() }
status = parseStatus(selectFirst("span[data-status]")!!.text())
}
description = document.select("div.section#main div.widget div.grid #synopsis").text()
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

View File

@ -0,0 +1,22 @@
package eu.kanade.tachiyomi.extension.tr.mikrokosmosfansub
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Response
import org.jsoup.Jsoup
class MikrokosmosFansub : ZeistManga("Mikrokosmos Fansub", "https://mikrokosmosfb.blogspot.com", "tr") {
override val pageListSelector = "div.check-box > script"
override fun pageListParse(response: Response): List<Page> {
val document = response.asJsoup()
val script = document.select(pageListSelector)
val content = script.html().substringAfter("const content = `").substringBefore("`;")
val images = Jsoup.parse(content).select("a")
return images.select("img[src]").mapIndexed { i, img ->
Page(i, "", img.attr("abs:src"))
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 KiB

View File

@ -1,9 +0,0 @@
package eu.kanade.tachiyomi.extension.es.muslosnosekai
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
class MuslosNoSekai : ZeistManga("Muslos No Sekai", "https://muslosnosekai.blogspot.com", "es") {
override val hasFilters = true
override val hasLanguageFilter = false
}

View File

@ -1,8 +1,10 @@
package eu.kanade.tachiyomi.extension.id.shiyurasub
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Request
import okhttp3.Response
class ShiyuraSub : ZeistManga("ShiyuraSub", "https://shiyurasub.blogspot.com", "id") {
@ -10,6 +12,11 @@ class ShiyuraSub : ZeistManga("ShiyuraSub", "https://shiyurasub.blogspot.com", "
override val hasFilters = true
override val hasLanguageFilter = false
override val supportsLatest = false
override fun popularMangaRequest(page: Int): Request = latestUpdatesRequest(page)
override fun popularMangaParse(response: Response): MangasPage = latestUpdatesParse(response)
override val pageListSelector = "main.content article.container"
override fun mangaDetailsParse(response: Response): SManga {

View File

@ -1,69 +1,13 @@
package eu.kanade.tachiyomi.extension.id.sobatmanku
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Request
import okhttp3.Response
class SobatManKu : ZeistManga("SobatManKu", "https://www.sobatmanku19.site", "id") {
override val supportsLatest = true
override val hasFilters = true
override fun latestUpdatesRequest(page: Int): Request {
return GET("$baseUrl/search/label/Update", headers)
}
override fun latestUpdatesParse(response: Response): MangasPage {
val doc = response.asJsoup()
val selector = doc.select(".grid.gtc-f141a > div")
val mangas = selector.map { element ->
SManga.create().apply {
element.select("a:nth-child(2)").let {
title = it.text()
setUrlWithoutDomain(it.attr("href"))
}
thumbnail_url = element.select("img").first()!!.attr("abs:src")
}
}
return MangasPage(mangas, false)
}
override fun mangaDetailsParse(response: Response): SManga {
val document = response.asJsoup()
val profileManga = document.selectFirst(".grid.gtc-235fr")!!
return SManga.create().apply {
thumbnail_url = profileManga.selectFirst("img")!!.attr("abs:src")
description = profileManga.select("#synopsis").text()
genre = profileManga.select("div.mt-15 > a[rel=tag]").joinToString { it.text() }
val infoElement = profileManga.select(".y6x11p")
infoElement.forEach {
val descText = it.select("span.dt").text()
when (it.ownText().trim()) {
"Status" -> {
status = parseStatus(descText)
}
"Author" -> {
author = descText
}
"Artist" -> {
artist = descText
}
}
}
}
}
override fun chapterListParse(response: Response): List<SChapter> {
return super.chapterListParse(response).onEach {
// fix some chapter name
@ -72,10 +16,4 @@ class SobatManKu : ZeistManga("SobatManKu", "https://www.sobatmanku19.site", "id
}
}
}
private fun parseStatus(element: String): Int = when (element.lowercase()) {
"ongoing" -> SManga.ONGOING
"completed" -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
}

View File

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.extension.id.tooncubus
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Response
@ -14,7 +13,7 @@ class Tooncubus : ZeistManga("Tooncubus", "https://www.tooncubus.top", "id") {
override fun chapterListParse(response: Response): List<SChapter> {
return response.asJsoup().selectFirst("ul.series-chapterlist")!!.select("div.flexch-infoz").map { element ->
SChapter.create().apply {
name = element.select("span")!!.text()
name = element.select("span").text()
url = element.select("a").attr("href") // The website uses another domain for reading
}
}
@ -23,14 +22,4 @@ class Tooncubus : ZeistManga("Tooncubus", "https://www.tooncubus.top", "id") {
override fun pageListRequest(chapter: SChapter) = GET(chapter.url, headers)
override fun getChapterUrl(chapter: SChapter) = chapter.url
override fun mangaDetailsParse(response: Response): SManga {
val document = response.asJsoup()
val profileManga = document.selectFirst(".grid.gtc-235fr")!!
return SManga.create().apply {
thumbnail_url = profileManga.selectFirst("img")!!.attr("src")
genre = profileManga.select("div.mt-15 > a[rel=tag]")
.joinToString { it.text() }
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

@ -0,0 +1,15 @@
package eu.kanade.tachiyomi.extension.pt.tyrantscans
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import eu.kanade.tachiyomi.source.model.MangasPage
import okhttp3.Request
import okhttp3.Response
class TyrantScans : ZeistManga("Tyrant Scans", "https://www.tyrantscans.com", "pt-BR") {
override val supportsLatest = false
override fun popularMangaRequest(page: Int): Request = latestUpdatesRequest(page)
override fun popularMangaParse(response: Response): MangasPage = latestUpdatesParse(response)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -11,6 +11,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request
@ -24,13 +25,34 @@ abstract class ZeistManga(
override val lang: String,
) : HttpSource() {
override val supportsLatest = false
override val supportsLatest = true
private val json: Json by injectLazy()
private val intl by lazy { ZeistMangaIntl(lang) }
override fun popularMangaRequest(page: Int): Request {
override fun headersBuilder(): Headers.Builder = super.headersBuilder()
.add("Referer", "$baseUrl/")
override fun popularMangaRequest(page: Int): Request = GET(baseUrl, headers)
protected open val popularMangaSelector = "div.PopularPosts div.grid > figure"
protected open val popularMangaSelectorTitle = "figcaption > a"
protected open val popularMangaSelectorUrl = "figcaption > a"
override fun popularMangaParse(response: Response): MangasPage {
val document = response.asJsoup()
val mangas = document.select(popularMangaSelector).map { element ->
SManga.create().apply {
thumbnail_url = element.selectFirst("img")!!.attr("abs:src")
title = element.selectFirst(popularMangaSelectorTitle)!!.text()
setUrlWithoutDomain(element.selectFirst(popularMangaSelectorUrl)!!.attr("href"))
}
}
return MangasPage(mangas, false)
}
override fun latestUpdatesRequest(page: Int): Request {
val startIndex = maxMangaResults * (page - 1) + 1
val url = apiUrl()
.addQueryParameter("orderby", "published")
@ -41,7 +63,7 @@ abstract class ZeistManga(
return GET(url, headers)
}
override fun popularMangaParse(response: Response): MangasPage {
override fun latestUpdatesParse(response: Response): MangasPage {
val jsonString = response.body.string()
val result = json.decodeFromString<ZeistMangaDto>(jsonString)
@ -59,9 +81,6 @@ abstract class ZeistManga(
return MangasPage(mangalist, false)
}
override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException("Not used.")
override fun latestUpdatesParse(response: Response): MangasPage = throw UnsupportedOperationException("Not used.")
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val startIndex = maxMangaResults * (page - 1) + 1
val url = apiUrl()
@ -70,7 +89,8 @@ abstract class ZeistManga(
if (query.isNotBlank()) {
url.addQueryParameter("q", query)
return GET(url.build(), headers)
val searchUrl = url.build().toString().replaceLast("q=", "q=label:$mangaCategory+")
return GET(searchUrl, headers)
}
filters.forEach { filter ->
@ -103,20 +123,65 @@ abstract class ZeistManga(
return GET(url.build(), headers)
}
override fun searchMangaParse(response: Response) = popularMangaParse(response)
override fun searchMangaParse(response: Response) = latestUpdatesParse(response)
protected open val statusSelectorList = listOf(
"Status",
"Estado",
)
protected open val authorSelectorList = listOf(
"Author",
"Autor",
"الكاتب",
"Yazar",
)
protected open val artisSelectorList = listOf(
"Artist",
"Artista",
"الرسام",
"Çizer",
)
protected open val mangaDetailsSelector = ".grid.gtc-235fr"
protected open val mangaDetailsSelectorDescription = "#synopsis"
protected open val mangaDetailsSelectorGenres = "div.mt-15 > a[rel=tag]"
protected open val mangaDetailsSelectorInfo = ".y6x11p"
protected open val mangaDetailsSelectorInfoTitle = "strong"
protected open val mangaDetailsSelectorInfoDescription = "span.dt"
override fun mangaDetailsParse(response: Response): SManga {
val document = response.asJsoup()
val profileManga = document.selectFirst(".grid.gtc-235fr")!!
val profileManga = document.selectFirst(mangaDetailsSelector)!!
return SManga.create().apply {
thumbnail_url = profileManga.selectFirst("img")!!.attr("abs:src")
description = profileManga.select("#synopsis").text()
genre = profileManga.select("div.mt-15 > a[rel=tag]")
description = profileManga.select(mangaDetailsSelectorDescription).text()
genre = profileManga.select(mangaDetailsSelectorGenres)
.joinToString { it.text() }
val infoElement = profileManga.select(mangaDetailsSelectorInfo)
infoElement.forEach { element ->
val infoText = element.ownText().trim().ifEmpty { element.selectFirst(mangaDetailsSelectorInfoTitle)?.text()?.trim() ?: "" }
val descText = element.select(mangaDetailsSelectorInfoDescription).text().trim()
when {
statusSelectorList.any { infoText.contains(it) } -> {
status = parseStatus(descText)
}
authorSelectorList.any { infoText.contains(it) } -> {
author = descText
}
artisSelectorList.any { infoText.contains(it) } -> {
artist = descText
}
}
}
}
}
protected open val chapterCategory = "Chapter"
protected open val chapterCategory: String = "Chapter"
override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()
@ -197,7 +262,7 @@ abstract class ZeistManga(
return url.toString()
}
open val pageListSelector = "div.check-box div.separator"
protected open val pageListSelector = "div.check-box div.separator"
override fun pageListParse(response: Response): List<Page> {
val document = response.asJsoup()
@ -209,7 +274,9 @@ abstract class ZeistManga(
override fun imageUrlParse(response: Response) = throw UnsupportedOperationException("Not used.")
open fun apiUrl(feed: String = "Series"): HttpUrl.Builder {
protected open val mangaCategory: String = "Series"
open fun apiUrl(feed: String = mangaCategory): HttpUrl.Builder {
return "$baseUrl/feeds/posts/default/-/".toHttpUrl().newBuilder()
.addPathSegment(feed)
.addQueryParameter("alt", "json")
@ -229,6 +296,9 @@ abstract class ZeistManga(
return FilterList(emptyList())
}
filterList.add(Filter.Header(intl.filterWarning))
filterList.add(Filter.Separator())
if (hasStatusFilter) filterList.add(StatusList(intl.statusFilterTitle, getStatusList()))
if (hasTypeFilter) filterList.add(TypeList(intl.typeFilterTitle, getTypeList()))
if (hasLanguageFilter) filterList.add(LanguageList(intl.languageFilterTitle, getLanguageList()))
@ -306,6 +376,48 @@ abstract class ZeistManga(
Language("English", "English"),
)
protected open val statusOnGoingList = listOf(
"ongoing",
"en curso",
"ativo",
"lançando",
"مستمر",
)
protected open val statusCompletedList = listOf(
"completed",
"completo",
)
protected open val statusHiatusList = listOf(
"hiatus",
)
protected open val statusCancelledList = listOf(
"cancelled",
"dropped",
"dropado",
"abandonado",
"cancelado",
)
protected open fun parseStatus(element: String): Int = when (element.lowercase().trim()) {
in statusOnGoingList -> SManga.ONGOING
in statusCompletedList -> SManga.COMPLETED
in statusHiatusList -> SManga.ON_HIATUS
in statusCancelledList -> SManga.CANCELLED
else -> SManga.UNKNOWN
}
private fun String.replaceLast(oldValue: String, newValue: String): String {
val lastIndexOf = lastIndexOf(oldValue)
return if (lastIndexOf == -1) {
this
} else {
substring(0, lastIndexOf) + newValue + substring(lastIndexOf + oldValue.length)
}
}
companion object {
private const val maxMangaResults = 20
private const val maxChapterResults = 999999

View File

@ -9,18 +9,26 @@ class ZeistMangaGenerator : ThemeSourceGenerator {
override val themeClass = "ZeistManga"
override val baseVersionCode: Int = 7
override val baseVersionCode: Int = 8
override val sources = listOf(
SingleLang("AnimeXNovel", "https://www.animexnovel.com", "pt-BR"),
SingleLang("Asupan Komik", "https://www.asupankomik.my.id", "id", overrideVersionCode = 1),
SingleLang("Eleven Scanlator", "https://elevenscanlator.blogspot.com", "pt-BR"),
SingleLang("Guilda Tier Draw", "https://www.guildatierdraw.com", "pt-BR", isNsfw = true),
SingleLang("Hijala", "https://hijala.blogspot.com", "ar"),
SingleLang("KLManhua", "https://klmanhua.blogspot.com", "id", isNsfw = true),
SingleLang("Manga Ai Land", "https://manga-ai-land.blogspot.com", "ar"),
SingleLang("Muslos No Sekai", "https://muslosnosekai.blogspot.com", "es"),
SingleLang("ShiyuraSub", "https://shiyurasub.blogspot.com", "id"),
SingleLang("Tooncubus", "https://www.tooncubus.top", "id", isNsfw = true),
SingleLang("SobatManKu", "https://www.sobatmanku19.site", "id"),
SingleLang("KomikRealm", "https://www.komikrealm.my.id", "id"),
SingleLang("Loner Translations", "https://loner-tl.blogspot.com", "ar"),
SingleLang("Manga Ai Land", "https://manga-ai-land.blogspot.com", "ar"),
SingleLang("Manga Soul", "https://www.manga-soul.com", "ar", isNsfw = true),
SingleLang("MikoRoku", "https://www.mikoroku.web.id", "id", isNsfw = true),
SingleLang("Mikrokosmos Fansub", "https://mikrokosmosfb.blogspot.com", "tr", isNsfw = true),
SingleLang("ShiyuraSub", "https://shiyurasub.blogspot.com", "id"),
SingleLang("SobatManKu", "https://www.sobatmanku19.site", "id"),
SingleLang("Tooncubus", "https://www.tooncubus.top", "id", isNsfw = true),
SingleLang("Tyrant Scans", "https://www.tyrantscans.com", "pt-BR"),
SingleLang("Yokai", "https://yokai-team.blogspot.com", "ar"),
)
companion object {