Update ZeistManga and add some sources (#15426)

* Update ZeistManga and add some sources

* Remove status from Tooncubus

* Linting

* Linting

* More Linting

* Miskey in import

* I hope it's the last
This commit is contained in:
seew3l 2023-02-23 17:20:23 -05:00 committed by GitHub
parent bda03aada9
commit 6366c65903
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 302 additions and 40 deletions

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.id.asupankomik
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
class AsupanKomik : ZeistManga("Asupan Komik", "https://www.asupankomik.my.id", "id") {
override val hasFilters = true
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 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: 90 KiB

View File

@ -1,14 +1,17 @@
package eu.kanade.tachiyomi.extension.es.datgarscanlation
import eu.kanade.tachiyomi.multisrc.zeistmanga.Language
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import org.jsoup.nodes.Document
class DatGarScanlation : ZeistManga("DatGarScanlation", "https://datgarscanlation.blogspot.com", "es") {
override val hasFilters = true
private val altChapterFeedRegex = """label\s*=\s*'([^']+)'""".toRegex()
private val altScriptSelector = "#latest > script"
override fun getChaptersUrl(doc: Document): String {
override fun getApiUrl(doc: Document): String {
var chapterRegex = chapterFeedRegex
var script = doc.selectFirst(scriptSelector)
@ -29,4 +32,8 @@ class DatGarScanlation : ZeistManga("DatGarScanlation", "https://datgarscanlatio
return url.toString()
}
override fun getLanguageList(): List<Language> = listOf(
Language(intl.all, ""),
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

View File

@ -0,0 +1,53 @@
package eu.kanade.tachiyomi.extension.ar.hijala
import eu.kanade.tachiyomi.multisrc.zeistmanga.Genre
import eu.kanade.tachiyomi.multisrc.zeistmanga.Language
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
class Hijala : ZeistManga("Hijala", "https://hijala.blogspot.com", "ar") {
override val hasFilters = true
override fun getLanguageList(): List<Language> = listOf(
Language(intl.all, ""),
)
override fun getGenreList(): List<Genre> = listOf(
Genre("أكشن", "Action"),
Genre("أثارة", "Thriller"),
Genre("أتشي", "Ecchi"),
Genre("حياة مدرسية", "School Life"),
Genre("تاريخي", "Historical"),
Genre("ألعاب", "Game"),
Genre("خيال علمي", "Sci-Fi"),
Genre("خيال", "Fantasy"),
Genre("خارق للطبيعة", "Supernatural"),
Genre("رومانسي", "Romance"),
Genre("رعب", "Horror"),
Genre("دراما", "Drama"),
Genre("سينين", "Seinen"),
Genre("سحري", "Magic"),
Genre("رياضي", "Sports"),
Genre("شونين", "Shounen"),
Genre("شوجو", "Shoujo"),
Genre("شريحة من الحياة", "Slice of Life"),
Genre("علاجي", "Medical"),
Genre("عسكري", "Military"),
Genre("طبخ", "Cooking"),
Genre("فنون قتال", "Martial Arts"),
Genre("غموض", "Mystery"),
Genre("عوالم متعددة", "Isekai"),
Genre("مانها", "مانها"),
Genre("مأساوي", "Tragedy"),
Genre("كوميديا", "Comedy"),
Genre("مغامرات", "Adventure"),
Genre("مصاص دماء", "مصاص دماء"),
Genre("مانهوا", "مانهوا"),
Genre("موسيقي", "موسيقي"),
Genre("موسيقى", "Music"),
Genre("مغامرات", "مغامرات"),
Genre("نفسي", "نفسي"),
Genre("نفسي", "Psychological"),
Genre("ميكا", "ميكا"),
)
}

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: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

View File

@ -0,0 +1,16 @@
package eu.kanade.tachiyomi.extension.id.klmanhua
import eu.kanade.tachiyomi.multisrc.zeistmanga.Language
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
class KLManhua : ZeistManga("KLManhua", "https://klmanhua.blogspot.com", "id") {
override val hasFilters = true
override fun getLanguageList(): List<Language> = listOf(
Language(intl.all, ""),
)
override val imgSelector = "a[href]"
override val imgSelectorAttr = "href"
}

View File

@ -1,22 +1,38 @@
package eu.kanade.tachiyomi.extension.ar.mangaailand
import eu.kanade.tachiyomi.multisrc.zeistmanga.Genre
import eu.kanade.tachiyomi.multisrc.zeistmanga.Language
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
import org.jsoup.nodes.Document
class MangaAiLand : ZeistManga("Manga Ai Land", "https://manga-ai-land.blogspot.com", "ar") {
override val chapterFeedRegex = """([^']+)\?""".toRegex()
override val scriptSelector = "#myUL > script"
override val hasFilters = true
override val imgSelector = "a[href]"
override val imgSelectorAttr = "href"
override fun getChaptersUrl(doc: Document): String {
val script = doc.selectFirst(scriptSelector)!!.attr("src")
val feed = chapterFeedRegex
.find(script)
?.groupValues?.get(1)
?: throw Exception("Failed to find chapter feed")
override fun getLanguageList(): List<Language> = listOf(
Language(intl.all, ""),
)
return "$baseUrl" + feed + "?alt=json&start-index=2&max-results=999999"
}
override fun getGenreList(): List<Genre> = listOf(
Genre("تراجيدي", "تراجيدي"),
Genre("تاريخي", "تاريخي"),
Genre("أكشن", "أكشن"),
Genre("خيالي", "خيالي"),
Genre("جيشي", "جيشي"),
Genre("تشويق", "تشويق"),
Genre("سينين", "سينين"),
Genre("سحري", "سحري"),
Genre("دراما", "دراما"),
Genre("عصابات", "عصابات"),
Genre("عسكري", "عسكري"),
Genre("شونين", "شونين"),
Genre("مغامرة", "مغامرة"),
Genre("فنون قتالية", "فنون قتالية"),
Genre("غموض", "غموض"),
Genre("وحوش", "وحوش"),
Genre("نجاة", "نجاة"),
Genre("نفسي", "نفسي"),
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

View File

@ -0,0 +1,13 @@
package eu.kanade.tachiyomi.extension.es.muslosnosekai
import eu.kanade.tachiyomi.multisrc.zeistmanga.Language
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
class MuslosNoSekai : ZeistManga("Muslos No Sekai", "https://muslosnosekai.blogspot.com", "es") {
override val hasFilters = true
override fun getLanguageList(): List<Language> = listOf(
Language(intl.all, ""),
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 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: 97 KiB

View File

@ -0,0 +1,11 @@
package eu.kanade.tachiyomi.extension.id.noromax
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
class Noromax : ZeistManga("Noromax", "https://www.noromax.xyz", "id") {
override val hasFilters = true
override val imgSelector = "a[href]"
override val imgSelectorAttr = "href"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

View File

@ -0,0 +1,16 @@
package eu.kanade.tachiyomi.extension.id.shiyurasub
import eu.kanade.tachiyomi.multisrc.zeistmanga.Language
import eu.kanade.tachiyomi.multisrc.zeistmanga.ZeistManga
class ShiyuraSub : ZeistManga("ShiyuraSub", "https://shiyurasub.blogspot.com", "id") {
override val hasFilters = true
override val imgSelector = "a[href]"
override val imgSelectorAttr = "href"
override fun getLanguageList(): List<Language> = listOf(
Language(intl.all, ""),
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

View File

@ -0,0 +1,34 @@
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
import org.jsoup.nodes.Document
class Tooncubus : ZeistManga("Tooncubus", "https://www.tooncubus.site", "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()
url = element.select("a").attr("href") // The website uses another domain for reading
}
}
}
override fun pageListRequest(chapter: SChapter) = GET(chapter.url, headers)
override fun getChapterUrl(chapter: SChapter) = chapter.url
override fun mangaDetailsParse(document: Document): SManga {
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() }
}
}
}

View File

@ -29,13 +29,29 @@ abstract class ZeistManga(
open val hasFilters = false
protected val json: Json by injectLazy()
protected val intl by lazy { ZeistMangaIntl(lang) }
open val chapterFeedRegex = """clwd\.run\('([^']+)'""".toRegex()
open val scriptSelector = "#clwd > script"
open val oldChapterFeedRegex = """([^']+)\?""".toRegex()
open val oldScriptSelector = "#myUL > script"
open val imgSelector = "img[src]"
open val imgSelectorAttr = "src"
open fun getChaptersUrl(doc: Document): String {
val script = doc.selectFirst(scriptSelector)!!
open fun getApiUrl(doc: Document): String {
val script = doc.selectFirst(scriptSelector)
if (script == null) {
val altScript = doc.selectFirst(oldScriptSelector)!!.attr("src")
val feed = oldChapterFeedRegex
.find(altScript)
?.groupValues?.get(1)
?: throw Exception("Failed to find chapter feed")
return "$baseUrl$feed?alt=json&start-index=2&max-results=999999"
}
val feed = chapterFeedRegex
.find(script.html())
?.groupValues?.get(1)
@ -50,7 +66,7 @@ abstract class ZeistManga(
override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup()
val url = getChaptersUrl(document)
val url = getApiUrl(document)
val req = GET(url, headers)
val res = client.newCall(req).execute()
@ -121,10 +137,8 @@ abstract class ZeistManga(
override fun mangaDetailsParse(document: Document): SManga {
val profileManga = document.selectFirst(".grid.gtc-235fr")!!
return SManga.create().apply {
title = profileManga.selectFirst("h1.mt-0.mb-6.fs-20")!!.text()
thumbnail_url = profileManga.selectFirst("img")!!.attr("src")
description = profileManga.select("#synopsis").text()
status = SManga.UNKNOWN
genre = profileManga.select("div.mt-15 > a[rel=tag]")
.joinToString { it.text() }
}
@ -150,6 +164,7 @@ abstract class ZeistManga(
mangalist.removeLast()
return MangasPage(mangalist, true)
}
return MangasPage(mangalist, false)
}
@ -230,20 +245,26 @@ abstract class ZeistManga(
// Theme Default Status
protected open fun getStatusList(): List<Status> = listOf(
Status(intl.statusAll, ""),
Status(intl.all, ""),
Status(intl.statusOngoing, "Ongoing"),
Status(intl.statusCompleted, "Completed"),
Status(intl.statusDropped, "Dropped"),
Status(intl.statusUpcoming, "Upcoming"),
Status(intl.statusHiatus, "Hiatus"),
Status(intl.statusCancelled, "Cancelled"),
)
// Theme Default Types
protected open fun getTypeList(): List<Type> = listOf(
Type(intl.typeAll, ""),
Type(intl.all, ""),
Type(intl.typeManga, "Manga"),
Type(intl.typeManhua, "Manhua"),
Type(intl.typeManhwa, "Manhwa"),
Type(intl.typeNovel, "Novel"),
Type(intl.typeWebNovelJP, "Web Novel (JP)"),
Type(intl.typeWebNovelKR, "Web Novel (KR)"),
Type(intl.typeWebNovelCN, "Web Novel (CN)"),
Type(intl.typeDoujinshi, "Doujinshi"),
)
// Theme Default Genres
@ -290,7 +311,7 @@ abstract class ZeistManga(
// Theme Default Languages
protected open fun getLanguageList(): List<Language> = listOf(
Language(intl.languageAll, ""),
Language(intl.all, ""),
Language("Indonesian", "Indonesian"),
Language("English", "English"),
)

View File

@ -34,11 +34,16 @@ data class ZeistMangaEntryDto(
val category: List<ZeistMangaEntryCategory>? = emptyList(),
@SerialName("link") val url: List<ZeistMangaEntryLink>? = emptyList(),
val content: ZeistMangaEntryContentDto? = null,
@SerialName("media\$thumbnail") val thumbnail: ZeistMangaEntryThumbnail? = null,
) {
fun toSManga(baseurl: String): SManga = SManga.create().apply {
title = this@ZeistMangaEntryDto.title!!.t
url = getChapterLink(this@ZeistMangaEntryDto.url!!).substringAfter(baseurl)
thumbnail_url = getThumbnail(this@ZeistMangaEntryDto.content!!)
thumbnail_url = if (this@ZeistMangaEntryDto.thumbnail == null) {
getThumbnailFromContent(this@ZeistMangaEntryDto.content!!)
} else {
getThumbnail(this@ZeistMangaEntryDto.thumbnail)
}
}
fun toSChapter(baseurl: String): SChapter = SChapter.create().apply {
@ -52,7 +57,12 @@ data class ZeistMangaEntryDto(
return list.first { it.rel == "alternate" }.href
}
private fun getThumbnail(html: ZeistMangaEntryContentDto): String {
private fun getThumbnail(thumbnail: ZeistMangaEntryThumbnail): String {
return thumbnail.url.replace("""\/s.+?-c\/""".toRegex(), "/w600/")
.replace("""=s(?!.*=s).+?-c$""".toRegex(), "=w600")
}
private fun getThumbnailFromContent(html: ZeistMangaEntryContentDto): String {
val document = Jsoup.parse(html.t)
return document.selectFirst("img")!!.attr("src")
}
@ -83,3 +93,8 @@ data class ZeistMangaEntryLink(
data class ZeistMangaEntryCategory(
val term: String,
)
@Serializable
data class ZeistMangaEntryThumbnail(
val url: String,
)

View File

@ -9,11 +9,18 @@ class ZeistMangaGenerator : ThemeSourceGenerator {
override val themeClass = "ZeistManga"
override val baseVersionCode: Int = 4
override val baseVersionCode: Int = 5
override val sources = listOf(
SingleLang("Asupan Komik", "https://www.asupankomik.my.id", "id"),
SingleLang("DatGarScanlation", "https://datgarscanlation.blogspot.com", "es"),
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("Noromax", "https://www.noromax.xyz", "id"),
SingleLang("ShiyuraSub", "https://shiyurasub.blogspot.com", "id"),
SingleLang("Tooncubus", "https://www.tooncubus.site", "id", isNsfw = true),
)
companion object {

View File

@ -8,46 +8,62 @@ class ZeistMangaIntl(lang: String) {
val statusFilterTitle: String = when (availableLang) {
SPANISH -> "Estado"
ARAB -> "حالة"
INDONESIAN -> "Status"
else -> "Status"
}
val statusAll: String = when (availableLang) {
SPANISH -> "Todos"
else -> "All"
}
val statusOngoing: String = when (availableLang) {
SPANISH -> "En curso"
ARAB -> "جاري التنفيذ"
INDONESIAN -> "Sedang berlangsung"
else -> "Ongoing"
}
val statusCompleted: String = when (availableLang) {
SPANISH -> "Completado"
ARAB -> "مكتمل"
INDONESIAN -> "Lengkap"
else -> "Completed"
}
val statusDropped: String = when (availableLang) {
SPANISH -> "Abandonada"
SPANISH -> "Abandonado"
ARAB -> "إسقاط"
INDONESIAN -> "Menjatuhkan"
else -> "Dropped"
}
val statusUpcoming: String = when (availableLang) {
SPANISH -> "Próximos"
ARAB -> "القادمة"
INDONESIAN -> "Mendatang"
else -> "Upcoming"
}
val statusHiatus: String = when (availableLang) {
SPANISH -> "En hiatus"
ARAB -> "فجوة"
INDONESIAN -> "Hiatus"
else -> "Hiatus"
}
val statusCancelled: String = when (availableLang) {
SPANISH -> "Cancelado"
ARAB -> "ألغيت"
INDONESIAN -> "Dibatalkan"
else -> "Cancelled"
}
// Type Filter
val typeFilterTitle: String = when (availableLang) {
SPANISH -> "Tipo"
ARAB -> "يكتب"
INDONESIAN -> "Jenis"
else -> "Type"
}
val typeAll: String = when (availableLang) {
SPANISH -> "Todos"
else -> "All"
}
val typeManga: String = when (availableLang) {
SPANISH -> "Manga"
else -> "Manga"
@ -68,35 +84,65 @@ class ZeistMangaIntl(lang: String) {
else -> "Novel"
}
val typeWebNovelJP: String = when (availableLang) {
SPANISH -> "Web Novel (JP)"
else -> "Web Novel (JP)"
}
val typeWebNovelKR: String = when (availableLang) {
SPANISH -> "Web Novel (KR)"
else -> "Web Novel (KR)"
}
val typeWebNovelCN: String = when (availableLang) {
SPANISH -> "Web Novel (CN)"
else -> "Web Novel (CN)"
}
val typeDoujinshi: String = when (availableLang) {
SPANISH -> "Doujinshi"
else -> "Doujinshi"
}
// Language Filter
val languageFilterTitle: String = when (availableLang) {
SPANISH -> "Idioma"
ARAB -> "لغة"
INDONESIAN -> "Bahasa"
else -> "Language"
}
val languageAll: String = when (availableLang) {
SPANISH -> "Todos"
else -> "All"
}
// Genre Filter
val genreFilterTitle: String = when (availableLang) {
SPANISH -> "Género"
ARAB -> "جينيرو"
INDONESIAN -> "Genre"
else -> "Genre"
}
// Extra
val filterWarning: String = when (availableLang) {
SPANISH -> "Los filtros serán ignorados si la búsqueda no está vacía."
ARAB -> "سيتم تجاهل عوامل التصفية إذا لم يكن البحث فارغًا"
INDONESIAN -> "Filter akan diabaikan jika pencarian tidak kosong."
else -> "Filters will be ignored if the search is not empty."
}
val all: String = when (availableLang) {
SPANISH -> "Todos"
ARAB -> "الجميع"
INDONESIAN -> "Semua"
else -> "All"
}
companion object {
const val ENGLISH = "en"
const val SPANISH = "es"
const val ARAB = "ar"
const val INDONESIAN = "id"
val AVAILABLE_LANGS = arrayOf(ENGLISH, SPANISH)
val AVAILABLE_LANGS = arrayOf(ENGLISH, SPANISH, ARAB, INDONESIAN)
}
}