From 28135aed6626edd91f0099582da02a79ae486cbb Mon Sep 17 00:00:00 2001 From: devi Date: Tue, 25 Jul 2023 21:30:07 +0200 Subject: [PATCH 1/6] add 2 new template and new source --- .../parsers/site/manga18/Manga18Parser.kt | 225 +++++++++++++++++ .../parsers/site/manga18/en/Hentai3zCc.kt | 96 ++++++++ .../parsers/site/manga18/en/Manga18.kt | 15 ++ .../parsers/site/manga18/en/PornComic18.kt | 16 ++ .../parsers/site/manga18/es/Tumanhwas.kt | 17 ++ .../site/mangareader/en/ManhuaScanUs.kt | 17 ++ .../parsers/site/mmrcms/MmrcmsParser.kt | 230 ++++++++++++++++++ .../site/mmrcms/en/ReadComicsOnline.kt | 16 ++ .../parsers/site/mmrcms/es/MangaDoor.kt | 22 ++ .../parsers/site/mmrcms/fr/JpMangas.kt | 17 ++ .../parsers/site/mmrcms/fr/LelScanVf.kt | 17 ++ .../kotatsu/parsers/site/mmrcms/fr/MangaFr.kt | 17 ++ .../parsers/site/mmrcms/fr/MangaScan.kt | 16 ++ .../parsers/site/mmrcms/fr/ScanFrOrg.kt | 18 ++ .../kotatsu/parsers/site/mmrcms/fr/ScanVf.kt | 17 ++ .../kotatsu/parsers/site/mmrcms/id/KomikId.kt | 21 ++ .../kotatsu/parsers/site/mmrcms/id/Mangaid.kt | 21 ++ .../parsers/site/mmrcms/pt/Animaregia.kt | 74 ++++++ 18 files changed, 872 insertions(+) create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhuaScanUs.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/ReadComicsOnline.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/es/MangaDoor.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpMangas.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/LelScanVf.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaScan.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanVf.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/KomikId.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/Mangaid.kt create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt 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 new file mode 100644 index 00000000..d6338eec --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt @@ -0,0 +1,225 @@ +package org.koitharu.kotatsu.parsers.site.madara + +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 +import org.koitharu.kotatsu.parsers.model.* +import org.koitharu.kotatsu.parsers.util.* +import java.text.SimpleDateFormat +import java.util.* + +internal abstract class Manga18Parser( + context: MangaLoaderContext, + source: MangaSource, + domain: String, + pageSize: Int = 20, +) : PagedMangaParser(context, source, pageSize) { + + override val configKeyDomain = ConfigKey.Domain(domain) + + override val sortOrders: Set = EnumSet.of( + SortOrder.UPDATED, + SortOrder.POPULARITY, + SortOrder.ALPHABETICAL, + ) + + protected open val listeurl = "list-manga" + protected open val tagUrl = "manga-list" + protected open val isNsfwSource = false + protected open val datePattern = "dd-MM-yyyy" + + + init { + paginator.firstPage = 1 + searchPaginator.firstPage = 1 + } + + + @JvmField + protected val ongoing: Set = hashSetOf( + "On Going", + ) + + @JvmField + protected val finished: Set = hashSetOf( + "Completed", + ) + + override suspend fun getListPage( + page: Int, + query: String?, + tags: Set?, + sortOrder: SortOrder, + ): List { + val url = buildString { + append("https://") + append(domain) + when { + !query.isNullOrEmpty() -> { + append("/$listeurl/") + append(page.toString()) + append("?search=") + append(query.urlEncoded()) + append("&") + } + + !tags.isNullOrEmpty() -> { + append("/$tagUrl/") + for (tag in tags) { + append(tag.key) + } + append("/") + append(page.toString()) + append("?") + } + + else -> { + append("/$listeurl/") + append(page.toString()) + append("?") + } + } + append("order_by=") + when (sortOrder) { + SortOrder.POPULARITY -> append("views") + SortOrder.UPDATED -> append("lastest") + SortOrder.ALPHABETICAL -> append("name") + else -> append("latest") + } + } + val doc = webClient.httpGet(url).parseHtml() + + return doc.select("div.story_item").map { div -> + val href = div.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found") + Manga( + id = generateUid(href), + url = href, + publicUrl = href.toAbsoluteUrl(div.host ?: domain), + coverUrl = div.selectFirst("img")?.src().orEmpty(), + title = div.selectFirstOrThrow("div.mg_info").selectFirst("div.mg_name a")?.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("div.grid_cate li").mapNotNullToSet { li -> + val a = li.selectFirst("a") ?: return@mapNotNullToSet null + val href = a.attr("href").substringAfterLast("/") + MangaTag( + key = href, + title = a.text(), + source = source, + ) + } + } + + protected open val selectdesc = "div.detail_reviewContent" + protected open val selectdate = "div.item p" + protected open val selectchapter = "div.chapter_box li" + protected open val selectState = "div.item:contains(Status) div.info_value" + protected open val selectAlt = "div.item:contains(Other name) div.info_value" + protected open val selectTag = "div.item:contains(Categories) div.info_value a" + + override suspend fun getDetails(manga: Manga): Manga = coroutineScope { + val fullUrl = manga.url.toAbsoluteUrl(domain) + val doc = webClient.httpGet(fullUrl).parseHtml() + val body = doc.body().selectFirstOrThrow("div.detail_listInfo") + + val chaptersDeferred = async { getChapters(manga, doc) } + + val desc = doc.select(selectdesc).let { + if (it.select("p").text().isNotEmpty()) { + it.select("p").joinToString(separator = "\n\n") { p -> + p.text().replace("
", "\n") + } + } else { + it.text() + } + } + + val stateDiv = body.selectFirst(selectState) + + val state = stateDiv?.let { + when (it.text()) { + in ongoing -> MangaState.ONGOING + in finished -> MangaState.FINISHED + else -> null + } + } + + val alt = doc.body().select(selectAlt).text() + + manga.copy( + tags = doc.body().select(selectTag).mapNotNullToSet { a -> + MangaTag( + key = a.attr("href").removeSuffix("/").substringAfterLast('/'), + title = a.text().toTitleCase(), + source = source, + ) + }, + description = desc, + altTitle = alt, + state = state, + chapters = chaptersDeferred.await(), + ) + } + + + protected open suspend fun getChapters(manga: Manga, doc: Document): List { + val dateFormat = SimpleDateFormat(datePattern, sourceLocale) + return doc.body().select(selectchapter).mapChapters(reversed = true) { i, li -> + val a = li.selectFirst("a") + val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") + val dateText = li.selectFirst(selectdate)?.text() + MangaChapter( + id = generateUid(href), + name = a.text(), + number = i + 1, + url = href, + uploadDate = dateFormat.tryParse(dateText), + source = source, + scanlator = null, + branch = null, + ) + } + } + + override suspend fun getPages(chapter: MangaChapter): List { + val fullUrl = chapter.url.toAbsoluteUrl(domain) + val doc = webClient.httpGet(fullUrl).parseHtml() + + val script = doc.selectFirstOrThrow("script:containsData(slides_p_path)") + val urlencoed = script.data().substringAfter('[').substringBefore(",]").replace("\"", "").split(",") + return urlencoed.map { url -> + val img = context.decodeBase64(url).toString(Charsets.UTF_8) + + MangaPage( + id = generateUid(img), + url = img, + preview = null, + source = source, + ) + } + } + + + protected fun Element.src(): String? { + var result = absUrl("data-src") + if (result.isEmpty()) result = absUrl("data-cfsrc") + if (result.isEmpty()) result = absUrl("src") + return result.ifEmpty { null } + } + +} 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 new file mode 100644 index 00000000..3a6ebeb8 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt @@ -0,0 +1,96 @@ +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.Manga +import org.koitharu.kotatsu.parsers.model.MangaSource +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.site.madara.Manga18Parser +import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrlOrNull +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.parseFailed +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.urlEncoded + + +@MangaSourceParser("HENTAI3ZCC", "Hentai3z Cc", "en") +internal class Hentai3zCc(context: MangaLoaderContext) : + Manga18Parser(context, MangaSource.HENTAI3ZCC, "hentai3z.cc") { + + override val isNsfwSource = true + + override suspend fun getListPage( + page: Int, + query: String?, + tags: Set?, + sortOrder: SortOrder, + ): List { + val url = buildString { + append("https://") + append(domain) + val pages = page + 1 + when { + !query.isNullOrEmpty() -> { + append("/$listeurl/") + append(pages.toString()) + append("?search=") + append(query.urlEncoded()) + append("&") + } + + !tags.isNullOrEmpty() -> { + append("/$tagUrl/") + for (tag in tags) { + append(tag.key) + } + append("/") + append(pages.toString()) + append("?") + } + + else -> { + append("/$listeurl/") + append(pages.toString()) + append("?") + } + } + append("order_by=") + when (sortOrder) { + SortOrder.POPULARITY -> append("views") + SortOrder.UPDATED -> append("lastest") + SortOrder.ALPHABETICAL -> append("name") + else -> append("latest") + } + } + val doc = webClient.httpGet(url).parseHtml() + + + return doc.select("div.story_item").map { div -> + val href = div.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found") + Manga( + id = generateUid(href), + url = href, + publicUrl = href.toAbsoluteUrl(div.host ?: domain), + coverUrl = div.selectFirst("img")?.src() + ?.replace("cover_thumb_2.webp", "cover_250x350.jpg") + ?.replace("admin.manga18.us", "bk.18porncomic.com") + .orEmpty(), + title = div.selectFirstOrThrow("div.mg_info").selectFirst("div.mg_name a")?.text().orEmpty(), + altTitle = null, + rating = RATING_UNKNOWN, + tags = emptySet(), + author = null, + state = null, + source = source, + isNsfw = isNsfwSource, + ) + } + } +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt new file mode 100644 index 00000000..0bded4e8 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt @@ -0,0 +1,15 @@ +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.Manga18Parser + + +@MangaSourceParser("MANGA18", "Manga18", "en") +internal class Manga18(context: MangaLoaderContext) : + Manga18Parser(context, MangaSource.MANGA18, "manga18.club") { + + override val isNsfwSource = true +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt new file mode 100644 index 00000000..98fb41dc --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt @@ -0,0 +1,16 @@ +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.Manga18Parser + + +@MangaSourceParser("PORNCOMIC18", "18 Porn Comic", "en") +internal class PornComic18(context: MangaLoaderContext) : + Manga18Parser(context, MangaSource.PORNCOMIC18, "18porncomic.com") { + + override val selectTag = "div.item:not(.info_label) div.info_value a" + override val isNsfwSource = true +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt new file mode 100644 index 00000000..19c0e9b3 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt @@ -0,0 +1,17 @@ +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.Manga18Parser + + +@MangaSourceParser("TUMANHWAS", "Tumanhwas", "es") +internal class Tumanhwas(context: MangaLoaderContext) : + Manga18Parser(context, MangaSource.TUMANHWAS, "tumanhwas.club") { + + override val isNsfwSource = true + override val selectTag = "div.item:contains(Géneros) div.info_value a" + override val selectAlt = "div.item:contains(Títulos alternativos) div.info_value" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhuaScanUs.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhuaScanUs.kt new file mode 100644 index 00000000..7f14fabe --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhuaScanUs.kt @@ -0,0 +1,17 @@ +package org.koitharu.kotatsu.parsers.site.mangareader.en + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser + + +@MangaSourceParser("MANHUASCANUS", "Manhua Scan Us", "en") +internal class ManhuaScanUs(context: MangaLoaderContext) : + MangaReaderParser(context, MangaSource.MANHUASCANUS, "manhuascan.us", pageSize = 30, searchPageSize = 30) { + + override val isNsfwSource: Boolean = true + override val datePattern = "dd-MM-yyyy" + override val listUrl = "/manga-list" + +} 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 new file mode 100644 index 00000000..77dc112e --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt @@ -0,0 +1,230 @@ +package org.koitharu.kotatsu.parsers.site.madara + +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 +import org.koitharu.kotatsu.parsers.model.* +import org.koitharu.kotatsu.parsers.util.* +import java.text.SimpleDateFormat +import java.util.* + +internal abstract class MmrcmsParser( + context: MangaLoaderContext, + source: MangaSource, + domain: String, + pageSize: Int = 20, +) : PagedMangaParser(context, source, pageSize) { + + override val configKeyDomain = ConfigKey.Domain(domain) + + override val sortOrders: Set = EnumSet.of( + SortOrder.POPULARITY, + SortOrder.ALPHABETICAL, + ) + + protected open val listeurl = "filterList" + protected open val tagUrl = "manga-list" + protected open val isNsfwSource = false + protected open val datePattern = "dd MMM. yyyy" + + + init { + paginator.firstPage = 1 + searchPaginator.firstPage = 1 + } + + + @JvmField + protected val ongoing: Set = hashSetOf( + "On Going", + "Ongoing", + "En cours", + "En curso", + ) + + @JvmField + protected val finished: Set = hashSetOf( + "Completed", + "Completo", + "Complete", + "Terminé", + ) + + override suspend fun getListPage( + page: Int, + query: String?, + tags: Set?, + sortOrder: SortOrder, + ): List { + val url = buildString { + append("https://") + append(domain) + + append("/$listeurl/") + 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("&sortBy=") + when (sortOrder) { + SortOrder.POPULARITY -> append("views") + SortOrder.ALPHABETICAL -> append("name") + else -> append("views") + } + } + val doc = webClient.httpGet(url).parseHtml() + + return doc.select("div.media").map { div -> + val href = div.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found") + Manga( + id = generateUid(href), + url = href, + publicUrl = href.toAbsoluteUrl(div.host ?: domain), + coverUrl = div.selectFirst("img")?.src().orEmpty(), + title = div.selectFirstOrThrow("div.media-body h5").text().orEmpty(), + altTitle = null, + rating = div.selectFirstOrThrow("span").ownText().toFloatOrNull()?.div(5f) ?: -1f, + tags = emptySet(), + author = null, + state = null, + source = source, + isNsfw = isNsfwSource, + ) + } + } + + override suspend fun getTags(): Set { + val doc = webClient.httpGet("https://$domain/$tagUrl/").parseHtml() + return doc.select("ul.list-category li").mapNotNullToSet { li -> + val a = li.selectFirst("a") ?: return@mapNotNullToSet null + val href = a.attr("href").substringAfterLast("cat=") + MangaTag( + key = href, + title = a.text(), + source = source, + ) + } + } + + protected open val selectdesc = "div.well" + protected open val selectState = "dt:contains(Statut)" + protected open val selectAlt = "dt:contains(Autres noms)" + protected open val selectAut = "dt:contains(Auteur(s))" + protected open val selectTag = "dt:contains(Catégories)" + + override suspend fun getDetails(manga: Manga): Manga = coroutineScope { + val fullUrl = manga.url.toAbsoluteUrl(domain) + val doc = webClient.httpGet(fullUrl).parseHtml() + val body = doc.body().selectFirstOrThrow("dl.dl-horizontal") + + val chaptersDeferred = async { getChapters(manga, doc) } + + val desc = doc.select(selectdesc).let { + if (it.select("p").text().isNotEmpty()) { + it.select("p").joinToString(separator = "\n\n") { p -> + p.text().replace("
", "\n") + } + } else { + it.text() + } + } + + val stateDiv = body.selectFirst(selectState)?.nextElementSibling() + + val state = stateDiv?.let { + when (it.text()) { + in ongoing -> MangaState.ONGOING + in finished -> MangaState.FINISHED + else -> null + } + } + + val alt = doc.body().selectFirst(selectAlt)?.nextElementSibling()?.text() + val auth = doc.body().selectFirst(selectAut)?.nextElementSibling()?.text() + + val tags = doc.body().selectFirst(selectTag)?.nextElementSibling()?.select("a") ?: emptySet() + + manga.copy( + tags = tags.mapNotNullToSet { a -> + MangaTag( + key = a.attr("href").substringAfterLast("/"), + title = a.text().toTitleCase(), + source = source, + ) + }, + author = auth, + description = desc, + altTitle = alt, + state = state, + chapters = chaptersDeferred.await(), + ) + } + + + protected open val selectdate = "div.date-chapter-title-rtl" + protected open val selectchapter = "ul.chapters > li:not(.btn)" + + protected open suspend fun getChapters(manga: Manga, doc: Document): List { + val dateFormat = SimpleDateFormat(datePattern, sourceLocale) + + return doc.body().select(selectchapter).mapChapters(reversed = true) { i, li -> + val a = li.selectFirst("a") + val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") + val dateText = li.selectFirst(selectdate)?.text() + MangaChapter( + id = generateUid(href), + name = li.selectFirstOrThrow("h5").text(), + number = i + 1, + url = href, + uploadDate = dateFormat.tryParse(dateText), + source = source, + scanlator = null, + branch = null, + ) + } + } + + protected open val selectPage = "div#all 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 { url -> + val img = url.src()?.toRelativeUrl(domain) ?: url.parseFailed("Image src not found") + MangaPage( + id = generateUid(img), + url = img, + preview = null, + source = source, + ) + } + } + + + protected fun Element.src(): String? { + var result = absUrl("data-src") + if (result.isEmpty()) result = absUrl("data-cfsrc") + if (result.isEmpty()) result = absUrl("src") + return result.ifEmpty { null } + } + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/ReadComicsOnline.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/ReadComicsOnline.kt new file mode 100644 index 00000000..abcdc546 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/ReadComicsOnline.kt @@ -0,0 +1,16 @@ +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.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser + + +@MangaSourceParser("READCOMICSONLINE", "Read Comics Online", "en") +internal class ReadComicsOnline(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.READCOMICSONLINE, "readcomicsonline.ru") { + + override val selectState = "dt:contains(Status)" + override val selectTag = "dt:contains(Categories)" +} 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 new file mode 100644 index 00000000..771354fc --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/es/MangaDoor.kt @@ -0,0 +1,22 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.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.MmrcmsParser +import java.util.Locale + + +@MangaSourceParser("MANGADOOR", "Manga Door", "es") +internal class MangaDoor(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.MANGADOOR, "mangadoor.com") { + + + override val sourceLocale: Locale = Locale.ENGLISH + + override val selectState = "dt:contains(Estado)" + override val selectAlt = "dt:contains(Otros nombres)" + override val selectAut = "dt:contains(Autor(es))" + override val selectTag = "dt:contains(Categorías)" +} 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 new file mode 100644 index 00000000..53c4a5d8 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpMangas.kt @@ -0,0 +1,17 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.fr + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import java.util.Locale + + +@MangaSourceParser("JPMANGAS", "JpMangas", "fr") +internal class JpMangas(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.JPMANGAS, "jpmangas.xyz") { + + + override val sourceLocale: Locale = Locale.ENGLISH +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/LelScanVf.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/LelScanVf.kt new file mode 100644 index 00000000..c3b35912 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/LelScanVf.kt @@ -0,0 +1,17 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.fr + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import java.util.Locale + + +@MangaSourceParser("LELSCANVF", "Lel Scan Vf", "fr") +internal class LelScanVf(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.LELSCANVF, "lelscanvf.cc") { + + + override val sourceLocale: Locale = Locale.ENGLISH +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt new file mode 100644 index 00000000..e5fdd00d --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt @@ -0,0 +1,17 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.fr + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import java.util.Locale + + +@MangaSourceParser("MANGAFR", "Manga Fr", "fr") +internal class MangaFr(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.MANGAFR, "manga-fr.me") { + + + override val sourceLocale: Locale = Locale.ENGLISH +} 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 new file mode 100644 index 00000000..3c7a6808 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaScan.kt @@ -0,0 +1,16 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.fr + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import java.util.Locale + + +@MangaSourceParser("MANGA_SCAN", "Manga-Scan", "fr") +internal class MangaScan(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.MANGA_SCAN, "manga-scan.co") { + + override val sourceLocale: Locale = Locale.ENGLISH +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt new file mode 100644 index 00000000..81fff394 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt @@ -0,0 +1,18 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.fr + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import java.util.Locale + + +@MangaSourceParser("SCAN_FR_ORG", "Scan-Fr Org", "fr") +internal class ScanFrOrg(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.SCAN_FR_ORG, "www.scan-fr.org") { + + + override val sourceLocale: Locale = Locale.ENGLISH + override val selectchapter = "ul.chapterszozo li" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanVf.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanVf.kt new file mode 100644 index 00000000..0d3031a9 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanVf.kt @@ -0,0 +1,17 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.fr + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import java.util.Locale + + +@MangaSourceParser("SCANVF", "Scan Vf", "fr") +internal class ScanVf(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.SCANVF, "www.scan-vf.net") { + + + override val sourceLocale: Locale = Locale.ENGLISH +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/KomikId.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/KomikId.kt new file mode 100644 index 00000000..20bac082 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/KomikId.kt @@ -0,0 +1,21 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.id + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import java.util.Locale + + +@MangaSourceParser("KOMIKID", "KomikId", "id") +internal class KomikId(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.KOMIKID, "komikid.com") { + + + override val selectState = "dt:contains(Status)" + override val selectAlt = "dt:contains(Other names)" + override val selectAut = "dt:contains(Author(s))" + override val selectTag = "dt:contains(Categories)" + override val sourceLocale: Locale = Locale.ENGLISH +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/Mangaid.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/Mangaid.kt new file mode 100644 index 00000000..fe361a9e --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/Mangaid.kt @@ -0,0 +1,21 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.id + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import java.util.Locale + + +@MangaSourceParser("MANGAID", "Mangaid", "id") +internal class Mangaid(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.MANGAID, "mangaid.click") { + + + override val selectState = "dt:contains(Status)" + override val selectAlt = "dt:contains(Other names)" + override val selectAut = "dt:contains(Author(s))" + override val selectTag = "dt:contains(Categories)" + override val sourceLocale: Locale = Locale.ENGLISH +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt new file mode 100644 index 00000000..db19266a --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt @@ -0,0 +1,74 @@ +package org.koitharu.kotatsu.parsers.site.mmrcms.pt + + +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope +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.MangaSource +import org.koitharu.kotatsu.parsers.model.MangaState +import org.koitharu.kotatsu.parsers.model.MangaTag +import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +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.selectFirstOrThrow +import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl +import org.koitharu.kotatsu.parsers.util.toTitleCase +import java.util.Locale + + +@MangaSourceParser("ANIMAREGIA", "Animaregia", "pt") +internal class Animaregia(context: MangaLoaderContext) : + MmrcmsParser(context, MangaSource.ANIMAREGIA, "animaregia.net") { + + override val selectdate = "div.col-md-4" + override val sourceLocale: Locale = Locale.ENGLISH + + override suspend fun getDetails(manga: Manga): Manga = coroutineScope { + val fullUrl = manga.url.toAbsoluteUrl(domain) + val doc = webClient.httpGet(fullUrl).parseHtml() + val body = doc.body().selectFirstOrThrow("ul.list-group") + + val chaptersDeferred = async { getChapters(manga, doc) } + + val desc = doc.select(selectdesc).let { + if (it.select("p").text().isNotEmpty()) { + it.select("p").joinToString(separator = "\n\n") { p -> + p.text().replace("
", "\n") + } + } else { + it.text() + } + } + + val stateDiv = body.selectFirst("li.list-group-item:contains(Status)")?.lastElementChild() + + val state = stateDiv?.let { + when (it.text()) { + in ongoing -> MangaState.ONGOING + in finished -> MangaState.FINISHED + else -> null + } + } + val auth = doc.body().selectFirst("li.list-group-item:contains(Autor(es)) a")?.text() + + val tags = doc.body().select("li.list-group-item:contains(Autor(es)) a") ?: emptySet() + + manga.copy( + tags = tags.mapNotNullToSet { a -> + MangaTag( + key = a.attr("href").substringAfterLast("/"), + title = a.text().toTitleCase(), + source = source, + ) + }, + author = auth, + description = desc, + altTitle = null, + state = state, + chapters = chaptersDeferred.await(), + ) + } +} From f6dc4f9a005a30fd65adb7a274872c331bc209d6 Mon Sep 17 00:00:00 2001 From: devi Date: Wed, 26 Jul 2023 19:04:43 +0200 Subject: [PATCH 2/6] add source --- .../kotatsu/parsers/site/fr/LugnicaScans.kt | 2 -- .../parsers/site/mangareader/en/LynxScans.kt | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LynxScans.kt 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 61b23dd0..6c41f95c 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 @@ -5,7 +5,6 @@ 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.exception.ParseException import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.network.UserAgents import org.koitharu.kotatsu.parsers.util.* @@ -167,7 +166,6 @@ internal class LugnicaScans(context: MangaLoaderContext) : PagedMangaParser(cont val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() val root = doc.body().requireElementById("forgen_reader") - ?: throw ParseException("Root not found", fullUrl) return root.select("img").map { img -> val url = img.attrAsRelativeUrlOrNull("data-src") ?: img.attrAsRelativeUrlOrNull("src") ?: img.parseFailed("Image src not found") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LynxScans.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LynxScans.kt new file mode 100644 index 00000000..44e65d8d --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/LynxScans.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.parsers.site.mangareader.en + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser + + +@MangaSourceParser("LYNXSCANS", "LynxScans", "en") +internal class LynxScans(context: MangaLoaderContext) : + MangaReaderParser(context, MangaSource.LYNXSCANS, "lynxscans.com", pageSize = 25, searchPageSize = 10) { + + override val listUrl = "/comics" + +} From 7e2a00520bf63626d34034827a32013875cba147 Mon Sep 17 00:00:00 2001 From: devi Date: Thu, 27 Jul 2023 16:42:28 +0200 Subject: [PATCH 3/6] fix and add updated on template Mmrcms --- .../parsers/site/manga18/Manga18Parser.kt | 34 ++--- .../parsers/site/manga18/en/Hentai3zCc.kt | 5 +- .../parsers/site/mmrcms/MmrcmsParser.kt | 131 +++++++++++------- .../kotatsu/parsers/site/mmrcms/fr/MangaFr.kt | 1 + .../parsers/site/mmrcms/fr/MangaScan.kt | 1 + .../parsers/site/mmrcms/pt/Animaregia.kt | 27 ++-- 6 files changed, 109 insertions(+), 90 deletions(-) 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 d6338eec..e9d46e77 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 @@ -27,8 +27,8 @@ internal abstract class Manga18Parser( SortOrder.ALPHABETICAL, ) - protected open val listeurl = "list-manga" - protected open val tagUrl = "manga-list" + protected open val listeurl = "list-manga/" + protected open val tagUrl = "manga-list/" protected open val isNsfwSource = false protected open val datePattern = "dd-MM-yyyy" @@ -40,12 +40,12 @@ internal abstract class Manga18Parser( @JvmField - protected val ongoing: Set = hashSetOf( + protected val ongoing: Set = setOf( "On Going", ) @JvmField - protected val finished: Set = hashSetOf( + protected val finished: Set = setOf( "Completed", ) @@ -60,7 +60,7 @@ internal abstract class Manga18Parser( append(domain) when { !query.isNullOrEmpty() -> { - append("/$listeurl/") + append("/$listeurl") append(page.toString()) append("?search=") append(query.urlEncoded()) @@ -68,7 +68,7 @@ internal abstract class Manga18Parser( } !tags.isNullOrEmpty() -> { - append("/$tagUrl/") + append("/$tagUrl") for (tag in tags) { append(tag.key) } @@ -78,7 +78,7 @@ internal abstract class Manga18Parser( } else -> { - append("/$listeurl/") + append("/$listeurl") append(page.toString()) append("?") } @@ -94,7 +94,7 @@ internal abstract class Manga18Parser( val doc = webClient.httpGet(url).parseHtml() return doc.select("div.story_item").map { div -> - val href = div.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found") + val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") Manga( id = generateUid(href), url = href, @@ -116,7 +116,7 @@ internal abstract class Manga18Parser( val doc = webClient.httpGet("https://$domain/$listeurl/").parseHtml() return doc.select("div.grid_cate li").mapNotNullToSet { li -> val a = li.selectFirst("a") ?: return@mapNotNullToSet null - val href = a.attr("href").substringAfterLast("/") + val href = a.attr("href").removeSuffix('/').substringAfterLast('/') MangaTag( key = href, title = a.text(), @@ -139,15 +139,7 @@ internal abstract class Manga18Parser( val chaptersDeferred = async { getChapters(manga, doc) } - val desc = doc.select(selectdesc).let { - if (it.select("p").text().isNotEmpty()) { - it.select("p").joinToString(separator = "\n\n") { p -> - p.text().replace("
", "\n") - } - } else { - it.text() - } - } + val desc = doc.selectFirstOrThrow(selectdesc).html() val stateDiv = body.selectFirst(selectState) @@ -164,7 +156,7 @@ internal abstract class Manga18Parser( manga.copy( tags = doc.body().select(selectTag).mapNotNullToSet { a -> MangaTag( - key = a.attr("href").removeSuffix("/").substringAfterLast('/'), + key = a.attr("href").removeSuffix('/').substringAfterLast('/'), title = a.text().toTitleCase(), source = source, ) @@ -180,8 +172,8 @@ internal abstract class Manga18Parser( protected open suspend fun getChapters(manga: Manga, doc: Document): List { val dateFormat = SimpleDateFormat(datePattern, sourceLocale) return doc.body().select(selectchapter).mapChapters(reversed = true) { i, li -> - val a = li.selectFirst("a") - val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") + val a = li.selectFirstOrThrow("a") + val href = a.attrAsRelativeUrl("href") val dateText = li.selectFirst(selectdate)?.text() MangaChapter( id = generateUid(href), 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 3a6ebeb8..babc32c1 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 @@ -9,11 +9,10 @@ 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.site.madara.Manga18Parser -import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrlOrNull +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.parseFailed import org.koitharu.kotatsu.parsers.util.parseHtml import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl @@ -73,7 +72,7 @@ internal class Hentai3zCc(context: MangaLoaderContext) : return doc.select("div.story_item").map { div -> - val href = div.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found") + val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") Manga( id = generateUid(href), url = href, 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 77dc112e..cb7362b9 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( override val sortOrders: Set = EnumSet.of( SortOrder.POPULARITY, SortOrder.ALPHABETICAL, + SortOrder.UPDATED, ) protected open val listeurl = "filterList" @@ -54,60 +55,98 @@ internal abstract class MmrcmsParser( "Terminé", ) + protected open val imgUpdated = "/cover/cover_250x350.jpg" + override suspend fun getListPage( page: Int, query: String?, tags: Set?, sortOrder: SortOrder, ): List { - val url = buildString { - append("https://") - append(domain) - - append("/$listeurl/") - append("?page=") - append(page.toString()) - append("&asc=true&author=&tag=") - - append("&alpha=") - if (!query.isNullOrEmpty()) { - append(query.urlEncoded()) + + 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 { + append("https://") + append(domain) + if (page == 2) { + append("/STOP") + } } + } else { + buildString { + append("https://") + append(domain) + + append("/$listeurl/") + append("?page=") + append(page.toString()) + append("&asc=true&author=&tag=") + + append("&alpha=") + if (!query.isNullOrEmpty()) { + append(query.urlEncoded()) + } - append("&cat=") - if (!tags.isNullOrEmpty()) { + append("&cat=") + if (!tags.isNullOrEmpty()) { - for (tag in tags) { - append(tag.key) + for (tag in tags) { + append(tag.key) + } } - } - append("&sortBy=") - when (sortOrder) { - SortOrder.POPULARITY -> append("views") - SortOrder.ALPHABETICAL -> append("name") - else -> append("views") + append("&sortBy=") + when (sortOrder) { + SortOrder.POPULARITY -> append("views") + SortOrder.ALPHABETICAL -> append("name") + else -> append("views") + } } } + val doc = webClient.httpGet(url).parseHtml() - return doc.select("div.media").map { div -> - val href = div.selectFirst("a")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found") - Manga( - id = generateUid(href), - url = href, - publicUrl = href.toAbsoluteUrl(div.host ?: domain), - coverUrl = div.selectFirst("img")?.src().orEmpty(), - title = div.selectFirstOrThrow("div.media-body h5").text().orEmpty(), - altTitle = null, - rating = div.selectFirstOrThrow("span").ownText().toFloatOrNull()?.div(5f) ?: -1f, - tags = emptySet(), - author = null, - state = null, - source = source, - isNsfw = isNsfwSource, - ) + if (sortOrder == SortOrder.UPDATED) { + + return doc.select("div.manga-item").map { div -> + val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href") + val deeplink = href.substringAfterLast("/") + Manga( + id = generateUid(href), + url = href, + publicUrl = href.toAbsoluteUrl(div.host ?: domain), + coverUrl = "https://$domain/uploads/manga/$deeplink$imgUpdated", + title = div.selectFirstOrThrow("a").text().orEmpty(), + altTitle = null, + rating = RATING_UNKNOWN, + tags = emptySet(), + author = null, + state = null, + source = source, + isNsfw = isNsfwSource, + ) + } + } else { + return doc.select("div.media").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("div.media-body h5").text().orEmpty(), + altTitle = null, + rating = div.selectFirstOrThrow("span").ownText().toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN, + tags = emptySet(), + author = null, + state = null, + source = source, + isNsfw = isNsfwSource, + ) + } } + } override suspend fun getTags(): Set { @@ -136,15 +175,7 @@ internal abstract class MmrcmsParser( val chaptersDeferred = async { getChapters(manga, doc) } - val desc = doc.select(selectdesc).let { - if (it.select("p").text().isNotEmpty()) { - it.select("p").joinToString(separator = "\n\n") { p -> - p.text().replace("
", "\n") - } - } else { - it.text() - } - } + val desc = doc.selectFirstOrThrow(selectdesc).text() val stateDiv = body.selectFirst(selectState)?.nextElementSibling() @@ -164,7 +195,7 @@ internal abstract class MmrcmsParser( manga.copy( tags = tags.mapNotNullToSet { a -> MangaTag( - key = a.attr("href").substringAfterLast("/"), + key = a.attr("href").removeSuffix('/').substringAfterLast('/'), title = a.text().toTitleCase(), source = source, ) @@ -185,8 +216,8 @@ internal abstract class MmrcmsParser( val dateFormat = SimpleDateFormat(datePattern, sourceLocale) return doc.body().select(selectchapter).mapChapters(reversed = true) { i, li -> - val a = li.selectFirst("a") - val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") + val a = li.selectFirstOrThrow("a") + val href = a.attrAsRelativeUrl("href") val dateText = li.selectFirst(selectdate)?.text() MangaChapter( id = generateUid(href), diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt index e5fdd00d..fd91da6e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt @@ -13,5 +13,6 @@ internal class MangaFr(context: MangaLoaderContext) : MmrcmsParser(context, MangaSource.MANGAFR, "manga-fr.me") { + override val imgUpdated = ".jpg" override val sourceLocale: Locale = Locale.ENGLISH } 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 3c7a6808..ef039b47 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 @@ -12,5 +12,6 @@ import java.util.Locale internal class MangaScan(context: MangaLoaderContext) : MmrcmsParser(context, MangaSource.MANGA_SCAN, "manga-scan.co") { + override val imgUpdated = ".jpg" override val sourceLocale: Locale = Locale.ENGLISH } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt index db19266a..3b37c247 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt @@ -9,13 +9,10 @@ import org.koitharu.kotatsu.parsers.model.Manga 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.SortOrder import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser -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.selectFirstOrThrow -import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl -import org.koitharu.kotatsu.parsers.util.toTitleCase +import org.koitharu.kotatsu.parsers.util.* +import java.util.EnumSet import java.util.Locale @@ -26,6 +23,12 @@ internal class Animaregia(context: MangaLoaderContext) : override val selectdate = "div.col-md-4" override val sourceLocale: Locale = Locale.ENGLISH + //temporary + override val sortOrders: Set = EnumSet.of( + SortOrder.POPULARITY, + SortOrder.ALPHABETICAL, + ) + override suspend fun getDetails(manga: Manga): Manga = coroutineScope { val fullUrl = manga.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() @@ -33,15 +36,7 @@ internal class Animaregia(context: MangaLoaderContext) : val chaptersDeferred = async { getChapters(manga, doc) } - val desc = doc.select(selectdesc).let { - if (it.select("p").text().isNotEmpty()) { - it.select("p").joinToString(separator = "\n\n") { p -> - p.text().replace("
", "\n") - } - } else { - it.text() - } - } + val desc = doc.select(selectdesc).text() val stateDiv = body.selectFirst("li.list-group-item:contains(Status)")?.lastElementChild() @@ -59,7 +54,7 @@ internal class Animaregia(context: MangaLoaderContext) : manga.copy( tags = tags.mapNotNullToSet { a -> MangaTag( - key = a.attr("href").substringAfterLast("/"), + key = a.attr("href").removeSuffix('/').substringAfterLast('/'), title = a.text().toTitleCase(), source = source, ) From 70fda48983e7b4a0b84179b64c5e4f625dabc8f9 Mon Sep 17 00:00:00 2001 From: devi Date: Thu, 27 Jul 2023 16:52:31 +0200 Subject: [PATCH 4/6] fix nswf --- .../kotatsu/parsers/site/manga18/Manga18Parser.kt | 1 - .../kotatsu/parsers/site/manga18/en/Hentai3zCc.kt | 5 ++--- .../koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt | 8 +++----- .../kotatsu/parsers/site/manga18/en/PornComic18.kt | 4 ++-- .../koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt | 4 ++-- .../kotatsu/parsers/site/mangareader/en/ManhuaScanUs.kt | 4 ++-- .../koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt | 1 - 7 files changed, 11 insertions(+), 16 deletions(-) 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 e9d46e77..311cb3c4 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 @@ -29,7 +29,6 @@ internal abstract class Manga18Parser( protected open val listeurl = "list-manga/" protected open val tagUrl = "manga-list/" - protected open val isNsfwSource = false protected open val datePattern = "dd-MM-yyyy" 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 babc32c1..94d744e3 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 @@ -3,6 +3,7 @@ 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.Manga import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.model.MangaTag @@ -19,12 +20,10 @@ import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl import org.koitharu.kotatsu.parsers.util.urlEncoded -@MangaSourceParser("HENTAI3ZCC", "Hentai3z Cc", "en") +@MangaSourceParser("HENTAI3ZCC", "Hentai3z Cc", "en", ContentType.HENTAI) internal class Hentai3zCc(context: MangaLoaderContext) : Manga18Parser(context, MangaSource.HENTAI3ZCC, "hentai3z.cc") { - override val isNsfwSource = true - override suspend fun getListPage( page: Int, query: String?, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt index 0bded4e8..53322a30 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt @@ -3,13 +3,11 @@ 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.MangaSource import org.koitharu.kotatsu.parsers.site.madara.Manga18Parser -@MangaSourceParser("MANGA18", "Manga18", "en") +@MangaSourceParser("MANGA18", "Manga18", "en", ContentType.HENTAI) internal class Manga18(context: MangaLoaderContext) : - Manga18Parser(context, MangaSource.MANGA18, "manga18.club") { - - override val isNsfwSource = true -} + Manga18Parser(context, MangaSource.MANGA18, "manga18.club") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt index 98fb41dc..f7f04976 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt @@ -3,14 +3,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.ContentType import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.Manga18Parser -@MangaSourceParser("PORNCOMIC18", "18 Porn Comic", "en") +@MangaSourceParser("PORNCOMIC18", "18 Porn Comic", "en", ContentType.HENTAI) internal class PornComic18(context: MangaLoaderContext) : Manga18Parser(context, MangaSource.PORNCOMIC18, "18porncomic.com") { override val selectTag = "div.item:not(.info_label) div.info_value a" - override val isNsfwSource = true } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt index 19c0e9b3..d5623e09 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt @@ -3,15 +3,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.ContentType import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.madara.Manga18Parser -@MangaSourceParser("TUMANHWAS", "Tumanhwas", "es") +@MangaSourceParser("TUMANHWAS", "Tumanhwas", "es", ContentType.HENTAI) internal class Tumanhwas(context: MangaLoaderContext) : Manga18Parser(context, MangaSource.TUMANHWAS, "tumanhwas.club") { - override val isNsfwSource = true override val selectTag = "div.item:contains(Géneros) div.info_value a" override val selectAlt = "div.item:contains(Títulos alternativos) div.info_value" } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhuaScanUs.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhuaScanUs.kt index 7f14fabe..797fcb25 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhuaScanUs.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/ManhuaScanUs.kt @@ -2,15 +2,15 @@ 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.ContentType import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser -@MangaSourceParser("MANHUASCANUS", "Manhua Scan Us", "en") +@MangaSourceParser("MANHUASCANUS", "Manhua Scan Us", "en", ContentType.HENTAI) internal class ManhuaScanUs(context: MangaLoaderContext) : MangaReaderParser(context, MangaSource.MANHUASCANUS, "manhuascan.us", pageSize = 30, searchPageSize = 30) { - override val isNsfwSource: Boolean = true override val datePattern = "dd-MM-yyyy" override val listUrl = "/manga-list" 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 cb7362b9..9e84fdd8 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 @@ -29,7 +29,6 @@ internal abstract class MmrcmsParser( protected open val listeurl = "filterList" protected open val tagUrl = "manga-list" - protected open val isNsfwSource = false protected open val datePattern = "dd MMM. yyyy" From 5df1da2bfde10508541ee03a7301b9df2ab95b54 Mon Sep 17 00:00:00 2001 From: devi Date: Thu, 27 Jul 2023 16:52:56 +0200 Subject: [PATCH 5/6] fix nswf --- .../parsers/site/ja/NicovideoSeigaParser.kt | 2 +- .../parsers/site/madara/MadaraParser.kt | 58 +++++++++---------- 2 files changed, 30 insertions(+), 30 deletions(-) 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 79c25bdf..1eee2f15 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 @@ -48,7 +48,7 @@ class NicovideoSeigaParser(context: MangaLoaderContext) : !query.isNullOrEmpty() -> return if (offset == 0) getSearchList(query, page) else emptyList() tags.isNullOrEmpty() -> "https://$domain/manga/list?page=$page&sort=${getSortKey(sortOrder)}" tags.size == 1 -> "https://$domain/manga/list?category=${tags.first().key}&page=$page" + - "&sort=${getSortKey(sortOrder)}" + "&sort=${getSortKey(sortOrder)}" tags.size > 1 -> throw IllegalArgumentException("This source supports only 1 category") else -> "https://$domain/manga/list?page=$page&sort=${getSortKey(sortOrder)}" 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 365ff64d..c8d767be 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 @@ -438,31 +438,31 @@ internal abstract class MadaraParser( val d = date?.lowercase() ?: return 0 return when { d.endsWith(" ago") || d.endsWith(" atrás") || // Handle translated 'ago' in Portuguese. - d.startsWith("há ") || // other translated 'ago' in Portuguese. - d.endsWith(" hace") || // other translated 'ago' in Spanish - d.endsWith(" назад") || // other translated 'ago' in Russian - d.endsWith(" önce") || // Handle translated 'ago' in Turkish. - d.endsWith(" trước") || // Handle translated 'ago' in Viêt Nam. - d.startsWith("il y a") || // Handle translated 'ago' in French. - //If there is no ago but just a motion of time - // short Hours - d.endsWith(" h") || - // short Day - d.endsWith(" d") || - // Day in Portuguese - d.endsWith(" días") || d.endsWith(" día") || - // Day in French - d.endsWith(" jour") || d.endsWith(" jours") || - // Hours in Portuguese - d.endsWith(" horas") || d.endsWith(" hora") || - // Hours in french - d.endsWith(" heure") || d.endsWith(" heures") || - // Minutes in English - d.endsWith(" mins") || - // Minutes in Portuguese - d.endsWith(" minutos") || d.endsWith(" minuto") || - //Minutes in French - d.endsWith(" minute") || d.endsWith(" minutes") -> parseRelativeDate(date) + d.startsWith("há ") || // other translated 'ago' in Portuguese. + d.endsWith(" hace") || // other translated 'ago' in Spanish + d.endsWith(" назад") || // other translated 'ago' in Russian + d.endsWith(" önce") || // Handle translated 'ago' in Turkish. + d.endsWith(" trước") || // Handle translated 'ago' in Viêt Nam. + d.startsWith("il y a") || // Handle translated 'ago' in French. + //If there is no ago but just a motion of time + // short Hours + d.endsWith(" h") || + // short Day + d.endsWith(" d") || + // Day in Portuguese + d.endsWith(" días") || d.endsWith(" día") || + // Day in French + d.endsWith(" jour") || d.endsWith(" jours") || + // Hours in Portuguese + d.endsWith(" horas") || d.endsWith(" hora") || + // Hours in french + d.endsWith(" heure") || d.endsWith(" heures") || + // Minutes in English + d.endsWith(" mins") || + // Minutes in Portuguese + d.endsWith(" minutos") || d.endsWith(" minuto") || + //Minutes in French + d.endsWith(" minute") || d.endsWith(" minutes") -> parseRelativeDate(date) // Handle 'yesterday' and 'today', using midnight d.startsWith("year") -> Calendar.getInstance().apply { @@ -559,10 +559,10 @@ internal abstract class MadaraParser( private fun createRequestTemplate() = ("action=madara_load_more&page=1&template=madara-core%2Fcontent%2Fcontent-search&vars%5Bs%5D=&vars%5B" + - "orderby%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").split( + "orderby%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").split( '&', ).map { val pos = it.indexOf('=') From 2089c3cc7bc25307993fc5e352994772857a380c Mon Sep 17 00:00:00 2001 From: devi Date: Thu, 27 Jul 2023 17:16:27 +0200 Subject: [PATCH 6/6] fix import name --- .../org/koitharu/kotatsu/parsers/site/manga18/Manga18Parser.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/manga18/en/Hentai3zCc.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/MmrcmsParser.kt | 2 +- .../koitharu/kotatsu/parsers/site/mmrcms/en/ReadComicsOnline.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/es/MangaDoor.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/fr/JpMangas.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/fr/LelScanVf.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaScan.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanVf.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/id/KomikId.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/id/Mangaid.kt | 2 +- .../org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) 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 311cb3c4..cc17baa0 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 @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.parsers.site.madara +package org.koitharu.kotatsu.parsers.site.manga18 import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope 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 94d744e3..fe77fddc 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 @@ -9,7 +9,7 @@ import org.koitharu.kotatsu.parsers.model.MangaSource 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.site.madara.Manga18Parser +import org.koitharu.kotatsu.parsers.site.manga18.Manga18Parser import org.koitharu.kotatsu.parsers.util.attrAsRelativeUrl import org.koitharu.kotatsu.parsers.util.domain import org.koitharu.kotatsu.parsers.util.generateUid diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt index 53322a30..75714c1c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/Manga18.kt @@ -5,7 +5,7 @@ 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.Manga18Parser +import org.koitharu.kotatsu.parsers.site.manga18.Manga18Parser @MangaSourceParser("MANGA18", "Manga18", "en", ContentType.HENTAI) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt index f7f04976..617e9621 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/en/PornComic18.kt @@ -5,7 +5,7 @@ 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.Manga18Parser +import org.koitharu.kotatsu.parsers.site.manga18.Manga18Parser @MangaSourceParser("PORNCOMIC18", "18 Porn Comic", "en", ContentType.HENTAI) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt index d5623e09..b9ebecfa 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/manga18/es/Tumanhwas.kt @@ -5,7 +5,7 @@ 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.Manga18Parser +import org.koitharu.kotatsu.parsers.site.manga18.Manga18Parser @MangaSourceParser("TUMANHWAS", "Tumanhwas", "es", ContentType.HENTAI) 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 9e84fdd8..37948641 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 @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.parsers.site.madara +package org.koitharu.kotatsu.parsers.site.mmrcms import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/ReadComicsOnline.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/ReadComicsOnline.kt index abcdc546..4e87357e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/ReadComicsOnline.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/en/ReadComicsOnline.kt @@ -4,7 +4,7 @@ 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.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser @MangaSourceParser("READCOMICSONLINE", "Read Comics Online", "en") 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 771354fc..1366220e 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 @@ -4,7 +4,7 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.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.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import java.util.Locale 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 53c4a5d8..9f8f64e5 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 @@ -4,7 +4,7 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.fr import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import java.util.Locale diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/LelScanVf.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/LelScanVf.kt index c3b35912..ea68767f 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/LelScanVf.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/LelScanVf.kt @@ -4,7 +4,7 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.fr import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import java.util.Locale diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt index fd91da6e..8c887cf2 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/MangaFr.kt @@ -4,7 +4,7 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.fr import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import java.util.Locale 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 ef039b47..67d008e2 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 @@ -4,7 +4,7 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.fr import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import java.util.Locale diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt index 81fff394..069412cd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanFrOrg.kt @@ -4,7 +4,7 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.fr import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import java.util.Locale diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanVf.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanVf.kt index 0d3031a9..6d8bbfed 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanVf.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/fr/ScanVf.kt @@ -4,7 +4,7 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.fr import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import java.util.Locale diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/KomikId.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/KomikId.kt index 20bac082..b2365740 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/KomikId.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/KomikId.kt @@ -4,7 +4,7 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.id import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import java.util.Locale diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/Mangaid.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/Mangaid.kt index fe361a9e..a72541ca 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/Mangaid.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/id/Mangaid.kt @@ -4,7 +4,7 @@ package org.koitharu.kotatsu.parsers.site.mmrcms.id import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import java.util.Locale diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt index 3b37c247..2ab9221a 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mmrcms/pt/Animaregia.kt @@ -10,7 +10,7 @@ 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.SortOrder -import org.koitharu.kotatsu.parsers.site.madara.MmrcmsParser +import org.koitharu.kotatsu.parsers.site.mmrcms.MmrcmsParser import org.koitharu.kotatsu.parsers.util.* import java.util.EnumSet import java.util.Locale