diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt index 49422e65..45c86648 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/config/ConfigKey.kt @@ -29,4 +29,9 @@ sealed class ConfigKey( class SplitByTranslations( override val defaultValue: Boolean, ) : ConfigKey("split_translations") + + class PreferredImageServer( + val presetValues: Map, + override val defaultValue: String?, + ) : ConfigKey("img_server") } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/BatoToParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/BatoToParser.kt index 3061b68c..49445d21 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/BatoToParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/BatoToParser.kt @@ -104,7 +104,12 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser( filter.locale?.let { append("&langs=") - append(it.language) + if (it.language == "in") { + append("id") + } else { + append(it.language) + } + } append("&genres=") @@ -318,7 +323,8 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser( return MangaChapter( id = generateUid(href), name = a.text(), - number = index + 1, + number = index + 1f, + volume = 0, url = href, scanlator = extra?.getElementsByAttributeValueContaining("href", "/group/")?.text(), uploadDate = runCatching { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt index c1687dc6..28e8956f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ExHentaiParser.kt @@ -212,7 +212,8 @@ internal class ExHentaiParser( chapters += MangaChapter( id = generateUid(url), name = "${manga.title} #$i", - number = i, + number = i.toFloat(), + volume = 0, url = url, uploadDate = 0L, source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/HitomiLaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/HitomiLaParser.kt index db06a5f2..f304474f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/HitomiLaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/HitomiLaParser.kt @@ -540,7 +540,8 @@ class HitomiLaParser(context: MangaLoaderContext) : MangaParser(context, MangaPa url = manga.url, name = json.getString("title"), scanlator = json.getString("type").toTitleCase(), - number = 1, + number = 1f, + volume = 0, branch = json.getString("language_localname"), source = source, uploadDate = dateFormat.tryParse(json.getString("date").substringBeforeLast("-")), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ImHentai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ImHentai.kt index d8ee6e19..262a3c93 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ImHentai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/ImHentai.kt @@ -130,7 +130,8 @@ internal class ImHentai(context: MangaLoaderContext) : MangaChapter( id = manga.id, name = manga.title, - number = 1, + number = 1f, + volume = 0, url = manga.url, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/LineWebtoonsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/LineWebtoonsParser.kt index 009f6913..c6818f09 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/LineWebtoonsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/LineWebtoonsParser.kt @@ -94,7 +94,8 @@ internal abstract class LineWebtoonsParser( MangaChapter( id = generateUid("$titleNo-$i"), name = jo.getString("episodeTitle"), - number = jo.getInt("episodeSeq"), + number = jo.getInt("episodeSeq").toFloat(), + volume = 0, url = "$titleNo-${jo.get("episodeNo")}", uploadDate = jo.getLong("modifyYmdt"), branch = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaDexParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaDexParser.kt index f6f5f78e..328e6c79 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaDexParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaDexParser.kt @@ -52,6 +52,7 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context is MangaListFilter.Search -> { append("&title=") append(filter.query) + append("&contentRating[]=safe&contentRating[]=suggestive&contentRating[]=erotica&contentRating[]=pornographic") } is MangaListFilter.Advanced -> { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt index f9e5188e..a41f31bc 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/MangaPark.kt @@ -193,7 +193,8 @@ internal class MangaPark(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, @@ -256,7 +257,7 @@ internal class MangaPark(context: MangaLoaderContext) : .findAll(script) .mapNotNullTo(ArrayList()) { 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( id = generateUid(url), url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineMangaParser.kt index 71a2f94a..c94d6ec8 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineMangaParser.kt @@ -145,7 +145,8 @@ internal abstract class NineMangaParser( MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDateByLang(li.selectFirst("span")?.text().orEmpty()), source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/WebtoonsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/WebtoonsParser.kt index 3e2ee9fb..6e7569a7 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/WebtoonsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/WebtoonsParser.kt @@ -86,7 +86,8 @@ internal abstract class WebtoonsParser( MangaChapter( id = generateUid("$titleNo-$i"), name = jo.getString("episodeTitle"), - number = jo.getInt("episodeSeq"), + number = jo.getInt("episodeSeq").toFloat(), + volume = 0, url = "$titleNo-${jo.get("episodeNo")}", uploadDate = jo.getLong("registerYmdt"), branch = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/AnimeBootstrapParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/AnimeBootstrapParser.kt index da5af8f5..b87818cc 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/AnimeBootstrapParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/AnimeBootstrapParser.kt @@ -146,7 +146,8 @@ internal abstract class AnimeBootstrapParser( MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = 0, source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/fr/PapScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/fr/PapScan.kt index 549961e3..edb06554 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/fr/PapScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/animebootstrap/fr/PapScan.kt @@ -3,6 +3,7 @@ package org.koitharu.kotatsu.parsers.site.animebootstrap.fr import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import org.jsoup.nodes.Document +import org.koitharu.kotatsu.parsers.Broken import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.* @@ -11,6 +12,7 @@ import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* +@Broken @MangaSourceParser("PAPSCAN", "PapScan", "fr") internal class PapScan(context: MangaLoaderContext) : AnimeBootstrapParser(context, MangaParserSource.PAPSCAN, "papscan.com") { @@ -125,7 +127,8 @@ internal class PapScan(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = li.selectFirstOrThrow("span em").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = dateFormat.tryParse(dateText), source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/FlixScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/FlixScans.kt index 2172f166..4d42eac2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/FlixScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/FlixScans.kt @@ -180,7 +180,8 @@ internal class FlixScans(context: MangaLoaderContext) : PagedMangaParser(context id = generateUid(url), url = url, name = j.getString("slug").replace('-', ' '), - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = dateFormat.tryParse(date), scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/MangaStorm.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/MangaStorm.kt index e64bccf8..83eb7d25 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/MangaStorm.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/MangaStorm.kt @@ -101,7 +101,8 @@ internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(contex MangaChapter( id = generateUid(url), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt index 67d38fda..add200e1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ar/TeamXNovel.kt @@ -31,7 +31,7 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex when (filter) { is MangaListFilter.Search -> { - append("/series?search=") + append("/?search=") append(filter.query.urlEncoded()) if (page > 1) { append("&page=") @@ -95,7 +95,7 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex publicUrl = href.toAbsoluteUrl(domain), rating = RATING_UNKNOWN, isNsfw = false, - coverUrl = div.selectFirstOrThrow("img").src().orEmpty(), + coverUrl = div.selectFirstOrThrow("img").src()?.replace("thumbnail_", "").orEmpty(), tags = emptySet(), state = when (div.selectFirst(".status")?.text()) { "مستمرة" -> MangaState.ONGOING @@ -183,7 +183,8 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex MangaChapter( id = generateUid(url), name = li.selectFirstOrThrow(".epl-title").text(), - number = url.substringAfterLast('/').toIntOrNull() ?: 0, + number = url.substringAfterLast('/').toFloatOrNull() ?: 0f, + volume = 0, url = url, scanlator = null, uploadDate = dateFormat.tryParse(li.selectFirstOrThrow(".epl-date").text()), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/be/AnibelParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/be/AnibelParser.kt index a10d1968..5f56e0cb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/be/AnibelParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/be/AnibelParser.kt @@ -144,7 +144,8 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context, MangaChapter( id = generateUid(jo.getString("id")), name = "Глава $number", - number = number, + number = number.toFloat(), + volume = 0, url = "${manga.url}/read/$number", scanlator = null, uploadDate = jo.getLong("released"), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/BeeToon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/BeeToon.kt index be87917a..2e3d84d2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/BeeToon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/BeeToon.kt @@ -109,7 +109,8 @@ internal class BeeToon(context: MangaLoaderContext) : MangaChapter( id = generateUid(url), name = a.selectFirstOrThrow(".chap").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = SimpleDateFormat("MM/dd/yyyy HH:mm:ss", Locale.ENGLISH) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/CloneMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/CloneMangaParser.kt index 62fe4255..246178f9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/CloneMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/CloneMangaParser.kt @@ -76,7 +76,8 @@ internal class CloneMangaParser(context: MangaLoaderContext) : MangaParser(conte val chapter = MangaChapter( id = generateUid("$series&page=$i"), name = "Chapter ${i + 1}", - number = i + 1, + number = i + 1f, + volume = 0, url = "$series&page=$i", scanlator = null, branch = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ComicExtra.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ComicExtra.kt index db2800c2..8d961b41 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ComicExtra.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ComicExtra.kt @@ -149,7 +149,8 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex MangaChapter( id = generateUid(url), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = dateFormat.tryParse(dateText), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/DynastyScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/DynastyScans.kt index b048041a..90d17742 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/DynastyScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/DynastyScans.kt @@ -182,7 +182,8 @@ internal class DynastyScans(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = dateFormat.tryParse(dateText), source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/FlixScansOrg.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/FlixScansOrg.kt index 0d7c8a7f..4854ca3f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/FlixScansOrg.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/FlixScansOrg.kt @@ -166,7 +166,8 @@ internal class FlixScansOrg(context: MangaLoaderContext) : id = generateUid(url), url = url, name = j.getString("slug").replace('-', ' '), - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = dateFormat.tryParse(date), scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaGeko.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaGeko.kt index caa672ad..80e41591 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaGeko.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaGeko.kt @@ -2,13 +2,11 @@ package org.koitharu.kotatsu.parsers.site.en import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope -import okhttp3.Headers import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* -import org.koitharu.kotatsu.parsers.network.UserAgents import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* @@ -23,9 +21,12 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context override val isMultipleTagsSupported = false - override val headers: Headers = Headers.Builder() - .add("User-Agent", UserAgents.CHROME_DESKTOP) - .build() + private val userAgentKey = ConfigKey.UserAgent(context.getDefaultUserAgent()) + + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(userAgentKey) + } override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { @@ -137,7 +138,8 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context MangaChapter( id = generateUid(url), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = dateFormat.tryParse(dateText), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaTownParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaTownParser.kt index c37692a4..837367a6 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaTownParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/MangaTownParser.kt @@ -160,7 +160,8 @@ internal class MangaTownParser(context: MangaLoaderContext) : id = generateUid(href), url = href, source = MangaParserSource.MANGATOWN, - number = i + 1, + number = i + 1f, + volume = 0, uploadDate = parseChapterDate( dateFormat, li.selectFirst("span.time")?.text(), @@ -176,10 +177,10 @@ internal class MangaTownParser(context: MangaLoaderContext) : override suspend fun getPages(chapter: MangaChapter): List { val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() - val root = doc.body().selectFirstOrThrow("div.page_select") - val isManga = root.select("select") + val root = doc.body().selectFirst("div.page_select") + val isManga = root?.select("select") - if (isManga.isEmpty()) {//Webtoon + if (isManga.isNullOrEmpty()) {//Webtoon val imgElements = doc.select("div#viewer.read_img img.image") return imgElements.map { val href = it.attr("src") @@ -256,7 +257,8 @@ internal class MangaTownParser(context: MangaLoaderContext) : id = generateUid(href), url = href, source = MangaParserSource.MANGATOWN, - number = i + 1, + number = i + 1f, + volume = 0, uploadDate = parseChapterDate( dateFormat, li.selectFirst("span.time")?.text(), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Mangaowl.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Mangaowl.kt index 84324dc4..ce84255e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Mangaowl.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Mangaowl.kt @@ -155,7 +155,8 @@ internal class Mangaowl(context: MangaLoaderContext) : MangaChapter( id = generateUid(url), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = url, uploadDate = dateFormat.tryParse(date), source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt index aba6aebb..d6936293 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Manhwa18Parser.kt @@ -161,7 +161,8 @@ class Manhwa18Parser(context: MangaLoaderContext) : MangaChapter( id = generateUid(chapterUrl), name = element.selectFirst(".chapter-name")?.text().orEmpty(), - number = index + 1, + number = index + 1f, + volume = 0, url = chapterUrl, scanlator = null, uploadDate = uploadDate, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ManhwasMen.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ManhwasMen.kt index f415e2d6..f9ff1cb4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ManhwasMen.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ManhwasMen.kt @@ -113,7 +113,8 @@ class ManhwasMen(context: MangaLoaderContext) : MangaChapter( id = generateUid(url), name = li.selectFirstOrThrow(".flex-grow-1 span").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = parseChapterDate( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Po2Scans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Po2Scans.kt index 22227825..cee1551e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Po2Scans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Po2Scans.kt @@ -76,7 +76,8 @@ internal class Po2Scans(context: MangaLoaderContext) : MangaParser(context, Mang MangaChapter( id = generateUid(url), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = dateFormat.tryParse(div.select(".detail span").last()?.text()), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Pururin.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Pururin.kt index 80b0e096..dd2c70b6 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Pururin.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/Pururin.kt @@ -126,7 +126,8 @@ internal class Pururin(context: MangaLoaderContext) : MangaChapter( id = manga.id, name = manga.title, - number = 1, + number = 1f, + volume = 0, url = manga.url, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ReaperComics.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ReaperComics.kt index e243d886..65f6887c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ReaperComics.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/ReaperComics.kt @@ -35,9 +35,7 @@ internal class ReaperComics(context: MangaLoaderContext) : override val configKeyDomain = ConfigKey.Domain("reaperscans.com") - private val userAgentKey = ConfigKey.UserAgent( - "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 userAgentKey = ConfigKey.UserAgent(context.getDefaultUserAgent()) private val baseHeaders: Headers 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 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() var hasNextPage = doc.selectFirst(chapterListNextPageSelector()) != null chapters.addAll( @@ -182,6 +180,7 @@ internal class ReaperComics(context: MangaLoaderContext) : id = generateUid(chapterUrl), name = li.selectFirst("div.truncate p.truncate")?.text().orEmpty(), number = totalChapters--, + volume = 0, url = chapterUrl, scanlator = null, uploadDate = parseChapterDate( @@ -256,6 +255,7 @@ internal class ReaperComics(context: MangaLoaderContext) : id = generateUid(chapterUrl), name = li.selectFirst("div.truncate p.truncate")?.text().orEmpty(), number = totalChapters--, + volume = 0, url = chapterUrl, scanlator = null, uploadDate = parseChapterDate( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt index a6f54689..ffe7be3a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TempleScanEsp.kt @@ -96,7 +96,8 @@ internal class TempleScanEsp(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = div.requireElementById("name").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = date, source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TuMangaOnlineParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TuMangaOnlineParser.kt index 8afd7df2..8be6f769 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TuMangaOnlineParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/es/TuMangaOnlineParser.kt @@ -147,7 +147,8 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser( return MangaChapter( id = generateUid(href), name = "One Shot", - number = 1, + number = 1f, + volume = 0, url = href, scanlator = element.select("div.col-md-6.text-truncate").text(), branch = null, @@ -163,7 +164,8 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser( return MangaChapter( id = generateUid(href), name = chName, - number = number + 1, + number = number + 1f, + volume = 0, url = href, scanlator = element.select("div.col-md-6.text-truncate").text(), branch = null, @@ -205,6 +207,9 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser( private suspend fun redirectToReadingPage(document: Document): Document { val script1 = document.selectFirst("script:containsData(uniqid)") val script2 = document.selectFirst("script:containsData(window.location.replace)") + val script3 = document.selectFirst("script:containsData(redirectUrl)") + val script4 = document.selectFirst("input#redir") + val script5 = document.selectFirst("script:containsData(window.opener):containsData(location.replace)") val redirectHeaders = Headers.Builder().set("Referer", document.baseUri()).build() @@ -226,15 +231,52 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser( if (script2 != null) { val data = script2.data() - val regexRedirect = """window\.location\.replace\('(.+)'\)""".toRegex() - val url = regexRedirect.find(data)!!.groupValues[1] + val regexRedirect = """window\.location\.replace\(['"](.+)['"]\)""".toRegex() + val url = regexRedirect.find(data)?.groupValues?.get(1)?.unescapeUrl() + + if (url != null) { + return redirectToReadingPage(webClient.httpGet(url, redirectHeaders).parseHtml()) + } + } + + if (script3 != null) { + val data = script3.data() + val regexRedirect = """redirectUrl\s*=\s*'(.+)'""".toRegex() + val url = regexRedirect.find(data)?.groupValues?.get(1)?.unescapeUrl() + + if (url != null) { + return redirectToReadingPage(webClient.httpGet(url, redirectHeaders).parseHtml()) + } + } + + if (script4 != null) { + val url = script4.attr("value").unescapeUrl() return redirectToReadingPage(webClient.httpGet(url, redirectHeaders).parseHtml()) } + if (script5 != null) { + val data = script5.data() + val regexRedirect = """;[^.]location\.replace\(['"](.+)['"]\)""".toRegex() + val url = regexRedirect.find(data)?.groupValues?.get(1)?.unescapeUrl() + + if (url != null) { + return redirectToReadingPage(webClient.httpGet(url, redirectHeaders).parseHtml()) + } + } + return document } + private fun String.unescapeUrl(): String { + return if (this.startsWith("http:\\/\\/") || this.startsWith("https:\\/\\/")) { + this.replace("\\/", "/") + } else { + this + } + } + + override suspend fun getAvailableTags(): Set { val doc = webClient.httpGet("https://$domain/library", headers).parseHtml() val elements = doc.body().select("div#books-genders > div > div") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt index c67362e4..b2a1b72d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/FmreaderParser.kt @@ -203,7 +203,8 @@ internal abstract class FmreaderParser( MangaChapter( id = generateUid(href), name = a.selectFirstOrThrow("div.chapter-name").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/en/Manhwa18Com.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/en/Manhwa18Com.kt index 8d3f2573..d6044a8c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/en/Manhwa18Com.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/en/Manhwa18Com.kt @@ -125,7 +125,8 @@ internal class Manhwa18Com(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = a.selectFirstOrThrow("div.chapter-name").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/Klz9.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/Klz9.kt index b878f99b..39892edb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/Klz9.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/Klz9.kt @@ -66,7 +66,8 @@ internal class Klz9(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = a.selectFirstOrThrow("a").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/WeLoveManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/WeLoveManga.kt index 75bc8827..86bdc064 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/WeLoveManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fmreader/ja/WeLoveManga.kt @@ -25,7 +25,8 @@ internal class WeLoveManga(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = a.selectFirstOrThrow("a").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/FoolSlideParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/FoolSlideParser.kt index 58077452..25e59e41 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/FoolSlideParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/FoolSlideParser.kt @@ -155,7 +155,8 @@ internal abstract class FoolSlideParser( MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = if (div.selectFirstOrThrow(selectDate).text().contains(", ")) { dateFormat.tryParse(dateText) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/fr/HniScantrad.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/fr/HniScantrad.kt index 6d46ab3d..0eae608d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/fr/HniScantrad.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/fr/HniScantrad.kt @@ -5,9 +5,11 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.foolslide.FoolSlideParser +// The source has changed template so for the moment it is dead. @MangaSourceParser("HNISCANTRAD", "HniScantrad", "fr") internal class HniScantrad(context: MangaLoaderContext) : - FoolSlideParser(context, MangaParserSource.HNISCANTRAD, "hni-scantrad.com") { + FoolSlideParser(context, MangaParserSource.HNISCANTRAD, "hni-scantrad.net") { + override val pagination = false override val searchUrl = "lel/search/" override val listUrl = "lel/directory/" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/it/PowerManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/it/PowerManga.kt index ad0eceb4..eeca13a3 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/it/PowerManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/foolslide/it/PowerManga.kt @@ -1,10 +1,12 @@ package org.koitharu.kotatsu.parsers.site.foolslide.it +import org.koitharu.kotatsu.parsers.Broken 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.foolslide.FoolSlideParser +@Broken @MangaSourceParser("POWERMANGA", "PowerManga", "it") internal class PowerManga(context: MangaLoaderContext) : FoolSlideParser(context, MangaParserSource.POWERMANGA, "reader.powermanga.org") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt index 7b014d30..45104ff8 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt @@ -5,6 +5,7 @@ import kotlinx.coroutines.awaitAll import kotlinx.coroutines.coroutineScope import okhttp3.Headers import org.jsoup.nodes.Element +import org.koitharu.kotatsu.parsers.Broken import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser @@ -15,6 +16,7 @@ import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.json.getIntOrDefault import java.util.* +@Broken @MangaSourceParser("BENTOMANGA", "BentoManga", "fr") internal class BentomangaParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.BENTOMANGA, 10) { @@ -227,7 +229,8 @@ internal class BentomangaParser(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = if (name != null && name != title) "$title: $name" else title, - number = href.substringAfterLast('/').toIntOrNull() ?: 0, + number = href.substringAfterLast('/').toFloatOrNull() ?: 0f, + volume = 0, url = href, scanlator = div.selectFirst(".team_link-name")?.textOrNull(), uploadDate = div.selectFirst(".component-chapter-date") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt index bd3e3952..9f5ce683 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/FuryoSociety.kt @@ -109,7 +109,8 @@ internal class FuryoSociety(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = div.selectFirstOrThrow("div.title").text() + " : " + div.selectFirstOrThrow("div.name").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LegacyScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LegacyScansParser.kt index 2f454b4d..165c6637 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LegacyScansParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LegacyScansParser.kt @@ -144,7 +144,8 @@ internal class LegacyScansParser(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, uploadDate = dateFormat.tryParse(dateText), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LireScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LireScan.kt index 05519a51..09c51c23 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LireScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LireScan.kt @@ -113,7 +113,8 @@ internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context, MangaChapter( id = generateUid(href), name = name, - number = i, + number = i.toFloat(), + volume = 0, url = href, scanlator = null, uploadDate = dateFormat.tryParse(dateText), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt index 44972956..5df1d608 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/LugnicaScans.kt @@ -183,7 +183,8 @@ internal class LugnicaScans(context: MangaLoaderContext) : MangaChapter( id = generateUid(url), name = "Chapitre : $id", - number = i, + number = i.toFloat(), + volume = 0, url = url, scanlator = null, uploadDate = dateFormat.tryParse(date), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScansMangasMe.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScansMangasMe.kt index 63e72ff5..6f106e34 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScansMangasMe.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScansMangasMe.kt @@ -107,11 +107,6 @@ internal class ScansMangasMe(context: MangaLoaderContext) : val doc = webClient.httpGet(fullUrl).parseHtml() val chaptersDeferred = getChapters(doc) val desc = doc.selectFirstOrThrow("div.desc").html() - val state = if (doc.select("div.spe span:contains(En cours)").isNullOrEmpty()) { - MangaState.FINISHED - } else { - MangaState.ONGOING - } val alt = doc.body().select("div.infox span.alter").text() val aut = doc.select("div.spe span")[2].text().replace("Auteur:", "") manga.copy( @@ -125,20 +120,26 @@ internal class ScansMangasMe(context: MangaLoaderContext) : description = desc, altTitle = alt, author = aut, - state = state, + state = when (doc.selectFirstOrThrow("div.spe span:contains(Statut:)").textOrNull() + ?.substringAfterLast(':')) { + " En cours" -> MangaState.ONGOING + " Terminé" -> MangaState.FINISHED + else -> null + }, chapters = chaptersDeferred, isNsfw = manga.isNsfw, ) } private fun getChapters(doc: Document): List { - return doc.body().requireElementById("chapter_list").select("li").mapChapters(reversed = true) { i, li -> + return doc.body().requireElementById("chapter_list").select("li").mapChapters(reversed = true) { _, li -> val a = li.selectFirstOrThrow("a") val href = a.attrAsRelativeUrl("href") MangaChapter( id = generateUid(href), name = li.selectFirstOrThrow("span.mobile chapter").text(), - number = i + 1, + number = li.selectFirstOrThrow("span.mobile chapter").text().substringAfterLast(" ").toFloat(), + volume = 0, url = href, uploadDate = 0, source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt index 181a6aa5..f46b20eb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/ScantradUnion.kt @@ -152,7 +152,8 @@ internal class ScantradUnion(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i, + number = i.toFloat(), + volume = 0, url = href, scanlator = null, uploadDate = dateFormat.tryParse(date), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt index 9293e0ae..a9e23f6c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt @@ -158,7 +158,8 @@ internal abstract class GalleryAdultsParser( MangaChapter( id = manga.id, name = manga.title, - number = 1, + number = 1f, + volume = 0, url = urlChapters, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/HentaiEra.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/HentaiEra.kt index 362ed0ff..af2565c5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/HentaiEra.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/HentaiEra.kt @@ -131,7 +131,8 @@ internal class HentaiEra(context: MangaLoaderContext) : MangaChapter( id = manga.id, name = manga.title, - number = 1, + number = 1f, + volume = 0, url = urlChapters, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt index 253eb4cc..9fb5d11a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt @@ -115,7 +115,8 @@ internal abstract class GattsuParser( MangaChapter( id = manga.id, name = manga.title, - number = 1, + number = 1f, + volume = 0, url = urlChapter, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/guya/GuyaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/guya/GuyaParser.kt index 7ed61e87..9a4943d2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/guya/GuyaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/guya/GuyaParser.kt @@ -91,7 +91,8 @@ internal abstract class GuyaParser( MangaChapter( id = generateUid(url), name = chapter.getString("title"), - number = i, + number = i.toFloat(), + volume = 0, url = url, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt index 14335972..4968b05b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt @@ -1,11 +1,9 @@ package org.koitharu.kotatsu.parsers.site.heancms -import okhttp3.Headers import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* -import org.koitharu.kotatsu.parsers.network.UserAgents import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.json.mapJSON import java.text.SimpleDateFormat @@ -20,8 +18,16 @@ internal abstract class HeanCms( override val configKeyDomain = ConfigKey.Domain(domain) + private val userAgentKey = ConfigKey.UserAgent(context.getDefaultUserAgent()) + + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(userAgentKey) + } + override val availableSortOrders: Set = EnumSet.of( SortOrder.ALPHABETICAL, + SortOrder.ALPHABETICAL_DESC, SortOrder.UPDATED, SortOrder.NEWEST, SortOrder.POPULARITY, @@ -30,15 +36,11 @@ internal abstract class HeanCms( override val availableStates: Set = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED) - override val headers: Headers = Headers.Builder() - .add("User-Agent", UserAgents.CHROME_DESKTOP) - .build() protected open val pathManga = "series" protected open val apiPath get() = getDomain("api") - //For some sources, you need to send a json. For the moment, this part only works in Get. ( ex source need json gloriousscan.com , omegascans.org ) override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { val url = buildString { append("https://") @@ -147,7 +149,8 @@ internal abstract class HeanCms( MangaChapter( id = generateUid(url), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = dateFormat.tryParse(date), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/en/OmegaScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/en/OmegaScans.kt index 60da274e..2869155c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/en/OmegaScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/en/OmegaScans.kt @@ -46,8 +46,8 @@ internal class OmegaScans(context: MangaLoaderContext) : SortOrder.POPULARITY -> append("total_views&order=desc") SortOrder.UPDATED -> append("latest&order=desc") SortOrder.NEWEST -> append("created_at&order=desc") - SortOrder.ALPHABETICAL -> append("title&order=desc") - SortOrder.ALPHABETICAL_DESC -> append("title&order=asc") + SortOrder.ALPHABETICAL -> append("title&order=asc") + SortOrder.ALPHABETICAL_DESC -> append("title&order=desc") else -> append("latest&order=desc") } append("&series_type=All&perPage=$pageSize") @@ -107,7 +107,7 @@ internal class OmegaScans(context: MangaLoaderContext) : val dateFormat = SimpleDateFormat(datePattern, Locale.ENGLISH) val chaptersJsonArray = json.getJSONArray("data") - var totalChapters = json.getJSONObject("meta").getInt("total") + var totalChapters = json.getJSONObject("meta").getInt("total").toFloat() val chapters = chaptersJsonArray.mapJSON { j -> val slug = j.getJSONObject("series").getString("series_slug") val chapterUrl = "https://$domain/$pathManga/$slug/${j.getString("chapter_slug")}" @@ -117,6 +117,7 @@ internal class OmegaScans(context: MangaLoaderContext) : url = chapterUrl, name = j.getString("chapter_name"), number = totalChapters--, + volume = 0, branch = null, uploadDate = dateFormat.tryParse(date), scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/es/YugenMangasEs.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/es/YugenMangasEs.kt index 3029628b..e3d48ef9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/es/YugenMangasEs.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/es/YugenMangasEs.kt @@ -1,5 +1,6 @@ package org.koitharu.kotatsu.parsers.site.heancms.es +import org.koitharu.kotatsu.parsers.Broken import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.* @@ -7,6 +8,7 @@ import org.koitharu.kotatsu.parsers.site.heancms.HeanCms import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.json.mapJSON +@Broken // Not dead but changed template and url visualikigai.com @MangaSourceParser("YUGEN_MANGAS_ES", "YugenMangas.lat", "es", ContentType.HENTAI) internal class YugenMangasEs(context: MangaLoaderContext) : HeanCms(context, MangaParserSource.YUGEN_MANGAS_ES, "yugenmangas.lat") { @@ -43,8 +45,8 @@ internal class YugenMangasEs(context: MangaLoaderContext) : SortOrder.POPULARITY -> append("total_views&order=desc") SortOrder.UPDATED -> append("latest&order=desc") SortOrder.NEWEST -> append("created_at&order=desc") - SortOrder.ALPHABETICAL -> append("title&order=desc") - SortOrder.ALPHABETICAL_DESC -> append("title&order=asc") + SortOrder.ALPHABETICAL -> append("title&order=asc") + SortOrder.ALPHABETICAL_DESC -> append("title&order=desc") else -> append("latest&order=desc") } append("&series_type=Comic&perPage=12") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/fr/PerfScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/fr/PerfScan.kt index afb37e53..d09c8349 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/fr/PerfScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/fr/PerfScan.kt @@ -1,10 +1,148 @@ package org.koitharu.kotatsu.parsers.site.heancms.fr +import org.json.JSONArray import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.site.heancms.HeanCms +import org.koitharu.kotatsu.parsers.util.* +import org.koitharu.kotatsu.parsers.util.json.* +import java.text.SimpleDateFormat +import java.util.* @MangaSourceParser("PERF_SCAN", "PerfScan", "fr") internal class PerfScan(context: MangaLoaderContext) : - HeanCms(context, MangaParserSource.PERF_SCAN, "perf-scan.fr") + HeanCms(context, MangaParserSource.PERF_SCAN, "perf-scan.fr") { + + override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { + val url = buildString { + append("https://api.") + append(domain) + append("/query?adult=true&query_string=") + when (filter) { + is MangaListFilter.Search -> { + append(filter.query.urlEncoded()) + } + + is MangaListFilter.Advanced -> { + + filter.states.oneOrThrowIfMany()?.let { + append("&status=") + append( + when (it) { + MangaState.ONGOING -> "Ongoing" + MangaState.FINISHED -> "Completed" + MangaState.ABANDONED -> "Dropped" + MangaState.PAUSED -> "Hiatus" + else -> "" + }, + ) + + } + append("&orderBy=") + when (filter.sortOrder) { + SortOrder.POPULARITY -> append("total_views&order=desc") + SortOrder.UPDATED -> append("latest&order=desc") + SortOrder.NEWEST -> append("created_at&order=desc") + SortOrder.ALPHABETICAL -> append("title&order=asc") + SortOrder.ALPHABETICAL_DESC -> append("title&order=desc") + else -> append("latest&order=desc") + } + append("&series_type=All&perPage=") + append(pageSize) + append("&tags_ids=") + append("[".urlEncoded()) + filter.tags.joinTo(this, ",") { it.key } + append("]".urlEncoded()) + + } + + null -> {} + } + append("&page=") + append(page) + } + val json = webClient.httpGet(url).parseJson() + return json.getJSONArray("data").mapJSON { j -> + val slug = j.getString("series_slug") + val urlManga = "https://$domain/$pathManga/$slug" + val cover = if (j.getString("thumbnail").contains('/')) { + j.getString("thumbnail") + } else { + "https://api.$domain/${j.getString("thumbnail")}" + } + Manga( + id = j.getLong("id"), + title = j.getString("title"), + altTitle = null, + url = urlManga.toRelativeUrl(domain), + publicUrl = urlManga, + rating = j.getFloatOrDefault("rating", RATING_UNKNOWN) / 5f, + isNsfw = isNsfwSource, + coverUrl = cover, + tags = setOf(), + state = when (j.getStringOrNull("status")) { + "Ongoing" -> MangaState.ONGOING + "Completed" -> MangaState.FINISHED + "Dropped" -> MangaState.ABANDONED + "Hiatus" -> MangaState.PAUSED + else -> null + }, + author = j.getStringOrNull("author"), + source = source, + description = j.getString("description"), + ) + } + + } + + override suspend fun getDetails(manga: Manga): Manga { + val url = buildString { + append("https://api.") + append(domain) + append("/chapter/query?perPage=9999&series_id=") + append(manga.id) + } + val json = webClient.httpGet(url).parseJson() + val dateFormat = SimpleDateFormat(datePattern, Locale.ENGLISH) + + val chaptersJsonArray = json.getJSONArray("data") + var totalChapters = json.getJSONObject("meta").getInt("total").toFloat() + val chapters = chaptersJsonArray.mapJSON { j -> + val slug = j.getJSONObject("series").getString("series_slug") + val chapterUrl = "https://$domain/$pathManga/$slug/${j.getString("chapter_slug")}" + val date = j.getString("created_at").substringBeforeLast("T") + MangaChapter( + id = j.getLong("id"), + url = chapterUrl, + name = j.getString("chapter_name"), + number = totalChapters--, + volume = 0, + branch = null, + uploadDate = dateFormat.tryParse(date), + scanlator = null, + source = source, + ) + } + + return manga.copy( + chapters = chapters.reversed(), + ) + } + + override suspend fun getAvailableTags(): Set { + val doc = webClient.httpGet("https://$domain/comics").parseHtml() + + val regex = Regex("\"tags\\\\.*?(\\[.+?])") + val tags = doc.select("script").firstNotNullOf { script -> + regex.find(script.html())?.groupValues?.getOrNull(1) + }.unescapeJson() + return JSONArray(tags).mapJSONToSet { + MangaTag( + key = it.getInt("id").toString(), + title = it.getString("name").toTitleCase(sourceLocale), + source = source, + ) + } + } +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/pt/ModeScanlator.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/pt/ModeScanlator.kt index 3513328f..d6a204f7 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/pt/ModeScanlator.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/pt/ModeScanlator.kt @@ -45,8 +45,8 @@ internal class ModeScanlator( SortOrder.POPULARITY -> append("total_views&order=desc") SortOrder.UPDATED -> append("latest&order=desc") SortOrder.NEWEST -> append("created_at&order=desc") - SortOrder.ALPHABETICAL -> append("title&order=desc") - SortOrder.ALPHABETICAL_DESC -> append("title&order=asc") + SortOrder.ALPHABETICAL -> append("title&order=asc") + SortOrder.ALPHABETICAL_DESC -> append("title&order=desc") else -> append("latest&order=desc") } append("&series_type=All&perPage=") @@ -108,7 +108,7 @@ internal class ModeScanlator( val dateFormat = SimpleDateFormat(datePattern, Locale.ENGLISH) val chaptersJsonArray = json.getJSONArray("data") - var totalChapters = json.getJSONObject("meta").getInt("total") + var totalChapters = json.getJSONObject("meta").getInt("total").toFloat() val chapters = chaptersJsonArray.mapJSON { j -> val slug = j.getJSONObject("series").getString("series_slug") val chapterUrl = "https://$domain/$pathManga/$slug/${j.getString("chapter_slug")}" @@ -118,6 +118,7 @@ internal class ModeScanlator( url = chapterUrl, name = j.getString("chapter_name"), number = totalChapters--, + volume = 0, branch = null, uploadDate = dateFormat.tryParse(date), scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt index 8a8c19c2..838d44ed 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt @@ -99,7 +99,8 @@ internal abstract class HeanCmsAlt( MangaChapter( id = generateUid(url), name = a.selectFirstOrThrow(selectChapterTitle).text(), - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = parseChapterDate( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/es/Brakeout.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/es/Brakeout.kt index b342a6a5..572ddecb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/es/Brakeout.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/es/Brakeout.kt @@ -35,7 +35,8 @@ internal class Brakeout(context: MangaLoaderContext) : MangaChapter( id = generateUid(url), name = div.selectFirstOrThrow(selectChapterTitle).text(), - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = parseChapterDate( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/DoujinDesuParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/DoujinDesuParser.kt index 9b854184..2c95a59a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/DoujinDesuParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/DoujinDesuParser.kt @@ -127,7 +127,8 @@ class DoujinDesuParser(context: MangaLoaderContext) : MangaChapter( id = generateUid(url), name = titleTag.text(), - number = index + 1, + number = index + 1f, + volume = 0, url = url, scanlator = null, uploadDate = chapterDateFormat.tryParse(element.select(".epsleft > .date").text()), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/mangaworld/MangaWorld.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/mangaworld/MangaWorld.kt new file mode 100644 index 00000000..6d8a155c --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/mangaworld/MangaWorld.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.it.mangaworld + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaParserSource + +@MangaSourceParser("MANGAWORLD", "MangaWorld", "it") +internal class MangaWorld( + context: MangaLoaderContext, +) : MangaWorldParser(context, MangaParserSource.MANGAWORLD, "mangaworld.ac") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/mangaworld/MangaWorldAdult.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/mangaworld/MangaWorldAdult.kt new file mode 100644 index 00000000..3fc1cd40 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/mangaworld/MangaWorldAdult.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.it.mangaworld + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaParserSource + +@MangaSourceParser("MANGAWORLDADULT", "MangaWorldAdult", "it") +internal class MangaWorldAdult( + context: MangaLoaderContext, +) : MangaWorldParser(context, MangaParserSource.MANGAWORLDADULT, "mangaworldadult.net") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/MangaWorld.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/mangaworld/MangaWorldParser.kt similarity index 71% rename from src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/MangaWorld.kt rename to src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/mangaworld/MangaWorldParser.kt index 831a857e..7fbfe235 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/MangaWorld.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/it/mangaworld/MangaWorldParser.kt @@ -1,7 +1,7 @@ -package org.koitharu.kotatsu.parsers.site.it +package org.koitharu.kotatsu.parsers.site.it.mangaworld +import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* @@ -9,14 +9,28 @@ import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* -@MangaSourceParser("MANGAWORLD", "mangaworld.ac", "it") -internal class MangaWorld( +abstract class MangaWorldParser( context: MangaLoaderContext, -) : PagedMangaParser(context, MangaParserSource.MANGAWORLD, pageSize = 16) { + source: MangaParserSource, + domain: String, + pageSize: Int = 16, +) : PagedMangaParser(context, source, pageSize) { override val availableSortOrders: Set = - EnumSet.of(SortOrder.POPULARITY, SortOrder.ALPHABETICAL, SortOrder.NEWEST, SortOrder.ALPHABETICAL_DESC) + EnumSet.of( + SortOrder.POPULARITY, + SortOrder.ALPHABETICAL, + SortOrder.NEWEST, + SortOrder.ALPHABETICAL_DESC, + SortOrder.UPDATED, + ) + + override val defaultSortOrder: SortOrder + get() = SortOrder.ALPHABETICAL - override val configKeyDomain = ConfigKey.Domain("mangaworld.ac") + override val configKeyDomain = ConfigKey.Domain(domain) + + override val availableStates: Set = + EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.ABANDONED, MangaState.PAUSED) override val isMultipleTagsSupported = true @@ -36,6 +50,10 @@ internal class MangaWorld( } is MangaListFilter.Advanced -> { + if (filter.tags.isEmpty() && filter.states.isEmpty() && filter.sortOrder == SortOrder.UPDATED) return parseMangaList( + webClient.httpGet("https://$domain/?page=$page").parseHtml(), + ) + if (filter.tags.isNotEmpty()) { filter.tags.joinTo(this, "&") { it.key.substringAfter("archive?") } } @@ -61,6 +79,10 @@ internal class MangaWorld( append("&page=$page") } val doc = webClient.httpGet(url).parseHtml() + return parseMangaList(doc) + } + + private fun parseMangaList(doc: Document): List { return doc.select(".comics-grid .entry").map { div -> val href = div.selectFirstOrThrow("a.thumb").attrAsRelativeUrl("href") val tags = div.select(".genres a[href*=/archive?genre=]") @@ -89,15 +111,26 @@ internal class MangaWorld( } } + override suspend fun getAvailableTags(): Set { val doc = webClient.httpGet("https://$domain/").parseHtml() - return doc.select("div[aria-labelledby=genresDropdown] a").mapNotNullToSet { + val genres = doc.select("div[aria-labelledby=genresDropdown] a").mapNotNullToSet { MangaTag( key = it.attr("href"), title = it.text().toTitleCase(sourceLocale), source = source, ) } + + val types = doc.select("div[aria-labelledby=typesDropdown] a").mapNotNullToSet { + MangaTag( + key = it.attr("href"), + title = it.text().toTitleCase(sourceLocale), + source = source, + ) + } + + return genres + types } override suspend fun getDetails(manga: Manga): Manga { @@ -116,8 +149,9 @@ internal class MangaWorld( MangaChapter( id = generateUid(url), name = a.selectFirstOrThrow("span.d-inline-block").text(), - number = i + 1, - url = url, + number = i + 1f, + volume = 0, + url = "$url?style=list", scanlator = null, uploadDate = SimpleDateFormat("dd MMMM yyyy", Locale.ITALIAN).tryParse( @@ -132,7 +166,10 @@ internal class MangaWorld( override suspend fun getPages(chapter: MangaChapter): List { val doc = webClient.httpGet(chapter.url.toAbsoluteUrl(domain)).parseHtml() - return doc.select("img.page-image").map { img -> + val selectWebtoonPages = "img.page-image" + val selectMangaPages = "img.img-fluid" + val imgSelector = if (doc.select(selectWebtoonPages).isNotEmpty()) selectWebtoonPages else selectMangaPages + return doc.select(imgSelector).map { img -> val urlPage = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") MangaPage( id = generateUid(urlPage), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ja/NicovideoSeigaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ja/NicovideoSeigaParser.kt index b2f8a2e7..6b0dc7b5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ja/NicovideoSeigaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ja/NicovideoSeigaParser.kt @@ -126,7 +126,8 @@ class NicovideoSeigaParser(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = li.select("div > div.description > div.title > a").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, branch = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/KeyoappParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/KeyoappParser.kt new file mode 100644 index 00000000..e5f08ddc --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/KeyoappParser.kt @@ -0,0 +1,307 @@ +package org.koitharu.kotatsu.parsers.site.keyoapp + +import androidx.collection.scatterSetOf +import kotlinx.coroutines.coroutineScope +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.PagedMangaParser +import org.koitharu.kotatsu.parsers.config.ConfigKey +import org.koitharu.kotatsu.parsers.model.* +import org.koitharu.kotatsu.parsers.util.* +import java.text.DateFormat +import java.text.SimpleDateFormat +import java.util.* + +internal abstract class KeyoappParser( + context: MangaLoaderContext, + source: MangaParserSource, + domain: String, + pageSize: Int = 24, +) : PagedMangaParser(context, source, pageSize) { + + override val configKeyDomain = ConfigKey.Domain(domain) + + private val userAgentKey = ConfigKey.UserAgent(context.getDefaultUserAgent()) + + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(userAgentKey) + } + + override val isMultipleTagsSupported = false + + override val availableSortOrders: Set = EnumSet.of( + SortOrder.UPDATED, + SortOrder.NEWEST, + ) + + protected open val listUrl = "series/" + protected open val datePattern = "MMM d, yyyy" + + + @JvmField + protected val ongoing = scatterSetOf( + "ongoing", + ) + + @JvmField + protected val finished = scatterSetOf( + "completed", + ) + + @JvmField + protected val paused = scatterSetOf( + "paused", + ) + + @JvmField + protected val upcoming = scatterSetOf( + "dropped", + ) + + init { + paginator.firstPage = 1 + searchPaginator.firstPage = 1 + } + + override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { + + var query = "" + var tag = "" + + if (page > 1) { + return emptyList() + } + + val url = urlBuilder().apply { + + when (filter) { + is MangaListFilter.Search -> { + addPathSegment("series") + query = filter.query + } + + is MangaListFilter.Advanced -> { + + if (filter.tags.isNotEmpty()) { + filter.tags.oneOrThrowIfMany()?.let { + tag = it.title + } + } + + when (filter.sortOrder) { + SortOrder.UPDATED -> addPathSegment("latest") + SortOrder.NEWEST -> addPathSegment("series") + else -> addPathSegment("latest") + } + + } + + null -> addPathSegment("latest") + } + }.build() + + return parseMangaList(webClient.httpGet(url).parseHtml(), tag, query) + } + + + protected open fun parseMangaList(doc: Document, tag: String, query: String): List { + + val manga = ArrayList() + + doc.select("#searched_series_page button").ifEmpty { + doc.select("div.grid > div.group") + }.map { div -> + + val title = div.selectFirstOrThrow("h3").text().orEmpty() + if (query.isNotEmpty() && title.contains(query, ignoreCase = true)) { + manga.add(addManga(div)) + } + + // Not all tags are present in UPDATED + val tags = div.attr("tags") ?: div.select("div.gap-1 a").joinToString() + if (tag.isNotEmpty() && tags.contains(tag, ignoreCase = true)) { + manga.add(addManga(div)) + } + + if (query.isEmpty() && tag.isEmpty()) { + manga.add(addManga(div)) + } + + } + + return manga + } + + + private fun addManga(div: Element): Manga { + val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") + val cover = div.selectFirst("div.h-full") ?: div.selectFirst("a") + return Manga( + id = generateUid(href), + url = href, + publicUrl = href.toAbsoluteUrl(div.host ?: domain), + coverUrl = cover?.styleValueOrNull("background-image")?.cssUrl().orEmpty(), + title = div.selectFirstOrThrow("h3").text().orEmpty(), + altTitle = null, + rating = RATING_UNKNOWN, + tags = div.select("div.gap-1 a").mapNotNullToSet { a -> + MangaTag( + key = a.attr("href").substringAfterLast('='), + title = a.text().toTitleCase(), + source = source, + ) + }, + author = null, + state = null, + source = source, + isNsfw = isNsfwSource, + ) + } + + private fun String.cssUrl(): String? { + val fromIndex = indexOf("url(") + if (fromIndex == -1) { + return null + } + val toIndex = indexOf(')', startIndex = fromIndex) + return if (toIndex == -1) { + null + } else { + substring(fromIndex + 4, toIndex).trim() + } + } + + + override suspend fun getAvailableTags(): Set { + val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml() + return doc.requireElementById("series_tags_page").select("button").mapNotNullToSet { button -> + val key = button.attr("tag") ?: return@mapNotNullToSet null + val name = button.text().toTitleCase(sourceLocale) + MangaTag( + key = key, + title = name, + source = source, + ) + } + } + + protected open val selectDesc = "div.grid > div.overflow-hidden > p" + protected open val selectState = "div[alt=Status]" + protected open val selectTag = "div.grid:has(>h1) > div > a" + protected open val selectAuthor = "div[alt=Author]" + protected open val selectChapter = "#chapters > a:not(:has(.text-sm span:matches(Upcoming)))" + + override suspend fun getDetails(manga: Manga): Manga = coroutineScope { + val fullUrl = manga.url.toAbsoluteUrl(domain) + val doc = webClient.httpGet(fullUrl).parseHtml() + val dateFormat = SimpleDateFormat(datePattern, sourceLocale) + manga.copy( + tags = doc.body().select(selectTag).mapNotNullToSet { a -> + MangaTag( + key = a.attr("href").substringAfterLast('='), + title = a.text().toTitleCase(), + source = source, + ) + }, + description = doc.selectFirstOrThrow(selectDesc).html(), + state = when ( + doc.selectFirstOrThrow(selectState).text().lowercase() + ) { + in ongoing -> MangaState.ONGOING + in finished -> MangaState.FINISHED + in paused -> MangaState.PAUSED + in upcoming -> MangaState.UPCOMING + else -> null + }, + chapters = doc.select(selectChapter) + .mapChapters(reversed = true) { i, a -> + val href = a.attrAsRelativeUrl("href") + val name = a.selectFirstOrThrow("span.truncate").text() + val dateText = a.selectLast("div.text-xs.w-fit")?.text() ?: "0" + MangaChapter( + id = generateUid(href), + name = name, + number = i + 1f, + volume = 0, + url = href, + scanlator = null, + uploadDate = parseChapterDate( + dateFormat, + dateText, + ), + branch = null, + source = source, + ) + }, + ) + } + + protected open val selectPage = "#pages > img" + + override suspend fun getPages(chapter: MangaChapter): List { + val fullUrl = chapter.url.toAbsoluteUrl(domain) + val doc = webClient.httpGet(fullUrl).parseHtml() + return doc.select(selectPage).map { img -> + val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") + MangaPage( + id = generateUid(url), + url = url, + preview = null, + source = source, + ) + } + } + + protected fun parseChapterDate(dateFormat: DateFormat, date: String?): Long { + val d = date?.lowercase() ?: return 0 + return when { + d.endsWith(" ago") -> parseRelativeDate(date) + + d.startsWith("year") -> Calendar.getInstance().apply { + add(Calendar.DAY_OF_MONTH, -1) + 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) + } + } + + private fun parseRelativeDate(date: String): Long { + val number = Regex("""(\d+)""").find(date)?.value?.toIntOrNull() ?: return 0 + val cal = Calendar.getInstance() + return when { + WordSet("second").anyWordIn(date) -> cal.apply { add(Calendar.SECOND, -number) }.timeInMillis + + WordSet("minute", "minutes").anyWordIn(date) -> cal.apply { add(Calendar.MINUTE, -number) }.timeInMillis + + WordSet("hour", "hours").anyWordIn(date) -> cal.apply { add(Calendar.HOUR, -number) }.timeInMillis + + WordSet("day", "days").anyWordIn(date) -> cal.apply { add(Calendar.DAY_OF_MONTH, -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 + } + } +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/en/EzManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/en/EzManga.kt new file mode 100644 index 00000000..af39deb6 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/en/EzManga.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.keyoapp.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.keyoapp.KeyoappParser + +@MangaSourceParser("EZMANGA", "EzManga", "en") +internal class EzManga(context: MangaLoaderContext) : + KeyoappParser(context, MangaParserSource.EZMANGA, "ezmanga.org") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/en/KewnScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/en/KewnScans.kt new file mode 100644 index 00000000..6aaca30f --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/en/KewnScans.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.keyoapp.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.keyoapp.KeyoappParser + +@MangaSourceParser("KEWNSCANS", "KewnScans", "en") +internal class KewnScans(context: MangaLoaderContext) : + KeyoappParser(context, MangaParserSource.KEWNSCANS, "kewnscans.org") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/en/LaidBackScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/en/LaidBackScans.kt new file mode 100644 index 00000000..2cd8c57b --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/en/LaidBackScans.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.keyoapp.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.keyoapp.KeyoappParser + +@MangaSourceParser("LAIDBACKSCANS", "LaidBackScans", "en") +internal class LaidBackScans(context: MangaLoaderContext) : + KeyoappParser(context, MangaParserSource.LAIDBACKSCANS, "laidbackscans.org") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/AnteikuScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/AnteikuScan.kt new file mode 100644 index 00000000..81115347 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/AnteikuScan.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.keyoapp.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.keyoapp.KeyoappParser + +@MangaSourceParser("ANTEIKUSCAN", "AnteikuScan", "fr") +internal class AnteikuScan(context: MangaLoaderContext) : + KeyoappParser(context, MangaParserSource.ANTEIKUSCAN, "anteikuscan.fr") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/Astrames.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/Astrames.kt new file mode 100644 index 00000000..e8555a93 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/Astrames.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.keyoapp.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.keyoapp.KeyoappParser + +@MangaSourceParser("ASTRAMES", "Astrames", "fr") +internal class Astrames(context: MangaLoaderContext) : + KeyoappParser(context, MangaParserSource.ASTRAMES, "astrames.fr") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/EdScanlation.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/EdScanlation.kt new file mode 100644 index 00000000..dd7caf54 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/EdScanlation.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.keyoapp.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.keyoapp.KeyoappParser + +@MangaSourceParser("EDSCANLATION", "EdScanlation", "fr") +internal class EdScanlation(context: MangaLoaderContext) : + KeyoappParser(context, MangaParserSource.EDSCANLATION, "edscanlation.fr") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/StarboundScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/StarboundScans.kt new file mode 100644 index 00000000..fa15dc11 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/keyoapp/fr/StarboundScans.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.keyoapp.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.keyoapp.KeyoappParser + +@MangaSourceParser("STARBOUNDSCANS", "StarboundScans", "fr") +internal class StarboundScans(context: MangaLoaderContext) : + KeyoappParser(context, MangaParserSource.STARBOUNDSCANS, "starboundscans.org") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/LikeMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/LikeMangaParser.kt index aaa371c5..9db6de11 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/LikeMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/LikeMangaParser.kt @@ -219,7 +219,8 @@ internal abstract class LikeMangaParser( MangaChapter( id = generateUid(url), name = li.selectFirstOrThrow("a").text(), - number = chapNum.toInt(), + number = chapNum.toFloat(), + volume = 0, url = url, scanlator = null, uploadDate = parseChapterDate( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/en/ZinManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/en/ZinManga.kt deleted file mode 100644 index 03e04fa2..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/likemanga/en/ZinManga.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.likemanga.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.likemanga.LikeMangaParser - -@MangaSourceParser("ZINMANGA_COM", "ZinManga.com", "en") -internal class ZinManga(context: MangaLoaderContext) : - LikeMangaParser(context, MangaParserSource.ZINMANGA_COM, "zinmanga.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt index 53cef55d..2f6a4486 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MadaraParser.kt @@ -7,8 +7,11 @@ import org.json.JSONObject import org.jsoup.nodes.Document import org.jsoup.nodes.Element import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaParserAuthProvider import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey +import org.koitharu.kotatsu.parsers.exception.AuthRequiredException +import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* import java.text.DateFormat @@ -20,11 +23,39 @@ internal abstract class MadaraParser( source: MangaParserSource, domain: String, pageSize: Int = 12, -) : PagedMangaParser(context, source, pageSize) { +) : PagedMangaParser(context, source, pageSize), MangaParserAuthProvider { override val configKeyDomain = ConfigKey.Domain(domain) + private val userAgentKey = ConfigKey.UserAgent(context.getDefaultUserAgent()) + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(userAgentKey) + } + + override val authUrl: String + get() = "https://${domain}" + + override val isAuthorized: Boolean + get() { + return context.cookieJar.getCookies(domain).any { + it.name.contains("wordpress_logged_in") + } + } + + override suspend fun getUsername(): String { + val body = webClient.httpGet("https://${domain}/").parseHtml().body() + return body.selectFirst(".c-user_name")?.text() + ?: run { + throw if (body.selectFirst("#loginform") != null) { + AuthRequiredException(source) + } else { + body.parseFailed("Cannot find username") + } + } + } + override val isMultipleTagsSupported = false override val availableSortOrders: Set = EnumSet.of( @@ -333,7 +364,7 @@ internal abstract class MadaraParser( publicUrl = href.toAbsoluteUrl(div.host ?: domain), coverUrl = div.selectFirst("img")?.src().orEmpty(), title = (summary?.selectFirst("h3") ?: summary?.selectFirst("h4") - ?: div.selectFirst(".manga-name"))?.text().orEmpty(), + ?: div.selectFirst(".manga-name") ?: div.selectFirst(".post-title"))?.text().orEmpty(), altTitle = null, rating = div.selectFirst("span.total_votes")?.ownText()?.toFloatOrNull()?.div(5f) ?: -1f, tags = summary?.selectFirst(".mg_genres")?.select("a")?.mapNotNullToSet { a -> @@ -472,7 +503,8 @@ internal abstract class MadaraParser( MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = link, uploadDate = parseChapterDate( dateFormat, @@ -506,7 +538,8 @@ internal abstract class MadaraParser( id = generateUid(href), url = link, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = parseChapterDate( dateFormat, @@ -549,7 +582,8 @@ internal abstract class MadaraParser( val doc = webClient.httpGet(fullUrl).parseHtml() val chapterProtector = doc.getElementById("chapter-protector-data") if (chapterProtector == null) { - val root = doc.body().selectFirstOrThrow(selectBodyPage) + val root = doc.body().selectFirst(selectBodyPage) + ?: 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") @@ -649,11 +683,6 @@ internal abstract class MadaraParser( } } - override fun onCreateConfig(keys: MutableCollection>) { - super.onCreateConfig(keys) - keys.add(userAgentKey) - } - // Parses dates in this form: // 21 hours ago private fun parseRelativeDate(date: String): Long { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/Ero18x.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/Ero18x.kt index 555a783b..7963ba78 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/Ero18x.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/Ero18x.kt @@ -33,7 +33,8 @@ internal class Ero18x(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = link, uploadDate = if (dateText == "Newly Published!") { parseChapterDate( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/ManhwaRaw.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/ManhwaRaw.kt index 330744e6..ee37c30c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/ManhwaRaw.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/all/ManhwaRaw.kt @@ -31,7 +31,8 @@ internal class ManhwaRaw(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = link, uploadDate = if (dateText == "Newly Published!") { parseChapterDate( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LekManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LekManga.kt index 9d6d8477..5fa44186 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LekManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LekManga.kt @@ -6,5 +6,5 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("MANGALEK", "LekManga", "ar") -internal class MangaLek(context: MangaLoaderContext) : +internal class LekManga(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.MANGALEK, "lekmanga.net", pageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LekMangaCom.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LekMangaCom.kt index 18f24c31..a6b65aac 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LekMangaCom.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LekMangaCom.kt @@ -31,7 +31,8 @@ internal class LekMangaCom(context: MangaLoaderContext) : id = generateUid(href), url = link, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LikeMangaNet.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LikeMangaNet.kt index c7e89721..1c83869c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LikeMangaNet.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/LikeMangaNet.kt @@ -6,5 +6,5 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("LIKEMANGANET", "Like-Manga.net", "ar") -internal class MangaLikeNet(context: MangaLoaderContext) : +internal class LikeMangaNet(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.LIKEMANGANET, "like-manga.net", pageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/RocksManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaPeak.kt similarity index 60% rename from src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/RocksManga.kt rename to src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaPeak.kt index 2ca0a03d..3511435b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/RocksManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaPeak.kt @@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("ROCKSMANGA", "RocksManga", "ar") -internal class RocksManga(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.ROCKSMANGA, "rocks-manga.com") +@MangaSourceParser("MANGAPEAK", "MangaPeak", "ar") +internal class MangaPeak(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.MANGAPEAK, "mangapeak.org") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/RocksManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/RocksManga.kt new file mode 100644 index 00000000..b8d01b59 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/RocksManga.kt @@ -0,0 +1,50 @@ +package org.koitharu.kotatsu.parsers.site.madara.ar + +import org.jsoup.nodes.Document +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaChapter +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrlOrNull +import org.koitharu.kotatsu.parsers.util.generateUid +import org.koitharu.kotatsu.parsers.util.mapChapters +import org.koitharu.kotatsu.parsers.util.parseFailed +import java.text.SimpleDateFormat + +@MangaSourceParser("ROCKSMANGA", "RocksManga", "ar") +internal class RocksManga(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.ROCKSMANGA, "rocks-manga.com") { + override val selectChapter = "ul#chapter-list li.chapter-item" + override val datePattern = "d MMMM yyyy" + override val selectDate = ".ch-post-time" + override val selectBodyPage = "div.reading-content" + override val selectPage = "img" + override val selectDesc = ".story" + + override suspend fun loadChapters(mangaUrl: String, document: Document): List { + val dateFormat = SimpleDateFormat(datePattern, sourceLocale) + return document.select(selectChapter).mapChapters(reversed = true) { i, li -> + val a = li.selectFirst("a") + val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") + val link = href + stylePage + val dateText = li.selectFirst("a.c-new-tag")?.attr("title") ?: li.selectFirst(selectDate)?.text() + val name = a.selectFirst(".ch-title")?.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, + ) + } + } +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AnshScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AnshScans.kt index a784f253..6327ae36 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AnshScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AnshScans.kt @@ -1,10 +1,12 @@ package org.koitharu.kotatsu.parsers.site.madara.en +import org.koitharu.kotatsu.parsers.Broken 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 +@Broken @MangaSourceParser("ANSHSCANS", "AnshScans", "en") internal class AnshScans(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.ANSHSCANS, "anshscans.org", 10) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentaixdickgirl.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentaixdickgirl.kt index 23759562..7ff70f2e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentaixdickgirl.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentaixdickgirl.kt @@ -28,7 +28,8 @@ internal class Hentaixdickgirl(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = link, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/InstaManhwa.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/InstaManhwa.kt index 49ca0d48..21544a05 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/InstaManhwa.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/InstaManhwa.kt @@ -121,7 +121,8 @@ internal class InstaManhwa(context: MangaLoaderContext) : id = generateUid(href), url = link, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScan.kt index d2308efa..02201592 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScan.kt @@ -125,7 +125,8 @@ internal class IsekaiScan(context: MangaLoaderContext) : id = generateUid(href), url = link, name = a.ownText(), - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScanEuParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScanEuParser.kt index 1b60642a..0c9e1d93 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScanEuParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScanEuParser.kt @@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.util.* -@MangaSourceParser("ISEKAISCAN_EU", "IsekaiScan.to", "en") +@MangaSourceParser("ISEKAISCAN_EU", "ParagonScans", "en") internal class IsekaiScanEuParser(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.ISEKAISCAN_EU, "paragonscans.com") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt index 8b377dc9..c11d0530 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDass.kt @@ -161,7 +161,8 @@ internal class MangaDass(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = link, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDistrict.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDistrict.kt index ff1a49d4..2d756b1e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDistrict.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDistrict.kt @@ -33,7 +33,8 @@ internal class MangaDistrict(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = a.ownText(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDna.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDna.kt index df15bece..8bfaf8a9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDna.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDna.kt @@ -151,7 +151,8 @@ internal class MangaDna(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = link, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaPure.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaPure.kt index 35a982a3..9a370f59 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaPure.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaPure.kt @@ -127,7 +127,8 @@ internal class MangaPure(context: MangaLoaderContext) : id = generateUid(href), url = link, name = a.ownText(), - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Paragonscans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTxTo.kt similarity index 53% rename from src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Paragonscans.kt rename to src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTxTo.kt index f85ef54c..6fe79976 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Paragonscans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTxTo.kt @@ -5,8 +5,8 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("PARAGONSCANS", "ParagonScans", "en") -internal class Paragonscans(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.PARAGONSCANS, "paragonscans.com", pageSize = 50) { - override val datePattern = "MM/dd/yyyy" +@MangaSourceParser("MANGATX_TO", "MangaTx.to", "en") +internal class MangaTxTo(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.MANGATX_TO, "mangatx.to", 10) { + override val tagPrefix = "manhua-genre/" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuaplus.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuaplus.kt index 098ed6c7..98e9ef15 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuaplus.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhuaplus.kt @@ -11,7 +11,7 @@ import org.koitharu.kotatsu.parsers.util.* @MangaSourceParser("MANHUAPLUS", "ManhuaPlus", "en") internal class Manhuaplus(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.MANHUAPLUS, "manhuaplus.org") { + MadaraParser(context, MangaParserSource.MANHUAPLUS, "manhuaplus.com") { override val withoutAjax = true diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhwaTop.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhwaTop.kt index d0bc467e..eda11aa4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhwaTop.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhwaTop.kt @@ -39,7 +39,8 @@ internal class ManhwaTop(context: MangaLoaderContext) : id = generateUid(href), url = link, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ResetScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ResetScans.kt index cfbaf814..64c7f330 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ResetScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ResetScans.kt @@ -27,7 +27,7 @@ internal class ResetScans(context: MangaLoaderContext) : webClient.httpPost(url, emptyMap()).parseHtml() } val dateFormat = SimpleDateFormat(datePattern, sourceLocale) - return doc.select(selectChapter).mapChapters(reversed = true) { i, li -> + return doc.select(selectChapter).mapChapters(reversed = true) { _, li -> val a = li.getElementsByTag("a").findWithText() val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") val link = href + stylePage diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/StoneScape.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/StoneScape.kt new file mode 100644 index 00000000..7deafe1c --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/StoneScape.kt @@ -0,0 +1,14 @@ +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.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("STONESCAPE", "StoneScape", "en") +internal class StoneScape(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.STONESCAPE, "stonescape.xyz", 10) { + override val listUrl = "series/" + override val tagPrefix = "series-genre/" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TcbScansManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TcbScansManga.kt new file mode 100644 index 00000000..93835de7 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TcbScansManga.kt @@ -0,0 +1,13 @@ +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.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("TCBSCANSMANGA", "TcbScansManga", "en") +internal class TcbScansManga(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.TCBSCANSMANGA, "tcbscans-manga.com", 10) { + override val selectPage = "img" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt index 87742fde..b1768a5e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt @@ -5,9 +5,10 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("TOPMANHUA", "TopManhua", "en") +@MangaSourceParser("TOPMANHUA", "ManhuaTop", "en") internal class TopManhua(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.TOPMANHUA, "topmanhua.com") { + MadaraParser(context, MangaParserSource.TOPMANHUA, "manhuatop.org") { override val tagPrefix = "manhua-genre/" + override val listUrl = "manhua/" override val datePattern = "MM/dd/yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ZinChanManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ZinChanManga.kt new file mode 100644 index 00000000..f5222491 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ZinChanManga.kt @@ -0,0 +1,12 @@ +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.ContentType +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("ZINCHANMANGA", "ZinChanManga", "en", ContentType.HENTAI) +internal class ZinChanManga(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.ZINCHANMANGA, "zinchanmanga.com", 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Zinmanga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Zinmanga.kt index fa50e31a..67606d18 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Zinmanga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Zinmanga.kt @@ -5,8 +5,9 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("ZINMANGA", "ZinManga.com", "en") +@MangaSourceParser("ZINMANGA", "ZinManga", "en") internal class Zinmanga(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.ZINMANGA, "zinmanga.com") { + MadaraParser(context, MangaParserSource.ZINMANGA, "zinmanga.net") { override val datePattern = "MM/dd/yyyy" + override val withoutAjax = true } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ManhwaEs.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ManhwaEs.kt index 047565c1..c1529aa2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ManhwaEs.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ManhwaEs.kt @@ -32,7 +32,8 @@ internal class ManhwaEs(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = link, uploadDate = if (dateText == "¡Recién publicado!") { parseChapterDate( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ManhwaLatino.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ManhwaLatino.kt index 7e35b147..0a2127c0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ManhwaLatino.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/ManhwaLatino.kt @@ -35,7 +35,8 @@ internal class ManhwaLatino(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = link, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TmoManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TmoManga.kt index f81645ad..43fadcbc 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TmoManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TmoManga.kt @@ -99,7 +99,8 @@ internal class TmoManga(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = link, uploadDate = 0, source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/BlueSolo.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/BlueSolo.kt index 3f09e9c8..c1b25732 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/BlueSolo.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/BlueSolo.kt @@ -1,10 +1,12 @@ package org.koitharu.kotatsu.parsers.site.madara.fr +import org.koitharu.kotatsu.parsers.Broken 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 +@Broken @MangaSourceParser("BLUESOLO", "BlueSolo", "fr") internal class BlueSolo(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.BLUESOLO, "www1.bluesolo.org", 10) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/EpsilonSoft.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/EpsilonSoft.kt new file mode 100644 index 00000000..cc7a365e --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/EpsilonSoft.kt @@ -0,0 +1,12 @@ +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.* +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("EPSILONSOFT", "EpsilonSoft", "fr") +internal class EpsilonSoft(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.EPSILONSOFT, "epsilonsoft.to") { + override val datePattern = "dd/MM/yy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/EpsilonscanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/EpsilonscanParser.kt similarity index 76% rename from src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/EpsilonscanParser.kt rename to src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/EpsilonscanParser.kt index 42961454..1c666dd5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/EpsilonscanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/EpsilonscanParser.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.fr +package org.koitharu.kotatsu.parsers.site.madara.fr import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser @@ -8,7 +8,6 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("EPSILONSCAN", "EpsilonScan", "fr", ContentType.HENTAI) internal class EpsilonscanParser(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.EPSILONSCAN, "epsilonscan.fr") { - override val withoutAjax = true - override val isTagsExclusionSupported = false + MadaraParser(context, MangaParserSource.EPSILONSCAN, "epsilonscan.to") { + override val datePattern = "dd/MM/yy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/HarmonyScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/HarmonyScan.kt new file mode 100644 index 00000000..863cd4bf --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/HarmonyScan.kt @@ -0,0 +1,11 @@ +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.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("HARMONYSCAN", "HarmonyScan", "fr") +internal class HarmonyScan(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.HARMONYSCAN, "harmony-scan.fr") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/HentaiOrigines.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/HentaiOrigines.kt new file mode 100644 index 00000000..8edf2db2 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/HentaiOrigines.kt @@ -0,0 +1,12 @@ +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.ContentType +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("HENTAIORIGINES", "HentaiOrigines", "fr", ContentType.HENTAI) +internal class HentaiOrigines(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.HENTAIORIGINES, "hentai-origines.fr") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/Hentaizone.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/Hentaizone.kt index 7660a64c..4eb6091a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/Hentaizone.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/Hentaizone.kt @@ -35,7 +35,8 @@ internal class Hentaizone(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = link, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/LunarHentai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/LunarHentai.kt index 9c8530d6..032663f4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/LunarHentai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/LunarHentai.kt @@ -1,11 +1,13 @@ package org.koitharu.kotatsu.parsers.site.madara.fr +import org.koitharu.kotatsu.parsers.Broken 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.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +@Broken @MangaSourceParser("LUNARHENTAI", "LunarHentai", "fr", ContentType.HENTAI) internal class LunarHentai(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.LUNARHENTAI, "hentai.lunarscans.fr") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScanHentaiMenu.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScanHentaiMenu.kt index e1046982..fcd6f866 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScanHentaiMenu.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScanHentaiMenu.kt @@ -8,4 +8,4 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("SCANHENTAIMENU", "ScanHentai.Menu", "fr", ContentType.HENTAI) internal class ScanHentaiMenu(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.SCANHENTAIMENU, "scan.hentai.menu") + MadaraParser(context, MangaParserSource.SCANHENTAIMENU, "x-manga.net") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScantradVf.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScantradVf.kt index f717a115..5d0c8e82 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScantradVf.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScantradVf.kt @@ -1,10 +1,12 @@ package org.koitharu.kotatsu.parsers.site.madara.fr +import org.koitharu.kotatsu.parsers.Broken 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 +@Broken @MangaSourceParser("SCANTRADVF", "Scantrad-Vf", "fr") internal class ScantradVf(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.SCANTRADVF, "scantrad-vf.me") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ToonFr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ToonFr.kt index cc476c96..df1f2680 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ToonFr.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ToonFr.kt @@ -32,7 +32,8 @@ internal class ToonFr(context: MangaLoaderContext) : id = generateUid(href), url = href, name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CafecomYaoi.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CafecomYaoi.kt index 2a67a702..9a64f03f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CafecomYaoi.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CafecomYaoi.kt @@ -2,12 +2,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.ContentType import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("CAFECOMYAOI", "CafecomYaoi", "pt") +@MangaSourceParser("CAFECOMYAOI", "CafecomYaoi", "pt", ContentType.HENTAI) internal class CafecomYaoi(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.CAFECOMYAOI, "cafecomyaoi.com.br") { override val datePattern = "dd/MM/yyyy" - override val postReq = true } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CeriseScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CeriseScans.kt index 963cb297..6dc642a7 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CeriseScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CeriseScans.kt @@ -1,10 +1,12 @@ 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.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +@Broken @MangaSourceParser("CERISE_SCANS", "CeriseScans", "pt") internal class CeriseScans(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.CERISE_SCANS, "cerisetoon.com") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CrystalScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CrystalScan.kt index 9d5222bd..2f3dfd1f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CrystalScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/CrystalScan.kt @@ -5,6 +5,7 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("CRYSTALSCAN", "CrystalScan", "pt") +@MangaSourceParser("CRYSTALSCAN", "CrystalComics", "pt") internal class CrystalScan(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.CRYSTALSCAN, "crystalscan.net") + MadaraParser(context, MangaParserSource.CRYSTALSCAN, "crystalcomics.com") + diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/DreamScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/DreamScan.kt new file mode 100644 index 00000000..28630ccd --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/DreamScan.kt @@ -0,0 +1,11 @@ +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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("DREAMSCAN", "DreamScan", "pt") +internal class DreamScan(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.DREAMSCAN, "dreamscan.com.br") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/GalinhaSamurai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/GalinhaSamurai.kt index 030f93fa..33e8b7fe 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/GalinhaSamurai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/GalinhaSamurai.kt @@ -5,8 +5,9 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("GALINHASAMURAI", "Galinha Samurai", "pt") +@MangaSourceParser("GALINHASAMURAI", "GalinhaSamurai", "pt") internal class GalinhaSamurai(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.GALINHASAMURAI, "galinhasamurai.com") { override val datePattern = "dd/MM/yyyy" + override val withoutAjax = true } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/HuntersScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/HuntersScan.kt index dc0c1b11..2f6b5525 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/HuntersScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/HuntersScan.kt @@ -11,5 +11,4 @@ internal class HuntersScan(context: MangaLoaderContext) : override val withoutAjax = true override val datePattern = "MM/dd/yyyy" override val tagPrefix = "series-genre/" - override val listUrl = "manga/" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/KakuseiProject.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/KakuseiProject.kt index bda0981c..70aee8ad 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/KakuseiProject.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/KakuseiProject.kt @@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("KAKUSEIPROJECT", "Kakusei Project", "pt") +@MangaSourceParser("KAKUSEIPROJECT", "KakuseiProject", "pt") internal class KakuseiProject(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.KAKUSEIPROJECT, "kakuseiproject.com", 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Kalango.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Kalango.kt new file mode 100644 index 00000000..c3debd9d --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Kalango.kt @@ -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 +import java.util.* + +@MangaSourceParser("KALANGO", "Kalango", "pt") +internal class Kalango(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.KALANGO, "kalango.org") { + override val datePattern: String = "dd 'de' MMMM 'de' yyyy" + override val sourceLocale: Locale = Locale.ENGLISH +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/LeitorDeManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/LeitorDeManga.kt new file mode 100644 index 00000000..f90feeb2 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/LeitorDeManga.kt @@ -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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("LEITORDEMANGA", "LeitorDeManga", "pt") +internal class LeitorDeManga(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.LEITORDEMANGA, "leitordemanga.com", 10) { + override val datePattern = "dd/MM/yyyy" + override val listUrl = "ler-manga/" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MaidScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MaidScan.kt index b66d5db4..e55f7416 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MaidScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MaidScan.kt @@ -8,6 +8,6 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("MAIDSCAN", "MaidScan", "pt", ContentType.HENTAI) internal class MaidScan(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.MAIDSCAN, "maidscan.com.br", 10) { - override val datePattern: String = "dd 'de' MMMMM 'de' yyyy" + MadaraParser(context, MangaParserSource.MAIDSCAN, "maidscans.com", 10) { + override val datePattern: String = "dd/MM/yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MaidSecret.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MaidSecret.kt new file mode 100644 index 00000000..3b339f7b --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MaidSecret.kt @@ -0,0 +1,13 @@ +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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MAIDSECRET", "MaidSecret", "pt") +internal class MaidSecret(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.MAIDSECRET, "maidsecret.com", 10) { + override val datePattern: String = "dd/MM/yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MangaNinja.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MangaNinja.kt new file mode 100644 index 00000000..df0c58b3 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MangaNinja.kt @@ -0,0 +1,13 @@ +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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGANINJA", "MangaNinja", "pt") +internal class MangaNinja(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.MANGANINJA, "manganinja.com", 10) { + override val datePattern: String = "dd/MM/yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MrBenne.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MrBenne.kt new file mode 100644 index 00000000..45ec457a --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MrBenne.kt @@ -0,0 +1,41 @@ +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.ContentType +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaTag +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +import org.koitharu.kotatsu.parsers.util.domain +import org.koitharu.kotatsu.parsers.util.mapNotNullToSet +import org.koitharu.kotatsu.parsers.util.parseHtml +import org.koitharu.kotatsu.parsers.util.toTitleCase + +@MangaSourceParser("MRBENNE", "MrBenne", "pt", ContentType.HENTAI) +internal class MrBenne(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.MRBENNE, "mrbenne.com", 10) { + override val datePattern: String = "dd/MM/yyyy" + + override suspend fun getAvailableTags(): Set { + val doc = webClient.httpGet("https://$domain/?s=&post_type=wp-manga").parseHtml() + val body = doc.body() + val root = body.selectFirst("div.form-group.checkbox-group") + val list = root?.select("div.checkbox").orEmpty() + val keySet = HashSet(list.size) + return list.mapNotNullToSet { div -> + val input = div.selectFirst("input") ?: return@mapNotNullToSet null + val label = div.selectFirst("label") ?: return@mapNotNullToSet null + val tag = input.attr("value") + if (tag.isEmpty() || !keySet.add(tag)) { + return@mapNotNullToSet null + } + MangaTag( + key = tag, + title = label.ownText().ifEmpty { + tag + }.toTitleCase(sourceLocale), + source = source, + ) + } + } +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MugiwarasOficial.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MugiwarasOficial.kt new file mode 100644 index 00000000..808383f4 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/MugiwarasOficial.kt @@ -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.MangaParserSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MUGIWARASOFICIAL", "MugiwarasOficial", "pt") +internal class MugiwarasOficial(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.MUGIWARASOFICIAL, "mugiwarasoficial.com") { + override val datePattern: String = "dd/MM/yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Neoxscans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Neoxscans.kt index b1a11a15..969144ed 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Neoxscans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Neoxscans.kt @@ -28,7 +28,8 @@ internal class Neoxscans(context: MangaLoaderContext) : id = generateUid(href), url = link, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/NinjaScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/NinjaScan.kt index 0e73517c..7da846dd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/NinjaScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/NinjaScan.kt @@ -5,8 +5,8 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("NINJASCAN", "NinjaScan", "pt") +@MangaSourceParser("NINJASCAN", "NinjaComics", "pt") internal class NinjaScan(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.NINJASCAN, "ninjascan.site") { + MadaraParser(context, MangaParserSource.NINJASCAN, "ninjacomics.xyz") { override val datePattern: String = "dd 'de' MMMMM 'de' yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Norterose.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Norterose.kt new file mode 100644 index 00000000..304a0c22 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Norterose.kt @@ -0,0 +1,13 @@ +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("NORTEROSE", "Norterose", "pt") +internal class Norterose(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.NORTEROSE, "norterose.com.br", 10) { + override val datePattern: String = "dd/MM/yyyy" + override val withoutAjax = true +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/SinensisScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/SinensisScans.kt index 555aaea4..54e2e1c9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/SinensisScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/SinensisScans.kt @@ -1,10 +1,12 @@ 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.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +@Broken // Not dead, changed template @MangaSourceParser("SINENSISSCANS", "SinensisScans", "pt") internal class SinensisScans(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.SINENSISSCANS, "sinensistoon.com") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/SussyScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/SussyScan.kt index 7db16146..df735e7b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/SussyScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/SussyScan.kt @@ -7,6 +7,4 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("SUSSYSCAN", "SussyScan", "pt") internal class SussyScan(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.SUSSYSCAN, "sussyscan.com") { - override val datePattern: String = "dd/MM/yyyy" -} + MadaraParser(context, MangaParserSource.SUSSYSCAN, "oldi.sussytoons.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Manhuabug.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Manhuabug.kt index e1d291b3..1293bec9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Manhuabug.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Manhuabug.kt @@ -11,4 +11,5 @@ internal class Manhuabug(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.MANHUABUG, "www.manhuabug.com", 10) { override val datePattern: String = "d MMMM yyyy" override val sourceLocale: Locale = Locale.ENGLISH + override val selectPage = "img" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Manhuakey.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Manhuakey.kt index d7efd12b..f6e45fd8 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Manhuakey.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Manhuakey.kt @@ -11,4 +11,5 @@ internal class Manhuakey(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.MANHUAKEY, "www.manhuakey.com", 10) { override val datePattern: String = "d MMMM yyyy" override val sourceLocale: Locale = Locale.ENGLISH + override val selectPage = "img" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/GloryManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/GloryManga.kt index 9f2ea4de..436e4367 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/GloryManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/GloryManga.kt @@ -5,6 +5,7 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +//This source requires an account. @MangaSourceParser("GLORYMANGA", "GloryManga", "tr") internal class GloryManga(context: MangaLoaderContext) : MadaraParser(context, MangaParserSource.GLORYMANGA, "glorymanga.com", 18) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Grimelek.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Grimelek.kt new file mode 100644 index 00000000..9a189d74 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Grimelek.kt @@ -0,0 +1,15 @@ +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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +//This source requires an account. +@MangaSourceParser("GRIMELEK", "Grimelek", "tr") +internal class Grimelek(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.GRIMELEK, "glorymanga.com", 20) { + override val datePattern = "d MMMM yyyy" + override val listUrl = "seri/" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Jiangzaitoon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Jiangzaitoon.kt index a10873c4..f70678a1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Jiangzaitoon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/Jiangzaitoon.kt @@ -8,6 +8,7 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("JIANGZAITOON", "JiangzaiToon", "tr", ContentType.HENTAI) internal class Jiangzaitoon(context: MangaLoaderContext) : - MadaraParser(context, MangaParserSource.JIANGZAITOON, "jiangzaitoon.cc") { + MadaraParser(context, MangaParserSource.JIANGZAITOON, "jiangzaitoon.dev") { override val datePattern = "d MMMM yyyy" + override val postReq = true } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MerlinScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MerlinScans.kt new file mode 100644 index 00000000..49c2256d --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MerlinScans.kt @@ -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.MangaParserSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +//Images blocked by ReCAPTCHA +@MangaSourceParser("MERLINSCANS", "MerlinScans", "tr") +internal class MerlinScans(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.MERLINSCANS, "merlinscans.com", 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MilaSub.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MilaSub.kt new file mode 100644 index 00000000..dbdf6617 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/MilaSub.kt @@ -0,0 +1,13 @@ +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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MILASUB", "MilaSub", "tr") +internal class MilaSub(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.MILASUB, "www.milasub.co", 20) { + override val datePattern = "d MMMM yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/OpiaToon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/OpiaToon.kt new file mode 100644 index 00000000..eeea2920 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/OpiaToon.kt @@ -0,0 +1,14 @@ +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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +//This source requires an account. +@MangaSourceParser("OPIATOON", "OpiaToon", "tr") +internal class OpiaToon(context: MangaLoaderContext) : + MadaraParser(context, MangaParserSource.OPIATOON, "opiatoon.biz", 20) { + override val datePattern = "d MMMM" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/TitanManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/TitanManga.kt index 11c56791..4c66f304 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/TitanManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/tr/TitanManga.kt @@ -24,7 +24,8 @@ internal class TitanManga(context: MangaLoaderContext) : id = generateUid(href), url = link, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = 0, scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/TruyenTranhDamMyy.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/TruyenTranhDamMyy.kt index e2c8885d..6988ae02 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/TruyenTranhDamMyy.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/TruyenTranhDamMyy.kt @@ -26,7 +26,8 @@ internal class TruyenTranhDamMyy(context: MangaLoaderContext) : id = generateUid(href), url = link, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = 0, // Correct datePattern not found. scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt index 8f47e9d2..aed6beb6 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/MadthemeParser.kt @@ -207,7 +207,8 @@ internal abstract class MadthemeParser( MangaChapter( id = generateUid(href), name = li.selectFirstOrThrow(".chapter-title").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/MangaJinx.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/MangaJinx.kt index 46dafe87..726e65d5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/MangaJinx.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/MangaJinx.kt @@ -26,7 +26,8 @@ internal class MangaJinx(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = li.selectFirstOrThrow(".chapter-title").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/ManhuaScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/ManhuaScan.kt index a8b4d8a7..9e9f64ed 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/ManhuaScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madtheme/en/ManhuaScan.kt @@ -108,7 +108,8 @@ internal class ManhuaScan(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = li.selectFirstOrThrow(".chapter-title").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt index 128a2e7c..f8bd2ea0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt @@ -182,7 +182,8 @@ internal abstract class Manga18Parser( MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = dateFormat.tryParse(dateText), source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/zh/Hanman18.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/zh/Hanman18.kt index b56ec481..6181d3af 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/zh/Hanman18.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/zh/Hanman18.kt @@ -24,7 +24,8 @@ internal class Hanman18(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = 0, source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/MangaboxParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/MangaboxParser.kt index 41568cd8..a887ab0b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/MangaboxParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/MangaboxParser.kt @@ -200,7 +200,8 @@ internal abstract class MangaboxParser( MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/Mangakakalot.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/Mangakakalot.kt index 63628fc9..9e95a365 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/Mangakakalot.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/Mangakakalot.kt @@ -32,7 +32,9 @@ internal class Mangakakalot(context: MangaLoaderContext) : is MangaListFilter.Search -> { append(searchUrl) - append(filter.query.urlEncoded()) + val regex = Regex("[^A-Za-z0-9 ]") + val q = regex.replace(filter.query, "") + append(q.replace(" ", "_")) append("?page=") } @@ -125,7 +127,8 @@ internal class Mangakakalot(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt index 9be9f96e..6d3089da 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/MangaReaderParser.kt @@ -29,6 +29,13 @@ internal abstract class MangaReaderParser( override val configKeyDomain = ConfigKey.Domain(domain) + private val userAgentKey = ConfigKey.UserAgent(context.getDefaultUserAgent()) + + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(userAgentKey) + } + override val availableSortOrders: Set get() = EnumSet.of( SortOrder.UPDATED, @@ -156,7 +163,8 @@ internal abstract class MangaReaderParser( id = generateUid(url), name = element.selectFirst(".chapternum")?.text() ?: "Chapter ${index + 1}", url = url, - number = index + 1, + number = index + 1f, + volume = 0, scanlator = null, uploadDate = dateFormat.tryParse(element.selectFirst(".chapterdate")?.text()), branch = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Eliton.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Eliton.kt deleted file mode 100644 index e0dfa594..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Eliton.kt +++ /dev/null @@ -1,12 +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.MangaParserSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("ELITON", "ThunderScans", "ar") -internal class Eliton(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.ELITON, "thunderscans.com", pageSize = 20, searchPageSize = 10) { - override val isTagsExclusionSupported = false -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Manjanoon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Manjanoon.kt index a9fed46c..eca40fca 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Manjanoon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Manjanoon.kt @@ -20,7 +20,8 @@ internal class Manjanoon(context: MangaLoaderContext) : id = generateUid(url), name = element.selectFirst(".chapternum")?.text() ?: "Chapter ${index + 1}", url = url, - number = index + 1, + number = index + 1f, + volume = 0, scanlator = null, uploadDate = 0, branch = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Normoyun.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Normoyun.kt index 49aa6290..2e1a89da 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Normoyun.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/Normoyun.kt @@ -10,7 +10,7 @@ import java.text.SimpleDateFormat @MangaSourceParser("NORMOYUN", "Normoyun", "ar") internal class Normoyun(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.NORMOYUN, "normoyun.com", pageSize = 42, searchPageSize = 39) { + MangaReaderParser(context, MangaParserSource.NORMOYUN, "t1manga.com", pageSize = 42, searchPageSize = 39) { override val datePattern = "MMMM dd, yyyy" override val selectMangaList = ".listupd .bs .bsx" @@ -86,7 +86,8 @@ internal class Normoyun(context: MangaLoaderContext) : id = generateUid(url), name = element.selectFirst("a")?.text() ?: "Chapter ${index + 1}", url = url, - number = index + 1, + number = index + 1f, + volume = 0, scanlator = null, uploadDate = dateFormat.tryParse(element.selectFirst(".chapter-date")?.text()), branch = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/PeachBl.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/PeachBl.kt new file mode 100644 index 00000000..3435fbda --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/PeachBl.kt @@ -0,0 +1,14 @@ +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.ContentType +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser +import java.util.* + +@MangaSourceParser("PEACHBL", "PeachBl", "ar", ContentType.HENTAI) +internal class PeachBl(context: MangaLoaderContext) : + MangaReaderParser(context, MangaParserSource.PEACHBL, "peach-bl.com", pageSize = 20, searchPageSize = 10) { + override val sourceLocale: Locale = Locale.ENGLISH +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/ThunderScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/ThunderScans.kt index c6f757e9..d47e5dc4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/ThunderScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/ThunderScans.kt @@ -7,4 +7,7 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("THUNDERSCANS", "ThunderScans", "ar") internal class ThunderScans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.THUNDERSCANS, "thunderscans.com", pageSize = 32, searchPageSize = 10) + MangaReaderParser(context, MangaParserSource.THUNDERSCANS, "thunderscans.com", pageSize = 32, searchPageSize = 10) { + override val isTagsExclusionSupported = false + override val selectChapter = ".eplister > ul > li" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/UmiManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/UmiManga.kt index add09cce..e19efbc1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/UmiManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/UmiManga.kt @@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("UMIMANGA", "UmiManga", "ar") -internal class BeastScans(context: MangaLoaderContext) : +internal class UmiManga(context: MangaLoaderContext) : MangaReaderParser(context, MangaParserSource.UMIMANGA, "www.umimanga.com", pageSize = 20, searchPageSize = 10) { override val isTagsExclusionSupported = false } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/VexManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/VexManga.kt index e83cdff1..cd10379a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/VexManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/ar/VexManga.kt @@ -28,7 +28,8 @@ internal class VexManga(context: MangaLoaderContext) : id = generateUid(url), name = element.selectFirst(".chapternum")?.text() ?: "Chapter ${index + 1}", url = url, - number = index + 1, + number = index + 1f, + volume = 0, scanlator = null, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ArvenScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ArvenScans.kt index 7f7898c9..cf511e41 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ArvenScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ArvenScans.kt @@ -5,8 +5,8 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -@MangaSourceParser("ARVENSCANS", "ArvenScans", "en") +@MangaSourceParser("ARVENSCANS", "ArvenComics", "en") internal class ArvenScans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.ARVENSCANS, "arvenscans.org", pageSize = 20, searchPageSize = 10) { + MangaReaderParser(context, MangaParserSource.ARVENSCANS, "arvencomics.com", pageSize = 20, searchPageSize = 10) { override val listUrl = "/series" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Constellarcomic.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Constellarcomic.kt index 225d07dd..118ddbee 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Constellarcomic.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Constellarcomic.kt @@ -29,7 +29,8 @@ internal class Constellarcomic(context: MangaLoaderContext) : id = generateUid(url), name = element.selectFirst(".chapternum")?.textOrNull() ?: "Chapter ${index + 1}", url = url, - number = index + 1, + number = index + 1f, + volume = 0, scanlator = null, uploadDate = 0, branch = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ErosScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ErosScans.kt new file mode 100644 index 00000000..ac06df6f --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ErosScans.kt @@ -0,0 +1,11 @@ +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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser + +@MangaSourceParser("EROSSCANS", "ErosScans", "en") +internal class ErosScans(context: MangaLoaderContext) : + MangaReaderParser(context, MangaParserSource.EROSSCANS, "erosscans.xyz", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/FlameComics.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/FlameComics.kt index 7124d386..b926e299 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/FlameComics.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/FlameComics.kt @@ -7,6 +7,6 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("FLAMECOMICS", "FlameComics", "en") internal class FlameComics(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.FLAMECOMICS, "flamecomics.com", pageSize = 24, searchPageSize = 10) { + MangaReaderParser(context, MangaParserSource.FLAMECOMICS, "flamecomics.me", pageSize = 24, searchPageSize = 10) { override val listUrl = "/series" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/FreakScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/FreakScans.kt index de7ed6e2..dfb0bdb8 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/FreakScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/FreakScans.kt @@ -1,10 +1,12 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en +import org.koitharu.kotatsu.parsers.Broken 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 +@Broken @MangaSourceParser("FREAKSCANS", "FreakScans", "en") internal class FreakScans(context: MangaLoaderContext) : MangaReaderParser(context, MangaParserSource.FREAKSCANS, "freakscans.com", pageSize = 20, searchPageSize = 20) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/KaiScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/KaiScans.kt index 307ad053..6b657038 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/KaiScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/KaiScans.kt @@ -8,6 +8,5 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("KAISCANS", "KaiScans", "en") internal class KaiScans(context: MangaLoaderContext) : MangaReaderParser(context, MangaParserSource.KAISCANS, "kaiscans.org", pageSize = 20, searchPageSize = 10) { - override val listUrl = "/series" override val isTagsExclusionSupported = false } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LuminousScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LuminousScans.kt index bd5bcb5b..af7220b3 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LuminousScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LuminousScans.kt @@ -7,7 +7,14 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("LUMINOUSSCANS", "LuminousScans", "en") internal class LuminousScans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.LUMINOUSSCANS, "lumitoon.com", pageSize = 20, searchPageSize = 10) { + MangaReaderParser( + context, + MangaParserSource.LUMINOUSSCANS, + "luminous-scans.com", + pageSize = 20, + searchPageSize = 10, + ) { + override val listUrl = "/series" override val isTagsExclusionSupported = false } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhwaFreak.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhwaFreak.kt index ed93a8e7..112ffe58 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhwaFreak.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhwaFreak.kt @@ -1,215 +1,10 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en -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.model.MangaParserSource 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("MANHWA_FREAK", "Manhwa-Freak.com", "en") +@MangaSourceParser("MANHWA_FREAK", "ManhwaFreak", "en") internal class ManhwaFreak(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.MANHWA_FREAK, "manhwa-freak.com", pageSize = 0, searchPageSize = 10) { - - override val selectMangaList = ".listupd .lastest-serie" - override val selectMangaListImg = "img" - override val availableStates: Set = emptySet() - override val isMultipleTagsSupported = false - override val isTagsExclusionSupported = false - - override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { - 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 { - 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): 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 - } - } -} + MangaReaderParser(context, MangaParserSource.MANHWA_FREAK, "manhwafreak.site", pageSize = 20, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt index fb69fb5e..71db541b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/RizzComic.kt @@ -15,6 +15,7 @@ import java.util.* @MangaSourceParser("RIZZCOMIC", "RizzComic", "en") internal class RizzComic(context: MangaLoaderContext) : MangaReaderParser(context, MangaParserSource.RIZZCOMIC, "rizzfables.com", pageSize = 50, searchPageSize = 20) { + override val datePattern = "dd MMM yyyy" override val listUrl = "/series" override val availableSortOrders: Set = EnumSet.of( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/TenkaiScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/TenkaiScan.kt index afd72471..cd7fef00 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/TenkaiScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/TenkaiScan.kt @@ -1,5 +1,6 @@ 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.MangaSourceParser import org.koitharu.kotatsu.parsers.model.ContentType @@ -7,6 +8,7 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser import java.util.* +@Broken // Not dead, changed template @MangaSourceParser("TENKAISCAN", "TenkaiScan", "es", ContentType.HENTAI) internal class TenkaiScan(context: MangaLoaderContext) : MangaReaderParser(context, MangaParserSource.TENKAISCAN, "tenkaiscan.net", 20, 10) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/TuManhwas.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/TuManhwas.kt index fcaf823f..1314b7cd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/TuManhwas.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/TuManhwas.kt @@ -58,7 +58,8 @@ internal class TuManhwas(context: MangaLoaderContext) : id = generateUid(url), name = element.selectFirst(".chapternum")?.textOrNull() ?: "Chapter ${index + 1}", url = url, - number = index + 1, + number = index + 1f, + volume = 0, scanlator = null, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/BananaScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/BananaScan.kt index b490e528..0f451225 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/BananaScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/BananaScan.kt @@ -1,10 +1,12 @@ package org.koitharu.kotatsu.parsers.site.mangareader.fr +import org.koitharu.kotatsu.parsers.Broken 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 +@Broken @MangaSourceParser("BANANASCAN", "BananaScan", "fr") internal class BananaScan(context: MangaLoaderContext) : MangaReaderParser(context, MangaParserSource.BANANASCAN, "banana-scan.com", pageSize = 20, searchPageSize = 20) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/LunarScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/LunarScans.kt index fdc7e9ad..dc0ff249 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/LunarScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/LunarScans.kt @@ -1,10 +1,12 @@ package org.koitharu.kotatsu.parsers.site.mangareader.fr +import org.koitharu.kotatsu.parsers.Broken 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 +@Broken @MangaSourceParser("LUNARSCANS", "LunarScans", "fr") internal class LunarScans(context: MangaLoaderContext) : MangaReaderParser(context, MangaParserSource.LUNARSCANS, "lunarscans.fr", pageSize = 20, searchPageSize = 10) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/MangasScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/MangasScans.kt new file mode 100644 index 00000000..4a7b65df --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/MangasScans.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.mangareader.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.mangareader.MangaReaderParser + +@MangaSourceParser("MANGASSCANS", "MangasScans", "fr") +internal class MangasScans(context: MangaLoaderContext) : + MangaReaderParser(context, MangaParserSource.MANGASSCANS, "mangas-scans.com", pageSize = 30, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/RimuScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/RimuScans.kt new file mode 100644 index 00000000..3d98ae7b --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/RimuScans.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.mangareader.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser + +@MangaSourceParser("RIMUSCANS", "RimuScans", "fr") +internal class RimuScans(context: MangaLoaderContext) : + MangaReaderParser(context, MangaParserSource.RIMUSCANS, "rimuscans.fr", pageSize = 30, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/SushiScanFR.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/SushiScanFR.kt index f4887064..8bfbb508 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/SushiScanFR.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/fr/SushiScanFR.kt @@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -@MangaSourceParser("SUSHISCANFR", "Anime-Sama.me", "fr") +@MangaSourceParser("SUSHISCANFR", "SushiScan.fr", "fr") internal class SushiScanFR(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.SUSHISCANFR, "anime-sama.me", pageSize = 36, searchPageSize = 10) + MangaReaderParser(context, MangaParserSource.SUSHISCANFR, "sushiscan.fr", pageSize = 36, searchPageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/AlterkaiScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/AlterkaiScans.kt new file mode 100644 index 00000000..87bc87fe --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/AlterkaiScans.kt @@ -0,0 +1,19 @@ +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.* + +@MangaSourceParser("ALTERKAISCANS", "AlterkaiScans", "id") +internal class AlterkaiScans(context: MangaLoaderContext) : + MangaReaderParser( + context, + MangaParserSource.ALTERKAISCANS, + "alterkaiscans.my.id", + pageSize = 20, + searchPageSize = 10, + ) { + override val sourceLocale: Locale = Locale.ENGLISH +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikTapParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikTapParser.kt index 1d964fe4..ed02edcb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikTapParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KomikTapParser.kt @@ -2,13 +2,12 @@ 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.MangaParserSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -import java.util.* -@MangaSourceParser("KOMIKTAP", "KomikTap", "id") +@MangaSourceParser("KOMIKTAP", "KomikTap", "id", ContentType.HENTAI) internal class KomikTapParser(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.KOMIKTAP, "komiktap.me", pageSize = 25, searchPageSize = 10) { - override val sourceLocale: Locale = Locale.ENGLISH + MangaReaderParser(context, MangaParserSource.KOMIKTAP, "komiktap.info", pageSize = 25, searchPageSize = 10) { override val isTagsExclusionSupported = false } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt index dcfe0e1c..f0792ad9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Komikcast.kt @@ -13,7 +13,7 @@ import java.util.* @MangaSourceParser("KOMIKCAST", "KomikCast", "id") internal class Komikcast(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.KOMIKCAST, "komikcast.lol", pageSize = 60, searchPageSize = 28) { + MangaReaderParser(context, MangaParserSource.KOMIKCAST, "komikcast.cz", pageSize = 60, searchPageSize = 28) { override val listUrl = "/daftar-komik" override val datePattern = "MMM d, yyyy" @@ -90,7 +90,8 @@ internal class Komikcast(context: MangaLoaderContext) : id = generateUid(url), name = element.selectFirst("a.chapter-link-item")?.ownText().orEmpty(), url = url, - number = index + 1, + number = index + 1f, + volume = 0, scanlator = null, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/MiHentai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/MiHentai.kt new file mode 100644 index 00000000..8eb841ac --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/MiHentai.kt @@ -0,0 +1,15 @@ +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.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser + +@MangaSourceParser("MIHENTAI", "MiHentai", "id", ContentType.HENTAI) +internal class MiHentai(context: MangaLoaderContext) : + MangaReaderParser(context, MangaParserSource.MIHENTAI, "mihentai.com", pageSize = 30, searchPageSize = 10) { + override val datePattern = "MMM d, yyyy" + override val isTagsExclusionSupported = false +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Ngomik.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Ngomik.kt new file mode 100644 index 00000000..87775108 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/Ngomik.kt @@ -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.* + +@MangaSourceParser("NGOMIK", "Ngomik", "id") +internal class Ngomik(context: MangaLoaderContext) : + MangaReaderParser(context, MangaParserSource.NGOMIK, "ngomik.mom", pageSize = 20, searchPageSize = 5) { + override val sourceLocale: Locale = Locale.ENGLISH +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/pt/MangasChan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/pt/MangasChan.kt index 0a392f66..0305b196 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/pt/MangasChan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/pt/MangasChan.kt @@ -1,10 +1,12 @@ 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.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser +@Broken @MangaSourceParser("MANGASCHAN", "MangasChan", "pt") internal class MangasChan(context: MangaLoaderContext) : MangaReaderParser(context, MangaParserSource.MANGASCHAN, "mangaschan.net", pageSize = 20, searchPageSize = 20) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/Mangaokutr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/Mangaokutr.kt index ecb02ea0..049d3f86 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/Mangaokutr.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/Mangaokutr.kt @@ -5,6 +5,6 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -@MangaSourceParser("MANGAOKUTR", "MangaOku Tr", "tr") +@MangaSourceParser("MANGAOKUTR", "MangaOkuTr", "tr") internal class Mangaokutr(context: MangaLoaderContext) : MangaReaderParser(context, MangaParserSource.MANGAOKUTR, "mangaokutr.com", pageSize = 25, searchPageSize = 20) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/MerlinScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/MerlinScans.kt deleted file mode 100644 index ada8480c..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/MerlinScans.kt +++ /dev/null @@ -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.MangaParserSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("MERLINSCANS", "MerlinScans", "tr") -internal class MerlinScans(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.MERLINSCANS, "merlinscans.com", pageSize = 25, searchPageSize = 20) { - override val isTagsExclusionSupported = false -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/MilaSub.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/MilaSub.kt deleted file mode 100644 index cc55e1ee..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/tr/MilaSub.kt +++ /dev/null @@ -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.MangaParserSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - -@MangaSourceParser("MILASUB", "MilaSub", "tr") -internal class MilaSub(context: MangaLoaderContext) : - MangaReaderParser(context, MangaParserSource.MILASUB, "www.milasub.com", pageSize = 20, searchPageSize = 10) { - override val isTagsExclusionSupported = false -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt index 553493e7..6199ad6e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt @@ -24,6 +24,7 @@ internal abstract class MmrcmsParser( SortOrder.POPULARITY, SortOrder.UPDATED, SortOrder.ALPHABETICAL, + SortOrder.ALPHABETICAL_DESC, ) protected open val listUrl = "filterList" @@ -103,7 +104,7 @@ internal abstract class MmrcmsParser( } append("&sortBy=") when (filter.sortOrder) { - SortOrder.POPULARITY -> append("views&asc=true") + SortOrder.POPULARITY -> append("views&asc=false") SortOrder.ALPHABETICAL -> append("name&asc=true") SortOrder.ALPHABETICAL_DESC -> append("name&asc=false") else -> append("name") @@ -231,7 +232,8 @@ internal abstract class MmrcmsParser( MangaChapter( id = generateUid(href), name = li.selectFirstOrThrow("h5").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = dateFormat.tryParse(dateText), source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/BananaScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/BananaScan.kt new file mode 100644 index 00000000..0dbba8fd --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/BananaScan.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser + +@MangaSourceParser("BANANASCAN_COM", "BananaScan.Com", "en") +internal class BananaScan(context: MangaLoaderContext) : + MmrcmsParser(context, MangaParserSource.BANANASCAN_COM, "bananascans.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/es/MangaDoor.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/es/MangaDoor.kt index 8482e19b..aac1938b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/es/MangaDoor.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/es/MangaDoor.kt @@ -1,11 +1,13 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.es +import org.koitharu.kotatsu.parsers.Broken 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.* +@Broken @MangaSourceParser("MANGADOOR", "MangaDoor", "es") internal class MangaDoor(context: MangaLoaderContext) : MmrcmsParser(context, MangaParserSource.MANGADOOR, "mangadoor.com") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/BentoScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/BentoScan.kt index feb288c0..89365e19 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/BentoScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/BentoScan.kt @@ -10,4 +10,5 @@ import java.util.* internal class BentoScan(context: MangaLoaderContext) : MmrcmsParser(context, MangaParserSource.BENTOSCAN, "bentoscan.com") { override val sourceLocale: Locale = Locale.ENGLISH + override val imgUpdated = ".jpg" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/FrScansCom.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/FrScansCom.kt index 2cce6815..ac1c288a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/FrScansCom.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/FrScansCom.kt @@ -1,11 +1,13 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.fr +import org.koitharu.kotatsu.parsers.Broken 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.* +@Broken @MangaSourceParser("FRSCANSCOM", "FrScans.com", "fr") internal class FrScansCom(context: MangaLoaderContext) : MmrcmsParser(context, MangaParserSource.FRSCANSCOM, "frscans.com") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpMangas.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpMangas.kt index f332b494..b6ba8755 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpMangas.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpMangas.kt @@ -1,11 +1,13 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.fr +import org.koitharu.kotatsu.parsers.Broken 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.* +@Broken @MangaSourceParser("JPMANGAS", "JpMangas", "fr") internal class JpMangas(context: MangaLoaderContext) : MmrcmsParser(context, MangaParserSource.JPMANGAS, "jpmangas.xyz") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpScanVf.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpScanVf.kt index 30dacff8..b94c7689 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpScanVf.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpScanVf.kt @@ -1,12 +1,13 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.fr +import org.koitharu.kotatsu.parsers.Broken 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.* -//the search doesn't work on the source. +@Broken @MangaSourceParser("JPSCANVF", "LireScanVf.com", "fr") internal class JpScanVf(context: MangaLoaderContext) : MmrcmsParser(context, MangaParserSource.JPSCANVF, "lirescanvf.com") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaScan.kt index 5851197e..62a8ad5e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaScan.kt @@ -8,7 +8,7 @@ import java.util.* @MangaSourceParser("MANGA_SCAN", "MangaScan", "fr") internal class MangaScan(context: MangaLoaderContext) : - MmrcmsParser(context, MangaParserSource.MANGA_SCAN, "mangascan-fr.com") { + MmrcmsParser(context, MangaParserSource.MANGA_SCAN, "mangascan-fr.co") { override val imgUpdated = ".jpg" override val sourceLocale: Locale = Locale.ENGLISH } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanManga.kt index df759975..4db7839b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanManga.kt @@ -1,11 +1,13 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.fr +import org.koitharu.kotatsu.parsers.Broken 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.* +@Broken @MangaSourceParser("SCANMANGA", "ScanManga", "fr") internal class ScanManga(context: MangaLoaderContext) : MmrcmsParser(context, MangaParserSource.SCANMANGA, "scan-manga.me") { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanMangaVfWs.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanMangaVfWs.kt index 1c5344f9..5e3e39cf 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanMangaVfWs.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanMangaVfWs.kt @@ -8,7 +8,7 @@ import java.util.* @MangaSourceParser("SCANMANGAVF_WS", "ScanMangaVf.ws", "fr") internal class ScanMangaVfWs(context: MangaLoaderContext) : - MmrcmsParser(context, MangaParserSource.SCANMANGAVF_WS, "scanmanga-vf.ws") { + MmrcmsParser(context, MangaParserSource.SCANMANGAVF_WS, "scanmanga-vf.me") { override val imgUpdated = ".jpg" override val selectTag = "dt:contains(Genres)" override val selectAlt = "dt:contains(Appelé aussi)" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/nepnep/NepnepParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/nepnep/NepnepParser.kt index 796e1c05..6790cff9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/nepnep/NepnepParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/nepnep/NepnepParser.kt @@ -61,7 +61,7 @@ internal abstract class NepnepParser( val imgUrl = "https://temp.compsci88.com/cover/" + m.getString("i") + ".jpg" val lastUpdate = m.getLong("lt") val views = m.getString("v") - val viewMonth = m.getString("vm") + //val viewMonth = m.getString("vm") when (filter) { @@ -223,7 +223,8 @@ internal abstract class NepnepParser( MangaChapter( id = generateUid(url), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = dateFormat.tryParse(date), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/otakusanctuary/OtakuSanctuaryParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/otakusanctuary/OtakuSanctuaryParser.kt index 279339ef..6ca8477f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/otakusanctuary/OtakuSanctuaryParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/otakusanctuary/OtakuSanctuaryParser.kt @@ -186,7 +186,8 @@ internal abstract class OtakuSanctuaryParser( MangaChapter( id = generateUid(url), name = name, - number = i, + number = i.toFloat(), + volume = 0, url = url, scanlator = null, uploadDate = parseChapterDate( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pizzareader/PizzaReaderParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pizzareader/PizzaReaderParser.kt index 60bb824c..bd136ef9 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pizzareader/PizzaReaderParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pizzareader/PizzaReaderParser.kt @@ -231,7 +231,8 @@ internal abstract class PizzaReaderParser( MangaChapter( id = generateUid(url), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = dateFormat.tryParse(date), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/BrMangas.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/BrMangas.kt index 4c4787a0..b4bce1f6 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/BrMangas.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/BrMangas.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.parsers.site.pt import okhttp3.Headers +import org.koitharu.kotatsu.parsers.Broken import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser @@ -10,6 +11,7 @@ import org.koitharu.kotatsu.parsers.network.UserAgents import org.koitharu.kotatsu.parsers.util.* import java.util.* +@Broken @MangaSourceParser("BRMANGAS", "BrMangas", "pt") internal class BrMangas(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.BRMANGAS, 25) { @@ -141,7 +143,8 @@ internal class BrMangas(context: MangaLoaderContext) : PagedMangaParser(context, MangaChapter( id = generateUid(url), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerManga.kt index e31c543e..a1583931 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerManga.kt @@ -121,7 +121,8 @@ class LerManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaPar MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, uploadDate = dateFormat.tryParse(div.selectFirstOrThrow("small small").text()), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerMangaOnline.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerMangaOnline.kt index e266095d..d3f8fc35 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerMangaOnline.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LerMangaOnline.kt @@ -114,7 +114,8 @@ class LerMangaOnline(context: MangaLoaderContext) : PagedMangaParser(context, Ma MangaChapter( id = generateUid(href), name = title, - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, uploadDate = dateFormat.tryParse(dateText), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LuratoonScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LuratoonScansParser.kt index edd4c971..70c73063 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LuratoonScansParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/LuratoonScansParser.kt @@ -6,23 +6,21 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.Response import okhttp3.ResponseBody.Companion.toResponseBody import org.json.JSONArray -import org.koitharu.kotatsu.parsers.ErrorMessages -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaParser -import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.* import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.zip.ZipInputStream -@MangaSourceParser("RANDOMSCANS", "Luratoon Scan", "pt") +@Broken // Not dead but totally changed structure +@MangaSourceParser("RANDOMSCANS", "LuratoonScan", "pt") internal class LuratoonScansParser(context: MangaLoaderContext) : MangaParser(context, MangaParserSource.RANDOMSCANS), Interceptor { override val availableSortOrders = setOf(SortOrder.ALPHABETICAL) - override val configKeyDomain = ConfigKey.Domain("luratoon.com") + override val configKeyDomain = ConfigKey.Domain("luratoons.com") private val userAgentKey = ConfigKey.UserAgent(context.getDefaultUserAgent()) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MangaOnline.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MangaOnline.kt index 780e1626..1dff1b2d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MangaOnline.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MangaOnline.kt @@ -104,7 +104,8 @@ class MangaOnline(context: MangaLoaderContext) : PagedMangaParser(context, Manga MangaChapter( id = generateUid(href), name = title, - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, uploadDate = dateFormat.tryParse(dateText), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MuitoHentai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MuitoHentai.kt index 0d972cef..40a06503 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MuitoHentai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/MuitoHentai.kt @@ -99,7 +99,8 @@ class MuitoHentai(context: MangaLoaderContext) : PagedMangaParser(context, Manga MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/OnePieceEx.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/OnePieceEx.kt index 5094c53f..e9891e3a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/OnePieceEx.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/OnePieceEx.kt @@ -73,7 +73,8 @@ class OnePieceEx(context: MangaLoaderContext) : PagedMangaParser(context, MangaP MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, uploadDate = 0, @@ -92,7 +93,8 @@ class OnePieceEx(context: MangaLoaderContext) : PagedMangaParser(context, MangaP MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/YugenMangas.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/YugenMangas.kt index c8673c0d..595377b2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/YugenMangas.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/pt/YugenMangas.kt @@ -12,11 +12,11 @@ import java.text.DateFormat import java.text.SimpleDateFormat import java.util.* -@MangaSourceParser("YUGENMANGAS", "YugenMangas.net.br", "pt") +@MangaSourceParser("YUGENMANGAS", "YugenApp", "pt") class YugenMangas(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.YUGENMANGAS, 28) { - override val availableSortOrders: Set = EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.UPDATED) - override val configKeyDomain = ConfigKey.Domain("yugenmangas.net.br") + override val availableSortOrders: Set = EnumSet.of(SortOrder.UPDATED, SortOrder.ALPHABETICAL) + override val configKeyDomain = ConfigKey.Domain("yugenapp.lat") override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { @@ -32,7 +32,7 @@ class YugenMangas(context: MangaLoaderContext) : PagedMangaParser(context, Manga val url = buildString { append("https://api.") append(domain) - append("/api/series/list/?query=") + append("/api/series/?search=") append(filter.query.urlEncoded()) } webClient.httpGet(url).parseJsonArray() @@ -40,7 +40,6 @@ class YugenMangas(context: MangaLoaderContext) : PagedMangaParser(context, Manga is MangaListFilter.Advanced -> { - if (filter.sortOrder == SortOrder.UPDATED) { val url = buildString { append("https://api.") @@ -52,7 +51,7 @@ class YugenMangas(context: MangaLoaderContext) : PagedMangaParser(context, Manga val url = buildString { append("https://api.") append(domain) - append("/api/all_series/") + append("/api/series_novels/all_series/") } webClient.httpGet(url).parseJson().getJSONArray("series") } @@ -73,7 +72,7 @@ class YugenMangas(context: MangaLoaderContext) : PagedMangaParser(context, Manga val slug = j.getString("slug") val cover = if (!j.getString("cover").startsWith("https://")) { // Some covers don't have the "/" so we ensure that the URL will be spelled correctly. - "https://$domain/media/" + j.getString("cover").removePrefix("/") + "https://api.$domain/media/" + j.getString("cover").removePrefix("/") } else { j.getString("cover") } @@ -97,11 +96,12 @@ class YugenMangas(context: MangaLoaderContext) : PagedMangaParser(context, Manga override suspend fun getDetails(manga: Manga): Manga { val detailManga = - webClient.httpPost("https://api.$domain/api/serie_details/${manga.url}", emptyMap()).parseJson() + webClient.httpPost("https://api.$domain/api/serie/serie_details/${manga.url}", emptyMap()).parseJson() val body = JSONObject() body.put("serie_slug", manga.url) - val chapterManga = webClient.httpPost("https://api.$domain/api/get_chapters_by_serie/", body).parseJson() - .getJSONArray("chapters") + val chapterManga = + webClient.httpPost("https://api.$domain/api/chapters/get_chapters_by_serie/", body).parseJson() + .getJSONArray("chapters") val dateFormat = SimpleDateFormat("dd/MM/yyyy", sourceLocale) return manga.copy( description = detailManga.getString("synopsis"), @@ -117,11 +117,12 @@ class YugenMangas(context: MangaLoaderContext) : PagedMangaParser(context, Manga } }, chapters = chapterManga.mapJSON { j -> - val url = "https://api.$domain/api/serie/${manga.url}/chapter/${j.getString("slug")}/images/imgs/" + val url = "https://api.$domain/api/serie/${manga.url}/chapter/${j.getString("slug")}/images/imgs/get/" MangaChapter( id = generateUid(url), name = j.getString("name"), - number = j.getString("name").removePrefix("Capítulo ").toInt(), + number = j.getString("name").removePrefix("Capítulo ").toFloat(), + volume = 0, url = url, scanlator = null, uploadDate = parseChapterDate( @@ -158,7 +159,7 @@ class YugenMangas(context: MangaLoaderContext) : PagedMangaParser(context, Manga val jsonPages = webClient.httpPost(chapter.url, emptyMap()).parseJson().getJSONArray("chapter_images") val pages = ArrayList(jsonPages.length()) for (i in 0 until jsonPages.length()) { - val img = "https://$domain/${jsonPages.getString(i)}" + val img = "https://api.$domain/${jsonPages.getString(i)}" pages.add( MangaPage( id = generateUid(img), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/AComics.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/AComics.kt index 47a84327..28a51de2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/AComics.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/AComics.kt @@ -142,7 +142,8 @@ internal class AComics(context: MangaLoaderContext) : MangaChapter( id = manga.id, name = manga.title, - number = 1, + number = 1f, + volume = 0, url = manga.url.replace("/about", "/"), scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/ChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/ChanParser.kt index 5390e1f1..4d0b7341 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/ChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/ChanParser.kt @@ -83,7 +83,8 @@ internal abstract class ChanParser( MangaChapter( id = generateUid(href), name = tr.selectFirst("a")?.text().orEmpty(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, branch = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/YaoiChanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/YaoiChanParser.kt index 16f42afd..8eb2c5d3 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/YaoiChanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/multichan/YaoiChanParser.kt @@ -34,7 +34,8 @@ internal class YaoiChanParser(context: MangaLoaderContext) : ChanParser(context, MangaChapter( id = generateUid(href), name = a.text().trim(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = 0L, source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt index 29b1ee3c..f886d57e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/ru/rulib/LibSocialParser.kt @@ -37,6 +37,18 @@ internal abstract class LibSocialParser( 5, MangaState.ABANDONED, ) private val imageServers = SuspendLazy(::fetchServers) + private val splitTranslationsKey = ConfigKey.SplitByTranslations(true) + private val preferredServerKey = ConfigKey.PreferredImageServer( + presetValues = mapOf( + null to null, + SERVER_MAIN to "Первый", + SERVER_SECONDARY to "Второй", + SERVER_COMPRESS to "Сжатия", + SERVER_DOWNLOAD to "Загрузки", + SERVER_CROP to "Обрезки", + ), + defaultValue = null, + ) override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { val urlBuilder = urlBuilder("api") @@ -132,10 +144,7 @@ internal abstract class LibSocialParser( } val servers = imageServers.get() val json = pages.await() - val primaryServer = - checkNotNull(servers[SERVER_MAIN] ?: servers[SERVER_DOWNLOAD] ?: servers[SERVER_SECONDARY]) { - "No available images servers" - } + val primaryServer = getPrimaryImageServer(servers) json.getJSONArray("pages").mapJSON { jo -> val url = jo.getString("url") MangaPage( @@ -167,6 +176,12 @@ internal abstract class LibSocialParser( } } + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(splitTranslationsKey) + keys.add(preferredServerKey) + } + private fun parseManga(jo: JSONObject): Manga { val cover = jo.getJSONObject("cover") return Manga( @@ -187,6 +202,16 @@ internal abstract class LibSocialParser( ) } + private fun getPrimaryImageServer(servers: ScatterMap): String { + val preferred = config[preferredServerKey] + if (preferred != null) { + servers[preferred]?.let { return it } + } + return checkNotNull(servers[SERVER_MAIN] ?: servers[SERVER_DOWNLOAD] ?: servers[SERVER_SECONDARY]) { + "No available images servers" + } + } + private suspend fun fetchChapters(manga: Manga): List { val url = urlBuilder("api") .addPathSegment("api") @@ -197,6 +222,7 @@ internal abstract class LibSocialParser( val json = webClient.httpGet(url).parseJson().getJSONArray("data") val builder = ChaptersListBuilder(json.length()) val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US) + val useBranching = config[splitTranslationsKey] for (i in 0 until json.length()) { val jo = json.getJSONObject(i) val volume = jo.getIntOrDefault("volume", 0) @@ -219,7 +245,7 @@ internal abstract class LibSocialParser( url = "${manga.url}/chapter?number=$numberString&volume=$volume", scanlator = team, uploadDate = dateFormat.tryParse(bjo.getStringOrNull("created_at")), - branch = team, + branch = if (useBranching) team else null, source = source, ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt index 340ab459..91b7884c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/ScanParser.kt @@ -3,7 +3,6 @@ package org.koitharu.kotatsu.parsers.site.scan import androidx.collection.ArrayMap import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import org.koitharu.kotatsu.parsers.ErrorMessages import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey @@ -21,17 +20,20 @@ internal abstract class ScanParser( override val availableSortOrders: Set = EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.RATING) - override val isSearchSupported = false override val configKeyDomain = ConfigKey.Domain(domain) override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { + var query = false + val url = buildString { append("https://") append(domain) when (filter) { is MangaListFilter.Search -> { - throw IllegalArgumentException(ErrorMessages.SEARCH_NOT_SUPPORTED) // TODO + append("/search?q=") + append(filter.query.urlEncoded()) + query = true } is MangaListFilter.Advanced -> { @@ -64,24 +66,58 @@ internal abstract class ScanParser( } } - val doc = webClient.httpGet(url).parseHtml() - return doc.select(".series-paginated .series").map { div -> - val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") - Manga( - id = generateUid(href), - url = href, - publicUrl = href.toAbsoluteUrl(div.host ?: domain), - coverUrl = div.selectFirst("img")?.attr("data-src")?.replace("\t", "").orEmpty(), - title = div.selectFirstOrThrow(".link-series h3").text().orEmpty(), - altTitle = null, - rating = RATING_UNKNOWN, - tags = emptySet(), - author = null, - state = null, - source = source, - isNsfw = isNsfwSource, - ) + if (query) { + val doc = webClient.httpGet(url).parseRaw() + + val list = if (doc.contains("grid-item-series")) { + doc.split("grid-item-series").drop(1) + } else { + doc.split("class=\\u0022series\\u0022\\").drop(1) + } + + return list.map { l -> + val href = l.substringAfter("href=\\u0022\\").substringBefore("\\u0022").replace("\\", "") + val cover = l.substringAfter("data-src=\\u0022").substringBefore("\\u0022\\u003E").replace("\\", "") + val title = l.substringAfter("item-title\\u0022\\u003E").substringBefore("\\u003C\\/p\\u003E").ifEmpty { + l.substringAfter("\\u003Ch3\\u003E").substringBefore("\\u003C\\/h3\\u003E") + } + Manga( + id = generateUid(href), + url = href, + publicUrl = href.toAbsoluteUrl(domain), + coverUrl = cover, + title = title, + altTitle = null, + rating = RATING_UNKNOWN, + tags = emptySet(), + author = null, + state = null, + source = source, + isNsfw = isNsfwSource, + ) + } + + } else { + val doc = webClient.httpGet(url).parseHtml() + return doc.select(".series-paginated .series, .series-paginated .grid-item-series").map { div -> + val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") + Manga( + id = generateUid(href), + url = href, + publicUrl = href.toAbsoluteUrl(div.host ?: domain), + coverUrl = div.selectFirst("img")?.attr("data-src")?.replace("\t", "").orEmpty(), + title = div.selectFirstOrThrow(".link-series h3, .item-title").text().orEmpty(), + altTitle = null, + rating = RATING_UNKNOWN, + tags = emptySet(), + author = null, + state = null, + source = source, + isNsfw = isNsfwSource, + ) + } } + } private var tagCache: ArrayMap? = null @@ -91,11 +127,12 @@ internal abstract class ScanParser( return getOrCreateTagMap().values.toSet() } - private suspend fun getOrCreateTagMap(): Map = mutex.withLock { + protected suspend fun getOrCreateTagMap(): Map = mutex.withLock { tagCache?.let { return@withLock it } val tagMap = ArrayMap() val tagElements = webClient.httpGet("https://$domain/manga").parseHtml() - .requireElementById("filter-wrapper").select(".form-filters div.form-check") + .requireElementById("filter-wrapper") + .select(".form-filters div.form-check, .form-filters div.custom-control") for (el in tagElements) { val name = el.selectFirstOrThrow("label").text() if (name.isEmpty()) continue @@ -113,28 +150,33 @@ internal abstract class ScanParser( val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml() val dateFormat = SimpleDateFormat("MM-dd-yyyy", sourceLocale) val tagMap = getOrCreateTagMap() - val selectTag = doc.select(".card-series-detail .col-6:contains(Categorie) div") + val selectTag = + doc.select(".card-series-detail .col-6:contains(Categorie) div, .card-series-about .mb-3:contains(Categorie) a, .card-series-about .mb-3:contains(Categorias) a") val tags = selectTag.mapNotNullToSet { tagMap[it.text()] } return manga.copy( - rating = doc.selectFirst(".card-series-detail .rate-value span")?.ownText()?.toFloatOrNull()?.div(5f) + rating = doc.selectFirst(".card-series-detail .rate-value span, .card-series-about .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 = 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(""), - number = i + 1, - url = href, - scanlator = null, - uploadDate = dateFormat.tryParse(doc.selectFirstOrThrow("h5 div").text()), - branch = null, - source = source, - ) - }, + author = doc.selectFirst(".card-series-detail .col-6:contains(Autore) div, .card-series-about .mb-3:contains(Autore) a") + ?.text(), + altTitle = doc.selectFirst(".card div.col-12.mb-4 h2, .card-series-about .h6")?.text().orEmpty(), + description = doc.selectFirst(".card div.col-12.mb-4 p, .card-series-desc .mb-4 p")?.html().orEmpty(), + chapters = doc.select(".chapters-list .col-chapter, .card-list-chapter .col-chapter") + .mapChapters(reversed = true) { i, div -> + val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") + MangaChapter( + id = generateUid(href), + name = div.selectFirstOrThrow("h5").html().substringBefore(""), + number = i + 1f, + volume = 0, + url = href, + scanlator = null, + uploadDate = dateFormat.tryParse(doc.selectFirstOrThrow("h5 div").text()), + branch = null, + source = source, + ) + }, ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/MangaItalia.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/MangaItalia.kt new file mode 100644 index 00000000..7202732d --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/MangaItalia.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.scan.it + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.scan.ScanParser + +@MangaSourceParser("MANGAITALIA", "MangaItalia", "pt") +internal class MangaItalia(context: MangaLoaderContext) : + ScanParser(context, MangaParserSource.MANGAITALIA, "manga-italia.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt index 82dcd386..6f47278d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/it/ScanIta.kt @@ -1,10 +1,58 @@ package org.koitharu.kotatsu.parsers.site.scan.it +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.model.Manga +import org.koitharu.kotatsu.parsers.model.MangaChapter import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.model.RATING_UNKNOWN import org.koitharu.kotatsu.parsers.site.scan.ScanParser +import org.koitharu.kotatsu.parsers.util.* +import java.text.SimpleDateFormat @MangaSourceParser("SCANITA", "ScanIta.org", "it") internal class ScanIta(context: MangaLoaderContext) : - ScanParser(context, MangaParserSource.SCANITA, "scanita.org") + ScanParser(context, MangaParserSource.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 { + 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(""), + number = i + 1f, + volume = 0, + url = href, + scanlator = null, + uploadDate = dateFormat.tryParse(doc.selectFirstOrThrow("h5 div").text()), + branch = null, + source = source, + ) + } + } +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/pt/MangaBr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/pt/MangaBr.kt new file mode 100644 index 00000000..1fdbb562 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/pt/MangaBr.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.scan.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.scan.ScanParser + +@MangaSourceParser("MANGABR", "MangaBr", "pt") +internal class MangaBr(context: MangaLoaderContext) : + ScanParser(context, MangaParserSource.MANGABR, "mangabr.net") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/pt/MangaTerra.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/pt/MangaTerra.kt new file mode 100644 index 00000000..264fe713 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/scan/pt/MangaTerra.kt @@ -0,0 +1,11 @@ +package org.koitharu.kotatsu.parsers.site.scan.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.scan.ScanParser + +@MangaSourceParser("MANGATERRA", "MangaTerra", "pt") +internal class MangaTerra(context: MangaLoaderContext) : + ScanParser(context, MangaParserSource.MANGATERRA, "manga-terra.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/sinmh/SinmhParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/sinmh/SinmhParser.kt index 0ca568c9..d029f159 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/sinmh/SinmhParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/sinmh/SinmhParser.kt @@ -176,7 +176,8 @@ internal abstract class SinmhParser( MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = 0, source = source, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/MangaAy.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/MangaAy.kt index e4a4f075..5be7dc0a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/MangaAy.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/MangaAy.kt @@ -167,7 +167,8 @@ class MangaAy(context: MangaLoaderContext) : PagedMangaParser(context, MangaPars MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, uploadDate = dateFormat.tryParse(tr.selectFirstOrThrow("time").attr("datetime")), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/SadScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/SadScans.kt index 9748ba2d..ab86836e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/SadScans.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/SadScans.kt @@ -77,7 +77,8 @@ internal class SadScans(context: MangaLoaderContext) : MangaParser(context, Mang MangaChapter( id = generateUid(url), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = dateFormat.tryParse(div.select(".detail span").last()?.text()), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt index b521b94d..f9d949ce 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/TrWebtoon.kt @@ -182,7 +182,8 @@ class TrWebtoon(context: MangaLoaderContext) : MangaChapter( id = generateUid(url), name = tr.selectFirstOrThrow("a").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = parseChapterDate( diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/YaoiFlix.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/YaoiFlix.kt index dd83fbba..9e1bd974 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/YaoiFlix.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/tr/YaoiFlix.kt @@ -116,7 +116,8 @@ class YaoiFlix(context: MangaLoaderContext) : PagedMangaParser(context, MangaPar MangaChapter( id = generateUid(href), name = div.selectFirstOrThrow(".name").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, uploadDate = dateFormat.tryParse(div.selectFirstOrThrow(".date").text()), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/BlogTruyenParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/BlogTruyenParser.kt index 8f3f6139..da074f2e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/BlogTruyenParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/BlogTruyenParser.kt @@ -197,7 +197,8 @@ class BlogTruyenParser(context: MangaLoaderContext) : MangaChapter( id = generateUid(id), name = name, - number = index + 1, + number = index + 1f, + volume = 0, url = relativeUrl, scanlator = null, uploadDate = uploadDate, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt index 92052219..ee35a0d6 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt @@ -5,14 +5,12 @@ import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import okhttp3.Headers import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaParser import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.* -import org.koitharu.kotatsu.parsers.network.UserAgents import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* @@ -23,10 +21,15 @@ private const val SEARCH_PAGE_SIZE = 10 @MangaSourceParser("HENTAIVN", "HentaiVN", "vi", type = ContentType.HENTAI) class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaParserSource.HENTAIVN) { - override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("hentaivn.red", "hentaivn.autos", "hentaivn.tv") + override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("zhentaivnz.cc") // hentaivn has created 2 different interfaces for mobile and desktop, and Cloudflare detects whether it's mobile or not even with a desktop user agent. - override val headers: Headers = Headers.Builder().add("User-Agent", UserAgents.CHROME_MOBILE).build() + private val userAgentKey = ConfigKey.UserAgent(context.getDefaultUserAgent()) + + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(userAgentKey) + } override val availableSortOrders: Set = EnumSet.of( SortOrder.UPDATED, @@ -244,7 +247,8 @@ class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaPa MangaChapter( id = generateUid(titleEl.attrAsRelativeUrl("href")), name = titleEl.text(), - number = index + 1, + number = index + 1f, + volume = 0, url = titleEl.attrAsRelativeUrl("href"), scanlator = null, uploadDate = chapterDateFormat.tryParse(dateStr), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/LxManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/LxManga.kt index 8b2fe965..196b86ed 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/LxManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/LxManga.kt @@ -142,7 +142,8 @@ internal class LxManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaChapter( id = generateUid(href), name = name, - number = i, + number = i.toFloat(), + volume = 0, url = href, scanlator = null, uploadDate = dateFormat.tryParse(date), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/Truyenqq.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/Truyenqq.kt index 4f80caf0..cca21337 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/Truyenqq.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/Truyenqq.kt @@ -17,7 +17,7 @@ internal class Truyenqq(context: MangaLoaderContext) : PagedMangaParser(context, override val availableStates: Set = 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 { @@ -138,7 +138,8 @@ internal class Truyenqq(context: MangaLoaderContext) : PagedMangaParser(context, MangaChapter( id = generateUid(href), name = name, - number = i + 1, + number = i + 1f, + volume = 0, url = href, scanlator = null, uploadDate = dateFormat.tryParse(dateText), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyentranhLHParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyentranhLHParser.kt index 27e2b288..a1033ef1 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyentranhLHParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/TruyentranhLHParser.kt @@ -133,7 +133,8 @@ class TruyentranhLHParser(context: MangaLoaderContext) : MangaChapter( id = generateUid(element.attrAsRelativeUrl("href")), name = element.selectFirst(".chapter-name")?.text()?.trim().orEmpty(), - number = index + 1, + number = index + 1f, + volume = 0, url = element.attrAsRelativeUrl("href"), scanlator = null, uploadDate = chapterDateFormat.tryParse(element.selectFirst(".chapter-time")?.text()), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/YurinekoParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/YurinekoParser.kt index f22b9a02..8c05fa80 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/YurinekoParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/YurinekoParser.kt @@ -89,7 +89,8 @@ class YurinekoParser(context: MangaLoaderContext) : PagedMangaParser(context, Ma MangaChapter( id = generateUid(chapterId.toLong()), name = jo.getString("name"), - number = i + 1, + number = i + 1f, + volume = 0, scanlator = null, url = "/read/$mangaId/$chapterId", uploadDate = df.tryParse(jo.getString("date")), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vmp/VmpParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vmp/VmpParser.kt index 8d242ec3..719338ea 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vmp/VmpParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vmp/VmpParser.kt @@ -122,7 +122,8 @@ internal abstract class VmpParser( MangaChapter( id = manga.id, name = manga.title, - number = 1, + number = 1f, + volume = 0, url = manga.url, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/WpComicsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/WpComicsParser.kt index 1d871fa3..4af889e0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/WpComicsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/WpComicsParser.kt @@ -234,7 +234,8 @@ internal abstract class WpComicsParser( MangaChapter( id = generateUid(href), name = a.text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt index 49536ef1..9cc37e8a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ZeistMangaParser.kt @@ -283,7 +283,8 @@ internal abstract class ZeistMangaParser( id = generateUid(href), url = href, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = dateFormat.tryParse(dateText), scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ar/MangaHub.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ar/MangaHub.kt new file mode 100644 index 00000000..ee37fee5 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/ar/MangaHub.kt @@ -0,0 +1,33 @@ +package org.koitharu.kotatsu.parsers.site.zeistmanga.ar + +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.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaState +import org.koitharu.kotatsu.parsers.model.MangaTag +import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser +import org.koitharu.kotatsu.parsers.util.* +import java.util.* + +@MangaSourceParser("MANGAHUB_LINK", "MangaHub.link", "ar", ContentType.HENTAI) +internal class MangaHub(context: MangaLoaderContext) : + ZeistMangaParser(context, MangaParserSource.MANGAHUB_LINK, "www.mangahub.link") { + + override val availableStates: Set = + EnumSet.of(MangaState.ONGOING, MangaState.FINISHED) + + override val sateOngoing: String = "مستمر" + override val sateFinished: String = "مكتمل" + + override suspend fun getAvailableTags(): Set { + val doc = webClient.httpGet("https://$domain").parseHtml() + return doc.requireElementById("Genre").select("div.items-center").mapNotNullToSet { + MangaTag( + key = it.selectFirstOrThrow("input").attr("value"), + title = it.selectFirstOrThrow("label").text().substringBefore(')').toTitleCase(sourceLocale), + source = source, + ) + } + } +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/KomikGes.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/KomikGes.kt index f0bea4de..43014bca 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/KomikGes.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/KomikGes.kt @@ -41,7 +41,8 @@ internal class KomikGes(context: MangaLoaderContext) : id = generateUid(href), url = href, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = dateFormat.tryParse(dateText), scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/MonzeeKomik.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/MonzeeKomik.kt index 934bad1a..260c43d4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/MonzeeKomik.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/MonzeeKomik.kt @@ -59,7 +59,8 @@ internal class MonzeeKomik(context: MangaLoaderContext) : id = generateUid(href), url = href, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = dateFormat.tryParse(dateText), scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/ToonCubus.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/ToonCubus.kt index 4fbe8b87..b9e50938 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/ToonCubus.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/id/ToonCubus.kt @@ -33,7 +33,8 @@ internal class ToonCubus(context: MangaLoaderContext) : id = generateUid(url), url = url, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = 0, scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/AnimeXNovel.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/AnimeXNovel.kt index cb31c225..dccc99fc 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/AnimeXNovel.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/AnimeXNovel.kt @@ -37,7 +37,8 @@ internal class AnimeXNovel(context: MangaLoaderContext) : id = generateUid(url), url = url, name = name, - number = i + 1, + number = i + 1f, + volume = 0, branch = null, uploadDate = 0, scanlator = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/GuildaTierDraw.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/GuildaTierDraw.kt index 6c7f715e..1389e8ab 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/GuildaTierDraw.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/GuildaTierDraw.kt @@ -12,7 +12,7 @@ import org.koitharu.kotatsu.parsers.util.requireElementById @MangaSourceParser("GUILDATIERDRAW", "GuildaTierDraw", "pt") internal class GuildaTierDraw(context: MangaLoaderContext) : - ZeistMangaParser(context, MangaParserSource.GUILDATIERDRAW, "www.guildatierdraw.com") { + ZeistMangaParser(context, MangaParserSource.GUILDATIERDRAW, "www.guildatierdraw.top") { override suspend fun getAvailableTags(): Set { val doc = webClient.httpGet("https://$domain").parseHtml() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/RaysScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/RaysScan.kt new file mode 100644 index 00000000..69767754 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/RaysScan.kt @@ -0,0 +1,18 @@ +package org.koitharu.kotatsu.parsers.site.zeistmanga.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.model.MangaSource +import org.koitharu.kotatsu.parsers.model.MangaState +import org.koitharu.kotatsu.parsers.model.MangaTag +import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser + +@MangaSourceParser("RAYSSCAN", "RaysScan", "pt") +internal class RaysScan(context: MangaLoaderContext) : + ZeistMangaParser(context, MangaParserSource.RAYSSCAN, "raysscan.blogspot.com") { + override val availableStates: Set = emptySet() + override suspend fun getAvailableTags(): Set = emptySet() +} + + diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/SolooScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/SolooScan.kt new file mode 100644 index 00000000..7dd2a7cb --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/SolooScan.kt @@ -0,0 +1,16 @@ +package org.koitharu.kotatsu.parsers.site.zeistmanga.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.model.MangaSource +import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser + +@MangaSourceParser("SOLOOSCAN", "SolooScan", "pt") +internal class SolooScan(context: MangaLoaderContext) : + ZeistMangaParser(context, MangaParserSource.SOLOOSCAN, "solooscan.blogspot.com") { + override val mangaCategory = "Recentes" + override val sateOngoing: String = "Lançando" + override val sateFinished: String = "Completo" + override val sateAbandoned: String = "Dropado" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/TemakiMangas.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/TemakiMangas.kt new file mode 100644 index 00000000..fec28c78 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zeistmanga/pt/TemakiMangas.kt @@ -0,0 +1,18 @@ +package org.koitharu.kotatsu.parsers.site.zeistmanga.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.model.MangaSource +import org.koitharu.kotatsu.parsers.model.MangaState +import org.koitharu.kotatsu.parsers.model.MangaTag +import org.koitharu.kotatsu.parsers.site.zeistmanga.ZeistMangaParser + +@MangaSourceParser("TEMAKIMANGAS", "TemakiMangas", "pt") +internal class TemakiMangas(context: MangaLoaderContext) : + ZeistMangaParser(context, MangaParserSource.TEMAKIMANGAS, "www.temakimangas.xyz") { + override val availableStates: Set = emptySet() + override suspend fun getAvailableTags(): Set = emptySet() +} + + diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zh/Baozimh.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zh/Baozimh.kt index 18b03eec..41b3ca88 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zh/Baozimh.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zh/Baozimh.kt @@ -179,7 +179,8 @@ internal class Baozimh(context: MangaLoaderContext) : MangaChapter( id = generateUid(url), name = a.selectFirstOrThrow("span").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = url, scanlator = null, uploadDate = 0, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt index abbc2b86..fdbff1ff 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/ZMangaParser.kt @@ -199,7 +199,8 @@ internal abstract class ZMangaParser( MangaChapter( id = generateUid(href), name = li.selectFirstOrThrow(".flexch-infoz span:not(.date)").text(), - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/MaidId.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/MaidId.kt index 36e9a4e3..856dac94 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/MaidId.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/MaidId.kt @@ -28,7 +28,8 @@ internal class MaidId(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = "Chapter $numChapter", - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/ShiroDoujin.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/ShiroDoujin.kt index f9df4db1..f1ba19ec 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/ShiroDoujin.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/ShiroDoujin.kt @@ -28,7 +28,8 @@ internal class ShiroDoujin(context: MangaLoaderContext) : MangaChapter( id = generateUid(href), name = "Chapter $numChapter", - number = i + 1, + number = i + 1f, + volume = 0, url = href, uploadDate = parseChapterDate( dateFormat,