Rm duniakomik close #952
Fix DoujinKu close #951 Fix DoujinDesu.tv close Add, fix some sources #963 change url close #965 ( the copy was added anyway )master
parent
5f771973a8
commit
50194df24d
@ -1,10 +1,98 @@
|
||||
package org.koitharu.kotatsu.parsers.site.madara.es
|
||||
|
||||
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.exception.ParseException
|
||||
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.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.text.SimpleDateFormat
|
||||
|
||||
@MangaSourceParser("MANGASNOSEKAI", "MangasNoSekai", "es")
|
||||
internal class MangasNoSekai(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.MANGASNOSEKAI, "mangasnosekai.com")
|
||||
MadaraParser(context, MangaParserSource.MANGASNOSEKAI, "mangasnosekai.com") {
|
||||
|
||||
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 { loadChapters(manga.url, doc) }
|
||||
manga.copy(
|
||||
tags = doc.body().select("#section-sinopsis a[href*=genre]").mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
|
||||
title = a.text().toTitleCase(),
|
||||
source = source,
|
||||
)
|
||||
},
|
||||
author = doc.selectFirst("section#section-sinopsis div.d-flex:has(div:contains(Autor)) p a")?.text()
|
||||
.orEmpty(),
|
||||
description = body.selectFirst("#section-sinopsis p")?.text().orEmpty(),
|
||||
altTitle = doc.selectFirst("section#section-sinopsis div.d-flex:has(div:contains(Otros nombres)) p")?.text()
|
||||
.orEmpty(),
|
||||
state = body.selectFirst("section#section-sinopsis div.d-flex:has(div:contains(Estado)) p")
|
||||
?.let {
|
||||
when (it.text()) {
|
||||
in ongoing -> MangaState.ONGOING
|
||||
in finished -> MangaState.FINISHED
|
||||
in abandoned -> MangaState.ABANDONED
|
||||
in paused -> MangaState.PAUSED
|
||||
else -> null
|
||||
}
|
||||
},
|
||||
chapters = chaptersDeferred.await(),
|
||||
)
|
||||
}
|
||||
|
||||
// todo take other pages
|
||||
override suspend fun loadChapters(mangaUrl: String, document: Document): List<MangaChapter> {
|
||||
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
|
||||
return document.select("div.container-capitulos div.contenedor-capitulo-miniatura")
|
||||
.mapChapters(reversed = true) { i, div ->
|
||||
val a = div.selectFirst("a")
|
||||
val href = a?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link is missing")
|
||||
val link = href + stylePage
|
||||
val dateText = div.selectFirst("a div.chapter-text")?.text()
|
||||
val name = div.selectFirst("a div.text-sm")?.text() ?: a.ownText()
|
||||
MangaChapter(
|
||||
id = generateUid(href),
|
||||
url = link,
|
||||
name = name,
|
||||
number = i + 1f,
|
||||
volume = 0,
|
||||
branch = null,
|
||||
uploadDate = parseChapterDate(
|
||||
dateFormat,
|
||||
dateText,
|
||||
),
|
||||
scanlator = null,
|
||||
source = source,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val fullUrl = chapter.url.toAbsoluteUrl(domain)
|
||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||
val root = doc.body().selectFirst("div.reading-content")
|
||||
?: throw ParseException("No image found, try to log in", fullUrl)
|
||||
return root.select(selectPage).map { div ->
|
||||
val img = div.selectFirstOrThrow("img")
|
||||
val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found")
|
||||
MangaPage(
|
||||
id = generateUid(url),
|
||||
url = url,
|
||||
preview = null,
|
||||
source = source,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
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.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("LUMOSKOMIK", "LumosKomik", "id")
|
||||
internal class LumosKomik(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.LUMOSKOMIK, "lumoskomik.com") {
|
||||
override val tagPrefix = "genre/"
|
||||
override val listUrl = "komik/"
|
||||
override val datePattern = "dd MMMM yyyy"
|
||||
override val sourceLocale: Locale = Locale.ENGLISH
|
||||
}
|
||||
@ -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.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("LIMITEDTIMEPOJECT", "LimitedTimePoject", "pt")
|
||||
internal class LimitedTimePoject(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.LIMITEDTIMEPOJECT, "limitedtimeproject.com", 10) {
|
||||
override val listUrl = "manhwa/"
|
||||
override val tagPrefix = "manhwa-genero/"
|
||||
override val datePattern = "dd 'de' MMMMM 'de' yyyy"
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
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.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("MANGAOKUSANA", "MangaOkusana", "tr")
|
||||
internal class MangaOkusana(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.MANGAOKUSANA, "mangaokusana.com") {
|
||||
override val datePattern = "dd MMMM yyyy"
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("ALTAYSCANS", "AltayScans", "en")
|
||||
internal class AltayScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.ALTAYSCANS, "altayscans.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("LUACOMIC_COM", "luaComic.com", "en")
|
||||
internal class LuaComicCom(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.LUACOMIC_COM, "luacomic.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
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.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import java.util.Locale
|
||||
|
||||
@MangaSourceParser("KOMIKINDO_MOE", "KomikIndo.moe", "id")
|
||||
internal class KomikIndo(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.KOMIKINDO_MOE, "komikindo.moe", pageSize = 20, searchPageSize = 10) {
|
||||
override val sourceLocale: Locale = Locale.ENGLISH
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
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.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("MANHWAKU", "Manhwaku", "id")
|
||||
internal class Manhwaku(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.MANHWAKU, "manhwaku.id", pageSize = 20, searchPageSize = 10)
|
||||
@ -0,0 +1,13 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mangareader.pt
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("DEMONSECT", "DemonSect", "pt")
|
||||
internal class DemonSect(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.DEMONSECT, "dsectcomics.org", pageSize = 20, searchPageSize = 10) {
|
||||
override val listUrl = "/comics"
|
||||
override val isTagsExclusionSupported = false
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
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.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("CULTURESUBS", "CultureSubs", "tr")
|
||||
internal class CultureSubs(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.CULTURESUBS, "culturesubs.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val isMultipleTagsSupported = false
|
||||
}
|
||||
@ -1,14 +0,0 @@
|
||||
package org.koitharu.kotatsu.parsers.site.mmrcms.fr
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("MANGASCANFR", "MangaScanFr", "fr")
|
||||
internal class MangaScanFr(context: MangaLoaderContext) :
|
||||
MmrcmsParser(context, MangaParserSource.MANGASCANFR, "mangascan-fr.net") {
|
||||
override val sourceLocale: Locale = Locale.ENGLISH
|
||||
override val imgUpdated = ".jpg"
|
||||
}
|
||||
@ -0,0 +1,136 @@
|
||||
package org.koitharu.kotatsu.parsers.site.wpcomics.vi
|
||||
|
||||
import androidx.collection.ArrayMap
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.exception.NotFoundException
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
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.wpcomics.WpComicsParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.util.EnumSet
|
||||
|
||||
@MangaSourceParser("NETTRUYENSSR", "NetTruyenSSR", "vi")
|
||||
internal class NetTruyenSSR(context: MangaLoaderContext) :
|
||||
WpComicsParser(context, MangaParserSource.NETTRUYENSSR, "nettruyenssr.com", 20) {
|
||||
|
||||
override val isMultipleTagsSupported = true
|
||||
override val isTagsExclusionSupported = true
|
||||
override val listUrl = "/tim-kiem-nang-cao"
|
||||
override val availableStates: Set<MangaState> =
|
||||
EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.allOf(SortOrder::class.java)
|
||||
|
||||
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
|
||||
val response =
|
||||
when (filter) {
|
||||
is MangaListFilter.Search -> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
append(domain)
|
||||
append("/search")
|
||||
append('/')
|
||||
append(page.toString())
|
||||
append('/')
|
||||
append("?keyword=")
|
||||
append(filter.query.urlEncoded())
|
||||
}
|
||||
|
||||
val result = runCatchingCancellable { webClient.httpGet(url) }
|
||||
val exception = result.exceptionOrNull()
|
||||
if (exception is NotFoundException) {
|
||||
return emptyList()
|
||||
}
|
||||
result.getOrThrow()
|
||||
}
|
||||
|
||||
is MangaListFilter.Advanced -> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
append(domain)
|
||||
append(listUrl)
|
||||
|
||||
append('/')
|
||||
append(page.toString())
|
||||
append('/')
|
||||
|
||||
val tagQuery = filter.tags.joinToString(",") { it.key }
|
||||
append("?genres=")
|
||||
append(tagQuery)
|
||||
|
||||
val tagQueryExclude = filter.tagsExclude.joinToString(",") { it.key }
|
||||
append("¬Genres=")
|
||||
append(tagQueryExclude)
|
||||
|
||||
append("&sex=All")
|
||||
|
||||
filter.states.oneOrThrowIfMany()?.let {
|
||||
append("&status=")
|
||||
append(
|
||||
when (it) {
|
||||
MangaState.ONGOING -> "on-going"
|
||||
MangaState.FINISHED -> "completed"
|
||||
MangaState.PAUSED -> "on-hold"
|
||||
MangaState.ABANDONED -> "canceled"
|
||||
else -> "-1"
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
append("&chapter_count=0")
|
||||
|
||||
append("&sort=")
|
||||
append(
|
||||
when (filter.sortOrder) {
|
||||
SortOrder.UPDATED -> "latest-updated"
|
||||
SortOrder.POPULARITY -> "views"
|
||||
SortOrder.NEWEST -> "new"
|
||||
SortOrder.RATING -> "score"
|
||||
SortOrder.ALPHABETICAL -> "az"
|
||||
SortOrder.ALPHABETICAL_DESC -> "za"
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
webClient.httpGet(url)
|
||||
}
|
||||
|
||||
null -> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
append(domain)
|
||||
append(listUrl)
|
||||
append('/')
|
||||
append(page.toString())
|
||||
append('/')
|
||||
append("?genres=¬Genres=&sex=All&status=&chapter_count=0&sort=latest-updated")
|
||||
}
|
||||
webClient.httpGet(url)
|
||||
}
|
||||
}
|
||||
|
||||
val tagMap = getOrCreateTagMap()
|
||||
return parseMangaList(response.parseHtml(), tagMap)
|
||||
}
|
||||
|
||||
override suspend fun getOrCreateTagMap(): ArrayMap<String, MangaTag> = mutex.withLock {
|
||||
tagCache?.let { return@withLock it }
|
||||
val doc = webClient.httpGet(listUrl.toAbsoluteUrl(domain)).parseHtml()
|
||||
val tagItems = doc.select("div.genre-item")
|
||||
val result = ArrayMap<String, MangaTag>(tagItems.size)
|
||||
for (item in tagItems) {
|
||||
val title = item.text()
|
||||
val key = item.selectFirstOrThrow("span").attr("data-id")
|
||||
if (key.isNotEmpty() && title.isNotEmpty()) {
|
||||
result[title] = MangaTag(title = title, key = key, source = source)
|
||||
}
|
||||
}
|
||||
tagCache = result
|
||||
result
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package org.koitharu.kotatsu.parsers.site.zeistmanga.id
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser
|
||||
|
||||
|
||||
@MangaSourceParser("MAGERIN", "Magerin", "id")
|
||||
internal class Magerin(context: MangaLoaderContext) :
|
||||
ZeistMangaParser(context, MangaParserSource.MAGERIN, "www.magerin.com")
|
||||
Loading…
Reference in New Issue