Fix ReaperComics close #816

close #699
Fix GuildaTierDraw close #786
Fix Truyenqq close #793
Fix JiangzaiToon close #783
Fix MangaPark close #734
Fix ScanIta close #670
Add MangaPeak close #888
Fix ArvenComics close #660
devi 2 years ago
parent cd468df9ad
commit 11c1eafa0d

@ -257,7 +257,7 @@ internal class MangaPark(context: MangaLoaderContext) :
.findAll(script) .findAll(script)
.mapNotNullTo(ArrayList()) { .mapNotNullTo(ArrayList()) {
val url = it.groupValues.getOrNull(1) ?: return@mapNotNullTo null val url = it.groupValues.getOrNull(1) ?: return@mapNotNullTo null
if (url.contains("/comic/") || url.contains("/manga/")) { if (url.contains("/comic/") || url.contains("/manga/") || url.contains("/image/mpup/")) {
MangaPage( MangaPage(
id = generateUid(url), id = generateUid(url),
url = url, url = url,

@ -35,9 +35,7 @@ internal class ReaperComics(context: MangaLoaderContext) :
override val configKeyDomain = ConfigKey.Domain("reaperscans.com") override val configKeyDomain = ConfigKey.Domain("reaperscans.com")
private val userAgentKey = ConfigKey.UserAgent( private val userAgentKey = ConfigKey.UserAgent(context.getDefaultUserAgent())
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
)
private val baseHeaders: Headers private val baseHeaders: Headers
get() = Headers.Builder().add("User-Agent", config[userAgentKey]).build() get() = Headers.Builder().add("User-Agent", config[userAgentKey]).build()
@ -171,7 +169,7 @@ internal class ReaperComics(context: MangaLoaderContext) :
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
val simpleDateFormat = SimpleDateFormat("dd/MM/yyyy", sourceLocale) val simpleDateFormat = SimpleDateFormat("dd/MM/yyyy", sourceLocale)
var totalChapters = (doc.selectFirst(selectTotalChapter)?.text()?.toIntOrNull() ?: 0) - 1 var totalChapters = (doc.selectFirst(selectTotalChapter)?.text()?.toFloatOrNull() ?: 0f) - 1f
val chapters = mutableSetOf<MangaChapter>() val chapters = mutableSetOf<MangaChapter>()
var hasNextPage = doc.selectFirst(chapterListNextPageSelector()) != null var hasNextPage = doc.selectFirst(chapterListNextPageSelector()) != null
chapters.addAll( chapters.addAll(
@ -182,6 +180,7 @@ internal class ReaperComics(context: MangaLoaderContext) :
id = generateUid(chapterUrl), id = generateUid(chapterUrl),
name = li.selectFirst("div.truncate p.truncate")?.text().orEmpty(), name = li.selectFirst("div.truncate p.truncate")?.text().orEmpty(),
number = totalChapters--, number = totalChapters--,
volume = 0,
url = chapterUrl, url = chapterUrl,
scanlator = null, scanlator = null,
uploadDate = parseChapterDate( uploadDate = parseChapterDate(
@ -256,6 +255,7 @@ internal class ReaperComics(context: MangaLoaderContext) :
id = generateUid(chapterUrl), id = generateUid(chapterUrl),
name = li.selectFirst("div.truncate p.truncate")?.text().orEmpty(), name = li.selectFirst("div.truncate p.truncate")?.text().orEmpty(),
number = totalChapters--, number = totalChapters--,
volume = 0,
url = chapterUrl, url = chapterUrl,
scanlator = null, scanlator = null,
uploadDate = parseChapterDate( uploadDate = parseChapterDate(

@ -6,5 +6,5 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("MANGALEK", "LekManga", "ar") @MangaSourceParser("MANGALEK", "LekManga", "ar")
internal class MangaLek(context: MangaLoaderContext) : internal class LekManga(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGALEK, "lekmanga.net", pageSize = 10) MadaraParser(context, MangaSource.MANGALEK, "lekmanga.net", pageSize = 10)

@ -6,5 +6,5 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("LIKEMANGANET", "Like-Manga.net", "ar") @MangaSourceParser("LIKEMANGANET", "Like-Manga.net", "ar")
internal class MangaLikeNet(context: MangaLoaderContext) : internal class LikeMangaNet(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.LIKEMANGANET, "like-manga.net", pageSize = 10) MadaraParser(context, MangaSource.LIKEMANGANET, "like-manga.net", pageSize = 10)

@ -0,0 +1,10 @@
package org.koitharu.kotatsu.parsers.site.madara.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.madara.MadaraParser
@MangaSourceParser("MANGAPEAK", "MangaPeak", "ar")
internal class MangaPeak(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGAPEAK, "mangapeak.org")

@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.*
@MangaSourceParser("ISEKAISCAN_EU", "IsekaiScan.to", "en") @MangaSourceParser("ISEKAISCAN_EU", "ParagonScans", "en")
internal class IsekaiScanEuParser(context: MangaLoaderContext) : internal class IsekaiScanEuParser(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.ISEKAISCAN_EU, "paragonscans.com") { MadaraParser(context, MangaSource.ISEKAISCAN_EU, "paragonscans.com") {

@ -1,10 +1,12 @@
package org.koitharu.kotatsu.parsers.site.madara.pt package org.koitharu.kotatsu.parsers.site.madara.pt
import org.koitharu.kotatsu.parsers.Broken
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@Broken
@MangaSourceParser("CERISE_SCANS", "CeriseScans", "pt") @MangaSourceParser("CERISE_SCANS", "CeriseScans", "pt")
internal class CeriseScans(context: MangaLoaderContext) : internal class CeriseScans(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.CERISE_SCANS, "cerisetoon.com") { MadaraParser(context, MangaSource.CERISE_SCANS, "cerisetoon.com") {

@ -11,4 +11,5 @@ internal class Manhuabug(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHUABUG, "www.manhuabug.com", 10) { MadaraParser(context, MangaSource.MANHUABUG, "www.manhuabug.com", 10) {
override val datePattern: String = "d MMMM yyyy" override val datePattern: String = "d MMMM yyyy"
override val sourceLocale: Locale = Locale.ENGLISH override val sourceLocale: Locale = Locale.ENGLISH
override val selectPage = "img"
} }

@ -11,4 +11,5 @@ internal class Manhuakey(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHUAKEY, "www.manhuakey.com", 10) { MadaraParser(context, MangaSource.MANHUAKEY, "www.manhuakey.com", 10) {
override val datePattern: String = "d MMMM yyyy" override val datePattern: String = "d MMMM yyyy"
override val sourceLocale: Locale = Locale.ENGLISH override val sourceLocale: Locale = Locale.ENGLISH
override val selectPage = "img"
} }

@ -8,6 +8,7 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("JIANGZAITOON", "JiangzaiToon", "tr", ContentType.HENTAI) @MangaSourceParser("JIANGZAITOON", "JiangzaiToon", "tr", ContentType.HENTAI)
internal class Jiangzaitoon(context: MangaLoaderContext) : internal class Jiangzaitoon(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.JIANGZAITOON, "jiangzaitoon.cc") { MadaraParser(context, MangaSource.JIANGZAITOON, "jiangzaitoon.dev") {
override val datePattern = "d MMMM yyyy" override val datePattern = "d MMMM yyyy"
override val postReq = true
} }

@ -0,0 +1,11 @@
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
//Images blocked by ReCAPTCHA
@MangaSourceParser("MERLINSCANS", "MerlinScans", "tr")
internal class MerlinScans(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MERLINSCANS, "merlinscans.com", 10)

@ -5,8 +5,8 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("ARVENSCANS", "ArvenScans", "en") @MangaSourceParser("ARVENSCANS", "ArvenComics", "en")
internal class ArvenScans(context: MangaLoaderContext) : internal class ArvenScans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.ARVENSCANS, "arvenscans.org", pageSize = 20, searchPageSize = 10) { MangaReaderParser(context, MangaSource.ARVENSCANS, "arvencomics.com", pageSize = 20, searchPageSize = 10) {
override val listUrl = "/series" override val listUrl = "/series"
} }

@ -1,5 +1,6 @@
package org.koitharu.kotatsu.parsers.site.mangareader.es package org.koitharu.kotatsu.parsers.site.mangareader.es
import org.koitharu.kotatsu.parsers.Broken
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.ContentType import org.koitharu.kotatsu.parsers.model.ContentType
@ -7,6 +8,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
import java.util.Locale import java.util.Locale
@Broken // Not dead, changed template
@MangaSourceParser("TENKAISCAN", "TenkaiScan", "es", ContentType.HENTAI) @MangaSourceParser("TENKAISCAN", "TenkaiScan", "es", ContentType.HENTAI)
internal class TenkaiScan(context: MangaLoaderContext) : internal class TenkaiScan(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.TENKAISCAN, "tenkaiscan.net", 20, 10) { MangaReaderParser(context, MangaSource.TENKAISCAN, "tenkaiscan.net", 20, 10) {

@ -1,10 +1,12 @@
package org.koitharu.kotatsu.parsers.site.mangareader.pt package org.koitharu.kotatsu.parsers.site.mangareader.pt
import org.koitharu.kotatsu.parsers.Broken
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@Broken
@MangaSourceParser("MANGASCHAN", "MangasChan", "pt") @MangaSourceParser("MANGASCHAN", "MangasChan", "pt")
internal class MangasChan(context: MangaLoaderContext) : internal class MangasChan(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MANGASCHAN, "mangaschan.net", pageSize = 20, searchPageSize = 20) { MangaReaderParser(context, MangaSource.MANGASCHAN, "mangaschan.net", pageSize = 20, searchPageSize = 20) {

@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("MANGAOKUTR", "MangaOku Tr", "tr") @MangaSourceParser("MANGAOKUTR", "MangaOkuTr", "tr")
internal class Mangaokutr(context: MangaLoaderContext) : internal class Mangaokutr(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MANGAOKUTR, "mangaokutr.com", pageSize = 25, searchPageSize = 20) MangaReaderParser(context, MangaSource.MANGAOKUTR, "mangaokutr.com", pageSize = 25, searchPageSize = 20)

@ -1,12 +0,0 @@
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.model.MangaSource
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("MERLINSCANS", "MerlinScans", "tr")
internal class MerlinScans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MERLINSCANS, "merlinscans.com", pageSize = 25, searchPageSize = 20) {
override val isTagsExclusionSupported = false
}

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

@ -1,10 +1,58 @@
package org.koitharu.kotatsu.parsers.site.scan.it package org.koitharu.kotatsu.parsers.site.scan.it
import kotlinx.coroutines.async
import org.jsoup.nodes.Document
import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.RATING_UNKNOWN
import org.koitharu.kotatsu.parsers.site.scan.ScanParser import org.koitharu.kotatsu.parsers.site.scan.ScanParser
import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat
import kotlinx.coroutines.coroutineScope
@MangaSourceParser("SCANITA", "ScanIta.org", "it") @MangaSourceParser("SCANITA", "ScanIta.org", "it")
internal class ScanIta(context: MangaLoaderContext) : internal class ScanIta(context: MangaLoaderContext) :
ScanParser(context, MangaSource.SCANITA, "scanita.org") ScanParser(context, MangaSource.SCANITA, "scanita.org") {
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
val tagMap = getOrCreateTagMap()
val selectTag = doc.select(".card-series-detail .col-6:contains(Categorie) div")
val tags = selectTag.mapNotNullToSet { tagMap[it.text()] }
val chaptersDeferred = async { loadChapters(doc) }
manga.copy(
rating = doc.selectFirst(".card-series-detail .rate-value span")?.ownText()?.toFloatOrNull()?.div(5f)
?: RATING_UNKNOWN,
tags = tags,
author = doc.selectFirst(".card-series-detail .col-6:contains(Autore) div")?.text(),
altTitle = doc.selectFirst(".card div.col-12.mb-4 h2")?.text().orEmpty(),
description = doc.selectFirst(".card div.col-12.mb-4 p")?.html().orEmpty(),
chapters = chaptersDeferred.await(),
)
}
private suspend fun loadChapters(document: Document): List<MangaChapter> {
val id = document.selectFirstOrThrow(".container-fluid button.w-100").attr("data-path")
.substringAfter("/manga/").substringBefore("/books")
val url = "https://$domain/manga/$id/books"
val doc = webClient.httpGet(url).parseHtml()
val dateFormat = SimpleDateFormat("MM-dd-yyyy", sourceLocale)
return doc.select(".chapters-list .col-chapter").mapChapters(reversed = true) { i, div ->
val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href")
MangaChapter(
id = generateUid(href),
name = div.selectFirstOrThrow("h5").html().substringBefore("<div").substringAfter("</span>"),
number = i + 1f,
volume = 0,
url = href,
scanlator = null,
uploadDate = dateFormat.tryParse(doc.selectFirstOrThrow("h5 div").text()),
branch = null,
source = source,
)
}
}
}

@ -17,7 +17,7 @@ internal class Truyenqq(context: MangaLoaderContext) : PagedMangaParser(context,
override val availableStates: Set<MangaState> = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED) override val availableStates: Set<MangaState> = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED)
override val configKeyDomain = ConfigKey.Domain("truyenqqvn.com") override val configKeyDomain = ConfigKey.Domain("truyenqqviet.com")
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> { override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {

@ -12,7 +12,7 @@ import org.koitharu.kotatsu.parsers.util.requireElementById
@MangaSourceParser("GUILDATIERDRAW", "GuildaTierDraw", "pt") @MangaSourceParser("GUILDATIERDRAW", "GuildaTierDraw", "pt")
internal class GuildaTierDraw(context: MangaLoaderContext) : internal class GuildaTierDraw(context: MangaLoaderContext) :
ZeistMangaParser(context, MangaSource.GUILDATIERDRAW, "www.guildatierdraw.com") { ZeistMangaParser(context, MangaSource.GUILDATIERDRAW, "www.guildatierdraw.top") {
override suspend fun getAvailableTags(): Set<MangaTag> { override suspend fun getAvailableTags(): Set<MangaTag> {
val doc = webClient.httpGet("https://$domain").parseHtml() val doc = webClient.httpGet("https://$domain").parseHtml()

Loading…
Cancel
Save