Add small sources, fix , rename sources , remove code not used, remove dead sources, typo.

devi 3 years ago
parent 81004b53a9
commit e43c9f6489

@ -85,7 +85,7 @@ internal class ComickFunParser(context: MangaLoaderContext) : MangaParser(contex
coverUrl = jo.getString("cover_url"), coverUrl = jo.getString("cover_url"),
largeCoverUrl = null, largeCoverUrl = null,
description = jo.getStringOrNull("desc"), description = jo.getStringOrNull("desc"),
tags = jo.selectGenres("genres", tagsMap), tags = jo.selectGenres(tagsMap),
state = runCatching { state = runCatching {
if (jo.getBoolean("translation_completed")) { if (jo.getBoolean("translation_completed")) {
MangaState.FINISHED MangaState.FINISHED
@ -203,8 +203,8 @@ internal class ComickFunParser(context: MangaLoaderContext) : MangaParser(contex
return chaptersBuilder.toList() return chaptersBuilder.toList()
} }
private fun JSONObject.selectGenres(name: String, tags: SparseArrayCompat<MangaTag>): Set<MangaTag> { private fun JSONObject.selectGenres(tags: SparseArrayCompat<MangaTag>): Set<MangaTag> {
val array = optJSONArray(name) ?: return emptySet() val array = optJSONArray("genres") ?: return emptySet()
val res = ArraySet<MangaTag>(array.length()) val res = ArraySet<MangaTag>(array.length())
for (i in 0 until array.length()) { for (i in 0 until array.length()) {
val id = array.getInt(i) val id = array.getInt(i)

@ -114,7 +114,7 @@ internal abstract class AnimeBootstrapParser(
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(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirstOrThrow(selectDesc).html()
@ -141,7 +141,7 @@ internal abstract class AnimeBootstrapParser(
protected open val selectChapter = "div.anime__details__episodes a" protected open val selectChapter = "div.anime__details__episodes a"
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, a -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, a ->
val href = a.attr("href") val href = a.attr("href")
MangaChapter( MangaChapter(

@ -102,7 +102,7 @@ internal class PapScan(context: MangaLoaderContext) :
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(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirstOrThrow(selectDesc).html()
@ -126,7 +126,7 @@ internal class PapScan(context: MangaLoaderContext) :
) )
} }
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val href = li.selectFirstOrThrow("a").attr("href") val href = li.selectFirstOrThrow("a").attr("href")

@ -14,7 +14,7 @@ import org.koitharu.kotatsu.parsers.util.json.mapJSON
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
@MangaSourceParser("MANGAOWL", "Mangaowl", "en") @MangaSourceParser("MANGAOWL", "Manga Owl .To", "en")
internal class Mangaowl(context: MangaLoaderContext) : internal class Mangaowl(context: MangaLoaderContext) :
PagedMangaParser(context, MangaSource.MANGAOWL, pageSize = 24) { PagedMangaParser(context, MangaSource.MANGAOWL, pageSize = 24) {

@ -99,12 +99,12 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser(
state = parseStatus(contents.select("span.book-status").text().orEmpty()), state = parseStatus(contents.select("span.book-status").text().orEmpty()),
author = contents.selectFirst("h5.card-title")?.attr("title")?.substringAfter(", "), author = contents.selectFirst("h5.card-title")?.attr("title")?.substringAfter(", "),
chapters = if (doc.select("div.chapters").isEmpty()) { chapters = if (doc.select("div.chapters").isEmpty()) {
doc.select(oneShotChapterListSelector()).mapChapters(reversed = true) { _, item -> doc.select(oneShotChapterListSelector).mapChapters(reversed = true) { _, item ->
oneShotChapterFromElement(item) oneShotChapterFromElement(item)
} }
} else { } else {
val chapters = ChaptersListBuilder(10) val chapters = ChaptersListBuilder(10)
doc.select(regularChapterListSelector()).reversed().forEachIndexed { i, item -> doc.select(regularChapterListSelector).reversed().forEachIndexed { i, item ->
val chaptername = item.select("div.col-10.text-truncate").text().replace("&nbsp;", " ").trim() val chaptername = item.select("div.col-10.text-truncate").text().replace("&nbsp;", " ").trim()
val scanelement = item.select("ul.chapter-list > li") val scanelement = item.select("ul.chapter-list > li")
scanelement.forEach { chapters.add(regularChapterFromElement(it, chaptername, i)) } scanelement.forEach { chapters.add(regularChapterFromElement(it, chaptername, i)) }
@ -114,7 +114,7 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser(
) )
} }
private fun oneShotChapterListSelector() = "div.chapter-list-element > ul.list-group li.list-group-item" private val oneShotChapterListSelector = "div.chapter-list-element > ul.list-group li.list-group-item"
private fun oneShotChapterFromElement(element: Element): MangaChapter { private fun oneShotChapterFromElement(element: Element): MangaChapter {
val href = element.selectFirstOrThrow("div.row > .text-right > a").attrAsRelativeUrl("href") val href = element.selectFirstOrThrow("div.row > .text-right > a").attrAsRelativeUrl("href")
@ -130,7 +130,7 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser(
) )
} }
private fun regularChapterListSelector() = "div.chapters > ul.list-group li.p-0.list-group-item" private val regularChapterListSelector = "div.chapters > ul.list-group li.p-0.list-group-item"
private fun regularChapterFromElement(element: Element, chName: String, number: Int): MangaChapter { private fun regularChapterFromElement(element: Element, chName: String, number: Int): MangaChapter {
val href = element.selectFirstOrThrow("div.row > .text-right > a").attrAsRelativeUrl("href") val href = element.selectFirstOrThrow("div.row > .text-right > a").attrAsRelativeUrl("href")

@ -27,7 +27,7 @@ internal abstract class FmreaderParser(
SortOrder.ALPHABETICAL, SortOrder.ALPHABETICAL,
) )
protected open val listeurl = "/manga-list.html" protected open val listUrl = "/manga-list.html"
protected open val datePattern = "MMMM d, yyyy" protected open val datePattern = "MMMM d, yyyy"
protected open val tagPrefix = "manga-list-genre-" protected open val tagPrefix = "manga-list-genre-"
@ -66,7 +66,7 @@ internal abstract class FmreaderParser(
val url = buildString { val url = buildString {
append("https://") append("https://")
append(domain) append(domain)
append(listeurl) append(listUrl)
append("?page=") append("?page=")
append(page.toString()) append(page.toString())
when { when {
@ -114,7 +114,7 @@ internal abstract class FmreaderParser(
protected open val selectBodyTag = "ul.filter-type li a" protected open val selectBodyTag = "ul.filter-type li a"
override suspend fun getTags(): Set<MangaTag> { override suspend fun getTags(): Set<MangaTag> {
val doc = webClient.httpGet("https://$domain/$listeurl").parseHtml() val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
return doc.select(selectBodyTag).mapNotNullToSet { a -> return doc.select(selectBodyTag).mapNotNullToSet { a ->
val href = a.attr("href").substringAfter(tagPrefix).substringBeforeLast(".html") val href = a.attr("href").substringAfter(tagPrefix).substringBeforeLast(".html")
MangaTag( MangaTag(
@ -134,7 +134,7 @@ internal abstract class FmreaderParser(
override suspend fun getDetails(manga: Manga): Manga = coroutineScope { override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
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(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirstOrThrow(selectDesc).html()
val stateDiv = doc.selectFirst(selectState) val stateDiv = doc.selectFirst(selectState)
val state = stateDiv?.let { val state = stateDiv?.let {
@ -167,7 +167,7 @@ internal abstract class FmreaderParser(
protected open val selectDate = "div.chapter-time" protected open val selectDate = "div.chapter-time"
protected open val selectChapter = "ul.list-chapters a" protected open val selectChapter = "ul.list-chapters a"
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, a -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, a ->
val href = a.attrAsRelativeUrl("href") val href = a.attrAsRelativeUrl("href")
@ -193,10 +193,8 @@ internal abstract class FmreaderParser(
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> { override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val fullUrl = chapter.url.toAbsoluteUrl(domain) val fullUrl = chapter.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml() val doc = webClient.httpGet(fullUrl).parseHtml()
return doc.select(selectPage).map { img -> return doc.select(selectPage).map { img ->
val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found")
MangaPage( MangaPage(
id = generateUid(url), id = generateUid(url),
url = url, url = url,

@ -14,7 +14,7 @@ import java.text.SimpleDateFormat
internal class Manhwa18Com(context: MangaLoaderContext) : internal class Manhwa18Com(context: MangaLoaderContext) :
FmreaderParser(context, MangaSource.MANHWA18COM, "manhwa18.com") { FmreaderParser(context, MangaSource.MANHWA18COM, "manhwa18.com") {
override val listeurl = "/tim-kiem" override val listUrl = "/tim-kiem"
override val selectState = "div.info-item:contains(Status) span.info-value " override val selectState = "div.info-item:contains(Status) span.info-value "
override val selectAlt = "div.info-item:contains(Other name) span.info-value " override val selectAlt = "div.info-item:contains(Other name) span.info-value "
override val selectTag = "div.info-item:contains(Genre) span.info-value a" override val selectTag = "div.info-item:contains(Genre) span.info-value a"
@ -45,7 +45,7 @@ internal class Manhwa18Com(context: MangaLoaderContext) :
else -> append("last_update") else -> append("last_update")
} }
} else { } else {
append(listeurl) append(listUrl)
append("?page=") append("?page=")
append(page.toString()) append(page.toString())
when { when {
@ -87,7 +87,7 @@ internal class Manhwa18Com(context: MangaLoaderContext) :
} }
override suspend fun getTags(): Set<MangaTag> { override suspend fun getTags(): Set<MangaTag> {
val doc = webClient.httpGet("https://$domain/$listeurl").parseHtml() val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
return doc.select(selectBodyTag).mapNotNullToSet { a -> return doc.select(selectBodyTag).mapNotNullToSet { a ->
val href = a.attr("href").substringAfterLast("/") val href = a.attr("href").substringAfterLast("/")
MangaTag( MangaTag(
@ -101,7 +101,7 @@ internal class Manhwa18Com(context: MangaLoaderContext) :
override suspend fun getDetails(manga: Manga): Manga = coroutineScope { override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
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(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirstOrThrow(selectDesc).html()
val stateDiv = doc.selectFirst(selectState) val stateDiv = doc.selectFirst(selectState)
val state = stateDiv?.let { val state = stateDiv?.let {
@ -129,7 +129,7 @@ internal class Manhwa18Com(context: MangaLoaderContext) :
) )
} }
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, a -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, a ->
val href = a.attrAsRelativeUrl("href") val href = a.attrAsRelativeUrl("href")

@ -25,7 +25,7 @@ internal class OlimpoScans(context: MangaLoaderContext) :
val url = buildString { val url = buildString {
append("https://") append("https://")
append(domain) append(domain)
append(listeurl) append(listUrl)
append("?page=") append("?page=")
append(page.toString()) append(page.toString())
when { when {

@ -37,7 +37,7 @@ internal class Klz9(context: MangaLoaderContext) :
val url = buildString { val url = buildString {
append("https://") append("https://")
append(domain) append(domain)
append("/$listeurl") append("/$listUrl")
append("?page=") append("?page=")
append(page.toString()) append(page.toString())
when { when {
@ -81,12 +81,12 @@ internal class Klz9(context: MangaLoaderContext) :
} }
} }
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(doc: Document): List<MangaChapter> {
val slug = doc.selectFirstOrThrow("div.h0rating").attr("slug") val slug = doc.selectFirstOrThrow("div.h0rating").attr("slug")
val docload = val docLoad =
webClient.httpGet("https://$domain/app/manga/controllers/cont.listChapter.php?slug=$slug").parseHtml() webClient.httpGet("https://$domain/app/manga/controllers/cont.listChapter.php?slug=$slug").parseHtml()
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return docload.body().select(selectChapter).mapChapters(reversed = true) { i, a -> return docLoad.body().select(selectChapter).mapChapters(reversed = true) { i, a ->
val href = "/" + a.selectFirstOrThrow("a.chapter").attrAsRelativeUrl("href") val href = "/" + a.selectFirstOrThrow("a.chapter").attrAsRelativeUrl("href")
val dateText = a.selectFirst(selectDate)?.text() val dateText = a.selectFirst(selectDate)?.text()
MangaChapter( MangaChapter(
@ -109,8 +109,8 @@ internal class Klz9(context: MangaLoaderContext) :
val fullUrl = chapter.url.toAbsoluteUrl(domain) val fullUrl = chapter.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml() val doc = webClient.httpGet(fullUrl).parseHtml()
val cid = doc.selectFirstOrThrow("#chapter").attr("value") val cid = doc.selectFirstOrThrow("#chapter").attr("value")
val docload = webClient.httpGet("https://$domain/app/manga/controllers/cont.listImg.php?cid=$cid").parseHtml() val docLoad = webClient.httpGet("https://$domain/app/manga/controllers/cont.listImg.php?cid=$cid").parseHtml()
return docload.select(selectPage).map { img -> return docLoad.select(selectPage).map { img ->
val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found")
MangaPage( MangaPage(

@ -3,7 +3,6 @@ package org.koitharu.kotatsu.parsers.site.fmreader.ja
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
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.Manga
import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaPage import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
@ -15,12 +14,12 @@ import java.text.SimpleDateFormat
internal class WeLoveManga(context: MangaLoaderContext) : internal class WeLoveManga(context: MangaLoaderContext) :
FmreaderParser(context, MangaSource.WELOVEMANGA, "welovemanga.one") { FmreaderParser(context, MangaSource.WELOVEMANGA, "welovemanga.one") {
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(doc: Document): List<MangaChapter> {
val mid = doc.selectFirstOrThrow("div.cmt input").attr("value") val mid = doc.selectFirstOrThrow("div.cmt input").attr("value")
val docload = val docLoad =
webClient.httpGet("https://$domain/app/manga/controllers/cont.Listchapter.php?mid=$mid").parseHtml() webClient.httpGet("https://$domain/app/manga/controllers/cont.Listchapter.php?mid=$mid").parseHtml()
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return docload.body().select(selectChapter).mapChapters(reversed = true) { i, a -> return docLoad.body().select(selectChapter).mapChapters(reversed = true) { i, a ->
val href = a.selectFirstOrThrow("a").attrAsRelativeUrl("href") val href = a.selectFirstOrThrow("a").attrAsRelativeUrl("href")
val dateText = a.selectFirst(selectDate)?.text() val dateText = a.selectFirst(selectDate)?.text()
MangaChapter( MangaChapter(
@ -43,8 +42,8 @@ internal class WeLoveManga(context: MangaLoaderContext) :
val fullUrl = chapter.url.toAbsoluteUrl(domain) val fullUrl = chapter.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml() val doc = webClient.httpGet(fullUrl).parseHtml()
val cid = doc.selectFirstOrThrow("#chapter").attr("value") val cid = doc.selectFirstOrThrow("#chapter").attr("value")
val docload = webClient.httpGet("https://$domain/app/manga/controllers/cont.listImg.php?cid=$cid").parseHtml() val docLoad = webClient.httpGet("https://$domain/app/manga/controllers/cont.listImg.php?cid=$cid").parseHtml()
return docload.select("img").map { img -> return docLoad.select("img").map { img ->
val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found")
MangaPage( MangaPage(

@ -38,7 +38,6 @@ internal abstract class FoolSlideParser(
tags: Set<MangaTag>?, tags: Set<MangaTag>?,
sortOrder: SortOrder, sortOrder: SortOrder,
): List<Manga> { ): List<Manga> {
val doc = if (!query.isNullOrEmpty()) { val doc = if (!query.isNullOrEmpty()) {
val url = buildString { val url = buildString {
append("https://$domain/$searchUrl") append("https://$domain/$searchUrl")
@ -62,7 +61,6 @@ internal abstract class FoolSlideParser(
} }
webClient.httpGet(url).parseHtml() webClient.httpGet(url).parseHtml()
} }
return doc.select("div.list div.group").map { div -> return doc.select("div.list div.group").map { div ->
val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href")
Manga( Manga(
@ -90,26 +88,22 @@ internal abstract class FoolSlideParser(
override suspend fun getDetails(manga: Manga): Manga = coroutineScope { override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
val fullUrl = manga.url.toAbsoluteUrl(domain) val fullUrl = manga.url.toAbsoluteUrl(domain)
val testAdultPage = webClient.httpGet(fullUrl).parseHtml() val testAdultPage = webClient.httpGet(fullUrl).parseHtml()
val doc = if (testAdultPage.selectFirst("div.info form") != null) { val doc = if (testAdultPage.selectFirst("div.info form") != null) {
webClient.httpPost(fullUrl, "adult=true").parseHtml() webClient.httpPost(fullUrl, "adult=true").parseHtml()
} else { } else {
testAdultPage testAdultPage
} }
val chapters = getChapters(manga, doc) val chapters = getChapters(doc)
val desc = if (doc.selectFirstOrThrow(selectInfo).html().contains("</b>")) { val desc = if (doc.selectFirstOrThrow(selectInfo).html().contains("</b>")) {
doc.selectFirstOrThrow(selectInfo).text().substringAfterLast(": ") doc.selectFirstOrThrow(selectInfo).text().substringAfterLast(": ")
} else { } else {
doc.selectFirstOrThrow(selectInfo).text() doc.selectFirstOrThrow(selectInfo).text()
} }
val author = if (doc.selectFirstOrThrow(selectInfo).html().contains("</b>")) { val author = if (doc.selectFirstOrThrow(selectInfo).html().contains("</b>")) {
doc.selectFirstOrThrow(selectInfo).text().substringAfter(": ").substringBefore("Art") doc.selectFirstOrThrow(selectInfo).text().substringAfter(": ").substringBefore("Art")
} else { } else {
null null
} }
manga.copy( manga.copy(
coverUrl = doc.selectFirst(".thumbnail img")?.src() ?: manga.coverUrl, coverUrl = doc.selectFirst(".thumbnail img")?.src() ?: manga.coverUrl,
description = desc, description = desc,
@ -124,7 +118,7 @@ internal abstract class FoolSlideParser(
protected open val selectDate = ".meta_r" protected open val selectDate = ".meta_r"
protected open val selectChapter = "div.list div.element" protected open val selectChapter = "div.list div.element"
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, div -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, div ->
val a = div.selectFirstOrThrow(".title a") val a = div.selectFirstOrThrow(".title a")

@ -77,7 +77,7 @@ internal class AssortedScans(context: MangaLoaderContext) :
} else { } else {
testAdultPage testAdultPage
} }
val chapters = getChapters(manga, doc) val chapters = getChapters(doc)
val desc = doc.getElementById("series-desc")?.selectFirst("div")?.html() val desc = doc.getElementById("series-desc")?.selectFirst("div")?.html()
val alt = doc.getElementById("series-aliases")?.selectFirst("div.alias")?.text() val alt = doc.getElementById("series-aliases")?.selectFirst("div.alias")?.text()
val author = doc.getElementById("series-authors")?.selectFirst("div.author")?.text() val author = doc.getElementById("series-authors")?.selectFirst("div.author")?.text()
@ -97,7 +97,7 @@ internal class AssortedScans(context: MangaLoaderContext) :
) )
} }
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(doc: Document): List<MangaChapter> {
return doc.body().select("div.chapter").mapChapters(reversed = true) { i, div -> return doc.body().select("div.chapter").mapChapters(reversed = true) { i, div ->
val a = div.selectFirstOrThrow("a") val a = div.selectFirstOrThrow("a")
val href = a.attrAsRelativeUrl("href") val href = a.attrAsRelativeUrl("href")

@ -21,7 +21,7 @@ internal class Seinagi(context: MangaLoaderContext) :
} else { } else {
testAdultPage testAdultPage
} }
val chapters = getChapters(manga, doc) val chapters = getChapters(doc)
val desc = if (doc.selectFirstOrThrow(selectInfo).html().contains("Description")) { val desc = if (doc.selectFirstOrThrow(selectInfo).html().contains("Description")) {
doc.selectFirstOrThrow(selectInfo).text().substringAfter("Description: ").substringBefore("Readings") doc.selectFirstOrThrow(selectInfo).text().substringAfter("Description: ").substringBefore("Readings")
} else { } else {

@ -19,7 +19,7 @@ internal class Pzykosis666hFansub(context: MangaLoaderContext) :
} else { } else {
testAdultPage testAdultPage
} }
val chapters = getChapters(manga, doc) val chapters = getChapters(doc)
val desc = if (doc.selectFirstOrThrow(selectInfo).html().contains("Descripción")) { val desc = if (doc.selectFirstOrThrow(selectInfo).html().contains("Descripción")) {
doc.selectFirstOrThrow(selectInfo).text().substringAfter("Descripción: ").substringBefore("Lecturas") doc.selectFirstOrThrow(selectInfo).text().substringAfter("Descripción: ").substringBefore("Lecturas")
} else { } else {

@ -25,7 +25,7 @@ internal class SeinagiAdulto(context: MangaLoaderContext) :
} else { } else {
testAdultPage testAdultPage
} }
val chapters = getChapters(manga, doc) val chapters = getChapters(doc)
val desc = if (doc.selectFirstOrThrow(selectInfo).html().contains("Descripción")) { val desc = if (doc.selectFirstOrThrow(selectInfo).html().contains("Descripción")) {
doc.selectFirstOrThrow(selectInfo).text().substringAfter("Descripción: ").substringBefore("Lecturas") doc.selectFirstOrThrow(selectInfo).text().substringAfter("Descripción: ").substringBefore("Lecturas")
} else { } else {

@ -5,6 +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.heancmsalt.HeanCmsAlt import org.koitharu.kotatsu.parsers.site.heancmsalt.HeanCmsAlt
@MangaSourceParser("LEGIONSCANS", "CerberuSeries", "es") @MangaSourceParser("LEGIONSCANS", "Cerberus Series", "es")
internal class CerberuSeries(context: MangaLoaderContext) : internal class CerberuSeries(context: MangaLoaderContext) :
HeanCmsAlt(context, MangaSource.LEGIONSCANS, "cerberuseries.xyz") HeanCmsAlt(context, MangaSource.LEGIONSCANS, "cerberuseries.xyz")

@ -13,13 +13,11 @@ import org.koitharu.kotatsu.parsers.util.generateUid
import org.koitharu.kotatsu.parsers.util.mapChapters import org.koitharu.kotatsu.parsers.util.mapChapters
import org.koitharu.kotatsu.parsers.util.parseFailed import org.koitharu.kotatsu.parsers.util.parseFailed
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Locale
@MangaSourceParser("MANHWARAW", "Manhwa Raw", "", ContentType.HENTAI) @MangaSourceParser("MANHWARAW", "Manhwa Raw", "", ContentType.HENTAI)
internal class ManhwaRaw(context: MangaLoaderContext) : internal class ManhwaRaw(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHWARAW, "manhwa-raw.com", 10) { MadaraParser(context, MangaSource.MANHWARAW, "manhwa-raw.com", 10) {
override val datePattern = "MMMM d" override val datePattern = "MM/dd"
override val sourceLocale: Locale = Locale.ENGLISH
override val withoutAjax = true override val withoutAjax = true
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> {
@ -29,8 +27,7 @@ internal class ManhwaRaw(context: MangaLoaderContext) :
val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing")
val link = href + stylePage val link = href + stylePage
val dateText = li.selectFirst("a.c-new-tag")?.attr("title") ?: li.selectFirst(selectDate)?.text() val dateText = li.selectFirst("a.c-new-tag")?.attr("title") ?: li.selectFirst(selectDate)?.text()
val name = a.selectFirst("h4")?.text() ?: a.ownText()
val name = a.selectFirst("p")?.text() ?: a.ownText()
MangaChapter( MangaChapter(
id = generateUid(href), id = generateUid(href),
name = name, name = name,

@ -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("AZORANOV", "Azoranov", "ar") @MangaSourceParser("AZORANOV", "Azora Nov", "ar")
internal class Azoranov(context: MangaLoaderContext) : internal class Azoranov(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.AZORANOV, "azoranov.com", pageSize = 10) { MadaraParser(context, MangaSource.AZORANOV, "azoranov.com", pageSize = 10) {
override val tagPrefix = "series-genre/" override val tagPrefix = "series-genre/"

@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGA_LEK", "Manga-Lek", "ar") @MangaSourceParser("MANGA_LEK", "Manga-Lek", "ar")
internal class Manga_Lek(context: MangaLoaderContext) : internal class MangaLekCom(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGA_LEK, "manga-lek.com") { MadaraParser(context, MangaSource.MANGA_LEK, "manga-lek.com") {
override val listUrl = "mangalek/" override val listUrl = "mangalek/"
override val postReq = true override val postReq = true

@ -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("MANGARBIC", "Mangarbic", "ar") @MangaSourceParser("MANGARBIC", "Manga Arabic", "ar")
internal class Mangarbic(context: MangaLoaderContext) : internal class Mangarbic(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGARBIC, "mangarabic.com") { MadaraParser(context, MangaSource.MANGARBIC, "mangarabic.com") {
override val postReq = true override val postReq = true

@ -5,6 +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("ITSYOURIGHTMANHUA", "Itsyourightmanhua", "en") @MangaSourceParser("ITSYOURIGHTMANHUA", "Its You Right Manhua", "en")
internal class Itsyourightmanhua(context: MangaLoaderContext) : internal class Itsyourightmanhua(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.ITSYOURIGHTMANHUA, "itsyourightmanhua.com", 10) MadaraParser(context, MangaSource.ITSYOURIGHTMANHUA, "itsyourightmanhua.com", 10)

@ -5,6 +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("JAIMINISBOX", "Jaiminisbox", "en") @MangaSourceParser("JAIMINISBOX", "Jaiminis Box", "en")
internal class Jaiminisbox(context: MangaLoaderContext) : internal class Jaiminisbox(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.JAIMINISBOX, "jaiminisbox.net") MadaraParser(context, MangaSource.JAIMINISBOX, "jaiminisbox.net")

@ -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("MANHUAES", "Manhuaes", "en") @MangaSourceParser("MANHUAES", "ManhuaEs", "en")
internal class Manhuaes(context: MangaLoaderContext) : internal class Manhuaes(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHUAES, "manhuaes.com") { MadaraParser(context, MangaSource.MANHUAES, "manhuaes.com") {
override val postReq = true override val postReq = true

@ -5,6 +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("MANHUAGA", "Manhuaga", "en") @MangaSourceParser("MANHUAGA", "ManhuaGa", "en")
internal class Manhuaga(context: MangaLoaderContext) : internal class Manhuaga(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHUAGA, "manhuaga.com") MadaraParser(context, MangaSource.MANHUAGA, "manhuaga.com")

@ -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("MANHUASY", "Manhuasy", "en") @MangaSourceParser("MANHUASY", "ManhuaSy", "en")
internal class Manhuasy(context: MangaLoaderContext) : internal class Manhuasy(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHUASY, "www.manhuasy.com") { MadaraParser(context, MangaSource.MANHUASY, "www.manhuasy.com") {
override val listUrl = "manhua/" override val listUrl = "manhua/"

@ -5,6 +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("MANHUAUS", "Manhuaus", "en") @MangaSourceParser("MANHUAUS", "ManhuaUs", "en")
internal class Manhuaus(context: MangaLoaderContext) : internal class Manhuaus(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHUAUS, "manhuaus.com") MadaraParser(context, MangaSource.MANHUAUS, "manhuaus.com")

@ -9,7 +9,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.*
@MangaSourceParser("MANHWADEN", "Manhwaden", "en", ContentType.HENTAI) @MangaSourceParser("MANHWADEN", "Manhwa Den", "en", ContentType.HENTAI)
internal class Manhwaden(context: MangaLoaderContext) : internal class Manhwaden(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHWADEN, "www.manhwaden.com", 10) { MadaraParser(context, MangaSource.MANHWADEN, "www.manhwaden.com", 10) {

@ -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("MANHWASCO", "Manhwasco", "en") @MangaSourceParser("MANHWASCO", "Manhwa Sco", "en")
internal class Manhwasco(context: MangaLoaderContext) : internal class Manhwasco(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHWASCO, "manhwasco.net") { MadaraParser(context, MangaSource.MANHWASCO, "manhwasco.net") {
override val selectGenre = "div.mg_genres a" override val selectGenre = "div.mg_genres a"

@ -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("PAINFULNIGHTZ", "Painfulnightz", "en") @MangaSourceParser("PAINFULNIGHTZ", "Painful Nightz", "en")
internal class Painfulnightz(context: MangaLoaderContext) : internal class Painfulnightz(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.PAINFULNIGHTZ, "painfulnightz.com") { MadaraParser(context, MangaSource.PAINFULNIGHTZ, "painfulnightz.com") {
override val datePattern = "d MMMM" override val datePattern = "d MMMM"

@ -5,6 +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("STKISSMANGA_COM", "1st Kiss-Manga .Com", "en") @MangaSourceParser("STKISSMANGA_COM", "1St Kiss-Manga .Com", "en")
internal class StkissMangaCom(context: MangaLoaderContext) : internal class StkissMangaCom(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.STKISSMANGA_COM, "1stkiss-manga.com", 10) MadaraParser(context, MangaSource.STKISSMANGA_COM, "1stkiss-manga.com", 10)

@ -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("STKISSMANGA_TV", "1stKissManga .Tv", "en") @MangaSourceParser("STKISSMANGA_TV", "1St Kiss Manga .Tv", "en")
internal class StkissMangaTv(context: MangaLoaderContext) : internal class StkissMangaTv(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.STKISSMANGA_TV, "1stkissmanga.tv", 20) { MadaraParser(context, MangaSource.STKISSMANGA_TV, "1stkissmanga.tv", 20) {
override val postReq = true override val postReq = true

@ -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("LECTORUNITOON", "Lectorunitoon", "es") @MangaSourceParser("LECTORUNITOON", "Lectoruni Toon", "es")
internal class Lectorunitoon(context: MangaLoaderContext) : internal class Lectorunitoon(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.LECTORUNITOON, "lectorunitoon.com", 10) { MadaraParser(context, MangaSource.LECTORUNITOON, "lectorunitoon.com", 10) {
override val tagPrefix = "generos/" override val tagPrefix = "generos/"

@ -6,6 +6,6 @@ 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("MANGAXICO", "Mangaxico", "es", ContentType.HENTAI) @MangaSourceParser("MANGAXICO", "Manga Xico", "es", ContentType.HENTAI)
internal class Mangaxico(context: MangaLoaderContext) : internal class Mangaxico(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAXICO, "mangaxico.com", 24) MadaraParser(context, MangaSource.MANGAXICO, "mangaxico.com", 24)

@ -7,6 +7,6 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("NOBLESSETRANSLATIONS", "Noblesse Translations", "es") @MangaSourceParser("NOBLESSETRANSLATIONS", "Noblesse Translations", "es")
internal class NoblesseTranslations(context: MangaLoaderContext) : internal class NoblesseTranslations(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.NOBLESSETRANSLATIONS, "www.noblessetranslations.com") { MadaraParser(context, MangaSource.NOBLESSETRANSLATIONS, "noblessetranslations.com") {
override val datePattern = "d MMMM, yyyy" override val datePattern = "d MMMM, yyyy"
} }

@ -5,6 +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("RIGHTDARKSCAN", "Rightdark Scan", "es") @MangaSourceParser("RIGHTDARKSCAN", "Right Dark Scan", "es")
internal class RightdarkScan(context: MangaLoaderContext) : internal class RightdarkScan(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.RIGHTDARKSCAN, "rightdark-scan.com", 10) MadaraParser(context, MangaSource.RIGHTDARKSCAN, "rightdark-scan.com", 10)

@ -8,7 +8,7 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.domain import org.koitharu.kotatsu.parsers.util.domain
import org.koitharu.kotatsu.parsers.util.insertCookies import org.koitharu.kotatsu.parsers.util.insertCookies
@MangaSourceParser("HHENTAIFR", "Hhentai", "fr", ContentType.HENTAI) @MangaSourceParser("HHENTAIFR", "H Hentai", "fr", ContentType.HENTAI)
internal class HhentaiFr(context: MangaLoaderContext) : internal class HhentaiFr(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.HHENTAIFR, "hhentai.fr") { MadaraParser(context, MangaSource.HHENTAIFR, "hhentai.fr") {

@ -5,6 +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("READERGEN", "Readergen", "fr") @MangaSourceParser("READERGEN", "Reader Gen", "fr")
internal class Readergen(context: MangaLoaderContext) : internal class Readergen(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.READERGEN, "fr.readergen.fr", 18) MadaraParser(context, MangaSource.READERGEN, "fr.readergen.fr", 18)

@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import java.util.Locale import java.util.Locale
@MangaSourceParser("KOMIKSA", "Komiksay", "id") @MangaSourceParser("KOMIKSA", "Komik Say", "id")
internal class Komiksay(context: MangaLoaderContext) : internal class Komiksay(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.KOMIKSA, "komiksay.site") { MadaraParser(context, MangaSource.KOMIKSA, "komiksay.site") {
override val tagPrefix = "komik-genre/" override val tagPrefix = "komik-genre/"

@ -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("BEYONDTHEATARAXIA", "Beyondtheataraxia", "it") @MangaSourceParser("BEYONDTHEATARAXIA", "Beyond The Ataraxia", "it")
internal class Beyondtheataraxia(context: MangaLoaderContext) : internal class Beyondtheataraxia(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.BEYONDTHEATARAXIA, "www.beyondtheataraxia.com", 10) { MadaraParser(context, MangaSource.BEYONDTHEATARAXIA, "www.beyondtheataraxia.com", 10) {
override val datePattern = "d MMMM yyyy" override val datePattern = "d MMMM yyyy"

@ -6,7 +6,7 @@ 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("FBSQUADS", "Fbsquads", "pt", ContentType.HENTAI) @MangaSourceParser("FBSQUADS", "Fb Squads", "pt", ContentType.HENTAI)
internal class Fbsquads(context: MangaLoaderContext) : internal class Fbsquads(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.FBSQUADS, "fbsquads.com") { MadaraParser(context, MangaSource.FBSQUADS, "fbsquads.com") {
override val datePattern: String = "dd/MM/yyyy" override val datePattern: String = "dd/MM/yyyy"

@ -6,7 +6,7 @@ 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("LEITORIZAKAYA", "Leitorizakaya", "pt", ContentType.HENTAI) @MangaSourceParser("LEITORIZAKAYA", "Leitor Izakaya", "pt", ContentType.HENTAI)
internal class Leitorizakaya(context: MangaLoaderContext) : internal class Leitorizakaya(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.LEITORIZAKAYA, "leitorizakaya.net") { MadaraParser(context, MangaSource.LEITORIZAKAYA, "leitorizakaya.net") {
override val datePattern: String = "dd/MM/yyyy" override val datePattern: String = "dd/MM/yyyy"

@ -6,7 +6,7 @@ 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("PIRULITOROSA", "Pirulitorosa", "pt", ContentType.HENTAI) @MangaSourceParser("PIRULITOROSA", "Pirulito Rosa", "pt", ContentType.HENTAI)
internal class Pirulitorosa(context: MangaLoaderContext) : internal class Pirulitorosa(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.PIRULITOROSA, "pirulitorosa.site") { MadaraParser(context, MangaSource.PIRULITOROSA, "pirulitorosa.site") {
override val postReq = true override val postReq = true

@ -6,7 +6,7 @@ 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("YCSCAN", "Ycscan", "pt", ContentType.HENTAI) @MangaSourceParser("YCSCAN", "Yc Scan", "pt", ContentType.HENTAI)
internal class Ycscan(context: MangaLoaderContext) : internal class Ycscan(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.YCSCAN, "ycscan.com", 20) { MadaraParser(context, MangaSource.YCSCAN, "ycscan.com", 20) {
override val datePattern: String = "dd/MM/yyyy" override val datePattern: String = "dd/MM/yyyy"

@ -6,7 +6,7 @@ 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("JIANGZAITOON", "Jiangzaitoon", "tr", ContentType.HENTAI) @MangaSourceParser("JIANGZAITOON", "Jiangzai Toon", "tr", ContentType.HENTAI)
internal class Jiangzaitoon(context: MangaLoaderContext) : internal class Jiangzaitoon(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.JIANGZAITOON, "jiangzaitoon.cc") { MadaraParser(context, MangaSource.JIANGZAITOON, "jiangzaitoon.cc") {
override val postReq = true override val postReq = true

@ -5,6 +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("MANGAWT", "Mangawt", "tr") @MangaSourceParser("MANGAWT", "MangaWt", "tr")
internal class Mangawt(context: MangaLoaderContext) : internal class Mangawt(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAWT, "mangawt.com") MadaraParser(context, MangaSource.MANGAWT, "mangawt.com")

@ -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("TIMENAIGHT", "Timenaight", "tr") @MangaSourceParser("TIMENAIGHT", "Time Naight", "tr")
internal class Timenaight(context: MangaLoaderContext) : internal class Timenaight(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.TIMENAIGHT, "timenaight.com") { MadaraParser(context, MangaSource.TIMENAIGHT, "timenaight.com") {
override val postReq = true override val postReq = true

@ -5,6 +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("WEBTOONEVRENI", "Webtoonevreni", "tr") @MangaSourceParser("WEBTOONEVRENI", "Webtoon Evreni", "tr")
internal class Webtoonevreni(context: MangaLoaderContext) : internal class Webtoonevreni(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.WEBTOONEVRENI, "webtoonevreni.net", 10) MadaraParser(context, MangaSource.WEBTOONEVRENI, "webtoonevreni.net", 10)

@ -137,7 +137,7 @@ internal abstract class MadthemeParser(
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(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirstOrThrow(selectDesc).html()
@ -175,7 +175,7 @@ internal abstract class MadthemeParser(
protected open val selectDate = "div .chapter-update" protected open val selectDate = "div .chapter-update"
protected open val selectChapter = "ul#chapter-list li" protected open val selectChapter = "ul#chapter-list li"
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")

@ -5,6 +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.madtheme.MadthemeParser import org.koitharu.kotatsu.parsers.site.madtheme.MadthemeParser
@MangaSourceParser("MANGAXYZ", "Mangaxyz", "en") @MangaSourceParser("MANGAXYZ", "MangaXyz", "en")
internal class Mangaxyz(context: MangaLoaderContext) : internal class Mangaxyz(context: MangaLoaderContext) :
MadthemeParser(context, MangaSource.MANGAXYZ, "mangaxyz.com") MadthemeParser(context, MangaSource.MANGAXYZ, "mangaxyz.com")

@ -132,7 +132,7 @@ internal abstract class Manga18Parser(
val doc = webClient.httpGet(fullUrl).parseHtml() val doc = webClient.httpGet(fullUrl).parseHtml()
val body = doc.body().selectFirstOrThrow("div.detail_listInfo") val body = doc.body().selectFirstOrThrow("div.detail_listInfo")
val chaptersDeferred = async { getChapters(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirstOrThrow(selectDesc).html()
@ -167,7 +167,7 @@ internal abstract class Manga18Parser(
protected open val selectDate = "div.item p" protected open val selectDate = "div.item p"
protected open val selectChapter = "div.chapter_box li" protected open val selectChapter = "div.chapter_box li"
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")

@ -11,7 +11,7 @@ import org.koitharu.kotatsu.parsers.util.*
internal class Hanman18(context: MangaLoaderContext) : internal class Hanman18(context: MangaLoaderContext) :
Manga18Parser(context, MangaSource.HANMAN18, "hanman18.com") { Manga18Parser(context, MangaSource.HANMAN18, "hanman18.com") {
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(doc: Document): List<MangaChapter> {
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")
val href = a.attrAsRelativeUrl("href") val href = a.attrAsRelativeUrl("href")

@ -130,7 +130,7 @@ internal abstract class MangaboxParser(
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(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirstOrThrow(selectDesc).html()
@ -168,7 +168,7 @@ internal abstract class MangaboxParser(
protected open val selectDate = "span" protected open val selectDate = "span"
protected open val selectChapter = "div.chapter-list div.row, ul.row-content-chapter li" protected open val selectChapter = "div.chapter-list div.row, ul.row-content-chapter li"
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")

@ -116,7 +116,7 @@ internal class Mangairo(context: MangaLoaderContext) :
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(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirstOrThrow(selectDesc).html()

@ -81,7 +81,7 @@ internal class Mangakakalot(context: MangaLoaderContext) :
} }
} }
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(doc: Document): List<MangaChapter> {
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")

@ -5,6 +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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("AREASCANS", "Areascans", "ar") @MangaSourceParser("AREASCANS", "Area Scans", "ar")
internal class Areascans(context: MangaLoaderContext) : internal class Areascans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.AREASCANS, "www.areascans.net", pageSize = 20, searchPageSize = 10) MangaReaderParser(context, MangaSource.AREASCANS, "www.areascans.net", pageSize = 20, searchPageSize = 10)

@ -5,6 +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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("MANGAATREND", "Mangaatrend", "ar") @MangaSourceParser("MANGAATREND", "Manga A Trend", "ar")
internal class Mangaatrend(context: MangaLoaderContext) : internal class Mangaatrend(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MANGAATREND, "mangaatrend.net", pageSize = 40, searchPageSize = 20) MangaReaderParser(context, MangaSource.MANGAATREND, "mangaatrend.net", pageSize = 40, searchPageSize = 20)

@ -6,7 +6,7 @@ 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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("MANHWAX", "Manhwax", "en", ContentType.HENTAI) @MangaSourceParser("MANHWAX", "ManhwaX", "en", ContentType.HENTAI)
internal class Manhwax(context: MangaLoaderContext) : internal class Manhwax(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MANHWAX, "manhwax.org", pageSize = 20, searchPageSize = 20) { MangaReaderParser(context, MangaSource.MANHWAX, "manhwax.org", pageSize = 20, searchPageSize = 20) {
override val datePattern = "MMM d, yyyy" override val datePattern = "MMM d, yyyy"

@ -0,0 +1,10 @@
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("MANJANOON_EN", "Manjanoon", "en")
internal class Manjanoon(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MANJANOON_EN, "manjanoon.net", pageSize = 20, searchPageSize = 10)

@ -0,0 +1,12 @@
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("RAISCANS", "Rai Scans", "en")
internal class RaiScans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.RAISCANS, "www.raiscans.com", pageSize = 20, searchPageSize = 10) {
override val listUrl = "/Series"
}

@ -5,6 +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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("AIYUMANGASCANLATION", "Aiyu Manga", "es") @MangaSourceParser("AIYUMANGASCANLATION", "Aiyu Manhua", "es")
internal class AiyuMangaScanlation(context: MangaLoaderContext) : internal class AiyuMangaScanlation(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.AIYUMANGASCANLATION, "aiyumanhua.com", 20, 10) MangaReaderParser(context, MangaSource.AIYUMANGASCANLATION, "aiyumanhua.com", 20, 10)

@ -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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("RAIKISCAN", "Raikiscan", "es") @MangaSourceParser("RAIKISCAN", "Raiki Scan", "es")
internal class Raikiscan(context: MangaLoaderContext) : internal class Raikiscan(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.RAIKISCAN, "raikiscan.com", pageSize = 20, searchPageSize = 20) { MangaReaderParser(context, MangaSource.RAIKISCAN, "raikiscan.com", pageSize = 20, searchPageSize = 20) {
override val datePattern = "MMM d, yyyy" override val datePattern = "MMM d, yyyy"

@ -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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("SENPAIEDICIONES", "Senpaiediciones", "es") @MangaSourceParser("SENPAIEDICIONES", "Senpai Ediciones", "es")
internal class Senpaiediciones(context: MangaLoaderContext) : internal class Senpaiediciones(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.SENPAIEDICIONES, "senpaiediciones.com", pageSize = 20, searchPageSize = 20) { MangaReaderParser(context, MangaSource.SENPAIEDICIONES, "senpaiediciones.com", pageSize = 20, searchPageSize = 20) {
override val datePattern = "MMM d, yyyy" override val datePattern = "MMM d, yyyy"

@ -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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("SHADOWMANGAS", "Shadowmangas", "es") @MangaSourceParser("SHADOWMANGAS", "Shadow Mangas", "es")
internal class Shadowmangas(context: MangaLoaderContext) : internal class Shadowmangas(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.SHADOWMANGAS, "shadowmangas.com", pageSize = 10, searchPageSize = 10) { MangaReaderParser(context, MangaSource.SHADOWMANGAS, "shadowmangas.com", pageSize = 10, searchPageSize = 10) {

@ -6,6 +6,6 @@ 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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("EPSILONSCAN", "Epsilonscan", "fr", ContentType.HENTAI) @MangaSourceParser("EPSILONSCAN", "Epsilon Scan", "fr", ContentType.HENTAI)
internal class EpsilonscanParser(context: MangaLoaderContext) : internal class EpsilonscanParser(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.EPSILONSCAN, "epsilonscan.fr", pageSize = 20, searchPageSize = 10) MangaReaderParser(context, MangaSource.EPSILONSCAN, "epsilonscan.fr", pageSize = 20, searchPageSize = 10)

@ -6,7 +6,7 @@ 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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("DUNIAKOMIK", "Duniakomik", "id", ContentType.HENTAI) @MangaSourceParser("DUNIAKOMIK", "Dunia Komik", "id", ContentType.HENTAI)
internal class Duniakomik(context: MangaLoaderContext) : internal class Duniakomik(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.DUNIAKOMIK, "duniakomik.org", pageSize = 12, searchPageSize = 12) { MangaReaderParser(context, MangaSource.DUNIAKOMIK, "duniakomik.org", pageSize = 12, searchPageSize = 12) {
override val datePattern = "MMM d, yyyy" override val datePattern = "MMM d, yyyy"

@ -7,8 +7,8 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
import java.util.* import java.util.*
@MangaSourceParser("KOMIKLOKALCFD", "Komiklokal .Cfd", "id", ContentType.HENTAI) @MangaSourceParser("KOMIKLOKALCFD", "Komik Lokal .Sbs", "id", ContentType.HENTAI)
internal class KomiklokalCfd(context: MangaLoaderContext) : internal class KomiklokalCfd(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.KOMIKLOKALCFD, "komiklokal.cfd", pageSize = 30, searchPageSize = 10) { MangaReaderParser(context, MangaSource.KOMIKLOKALCFD, "komiklokal.sbs", pageSize = 30, searchPageSize = 10) {
override val sourceLocale: Locale = Locale.ENGLISH override val sourceLocale: Locale = Locale.ENGLISH
} }

@ -6,7 +6,7 @@ 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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("LIANSCANS", "Lianscans", "id", ContentType.HENTAI) @MangaSourceParser("LIANSCANS", "Lian Scans", "id", ContentType.HENTAI)
internal class Lianscans(context: MangaLoaderContext) : internal class Lianscans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.LIANSCANS, "www.lianscans.my.id", pageSize = 10, searchPageSize = 10) { MangaReaderParser(context, MangaSource.LIANSCANS, "www.lianscans.my.id", pageSize = 10, searchPageSize = 10) {

@ -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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("MUNDOMANGAKUN", "Mundomangakun", "pt") @MangaSourceParser("MUNDOMANGAKUN", "Mundo Manga Kun", "pt")
internal class Mundomangakun(context: MangaLoaderContext) : internal class Mundomangakun(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MUNDOMANGAKUN, "mundomangakun.com.br", pageSize = 20, searchPageSize = 20) { MangaReaderParser(context, MangaSource.MUNDOMANGAKUN, "mundomangakun.com.br", pageSize = 20, searchPageSize = 20) {
override val datePattern = "MMM d, yyyy" override val datePattern = "MMM d, yyyy"

@ -5,6 +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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("AYATOON", "Ayatoon", "tr") @MangaSourceParser("AYATOON", "Aya Toon", "tr")
internal class Ayatoon(context: MangaLoaderContext) : internal class Ayatoon(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.AYATOON, "ayatoon.com", pageSize = 20, searchPageSize = 20) MangaReaderParser(context, MangaSource.AYATOON, "ayatoon.com", pageSize = 20, searchPageSize = 20)

@ -5,6 +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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("GOLGEBAHCESI", "Golgebahcesi", "tr") @MangaSourceParser("GOLGEBAHCESI", "Golge Bahcesi", "tr")
internal class Golgebahcesi(context: MangaLoaderContext) : internal class Golgebahcesi(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.GOLGEBAHCESI, "golgebahcesi.com", pageSize = 14, searchPageSize = 9) MangaReaderParser(context, MangaSource.GOLGEBAHCESI, "golgebahcesi.com", pageSize = 14, searchPageSize = 9)

@ -5,6 +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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("MANGAEFENDISI", "Mangaefendisi", "tr") @MangaSourceParser("MANGAEFENDISI", "Manga Efendisi", "tr")
internal class Mangaefendisi(context: MangaLoaderContext) : internal class Mangaefendisi(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MANGAEFENDISI, "mangaefendisi.net", pageSize = 30, searchPageSize = 20) MangaReaderParser(context, MangaSource.MANGAEFENDISI, "mangaefendisi.net", pageSize = 30, searchPageSize = 20)

@ -5,6 +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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("MANGAOKUTR", "Mangaokutr", "tr") @MangaSourceParser("MANGAOKUTR", "Manga Oku Tr", "tr")
internal class Mangaokutr(context: MangaLoaderContext) : internal class Mangaokutr(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MANGAOKUTR, "mangaokutr.com", pageSize = 25, searchPageSize = 20) MangaReaderParser(context, MangaSource.MANGAOKUTR, "mangaokutr.com", pageSize = 25, searchPageSize = 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.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("RAINDROPTEAMFAN", "Raindropteamfan", "tr") @MangaSourceParser("RAINDROPTEAMFAN", "Raindrop Fansub", "tr")
internal class Raindropteamfan(context: MangaLoaderContext) : internal class Raindropteamfan(context: MangaLoaderContext) :
MangaReaderParser( MangaReaderParser(
context, context,

@ -161,7 +161,7 @@ internal abstract class MmrcmsParser(
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 body = doc.body().selectFirstOrThrow("dl.dl-horizontal") val body = doc.body().selectFirstOrThrow("dl.dl-horizontal")
val chaptersDeferred = async { getChapters(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).text() val desc = doc.selectFirstOrThrow(selectDesc).text()
val stateDiv = body.selectFirst(selectState)?.nextElementSibling() val stateDiv = body.selectFirst(selectState)?.nextElementSibling()
val state = stateDiv?.let { val state = stateDiv?.let {
@ -194,7 +194,7 @@ internal abstract class MmrcmsParser(
protected open val selectDate = "div.date-chapter-title-rtl" protected open val selectDate = "div.date-chapter-title-rtl"
protected open val selectChapter = "ul.chapters > li:not(.btn)" protected open val selectChapter = "ul.chapters > li:not(.btn)"
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")

@ -103,7 +103,7 @@ internal class Onma(context: MangaLoaderContext) :
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 body = doc.body().selectFirstOrThrow("div.panel-body") val body = doc.body().selectFirstOrThrow("div.panel-body")
val chaptersDeferred = async { getChapters(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirst(selectDesc)?.text().orEmpty() val desc = doc.selectFirst(selectDesc)?.text().orEmpty()
val stateDiv = body.selectFirst(selectState) val stateDiv = body.selectFirst(selectState)
val state = stateDiv?.let { val state = stateDiv?.let {

@ -8,7 +8,7 @@ import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser
import java.util.Locale import java.util.Locale
@MangaSourceParser("MANGAID", "Mangaid", "id") @MangaSourceParser("MANGAID", "Manga Id", "id")
internal class Mangaid(context: MangaLoaderContext) : internal class Mangaid(context: MangaLoaderContext) :
MmrcmsParser(context, MangaSource.MANGAID, "mangaid.click") { MmrcmsParser(context, MangaSource.MANGAID, "mangaid.click") {

@ -31,7 +31,7 @@ internal class Animaregia(context: MangaLoaderContext) :
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 body = doc.body().selectFirstOrThrow("ul.list-group") val body = doc.body().selectFirstOrThrow("ul.list-group")
val chaptersDeferred = async { getChapters(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.select(selectDesc).text() val desc = doc.select(selectDesc).text()
val stateDiv = body.selectFirst("li.list-group-item:contains(Status)")?.lastElementChild() val stateDiv = body.selectFirst("li.list-group-item:contains(Status)")?.lastElementChild()
val state = stateDiv?.let { val state = stateDiv?.let {

@ -206,7 +206,6 @@ internal abstract class OtakuSanctuaryParser(
val urls = json.replace("\\u0022", "").substringAfter("{\"view\":\"[").substringBefore("]\",\"isSuccess") val urls = json.replace("\\u0022", "").substringAfter("{\"view\":\"[").substringBefore("]\",\"isSuccess")
.split(",") .split(",")
return urls.map { return urls.map {
val urlImage = processUrl(it) val urlImage = processUrl(it)
MangaPage( MangaPage(
id = generateUid(urlImage), id = generateUid(urlImage),

@ -1,139 +0,0 @@
package org.koitharu.kotatsu.parsers.site.pt
import okhttp3.Headers
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.PagedMangaParser
import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.network.UserAgents
import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("GOLDENMANGA", "Golden Manga", "pt")
internal class GoldenManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.GOLDENMANGA, 36) {
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
override val configKeyDomain = ConfigKey.Domain("goldenmanga.top")
override val headers: Headers = Headers.Builder()
.add("User-Agent", UserAgents.CHROME_MOBILE)
.build()
override suspend fun getListPage(
page: Int,
query: String?,
tags: Set<MangaTag>?,
sortOrder: SortOrder,
): List<Manga> {
val url = buildString {
append("https://")
append(domain)
if (!query.isNullOrEmpty()) {
append("/mangabr?pagina=")
append(page.toString())
append("&busca=")
append(query.urlEncoded())
} else {
append("/mangas")
append("?pagina=")
append(page.toString())
}
if (!tags.isNullOrEmpty()) {
append("&genero=")
for (tag in tags) {
append(tag.key)
append(",")
}
}
}
val doc = webClient.httpGet(url).parseHtml()
return doc.select("section.row div.mangas")
.map { div ->
val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href")
Manga(
id = generateUid(href),
title = div.selectFirstOrThrow("a h3").text(),
altTitle = null,
url = href,
publicUrl = href.toAbsoluteUrl(domain),
rating = RATING_UNKNOWN,
isNsfw = div.selectFirst("div.MangaAdulto") != null,
coverUrl = div.selectFirstOrThrow("img").attrAsAbsoluteUrl("src"),
tags = setOf(),
state = null,
author = null,
source = source,
)
}
}
override suspend fun getTags(): Set<MangaTag> {
val doc = webClient.httpGet("https://$domain/mangas").parseHtml()
return doc.select("div.container a.btn.btn-warning ").mapNotNullToSet { a ->
MangaTag(
key = a.attr("href").substringAfterLast("="),
title = a.text(),
source = source,
)
}
}
override suspend fun getDetails(manga: Manga): Manga {
val root = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
val dateFormat = SimpleDateFormat("(dd/MM/yyyy)", Locale.ENGLISH)
return manga.copy(
altTitle = null,
state = when (root.select("h5.cg_color")[3].select("a").text()) {
"ativo", "Ativo" -> MangaState.ONGOING
"Completo" -> MangaState.FINISHED
else -> null
},
tags = root.select("h5.cg_color")[0].select("a").mapNotNullToSet { a ->
if (a.text().isNullOrEmpty()) {
return@mapNotNullToSet null
} else {
MangaTag(
key = a.attr("href").substringAfterLast("="),
title = a.text().toTitleCase(),
source = source,
)
}
},
author = root.select("h5.cg_color a")[1].text(),
description = root.getElementById("manga_capitulo_descricao")?.html(),
chapters = root.requireElementById("capitulos").select("li")
.mapChapters(reversed = true) { i, div ->
val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href")
val dateText = div.selectFirstOrThrow("div.col-sm-5 span").text()
val name = div.selectFirstOrThrow("div.col-sm-5").text().substringBeforeLast("(")
MangaChapter(
id = generateUid(href),
name = name,
number = i,
url = href,
scanlator = null,
uploadDate = dateFormat.tryParse(dateText),
branch = null,
source = source,
)
},
)
}
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val fullUrl = chapter.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml()
val root = doc.body().requireElementById("capitulos_images")
return root.select("img").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,174 +0,0 @@
package org.koitharu.kotatsu.parsers.site.pt
import org.jsoup.nodes.Element
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.PagedMangaParser
import org.koitharu.kotatsu.parsers.config.ConfigKey
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.util.*
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
import org.koitharu.kotatsu.parsers.util.json.mapJSON
import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("UNION_MANGAS", "Union Mangás", "pt")
class UnionMangasParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.UNION_MANGAS, 40) {
override val sortOrders: Set<SortOrder> = EnumSet.of(
SortOrder.ALPHABETICAL,
SortOrder.POPULARITY,
)
override val configKeyDomain = ConfigKey.Domain("unionmangasbr.top", "guimah.com")
override suspend fun getListPage(
page: Int,
query: String?,
tags: Set<MangaTag>?,
sortOrder: SortOrder,
): List<Manga> {
if (!query.isNullOrEmpty()) {
return if (page == searchPaginator.firstPage) {
search(query)
} else {
emptyList()
}
}
val tag = tags.oneOrThrowIfMany()
val url = urlBuilder()
.addPathSegment("lista-mangas")
.addPathSegment(
when {
tag != null -> tag.key
sortOrder == SortOrder.ALPHABETICAL -> "a-z"
else -> "visualizacoes"
},
).addPathSegment(page.toString())
val doc = webClient.httpGet(url.build()).parseHtml()
val root = doc.selectFirstOrThrow("div.tamanho-bloco-perfil")
return root.select(".lista-itens").map { div ->
val a = div.selectFirstOrThrow("a")
val img = div.selectFirstOrThrow("img")
val href = a.attrAsRelativeUrl("href")
Manga(
id = generateUid(href),
url = href,
publicUrl = a.attrAsAbsoluteUrl("href"),
title = div.selectLastOrThrow("a").text(),
coverUrl = img.attrAsAbsoluteUrl("src"),
altTitle = null,
rating = RATING_UNKNOWN,
tags = emptySet(),
description = div.selectLast("div")?.ownText(),
state = null,
author = null,
isNsfw = false,
source = source,
)
}
}
override suspend fun getDetails(manga: Manga): Manga {
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
val dateFormat = SimpleDateFormat("dd/MM/yyyy", Locale.ROOT)
return manga.copy(
rating = doc.select("h2")
.find { it.ownText().startsWith('#') }
?.ownText()?.drop(1)?.toFloatOrNull()?.div(10f) ?: manga.rating,
largeCoverUrl = doc.selectFirst("img.img-thumbnail")?.attrAsAbsoluteUrlOrNull("src"),
description = doc.selectFirst(".panel-default")?.selectFirst(".panel-body")?.html(),
author = doc.tableValue("Autor")?.ownText(),
altTitle = doc.tableValue("Título(s) Alternativo(s)")?.ownText(),
state = when (doc.tableValue("Status")?.selectLast(".label")?.text()) {
"Completo" -> MangaState.FINISHED
"Ativo" -> MangaState.ONGOING
else -> null
},
tags = doc.tableValue("Gênero(s)")?.select("a")?.mapToSet {
it.toMangaTag()
} ?: manga.tags,
isNsfw = doc.selectFirst(".alert-danger")?.html()?.contains("18 anos") == true,
chapters = doc.select("div.row.capitulos").mapChapters(reversed = true) { i, div ->
val a = div.selectFirstOrThrow("a")
val href = a.attrAsRelativeUrl("href")
val title = a.text()
MangaChapter(
id = generateUid(href),
name = title,
number = i + 1,
url = href,
scanlator = div.selectLast("a")?.text()?.takeUnless { it == title },
uploadDate = dateFormat.tryParse(
a.nextElementSibling()?.text()?.removeSurrounding("(", ")"),
),
branch = null,
source = source,
)
},
)
}
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val fullUrl = chapter.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml()
return doc.body().selectOrThrow("img[pag]").mapNotNull { img ->
val href = img.attrAsRelativeUrl("src")
if (href.startsWith("/images/banner")) {
return@mapNotNull null
}
MangaPage(
id = generateUid(href),
url = href,
preview = null,
source = source,
)
}
}
override suspend fun getTags(): Set<MangaTag> {
val doc = webClient.httpGet(urlBuilder().addPathSegment("lista-mangas").build()).parseHtml()
val ul = doc.body().selectFirstOrThrow(".nav-tabs").selectFirstOrThrow("ul.dropdown-menu")
return ul.select("li").mapToSet { li ->
li.selectFirstOrThrow("a").toMangaTag()
}
}
private suspend fun search(query: String): List<Manga> {
val domain = domain
val json = webClient.httpGet(
urlBuilder()
.addPathSegments("assets/busca.php")
.addQueryParameter("nomeManga", query)
.build(),
).parseJson()
return json.getJSONArray("items").mapJSON { jo ->
val href = "/perfil/" + jo.getString("url")
Manga(
id = generateUid(href),
url = href,
publicUrl = href.toAbsoluteUrl(domain),
title = jo.getString("titulo"),
rating = RATING_UNKNOWN,
tags = emptySet(),
author = jo.getStringOrNull("autor"),
coverUrl = jo.getString("imagem"),
state = null,
isNsfw = false,
altTitle = null,
source = source,
)
}
}
private fun Element.tableValue(title: String): Element? {
return select("h4.media-heading")
.find { it.selectFirst("label.subtit-manga")?.text()?.contains(title, ignoreCase = true) == true }
}
private fun Element.toMangaTag() = MangaTag(
title = text().toTitleCase(sourceLocale),
key = attr("href").removeSuffix('/').substringAfterLast('/'),
source = source,
)
}

@ -15,7 +15,7 @@ import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed
import org.koitharu.kotatsu.parsers.util.json.mapJSONToSet import org.koitharu.kotatsu.parsers.util.json.mapJSONToSet
import java.util.* import java.util.*
@MangaSourceParser("DESUME", "Desu.me", "ru") @MangaSourceParser("DESUME", "Desu .Me", "ru")
internal class DesuMeParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.DESUME, 20) { internal class DesuMeParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.DESUME, 20) {
override val configKeyDomain = ConfigKey.Domain("desu.me", "desu.win") override val configKeyDomain = ConfigKey.Domain("desu.me", "desu.win")

@ -11,8 +11,6 @@ import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
private const val MAX_THUMB_INDEX = 19
@MangaSourceParser("NUDEMOON", "Nude-Moon", "ru", type = ContentType.HENTAI) @MangaSourceParser("NUDEMOON", "Nude-Moon", "ru", type = ContentType.HENTAI)
internal class NudeMoonParser( internal class NudeMoonParser(
context: MangaLoaderContext, context: MangaLoaderContext,

@ -24,7 +24,7 @@ private const val PAGE_SIZE = 30
private const val STATUS_ONGOING = 1 private const val STATUS_ONGOING = 1
private const val STATUS_FINISHED = 0 private const val STATUS_FINISHED = 0
@MangaSourceParser("REMANGA", "Remanga", "ru") @MangaSourceParser("REMANGA", "Re Manga", "ru")
internal class RemangaParser( internal class RemangaParser(
context: MangaLoaderContext, context: MangaLoaderContext,
) : PagedMangaParser(context, MangaSource.REMANGA, PAGE_SIZE), MangaParserAuthProvider { ) : PagedMangaParser(context, MangaSource.REMANGA, PAGE_SIZE), MangaParserAuthProvider {

@ -122,7 +122,7 @@ internal abstract class SinmhParser(
val doc = webClient.httpGet(fullUrl).parseHtml() val doc = webClient.httpGet(fullUrl).parseHtml()
val body = doc.body() val body = doc.body()
val chapters = getChapters(manga, doc) val chapters = getChapters(doc)
val desc = body.selectFirst(selectDesc)?.html() val desc = body.selectFirst(selectDesc)?.html()
@ -150,7 +150,7 @@ internal abstract class SinmhParser(
protected open val selectChapter = "ul#chapter-list-1 li" protected open val selectChapter = "ul#chapter-list-1 li"
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
return doc.body().select(selectChapter).mapChapters { i, li -> return doc.body().select(selectChapter).mapChapters { i, li ->
val href = li.selectFirstOrThrow("a").attrAsRelativeUrl("href") val href = li.selectFirstOrThrow("a").attrAsRelativeUrl("href")
val name = li.selectFirstOrThrow("a").text() val name = li.selectFirstOrThrow("a").text()

@ -79,14 +79,14 @@ class HentaiUkrParser(context: MangaLoaderContext) : MangaParser(context, MangaS
val ids = tags.mapToSet { it.key } val ids = tags.mapToSet { it.key }
json.retainAll { item -> json.retainAll { item ->
item.getJSONArray("tags") item.getJSONArray("tags")
.mapJSON { it.getAsString("id") } .mapJSON { it.getAsString() }
.any { x -> x in ids } .any { x -> x in ids }
} }
} }
// Return to app // Return to app
return json.drop(offset).take(PAGE_SIZE).map { jo -> return json.drop(offset).take(PAGE_SIZE).map { jo ->
val id = jo.getAsLong("id") val id = jo.getAsLong()
Manga( Manga(
id = generateUid(id), id = generateUid(id),
title = jo.getString("name"), title = jo.getString("name"),
@ -124,7 +124,7 @@ class HentaiUkrParser(context: MangaLoaderContext) : MangaParser(context, MangaS
x.getJSONArray("tags").mapJSON { t -> x.getJSONArray("tags").mapJSON { t ->
MangaTag( MangaTag(
title = t.getString("name"), title = t.getString("name"),
key = t.getAsString("id"), key = t.getAsString(),
source = source, source = source,
) )
} }
@ -138,7 +138,7 @@ class HentaiUkrParser(context: MangaLoaderContext) : MangaParser(context, MangaS
tagsSet.add( tagsSet.add(
MangaTag( MangaTag(
title = item.getString("name"), title = item.getString("name"),
key = item.getAsString("id"), key = item.getAsString(),
source = source, source = source,
), ),
) )
@ -157,8 +157,8 @@ class HentaiUkrParser(context: MangaLoaderContext) : MangaParser(context, MangaS
return chain.proceed(newRequest) return chain.proceed(newRequest)
} }
private fun JSONObject.getAsLong(name: String): Long { private fun JSONObject.getAsLong(): Long {
val rawValue = opt(name) val rawValue = opt("id")
return when (rawValue) { return when (rawValue) {
null, JSONObject.NULL -> null null, JSONObject.NULL -> null
is Long -> rawValue is Long -> rawValue
@ -168,7 +168,7 @@ class HentaiUkrParser(context: MangaLoaderContext) : MangaParser(context, MangaS
} ?: error("Cannot read value $rawValue as Long") } ?: error("Cannot read value $rawValue as Long")
} }
private fun JSONObject.getAsString(name: String): String { private fun JSONObject.getAsString(): String {
return get(name).toString() return get("id").toString()
} }
} }

@ -34,7 +34,7 @@ class MangaInUaParser(context: MangaLoaderContext) : PagedMangaParser(
sortOrder: SortOrder, sortOrder: SortOrder,
): List<Manga> { ): List<Manga> {
val url = when { val url = when {
!query.isNullOrEmpty() -> ("/index.php?do=search" + "&subaction=search" + "&search_start=$page" + "&full_search=1" + "&story=$query" + "&titleonly=3").toAbsoluteUrl( !query.isNullOrEmpty() -> ("/index.php?do=search&subaction=search&search_start=$page&full_search=1&story=$query&titleonly=3").toAbsoluteUrl(
domain, domain,
) )

@ -56,7 +56,7 @@ class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaSo
val infoEl = infoElDeferred.await() val infoEl = infoElDeferred.await()
val stateDoc = stateDocDeferred.await() val stateDoc = stateDocDeferred.await()
manga.copy( manga.copy(
altTitle = infoEl.infoText("Tên Khác:"), altTitle = infoEl.selectFirst("span.info:contains(Tên Khác:)")?.parent()?.select("span:not(.info) > a")?.joinToString { it.text() },
author = infoEl.select("p:contains(Tác giả:) a").text(), author = infoEl.select("p:contains(Tác giả:) a").text(),
description = infoEl.select("p:contains(Nội dung:) + p").html(), description = infoEl.select("p:contains(Nội dung:) + p").html(),
tags = tagCache.tryGet().getOrNull()?.let { tagMap -> tags = tagCache.tryGet().getOrNull()?.let { tagMap ->
@ -173,8 +173,8 @@ class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaSo
return docs.selectFirstOrThrow("div.main").selectFirstOrThrow("div.block-item").select("ul > li.item") return docs.selectFirstOrThrow("div.main").selectFirstOrThrow("div.block-item").select("ul > li.item")
.map { el -> .map { el ->
val relativeUrl = el.selectFirstOrThrow("div.box-cover-2 > a").attrAsRelativeUrl("href") val relativeUrl = el.selectFirstOrThrow("div.box-cover > a").attrAsRelativeUrl("href")
val descriptionsEl = el.selectFirstOrThrow("div.box-description-2") val descriptionsEl = el.selectFirstOrThrow("div.box-description")
Manga( Manga(
id = generateUid(relativeUrl), id = generateUid(relativeUrl),
title = descriptionsEl.selectFirst("a")?.text().orEmpty(), title = descriptionsEl.selectFirst("a")?.text().orEmpty(),
@ -183,7 +183,7 @@ class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaSo
publicUrl = relativeUrl.toAbsoluteUrl(domain), publicUrl = relativeUrl.toAbsoluteUrl(domain),
rating = RATING_UNKNOWN, rating = RATING_UNKNOWN,
isNsfw = true, isNsfw = true,
coverUrl = el.selectFirst("div.box-cover-2 img")?.src().orEmpty(), coverUrl = el.selectFirst("div.box-cover img")?.src().orEmpty(),
tags = emptySet(), tags = emptySet(),
state = null, state = null,
author = null, author = null,
@ -239,8 +239,5 @@ class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaSo
) )
} }
} }
private fun Element.infoText(title: String) =
selectFirst("span.info:contains($title)")?.parent()?.select("span:not(.info) > a")?.joinToString { it.text() }
} }

@ -33,7 +33,7 @@ import java.text.SimpleDateFormat
import java.util.EnumSet import java.util.EnumSet
import java.util.Locale import java.util.Locale
@MangaSourceParser("YURINEKO", "Yurineko", "vi", ContentType.HENTAI) @MangaSourceParser("YURINEKO", "Yuri Neko", "vi", ContentType.HENTAI)
class YurinekoParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.YURINEKO, 20) { class YurinekoParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.YURINEKO, 20) {
override val configKeyDomain: ConfigKey.Domain override val configKeyDomain: ConfigKey.Domain
get() = ConfigKey.Domain("yurineko.net") get() = ConfigKey.Domain("yurineko.net")

@ -126,7 +126,7 @@ internal abstract class WpComicsParser(
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(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirstOrThrow(selectDesc).html()
@ -162,7 +162,7 @@ internal abstract class WpComicsParser(
protected open val selectDate = "div.col-xs-4" protected open val selectDate = "div.col-xs-4"
protected open val selectChapter = "div#nt_listchapter li:not(.heading)" protected open val selectChapter = "div#nt_listchapter li:not(.heading)"
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")

@ -140,7 +140,7 @@ internal abstract class ZMangaParser(
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(manga, doc) } val chaptersDeferred = async { getChapters(doc) }
val desc = doc.selectFirstOrThrow(selectDesc).html() val desc = doc.selectFirstOrThrow(selectDesc).html()
@ -179,7 +179,7 @@ internal abstract class ZMangaParser(
protected open val selectDate = "span.date" protected open val selectDate = "span.date"
protected open val selectChapter = "ul.series-chapterlist li" protected open val selectChapter = "ul.series-chapterlist li"
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")

@ -3,7 +3,6 @@ package org.koitharu.kotatsu.parsers.site.zmanga.id
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
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.Manga
import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.zmanga.ZMangaParser import org.koitharu.kotatsu.parsers.site.zmanga.ZMangaParser
@ -18,7 +17,7 @@ import java.text.SimpleDateFormat
internal class MaidId(context: MangaLoaderContext) : internal class MaidId(context: MangaLoaderContext) :
ZMangaParser(context, MangaSource.MAID_ID, "www.maid.my.id") { ZMangaParser(context, MangaSource.MAID_ID, "www.maid.my.id") {
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")

@ -4,7 +4,6 @@ import org.jsoup.nodes.Document
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
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.zmanga.ZMangaParser import org.koitharu.kotatsu.parsers.site.zmanga.ZMangaParser
@ -18,7 +17,7 @@ import java.text.SimpleDateFormat
internal class ShiroDoujin(context: MangaLoaderContext) : internal class ShiroDoujin(context: MangaLoaderContext) :
ZMangaParser(context, MangaSource.SHIRO_DOUJIN, "shirodoujin.com") { ZMangaParser(context, MangaSource.SHIRO_DOUJIN, "shirodoujin.com") {
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> { override suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")

Loading…
Cancel
Save