Fix Chapters madtheme

Url NettruyenBing
Remove Dead Sources :
AkuManga , CmReader, FalconManga, JaiminisBox, Manga3s, MangaCv, MangaLeks, UniToonOficial , 1stKissManga.tv, Manhwa2read, ManhuaMix, ManhuaDex, Hwago, ImmortalUpdates, KomikSay, MangaTx, Scan-Fr.org, QueenScans, PhantomScans, OpScanlations, NeuManga.net, ManhwaFreak.fr, Lady Estelar Scan, KomikManhwa, KomikManga, KaratcamScans, Boosei, LyraScans, MangaDiyari, MangaPro, NHentai.uk, Oxapk, SpiderScans, MangaNelo.biz, MangaOnline.team, SpartanManga
pull/421/head
devi 2 years ago
parent a390e0de49
commit 327c05d03e

@ -1,88 +0,0 @@
package org.koitharu.kotatsu.parsers.site.galleryadults.all
import org.koitharu.kotatsu.parsers.ErrorMessages
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.galleryadults.GalleryAdultsParser
import org.koitharu.kotatsu.parsers.util.*
import java.util.*
@MangaSourceParser("NHENTAIUK", "NHentai.uk", type = ContentType.HENTAI)
internal class NHentaiUk(context: MangaLoaderContext) :
GalleryAdultsParser(context, MangaSource.NHENTAIUK, "nhentai.uk", pageSize = 50) {
override val selectGallery = ".gallery"
override val selectGalleryLink = "a"
override val selectGalleryTitle = ".caption"
override val pathTagUrl = "/tags/popular?p="
override val selectTags = "#tag-container"
override val selectTag = "div.tag-container:contains(Tags:) span.tags"
override val selectAuthor = "div.tag-container:contains(Artists:) a"
override val selectLanguageChapter = "div.tag-container:contains(Languages:) a"
override val idImg = "image-container"
override suspend fun getAvailableLocales(): Set<Locale> = setOf(
Locale.ENGLISH,
Locale.FRENCH,
Locale.JAPANESE,
Locale.CHINESE,
Locale("es"),
Locale("ru"),
Locale("ko"),
Locale.GERMAN,
Locale("pt"),
Locale.ITALIAN,
Locale("tr"),
)
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
val url = buildString {
append("https://")
append(domain)
when (filter) {
is MangaListFilter.Search -> {
throw IllegalArgumentException(ErrorMessages.SEARCH_NOT_SUPPORTED)
}
is MangaListFilter.Advanced -> {
when {
filter.locale != null && filter.tags.isNotEmpty() -> {
throw IllegalArgumentException(ErrorMessages.FILTER_BOTH_LOCALE_GENRES_NOT_SUPPORTED)
}
filter.locale != null -> {
append("/language")
append(filter.locale.toLanguagePath())
append("/?p=")
}
filter.tags.isNotEmpty() -> {
filter.tags.oneOrThrowIfMany()?.let {
append("/tag/")
append(it.key)
}
append("/?p=")
}
else -> {
append("/home?p=")
}
}
}
null -> append("/?")
}
append(page.toString())
}
return parseMangaList(webClient.httpGet(url).parseHtml())
}
override suspend fun getPageUrl(page: MangaPage): String {
val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml()
val root = doc.body()
return root.requireElementById(idImg).selectFirstOrThrow("img").src() ?: root.parseFailed("Image src not found")
}
}

@ -1,13 +0,0 @@
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
import java.util.Locale
@MangaSourceParser("AKUMANGA", "AkuManga", "ar")
internal class AkuManga(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.AKUMANGA, "akumanga.com") {
override val sourceLocale: Locale = Locale.ENGLISH
}

@ -1,12 +0,0 @@
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("FALCONMANGA", "FalconManga", "ar")
internal class FalconManga(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.FALCONMANGA, "falconmanga.com") {
override val datePattern = "d MMMM، yyyy"
}

@ -1,13 +0,0 @@
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("MANGALEKS", "MangaLeks", "ar")
internal class MangaLeks(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGALEKS, "mangaleks.com") {
override val datePattern = "yyyy/MM/dd"
override val postReq = true
}

@ -1,9 +0,0 @@
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("CM_READER", "CmReader", "en")
internal class CmReader(context: MangaLoaderContext) : MadaraParser(context, MangaSource.CM_READER, "cmreader.info")

@ -1,10 +0,0 @@
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("JAIMINISBOX", "JaiminisBox", "en")
internal class Jaiminisbox(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.JAIMINISBOX, "jaiminisbox.net")

@ -1,12 +0,0 @@
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("MANGA_3S", "Manga3s", "en")
internal class Manga3s(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGA_3S, "manga3s.com") {
override val tagPrefix = "manhwa-genre/"
override val datePattern = "MMMM dd, yyyy"
}

@ -1,12 +0,0 @@
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("MANGACV", "MangaCv", "en")
internal class MangaCv(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGACV, "mangacv.com", pageSize = 10) {
override val datePattern = "MMMM dd, yyyy"
}

@ -1,10 +0,0 @@
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("MANGA_ONLINE", "MangaOnline.team", "en")
internal class MangaOnline(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGA_ONLINE, "mangaonline.team", 18)

@ -1,12 +0,0 @@
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("MANGATX", "MangaTx", "en")
internal class MangaTx(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGATX, "mangatx.com") {
override val datePattern = "MMMM dd, yyyy"
}

@ -1,12 +0,0 @@
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("MANGANELO", "MangaNelo.biz", "en")
internal class Manganelo(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGANELO, "manganelo.biz", 10) {
override val postReq = true
}

@ -1,10 +0,0 @@
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("MANHUADEX", "ManhuaDex", "en")
internal class ManhuaDex(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHUADEX, "manhuadex.com")

@ -1,13 +0,0 @@
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("MANHUAMIX", "ManhuaMix", "en")
internal class Manhuamix(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHUAMIX, "manhuamix.com", 20) {
override val tagPrefix = "manhua-genre/"
override val listUrl = "manhua/"
}

@ -1,10 +0,0 @@
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("MANHWA2READ", "Manhwa2read", "en")
internal class Manhwa2Read(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANHWA2READ, "manhwa2read.com")

@ -1,12 +0,0 @@
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("STKISSMANGA_TV", "1stKissManga.tv", "en")
internal class StkissMangaTv(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.STKISSMANGA_TV, "1stkissmanga.tv", 20) {
override val postReq = true
}

@ -1,13 +0,0 @@
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("UNITOONOFICIAL", "UniToonOficial", "es")
internal class UniToonOficial(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.UNITOONOFICIAL, "unitoonoficial.com") {
override val datePattern = "dd/MM/yyyy"
override val tagPrefix = "generos/"
}

@ -1,14 +0,0 @@
package org.koitharu.kotatsu.parsers.site.madara.fr
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("KARATCAMSCANS", "KaratcamScans", "fr")
internal class KaratcamScans(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.KARATCAMSCANS, "karatcam-scans.fr") {
override val tagPrefix = "webtoon-genre/"
override val listUrl = "webtoon/"
override val datePattern = "dd/MM/yyyy"
}

@ -1,15 +0,0 @@
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
import java.util.Locale
@MangaSourceParser("HWAGO", "Hwago", "id")
internal class Hwago(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.HWAGO, "hwago.id", 10) {
override val listUrl = "komik/"
override val tagPrefix = "genre/"
override val sourceLocale: Locale = Locale.ENGLISH
}

@ -1,14 +0,0 @@
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
import java.util.Locale
@MangaSourceParser("IMMORTALUPDATESID", "ImmortalUpdates", "id")
internal class ImmortalUpdatesId(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.IMMORTALUPDATESID, "immortalupdates.id") {
override val datePattern = "d MMMM yyyy"
override val sourceLocale: Locale = Locale.ENGLISH
}

@ -1,16 +0,0 @@
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
import java.util.Locale
@MangaSourceParser("KOMIKSA", "KomikSay", "id")
internal class Komiksay(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.KOMIKSA, "komiksay.site") {
override val tagPrefix = "komik-genre/"
override val listUrl = "komik/"
override val datePattern = "MMMM d"
override val sourceLocale: Locale = Locale.ENGLISH
}

@ -1,12 +0,0 @@
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("LADYESTELARSCAN", "Lady Estelar Scan", "pt")
internal class LadyestelarScan(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.LADYESTELARSCAN, "ladyestelarscan.com.br", 10) {
override val datePattern: String = "dd/MM/yyyy"
}

@ -1,10 +0,0 @@
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("MANGADIYARI", "MangaDiyari", "tr")
internal class MangaDiyari(context: MangaLoaderContext) :
MadaraParser(context, MangaSource.MANGADIYARI, "manga-diyari.com", 10)

@ -197,7 +197,10 @@ internal abstract class MadthemeParser(
protected open suspend fun getChapters(doc: Document): List<MangaChapter> { protected open suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale) val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> val slug = doc.selectFirstOrThrow("script:containsData(bookSlug)").data().substringAfter("bookSlug = \"")
.substringBefore("\";")
val docChapter = webClient.httpGet("https://$domain/api/manga/$slug/chapters?source=detail").parseHtml()
return docChapter.select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a") val a = li.selectFirstOrThrow("a")
val href = a.attrAsRelativeUrl("href") val href = a.attrAsRelativeUrl("href")
val dateText = li.selectFirst(selectDate)?.text() val dateText = li.selectFirst(selectDate)?.text()

@ -1,22 +1,51 @@
package org.koitharu.kotatsu.parsers.site.madtheme.en package org.koitharu.kotatsu.parsers.site.madtheme.en
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.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaPage import org.koitharu.kotatsu.parsers.model.MangaPage
import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.madtheme.MadthemeParser import org.koitharu.kotatsu.parsers.site.madtheme.MadthemeParser
import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrl
import org.koitharu.kotatsu.parsers.util.domain import org.koitharu.kotatsu.parsers.util.domain
import org.koitharu.kotatsu.parsers.util.generateUid 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.parseHtml
import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow
import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl
import java.text.SimpleDateFormat
@MangaSourceParser("MANGAJINX", "MangaJinx", "en") @MangaSourceParser("MANGAJINX", "MangaJinx", "en")
internal class MangaJinx(context: MangaLoaderContext) : internal class MangaJinx(context: MangaLoaderContext) :
MadthemeParser(context, MangaSource.MANGAJINX, "mangajinx.com") { MadthemeParser(context, MangaSource.MANGAJINX, "mangajinx.com") {
override val listUrl = "search" override val listUrl = "search"
override suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
val id = doc.selectFirstOrThrow("script:containsData(bookId)").data().substringAfter("bookId = ")
.substringBefore(";")
val docChapter = webClient.httpGet("https://$domain/service/backend/chaplist/?manga_id=$id").parseHtml()
return docChapter.select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a")
val href = a.attrAsRelativeUrl("href")
val dateText = li.selectFirst(selectDate)?.text()
MangaChapter(
id = generateUid(href),
name = li.selectFirstOrThrow(".chapter-title").text(),
number = i + 1,
url = href,
uploadDate = parseChapterDate(
dateFormat,
dateText,
),
source = source,
scanlator = null,
branch = null,
)
}
}
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> { override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val chapterUrl = chapter.url.toAbsoluteUrl(domain) val chapterUrl = chapter.url.toAbsoluteUrl(domain)
val docs = webClient.httpGet(chapterUrl).parseHtml() val docs = webClient.httpGet(chapterUrl).parseHtml()

@ -1,10 +1,12 @@
package org.koitharu.kotatsu.parsers.site.madtheme.en package org.koitharu.kotatsu.parsers.site.madtheme.en
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.* import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.madtheme.MadthemeParser import org.koitharu.kotatsu.parsers.site.madtheme.MadthemeParser
import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat
import java.util.Locale import java.util.Locale
@MangaSourceParser("MANHUASCAN", "ManhuaScan.io", "en") @MangaSourceParser("MANHUASCAN", "ManhuaScan.io", "en")
@ -94,6 +96,31 @@ internal class ManhuaScan(context: MangaLoaderContext) :
} }
} }
override suspend fun getChapters(doc: Document): List<MangaChapter> {
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
val id = doc.selectFirstOrThrow("script:containsData(bookId)").data().substringAfter("bookId = ")
.substringBefore(";")
val docChapter = webClient.httpGet("https://$domain/service/backend/chaplist/?manga_id=$id").parseHtml()
return docChapter.select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirstOrThrow("a")
val href = a.attrAsRelativeUrl("href")
val dateText = li.selectFirst(selectDate)?.text()
MangaChapter(
id = generateUid(href),
name = li.selectFirstOrThrow(".chapter-title").text(),
number = i + 1,
url = href,
uploadDate = parseChapterDate(
dateFormat,
dateText,
),
source = source,
scanlator = null,
branch = null,
)
}
}
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> { override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val chapterUrl = chapter.url.toAbsoluteUrl(domain) val chapterUrl = chapter.url.toAbsoluteUrl(domain)
val docs = webClient.httpGet(chapterUrl).parseHtml() val docs = webClient.httpGet(chapterUrl).parseHtml()

@ -1,10 +0,0 @@
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("MANGAPROTM", "MangaPro", "ar")
internal class MangaProtm(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MANGAPROTM, "mangapro.co", pageSize = 20, searchPageSize = 20)

@ -1,89 +0,0 @@
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.Manga
import org.koitharu.kotatsu.parsers.model.MangaChapter
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.model.WordSet
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
import org.koitharu.kotatsu.parsers.util.*
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*
@MangaSourceParser("OXAPK", "Oxapk", "ar")
internal class Oxapk(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.OXAPK, "oxapk.com", pageSize = 24, searchPageSize = 10) {
override val sourceLocale: Locale = Locale.ENGLISH
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("#chapterlist > ul > li").mapChapters(reversed = true) { index, element ->
val url = element.selectFirst("a")?.attrAsRelativeUrl("href") ?: return@mapChapters null
MangaChapter(
id = generateUid(url),
name = docs.selectFirst("a.chapter-link-item")?.ownText().orEmpty(),
url = url,
number = index + 1,
scanlator = null,
uploadDate = parseChapterDate(
dateFormat,
element.selectFirst("div.chapter-link-time")?.text(),
),
branch = null,
source = source,
)
}
return parseInfo(docs, manga, chapters)
}
private fun parseChapterDate(dateFormat: DateFormat, date: String?): Long {
date ?: return 0
return when {
date.endsWith("منذ ", ignoreCase = true) -> {
parseRelativeDate(date)
}
else -> dateFormat.tryParse(date)
}
}
private fun parseRelativeDate(date: String): Long {
val number = Regex("""(\d+)""").find(date)?.value?.toIntOrNull() ?: return 0
val cal = Calendar.getInstance()
return when {
WordSet("أيام").anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -number) }.timeInMillis
WordSet("hour", "hours").anyWordIn(date) -> cal.apply {
add(
Calendar.HOUR,
-number,
)
}.timeInMillis
WordSet(
"mins",
).anyWordIn(date) -> cal.apply {
add(
Calendar.MINUTE,
-number,
)
}.timeInMillis
WordSet("second").anyWordIn(date) -> cal.apply {
add(
Calendar.SECOND,
-number,
)
}.timeInMillis
WordSet("أشهر").anyWordIn(date) -> cal.apply { add(Calendar.MONTH, -number) }.timeInMillis
WordSet("year").anyWordIn(date) -> cal.apply { add(Calendar.YEAR, -number) }.timeInMillis
else -> 0
}
}
}

@ -1,10 +0,0 @@
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("SPIDERSCANS", "SpiderScans", "ar")
internal class SpiderScans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.SPIDERSCANS, "spiderscans.com", pageSize = 20, searchPageSize = 10)

@ -1,13 +0,0 @@
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("EDOMAE", "Edomae", "en")
internal class Edomae(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.EDOMAE, "edomae.co", pageSize = 20, searchPageSize = 10) {
override val encodedSrc = true
override val selectScript = "#content script"
}

@ -1,10 +0,0 @@
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("LYRASCANS", "LyraScans", "en")
internal class LyraScans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.LYRASCANS, "lyrascans.com", pageSize = 20, searchPageSize = 10)

@ -1,10 +0,0 @@
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("OPSCANS", "OpScanlations", "en")
internal class OpScans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.OPSCANS, "opscanlations.com", pageSize = 20, searchPageSize = 10)

@ -1,12 +0,0 @@
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("PHANTOMSCANS", "PhantomScans", "en")
internal class Phantomscans(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.PHANTOMSCANS, "phantomscans.com", pageSize = 20, searchPageSize = 20) {
override val datePattern = "MMM d, yyyy"
}

@ -1,10 +0,0 @@
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, "fairymanga.com", pageSize = 20, searchPageSize = 10)

