add source and fix japscan
This commit is contained in:
@@ -49,7 +49,7 @@ internal class JapScanParser(context: MangaLoaderContext) : PagedMangaParser(con
|
||||
override val configKeyDomain = ConfigKey.Domain("www.japscan.lol", "japscan.ws")
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
||||
.add("User-Agent", UserAgents.CHROME_MOBILE)
|
||||
.build()
|
||||
|
||||
override suspend fun getListPage(
|
||||
@@ -68,21 +68,19 @@ internal class JapScanParser(context: MangaLoaderContext) : PagedMangaParser(con
|
||||
.build()
|
||||
val root = webClient.httpGet(url).parseHtml()
|
||||
.requireElementById("main")
|
||||
.selectFirstOrThrow(".flex-wrap")
|
||||
return root.select(".mainTitle")
|
||||
.map { p ->
|
||||
val div = checkNotNull(p.parent())
|
||||
val a = div.selectFirstOrThrow("a")
|
||||
val href = a.attrAsRelativeUrl("href")
|
||||
.selectFirstOrThrow(".p-2.row.d-flex")
|
||||
return root.select("div.col-4")
|
||||
.map { div ->
|
||||
val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href")
|
||||
Manga(
|
||||
id = generateUid(href),
|
||||
title = p.text(),
|
||||
title = div.selectFirstOrThrow("p.p-1 a").text(),
|
||||
altTitle = null,
|
||||
url = href,
|
||||
publicUrl = href.toAbsoluteUrl(domain),
|
||||
rating = RATING_UNKNOWN,
|
||||
isNsfw = false,
|
||||
coverUrl = div.selectFirstOrThrow("img").attrAsAbsoluteUrl("src"),
|
||||
coverUrl = div.selectFirstOrThrow("img.img-fluid").attrAsAbsoluteUrl("src"),
|
||||
tags = setOf(),
|
||||
state = null,
|
||||
author = null,
|
||||
@@ -128,6 +126,27 @@ internal class JapScanParser(context: MangaLoaderContext) : PagedMangaParser(con
|
||||
)
|
||||
}
|
||||
|
||||
private fun extractQuotedContent(input: String): List<String> {
|
||||
val regex = Regex("'(.*?)'")
|
||||
return regex.findAll(input).map { it.groupValues[1] }.toList()
|
||||
}
|
||||
|
||||
private fun listJSToKey(jsList: MutableList<String>, offsettab: Int, listKey: List<String>): MutableList<String> {
|
||||
for (i in 0 until jsList.size) {
|
||||
if (jsList[i].contains("0x")) {
|
||||
var decoupeHexa = jsList[i].split("('")[1]
|
||||
decoupeHexa = decoupeHexa.split("')")[0]
|
||||
var indexkey = Integer.decode(decoupeHexa) - offsettab - 1
|
||||
if (indexkey < 0) {
|
||||
indexkey = listKey.size - 1
|
||||
}
|
||||
jsList[i] = listKey[indexkey]
|
||||
}
|
||||
}
|
||||
|
||||
return jsList
|
||||
}
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val chapterUrl = chapter.url.toAbsoluteUrl(domain)
|
||||
val doc = webClient.httpGet(chapterUrl).parseHtml()
|
||||
@@ -137,20 +156,67 @@ internal class JapScanParser(context: MangaLoaderContext) : PagedMangaParser(con
|
||||
val embeddedData = doc.requireElementById("data").attr("data-data")
|
||||
val script = webClient.httpGet(scriptUrl).parseRaw()
|
||||
|
||||
val shortkeyRegex = Regex("""'([\dA-Z]{2})'""", RegexOption.IGNORE_CASE)
|
||||
val longkeyRegex = Regex("""'([\dA-Z]{20})'""", RegexOption.IGNORE_CASE)
|
||||
var tabKey = "'" + script.split("=['")[1]
|
||||
tabKey = tabKey.split("];")[0]
|
||||
val listKey = tabKey.split("','").toMutableList()
|
||||
|
||||
val longTables = longkeyRegex.findAll(script).map {
|
||||
it.groupValues[1]
|
||||
}.toList()
|
||||
var decoupeOffset = script.split("-0x")[1]
|
||||
decoupeOffset = "0x" + decoupeOffset.split(";")[0]
|
||||
|
||||
val shortTables = shortkeyRegex.findAll(script).map {
|
||||
it.groupValues[1]
|
||||
}.toList()
|
||||
val offsettab = Integer.decode(decoupeOffset)
|
||||
|
||||
var decoupeFuncOrder = script.split("while(!![])")[1]
|
||||
decoupeFuncOrder = decoupeFuncOrder.split("if")[0]
|
||||
|
||||
val listKeyOrder = extractQuotedContent(decoupeFuncOrder).toMutableList()
|
||||
|
||||
if (listKeyOrder.size < 3) {
|
||||
throw Exception("L'ordre des clés n'a pas pu être déterminé")
|
||||
}
|
||||
var goodorder = false
|
||||
for (i in 0 until listKey.size) {
|
||||
for (z in 0 until listKeyOrder.size) {
|
||||
if (listKey[Integer.decode(listKeyOrder[z]) - offsettab - 1].contains("[0-9]".toRegex())) {
|
||||
goodorder = true
|
||||
} else {
|
||||
goodorder = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (goodorder) {
|
||||
break
|
||||
}
|
||||
|
||||
val firstElement = listKey.removeAt(0)
|
||||
listKey.add(firstElement)
|
||||
}
|
||||
|
||||
if (!goodorder) {
|
||||
throw Exception("L'ordre des clés n'a pas pu être déterminé")
|
||||
}
|
||||
|
||||
val zjscalc = script.split("/[A-Z0-9]/gi,")[1]
|
||||
|
||||
val calc1 = zjscalc.split(",")[0]
|
||||
var calc1tab = calc1.split("+").toMutableList()
|
||||
calc1tab = listJSToKey(calc1tab, offsettab, listKey)
|
||||
|
||||
val calc2 = zjscalc.split(",")[1]
|
||||
var calc2tab = calc2.split("+").toMutableList()
|
||||
calc2tab = listJSToKey(calc2tab, offsettab, listKey)
|
||||
|
||||
var key1 = calc1tab.joinToString("")
|
||||
var key2 = calc2tab.joinToString("")
|
||||
|
||||
key1 = key1.replace("'", "")
|
||||
key2 = key2.replace("'", "")
|
||||
key1 = key1.replace(" ", "")
|
||||
key2 = key2.replace(" ", "")
|
||||
|
||||
val keyTables = listOf(
|
||||
shortTables[1].reversed() + longTables[1].reversed() + longTables[4].reversed() + longTables[0].reversed(),
|
||||
shortTables[2].reversed() + longTables[3].reversed() + longTables[5].reversed() + longTables[2].reversed(),
|
||||
key1.reversed(),
|
||||
key2.reversed(),
|
||||
)
|
||||
|
||||
var error: Exception? = null
|
||||
|
||||
@@ -264,13 +264,14 @@ internal abstract class MadaraParser(
|
||||
protected open val selectgenre = "div.genres-content a"
|
||||
protected open val selectdate = "span.chapter-release-date i"
|
||||
protected open val selectchapter = "li.wp-manga-chapter"
|
||||
protected open val selectTestAsync = "div.listing-chapters_wrap"
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
|
||||
val fullUrl = manga.url.toAbsoluteUrl(domain)
|
||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||
val body = doc.body()
|
||||
|
||||
val testchekasync = body.select("div.listing-chapters_wrap")
|
||||
val testchekasync = body.select(selectTestAsync)
|
||||
|
||||
val chaptersDeferred = if (testchekasync.isNullOrEmpty()) {
|
||||
async { loadChapters(manga.url, doc) }
|
||||
@@ -329,10 +330,10 @@ internal abstract class MadaraParser(
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
protected open suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> {
|
||||
val root2 = doc.body().selectFirstOrThrow("div.content-area")
|
||||
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
|
||||
return root2.select(selectchapter).mapChapters(reversed = true) { i, li ->
|
||||
return doc.body().select(selectchapter).mapChapters(reversed = true) { i, li ->
|
||||
val a = li.selectFirst("a")
|
||||
val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing")
|
||||
val link = href + stylepage
|
||||
@@ -389,6 +390,8 @@ internal abstract class MadaraParser(
|
||||
}
|
||||
}
|
||||
|
||||
protected open val selectPage = "div.page-break"
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val fullUrl = chapter.url.toAbsoluteUrl(domain)
|
||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||
@@ -396,7 +399,7 @@ internal abstract class MadaraParser(
|
||||
val chapterProtector = doc.getElementById("chapter-protector-data")
|
||||
if (chapterProtector == null) {
|
||||
val root = doc.body().selectFirstOrThrow("div.main-col-inner").selectFirstOrThrow("div.reading-content")
|
||||
return root.select("div.page-break").map { div ->
|
||||
return root.select(selectPage).map { div ->
|
||||
val img = div.selectFirstOrThrow("img")
|
||||
val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found")
|
||||
MangaPage(
|
||||
@@ -436,30 +439,31 @@ internal abstract class MadaraParser(
|
||||
val d = date?.lowercase() ?: return 0
|
||||
return when {
|
||||
d.endsWith(" ago") || d.endsWith(" atrás") || // Handle translated 'ago' in Portuguese.
|
||||
d.startsWith("há ") || // other translated 'ago' in Portuguese.
|
||||
d.endsWith(" hace") || // other translated 'ago' in Spanish
|
||||
d.endsWith(" önce") || // Handle translated 'ago' in Turkish.
|
||||
d.endsWith(" trước") || // Handle translated 'ago' in Viêt Nam.
|
||||
d.startsWith("il y a") || // Handle translated 'ago' in French.
|
||||
//If there is no ago but just a motion of time
|
||||
// short Hours
|
||||
d.endsWith(" h") ||
|
||||
// short Day
|
||||
d.endsWith(" d") ||
|
||||
// Day in Portuguese
|
||||
d.endsWith(" días") || d.endsWith(" día") ||
|
||||
// Day in French
|
||||
d.endsWith(" jour") || d.endsWith(" jours") ||
|
||||
// Hours in Portuguese
|
||||
d.endsWith(" horas") || d.endsWith(" hora") ||
|
||||
// Hours in french
|
||||
d.endsWith(" heure") || d.endsWith(" heures") ||
|
||||
// Minutes in English
|
||||
d.endsWith(" mins") ||
|
||||
// Minutes in Portuguese
|
||||
d.endsWith(" minutos") || d.endsWith(" minuto") ||
|
||||
//Minutes in French
|
||||
d.endsWith(" minute") || d.endsWith(" minutes") -> parseRelativeDate(date)
|
||||
d.startsWith("há ") || // other translated 'ago' in Portuguese.
|
||||
d.endsWith(" hace") || // other translated 'ago' in Spanish
|
||||
d.endsWith(" назад") || // other translated 'ago' in Russian
|
||||
d.endsWith(" önce") || // Handle translated 'ago' in Turkish.
|
||||
d.endsWith(" trước") || // Handle translated 'ago' in Viêt Nam.
|
||||
d.startsWith("il y a") || // Handle translated 'ago' in French.
|
||||
//If there is no ago but just a motion of time
|
||||
// short Hours
|
||||
d.endsWith(" h") ||
|
||||
// short Day
|
||||
d.endsWith(" d") ||
|
||||
// Day in Portuguese
|
||||
d.endsWith(" días") || d.endsWith(" día") ||
|
||||
// Day in French
|
||||
d.endsWith(" jour") || d.endsWith(" jours") ||
|
||||
// Hours in Portuguese
|
||||
d.endsWith(" horas") || d.endsWith(" hora") ||
|
||||
// Hours in french
|
||||
d.endsWith(" heure") || d.endsWith(" heures") ||
|
||||
// Minutes in English
|
||||
d.endsWith(" mins") ||
|
||||
// Minutes in Portuguese
|
||||
d.endsWith(" minutos") || d.endsWith(" minuto") ||
|
||||
//Minutes in French
|
||||
d.endsWith(" minute") || d.endsWith(" minutes") -> parseRelativeDate(date)
|
||||
|
||||
// Handle 'yesterday' and 'today', using midnight
|
||||
d.startsWith("year") -> Calendar.getInstance().apply {
|
||||
@@ -505,6 +509,7 @@ internal abstract class MadaraParser(
|
||||
"day",
|
||||
"days",
|
||||
"d",
|
||||
"день",
|
||||
).anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis
|
||||
|
||||
WordSet("jam", "saat", "heure", "hora", "horas", "hour", "hours", "h").anyWordIn(date) -> cal.apply {
|
||||
@@ -523,6 +528,7 @@ internal abstract class MadaraParser(
|
||||
"minuto",
|
||||
"mins",
|
||||
"phút",
|
||||
"минут",
|
||||
).anyWordIn(date) -> cal.apply {
|
||||
add(
|
||||
Calendar.MINUTE,
|
||||
@@ -554,10 +560,10 @@ internal abstract class MadaraParser(
|
||||
|
||||
private fun createRequestTemplate() =
|
||||
("action=madara_load_more&page=1&template=madara-core%2Fcontent%2Fcontent-search&vars%5Bs%5D=&vars%5B" +
|
||||
"orderby%5D=meta_value_num&vars%5Bpaged%5D=1&vars%5Btemplate%5D=search&vars%5Bmeta_query" +
|
||||
"%5D%5B0%5D%5Brelation%5D=AND&vars%5Bmeta_query%5D%5Brelation%5D=OR&vars%5Bpost_type" +
|
||||
"%5D=wp-manga&vars%5Bpost_status%5D=publish&vars%5Bmeta_key%5D=_latest_update&vars%5Border" +
|
||||
"%5D=desc&vars%5Bmanga_archives_item_layout%5D=default").split(
|
||||
"orderby%5D=meta_value_num&vars%5Bpaged%5D=1&vars%5Btemplate%5D=search&vars%5Bmeta_query" +
|
||||
"%5D%5B0%5D%5Brelation%5D=AND&vars%5Bmeta_query%5D%5Brelation%5D=OR&vars%5Bpost_type" +
|
||||
"%5D=wp-manga&vars%5Bpost_status%5D=publish&vars%5Bmeta_key%5D=_latest_update&vars%5Border" +
|
||||
"%5D=desc&vars%5Bmanga_archives_item_layout%5D=default").split(
|
||||
'&',
|
||||
).map {
|
||||
val pos = it.indexOf('=')
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("FALCONMANGA", "FalconManga", "ar")
|
||||
internal class FalconManga(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.FALCONMANGA, "falconmanga.com") {
|
||||
|
||||
override val datePattern = "d MMMM، yyyy"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("KOLMANGA", "KolManga", "ar")
|
||||
internal class KolManga(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.KOLMANGA, "kolmanga.com")
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("MANGALEKS", "MangaLeks", "ar")
|
||||
internal class MangaLeks(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANGALEKS, "mangaleks.com") {
|
||||
|
||||
override val datePattern = "yyyy/MM/dd"
|
||||
override val postreq = true
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("ARCANESCANS", "ArcaneScans", "en")
|
||||
internal class ArcaneScans(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.ARCANESCANS, "arcanescans.com", 10)
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("COMIZ", "Comiz", "en")
|
||||
internal class Comiz(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.COMIZ, "v2.comiz.net", 10) {
|
||||
|
||||
override val isNsfwSource = true
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("DUCKMANGA", "DuckManga", "en")
|
||||
internal class DuckManga(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.DUCKMANGA, "duckmanga.com", 20) {
|
||||
|
||||
override val isNsfwSource = true
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("GRABBER", "Grabber", "en")
|
||||
internal class Grabber(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.GRABBER, "grabber.zone", 20) {
|
||||
|
||||
override val tagPrefix = "type/"
|
||||
override val datePattern = "dd.MM.yyyy"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("HENTAI3Z", "Hentai3z", "en")
|
||||
internal class Hentai3z(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.HENTAI3Z, "hentai3z.xyz", pageSize = 20) {
|
||||
|
||||
override val isNsfwSource = true
|
||||
override val withoutAjax = true
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
|
||||
import org.jsoup.nodes.Document
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
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.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrlOrNull
|
||||
import org.koitharu.kotatsu.parsers.util.generateUid
|
||||
import org.koitharu.kotatsu.parsers.util.mapChapters
|
||||
import org.koitharu.kotatsu.parsers.util.parseFailed
|
||||
import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
@MangaSourceParser("HENTAIXDICKGIRL", "Hentaixdickgirl", "en")
|
||||
internal class Hentaixdickgirl(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.HENTAIXDICKGIRL, "hentaixdickgirl.com", 16) {
|
||||
|
||||
override val isNsfwSource = true
|
||||
override val postreq = true
|
||||
|
||||
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> {
|
||||
val root2 = doc.body().selectFirstOrThrow("div.listing-chapters_wrap")
|
||||
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
|
||||
return root2.select(selectchapter).mapChapters(reversed = true) { i, li ->
|
||||
val a = li.selectFirst("a")
|
||||
val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing")
|
||||
val link = href + stylepage
|
||||
val dateText = li.selectFirst("a.c-new-tag")?.attr("title") ?: li.selectFirst(selectdate)?.text()
|
||||
val name = a.selectFirst("p")?.text() ?: a.ownText()
|
||||
MangaChapter(
|
||||
id = generateUid(href),
|
||||
name = name,
|
||||
number = i + 1,
|
||||
url = link,
|
||||
uploadDate = parseChapterDate(
|
||||
dateFormat,
|
||||
dateText,
|
||||
),
|
||||
source = source,
|
||||
scanlator = null,
|
||||
branch = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("JIMANGA", "JiManga", "en")
|
||||
internal class JiManga(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.JIMANGA, "jimanga.com")
|
||||
@@ -0,0 +1,202 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import org.jsoup.nodes.Document
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
@MangaSourceParser("MANGADASS", "MangaDass", "en")
|
||||
internal class MangaDass(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANGADASS, "mangadass.com", 20) {
|
||||
|
||||
override val isNsfwSource = true
|
||||
override val datePattern = "dd MMM yyyy"
|
||||
override val withoutAjax = true
|
||||
override val selectchapter = "li.a-h"
|
||||
override val selectdesc = "div.ss-manga"
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> {
|
||||
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
append(domain)
|
||||
val pages = page + 1
|
||||
|
||||
when {
|
||||
!query.isNullOrEmpty() -> {
|
||||
|
||||
append("/?s=")
|
||||
append(query.urlEncoded())
|
||||
append("&page=")
|
||||
append(pages.toString())
|
||||
}
|
||||
|
||||
!tags.isNullOrEmpty() -> {
|
||||
append("/$tagPrefix")
|
||||
for (tag in tags) {
|
||||
append(tag.key)
|
||||
}
|
||||
append("/")
|
||||
append(pages.toString())
|
||||
append("?")
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
||||
append("/$listeurl")
|
||||
append("/")
|
||||
append(pages.toString())
|
||||
append("?")
|
||||
}
|
||||
}
|
||||
append("orderby=")
|
||||
when (sortOrder) {
|
||||
SortOrder.POPULARITY -> append("views")
|
||||
SortOrder.UPDATED -> append("latest")
|
||||
SortOrder.NEWEST -> append("new-manga")
|
||||
SortOrder.ALPHABETICAL -> append("alphabet")
|
||||
else -> append("latest")
|
||||
}
|
||||
}
|
||||
val doc = webClient.httpGet(url).parseHtml()
|
||||
|
||||
|
||||
return doc.select("div.row.c-tabs-item__content").ifEmpty {
|
||||
doc.select("div.page-item-detail")
|
||||
}.map { div ->
|
||||
val href = div.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found")
|
||||
val summary = div.selectFirst(".tab-summary") ?: div.selectFirst(".item-summary")
|
||||
Manga(
|
||||
id = generateUid(href),
|
||||
url = href,
|
||||
publicUrl = href.toAbsoluteUrl(div.host ?: domain),
|
||||
coverUrl = div.selectFirst("img")?.src().orEmpty(),
|
||||
title = (summary?.selectFirst("h3") ?: summary?.selectFirst("h4"))?.text().orEmpty(),
|
||||
altTitle = null,
|
||||
rating = div.selectFirst("span.total_votes")?.ownText()?.toFloatOrNull()?.div(5f) ?: -1f,
|
||||
tags = summary?.selectFirst(".mg_genres")?.select("a")?.mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||
title = a.text().ifEmpty { return@mapNotNullToSet null }.toTitleCase(),
|
||||
source = source,
|
||||
)
|
||||
}.orEmpty(),
|
||||
author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
|
||||
state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()
|
||||
?.lowercase()) {
|
||||
in ongoing -> MangaState.ONGOING
|
||||
in finished -> MangaState.FINISHED
|
||||
else -> null
|
||||
},
|
||||
source = source,
|
||||
isNsfw = isNsfwSource,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
|
||||
val fullUrl = manga.url.toAbsoluteUrl(domain)
|
||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||
val body = doc.body()
|
||||
|
||||
val chaptersDeferred = async { getChapters(manga, doc) }
|
||||
|
||||
val desc = body.select(selectdesc).let {
|
||||
if (it.select("p").text().isNotEmpty()) {
|
||||
it.select("p").joinToString(separator = "\n\n") { p ->
|
||||
p.text().replace("<br>", "\n")
|
||||
}
|
||||
} else {
|
||||
it.text()
|
||||
}
|
||||
}
|
||||
|
||||
val stateDiv = (body.selectFirst("div.post-content_item:contains(Status)"))?.selectLast("div.summary-content")
|
||||
|
||||
val state = stateDiv?.let {
|
||||
when (it.text()) {
|
||||
in ongoing -> MangaState.ONGOING
|
||||
in finished -> MangaState.FINISHED
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
val alt =
|
||||
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
|
||||
?.trim() ?: doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content")
|
||||
.firstOrNull()?.tableValue()?.text()?.trim()
|
||||
|
||||
manga.copy(
|
||||
tags = doc.body().select(selectgenre).mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||
title = a.text().toTitleCase(),
|
||||
source = source,
|
||||
)
|
||||
},
|
||||
description = desc,
|
||||
altTitle = alt,
|
||||
state = state,
|
||||
chapters = chaptersDeferred.await(),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> {
|
||||
val root2 = doc.body().selectFirstOrThrow("div.panel-manga-chapter")
|
||||
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
|
||||
return root2.select(selectchapter).mapChapters(reversed = true) { i, li ->
|
||||
val a = li.selectFirst("a")
|
||||
val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing")
|
||||
val link = href + stylepage
|
||||
val dateText = li.selectFirst("a.c-new-tag")?.attr("title") ?: li.selectFirst(selectdate)?.text()
|
||||
val name = a.selectFirst("p")?.text() ?: a.ownText()
|
||||
MangaChapter(
|
||||
id = generateUid(href),
|
||||
name = name,
|
||||
number = i + 1,
|
||||
url = link,
|
||||
uploadDate = parseChapterDate(
|
||||
dateFormat,
|
||||
dateText,
|
||||
),
|
||||
source = source,
|
||||
scanlator = null,
|
||||
branch = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val fullUrl = chapter.url.toAbsoluteUrl(domain)
|
||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||
val root = doc.body().selectFirstOrThrow("div.read-manga").selectFirstOrThrow("div.read-content")
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import org.jsoup.nodes.Document
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
@MangaSourceParser("MANGADNA", "MangaDna", "en")
|
||||
internal class MangaDna(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANGADNA, "mangadna.com", 20) {
|
||||
|
||||
override val isNsfwSource = true
|
||||
override val datePattern = "dd MMM yyyy"
|
||||
override val withoutAjax = true
|
||||
override val selectdesc = "div.dsct"
|
||||
override val selectchapter = "li.a-h"
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> {
|
||||
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
append(domain)
|
||||
val pages = page + 1
|
||||
|
||||
when {
|
||||
!query.isNullOrEmpty() -> {
|
||||
append("/page/")
|
||||
append(pages.toString())
|
||||
append("/?s=")
|
||||
append(query.urlEncoded())
|
||||
append("&post_type=wp-manga&")
|
||||
}
|
||||
|
||||
!tags.isNullOrEmpty() -> {
|
||||
append("/$tagPrefix")
|
||||
for (tag in tags) {
|
||||
append(tag.key)
|
||||
}
|
||||
append("/page/")
|
||||
append(pages.toString())
|
||||
append("?")
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
||||
append("/$listeurl")
|
||||
append("/page/")
|
||||
append(pages.toString())
|
||||
append("?")
|
||||
}
|
||||
}
|
||||
append("m_orderby=")
|
||||
when (sortOrder) {
|
||||
SortOrder.POPULARITY -> append("views")
|
||||
SortOrder.UPDATED -> append("latest")
|
||||
SortOrder.NEWEST -> append("new-manga")
|
||||
SortOrder.ALPHABETICAL -> append("alphabet")
|
||||
else -> append("latest")
|
||||
}
|
||||
}
|
||||
val doc = webClient.httpGet(url).parseHtml()
|
||||
|
||||
|
||||
return doc.select("div.home-item").map { div ->
|
||||
val href = div.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found")
|
||||
val summary = div.selectFirst(".tab-summary") ?: div.selectFirst(".hcontent")
|
||||
Manga(
|
||||
id = generateUid(href),
|
||||
url = href,
|
||||
publicUrl = href.toAbsoluteUrl(div.host ?: domain),
|
||||
coverUrl = div.selectFirst("img")?.src().orEmpty(),
|
||||
title = (summary?.selectFirst("h3") ?: summary?.selectFirst("h4"))?.text().orEmpty(),
|
||||
altTitle = null,
|
||||
rating = div.selectFirst("div.hitem-rate span")?.ownText()?.toFloatOrNull()?.div(5f) ?: -1f,
|
||||
tags = summary?.selectFirst(".mg_genres")?.select("a")?.mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||
title = a.text().ifEmpty { return@mapNotNullToSet null }.toTitleCase(),
|
||||
source = source,
|
||||
)
|
||||
}.orEmpty(),
|
||||
author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
|
||||
state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()
|
||||
?.lowercase()) {
|
||||
in ongoing -> MangaState.ONGOING
|
||||
in finished -> MangaState.FINISHED
|
||||
else -> null
|
||||
},
|
||||
source = source,
|
||||
isNsfw = isNsfwSource,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
|
||||
val fullUrl = manga.url.toAbsoluteUrl(domain)
|
||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||
val body = doc.body()
|
||||
|
||||
val chaptersDeferred = async { getChapters(manga, doc) }
|
||||
|
||||
val desc = body.select(selectdesc).let {
|
||||
if (it.select("p").text().isNotEmpty()) {
|
||||
it.select("p").joinToString(separator = "\n\n") { p ->
|
||||
p.text().replace("<br>", "\n")
|
||||
}
|
||||
} else {
|
||||
it.text()
|
||||
}
|
||||
}
|
||||
|
||||
val stateDiv = (body.selectFirst("div.post-content_item:contains(Status)"))?.selectLast("div.summary-content")
|
||||
|
||||
val state = stateDiv?.let {
|
||||
when (it.text()) {
|
||||
in ongoing -> MangaState.ONGOING
|
||||
in finished -> MangaState.FINISHED
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
val alt =
|
||||
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
|
||||
?.trim() ?: doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content")
|
||||
.firstOrNull()?.tableValue()?.text()?.trim()
|
||||
|
||||
manga.copy(
|
||||
tags = doc.body().select(selectgenre).mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||
title = a.text().toTitleCase(),
|
||||
source = source,
|
||||
)
|
||||
},
|
||||
description = desc,
|
||||
altTitle = alt,
|
||||
state = state,
|
||||
chapters = chaptersDeferred.await(),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getChapters(manga: Manga, doc: Document): List<MangaChapter> {
|
||||
val root2 = doc.body().selectFirstOrThrow("div.panel-manga-chapter")
|
||||
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
|
||||
return root2.select(selectchapter).mapChapters(reversed = true) { i, li ->
|
||||
val a = li.selectFirst("a")
|
||||
val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing")
|
||||
val link = href + stylepage
|
||||
val dateText = li.selectFirst("a.c-new-tag")?.attr("title") ?: li.selectFirst(selectdate)?.text()
|
||||
val name = a.selectFirst("p")?.text() ?: a.ownText()
|
||||
MangaChapter(
|
||||
id = generateUid(href),
|
||||
name = name,
|
||||
number = i + 1,
|
||||
url = link,
|
||||
uploadDate = parseChapterDate(
|
||||
dateFormat,
|
||||
dateText,
|
||||
),
|
||||
source = source,
|
||||
scanlator = null,
|
||||
branch = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val fullUrl = chapter.url.toAbsoluteUrl(domain)
|
||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||
val root = doc.body().selectFirstOrThrow("div.read-manga").selectFirstOrThrow("div.read-content")
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("MANGAFASTNET", "Manga Fast Net", "en")
|
||||
internal class MangaFastNet(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANGAFASTNET, "manhuafast.net") {
|
||||
|
||||
override val withoutAjax = true
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("MANGAGOYAOI", "Mangagoyaoi", "en")
|
||||
internal class Mangagoyaoi(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANGAGOYAOI, "mangagoyaoi.com") {
|
||||
|
||||
override val isNsfwSource = true
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
|
||||
@MangaSourceParser("MANHWAZ", "Manhwaz", "en")
|
||||
internal class Manhwaz(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANHWAZ, "manhwaz.com", 40) {
|
||||
|
||||
override val listeurl = "genre/manhwa"
|
||||
override val tagPrefix = "genre/"
|
||||
override val withoutAjax = true
|
||||
override val selectTestAsync = "div.list-chapter"
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> {
|
||||
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
append(domain)
|
||||
val pages = page + 1
|
||||
|
||||
when {
|
||||
!query.isNullOrEmpty() -> {
|
||||
|
||||
append("/search?s=")
|
||||
append(query.urlEncoded())
|
||||
append("&page=")
|
||||
append(pages.toString())
|
||||
}
|
||||
|
||||
!tags.isNullOrEmpty() -> {
|
||||
append("/$tagPrefix")
|
||||
for (tag in tags) {
|
||||
append(tag.key)
|
||||
}
|
||||
append("?page=")
|
||||
append(pages.toString())
|
||||
append("&")
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
||||
append("/$listeurl")
|
||||
append("?page=")
|
||||
append(pages.toString())
|
||||
append("&")
|
||||
}
|
||||
}
|
||||
append("m_orderby=")
|
||||
when (sortOrder) {
|
||||
SortOrder.POPULARITY -> append("views")
|
||||
SortOrder.UPDATED -> append("latest")
|
||||
SortOrder.NEWEST -> append("new-manga")
|
||||
SortOrder.ALPHABETICAL -> append("alphabet")
|
||||
else -> append("latest")
|
||||
}
|
||||
}
|
||||
val doc = webClient.httpGet(url).parseHtml()
|
||||
|
||||
return doc.select("div.row.c-tabs-item__content").ifEmpty {
|
||||
doc.select("div.page-item-detail")
|
||||
}.map { div ->
|
||||
val href = div.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found")
|
||||
val summary = div.selectFirst(".tab-summary") ?: div.selectFirst(".item-summary")
|
||||
Manga(
|
||||
id = generateUid(href),
|
||||
url = href,
|
||||
publicUrl = href.toAbsoluteUrl(div.host ?: domain),
|
||||
coverUrl = div.selectFirst("img")?.src().orEmpty(),
|
||||
title = (summary?.selectFirst("h3") ?: summary?.selectFirst("h4"))?.text().orEmpty(),
|
||||
altTitle = null,
|
||||
rating = div.selectFirst("span.total_votes")?.ownText()?.toFloatOrNull()?.div(5f) ?: -1f,
|
||||
tags = summary?.selectFirst(".mg_genres")?.select("a")?.mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||
title = a.text().ifEmpty { return@mapNotNullToSet null }.toTitleCase(),
|
||||
source = source,
|
||||
)
|
||||
}.orEmpty(),
|
||||
author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
|
||||
state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()
|
||||
?.lowercase()) {
|
||||
in ongoing -> MangaState.ONGOING
|
||||
in finished -> MangaState.FINISHED
|
||||
else -> null
|
||||
},
|
||||
source = source,
|
||||
isNsfw = isNsfwSource,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("PARITEHABER", "Paritehaber", "en")
|
||||
internal class Paritehaber(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.PARITEHABER, "www.paritehaber.com", 10) {
|
||||
|
||||
override val isNsfwSource = true
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("RIO2MANGANET", "Rio2MangaNet", "en")
|
||||
internal class Rio2MangaNet(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.RIO2MANGANET, "rio2manga.net", 10)
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("SHIBAMANGA", "Shiba Manga", "en")
|
||||
internal class ShibaManga(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.SHIBAMANGA, "shibamanga.com") {
|
||||
|
||||
override val datePattern = "MM/dd/yyyy"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("WEBCOMIC", "WebComic", "en")
|
||||
internal class WebComic(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.WEBCOMIC, "webcomic.me") {
|
||||
|
||||
override val postreq = true
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.es
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
|
||||
@MangaSourceParser("COCORIP", "Cocorip", "es")
|
||||
internal class Cocorip(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.COCORIP, "cocorip.net", 16) {
|
||||
|
||||
override val datePattern = "dd/MM/yyyy"
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.es
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrlOrNull
|
||||
import org.koitharu.kotatsu.parsers.util.domain
|
||||
import org.koitharu.kotatsu.parsers.util.generateUid
|
||||
import org.koitharu.kotatsu.parsers.util.host
|
||||
import org.koitharu.kotatsu.parsers.util.parseFailed
|
||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||
import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl
|
||||
import org.koitharu.kotatsu.parsers.util.urlEncoded
|
||||
import java.util.EnumSet
|
||||
|
||||
@MangaSourceParser("DRAGONTRANSLATION", "DragonTranslation", "es")
|
||||
internal class DragonTranslationParser(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.DRAGONTRANSLATION, "dragontranslation.net", 30) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
)
|
||||
|
||||
override val selectPage = "div#chapter_imgs img"
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> {
|
||||
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
append(domain)
|
||||
val pages = page + 1
|
||||
|
||||
when {
|
||||
!query.isNullOrEmpty() -> {
|
||||
append("/mangas?buscar=")
|
||||
append(query.urlEncoded())
|
||||
append("&page=")
|
||||
append(pages.toString())
|
||||
}
|
||||
|
||||
!tags.isNullOrEmpty() -> {
|
||||
append("/mangas?tag=")
|
||||
for (tag in tags) {
|
||||
append(tag.key)
|
||||
}
|
||||
append("&page=")
|
||||
append(pages.toString())
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
||||
append("/mangas")
|
||||
append("?page=")
|
||||
append(pages.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
val doc = webClient.httpGet(url).parseHtml()
|
||||
|
||||
return doc.select("div.video-bg div.col-6 ").map { div ->
|
||||
val href =
|
||||
div.selectFirst("a.series-link")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found")
|
||||
Manga(
|
||||
id = generateUid(href),
|
||||
url = href,
|
||||
publicUrl = href.toAbsoluteUrl(div.host ?: domain),
|
||||
coverUrl = div.selectFirst("img.thumb-img")?.src().orEmpty(),
|
||||
title = div.selectFirst("div.series-box h5")?.text().orEmpty(),
|
||||
altTitle = null,
|
||||
rating = div.selectFirst("span.total_votes")?.ownText()?.toFloatOrNull()?.div(5f) ?: -1f,
|
||||
tags = emptySet(),
|
||||
author = null,
|
||||
state = null,
|
||||
source = source,
|
||||
isNsfw = isNsfwSource,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.es
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
|
||||
@MangaSourceParser("KOINOBORISCAN", "Koinobori Scan", "es")
|
||||
internal class KoinoboriScan(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.KOINOBORISCAN, "koinoboriscan.com") {
|
||||
|
||||
override val postreq = true
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.es
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
|
||||
@MangaSourceParser("LECTORUNITOON", "Lectorunitoon", "es")
|
||||
internal class Lectorunitoon(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.LECTORUNITOON, "lectorunitoon.com", 10) {
|
||||
|
||||
override val tagPrefix = "generos/"
|
||||
override val datePattern = "dd/MM/yyyy"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.es
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
|
||||
@MangaSourceParser("RIGHTDARKSCAN", "Rightdark Scan", "es")
|
||||
internal class RightdarkScan(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.RIGHTDARKSCAN, "rightdark-scan.com", 10)
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.es
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
|
||||
@MangaSourceParser("TRADUCCIONESMOONLIGHT", "Traducciones Moonlight", "es")
|
||||
internal class TraduccionesMoonlight(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.TRADUCCIONESMOONLIGHT, "traduccionesmoonlight.com") {
|
||||
|
||||
override val datePattern = "d MMMM, yyyy"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.id
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("INDO18H", "Indo18h", "id")
|
||||
internal class Indo18h(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.INDO18H, "indo18h.com", 24) {
|
||||
|
||||
override val isNsfwSource = true
|
||||
override val withoutAjax = true
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.id
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("MANHWAPLUS", "Manhwa Plus", "id")
|
||||
internal class ManhwaPlus(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANHWAPLUS, "manhwaplus.pro", 10) {
|
||||
|
||||
override val isNsfwSource = true
|
||||
override val tagPrefix = "genre/"
|
||||
override val datePattern = "MMMM d, yyyy"
|
||||
override val sourceLocale: Locale = Locale.ENGLISH
|
||||
override val withoutAjax = true
|
||||
override val listeurl = "series/"
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> {
|
||||
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
append(domain)
|
||||
val pages = page + 1
|
||||
|
||||
when {
|
||||
!query.isNullOrEmpty() -> {
|
||||
append("/page/")
|
||||
append(pages.toString())
|
||||
append("/?s=")
|
||||
append(query.urlEncoded())
|
||||
append("&post_type=wp-manga&")
|
||||
}
|
||||
|
||||
!tags.isNullOrEmpty() -> {
|
||||
append("/$tagPrefix")
|
||||
for (tag in tags) {
|
||||
append(tag.key)
|
||||
}
|
||||
append("/page/")
|
||||
append(pages.toString())
|
||||
append("?")
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
||||
append("/$listeurl")
|
||||
append("/page/")
|
||||
append(pages.toString())
|
||||
append("?")
|
||||
}
|
||||
}
|
||||
}
|
||||
val doc = webClient.httpGet(url).parseHtml()
|
||||
|
||||
return doc.select("div.row.c-tabs-item__content").ifEmpty {
|
||||
doc.select("div.page-item-detail")
|
||||
}.map { div ->
|
||||
val href = div.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found")
|
||||
val summary = div.selectFirst(".tab-summary") ?: div.selectFirst(".item-summary")
|
||||
Manga(
|
||||
id = generateUid(href),
|
||||
url = href,
|
||||
publicUrl = href.toAbsoluteUrl(div.host ?: domain),
|
||||
coverUrl = div.selectFirst("img")?.attr("data-wpfc-original-src") ?: div.selectFirst("img")?.src()
|
||||
.orEmpty(),
|
||||
title = (summary?.selectFirst("h3") ?: summary?.selectFirst("h4")
|
||||
?: div.selectFirst("h5.series-title"))?.text().orEmpty(),
|
||||
altTitle = null,
|
||||
rating = div.selectFirst("span.total_votes")?.ownText()?.toFloatOrNull()?.div(5f) ?: -1f,
|
||||
tags = summary?.selectFirst(".mg_genres")?.select("a")?.mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").removeSuffix('/').substringAfterLast('/'),
|
||||
title = a.text().ifEmpty { return@mapNotNullToSet null }.toTitleCase(),
|
||||
source = source,
|
||||
)
|
||||
}.orEmpty(),
|
||||
author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(),
|
||||
state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()
|
||||
?.lowercase()) {
|
||||
in ongoing -> MangaState.ONGOING
|
||||
in finished -> MangaState.FINISHED
|
||||
else -> null
|
||||
},
|
||||
source = source,
|
||||
isNsfw = isNsfwSource,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.ru
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
|
||||
@MangaSourceParser("MANGAZAVR", "Mangazavr", "ru")
|
||||
internal class Mangazavr(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANGAZAVR, "mangazavr.ru") {
|
||||
|
||||
override val datePattern = "dd.MM.yyyy"
|
||||
override val isNsfwSource = true
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("MANHUABUG", "Manhuabug", "th")
|
||||
internal class Manhuabug(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANHUABUG, "www.manhuabug.com", 10) {
|
||||
|
||||
override val datePattern: String = "d MMMM yyyy"
|
||||
override val sourceLocale: Locale = Locale.ENGLISH
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("MANHUAKEY", "Manhuakey", "th")
|
||||
internal class Manhuakey(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANHUAKEY, "www.manhuakey.com", 10) {
|
||||
|
||||
override val datePattern: String = "d MMMM yyyy"
|
||||
override val sourceLocale: Locale = Locale.ENGLISH
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.tr
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
|
||||
@MangaSourceParser("KUROIMANGA", "Kuroi Manga", "tr")
|
||||
internal class KuroiManga(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.KUROIMANGA, "www.kuroimanga.com") {
|
||||
|
||||
override val datePattern = "d MMMM yyyy"
|
||||
override val isNsfwSource = true
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.tr
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
|
||||
@MangaSourceParser("NIVERAFANSUB", "Nivera Fansub", "tr")
|
||||
internal class NiveraFansub(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.NIVERAFANSUB, "niverafansub.com") {
|
||||
|
||||
override val datePattern = "d MMMM yyyy"
|
||||
override val isNsfwSource = true
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.tr
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
|
||||
@MangaSourceParser("VIYAFANSUB", "Viya Fansub", "tr")
|
||||
internal class ViyaFansub(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.VIYAFANSUB, "viyafansub.com") {
|
||||
|
||||
override val datePattern = "d MMMM yyyy"
|
||||
override val isNsfwSource = true
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.vi
|
||||
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
|
||||
@MangaSourceParser("MANGAZODIAC", "Manga Zodiac", "vi")
|
||||
internal class MangaZodiac(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANGAZODIAC, "mangazodiac.com")
|
||||
@@ -29,6 +29,7 @@ import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl
|
||||
import org.koitharu.kotatsu.parsers.util.tryParse
|
||||
import org.koitharu.kotatsu.parsers.util.urlEncoded
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Base64
|
||||
import java.util.EnumSet
|
||||
import java.util.Locale
|
||||
|
||||
@@ -92,6 +93,7 @@ internal abstract class MangaReaderParser(
|
||||
tablemode.selectFirst(".infotable td:contains(Status)")
|
||||
?: tablemode.selectFirst(".infotable td:contains(Statut)")
|
||||
?: tablemode.selectFirst(".infotable td:contains(حالة العمل)")
|
||||
?: tablemode.selectFirst(".infotable td:contains(الحالة)")
|
||||
?: tablemode.selectFirst(".infotable td:contains(Estado)")
|
||||
?: docs.selectFirst(".infotable td:contains(สถานะ)")
|
||||
?: tablemode.selectFirst(".infotable td:contains(Stato )")
|
||||
@@ -103,7 +105,7 @@ internal abstract class MangaReaderParser(
|
||||
?: docs.selectFirst(".tsinfo div:contains(حالة العمل)") ?: docs.selectFirst(".tsinfo div:contains(Estado)")
|
||||
?: docs.selectFirst(".tsinfo div:contains(สถานะ)") ?: docs.selectFirst(".tsinfo div:contains(Stato )")
|
||||
?: docs.selectFirst(".tsinfo div:contains(Durum)") ?: docs.selectFirst(".tsinfo div:contains(Statüsü)")
|
||||
?: docs.selectFirst(".tsinfo div:contains(Statü)")
|
||||
?: docs.selectFirst(".tsinfo div:contains(Statü)") ?: docs.selectFirst(".tsinfo div:contains(الحالة)")
|
||||
}
|
||||
|
||||
val state = if (tablemode != null) {
|
||||
@@ -120,7 +122,7 @@ internal abstract class MangaReaderParser(
|
||||
"En cours \uD83D\uDFE2", "En cours de publication", "Đang tiến hành", "Em lançamento", "em lançamento", "Em Lançamento",
|
||||
"Онгоінг", "Publishing", "Devam Ediyor", "Em Andamento", "In Corso", "Güncel", "Berjalan", "Продолжается", "Updating",
|
||||
"Lançando", "In Arrivo", "Emision", "En emision", "مستمر", "Curso", "En marcha", "Publicandose", "Publicando", "连载中",
|
||||
"Devam ediyor",
|
||||
"Devam ediyor", "Devam Etmekte",
|
||||
-> MangaState.ONGOING
|
||||
|
||||
"Completed", "Completo", "Complété", "Fini", "Achevé", "Terminé", "Terminé ⚫", "Tamamlandı", "Đã hoàn thành", "Hoàn Thành", "مكتملة",
|
||||
@@ -204,8 +206,10 @@ internal abstract class MangaReaderParser(
|
||||
return parseMangaList(webClient.httpGet(url).parseHtml())
|
||||
}
|
||||
|
||||
protected open val selectMangaliste = ".postbody .listupd .bs .bsx"
|
||||
|
||||
protected open fun parseMangaList(docs: Document): List<Manga> {
|
||||
return docs.select(".postbody .listupd .bs .bsx").mapNotNull {
|
||||
return docs.select(selectMangaliste).mapNotNull {
|
||||
val a = it.selectFirst("a") ?: return@mapNotNull null
|
||||
val relativeUrl = a.attrAsRelativeUrl("href")
|
||||
val rating = it.selectFirst(".numscore")?.text()
|
||||
@@ -228,12 +232,15 @@ internal abstract class MangaReaderParser(
|
||||
}
|
||||
}
|
||||
|
||||
protected open val encodedSrc = false
|
||||
protected open val selectScript = "div.wrapper script"
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val chapterUrl = chapter.url.toAbsoluteUrl(domain)
|
||||
val docs = webClient.httpGet(chapterUrl).parseHtml()
|
||||
|
||||
val test = docs.select("script:containsData(ts_reader)")
|
||||
if (test.isNullOrEmpty()) {
|
||||
if (test.isNullOrEmpty() and !encodedSrc) {
|
||||
return docs.select("div#readerarea img").map { img ->
|
||||
val url = img.imageUrl()
|
||||
MangaPage(
|
||||
@@ -244,11 +251,32 @@ internal abstract class MangaReaderParser(
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val script = docs.selectFirstOrThrow("script:containsData(ts_reader)")
|
||||
val images = JSONObject(script.data().substringAfter('(').substringBeforeLast(')'))
|
||||
.getJSONArray("sources")
|
||||
.getJSONObject(0)
|
||||
.getJSONArray("images")
|
||||
val images = if (encodedSrc) {
|
||||
val script = docs.select(selectScript)
|
||||
var decode = ""
|
||||
for (i in script) {
|
||||
if (i.attr("src").startsWith("data:text/javascript;base64,")) {
|
||||
decode = Base64.getDecoder().decode(i.attr("src").replace("data:text/javascript;base64,", ""))
|
||||
.decodeToString()
|
||||
if (decode.startsWith("ts_reader.run")) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
JSONObject(decode.substringAfter('(').substringBeforeLast(')'))
|
||||
.getJSONArray("sources")
|
||||
.getJSONObject(0)
|
||||
.getJSONArray("images")
|
||||
|
||||
} else {
|
||||
val script = docs.selectFirstOrThrow("script:containsData(ts_reader)")
|
||||
JSONObject(script.data().substringAfter('(').substringBeforeLast(')'))
|
||||
.getJSONArray("sources")
|
||||
.getJSONObject(0)
|
||||
.getJSONArray("images")
|
||||
}
|
||||
|
||||
val pages = ArrayList<MangaPage>(images.length())
|
||||
for (i in 0 until images.length()) {
|
||||
pages.add(
|
||||
@@ -292,7 +320,7 @@ internal abstract class MangaReaderParser(
|
||||
return@withLock tagMap
|
||||
}
|
||||
|
||||
private fun Element.imageUrl(): String {
|
||||
protected open fun Element.imageUrl(): String {
|
||||
return attrAsAbsoluteUrlOrNull("src")
|
||||
?: attrAsAbsoluteUrlOrNull("data-src")
|
||||
?: attrAsAbsoluteUrlOrNull("data-cfsrc")
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.ar
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("AREASCANS", "Areascans", "ar")
|
||||
internal class Areascans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.AREASCANS, pageSize = 20, searchPageSize = 10) {
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("www.areascans.net")
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale("ar", "AR"))
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.ar
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("BEASTSCANS", "Beast Scans", "ar")
|
||||
internal class BeastScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.BEASTSCANS, pageSize = 20, searchPageSize = 10) {
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("beast-scans.com")
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale("ar", "AR"))
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
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.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrl
|
||||
import org.koitharu.kotatsu.parsers.util.domain
|
||||
import org.koitharu.kotatsu.parsers.util.generateUid
|
||||
import org.koitharu.kotatsu.parsers.util.mapChapters
|
||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||
import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl
|
||||
import org.koitharu.kotatsu.parsers.util.tryParse
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("BABELTOON", "BabelToon", "en")
|
||||
internal class BabelToon(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.BABELTOON, pageSize = 20, searchPageSize = 10) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("babeltoon.com")
|
||||
|
||||
override val listUrl = "/series"
|
||||
override val selectMangaliste = ".postbody .listupd .maindet .inmain"
|
||||
override val chapterDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH)
|
||||
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val docs = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||
val chapters = docs.select(".eplister > ul > li").mapChapters(reversed = true) { index, element ->
|
||||
val url = element.selectFirst("a")?.attrAsRelativeUrl("href") ?: return@mapChapters null
|
||||
MangaChapter(
|
||||
id = generateUid(url),
|
||||
name = element.selectFirst(".epl-num")?.text() ?: "Chapter ${index + 1}",
|
||||
url = url,
|
||||
number = index + 1,
|
||||
scanlator = null,
|
||||
uploadDate = chapterDateFormat.tryParse(element.selectFirst(".epl-date")?.text()),
|
||||
branch = null,
|
||||
source = source,
|
||||
)
|
||||
}
|
||||
return parseInfo(docs, manga, chapters)
|
||||
}
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val chapterUrl = chapter.url.toAbsoluteUrl(domain)
|
||||
val docs = webClient.httpGet(chapterUrl).parseHtml()
|
||||
|
||||
return docs.select("div.epcontent img").map { img ->
|
||||
val url = img.imageUrl()
|
||||
MangaPage(
|
||||
id = generateUid(url),
|
||||
url = url,
|
||||
preview = null,
|
||||
source = source,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
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.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("FREAKSCANS", "FreakScans", "en")
|
||||
internal class FreakScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.FREAKSCANS, pageSize = 20, searchPageSize = 20) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("freakscans.com")
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
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.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("QUEENSCANS", "QueenScans", "en")
|
||||
internal class QueenScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.QUEENSCANS, pageSize = 30, searchPageSize = 10) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("queenscans.com")
|
||||
|
||||
override val listUrl = "/comics"
|
||||
|
||||
}
|
||||
@@ -8,12 +8,13 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("DRAGONTRANSLATION", "DragonTranslation", "es")
|
||||
internal class DragonTranslationParser(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.DRAGONTRANSLATION, pageSize = 20, searchPageSize = 10) {
|
||||
@MangaSourceParser("SKYMANGAS", "Sky Mangas", "es")
|
||||
internal class SkyMangas(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.SKYMANGAS, pageSize = 20, searchPageSize = 10) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("dragontranslation.net")
|
||||
get() = ConfigKey.Domain("skymangas.com")
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH)
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale("es", "ES"))
|
||||
override val encodedSrc = true
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.id
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("DOUJINDESURIP", "Doujin Desu Rip", "id")
|
||||
internal class DoujinDesuRip(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.DOUJINDESURIP, pageSize = 10, searchPageSize = 10) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("doujindesu.rip")
|
||||
|
||||
override val isNsfwSource = true
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMM d, yyyy", Locale("in", "ID"))
|
||||
|
||||
}
|
||||
@@ -2,29 +2,12 @@ package org.koitharu.kotatsu.parsers.site.mangareader.id
|
||||
|
||||
import org.json.JSONObject
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.model.RATING_UNKNOWN
|
||||
import org.koitharu.kotatsu.parsers.model.WordSet
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import org.koitharu.kotatsu.parsers.util.attrAsAbsoluteUrl
|
||||
import org.koitharu.kotatsu.parsers.util.attrAsAbsoluteUrlOrNull
|
||||
import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrl
|
||||
import org.koitharu.kotatsu.parsers.util.domain
|
||||
import org.koitharu.kotatsu.parsers.util.generateUid
|
||||
import org.koitharu.kotatsu.parsers.util.mapChapters
|
||||
import org.koitharu.kotatsu.parsers.util.mapNotNullToSet
|
||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||
import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow
|
||||
import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl
|
||||
import org.koitharu.kotatsu.parsers.util.tryParse
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.text.DateFormat
|
||||
import java.util.Calendar
|
||||
|
||||
@@ -118,13 +101,6 @@ internal class Komikcast(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
private fun Element.imageUrl(): String {
|
||||
return attrAsAbsoluteUrlOrNull("src")
|
||||
?: attrAsAbsoluteUrlOrNull("data-src")
|
||||
?: attrAsAbsoluteUrlOrNull("data-cfsrc")
|
||||
?: ""
|
||||
}
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val chapterUrl = chapter.url.toAbsoluteUrl(domain)
|
||||
val docs = webClient.httpGet(chapterUrl).parseHtml()
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.id
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("KOMIKLOKALCFD", "Komiklokal Cfd", "id")
|
||||
internal class KomiklokalCfd(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.KOMIKLOKALCFD, pageSize = 30, searchPageSize = 10) {
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("komiklokal.cfd")
|
||||
|
||||
override val isNsfwSource = true
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH)
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.id
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("MANHWAINDOICU", "Manhwa Indo Icu", "id")
|
||||
internal class ManhwaIndoIcu(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.MANHWAINDOICU, pageSize = 30, searchPageSize = 10) {
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("manhwaindo.icu")
|
||||
|
||||
override val isNsfwSource = true
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH)
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.id
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("NONBIRI", "Nonbiri", "id")
|
||||
internal class Nonbiri(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.NONBIRI, pageSize = 15, searchPageSize = 10) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("nonbiri.space")
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMM d, yyyy", Locale("in", "ID"))
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.ja
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("MANGAMATE", "Manga Mate", "ja")
|
||||
internal class MangaMate(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.MANGAMATE, pageSize = 10, searchPageSize = 10) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("manga-mate.org")
|
||||
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("M月 d, yyyy", Locale.ENGLISH)
|
||||
override val encodedSrc = true
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.th
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("MANGAMOONS", "Manga Moons", "th")
|
||||
internal class MangaMoons(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.MANGAMOONS, pageSize = 20, searchPageSize = 10) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("manga-moons.net")
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale("th", "TH"))
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.tr
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("AFRODITSCANS", "Afrodit Scans", "tr")
|
||||
internal class AfroditScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.AFRODITSCANS, pageSize = 24, searchPageSize = 10) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("afroditscans.com")
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMM d, yyyy", Locale("tr"))
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.tr
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("ATHENAFANSUB", "AthenaFansub", "tr")
|
||||
internal class AthenaFansub(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.ATHENAFANSUB, pageSize = 20, searchPageSize = 10) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("athenafansub.com")
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale("tr", "TR"))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.tr
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("NYXMANGA", "Nyx Manga", "tr")
|
||||
internal class NyxManga(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.NYXMANGA, pageSize = 14, searchPageSize = 10) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("nyxmanga.com")
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale("tr", "TR"))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.tr
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("SPARTANMANGA", "Spartan Manga", "tr")
|
||||
internal class SpartanManga(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.SPARTANMANGA, pageSize = 40, searchPageSize = 20) {
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("spartanmanga.com.tr")
|
||||
|
||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale("tr", "TR"))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user