Merge pull request #217 from davvarrr/master
add source and fix
commit
506f6f7d30
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.all
|
||||||
|
|
||||||
import androidx.collection.ArraySet
|
import androidx.collection.ArraySet
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.all
|
||||||
|
|
||||||
import androidx.collection.ArraySet
|
import androidx.collection.ArraySet
|
||||||
import androidx.collection.SparseArrayCompat
|
import androidx.collection.SparseArrayCompat
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.all
|
||||||
|
|
||||||
import androidx.collection.SparseArrayCompat
|
import androidx.collection.SparseArrayCompat
|
||||||
import androidx.collection.set
|
import androidx.collection.set
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.all
|
||||||
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.all
|
||||||
|
|
||||||
import androidx.collection.ArraySet
|
import androidx.collection.ArraySet
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.all
|
||||||
|
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.be
|
||||||
|
|
||||||
import androidx.collection.ArraySet
|
import androidx.collection.ArraySet
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.en
|
||||||
|
|
||||||
import org.koitharu.kotatsu.parsers.InternalParsersApi
|
import org.koitharu.kotatsu.parsers.InternalParsersApi
|
||||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.en
|
||||||
|
|
||||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
import org.koitharu.kotatsu.parsers.MangaParser
|
import org.koitharu.kotatsu.parsers.MangaParser
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.en
|
||||||
|
|
||||||
import androidx.collection.ArrayMap
|
import androidx.collection.ArrayMap
|
||||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.es
|
||||||
|
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.fr
|
||||||
|
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.id
|
||||||
|
|
||||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site
|
package org.koitharu.kotatsu.parsers.site.ja
|
||||||
|
|
||||||
import org.koitharu.kotatsu.parsers.InternalParsersApi
|
import org.koitharu.kotatsu.parsers.InternalParsersApi
|
||||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
@ -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")
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
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.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||||
|
|
||||||
|
@MangaSourceParser("AREASCANS", "Areascans", "ar")
|
||||||
|
internal class Areascans(context: MangaLoaderContext) :
|
||||||
|
MangaReaderParser(context, MangaSource.AREASCANS, "www.areascans.net", pageSize = 20, searchPageSize = 10)
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
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.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||||
|
|
||||||
|
@MangaSourceParser("BEASTSCANS", "Beast Scans", "ar")
|
||||||
|
internal class BeastScans(context: MangaLoaderContext) :
|
||||||
|
MangaReaderParser(context, MangaSource.BEASTSCANS, "beast-scans.com", pageSize = 20, searchPageSize = 10)
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
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.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
|
||||||
|
|
||||||
|
@MangaSourceParser("BABELTOON", "BabelToon", "en")
|
||||||
|
internal class BabelToon(context: MangaLoaderContext) :
|
||||||
|
MangaReaderParser(context, MangaSource.BABELTOON, "babeltoon.com", pageSize = 20, searchPageSize = 10) {
|
||||||
|
|
||||||
|
override val listUrl = "/series"
|
||||||
|
override val selectMangaliste = ".postbody .listupd .maindet .inmain"
|
||||||
|
|
||||||
|
override suspend fun getDetails(manga: Manga): Manga {
|
||||||
|
val docs = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||||
|
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
|
||||||
|
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 = dateFormat.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,14 @@
|
|||||||
|
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("FREAKSCANS", "FreakScans", "en")
|
||||||
|
internal class FreakScans(context: MangaLoaderContext) :
|
||||||
|
MangaReaderParser(context, MangaSource.FREAKSCANS, "freakscans.com", pageSize = 20, searchPageSize = 20) {
|
||||||
|
|
||||||
|
override val datePattern = "MMM d, yyyy"
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
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("QUEENSCANS", "QueenScans", "en")
|
||||||
|
internal class QueenScans(context: MangaLoaderContext) :
|
||||||
|
MangaReaderParser(context, MangaSource.QUEENSCANS, "queenscans.com", pageSize = 30, searchPageSize = 10) {
|
||||||
|
|
||||||
|
override val listUrl = "/comics"
|
||||||
|
override val datePattern = "MMM d, yyyy"
|
||||||
|
}
|
||||||
@ -1,19 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.parsers.site.mangareader.es
|
|
||||||
|
|
||||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
|
||||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
|
||||||
import org.koitharu.kotatsu.parsers.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("DRAGONTRANSLATION", "DragonTranslation", "es")
|
|
||||||
internal class DragonTranslationParser(context: MangaLoaderContext) :
|
|
||||||
MangaReaderParser(context, MangaSource.DRAGONTRANSLATION, pageSize = 20, searchPageSize = 10) {
|
|
||||||
override val configKeyDomain: ConfigKey.Domain
|
|
||||||
get() = ConfigKey.Domain("dragontranslation.net")
|
|
||||||
|
|
||||||
override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH)
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package org.koitharu.kotatsu.parsers.site.mangareader.es
|
||||||
|
|
||||||
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
|
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||||
|
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||||
|
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||||
|
|
||||||
|
@MangaSourceParser("SKYMANGAS", "Sky Mangas", "es")
|
||||||
|
internal class SkyMangas(context: MangaLoaderContext) :
|
||||||
|
MangaReaderParser(context, MangaSource.SKYMANGAS, "skymangas.com", pageSize = 20, searchPageSize = 10) {
|
||||||
|
|
||||||
|
override val encodedSrc = true
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue