Add sources
This commit is contained in:
@@ -29,6 +29,7 @@ internal abstract class FmreaderParser(
|
||||
|
||||
protected open val listeurl = "/manga-list.html"
|
||||
protected open val datePattern = "MMMM d, yyyy"
|
||||
protected open val tagPrefix = "manga-list-genre-"
|
||||
|
||||
init {
|
||||
paginator.firstPage = 1
|
||||
@@ -39,11 +40,20 @@ internal abstract class FmreaderParser(
|
||||
protected val ongoing: Set<String> = setOf(
|
||||
"On going",
|
||||
"Incomplete",
|
||||
"En curso",
|
||||
)
|
||||
|
||||
@JvmField
|
||||
protected val finished: Set<String> = setOf(
|
||||
"Completed",
|
||||
"Completado",
|
||||
)
|
||||
|
||||
@JvmField
|
||||
protected val abandoned: Set<String> = hashSetOf(
|
||||
"Canceled",
|
||||
"Cancelled",
|
||||
"Drop",
|
||||
)
|
||||
|
||||
override suspend fun getListPage(
|
||||
@@ -106,7 +116,7 @@ internal abstract class FmreaderParser(
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listeurl").parseHtml()
|
||||
return doc.select(selectBodyTag).mapNotNullToSet { a ->
|
||||
val href = a.attr("href").substringAfter("manga-list-genre-").substringBeforeLast(".html")
|
||||
val href = a.attr("href").substringAfter(tagPrefix).substringBeforeLast(".html")
|
||||
MangaTag(
|
||||
key = href,
|
||||
title = a.text(),
|
||||
@@ -131,6 +141,7 @@ internal abstract class FmreaderParser(
|
||||
when (it.text()) {
|
||||
in ongoing -> MangaState.ONGOING
|
||||
in finished -> MangaState.FINISHED
|
||||
in abandoned -> MangaState.ABANDONED
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -140,7 +151,7 @@ internal abstract class FmreaderParser(
|
||||
manga.copy(
|
||||
tags = doc.body().select(selectTag).mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
key = a.attr("href").substringAfter("manga-list-genre-").substringBeforeLast(".html"),
|
||||
key = a.attr("href").substringAfter(tagPrefix).substringBeforeLast(".html"),
|
||||
title = a.text().toTitleCase(),
|
||||
source = source,
|
||||
)
|
||||
@@ -201,6 +212,7 @@ internal abstract class FmreaderParser(
|
||||
val d = date?.lowercase() ?: return 0
|
||||
return when {
|
||||
d.endsWith(" ago") ||
|
||||
d.endsWith(" atrás") ||
|
||||
// short Hours
|
||||
d.endsWith(" h") ||
|
||||
// short Day
|
||||
@@ -240,40 +252,44 @@ internal abstract class FmreaderParser(
|
||||
val number = Regex("""(\d+)""").find(date)?.value?.toIntOrNull() ?: return 0
|
||||
val cal = Calendar.getInstance()
|
||||
return when {
|
||||
WordSet(
|
||||
"day",
|
||||
"days",
|
||||
).anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis
|
||||
|
||||
WordSet("hour", "hours", "h").anyWordIn(date) -> cal.apply {
|
||||
add(
|
||||
Calendar.HOUR,
|
||||
-number,
|
||||
)
|
||||
}.timeInMillis
|
||||
|
||||
WordSet(
|
||||
"min",
|
||||
"minute",
|
||||
"minutes",
|
||||
).anyWordIn(date) -> cal.apply {
|
||||
WordSet("second").anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis
|
||||
WordSet("min", "minute", "minutes", "minuto", "minutos").anyWordIn(date) -> cal.apply {
|
||||
add(
|
||||
Calendar.MINUTE,
|
||||
-number,
|
||||
)
|
||||
}.timeInMillis
|
||||
|
||||
WordSet("second").anyWordIn(date) -> cal.apply {
|
||||
WordSet("hour", "hours", "hora", "horas", "h").anyWordIn(date) -> cal.apply {
|
||||
add(
|
||||
Calendar.SECOND,
|
||||
Calendar.HOUR,
|
||||
-number,
|
||||
)
|
||||
}.timeInMillis
|
||||
|
||||
WordSet("month", "months").anyWordIn(date) -> cal.apply { add(Calendar.MONTH, -number) }.timeInMillis
|
||||
WordSet("year").anyWordIn(date) -> cal.apply { add(Calendar.YEAR, -number) }.timeInMillis
|
||||
WordSet("day", "days", "día", "dia").anyWordIn(date) -> cal.apply {
|
||||
add(
|
||||
Calendar.DAY_OF_MONTH,
|
||||
-number,
|
||||
)
|
||||
}.timeInMillis
|
||||
|
||||
WordSet("week", "weeks", "semana", "semanas").anyWordIn(date) -> cal.apply {
|
||||
add(
|
||||
Calendar.WEEK_OF_YEAR,
|
||||
-number,
|
||||
)
|
||||
}.timeInMillis
|
||||
|
||||
WordSet("month", "months", "mes", "meses").anyWordIn(date) -> cal.apply {
|
||||
add(
|
||||
Calendar.MONTH,
|
||||
-number,
|
||||
)
|
||||
}.timeInMillis
|
||||
|
||||
WordSet("year", "año", "años").anyWordIn(date) -> cal.apply { add(Calendar.YEAR, -number) }.timeInMillis
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package org.koitharu.kotatsu.parsers.site.fmreader.es
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.site.fmreader.FmreaderParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
|
||||
@MangaSourceParser("OLIMPOSCANS", "Olimpo Scans", "es")
|
||||
internal class OlimpoScans(context: MangaLoaderContext) :
|
||||
FmreaderParser(context, MangaSource.OLIMPOSCANS, "olimposcans.com") {
|
||||
|
||||
override val selectState = "ul.manga-info li:contains(Estado) a"
|
||||
override val selectAlt = "ul.manga-info li:contains(Otros nombres)"
|
||||
override val selectTag = "ul.manga-info li:contains(Género) a"
|
||||
override val tagPrefix = "lista-de-comics-genero-"
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
tags: Set<MangaTag>?,
|
||||
sortOrder: SortOrder,
|
||||
): List<Manga> {
|
||||
val tag = tags.oneOrThrowIfMany()
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
append(domain)
|
||||
append(listeurl)
|
||||
append("?page=")
|
||||
append(page.toString())
|
||||
when {
|
||||
!query.isNullOrEmpty() -> {
|
||||
append("&name=")
|
||||
append(query.urlEncoded())
|
||||
}
|
||||
|
||||
!tags.isNullOrEmpty() -> {
|
||||
append("&genre=")
|
||||
append(tag?.key.orEmpty())
|
||||
}
|
||||
}
|
||||
append("&sort=")
|
||||
when (sortOrder) {
|
||||
SortOrder.POPULARITY -> append("views")
|
||||
SortOrder.UPDATED -> append("last_update")
|
||||
SortOrder.ALPHABETICAL -> append("name")
|
||||
else -> append("last_update")
|
||||
}
|
||||
}
|
||||
val doc = webClient.httpGet(url).parseHtml()
|
||||
val lastPage =
|
||||
doc.selectLast(".pagination a")?.attr("href")?.substringAfterLast("page=")?.substringBeforeLast("&artist")
|
||||
?.toInt() ?: 1
|
||||
if (lastPage < page) {
|
||||
return emptyList()
|
||||
}
|
||||
return doc.select("div.thumb-item-flow").map { div ->
|
||||
val href = "/" + div.selectFirstOrThrow("div.series-title a").attrAsRelativeUrl("href")
|
||||
Manga(
|
||||
id = generateUid(href),
|
||||
url = href,
|
||||
publicUrl = href.toAbsoluteUrl(div.host ?: domain),
|
||||
coverUrl = div.selectFirstOrThrow("div.img-in-ratio").attr("data-bg").toAbsoluteUrl(domain),
|
||||
title = div.selectFirstOrThrow("div.series-title").text().orEmpty(),
|
||||
altTitle = null,
|
||||
rating = RATING_UNKNOWN,
|
||||
tags = emptySet(),
|
||||
author = null,
|
||||
state = null,
|
||||
source = source,
|
||||
isNsfw = isNsfwSource,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val fullUrl = ("/" + chapter.url).toAbsoluteUrl(domain)
|
||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||
return doc.select(selectPage).map { img ->
|
||||
val url = ("/proxy.php?link=" + img.src()).toRelativeUrl(domain)
|
||||
MangaPage(
|
||||
id = generateUid(url),
|
||||
url = url,
|
||||
preview = null,
|
||||
source = source,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,12 @@ package org.koitharu.kotatsu.parsers.site.heancms.pt
|
||||
|
||||
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.heancms.HeanCms
|
||||
|
||||
@MangaSourceParser("REAPERSCANSPT", "Reaper Scans", "pt")
|
||||
internal class ReaperScansPt(context: MangaLoaderContext) :
|
||||
HeanCms(context, MangaSource.REAPERSCANSPT, "reaperscans.net")
|
||||
HeanCms(context, MangaSource.REAPERSCANSPT, "reaperscans.net") {
|
||||
override val configKeyDomain = ConfigKey.Domain("reaperscans.net", "reaperbr.online")
|
||||
}
|
||||
|
||||
@@ -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("MANGALEK_NET", "Manga Lek .Net", "ar")
|
||||
internal class MangaLekNet(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANGALEK_NET, "manga-lek.net", pageSize = 10)
|
||||
@@ -7,4 +7,4 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
|
||||
@MangaSourceParser("MANGALIONZ", "Manga Lionz", "ar")
|
||||
internal class MangaLionz(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.MANGALIONZ, "mangalionz.com", pageSize = 10)
|
||||
MadaraParser(context, MangaSource.MANGALIONZ, "mangalionz.org", pageSize = 10)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
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("GANZOSCAN", "Ganzo Scan", "es")
|
||||
internal class GanzoScan(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.GANZOSCAN, "ganzoscan.com") {
|
||||
override val datePattern: String = "dd 'de' MMMMM 'de' yyyy"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
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("FLOWERMANGA", "Flower Manga", "pt")
|
||||
internal class FlowerManga(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.FLOWERMANGA, "flowermanga.com", 24) {
|
||||
override val datePattern = "d MMMM yyyy"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
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("KAKUSEIPROJECT", "Kakusei Project", "pt")
|
||||
internal class KakuseiProject(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.KAKUSEIPROJECT, "kakuseiproject.com.br", 10)
|
||||
@@ -0,0 +1,12 @@
|
||||
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("SWEETSCAN", "Sweet Scan", "pt")
|
||||
internal class SweetScan(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.SWEETSCAN, "sweetscan.net") {
|
||||
override val datePattern: String = "dd 'de' MMMMM 'de' yyyy"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
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("CYPHERSCANS", "Cypher Scans", "en")
|
||||
internal class CypherScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.CYPHERSCANS, "cypherscans.xyz", pageSize = 20, searchPageSize = 10)
|
||||
@@ -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.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("WARUNGKOMIK", "Warung Komik", "id")
|
||||
internal class WarungKomik(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaSource.WARUNGKOMIK, "warungkomik.com", pageSize = 20, searchPageSize = 10)
|
||||
Reference in New Issue
Block a user