Minor daily update

pull/385/head
devi 2 years ago
parent 6f73ff23e8
commit 885d98cebd

@ -162,7 +162,7 @@ internal abstract class NineMangaParser(
return getOrCreateTagMap().values.toSet() return getOrCreateTagMap().values.toSet()
} }
protected suspend fun getOrCreateTagMap(): Map<String, MangaTag> = mutex.withLock { private suspend fun getOrCreateTagMap(): Map<String, MangaTag> = mutex.withLock {
tagCache?.let { return@withLock it } tagCache?.let { return@withLock it }
val tagMap = ArrayMap<String, MangaTag>() val tagMap = ArrayMap<String, MangaTag>()
val tagElements = webClient.httpGet("https://${domain}/search/?type=high").parseHtml().select("li.cate_list") val tagElements = webClient.httpGet("https://${domain}/search/?type=high").parseHtml().select("li.cate_list")

@ -135,7 +135,7 @@ internal abstract class FmreaderParser(
val fullUrl = manga.url.toAbsoluteUrl(domain) val fullUrl = manga.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml() val doc = webClient.httpGet(fullUrl).parseHtml()
val chaptersDeferred = async { getChapters(doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirst(selectDesc)?.html()
val stateDiv = doc.selectFirst(selectState) val stateDiv = doc.selectFirst(selectState)
val state = stateDiv?.let { val state = stateDiv?.let {
when (it.text()) { when (it.text()) {

@ -1,11 +1,10 @@
package org.koitharu.kotatsu.parsers.site.en package org.koitharu.kotatsu.parsers.site.likemanga
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.PagedMangaParser
import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.model.*
@ -14,11 +13,15 @@ import java.text.DateFormat
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@MangaSourceParser("LIKEMANGA", "LikeManga", "en") internal abstract class LikeMangaParser(
internal class LikeManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.LIKEMANGA, 36) { context: MangaLoaderContext,
source: MangaSource,
domain: String,
pageSize: Int = 36,
) : PagedMangaParser(context, source, pageSize) {
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST) override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST)
override val configKeyDomain = ConfigKey.Domain("likemanga.io") override val configKeyDomain = ConfigKey.Domain(domain)
override suspend fun getListPage( override suspend fun getListPage(
page: Int, page: Int,

@ -0,0 +1,10 @@
package org.koitharu.kotatsu.parsers.site.likemanga.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.likemanga.LikeMangaParser
@MangaSourceParser("LIKEMANGA", "LikeManga", "en")
internal class LikeManga(context: MangaLoaderContext) :
LikeMangaParser(context, MangaSource.LIKEMANGA, "likemanga.io")

@ -0,0 +1,10 @@
package org.koitharu.kotatsu.parsers.site.likemanga.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.likemanga.LikeMangaParser
@MangaSourceParser("ZINMANGA_IO", "ZinManga.io", "en")
internal class ZinManga(context: MangaLoaderContext) :
LikeMangaParser(context, MangaSource.ZINMANGA_IO, "zinmanga.io")

@ -6,7 +6,5 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("AQUAMANGA", "AquaManga", "en") @MangaSourceParser("AQUAMANGA", "AquaManga", "en")
internal class AquaManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.AQUAMANGA, "aquamanga.com") { internal class AquaManga(context: MangaLoaderContext) :
override val datePattern = "MMMM dd, yyyy" MadaraParser(context, MangaSource.AQUAMANGA, "aquamanga.org", 20)
override val withoutAjax = true
}

@ -1,13 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("ASTRALLIBRARY", "AstralLibrary", "en")
internal class Astrallibrary(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.ASTRALLIBRARY, "astrallibrary.net", 18) {
override val datePattern = "dd MMM"
override val postReq = true
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("BLOG_MANGA", "BlogManga", "en")
internal class BlogManga(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.BLOG_MANGA, "blogmanga.net") {
override val postReq = true
}

@ -1,143 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.jsoup.nodes.Document
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("COFFEE_MANGA_TOP", "CoffeeManga.top", "en")
internal class CoffeeMangaTop(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.COFFEE_MANGA_TOP, "coffeemanga.top") {
override val tagPrefix = "mangas/"
override val listUrl = "latest-manga/"
override val datePattern = "MMMM d, HH:mm"
override val sortOrders: Set<SortOrder> = EnumSet.of(
SortOrder.POPULARITY,
SortOrder.UPDATED,
)
override suspend fun getListPage(
page: Int,
query: String?,
tags: Set<MangaTag>?,
sortOrder: SortOrder,
): List<Manga> {
val tag = tags.oneOrThrowIfMany()
val url = buildString {
append("https://")
append(domain)
val pages = page + 1
when {
!query.isNullOrEmpty() -> {
append("/?search=")
append(query.urlEncoded())
append("&page=")
append(pages.toString())
append("&post_type=wp-manga")
}
!tags.isNullOrEmpty() -> {
append("/mangas/")
append(tag?.key.orEmpty())
append("?orderby=2&page=")
append(pages.toString())
}
else -> {
if (sortOrder == SortOrder.POPULARITY) {
append("/popular-manga")
}
if (sortOrder == SortOrder.UPDATED) {
append("/latest-manga")
}
append("?page=")
append(pages.toString())
}
}
}
val doc = webClient.httpGet(url).parseHtml()
return doc.select("div.row.c-tabs-item__content").ifEmpty {
doc.select("div.page-item-detail.manga")
}.map { div ->
val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href")
val summary = div.selectFirst(".tab-summary") ?: div.selectFirst(".item-summary")
Manga(
id = generateUid(href),
url = href,
publicUrl = href.toAbsoluteUrl(div.host ?: domain),
coverUrl = div.selectFirst("img")?.src().orEmpty(),
title = (summary?.selectFirst("h3") ?: summary?.selectFirst("h4"))?.text().orEmpty(),
altTitle = null,
rating = div.selectFirst("span.total_votes")?.ownText()?.toFloatOrNull()?.div(5f) ?: -1f,
tags = summary?.selectFirst(".mg_genres")?.select("a")?.mapNotNullToSet { a ->
MangaTag(
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
title = a.text().ifEmpty { return@mapNotNullToSet null }.toTitleCase(),
source = source,
)
}.orEmpty(),
author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()?.trim()
?.lowercase()) {
"Ongoing" -> MangaState.ONGOING
"Completed " -> MangaState.FINISHED
else -> null
},
source = source,
isNsfw = isNsfwSource,
)
}
}
override suspend fun loadChapters(mangaUrl: String, document: Document): List<MangaChapter> {
val mangaId = document.select("div[id^=manga-chapters-holder]").attr("data-id")
val doc = webClient.httpGet("https://$domain/ajax-list-chapter?mangaID=$mangaId").parseHtml()
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirst("a")
val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing")
val link = href + stylePage
MangaChapter(
id = generateUid(href),
url = link,
name = a.ownText(),
number = i + 1,
branch = null,
uploadDate = parseChapterDate(
dateFormat,
li.selectFirst(selectDate)?.text(),
),
scanlator = null,
source = source,
)
}
}
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val fullUrl = chapter.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml()
val urlarray = doc.select("p#arraydata").text().split(',').toTypedArray()
return urlarray.map { url ->
MangaPage(
id = generateUid(url),
url = url,
preview = null,
source = source,
)
}
}
}

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("COMICSCANS", "ComicScans", "en")
internal class ComicScans(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.COMICSCANS, "www.comicscans.org")

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("GLMANGA", "GlManga", "en")
internal class GlManga(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.GLMANGA, "glmanga.com")

@ -7,7 +7,7 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("GOURMETSCANS", "GourmetScans", "en") @MangaSourceParser("GOURMETSCANS", "GourmetScans", "en")
internal class GourmetScans(context: MangaLoaderContext) : internal class GourmetScans(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.GOURMETSCANS, "gourmetscans.net") { MadaraParser(context, MangaSource.GOURMETSCANS, "gourmetsupremacy.com") {
override val listUrl = "project/" override val listUrl = "project/"
override val tagPrefix = "genre/" override val tagPrefix = "genre/"
override val stylePage = "" override val stylePage = ""

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("LADYMANGA", "LadyManga", "en")
internal class LadyManga(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.LADYMANGA, "ladymanga.com")

@ -1,14 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGA_247", "247MANGA", "en")
internal class Manga247(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGA_247, "247manga.com") {
override val tagPrefix = "manhwa-genre/"
override val datePattern = "MMMM dd, yyyy"
override val withoutAjax = true
override val listUrl = "manhwa/"
}

@ -1,13 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGACLASH_TV", "MangaClash.tv", "en")
internal class MangaClashTv(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGACLASH_TV, "mangaclash.tv", pageSize = 10) {
override val datePattern = "MM/dd/yyyy"
override val postReq = true
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGADINOTOP", "MangaDino", "en")
internal class MangaDinoTop(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGADINOTOP, "mangadino.top", 10) {
override val postReq = true
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAFAST", "MangaFast", "en")
internal class MangaFast(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAFAST, "manga-fast.com") {
override val datePattern = "d MMMM، yyyy"
}

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAGREAT", "MangaGreat", "en")
internal class MangaGreat(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAGREAT, "mangagreat.org")

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAKIK", "MangaKik", "en")
internal class MangaKik(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAKIK, "mangakik.biz", 10)

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAKING", "MangaKing", "en")
internal class MangaKing(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAKING, "mangaking.net")

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAKITSU", "MangaKitsu", "en")
internal class MangaKitsu(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAKITSU, "mangakitsu.com", 20)

@ -2,12 +2,9 @@ package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.ContentType
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAOWLBLOG", "MangaOwl.blog", "en", ContentType.HENTAI) @MangaSourceParser("MANGAOWLBLOG", "MangaOwlnet.com", "en")
internal class MangaOwlBlog(context: MangaLoaderContext) : internal class MangaOwlBlog(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAOWLBLOG, "mangaowl.blog", 20) { MadaraParser(context, MangaSource.MANGAOWLBLOG, "mangaowlnet.com")
override val postReq = true
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGARAWINFO", "Manga-Raw.info", "en")
internal class MangaRawInfo(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGARAWINFO, "manga-raw.info", 20) {
override val postReq = true
}

@ -7,4 +7,4 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAROCKTEAM", "MangaRock.team", "en") @MangaSourceParser("MANGAROCKTEAM", "MangaRock.team", "en")
internal class MangaRockTeam(context: MangaLoaderContext) : internal class MangaRockTeam(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAROCKTEAM, "mangarock.team", 18) MadaraParser(context, MangaSource.MANGAROCKTEAM, "mangarockteam.com")

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAROCKY", "MangaRocky", "en")
internal class MangaRocky(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAROCKY, "mangarocky.com") {
override val postReq = true
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAUPDATESTOP", "MangaUpdates.top", "en")
internal class MangaUpdatesTop(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAUPDATESTOP, "mangaupdates.top", 10) {
override val postReq = true
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAVISA", "MangaVisa", "en")
internal class MangaVisa(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAVISA, "mangavisa.com") {
override val withoutAjax = true
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAX1", "MangaX1", "en")
internal class Mangax1(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAX1, "mangax1.com") {
override val postReq = true
}

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANHUAMANHWAONLINE", "ManhuaManhwa.online", "en")
internal class ManhuaManhwaOnline(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHUAMANHWAONLINE, "manhuamanhwa.online", 10)

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANHUASCANINFO", "ManhuaScan.info", "en")
internal class ManhuaScanInfo(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHUASCANINFO, "manhuascan.info", 10) {
override val postReq = true
}

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANHWAKOOL", "ManhwaKool", "en")
internal class ManhwaKool(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHWAKOOL, "manhwakool.com", pageSize = 10)

@ -1,11 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANHWAWORLD", "ManhwaWorld", "en")
internal class ManhwaWorld(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHWAWORLD, "manhwaworld.com")

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANHWAS", "FreeManhwa", "en")
internal class Manhwas(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHWAS, "manhwas.com")

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("PAINFULNIGHTZ", "Painful Nightz", "en")
internal class Painfulnightz(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.PAINFULNIGHTZ, "painfulnightz.com") {
override val datePattern = "d MMMM"
}

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("SAWAMICS", "Sawamics", "en")
internal class Sawamics(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.SAWAMICS, "sawamics.com", 10)

@ -5,8 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("STKISSMANGABLOG", "1stKissManga.blog", "en") @MangaSourceParser("STKISSMANGABLOG", "1StKissManga.net", "en")
internal class StkissMangaBlog(context: MangaLoaderContext) : internal class StkissMangaBlog(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.STKISSMANGABLOG, "1stkissmanga.blog", 10) { MadaraParser(context, MangaSource.STKISSMANGABLOG, "1st-kissmanga.net", 20)
override val postReq = true
}

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("WAKAMICS", "Wakamics", "en")
internal class Wakamics(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.WAKAMICS, "wakamics.net", 10)

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("WEBCOMIC", "WebComic", "en")
internal class WebComic(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.WEBCOMIC, "webcomic.me") {
override val postReq = true
}

@ -1,13 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("WEBTOONCITY", "WebtoonCity", "en")
internal class WebtoonCity(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.WEBTOONCITY, "webtooncity.com", 20) {
override val listUrl = "webtoon/"
override val tagPrefix = "webtoon-genre/"
}

@ -1,14 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.ContentType
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("WEBTOONS", "Webtoons", "en", ContentType.HENTAI)
internal class Webtoons(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.WEBTOONS, "webtoons.top", 20) {
override val listUrl = "read/"
override val postReq = true
}

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("ZINMANGA_TOP", "ZinManga.top", "en")
internal class ZinMangaTop(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.ZINMANGA_TOP, "zinmanga.top", 20)

@ -5,7 +5,7 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("ZINMANGA", "ZinManga", "en") @MangaSourceParser("ZINMANGA", "ZinManga.com", "en")
internal class Zinmanga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.ZINMANGA, "zinmanga.com") { internal class Zinmanga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.ZINMANGA, "zinmanga.com") {
override val datePattern = "MM/dd/yyyy" override val datePattern = "MM/dd/yyyy"
} }

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("ZINMANHWA", "ZinManhwa", "en")
internal class Zinmanhwa(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.ZINMANHWA, "zinmanhwa.com") {
override val datePattern = "dd/MM/yyyy"
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("ZUTTOMANGA", "ZuttoManga", "en")
internal class ZuttoManga(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.ZUTTOMANGA, "zuttomanga.com") {
override val postReq = true
}

@ -1,11 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.es
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.ContentType
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("EROMIAU", "Eromiau", "es", ContentType.HENTAI)
internal class Eromiau(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.EROMIAU, "www.eromiau.com", 10)

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.es
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("GANZOSCAN", "GanzoScan", "es")
internal class GanzoScan(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.GANZOSCAN, "ganzoscan.com") {
override val datePattern: String = "dd 'de' MMMMM 'de' yyyy"
}

@ -8,5 +8,5 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("HERENSCAN", "HerenScan", "es") @MangaSourceParser("HERENSCAN", "HerenScan", "es")
internal class HerenScan(context: MangaLoaderContext) : internal class HerenScan(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.HERENSCAN, "herenscan.com") { MadaraParser(context, MangaSource.HERENSCAN, "herenscan.com") {
override val datePattern = "d 'de' MMMMM 'de' yyyy" override val datePattern = "dd/MM/yyyy"
} }

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.es
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGAREADERPRO", "MangaReaderPro", "es")
internal class MangaReaderpro(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAREADERPRO, "mangareaderpro.com", 10) {
override val datePattern = "MM/dd/yyyy"
}

@ -13,7 +13,7 @@ internal class ManhwaEs(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHWA_ES, "manhwa-es.com", 10) { MadaraParser(context, MangaSource.MANHWA_ES, "manhwa-es.com", 10) {
override val withoutAjax = true override val withoutAjax = true
override val datePattern = "d 'de' MMMM" override val datePattern = "MM/dd"
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)

@ -8,5 +8,5 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("SAMURAISCAN", "SamuraiScan", "es") @MangaSourceParser("SAMURAISCAN", "SamuraiScan", "es")
internal class SamuraiScan(context: MangaLoaderContext) : internal class SamuraiScan(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.SAMURAISCAN, "samuraiscan.com", 10) { MadaraParser(context, MangaSource.SAMURAISCAN, "samuraiscan.com", 10) {
override val datePattern = "dd/MM/yyyy" override val listUrl = "leer/"
} }

@ -7,4 +7,6 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("FRSCAN", "Fr-Scan", "fr") @MangaSourceParser("FRSCAN", "Fr-Scan", "fr")
internal class FrScan(context: MangaLoaderContext) : internal class FrScan(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.FRSCAN, "fr-scan.com") MadaraParser(context, MangaSource.FRSCAN, "fr-scan.com") {
override val withoutAjax = true
}

@ -1,14 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.id
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("GOURMETSCANS_ID", "IdGourmetScans", "id")
internal class GourmetScansId(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.GOURMETSCANS_ID, "id.gourmetscans.net") {
override val listUrl = "project/"
override val tagPrefix = "genre/"
override val stylePage = ""
}

@ -1,191 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.ja
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import org.jsoup.nodes.Document
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.exception.ParseException
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("HACHIMANGA", "HachiManga", "ja")
internal class HachiManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.HACHIMANGA, "hachiraw.com") {
override val datePattern = "MMMM dd, yyyy"
override val selectChapter = "li.a-h"
override val selectDate = "span.chapter-tim"
override val selectDesc = "div.dsct"
override val tagPrefix = "genre/"
override val sortOrders: Set<SortOrder> = EnumSet.of(
SortOrder.UPDATED,
SortOrder.POPULARITY,
SortOrder.NEWEST,
SortOrder.RATING,
)
override suspend fun getListPage(
page: Int,
query: String?,
tags: Set<MangaTag>?,
sortOrder: SortOrder,
): List<Manga> {
val tag = tags.oneOrThrowIfMany()
val url = buildString {
append("https://")
append(domain)
val pages = page + 1
when {
!query.isNullOrEmpty() -> {
append("/search/")
append(pages.toString())
append("/?keyword=")
append(query.urlEncoded())
}
!tags.isNullOrEmpty() -> {
append("/$tagPrefix")
append(tag?.key.orEmpty())
append("/")
append(pages.toString())
append("/")
}
else -> {
if (sortOrder == SortOrder.POPULARITY) {
append("/top-bookmarked")
}
if (sortOrder == SortOrder.NEWEST) {
append("/new-manga")
}
if (sortOrder == SortOrder.RATING) {
append("/top-rating")
}
if (sortOrder == SortOrder.UPDATED) {
append("/latest-updates")
}
append("/")
append(pages.toString())
append("/")
}
}
}
val doc = webClient.httpGet(url).parseHtml()
return doc.select("div.manga-item").map { div ->
val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href")
val summary = div.selectFirst(".tab-summary") ?: div.selectFirst("div.data.wleft")
Manga(
id = generateUid(href),
url = href,
publicUrl = href.toAbsoluteUrl(div.host ?: domain),
coverUrl = div.selectFirst("img")?.src().orEmpty(),
title = (summary?.selectFirst("h3") ?: summary?.selectFirst("h4"))?.text().orEmpty(),
altTitle = null,
rating = div.selectFirst("span.total_votes")?.ownText()?.toFloatOrNull()?.div(5f) ?: -1f,
tags = summary?.selectFirst(".mg_genres")?.select("a")?.mapNotNullToSet { a ->
MangaTag(
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
title = a.text().ifEmpty { return@mapNotNullToSet null }.toTitleCase(),
source = source,
)
}.orEmpty(),
author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()?.trim()
?.lowercase()) {
"Ongoing" -> MangaState.ONGOING
"Completed " -> MangaState.FINISHED
else -> null
},
source = source,
isNsfw = isNsfwSource,
)
}
}
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
val fullUrl = manga.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml()
val body = doc.body()
val chaptersDeferred = async { getChapters(manga, doc) }
val desc = body.select(selectDesc).html()
val stateDiv = (body.selectFirst("div.post-content_item:contains(状態)"))?.selectLast("div.summary-content")
val state = stateDiv?.let {
when (it.text()) {
in ongoing -> MangaState.ONGOING
in finished -> MangaState.FINISHED
else -> null
}
}
val alt = doc.body().select(".post-content_item:contains(代替名) .summary-content").firstOrNull()?.tableValue()
?.text()?.trim()
manga.copy(
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
MangaTag(
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
title = a.text().toTitleCase(),
source = source,
)
},
description = desc,
altTitle = alt,
state = state,
chapters = chaptersDeferred.await(),
)
}
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> {
val root2 = doc.body().selectFirstOrThrow("div.manga-content")
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return root2.select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirst("a")
val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing")
val link = href + stylePage
val dateText = li.selectFirst("a.c-new-tag")?.attr("title") ?: li.selectFirst(selectDate)?.text()
val name = a.selectFirst("p")?.text() ?: a.ownText()
MangaChapter(
id = generateUid(href),
name = name,
number = i + 1,
url = link,
uploadDate = parseChapterDate(
dateFormat,
dateText,
),
source = source,
scanlator = null,
branch = null,
)
}
}
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val fullUrl = chapter.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml()
val root = doc.body().selectFirst("div.chapter-pages")
?: throw ParseException("Root not found", fullUrl)
return root.select("div.chapter-page").map { div ->
val img = div.selectFirst("img") ?: div.parseFailed("Page image not found")
val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found")
MangaPage(
id = generateUid(url),
url = url,
preview = null,
source = source,
)
}
}
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.pt
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("AKIMANGA", "AkiManga", "pt")
internal class AkiManga(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.AKIMANGA, "akimanga.com") {
override val datePattern = "dd/MM/yyyy"
}

@ -7,6 +7,4 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("DEMONSECT", "DemonSect", "pt") @MangaSourceParser("DEMONSECT", "DemonSect", "pt")
internal class DemonSect(context: MangaLoaderContext) : internal class DemonSect(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.DEMONSECT, "demonsect.com.br", 10) { MadaraParser(context, MangaSource.DEMONSECT, "demonsect.com.br", 10)
override val datePattern = "MMM dd, yyyy"
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.pt
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("TABERU", "Taberu", "pt")
internal class Taberu(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.TABERU, "taberu.org", 10) {
override val datePattern: String = "dd/MM/yyyy"
}

@ -1,6 +1,5 @@
package org.koitharu.kotatsu.parsers.site.madara.th package org.koitharu.kotatsu.parsers.site.madara.th
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.ContentType import org.koitharu.kotatsu.parsers.model.ContentType
@ -9,6 +8,6 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("CAT_300", "Cat300", "th", ContentType.HENTAI) @MangaSourceParser("CAT_300", "Cat300", "th", ContentType.HENTAI)
internal class Cat300(context: MangaLoaderContext) : MadaraParser(context, MangaSource.CAT_300, "cat300.com") { internal class Cat300(context: MangaLoaderContext) : MadaraParser(context, MangaSource.CAT_300, "cat300.com") {
override val datePattern = "MMMM dd, yyyy" override val datePattern = "MMMM dd, yyyy"
override val withoutAjax = true
} }

@ -11,5 +11,5 @@ internal class Cizgiromanarsivi(context: MangaLoaderContext) :
override val stylePage = "" override val stylePage = ""
override val tagPrefix = "kategori/" override val tagPrefix = "kategori/"
override val listUrl = "seri/" override val listUrl = "seri/"
override val datePattern = "dd.MM.yyyy" override val datePattern = "dd/MM/yyyy"
} }

@ -0,0 +1,32 @@
package org.koitharu.kotatsu.parsers.site.madara.vi
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.ContentType
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.*
@MangaSourceParser("QUAANHDAOCUTEO", "Quaanhdaocuteo", "vi", ContentType.HENTAI)
internal class Quaanhdaocuteo(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.QUAANHDAOCUTEO, "quaanhdaocuteo.com") {
override val datePattern = "dd/MM/yyyy"
override val selectPage = "p img"
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val fullUrl = chapter.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml()
val root = doc.body().selectFirstOrThrow(selectBodyPage)
return root.select(selectPage).map { img ->
val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found")
MangaPage(
id = generateUid(url),
url = url,
preview = null,
source = source,
)
}
}
}

@ -1,12 +0,0 @@
package org.koitharu.kotatsu.parsers.site.mangareader.en
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("LYNXSCANS", "LynxScans", "en")
internal class LynxScans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.LYNXSCANS, "lynxscans.com", pageSize = 25, searchPageSize = 10) {
override val listUrl = "/comics"
}

@ -0,0 +1,13 @@
package org.koitharu.kotatsu.parsers.site.mangareader.es
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
import java.util.Locale
@MangaSourceParser("MANGAREADERPRO", "MangaReaderPro", "es")
internal class MangaReaderpro(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MANGAREADERPRO, "mangareaderpro.com", pageSize = 20, searchPageSize = 10) {
override val sourceLocale: Locale = Locale.ENGLISH
}

@ -1,12 +1,10 @@
package org.koitharu.kotatsu.parsers.site.madara.tr package org.koitharu.kotatsu.parsers.site.mangareader.tr
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("REAPERSCANSTR", "ReaperScansTr", "tr") @MangaSourceParser("REAPERSCANSTR", "ReaperScansTr", "tr")
internal class ReaperScansTr(context: MangaLoaderContext) : internal class ReaperScansTr(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.REAPERSCANSTR, "reaperscanstr.com", 5) { MangaReaderParser(context, MangaSource.REAPERSCANSTR, "reaperscans.com.tr", pageSize = 20, searchPageSize = 10)
override val listUrl = "seri/"
}
Loading…
Cancel
Save