New source: PrismaScans
parent
dd6de64c44
commit
7588617316
@ -0,0 +1,68 @@
|
|||||||
|
package org.koitharu.kotatsu.parsers.site.madara
|
||||||
|
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.coroutineScope
|
||||||
|
import org.jsoup.nodes.Element
|
||||||
|
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||||
|
import org.koitharu.kotatsu.parsers.model.*
|
||||||
|
import org.koitharu.kotatsu.parsers.util.*
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
internal abstract class Madara6Parser(
|
||||||
|
context: MangaLoaderContext,
|
||||||
|
source: MangaSource,
|
||||||
|
domain: String,
|
||||||
|
) : MadaraParser(context, source, domain) {
|
||||||
|
|
||||||
|
override suspend fun getDetails(manga: Manga): Manga {
|
||||||
|
return coroutineScope {
|
||||||
|
val chapters = async { loadChapters(manga.url) }
|
||||||
|
val body = context.httpGet(manga.url.toAbsoluteUrl(getDomain())).parseHtml().body()
|
||||||
|
parseDetails(manga, body, chapters.await())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun Element.tableValue(): Element {
|
||||||
|
for (p in parents()) {
|
||||||
|
val children = p.children()
|
||||||
|
if (children.size == 2) {
|
||||||
|
return children[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parseFailed("Cannot find tableValue for node ${text()}")
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun String.asMangaState(): MangaState?
|
||||||
|
|
||||||
|
protected fun Element.asMangaTag() = MangaTag(
|
||||||
|
title = ownText(),
|
||||||
|
key = attr("href").removeSuffix('/').substringAfterLast('/')
|
||||||
|
.replace('-', '+'),
|
||||||
|
source = source,
|
||||||
|
)
|
||||||
|
|
||||||
|
protected open suspend fun loadChapters(mangaUrl: String): List<MangaChapter> {
|
||||||
|
val url = mangaUrl.toAbsoluteUrl(getDomain()).removeSuffix('/') + "/ajax/chapters/"
|
||||||
|
val dateFormat = SimpleDateFormat("dd MMMM yyyy", sourceLocale ?: Locale.ROOT)
|
||||||
|
val doc = context.httpPost(url, emptyMap()).parseHtml()
|
||||||
|
return doc.select("li.wp-manga-chapter").asReversed().mapChapters { i, li ->
|
||||||
|
val a = li.selectFirstOrThrow("a")
|
||||||
|
val href = a.attrAsRelativeUrl("href")
|
||||||
|
MangaChapter(
|
||||||
|
id = generateUid(href),
|
||||||
|
url = href,
|
||||||
|
name = a.text(),
|
||||||
|
number = i + 1,
|
||||||
|
branch = null,
|
||||||
|
uploadDate = dateFormat.tryParse(
|
||||||
|
li.selectFirst(".chapter-release-date")?.text()?.trim(),
|
||||||
|
),
|
||||||
|
scanlator = null,
|
||||||
|
source = source,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract fun parseDetails(manga: Manga, body: Element, chapters: List<MangaChapter>): Manga
|
||||||
|
}
|
||||||
@ -0,0 +1,57 @@
|
|||||||
|
package org.koitharu.kotatsu.parsers.site.madara
|
||||||
|
|
||||||
|
import org.jsoup.nodes.Element
|
||||||
|
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.model.MangaState
|
||||||
|
import org.koitharu.kotatsu.parsers.util.attrAsAbsoluteUrlOrNull
|
||||||
|
import org.koitharu.kotatsu.parsers.util.mapToSet
|
||||||
|
import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@MangaSourceParser("PRISMA_SCANS", "Prisma Scans", "pt")
|
||||||
|
internal class PrismaScansParser(context: MangaLoaderContext) :
|
||||||
|
Madara6Parser(context, MangaSource.PRISMA_SCANS, "prismascans.net") {
|
||||||
|
|
||||||
|
override val tagPrefix = "manga-genre/"
|
||||||
|
|
||||||
|
override fun getFaviconUrl(): String {
|
||||||
|
return "https://${getDomain()}/wp-content/uploads/2022/07/cropped-branca-1-192x192.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun parseDetails(manga: Manga, body: Element, chapters: List<MangaChapter>): Manga {
|
||||||
|
val root = body.selectFirstOrThrow(".site-content")
|
||||||
|
val postContent = root.selectFirstOrThrow(".post-content")
|
||||||
|
val tags = postContent.getElementsContainingOwnText("Gênero")
|
||||||
|
.firstOrNull()?.tableValue()
|
||||||
|
?.getElementsByAttributeValueContaining("href", tagPrefix)
|
||||||
|
?.mapToSet { a -> a.asMangaTag() } ?: manga.tags
|
||||||
|
return manga.copy(
|
||||||
|
largeCoverUrl = root.selectFirst("picture")
|
||||||
|
?.selectFirst("img[data-src]")
|
||||||
|
?.attrAsAbsoluteUrlOrNull("data-src"),
|
||||||
|
description = root.selectFirstOrThrow(".description-summary").firstElementChild()?.html(),
|
||||||
|
author = postContent.getElementsContainingOwnText("Artista")
|
||||||
|
.firstOrNull()?.tableValue()?.text()?.trim(),
|
||||||
|
altTitle = postContent.getElementsContainingOwnText("Título Alternativo")
|
||||||
|
.firstOrNull()?.tableValue()?.text()?.trim(),
|
||||||
|
state = postContent.getElementsContainingOwnText("Status")
|
||||||
|
.firstOrNull()?.tableValue()?.text()?.asMangaState(),
|
||||||
|
tags = tags,
|
||||||
|
isNsfw = body.hasClass("adult-content"),
|
||||||
|
chapters = chapters,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun String.asMangaState() = when (trim().lowercase(sourceLocale ?: Locale.ROOT)) {
|
||||||
|
"em lançamento" -> MangaState.ONGOING
|
||||||
|
"completo",
|
||||||
|
"cancelado",
|
||||||
|
-> MangaState.FINISHED
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue