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 6ce8f607..0b1c33fa 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 @@ -44,6 +44,7 @@ internal abstract class AnimeBootstrapParser( tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -59,9 +60,7 @@ internal abstract class AnimeBootstrapParser( if (!tags.isNullOrEmpty()) { append("&categorie=") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) } append("&sort=") 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 70364078..1e6aabc2 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 @@ -6,27 +6,9 @@ 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.MangaSource -import org.koitharu.kotatsu.parsers.model.MangaState -import org.koitharu.kotatsu.parsers.model.MangaTag -import org.koitharu.kotatsu.parsers.model.RATING_UNKNOWN -import org.koitharu.kotatsu.parsers.model.SortOrder +import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.site.animebootstrap.AnimeBootstrapParser -import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrl -import org.koitharu.kotatsu.parsers.util.domain -import org.koitharu.kotatsu.parsers.util.generateUid -import org.koitharu.kotatsu.parsers.util.host -import org.koitharu.kotatsu.parsers.util.mapChapters -import org.koitharu.kotatsu.parsers.util.mapNotNullToSet -import org.koitharu.kotatsu.parsers.util.parseHtml -import org.koitharu.kotatsu.parsers.util.removeSuffix -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow -import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl -import org.koitharu.kotatsu.parsers.util.toTitleCase -import org.koitharu.kotatsu.parsers.util.tryParse -import org.koitharu.kotatsu.parsers.util.urlEncoded +import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.EnumSet import java.util.Locale @@ -56,6 +38,9 @@ internal class PapScan(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { + + val tag = tags.oneOrThrowIfMany() + val url = buildString { append("https://") append(domain) @@ -70,9 +55,7 @@ internal class PapScan(context: MangaLoaderContext) : if (!tags.isNullOrEmpty()) { append("&cat=") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) } append("&sortBy=") when (sortOrder) { 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 98d138a0..2bd01f6c 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 @@ -54,6 +54,7 @@ internal abstract class FmreaderParser( tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -69,9 +70,7 @@ internal abstract class FmreaderParser( !tags.isNullOrEmpty() -> { append("&genre=") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) } } @@ -92,8 +91,9 @@ internal abstract class FmreaderParser( id = generateUid(href), url = href, publicUrl = href.toAbsoluteUrl(div.host ?: domain), - coverUrl = div.selectFirstOrThrow("div.img-in-ratio").attr("style").substringAfter("('") - .substringBeforeLast("')"), + coverUrl = div.selectFirstOrThrow("div.img-in-ratio").attr("data-bg") + ?: div.selectFirstOrThrow("div.img-in-ratio").attr("style").substringAfter("('") + .substringBeforeLast("')"), title = div.selectFirstOrThrow("div.series-title").text().orEmpty(), altTitle = null, rating = RATING_UNKNOWN, @@ -106,10 +106,11 @@ internal abstract class FmreaderParser( } } + protected open val selectBodyTag = "ul.filter-type li a" + override suspend fun getTags(): Set { val doc = webClient.httpGet("https://$domain/$listeurl").parseHtml() - return doc.select("ul.filter-type li").mapNotNullToSet { li -> - val a = li.selectFirst("a") ?: return@mapNotNullToSet null + return doc.select(selectBodyTag).mapNotNullToSet { a -> val href = a.attr("href").substringAfter("manga-list-genre-").substringBeforeLast(".html") MangaTag( key = href, 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 0e4147ac..cb1f1f50 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 @@ -6,22 +6,9 @@ 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.ContentType -import org.koitharu.kotatsu.parsers.model.Manga -import org.koitharu.kotatsu.parsers.model.MangaChapter -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.model.MangaState -import org.koitharu.kotatsu.parsers.model.MangaTag +import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.site.fmreader.FmreaderParser -import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrl -import org.koitharu.kotatsu.parsers.util.domain -import org.koitharu.kotatsu.parsers.util.generateUid -import org.koitharu.kotatsu.parsers.util.mapChapters -import org.koitharu.kotatsu.parsers.util.mapNotNullToSet -import org.koitharu.kotatsu.parsers.util.parseHtml -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow -import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl -import org.koitharu.kotatsu.parsers.util.toTitleCase +import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat @MangaSourceParser("MANHWA18COM", "Manhwa18 Com", "en", ContentType.HENTAI) @@ -35,6 +22,87 @@ internal class Manhwa18Com(context: MangaLoaderContext) : override val selectTag = "div.info-item:contains(Genre) span.info-value a" override val datePattern = "dd/MM/yyyy" override val selectPage = "div#chapter-content img" + override val selectBodyTag = "div.genres-menu a" + + override suspend fun getListPage( + page: Int, + query: String?, + tags: Set?, + sortOrder: SortOrder, + ): List { + val tag = tags.oneOrThrowIfMany() + + val url = buildString { + append("https://") + append(domain) + if (!tags.isNullOrEmpty()) { + append("/genre/") + append(tag?.key.orEmpty()) + append("?page=") + append(page.toString()) + append("&sort=") + when (sortOrder) { + SortOrder.POPULARITY -> append("views") + SortOrder.UPDATED -> append("last_update") + SortOrder.ALPHABETICAL -> append("name") + else -> append("last_update") + } + } else { + append(listeurl) + append("?page=") + append(page.toString()) + when { + !query.isNullOrEmpty() -> { + append("&q=") + append(query.urlEncoded()) + } + } + + append("&sort=") + when (sortOrder) { + SortOrder.POPULARITY -> append("views") + SortOrder.UPDATED -> append("last_update") + SortOrder.ALPHABETICAL -> append("name") + else -> append("last_update") + } + + } + } + val doc = webClient.httpGet(url).parseHtml() + + return doc.select("div.thumb-item-flow").map { div -> + + val href = div.selectFirstOrThrow("div.series-title a").attrAsRelativeUrl("href") + Manga( + id = generateUid(href), + url = href, + publicUrl = href.toAbsoluteUrl(div.host ?: domain), + coverUrl = div.selectFirstOrThrow("div.img-in-ratio").attr("data-bg") + ?: div.selectFirstOrThrow("div.img-in-ratio").attr("style").substringAfter("('") + .substringBeforeLast("')"), + title = div.selectFirstOrThrow("div.series-title").text().orEmpty(), + altTitle = null, + rating = RATING_UNKNOWN, + tags = emptySet(), + author = null, + state = null, + source = source, + isNsfw = isNsfwSource, + ) + } + } + + override suspend fun getTags(): Set { + val doc = webClient.httpGet("https://$domain/$listeurl").parseHtml() + return doc.select(selectBodyTag).mapNotNullToSet { a -> + val href = a.attr("href").substringAfterLast("/") + MangaTag( + key = href, + title = a.text(), + source = source, + ) + } + } override suspend fun getDetails(manga: Manga): Manga = coroutineScope { val fullUrl = manga.url.toAbsoluteUrl(domain) 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 6adfdc00..ae13b2ea 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 @@ -27,6 +27,7 @@ internal class Klz9(context: MangaLoaderContext) : override val selectChapter = "tr" override val selectDate = "td i" override val selectPage = "img" + override val selectBodyTag = "div.panel-body a" override suspend fun getListPage( page: Int, @@ -34,6 +35,7 @@ internal class Klz9(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -49,9 +51,7 @@ internal class Klz9(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("&genre=") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) } } 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 e0227102..98cc191b 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 @@ -137,13 +137,12 @@ internal abstract class MadaraParser( tags: Set?, sortOrder: SortOrder, ): List { - + val tag = tags.oneOrThrowIfMany() val doc = if (withoutAjax) { val url = buildString { append("https://") append(domain) val pages = page + 1 - when { !query.isNullOrEmpty() -> { append("/page/") @@ -155,9 +154,7 @@ internal abstract class MadaraParser( !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/page/") append(pages.toString()) append("?") @@ -182,8 +179,6 @@ internal abstract class MadaraParser( } webClient.httpGet(url).parseHtml() } else { - val tag = tags.oneOrThrowIfMany() - val payload = if (sortOrder == SortOrder.RATING) { createRequestTemplate(ratingRequest) } else { @@ -273,7 +268,7 @@ internal abstract class MadaraParser( "div.description-summary div.summary__content, div.summary_content div.post-content_item > h5 + div, div.summary_content div.manga-excerpt, div.post-content div.manga-summary, div.post-content div.desc, div.c-page__content div.summary__content" protected open val selectGenre = "div.genres-content a" protected open val selectTestAsync = "div.listing-chapters_wrap" - + protected open val selectState = "" override suspend fun getDetails(manga: Manga): Manga = coroutineScope { val fullUrl = manga.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() @@ -289,18 +284,23 @@ internal abstract class MadaraParser( val desc = body.select(selectDesc).html() - val stateDiv = (body.selectFirst("div.post-content_item:contains(Status)") - ?: body.selectFirst("div.post-content_item:contains(Statut)") - ?: body.selectFirst("div.post-content_item:contains(État)") - ?: body.selectFirst("div.post-content_item:contains(حالة العمل)") - ?: body.selectFirst("div.post-content_item:contains(Estado)") - ?: body.selectFirst("div.post-content_item:contains(สถานะ)") - ?: body.selectFirst("div.post-content_item:contains(Stato)") - ?: body.selectFirst("div.post-content_item:contains(Durum)") - ?: body.selectFirst("div.post-content_item:contains(Statüsü)") - ?: body.selectFirst("div.post-content_item:contains(Статус)") - ?: body.selectFirst("div.post-content_item:contains(状态)") - ?: body.selectFirst("div.post-content_item:contains(الحالة)"))?.selectLast("div.summary-content") + val stateDiv = if (selectState.isEmpty()) { + (body.selectFirst("div.post-content_item:contains(Status)") + ?: body.selectFirst("div.post-content_item:contains(Statut)") + ?: body.selectFirst("div.post-content_item:contains(État)") + ?: body.selectFirst("div.post-content_item:contains(حالة العمل)") + ?: body.selectFirst("div.post-content_item:contains(Estado)") + ?: body.selectFirst("div.post-content_item:contains(สถานะ)") + ?: body.selectFirst("div.post-content_item:contains(Stato)") + ?: body.selectFirst("div.post-content_item:contains(Durum)") + ?: body.selectFirst("div.post-content_item:contains(Statüsü)") + ?: body.selectFirst("div.post-content_item:contains(Статус)") + ?: body.selectFirst("div.post-content_item:contains(状态)") + ?: body.selectFirst("div.post-content_item:contains(الحالة)"))?.selectLast("div.summary-content") + } else { + body.selectFirst(selectState) + } + val state = stateDiv?.let { when (it.text()) { @@ -553,10 +553,13 @@ internal abstract class MadaraParser( } } - private val ratingRequest = "action=madara_load_more&page=1&template=madara-core%2Fcontent%2Fcontent-search&vars%5Bs%5D=&vars%5Borderby%5D%5Bquery_avarage_reviews%5D=DESC&vars%5Borderby%5D%5Bquery_total_reviews%5D=DESC&vars%5Bpaged%5D=1&vars%5Btemplate%5D=search&vars%5Bmeta_query%5D%5B0%5D%5Brelation%5D=AND&vars%5Bmeta_query%5D%5B0%5D%5Bquery_avarage_reviews%5D%5Bkey%5D=_manga_avarage_reviews&vars%5Bmeta_query%5D%5B0%5D%5Bquery_total_reviews%5D%5Bkey%5D=_manga_total_votes&vars%5Bmeta_query%5D%5Brelation%5D=AND&vars%5Bpost_type%5D=wp-manga&vars%5Bpost_status%5D=publish&vars%5Bmanga_archives_item_layout%5D=default" - private val defaultRequest = "action=madara_load_more&page=1&template=madara-core%2Fcontent%2Fcontent-search&vars%5Bs%5D=&vars%5Borderby%5D=meta_value_num&vars%5Bpaged%5D=1&vars%5Btemplate%5D=search&vars%5Bmeta_query%5D%5B0%5D%5Brelation%5D=AND&vars%5Bmeta_query%5D%5Brelation%5D=OR&vars%5Bpost_type%5D=wp-manga&vars%5Bpost_status%5D=publish&vars%5Bmeta_key%5D=_latest_update&vars%5Border%5D=desc&vars%5Bmanga_archives_item_layout%5D=default" + private val ratingRequest = + "action=madara_load_more&page=1&template=madara-core%2Fcontent%2Fcontent-search&vars%5Bs%5D=&vars%5Borderby%5D%5Bquery_avarage_reviews%5D=DESC&vars%5Borderby%5D%5Bquery_total_reviews%5D=DESC&vars%5Bpaged%5D=1&vars%5Btemplate%5D=search&vars%5Bmeta_query%5D%5B0%5D%5Brelation%5D=AND&vars%5Bmeta_query%5D%5B0%5D%5Bquery_avarage_reviews%5D%5Bkey%5D=_manga_avarage_reviews&vars%5Bmeta_query%5D%5B0%5D%5Bquery_total_reviews%5D%5Bkey%5D=_manga_total_votes&vars%5Bmeta_query%5D%5Brelation%5D=AND&vars%5Bpost_type%5D=wp-manga&vars%5Bpost_status%5D=publish&vars%5Bmanga_archives_item_layout%5D=default" + private val defaultRequest = + "action=madara_load_more&page=1&template=madara-core%2Fcontent%2Fcontent-search&vars%5Bs%5D=&vars%5Borderby%5D=meta_value_num&vars%5Bpaged%5D=1&vars%5Btemplate%5D=search&vars%5Bmeta_query%5D%5B0%5D%5Brelation%5D=AND&vars%5Bmeta_query%5D%5Brelation%5D=OR&vars%5Bpost_type%5D=wp-manga&vars%5Bpost_status%5D=publish&vars%5Bmeta_key%5D=_latest_update&vars%5Border%5D=desc&vars%5Bmanga_archives_item_layout%5D=default" + private companion object { - private fun createRequestTemplate(query : String) = + private fun createRequestTemplate(query: String) = (query).split( '&', ).map { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaLek.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaLek.kt index 696c388a..64a0a274 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaLek.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaLek.kt @@ -7,4 +7,6 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser @MangaSourceParser("MANGALEK", "MangaLek", "ar") internal class MangaLek(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGALEK, "mangalek.com", pageSize = 20) + MadaraParser(context, MangaSource.MANGALEK, "mangalek.com", pageSize = 20) { + override val datePattern = "dd-MM-yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/BestManhuaCom.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/BestManhuaCom.kt index 5730c272..2d394ebf 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/BestManhuaCom.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/BestManhuaCom.kt @@ -31,7 +31,7 @@ internal class BestManhuaCom(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { - + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -47,9 +47,7 @@ internal class BestManhuaCom(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/") append(pages.toString()) append("?") @@ -67,7 +65,7 @@ internal class BestManhuaCom(context: MangaLoaderContext) : SortOrder.UPDATED -> append("latest-updated") SortOrder.NEWEST -> append("release-date") SortOrder.ALPHABETICAL -> append("name-az") - else -> append("latest") + SortOrder.RATING -> append("rating") } } val doc = webClient.httpGet(url).parseHtml() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai4Free.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai4Free.kt index 3943568c..0a0e3334 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai4Free.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai4Free.kt @@ -28,6 +28,9 @@ internal class Hentai4Free(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { + + val tag = tags.oneOrThrowIfMany() + val url = buildString { append("https://") append(domain) @@ -43,9 +46,7 @@ internal class Hentai4Free(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/") if (pages > 1) { append("page/") @@ -65,7 +66,7 @@ internal class Hentai4Free(context: MangaLoaderContext) : SortOrder.UPDATED -> append("latest") SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") - else -> append("latest") + SortOrder.RATING -> append("rating") } } } 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 71bcb666..6f51fa8b 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 @@ -28,6 +28,7 @@ internal class IsekaiScan(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -45,10 +46,7 @@ internal class IsekaiScan(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/mangas/") - for (tag in tags) { - append(tag.key) - } - + append(tag?.key.orEmpty()) append("?orderby=2&page=") append(pages.toString()) 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 ef41c984..e7ee2f09 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 @@ -20,6 +20,7 @@ internal class IsekaiScanEuParser(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -36,9 +37,7 @@ internal class IsekaiScanEuParser(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/page/") append(pages.toString()) append("?") @@ -58,7 +57,7 @@ internal class IsekaiScanEuParser(context: MangaLoaderContext) : SortOrder.UPDATED -> append("latest") SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") - else -> append("latest") + SortOrder.RATING -> append("rating") } } val doc = webClient.httpGet(url).parseHtml() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Jaiminisbox.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Jaiminisbox.kt new file mode 100644 index 00000000..4964cd94 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Jaiminisbox.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.en + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("JAIMINISBOX", "Jaiminisbox", "en") +internal class Jaiminisbox(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.JAIMINISBOX, "jaiminisbox.net") 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 31eb65e3..9c97dbd6 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 @@ -25,7 +25,7 @@ internal class MangaDass(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { - + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -42,9 +42,7 @@ internal class MangaDass(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/") append(pages.toString()) append("?") @@ -64,7 +62,7 @@ internal class MangaDass(context: MangaLoaderContext) : SortOrder.UPDATED -> append("latest") SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") - else -> append("latest") + SortOrder.RATING -> append("rating") } } val doc = webClient.httpGet(url).parseHtml() 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 5ec8928d..e8fd2d22 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 @@ -25,7 +25,7 @@ internal class MangaDna(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { - + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -42,9 +42,7 @@ internal class MangaDna(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/page/") append(pages.toString()) append("?") @@ -64,7 +62,7 @@ internal class MangaDna(context: MangaLoaderContext) : SortOrder.UPDATED -> append("latest") SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") - else -> append("latest") + SortOrder.RATING -> append("rating") } } val doc = webClient.httpGet(url).parseHtml() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwaz.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwaz.kt index d9825636..b2ada718 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwaz.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manhwaz.kt @@ -21,7 +21,7 @@ internal class Manhwaz(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { - + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -38,9 +38,7 @@ internal class Manhwaz(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("?page=") append(pages.toString()) append("&") @@ -60,7 +58,7 @@ internal class Manhwaz(context: MangaLoaderContext) : SortOrder.UPDATED -> append("latest") SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") - else -> append("latest") + SortOrder.RATING -> append("rating") } } val doc = webClient.httpGet(url).parseHtml() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/DragonTranslationParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/DragonTranslationParser.kt index 7ed4d8a4..76b75ce5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/DragonTranslationParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/DragonTranslationParser.kt @@ -14,9 +14,7 @@ import java.util.* internal class DragonTranslationParser(context: MangaLoaderContext) : MadaraParser(context, MangaSource.DRAGONTRANSLATION, "dragontranslation.net", 30) { - override val sortOrders: Set = EnumSet.of( - SortOrder.UPDATED, - ) + override val sortOrders: Set = EnumSet.of(SortOrder.UPDATED) override val selectPage = "div#chapter_imgs img" @@ -27,6 +25,8 @@ internal class DragonTranslationParser(context: MangaLoaderContext) : sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() + val url = buildString { append("https://") append(domain) @@ -42,9 +42,7 @@ internal class DragonTranslationParser(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/mangas?tag=") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("&page=") append(pages.toString()) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MangaCrab.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MangaCrab.kt new file mode 100644 index 00000000..1f66285e --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MangaCrab.kt @@ -0,0 +1,19 @@ +package org.koitharu.kotatsu.parsers.site.madara.es + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + + +@MangaSourceParser("MANGA_CRAB", "Manga Crab", "es") +internal class MangaCrab(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.MANGA_CRAB, "manga-crab.com") { + + override val datePattern = "dd/MM/yyyy" + override val tagPrefix = "manga-genero/" + override val listUrl = "series/" + override val selectChapter = "div.listing-chapters_wrap > ul > li" + override val selectDesc = "div.c-page__content div.modal-contenido p" + override val selectState = "div.summary-content2" +} 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 0d4a9b04..98e25bf3 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 @@ -15,7 +15,7 @@ import java.text.SimpleDateFormat internal class ManhwaLatino(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANHWALATINO, "manhwa-latino.com", 10) { - override val datePattern = "MM/dd/yyyy" + override val datePattern = "dd 'de' MMMM" override val withoutAjax = true diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MantrazScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MantrazScan.kt new file mode 100644 index 00000000..fdad0722 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MantrazScan.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.parsers.site.madara.es + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + + +@MangaSourceParser("MANTRAZSCAN", "MantrazScan", "es") +internal class MantrazScan(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.MANTRAZSCAN, "mantrazscan.com") { + + override val datePattern = "dd/MM/yyyy" + override val tagPrefix = "generos-de-manga/" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MonarcaManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MonarcaManga.kt index 16334963..9f4d6186 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MonarcaManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/MonarcaManga.kt @@ -19,7 +19,7 @@ internal class MonarcaManga(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { - + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -36,9 +36,7 @@ internal class MonarcaManga(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/page/") append(pages.toString()) append("?") @@ -58,7 +56,7 @@ internal class MonarcaManga(context: MangaLoaderContext) : SortOrder.UPDATED -> append("latest") SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") - else -> append("latest") + SortOrder.RATING -> append("rating") } } val doc = webClient.httpGet(url).parseHtml() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TempleScanEsp.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TempleScanEsp.kt index 7c55526e..550cb778 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TempleScanEsp.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TempleScanEsp.kt @@ -6,11 +6,11 @@ import org.koitharu.kotatsu.parsers.model.ContentType import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("TEMPLESCANESP", "TempleScanEsp", "es" , ContentType.HENTAI) +@MangaSourceParser("TEMPLESCANESP", "TempleScanEsp", "es", ContentType.HENTAI) internal class TempleScanEsp(context: MangaLoaderContext) : MadaraParser(context, MangaSource.TEMPLESCANESP, "templescanesp.com") { - override val listUrl = "series/" + override val listUrl = "series/" override val tagPrefix = "genero/" override val datePattern = "dd.MM.yyyy" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TenkaiScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TenkaiScan.kt index d8a1d205..70927dd0 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TenkaiScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/TenkaiScan.kt @@ -6,6 +6,6 @@ import org.koitharu.kotatsu.parsers.model.ContentType import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.MadaraParser -@MangaSourceParser("TENKAISCAN", "Tenkai Scan", "es" , ContentType.HENTAI) +@MangaSourceParser("TENKAISCAN", "Tenkai Scan", "es", ContentType.HENTAI) internal class TenkaiScan(context: MangaLoaderContext) : MadaraParser(context, MangaSource.TENKAISCAN, "tenkaiscan.net") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/BirdToon.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/BirdToon.kt new file mode 100644 index 00000000..75bf6e6e --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/BirdToon.kt @@ -0,0 +1,16 @@ +package org.koitharu.kotatsu.parsers.site.madara.id + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.ContentType +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +import java.util.Locale + +@MangaSourceParser("BIRDTOON", "BirdToon", "id", ContentType.HENTAI) +internal class BirdToon(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.BIRDTOON, "birdtoon.net", 10) { + override val sourceLocale: Locale = Locale.ENGLISH + override val tagPrefix = "komik-genre/" + override val listUrl = "komik/" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/ManhwaPlus.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/ManhwaPlus.kt index f582e3fa..c9adc5f6 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/ManhwaPlus.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/ManhwaPlus.kt @@ -24,7 +24,7 @@ internal class ManhwaPlus(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { - + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -41,9 +41,7 @@ internal class ManhwaPlus(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/page/") append(pages.toString()) append("?") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ja/HachiManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ja/HachiManga.kt index 67353844..2b7d38bf 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ja/HachiManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ja/HachiManga.kt @@ -35,6 +35,7 @@ internal class HachiManga(context: MangaLoaderContext) : MadaraParser(context, M tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -51,9 +52,7 @@ internal class HachiManga(context: MangaLoaderContext) : MadaraParser(context, M !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/") append(pages.toString()) append("/") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Saytruyenhay.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Saytruyenhay.kt index fbbabfce..fd38c481 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Saytruyenhay.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/Saytruyenhay.kt @@ -24,8 +24,7 @@ internal class Saytruyenhay(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { - - + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -42,15 +41,12 @@ internal class Saytruyenhay(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/$tagPrefix") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("?page=") append(pages.toString()) } else -> { - append("/$listUrl") append("?page=") append(pages.toString()) @@ -62,7 +58,7 @@ internal class Saytruyenhay(context: MangaLoaderContext) : SortOrder.UPDATED -> append("latest") SortOrder.NEWEST -> append("new-manga") SortOrder.ALPHABETICAL -> append("alphabet") - else -> append("latest") + SortOrder.RATING -> append("rating") } } val doc = webClient.httpGet(url).parseHtml() 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 fb2f52d5..932c5a48 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 @@ -3,7 +3,6 @@ package org.koitharu.kotatsu.parsers.site.manga18 import kotlinx.coroutines.async 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 @@ -54,6 +53,7 @@ internal abstract class Manga18Parser( tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -68,9 +68,7 @@ internal abstract class Manga18Parser( !tags.isNullOrEmpty() -> { append("/$tagUrl") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/") append(page.toString()) append("?") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt index 496cbc32..d8a6ad4b 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt @@ -18,6 +18,7 @@ internal class Hentai3zCc(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -33,9 +34,7 @@ internal class Hentai3zCc(context: MangaLoaderContext) : !tags.isNullOrEmpty() -> { append("/$tagUrl") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/") append(pages.toString()) append("?") 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 1e8be965..f4f738fe 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 @@ -50,6 +50,7 @@ internal abstract class MangaboxParser( tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -62,9 +63,7 @@ internal abstract class MangaboxParser( } else if (!tags.isNullOrEmpty()) { append("/") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) append("/") append(page.toString()) } else { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/Mangairo.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/Mangairo.kt index 5ae9a213..d2acb52a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/Mangairo.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/Mangairo.kt @@ -45,6 +45,7 @@ internal class Mangairo(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -70,9 +71,7 @@ internal class Mangairo(context: MangaLoaderContext) : if (!tags.isNullOrEmpty()) { append("/ctg-") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) } else { append("/ctg-all") } 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 new file mode 100644 index 00000000..20b9cf16 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangabox/en/Mangakakalot.kt @@ -0,0 +1,115 @@ +package org.koitharu.kotatsu.parsers.site.mangabox.en + + +import org.jsoup.nodes.Document +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.config.ConfigKey +import org.koitharu.kotatsu.parsers.model.* +import org.koitharu.kotatsu.parsers.site.mangabox.MangaboxParser +import org.koitharu.kotatsu.parsers.util.* +import java.text.SimpleDateFormat + + +@MangaSourceParser("MANGAKAKALOT", "Mangakakalot", "en") +internal class Mangakakalot(context: MangaLoaderContext) : + MangaboxParser(context, MangaSource.MANGAKAKALOT) { + + override val configKeyDomain = ConfigKey.Domain("mangakakalot.com", "chapmanganato.com") + + override val otherDomain = "chapmanganato.com" + + override val listUrl = "/manga_list" + + override suspend fun getListPage( + page: Int, + query: String?, + tags: Set?, + sortOrder: SortOrder, + ): List { + val tag = tags.oneOrThrowIfMany() + val url = buildString { + append("https://") + append(domain) + + if (!query.isNullOrEmpty()) { + append(searchUrl) + append(query.replace(" ", "_").urlEncoded()) + append("?page=") + append(page.toString()) + + }else { + append("$listUrl/") + when (sortOrder) { + SortOrder.POPULARITY -> append("?type=topview") + SortOrder.UPDATED -> append("") + SortOrder.NEWEST -> append("?type=newest") + else -> append("") + } + if (!tags.isNullOrEmpty()) { + append("&category=") + append(tag?.key.orEmpty()) + }else{ + append("&category=all") + } + append("&state=all&page=") + append(page) + + } + + + } + + val doc = webClient.httpGet(url).parseHtml() + + return doc.select("div.list-truyen-item-wrap").ifEmpty { + doc.select("div.story_item") + }.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")?.src().orEmpty(), + title = div.selectFirstOrThrow("h3").text().orEmpty(), + altTitle = null, + rating = RATING_UNKNOWN, + tags = emptySet(), + author = null, + state = null, + source = source, + isNsfw = isNsfwSource, + ) + } + } + + override suspend fun getChapters(manga: Manga, doc: Document): List { + + return doc.body().select(selectChapter).mapChapters(reversed = true) { i, li -> + val a = li.selectFirstOrThrow("a") + val href = a.attrAsRelativeUrl("href") + val dateText = li.select(selectDate).last()?.text() ?: "0" + val dateFormat = if(dateText.contains("-")) + { + SimpleDateFormat("MMM-dd-yy", sourceLocale) + }else + { + SimpleDateFormat(datePattern, sourceLocale) + } + + MangaChapter( + id = generateUid(href), + name = a.text(), + number = i + 1, + url = href, + uploadDate = parseChapterDate( + dateFormat, + dateText, + ), + source = source, + scanlator = null, + branch = null, + ) + } + } +} 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 48c661e7..7a9dfdf9 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 @@ -220,13 +220,13 @@ internal abstract class MangaReaderParser( protected open val encodedSrc = false protected open val selectScript = "div.wrapper script" - protected open val selectPage = "div#readerarea img" + protected open val selectTestScript = "script:containsData(ts_reader)" override suspend fun getPages(chapter: MangaChapter): List { val chapterUrl = chapter.url.toAbsoluteUrl(domain) val docs = webClient.httpGet(chapterUrl).parseHtml() - val test = docs.select("script:containsData(ts_reader)") + val test = docs.select(selectTestScript) if (test.isNullOrEmpty() and !encodedSrc) { return docs.select(selectPage).map { img -> val url = img.src()?.toRelativeUrl(domain) ?: img.parseFailed("Image src not found") @@ -257,7 +257,7 @@ internal abstract class MangaReaderParser( .getJSONArray("images") } else { - val script = docs.selectFirstOrThrow("script:containsData(ts_reader)") + val script = docs.selectFirstOrThrow(selectTestScript) JSONObject(script.data().substringAfter('(').substringBeforeLast(')')) .getJSONArray("sources") .getJSONObject(0) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/AsuraScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/AsuraScansParser.kt index f78e7426..6d897ac3 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/AsuraScansParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/AsuraScansParser.kt @@ -7,7 +7,11 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("ASURASCANS", "Asura Scans", "en") internal class AsuraScansParser(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.ASURASCANS, "asura.gg", pageSize = 20, searchPageSize = 10) { + MangaReaderParser(context, MangaSource.ASURASCANS, "asura.nacm.xyz", pageSize = 20, searchPageSize = 10) { override val datePattern = "MMM d, yyyy" + override val selectPage = "div#readerarea p img" + + // A little dummy text to avoid importing the whole getpage part + override val selectTestScript = "Force to parse html" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/BirdManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/BirdManga.kt index 616b0a53..e2d5971d 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/BirdManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/BirdManga.kt @@ -9,5 +9,5 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("BIRDMANGA", "Bird Manga", "en") internal class BirdManga(context: MangaLoaderContext) : MangaReaderParser(context, MangaSource.BIRDMANGA, "birdmanga.com", pageSize = 20, searchPageSize = 10) { - override val encodedSrc = true + override val encodedSrc = true } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MiauScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MiauScan.kt index c77bb9d1..587bbe2f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MiauScan.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/es/MiauScan.kt @@ -7,4 +7,4 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser @MangaSourceParser("MIAUSCAN", "Miau Scan", "es") internal class MiauScan(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.MIAUSCAN, "miauscan.com", pageSize = 20, searchPageSize = 20) + MangaReaderParser(context, MangaSource.MIAUSCAN, "miauscans.com", pageSize = 20, searchPageSize = 20) 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 f1b8dba9..aad06724 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 @@ -61,7 +61,7 @@ internal abstract class MmrcmsParser( tags: Set?, sortOrder: SortOrder, ): List { - + val tag = tags.oneOrThrowIfMany() val url = if (sortOrder == SortOrder.UPDATED) { //the Updated page doesn't really exist, we just use the home page to weight the latest chapters, so it doesn't include tag and page management. buildString { @@ -75,23 +75,19 @@ internal abstract class MmrcmsParser( buildString { append("https://") append(domain) - append("/$listUrl/") append("?page=") append(page.toString()) append("&asc=true&author=&tag=") - append("&alpha=") + if (!query.isNullOrEmpty()) { append(query.urlEncoded()) } append("&cat=") if (!tags.isNullOrEmpty()) { - - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) } append("&sortBy=") 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 0a11e229..a5059ab5 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 @@ -146,12 +146,12 @@ class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaSo val url = "/forum/search-plus.php".toAbsoluteUrl(domain) val docs = webClient.httpGet(url).parseHtml() return docs.selectFirstOrThrow("ul.ul-search").select("li").mapNotNull { el -> - MangaTag( - title = el.text(), - key = el.selectFirst("input")?.attr("value") ?: return@mapNotNull null, - source = source, - ) - }.associateBy { it.title } + MangaTag( + title = el.text(), + key = el.selectFirst("input")?.attr("value") ?: return@mapNotNull null, + source = source, + ) + }.associateBy { it.title } } private fun getSortCookies(sortOrder: SortOrder): Array { @@ -225,19 +225,19 @@ class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaSo val chaptersEl = webClient.httpGet(chaptersAjax).parseHtml() val chapterDateFormat = SimpleDateFormat("dd/MM/yyyy") return chaptersEl.select("tbody > tr").mapChapters(reversed = true) { index, element -> - val titleEl = element.selectFirst("td > a") ?: return@mapChapters null - val dateStr = element.selectLast("td")?.text() - MangaChapter( - id = generateUid(titleEl.attrAsRelativeUrl("href")), - name = titleEl.text(), - number = index + 1, - url = titleEl.attrAsRelativeUrl("href"), - scanlator = null, - uploadDate = chapterDateFormat.tryParse(dateStr), - branch = null, - source = source, - ) - } + val titleEl = element.selectFirst("td > a") ?: return@mapChapters null + val dateStr = element.selectLast("td")?.text() + MangaChapter( + id = generateUid(titleEl.attrAsRelativeUrl("href")), + name = titleEl.text(), + number = index + 1, + url = titleEl.attrAsRelativeUrl("href"), + scanlator = null, + uploadDate = chapterDateFormat.tryParse(dateStr), + branch = null, + source = source, + ) + } } private fun Element.infoText(title: String) = 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 dd6015ee..5fa9d06c 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 @@ -16,7 +16,6 @@ internal abstract class VmpParser( ) : PagedMangaParser(context, source, pageSize) { override val configKeyDomain = ConfigKey.Domain(domain) - override val sortOrders: Set = EnumSet.of(SortOrder.UPDATED) protected open val listUrl = "xxx/" @@ -33,20 +32,15 @@ internal abstract class VmpParser( tags: Set?, sortOrder: SortOrder, ): List { - + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://$domain/") - if(!tags.isNullOrEmpty()) - { - append(geneUrl) - for (tag in tags) { - append(tag.key) - } - append("/page/") - append(page.toString()) - - }else - { + if (!tags.isNullOrEmpty()) { + append(geneUrl) + append(tag?.key.orEmpty()) + append("/page/") + append(page.toString()) + } else { append(listUrl) append("/page/") append(page.toString()) @@ -92,10 +86,10 @@ internal abstract class VmpParser( override suspend fun getDetails(manga: Manga): Manga = coroutineScope { val fullUrl = manga.url.toAbsoluteUrl(domain) - val doc= webClient.httpGet(fullUrl).parseHtml() + val doc = webClient.httpGet(fullUrl).parseHtml() manga.copy( - tags = doc.select("div.tax_box div.links ul:not(.post-categories) li a").mapNotNullToSet { a -> + tags = doc.select("div.tax_box div.links ul:not(.post-categories) li a").mapNotNullToSet { a -> MangaTag( key = a.attr("href").removeSuffix("/").substringAfterLast(geneUrl, ""), title = a.text().toTitleCase(), 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 9431a585..b5eb2e1c 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 @@ -55,6 +55,7 @@ internal abstract class WpComicsParser( tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -62,9 +63,7 @@ internal abstract class WpComicsParser( if (!tags.isNullOrEmpty()) { append("/") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) } append("?page=") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/en/XoxoComics.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/en/XoxoComics.kt index e71f8714..e954a0f4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/en/XoxoComics.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/en/XoxoComics.kt @@ -8,7 +8,7 @@ import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser import org.koitharu.kotatsu.parsers.util.* import java.util.EnumSet -@MangaSourceParser("XOXOCOMICS", "Xoxo Comics", "vi", ContentType.COMICS) +@MangaSourceParser("XOXOCOMICS", "Xoxo Comics", "en", ContentType.COMICS) internal class XoxoComics(context: MangaLoaderContext) : WpComicsParser(context, MangaSource.XOXOCOMICS, "xoxocomics.net", 50) { @@ -28,6 +28,7 @@ internal class XoxoComics(context: MangaLoaderContext) : tags: Set?, sortOrder: SortOrder, ): List { + val tag = tags.oneOrThrowIfMany() val url = buildString { append("https://") append(domain) @@ -41,9 +42,7 @@ internal class XoxoComics(context: MangaLoaderContext) : append(listUrl) if (!tags.isNullOrEmpty()) { append("/") - for (tag in tags) { - append(tag.key) - } + append(tag?.key.orEmpty()) } append("/") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/NeuManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/NeuManga.kt index 6ffc88a3..82bf83e3 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/NeuManga.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/zmanga/id/NeuManga.kt @@ -7,6 +7,6 @@ import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.zmanga.ZMangaParser -@MangaSourceParser("NEU_MANGA", "Neu Manga", "id") +@MangaSourceParser("NEU_MANGA", "Neu Manga Net", "id") internal class NeuManga(context: MangaLoaderContext) : ZMangaParser(context, MangaSource.NEU_MANGA, "neumanga.net")