@ -1,215 +0,0 @@
package org.koitharu.kotatsu.parsers.site.mangareader.fr
import org.jsoup.nodes.Document
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
import org.koitharu.kotatsu.parsers.util.*
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
@MangaSourceParser("MANHWA_FREAK_FR", "ManhwaFreak.fr", "fr")
internal class ManhwaFreakFr(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.MANHWA_FREAK_FR, "manhwafreak.fr", pageSize = 0, searchPageSize = 10) {
override val selectMangaList = ".listupd .lastest-serie"
override val selectMangaListImg = "img"
override val sourceLocale: Locale = Locale.ENGLISH
override val availableStates: Set<MangaState> = emptySet()
override val isMultipleTagsSupported = false
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
val url = buildString {
append("https://")
append(domain)
when (filter) {
is MangaListFilter.Search -> {
append("/page/")
append(page.toString())
append("/?s=")
append(filter.query.urlEncoded())
}
is MangaListFilter.Advanced -> {
if (page > 1) {
return emptyList()
}
if (filter.tags.isNotEmpty()) {
filter.tags.oneOrThrowIfMany()?.let {
append("/genres/?genre=")
append(it.key)
}
} else {
append(listUrl)
append("/?order=")
append(
when (filter.sortOrder) {
SortOrder.ALPHABETICAL -> "az"
SortOrder.NEWEST -> "new"
SortOrder.POPULARITY -> "views"
SortOrder.UPDATED -> ""
else -> ""
},
)
}
}
null -> {
append(listUrl)
}
}
}
return parseMangaList(webClient.httpGet(url).parseHtml())
}
override suspend fun getAvailableTags(): Set<MangaTag> {
val doc = webClient.httpGet("https://$domain/genres/").parseHtml()
return doc.select("ul.genre-list li a").mapNotNullToSet { a ->
val href = a.attr("href").substringAfterLast("=")
MangaTag(
key = href,
title = a.text(),
source = source,
)
}
}
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("div.chapter-li a").mapChapters(reversed = true) { index, a ->
val url = a.attrAsRelativeUrl("href")
val dateText = a.selectFirst(".chapter-info p.new")?.text() ?: a.select(".chapter-info p")[1].text()
MangaChapter(
id = generateUid(url),
name = a.selectFirst(".chapter-info p:contains(Chapter)")?.text() ?: "Chapter ${index + 1}",
url = url,
number = index + 1,
scanlator = null,
uploadDate = if (dateText == "NEW") {
parseChapterDate(
dateFormat,
"today",
)
} else {
parseChapterDate(
dateFormat,
dateText,
)
},
branch = null,
source = source,
)
}
return parseInfo(docs, manga, chapters)
}
override suspend fun parseInfo(docs: Document, manga: Manga, chapters: List<MangaChapter>): Manga {
val tagMap = getOrCreateTagMap()
val selectTag = docs.requireElementById("info").select("div:contains(Genre) > p:last-child").text().split(",")
val tags = selectTag.mapNotNullToSet { tagMap[it] }
val mangaState = docs.requireElementById("info").select("div:contains(Status) > p:last-child").text().let {
when (it) {
"Ongoing" -> MangaState.ONGOING
"Completed" -> MangaState.FINISHED
else -> null
}
}
val author = docs.requireElementById("info").select("div:contains(Author(s)) > p:last-child").text()
return manga.copy(
altTitle = docs.requireElementById("info").select("div:contains(Alternative) > p:last-child").text(),
description = docs.requireElementById("summary").html(),
state = mangaState,
author = author,
isNsfw = manga.isNsfw,
tags = tags,
chapters = chapters,
)
}
private fun parseChapterDate(dateFormat: DateFormat, date: String?): Long {
// Clean date (e.g. 5th December 2019 to 5 December 2019) before parsing it
val d = date?.lowercase() ?: return 0
return when {
d.endsWith(" ago") -> parseRelativeDate(date)
// Handle 'yesterday' and 'today', using midnight
d.startsWith("year") -> Calendar.getInstance().apply {
add(Calendar.DAY_OF_MONTH, -1) // yesterday
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}.timeInMillis
d.startsWith("today") -> Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, 0)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
set(Calendar.MILLISECOND, 0)
}.timeInMillis
date.contains(Regex("""\d(st|nd|rd|th)""")) -> date.split(" ").map {
if (it.contains(Regex("""\d\D\D"""))) {
it.replace(Regex("""\D"""), "")
} else {
it
}
}.let { dateFormat.tryParse(it.joinToString(" ")) }
else -> dateFormat.tryParse(date)
}
}
// Parses dates in this form:
// 21 hours ago
private fun parseRelativeDate(date: String): Long {
val number = Regex("""(\d+)""").find(date)?.value?.toIntOrNull() ?: return 0
val cal = Calendar.getInstance()
return when {
WordSet(
"day",
"days",
"d",
).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(
"minute",
"minutes",
"mins",
).anyWordIn(date) -> cal.apply {
add(
Calendar.MINUTE,
-number,
)
}.timeInMillis
WordSet("second").anyWordIn(date) -> cal.apply {
add(
Calendar.SECOND,
-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
else -> 0
}
}
}

@ -1,12 +0,0 @@
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("BOOSEI", "Boosei", "id")
internal class Boosei(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.BOOSEI, "boosei.net", pageSize = 30, searchPageSize = 30) {
override val datePattern = "MMM d, yyyy"
}

@ -1,16 +0,0 @@
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
import java.util.*
@MangaSourceParser("KOMIKMANGA", "KomikManga", "id")
internal class KomikMangaParser(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.KOMIKMANGA, "komikhentai.co", pageSize = 20, searchPageSize = 10) {
override val listUrl = "/project"
override val datePattern = "MMM d, yyyy"
override val sourceLocale: Locale = Locale.ENGLISH
}

@ -1,14 +0,0 @@
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.ContentType
import org.koitharu.kotatsu.parsers.model.MangaSource
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
@MangaSourceParser("KOMIKMANHWA", "KomikManhwa", "id", ContentType.HENTAI)
internal class KomikManhwa(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.KOMIKMANHWA, "komikmanhwa.me", pageSize = 20, searchPageSize = 20) {
override val listUrl = "/series"
override val datePattern = "MMM d, yyyy"
}

@ -1,11 +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("SPARTANMANGA", "SpartanManga", "tr")
internal class SpartanManga(context: MangaLoaderContext) :
MangaReaderParser(context, MangaSource.SPARTANMANGA, "spartanmanga.com.tr", pageSize = 40, searchPageSize = 20)

@ -1,15 +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.MangaSource
import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser
import java.util.Locale
@MangaSourceParser("SCAN_FR_ORG", "Scan-Fr.org", "fr")
internal class ScanFrOrg(context: MangaLoaderContext) :
MmrcmsParser(context, MangaSource.SCAN_FR_ORG, "www.scan-fr.org") {
override val sourceLocale: Locale = Locale.ENGLISH
override val selectChapter = "ul.chapterszozo li"
}

@ -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.wpcomics.WpComicsParser import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser
@MangaSourceParser("NETTRUYENMAX", "NettruyenMax", "vi") @MangaSourceParser("NETTRUYENMAX", "NettruyenBing", "vi")
internal class Nettruyenmax(context: MangaLoaderContext) : internal class Nettruyenmax(context: MangaLoaderContext) :
WpComicsParser(context, MangaSource.NETTRUYENMAX, "www.nettruyenus.com", 36) WpComicsParser(context, MangaSource.NETTRUYENMAX, "www.nettruyenbing.com", 36)

@ -16,7 +16,7 @@ import java.text.SimpleDateFormat
@MangaSourceParser("MONZEEKOMIK", "MonzeeKomik", "id") @MangaSourceParser("MONZEEKOMIK", "MonzeeKomik", "id")
internal class MonzeeKomik(context: MangaLoaderContext) : internal class MonzeeKomik(context: MangaLoaderContext) :
ZeistMangaParser(context, MangaSource.MONZEEKOMIK, "www.monzeekomik.my.id"){ ZeistMangaParser(context, MangaSource.MONZEEKOMIK, "www.monzeekomik.my.id") {
override val selectPage = "article#reader img" override val selectPage = "article#reader img"
override suspend fun loadChapters(mangaUrl: String, doc: Document): List<MangaChapter> { override suspend fun loadChapters(mangaUrl: String, doc: Document): List<MangaChapter> {
@ -32,13 +32,12 @@ internal class MonzeeKomik(context: MangaLoaderContext) :
val feedClean = feedFind.removeSuffix(")") // clean val feedClean = feedFind.removeSuffix(")") // clean
val feed = if(feedClean == "Reincarnation Colosseum") // hot fix val feed = if (feedClean == "Reincarnation Colosseum") // hot fix
{ {
"I Have 90 Billion Licking Gold" "I Have 90 Billion Licking Gold"
}else } else {
{ feedClean
feedClean }
}
val url = buildString { val url = buildString {
append("https://") append("https://")

@ -1,10 +0,0 @@
package org.koitharu.kotatsu.parsers.site.zmanga.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.zmanga.ZMangaParser
@MangaSourceParser("NEU_MANGA", "NeuManga.net", "id")
internal class NeuManga(context: MangaLoaderContext) :
ZMangaParser(context, MangaSource.NEU_MANGA, "neumanga.net")
Loading…
Cancel
Save