diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/AiyuMangaScanlation.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/AiyuMangaScanlation.kt deleted file mode 100644 index ca2361ac..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/AiyuMangaScanlation.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -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.util.mapToSet -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow - -@MangaSourceParser("AIYUMANGASCANLATION", "AiyuMangaScanlation", "es") -internal class AiyuMangaScanlation(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.AIYUMANGASCANLATION, "aiyumangascanlation.com") { - - override val tagPrefix = "manga-genre/" - override val datePattern = "MM/dd/yyyy" - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".post-content") - val tags = postContent.getElementsContainingOwnText("Genre(s)") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - description = postContent.getElementsContainingOwnText("Summary") - .firstOrNull()?.tableValue()?.text()?.trim(), - altTitle = postContent.getElementsContainingOwnText("Alternative") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Status") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } - - override fun String.asMangaState(): MangaState? = when (this) { - "OnGoing", - "Upcoming", - -> MangaState.ONGOING - - "Completed", - "Dropped", - -> MangaState.FINISHED - - else -> null - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/AstralManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/AstralManga.kt deleted file mode 100644 index ca57451a..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/AstralManga.kt +++ /dev/null @@ -1,59 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -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.util.assertNotNull -import org.koitharu.kotatsu.parsers.util.attrAsAbsoluteUrlOrNull -import org.koitharu.kotatsu.parsers.util.mapToSet -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow - -@MangaSourceParser("ASTRALMANGA", "AstralManga", "fr") -internal class AstralManga(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.ASTRALMANGA, "astral-manga.fr", pageSize = 12) { - - override val datePattern = "dd/MM/yyyy" - - override fun String.asMangaState(): MangaState? = when (this) { - "En cours", - -> MangaState.ONGOING - - "Terminé", - "Complété", - -> MangaState.FINISHED - - else -> null - } - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".post-content") - val tags = postContent.getElementsContainingOwnText("Genre(s)") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - rating = postContent.selectFirstOrThrow(".post-rating") - .selectFirstOrThrow(".total_votes").text().toFloat() / 5f, - largeCoverUrl = root.selectFirst(".summary_image") - ?.selectFirst("img[data-src]") - ?.attrAsAbsoluteUrlOrNull("data-src") - .assertNotNull("largeCoverUrl"), - description = root.selectFirstOrThrow(".manga-excerpt") - .firstElementChild()?.html(), - author = postContent.getElementsContainingOwnText("Auteur(s)") - .firstOrNull()?.tableValue()?.text()?.trim(), - altTitle = postContent.getElementsContainingOwnText("Alternatif") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Statut") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Atlantisscan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Atlantisscan.kt deleted file mode 100644 index e1e89fec..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Atlantisscan.kt +++ /dev/null @@ -1,57 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -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.util.assertNotNull -import org.koitharu.kotatsu.parsers.util.attrAsAbsoluteUrlOrNull -import org.koitharu.kotatsu.parsers.util.mapToSet -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow - - -@MangaSourceParser("ATLANTISSCAN", "Atlantisscan", "pt") -internal class Atlantisscan(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.ATLANTISSCAN, "atlantisscan.com") { - - override val datePattern = "dd/MM/yyyy" - - override fun String.asMangaState(): MangaState? = when (this) { - "OnGoing", - -> MangaState.ONGOING - - "finished", - -> MangaState.FINISHED - - else -> null - } - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".summary_content") - val tags = postContent.getElementsContainingOwnText("Genre(s) ") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - largeCoverUrl = root.selectFirst(".summary_image") - ?.selectFirst("img[data-src]") - ?.attrAsAbsoluteUrlOrNull("data-src") - .assertNotNull("largeCoverUrl"), - description = root.selectFirstOrThrow(".description-summary") - .firstElementChild()?.html(), - author = postContent.getElementsContainingOwnText("Author(s)") - .firstOrNull()?.tableValue()?.text()?.trim(), - altTitle = postContent.getElementsContainingOwnText("Alternative") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Status") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/FrScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/FrScan.kt deleted file mode 100644 index 86f46179..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/FrScan.kt +++ /dev/null @@ -1,60 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -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.util.assertNotNull -import org.koitharu.kotatsu.parsers.util.attrAsAbsoluteUrlOrNull -import org.koitharu.kotatsu.parsers.util.mapToSet -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow -import java.util.* - -@MangaSourceParser("FRSCAN", "FrScan", "fr") -internal class FrScan(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.FRSCAN, "fr-scan.com") { - - override val datePattern = "MMMM d, yyyy" - override val sourceLocale: Locale = Locale.FRENCH - - override fun String.asMangaState(): MangaState? = when (this) { - "OnGoing", - -> MangaState.ONGOING - - "Complété", - -> MangaState.FINISHED - - else -> null - } - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".post-content") - val tags = postContent.getElementsContainingOwnText("Genre(s)") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - rating = postContent.selectFirstOrThrow(".post-rating") - .selectFirstOrThrow(".total_votes").text().toFloat() / 5f, - largeCoverUrl = root.selectFirst(".summary_image") - ?.selectFirst("img[data-src]") - ?.attrAsAbsoluteUrlOrNull("data-src") - .assertNotNull("largeCoverUrl"), - description = root.selectFirstOrThrow(".description-summary") - .firstElementChild()?.html(), - author = postContent.getElementsContainingOwnText("Auteur(s)") - .firstOrNull()?.tableValue()?.text()?.trim(), - altTitle = postContent.getElementsContainingOwnText("Alternatif") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Statut") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hentai4Free.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hentai4Free.kt deleted file mode 100644 index dc2e473a..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hentai4Free.kt +++ /dev/null @@ -1,69 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -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.MangaTag -import org.koitharu.kotatsu.parsers.util.* -import java.text.SimpleDateFormat -import java.util.* - -@MangaSourceParser("HENTAI_4FREE", "Hentai4Free", "en") -internal class Hentai4Free(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.HENTAI_4FREE, "hentai4free.net", pageSize = 24) { - - override val tagPrefix = "hentai-tag/" - - override val isNsfwSource = true - - override suspend fun getTags(): Set { - val doc = webClient.httpGet("https://$domain/").parseHtml() - val body = doc.body() - val root1 = body.selectFirst("header")?.selectFirst("ul.second-menu") - val list = root1?.select("li").orEmpty() - val keySet = HashSet(list.size) - return list.mapNotNullToSet { li -> - val a = li.selectFirst("a") ?: return@mapNotNullToSet null - val href = a.attr("href").removeSuffix("/") - .substringAfterLast(tagPrefix, "") - if (href.isEmpty() || !keySet.add(href)) { - return@mapNotNullToSet null - } - MangaTag( - key = href, - title = a.ownText().trim().toTitleCase(), - source = source, - ) - } - } - - override suspend fun getChapters(manga: Manga, doc: Document): List { - val slug = manga.url.removeSuffix('/').substringAfterLast('/') - val doc2 = webClient.httpPost( - "https://$domain/hentai/$slug/ajax/chapters/", - mapOf(), - ).parseHtml() - val ul = doc2.body().selectFirstOrThrow("ul") - val dateFormat = SimpleDateFormat(datePattern, Locale.US) - return ul.select("li").mapChapters(reversed = true) { i, li -> - val a = li.selectFirst("a") - val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") - MangaChapter( - id = generateUid(href), - name = a.ownText(), - number = i + 1, - url = href, - uploadDate = parseChapterDate( - dateFormat, - li.selectFirst("span.chapter-release-date i")?.text(), - ), - source = source, - scanlator = null, - branch = null, - ) - } - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hentaiteca.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hentaiteca.kt deleted file mode 100644 index e13664d4..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hentaiteca.kt +++ /dev/null @@ -1,63 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -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.util.assertNotNull -import org.koitharu.kotatsu.parsers.util.attrAsAbsoluteUrlOrNull -import org.koitharu.kotatsu.parsers.util.mapToSet -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow - -@MangaSourceParser("HENTAITECA", "Hentaiteca", "pt") -internal class Hentaiteca(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.HENTAITECA, "hentaiteca.net", pageSize = 10) { - - override val datePattern = "MM/dd/yyyy" - - override val tagPrefix = "genero/" - - override val isNsfwSource = true - - override fun String.asMangaState(): MangaState? = when (this) { - "Em Lançamento", - -> MangaState.ONGOING - - "Completo", - -> MangaState.FINISHED - - else -> null - } - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".summary_content") - val tags = postContent.getElementsContainingOwnText("Gênero(s)") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - rating = postContent.selectFirstOrThrow(".post-rating") - .selectFirstOrThrow(".total_votes").text().toFloat() / 5f, - largeCoverUrl = root.selectFirst(".summary_image") - ?.selectFirst("img[data-src]") - ?.attrAsAbsoluteUrlOrNull("data-src") - .assertNotNull("largeCoverUrl"), - description = root.selectFirstOrThrow(".description-summary") - .firstElementChild()?.html(), - author = postContent.getElementsContainingOwnText("Autor(es)") - .firstOrNull()?.tableValue()?.text()?.trim(), - altTitle = postContent.getElementsContainingOwnText("Alternatif") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Status") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } - -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hentaizone.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hentaizone.kt deleted file mode 100644 index 12f1c086..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hentaizone.kt +++ /dev/null @@ -1,93 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -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.util.* -import java.text.SimpleDateFormat -import java.util.* - - -@MangaSourceParser("HENTAIZONE", "Hentaizone", "fr") -internal class Hentaizone(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.HENTAIZONE, "hentaizone.xyz", pageSize = 10) { - - override val datePattern = "MMM d, yyyy" - override val sourceLocale: Locale = Locale.FRENCH - - override val isNsfwSource = true - - override fun String.asMangaState(): MangaState? = when (this) { - "En Cours", - -> MangaState.ONGOING - - "Terminé", - -> MangaState.FINISHED - - else -> null - } - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".summary_content") - val tags = postContent.getElementsContainingOwnText("Genre(s)") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - rating = postContent.selectFirstOrThrow(".post-rating") - .selectFirstOrThrow(".total_votes").text().toFloat() / 5f, - description = root.selectFirst("div.description-summary")?.selectFirst("div.summary__content")?.select("p") - ?.filterNot { it.ownText().startsWith("A brief description") }?.joinToString { it.html() }, - author = postContent.getElementsContainingOwnText("Auteur(s)") - .firstOrNull()?.tableValue()?.text()?.trim(), - altTitle = postContent.getElementsContainingOwnText("Alternatif") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Statut") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - chapters = chapters, - ) - } - - - override suspend fun getChapters(manga: Manga, doc: Document): List { - val root2 = doc.body().selectFirstOrThrow("div.content-area").selectFirstOrThrow("div.c-page") - val dateFormat = SimpleDateFormat(datePattern, sourceLocale) - return root2.select("li").mapChapters(reversed = true) { i, li -> - val a = li.selectFirst("a") - val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") - - // correct parse date missing a "." - val date_org = li.selectFirst("span.chapter-release-date i")?.text() ?: "janv 1, 2000" - val date_corect_parse = date_org - .replace("janv", "janv.") - .replace("févr", "févr.") - .replace("avr", "avr.") - .replace("juil", "juil.") - .replace("sept", "sept.") - .replace("nov", "nov.") - .replace("oct", "oct.") - .replace("déc", "déc.") - - MangaChapter( - id = generateUid(href), - name = a.ownText(), - number = i + 1, - url = href, - uploadDate = parseChapterDate( - dateFormat, - date_corect_parse, - ), - source = source, - scanlator = null, - branch = null, - ) - } - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/HhentaiFr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/HhentaiFr.kt deleted file mode 100644 index 367c8468..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/HhentaiFr.kt +++ /dev/null @@ -1,66 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -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.util.domain -import org.koitharu.kotatsu.parsers.util.insertCookies -import org.koitharu.kotatsu.parsers.util.mapToSet -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow -import java.util.* - - -@MangaSourceParser("HHENTAIFR", "HhentaiFr", "fr") -internal class HhentaiFr(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.HHENTAIFR, "hhentai.fr") { - - override val datePattern = "MMMM d, yyyy" - override val sourceLocale: Locale = Locale.FRENCH - - override val isNsfwSource = true - - init { - context.cookieJar.insertCookies( - domain, - "age_gate=32;", - ) - } - - override fun String.asMangaState(): MangaState? = when (this) { - "En Cours", - -> MangaState.ONGOING - - "Terminé", - -> MangaState.FINISHED - - else -> null - } - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".summary_content") - val tags = postContent.getElementsContainingOwnText("Genre(s)") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - rating = postContent.selectFirstOrThrow(".post-rating") - .selectFirstOrThrow(".total_votes").text().toFloat() / 5f, - description = root.selectFirstOrThrow(".description-summary") - .firstElementChild()?.html(), - author = postContent.getElementsContainingOwnText("Auteur(s)") - .firstOrNull()?.tableValue()?.text()?.trim(), - altTitle = postContent.getElementsContainingOwnText("Alternatif") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Statut") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hipercool.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hipercool.kt deleted file mode 100644 index d9b942ee..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Hipercool.kt +++ /dev/null @@ -1,54 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -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.util.attrAsAbsoluteUrlOrNull -import org.koitharu.kotatsu.parsers.util.mapToSet -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow -import java.util.* - - -@MangaSourceParser("HIPERCOOL", "Hipercool", "pt") -internal class Hipercool(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.HIPERCOOL, "hipercool.xyz", pageSize = 20) { - - override val datePattern = "MMMM d, yyyy" - - override val tagPrefix = "manga-tag/" - - override val isNsfwSource = true - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".main-col") - val tags = postContent.getElementsByClass("tags-content") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - - return manga.copy( - - - largeCoverUrl = root.selectFirst("picture") - ?.selectFirst("img[data-src]") - ?.attrAsAbsoluteUrlOrNull("data-src"), - description = root.selectFirst("div.description-summary")?.selectFirst("div.summary__content")?.select("p") - ?.filterNot { it.ownText().startsWith("A brief description") }?.joinToString { it.html() }, - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } - - override fun String.asMangaState() = when (trim().lowercase(Locale.ROOT)) { - "em lançamento" -> MangaState.ONGOING - - else -> null - } - -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/IsekaiScanEuParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/IsekaiScanEuParser.kt deleted file mode 100644 index 9e2a099c..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/IsekaiScanEuParser.kt +++ /dev/null @@ -1,81 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Document -import org.jsoup.nodes.Element -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.MangaTag -import org.koitharu.kotatsu.parsers.util.* -import java.text.SimpleDateFormat -import java.util.* - -@MangaSourceParser("ISEKAISCAN_EU", "IsekaiScan", "en") -internal class IsekaiScanEuParser(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.ISEKAISCAN_EU, "isekaiscan.to") { - - override val datePattern = "MM/dd/yyyy" - - override suspend fun getChapters(manga: Manga, doc: Document): List { - doc.selectFirst("ul.version-chap")?.let { - return parseChapters(it) - } - val mangaId = doc.body().requireElementById("manga-chapters-holder").attr("data-id") - val ul = webClient.httpPost( - "https://${domain}/wp-admin/admin-ajax.php", - mapOf( - "action" to "manga_get_chapters", - "manga" to mangaId, - ), - ).parseHtml().body().selectFirstOrThrow("ul") - return parseChapters(ul) - } - - override suspend fun getTags(): Set { - val doc = webClient.httpGet("https://$domain/mangax/").parseHtml() - val body = doc.body() - val root1 = body.selectFirst("header")?.selectFirst("ul.second-menu") - val root2 = body.selectFirst("div.genres_wrap")?.selectFirst("ul.list-unstyled") - if (root1 == null && root2 == null) { - doc.parseFailed("Root not found") - } - val list = root1?.select("li").orEmpty() + root2?.select("li").orEmpty() - val keySet = HashSet(list.size) - return list.mapNotNullToSet { li -> - val a = li.selectFirst("a") ?: return@mapNotNullToSet null - val href = a.attr("href").removeSuffix("/") - .substringAfterLast(tagPrefix, "") - if (href.isEmpty() || !keySet.add(href)) { - return@mapNotNullToSet null - } - MangaTag( - key = href, - title = a.ownText().toTitleCase(Locale.ENGLISH), - source = source, - ) - } - } - - private fun parseChapters(ul: Element): List { - val dateFormat = SimpleDateFormat(datePattern, Locale.US) - return ul.select("li").mapChapters(reversed = true) { i, li -> - val a = li.selectFirst("a") - val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") - MangaChapter( - id = generateUid(href), - name = a.ownText(), - number = i + 1, - url = href, - uploadDate = parseChapterDate( - dateFormat, - li.selectFirst("span.chapter-release-date i")?.text(), - ), - source = source, - scanlator = null, - branch = null, - ) - } - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Madara5Parser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Madara5Parser.kt deleted file mode 100644 index 9469331b..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Madara5Parser.kt +++ /dev/null @@ -1,183 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import androidx.collection.arraySetOf -import org.jsoup.nodes.Element -import org.koitharu.kotatsu.parsers.InternalParsersApi -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.PagedMangaParser -import org.koitharu.kotatsu.parsers.config.ConfigKey -import org.koitharu.kotatsu.parsers.model.* -import org.koitharu.kotatsu.parsers.util.* -import java.text.SimpleDateFormat -import java.util.* - -abstract class Madara5Parser @InternalParsersApi constructor( - context: MangaLoaderContext, - source: MangaSource, - domain: String, -) : PagedMangaParser(context, source, pageSize = 22) { - - protected open val datePattern = "MMMM dd, HH:mm" - protected open val tagPrefix = "/mangas/" - protected open val nsfwTags = arraySetOf("yaoi", "yuri", "mature") - - override val sortOrders: Set = EnumSet.of(SortOrder.UPDATED) - - override val configKeyDomain = ConfigKey.Domain(domain) - - override suspend fun getListPage( - page: Int, - query: String?, - tags: Set?, - sortOrder: SortOrder, - ): List { - val domain = domain - val url = buildString { - append("https://") - append(domain) - append("/search?s=") - if (!query.isNullOrEmpty()) { - append(query.urlEncoded()) - } - append("&post_type=wp-manga") - if (!tags.isNullOrEmpty()) { - for (tag in tags) { - append("&genre%5B%5D=") - append(tag.key) - } - } - append("&op=1&author=&artist=&page=") - append(page) - } - val root = webClient.httpGet(url).parseHtml().body().selectFirstOrThrow(".search-wrap") - return root.select(".c-tabs-item__content").map { div -> - val a = div.selectFirstOrThrow("a") - val img = div.selectLastOrThrow("img") - val href = a.attrAsRelativeUrl("href") - val postContent = root.selectFirstOrThrow(".post-content") - val tagSet = postContent.getElementsContainingOwnText("Genre") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { it.asMangaTag() }.orEmpty() - Manga( - id = generateUid(href), - title = a.attr("title"), - altTitle = postContent.getElementsContainingOwnText("Alternative") - .firstOrNull()?.tableValue()?.text()?.trim(), - url = href, - publicUrl = a.attrAsAbsoluteUrl("href"), - coverUrl = img.src().orEmpty(), - author = postContent.getElementsContainingOwnText("Author") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Status") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - isNsfw = isNsfw(tagSet), - rating = div.selectFirstOrThrow(".score").text() - .toFloatOrNull()?.div(5f) ?: RATING_UNKNOWN, - tags = tagSet, - source = source, - ) - } - } - - override suspend fun getDetails(manga: Manga): Manga { - val root = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml().body() - .selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".post-content") - val tags = postContent.getElementsContainingOwnText("Genre") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - val mangaId = root.getElementById("manga-chapters-holder")?.attr("data-id")?.toLongOrNull() - ?: root.parseFailed("Cannot find mangaId") - return manga.copy( - description = (root.selectFirst(".detail-content") - ?: root.selectFirstOrThrow(".description-summary")).html(), - author = postContent.getElementsContainingOwnText("Author") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Status") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = isNsfw(tags), - chapters = loadChapters(mangaId), - ) - } - - override suspend fun getPages(chapter: MangaChapter): List { - val fullUrl = chapter.url.toAbsoluteUrl(domain) - val doc = webClient.httpGet(fullUrl).parseHtml() - val arrayData = doc.getElementById("arraydata") ?: doc.parseFailed("#arraydata not found") - return arrayData.html().split(',').map { url -> - MangaPage( - id = generateUid(url), - url = url, - preview = null, - source = source, - ) - } - } - - override suspend fun getTags(): Set { - val doc = webClient.httpGet("http://${domain}/").parseHtml().body() - return doc.getElementsByAttributeValueContaining("href", tagPrefix) - .mapToSet { it.asMangaTag() } - } - - private suspend fun loadChapters(mangaId: Long): List { - val dateFormat = SimpleDateFormat(datePattern, sourceLocale) - val doc = webClient.httpGet("https://${domain}/ajax-list-chapter?mangaID=$mangaId").parseHtml() - return doc.select("li.wp-manga-chapter").mapChapters(reversed = true) { i, li -> - val a = li.selectFirstOrThrow("a") - val href = a.attrAsRelativeUrl("href") - MangaChapter( - id = generateUid(href), - url = href, - name = a.text(), - number = i + 1, - branch = null, - uploadDate = dateFormat.tryParse( - li.selectFirst(".chapter-release-date")?.text()?.trim(), - ), - scanlator = null, - source = source, - ) - } - } - - protected fun isNsfw(tags: Set): Boolean { - return tags.any { it.key in nsfwTags } - } - - private fun Element.src(): String? { - return absUrl("data-src").ifEmpty { - absUrl("src") - }.takeUnless { it.isEmpty() } - } - - private fun Element.tableValue(): Element { - for (p in parents()) { - val children = p.children() - if (children.size == 2) { - return children[1] - } - } - parseFailed("Cannot find tableValue for node ${text()}") - } - - private fun String.asMangaState() = when (trim().lowercase(sourceLocale)) { - "ongoing" -> MangaState.ONGOING - "completed" -> MangaState.FINISHED - else -> null - } - - private fun Element.asMangaTag() = MangaTag( - title = ownText(), - key = attr("href").removeSuffix('/').substringAfterLast('/') - .replace('-', '+'), - source = source, - ) - - @MangaSourceParser("MANGAOWLS", "BeautyManga", "en") - class BeautyManga(context: MangaLoaderContext) : Madara5Parser(context, MangaSource.MANGAOWLS, "beautymanga.com") -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Madara6Parser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Madara6Parser.kt deleted file mode 100644 index f4629e34..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/Madara6Parser.kt +++ /dev/null @@ -1,71 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import kotlinx.coroutines.async -import kotlinx.coroutines.coroutineScope -import org.jsoup.nodes.Element -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.model.* -import org.koitharu.kotatsu.parsers.util.* -import java.text.SimpleDateFormat - -internal abstract class Madara6Parser( - context: MangaLoaderContext, - source: MangaSource, - domain: String, - pageSize: Int = 12, -) : MadaraParser(context, source, domain, pageSize) { - - override val datePattern: String = "dd MMMM yyyy" - - override suspend fun getDetails(manga: Manga): Manga { - return coroutineScope { - val chapters = async { loadChapters(manga.url) } - val body = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml().body() - parseDetails(manga, body, chapters.await()) - } - } - - protected fun Element.tableValue(): Element { - for (p in parents()) { - val children = p.children() - if (children.size == 2) { - return children[1] - } - } - parseFailed("Cannot find tableValue for node ${text()}") - } - - protected abstract fun String.asMangaState(): MangaState? - - protected fun Element.asMangaTag() = MangaTag( - title = ownText(), - key = attr("href").removeSuffix('/').substringAfterLast('/') - .replace('-', '+'), - source = source, - ) - - protected open suspend fun loadChapters(mangaUrl: String): List { - val url = mangaUrl.toAbsoluteUrl(domain).removeSuffix('/') + "/ajax/chapters/" - val dateFormat = SimpleDateFormat(datePattern, sourceLocale) - val doc = webClient.httpPost(url, emptyMap()).parseHtml() - return doc.select("li.wp-manga-chapter").mapChapters(reversed = true) { i, li -> - val a = li.selectFirstOrThrow("a") - val href = a.attrAsRelativeUrl("href") + "?style=list" - MangaChapter( - id = generateUid(href), - url = href, - name = a.text(), - number = i + 1, - branch = null, - uploadDate = parseChapterDate( - dateFormat, - li.selectFirst("span.chapter-release-date i")?.text(), - ), - scanlator = null, - source = source, - ) - } - } - - protected abstract fun parseDetails(manga: Manga, body: Element, chapters: List): Manga -} 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 bf32b9c8..786a8167 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 @@ -5,7 +5,6 @@ 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.MangaSourceParser import org.koitharu.kotatsu.parsers.PagedMangaParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.exception.ParseException @@ -15,6 +14,7 @@ import java.text.DateFormat import java.text.SimpleDateFormat import java.util.* + internal abstract class MadaraParser( context: MangaLoaderContext, source: MangaSource, @@ -38,6 +38,28 @@ internal abstract class MadaraParser( searchPaginator.firstPage = 0 } + protected fun Element.tableValue(): Element { + for (p in parents()) { + val children = p.children() + if (children.size == 2) { + return children[1] + } + } + parseFailed("Cannot find tableValue for node ${text()}") + } + + + protected val ongoing: Array = arrayOf( + "مستمرة", "En curso", "En Curso","Ongoing", "OnGoing","On going", + "Ativo", "En Cours", "En cours", "Đang tiến hành", "Em lançamento", "em lançamento", "Em Lançamento", "Онгоінг", "Publishing", + "Devam Ediyor", "Em Andamento", "In Corso", "Güncel", "Berjalan", "Продолжается", "Updating", + "Lançando", "In Arrivo", "Emision", "En emision", "مستمر", "Curso", "En marcha", "Publicandose", "连载中",) + + protected val finished: Array = arrayOf( + "Completed", "Completo", "Complété", "Fini", "Terminé", "Tamamlandı", "Đã hoàn thành", "مكتملة", "Завершено", + "Finished", "Finalizado", "Completata", "One-Shot", "Bitti", "Tamat", "Completado", "Concluído", "Concluido", "已完结",) + + override suspend fun getListPage( page: Int, query: String?, @@ -80,9 +102,16 @@ internal abstract class MadaraParser( }.orEmpty(), author = summary?.selectFirst(".mg_author")?.selectFirst("a")?.ownText(), state = when (summary?.selectFirst(".mg_status")?.selectFirst(".summary-content")?.ownText()?.trim() - ?.lowercase()) { - "ongoing" -> MangaState.ONGOING - "completed" -> MangaState.FINISHED + ?.lowercase()) + { + "مستمرة", "En curso", "En Curso","Ongoing", "OnGoing","On going", + "Ativo", "En Cours", "En cours", "Đang tiến hành", "Em lançamento", "em lançamento", "Em Lançamento", "Онгоінг", "Publishing", + "Devam Ediyor", "Em Andamento", "In Corso", "Güncel", "Berjalan", "Продолжается", "Updating", + "Lançando", "In Arrivo", "Emision", "En emision", "مستمر", "Curso", "En marcha", "Publicandose", "连载中", + -> MangaState.ONGOING + "Completed", "Completo", "Complété", "Fini", "Terminé", "Tamamlandı", "Đã hoàn thành", "مكتملة", "Завершено", + "Finished", "Finalizado", "Completata", "One-Shot", "Bitti", "Tamat", "Completado", "Concluído", "Concluido", "已完结", + -> MangaState.FINISHED else -> null }, source = source, @@ -120,36 +149,68 @@ internal abstract class MadaraParser( override suspend fun getDetails(manga: Manga): Manga = coroutineScope { val fullUrl = manga.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() - val chaptersDeferred = async { getChapters(manga, doc) } - val root = doc.body().selectFirst("div.profile-manga")?.selectFirst("div.summary_content") - ?.selectFirst("div.post-content") ?: throw ParseException("Root not found", fullUrl) - val root2 = doc.body().selectFirst("div.content-area")?.selectFirst("div.c-page") - ?: throw ParseException("Root2 not found", fullUrl) - manga.copy( - tags = root.selectFirst("div.genres-content")?.select("a")?.mapNotNullToSet { a -> + + val testchekasync = doc.body().select("div.listing-chapters_wrap") + + val chaptersDeferred = if(testchekasync.isNullOrEmpty()) + { + async { loadChapters(manga.url) } + + }else + { + async { getChapters(manga, doc) } + } + + val desc = doc.body().selectFirst("div.description-summary div.summary__content") ?: + doc.body().selectFirst("div.summary_content div.post-content_item > h5 + div") ?: + doc.body().selectFirst("div.summary_content div.manga-excerpt") + + + val stateselect = + doc.body().select("div.post-content_item:contains(Status) > div.summary-content").last() ?: doc.body().select("div.post-content_item:contains(Statut) > div.summary-content").last() + ?: doc.body().select("div.post-content_item:contains(حالة العمل) > div.summary-content").last() ?: doc.body().select("div.post-content_item:contains(Estado) > div.summary-content").last() + ?: doc.body().select("div.post-content_item:contains(สถานะ) > div.summary-content").last() ?: doc.body().select("div.post-content_item:contains(Stato) > div.summary-content").last() + ?: doc.body().select("div.post-content_item:contains(Durum) > div.summary-content").last() ?: doc.body().select("div.post-content_item:contains(Statüsü) > div.summary-content").last() + ?: doc.body().select("div.summary-content").last() + + val state = + stateselect?.let { + when (it.text()) { + in ongoing -> MangaState.ONGOING + in finished -> MangaState.FINISHED + else -> null + } + } + + manga.copy( + tags = doc.body().select("div.genres-content a").mapNotNullToSet { a -> MangaTag( key = a.attr("href").removeSuffix("/").substringAfterLast('/'), title = a.text().toTitleCase(), source = source, ) - } ?: manga.tags, - description = root2.selectFirst("div.description-summary")?.selectFirst("div.summary__content")?.select("p") - ?.filterNot { it.ownText().startsWith("A brief description") }?.joinToString { it.html() }, + }, + description = desc?.select("p")?.filterNot { it.ownText().startsWith("A brief description") }?.joinToString { it.text() }, + altTitle = + doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()?.trim() ?: + doc.body().select(".post-content_item:contains(Nomes alternativos: ) .summary-content").firstOrNull()?.tableValue()?.text()?.trim(), + state = state, chapters = chaptersDeferred.await(), ) } protected open suspend fun getChapters(manga: Manga, doc: Document): List { - val root2 = doc.body().selectFirstOrThrow("div.content-area").selectFirstOrThrow("div.c-page") + val root2 = doc.body().selectFirstOrThrow("div.content-area") val dateFormat = SimpleDateFormat(datePattern, sourceLocale) - return root2.select("li").mapChapters(reversed = true) { i, li -> + return root2.select("li.wp-manga-chapter").mapChapters(reversed = true) { i, li -> val a = li.selectFirst("a") val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") + val link = href + "?style=list" MangaChapter( id = generateUid(href), name = a.ownText(), number = i + 1, - url = href, + url = link, uploadDate = parseChapterDate( dateFormat, li.selectFirst("span.chapter-release-date i")?.text(), @@ -161,6 +222,30 @@ internal abstract class MadaraParser( } } + protected open suspend fun loadChapters(mangaUrl: String): List { + val url = mangaUrl.toAbsoluteUrl(domain).removeSuffix('/') + "/ajax/chapters/" + val dateFormat = SimpleDateFormat(datePattern, sourceLocale) + val doc = webClient.httpPost(url, emptyMap()).parseHtml() + return doc.select("li.wp-manga-chapter").mapChapters(reversed = true) { i, li -> + val a = li.selectFirst("a") + val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") + val link = href + "?style=list" + MangaChapter( + id = generateUid(href), + url = link, + name = a.text(), + number = i + 1, + branch = null, + uploadDate = parseChapterDate( + dateFormat, + li.selectFirst("span.chapter-release-date i")?.text(), + ), + scanlator = null, + source = source, + ) + } + } + override suspend fun getPages(chapter: MangaChapter): List { val fullUrl = chapter.url.toAbsoluteUrl(domain) val doc = webClient.httpGet(fullUrl).parseHtml() @@ -289,199 +374,4 @@ internal abstract class MadaraParser( it.substring(0, pos) to it.substring(pos + 1) }.toMutableMap() - @MangaSourceParser("MANGAWEEBS", "MangaWeebs", "en") - class MangaWeebs(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.MANGAWEEBS, "mangaweebs.in", - pageSize = 20, - ) { - override val datePattern = "dd MMMM HH:mm" - } - - @MangaSourceParser("HACHIMANGA", "HachiManga", "ja") - class HachiManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.HACHIMANGA, "hachiraw.com") { - - override val sourceLocale: Locale = Locale.ENGLISH - } - - @MangaSourceParser("PIANMANGA", "PianManga", "en") - class PianManga(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.PIANMANGA, "pianmanga.me", - pageSize = 10, - ) - - @MangaSourceParser("MANGAROSIE", "MangaRosie", "en") - class MangaRosie(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.MANGAROSIE, "mangarosie.in", - pageSize = 16, - ) - - @MangaSourceParser("MANGATX", "MangaTx", "en") - class MangaTx(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGATX, "mangatx.com") - - @MangaSourceParser("MANGAEFFECT", "MangaEffect", "en") - class MangaEffect(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGAEFFECT, "mangaeffect.com") { - override val datePattern = "dd.MM.yyyy" - } - - @MangaSourceParser("AQUAMANGA", "AquaManga", "en") - class AquaManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.AQUAMANGA, "aquamanga.com") - - @MangaSourceParser("MANGALEK", "MangaLek", "ar") - class MangaLek(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.MANGALEK, "mangalek.com", - pageSize = 10, - ) - - @MangaSourceParser("HARIMANGA", "HariManga", "en") - class HariManga(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.HARIMANGA, "harimanga.com", - pageSize = 10, - ) { - override val datePattern = "MM/dd/yyyy" - } - - @MangaSourceParser("KISSMANGA", "KissManga", "en") - class KissManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.KISSMANGA, "kissmanga.in") - - @MangaSourceParser("MANGAROCK", "MangaRock", "en") - class MangaRock(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGAROCK, "mangarockteam.com") - - @MangaSourceParser("FREEMANGA", "FreeManga", "en") - class FreeManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.FREEMANGA, "freemanga.me") - - @MangaSourceParser("MANGA_KOMI", "MangaKomi", "en") - class MangaKomi(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.MANGA_KOMI, "mangakomi.io", - pageSize = 18, - ) - - @MangaSourceParser("MANHWACLAN", "ManhwaClan", "en") - class ManhwaClan(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.MANHWACLAN, "manhwaclan.com", - pageSize = 10, - ) - - @MangaSourceParser("MANGA_3S", "Manga3s", "en") - class Manga3s(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGA_3S, "manga3s.com") { - override val tagPrefix = "manhwa-genre/" - } - - @MangaSourceParser("MANHWAKOOL", "Manhwa Kool", "en") - class ManhwaKool(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.MANHWAKOOL, "manhwakool.com", - pageSize = 10, - ) { - override val datePattern: String = "MM/dd" - } - - @MangaSourceParser("TOPMANHUA", "Top Manhua", "en") - class TopManhua(context: MangaLoaderContext) : MadaraParser(context, MangaSource.TOPMANHUA, "www.topmanhua.com") { - override val tagPrefix = "manhua-genre/" - override val datePattern = "MM/dd/yyyy" - } - - @MangaSourceParser("S2MANGA", "S2Manga", "en") - class S2Manga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.S2MANGA, "s2manga.com") - - @MangaSourceParser("SKY_MANGA", "Sky Manga", "en") - class SkyManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.SKY_MANGA, "skymanga.xyz") { - - override val isNsfwSource = true - - } - - @MangaSourceParser("BAKAMAN", "BakaMan", "th") - class BakaMan(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.BAKAMAN, "bakaman.net", - pageSize = 18, - ) { - - override val isNsfwSource = false - } - - @MangaSourceParser("HENTAI20", "Hentai20", "en") - class Hentai20(context: MangaLoaderContext) : MadaraParser(context, MangaSource.HENTAI20, "hentai20.io") { - - override val tagPrefix = "manga-genre/" - - override val isNsfwSource = true - } - - @MangaSourceParser("ALLPORN_COMIC", "All Porn Comic", "en") - class AllPornComic(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.ALLPORN_COMIC, "allporncomic.com", pageSize = 24) { - - override val tagPrefix = "porncomic-genre/" - - override val isNsfwSource = true - - } - - @MangaSourceParser("CAT_300", "Cat300", "th") - class Cat300(context: MangaLoaderContext) : MadaraParser(context, MangaSource.CAT_300, "cat300.com") { - - override val isNsfwSource = true - } - - @MangaSourceParser("BIBIMANGA", "BibiManga", "en") - class BibiManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.BIBIMANGA, "bibimanga.com") { - - override val isNsfwSource = false - } - - @MangaSourceParser("TREE_MANGA", "Tree Manga", "en") - class TreeManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.TREE_MANGA, "treemanga.com") { - - override val datePattern = "MM/dd/yyyy" - - } - - @MangaSourceParser("MANGACV", "Manga Cv", "en") - class MangaCv(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.MANGACV, "mangacv.com", - pageSize = 10, - ) - - @MangaSourceParser("TOONILY", "Toonily", "en") - class Toonily(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.TOONILY, "toonily.com", - pageSize = 18, - ) { - - override val tagPrefix = "webtoon-genre/" - - override val isNsfwSource = false - } - - @MangaSourceParser("MANGA_MANHUA", "Manga Manhua", "en") - class MangaManhua(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGA_MANHUA, "mangamanhua.online", pageSize = 10) - { - override val datePattern = "d MMMM، yyyy" - } - - @MangaSourceParser("MANGA_247", "247MANGA", "en") - class Manga247(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGA_247, "247manga.com") { - override val tagPrefix = "manhwa-genre/" - } - - @MangaSourceParser("MANGA_365", "365Manga", "en") - class Manga365(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGA_365, "365manga.com") - - @MangaSourceParser("MANGACLASH", "Mangaclash", "en") - class Mangaclash(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.MANGACLASH, "mangaclash.com", - pageSize = 18, - ) { - override val datePattern = "MM/dd/yyyy" - } - - @MangaSourceParser("ZINMANGA", "ZINMANGA", "en") - class Zinmanga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.ZINMANGA, "zinmanga.com") - { - override val datePattern = "MM/dd/yyyy" - } - - @MangaSourceParser("STKISSMANGA", "Stkissmanga", "en") - class Stkissmanga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.STKISSMANGA, "1stkissmanga.me") } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangaScantrad.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangaScantrad.kt deleted file mode 100644 index 743f79d8..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangaScantrad.kt +++ /dev/null @@ -1,60 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -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.util.assertNotNull -import org.koitharu.kotatsu.parsers.util.attrAsAbsoluteUrlOrNull -import org.koitharu.kotatsu.parsers.util.mapToSet -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow -import java.util.* - -@MangaSourceParser("MANGA_SCANTRAD", "Manga Scantrad", "fr") -internal class MangaScantrad(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.MANGA_SCANTRAD, "manga-scantrad.io") { - - override val datePattern = "d MMMM yyyy" - override val sourceLocale: Locale = Locale.FRENCH - - override fun String.asMangaState(): MangaState? = when (this) { - "OnGoing", - -> MangaState.ONGOING - - "Complété", - -> MangaState.FINISHED - - else -> null - } - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".summary_content") - val tags = postContent.getElementsContainingOwnText("Genre(s)") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - rating = postContent.selectFirstOrThrow(".post-rating") - .selectFirstOrThrow(".total_votes").text().toFloat() / 5f, - largeCoverUrl = root.selectFirst(".summary_image") - ?.selectFirst("img[data-src]") - ?.attrAsAbsoluteUrlOrNull("data-src") - .assertNotNull("largeCoverUrl"), - description = root.selectFirstOrThrow(".description-summary") - .firstElementChild()?.html(), - author = postContent.getElementsContainingOwnText("Auteur(s)") - .firstOrNull()?.tableValue()?.text()?.trim(), - altTitle = postContent.getElementsContainingOwnText("Alternatif") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("État") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangalinkParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangalinkParser.kt deleted file mode 100644 index d113210f..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangalinkParser.kt +++ /dev/null @@ -1,46 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -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.exception.ParseException -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.util.* - -@MangaSourceParser("MANGALINK_AR", "Mangalink", "ar") -internal class MangalinkParser(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.MANGALINK_AR, "mangalink.online", pageSize = 10) { - - override suspend fun getDetails(manga: Manga): Manga = coroutineScope { - val fullUrl = manga.url.toAbsoluteUrl(domain) - val doc = webClient.httpGet(fullUrl).parseHtml() - val chaptersDeferred = async { getChapters(manga, doc) } - val root = doc.body().selectFirst("div.profile-manga") - ?.selectFirst("div.summary_content") - ?.selectFirst("div.post-content") - ?: throw ParseException("Root not found", fullUrl) - val root2 = doc.body().selectFirst("div.content-area") - ?.selectFirst("div.c-page") - ?: throw ParseException("Root2 not found", fullUrl) - manga.copy( - tags = root.selectFirst("div.genres-content")?.select("a") - ?.mapNotNullToSet { a -> - MangaTag( - key = a.attr("href").removeSuffix("/").substringAfterLast('/'), - title = a.text().toTitleCase(), - source = source, - ) - } ?: manga.tags, - description = root2.selectFirst("div.description-summary") - ?.selectFirst("div.summary__content") - ?.select("p") - ?.filterNot { it.ownText().startsWith("A brief description") } - ?.joinToString { it.html() }, - chapters = chaptersDeferred.await(), - ) - } - -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/NeatManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/NeatManga.kt deleted file mode 100644 index 26529546..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/NeatManga.kt +++ /dev/null @@ -1,98 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -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.exception.ParseException -import org.koitharu.kotatsu.parsers.model.* -import org.koitharu.kotatsu.parsers.util.* -import java.text.SimpleDateFormat -import java.util.* - -@MangaSourceParser("NEATMANGA", "NeatManga", "en") -internal class NeatManga(context: MangaLoaderContext) : MadaraParser( - context, MangaSource.NEATMANGA, "neatmangas.com", - pageSize = 20, -) { - - override val datePattern = "dd MMMM yyyy" - - override suspend fun getDetails(manga: Manga): Manga = coroutineScope { - val chaptersDeferred = async { getChapters(manga) } - val fullUrl = manga.url.toAbsoluteUrl(domain) - val doc = webClient.httpGet(fullUrl).parseHtml() - val root = doc.body().selectFirst("div.profile-manga") - ?.selectFirst("div.summary_content") - ?.selectFirst("div.post-content") - ?: throw ParseException("Root not found", fullUrl) - val root2 = doc.body().selectFirst("div.content-area") - ?.selectFirst("div.c-page") - ?: throw ParseException("Root2 not found", fullUrl) - manga.copy( - tags = root.selectFirst("div.genres-content")?.select("a") - ?.mapNotNullToSet { a -> - MangaTag( - key = a.attr("href").removeSuffix("/").substringAfterLast('/'), - title = a.text().toTitleCase(), - source = source, - ) - } ?: manga.tags, - description = root2.getElementsMatchingOwnText("Summary") - .firstOrNull() - ?.nextElementSibling() - ?.select("p") - ?.filterNot { it.ownText().startsWith("A brief description") } - ?.joinToString { it.html() }, - chapters = chaptersDeferred.await(), - ) - } - - private suspend fun getChapters(manga: Manga): List { - val slug = manga.url.removeSuffix('/').substringAfterLast('/') - val doc2 = webClient.httpPost( - "https://$domain/manga/$slug/ajax/chapters/", - mapOf(), - ).parseHtml() - val ul = doc2.body().selectFirstOrThrow("ul") - val dateFormat = SimpleDateFormat(datePattern, Locale.US) - return ul.select("li").mapChapters(reversed = true) { i, li -> - val a = li.selectFirst("a") - val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing") - MangaChapter( - id = generateUid(href), - name = a.ownText(), - number = i + 1, - url = href, - uploadDate = parseChapterDate( - dateFormat, - li.selectFirst("span.chapter-release-date i")?.text(), - ), - 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 root = doc.body().selectFirst("div.main-col-inner") - ?.selectFirst("div.reading-content") - ?: throw ParseException("Root not found", fullUrl) - return root.select("div.page-break").mapNotNull { div -> - val img = div.selectFirst("img") - if (img == null || img.attr("id").isNullOrEmpty()) { - return@mapNotNull null - } - val url = img.src()?.toRelativeUrl(domain) ?: div.parseFailed("Image src not found") - MangaPage( - id = generateUid(url), - url = url, - preview = null, - source = source, - ) - } - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/PrismaScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/PrismaScansParser.kt deleted file mode 100644 index 381eab58..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/PrismaScansParser.kt +++ /dev/null @@ -1,53 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -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.util.attrAsAbsoluteUrlOrNull -import org.koitharu.kotatsu.parsers.util.mapToSet -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow - -@MangaSourceParser("PRISMA_SCANS", "Prisma Scans", "pt") -internal class PrismaScansParser(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.PRISMA_SCANS, "prismascans.net", 10) { - - override val tagPrefix = "manga-genre/" - override val datePattern = "MMM dd, yyyy" - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".post-content") - val tags = postContent.getElementsContainingOwnText("Gênero") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - largeCoverUrl = root.selectFirst("picture") - ?.selectFirst("img[data-src]") - ?.attrAsAbsoluteUrlOrNull("data-src"), - description = root.selectFirstOrThrow(".manga-excerpt").firstElementChild()?.html(), - author = postContent.getElementsContainingOwnText("Artista") - .firstOrNull()?.tableValue()?.text()?.trim(), - altTitle = postContent.getElementsContainingOwnText("Título Alternativo") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Status") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } - - override fun String.asMangaState() = when (trim().lowercase(sourceLocale)) { - "em lançamento" -> MangaState.ONGOING - "completo", - "cancelado", - -> MangaState.FINISHED - - else -> null - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ReaperScansFr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ReaperScansFr.kt deleted file mode 100644 index 1f39412d..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ReaperScansFr.kt +++ /dev/null @@ -1,37 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -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.MangaTag -import org.koitharu.kotatsu.parsers.util.* - -@MangaSourceParser("REAPERSCANS_FR", "ReaperScansFr", "fr") -internal class ReaperScansFr(context: MangaLoaderContext) : - MadaraParser(context, MangaSource.REAPERSCANS_FR, "reaperscans.fr") { - - override val datePattern = "MM/dd/yyyy" - - override suspend fun getDetails(manga: Manga): Manga = coroutineScope { - val fullUrl = manga.url.toAbsoluteUrl(domain) - val doc = webClient.httpGet(fullUrl).parseHtml() - val chaptersDeferred = async { getChapters(manga, doc) } - val root = doc.body().selectFirstOrThrow(".site-content") - manga.copy( - tags = root.selectFirst("div.genres-content")?.select("a")?.mapNotNullToSet { a -> - MangaTag( - key = a.attr("href").removeSuffix("/").substringAfterLast('/'), - title = a.text().toTitleCase(), - source = source, - ) - } ?: manga.tags, - description = root.requireElementById("nav-profile") - .selectFirstOrThrow(".description-summary") - .firstElementChild()?.html(), - chapters = chaptersDeferred.await(), - ) - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ReaperScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ReaperScansParser.kt deleted file mode 100644 index 383e134a..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ReaperScansParser.kt +++ /dev/null @@ -1,86 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.* -import org.koitharu.kotatsu.parsers.util.* -import java.util.* - -@MangaSourceParser("REAPER_SCANS_ID", "ReaperScansID", "id") -internal class ReaperScansParser(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.REAPER_SCANS_ID, "reaperscans.id") { - - override val datePattern = "MMMM dd, yyyy" - override val tagPrefix = "genre/" - override val sourceLocale: Locale = Locale.ENGLISH - - override fun String.asMangaState(): MangaState? = when (this) { - "OnGoing", - "Upcoming", - -> MangaState.ONGOING - - "Completed", - "Dropped", - -> MangaState.FINISHED - - else -> null - } - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.requireElementById("nav-info") - val tags = postContent.getElementsContainingOwnText("Gênero") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - rating = postContent.selectFirstOrThrow(".post-rating") - .selectFirstOrThrow(".total_votes").text().toFloat() / 5f, - largeCoverUrl = root.selectFirst(".summary_image") - ?.selectFirst("img[data-src]") - ?.attrAsAbsoluteUrlOrNull("data-src") - .assertNotNull("largeCoverUrl"), - description = root.requireElementById("nav-profile") - .selectFirstOrThrow(".description-summary") - .firstElementChild()?.html(), - author = postContent.getElementsContainingOwnText("Author(s)") - .firstOrNull()?.tableValue()?.text()?.trim(), - altTitle = postContent.getElementsContainingOwnText("Alternative") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Status") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } - - override suspend fun getTags(): Set { - val doc = webClient.httpGet("https://${domain}/semua-komik/").parseHtml() - val body = doc.body() - val root1 = body.selectFirst("header")?.selectFirst("ul.second-menu") - val root2 = body.selectFirst("div.genres_wrap")?.selectFirst("ul.list-unstyled") - if (root1 == null && root2 == null) { - doc.parseFailed("Root not found") - } - val list = root1?.select("li").orEmpty() + root2?.select("li").orEmpty() - val keySet = HashSet(list.size) - return list.mapNotNullToSet { li -> - val a = li.selectFirst("a") ?: return@mapNotNullToSet null - val href = a.attr("href").removeSuffix("/") - .substringAfterLast(tagPrefix, "") - if (href.isEmpty() || !keySet.add(href)) { - return@mapNotNullToSet null - } - MangaTag( - key = href, - title = a.ownText().trim().ifEmpty { - a.selectFirst(".menu-image-title")?.text()?.trim() ?: return@mapNotNullToSet null - }.toTitleCase(), - source = source, - ) - } - } - -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ScantradVf.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ScantradVf.kt deleted file mode 100644 index 818d8aac..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ScantradVf.kt +++ /dev/null @@ -1,76 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.model.* -import org.koitharu.kotatsu.parsers.util.* - -@MangaSourceParser("SCANTRADVF", "ScantradVf", "fr") -internal class ScantradVf(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.SCANTRADVF, "scantrad-vf.co") { - - override val datePattern = "d MMMM yyyy" - - override val tagPrefix = "genre/" - - override fun String.asMangaState(): MangaState? = when (this) { - "En cours", - -> MangaState.ONGOING - - "Complété", - "Terminé", - -> MangaState.FINISHED - - else -> null - } - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".summary_content") - val tags = postContent.getElementsContainingOwnText("Genre(s)") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - rating = postContent.selectFirstOrThrow(".post-rating") - .selectFirstOrThrow(".total_votes").text().toFloat() / 5f, - description = root.selectFirstOrThrow(".description-summary") - .firstElementChild()?.html(), - author = postContent.getElementsContainingOwnText("Auteur(s)") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Status") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } - - override suspend fun getTags(): Set { - val doc = webClient.httpGet("https://${domain}/genre/action/").parseHtml() - val body = doc.body() - val root1 = body.selectFirst("header")?.selectFirst("ul.second-menu") - val root2 = body.selectFirst("div.genres_wrap")?.selectFirst("ul.list-unstyled") - if (root1 == null && root2 == null) { - doc.parseFailed("Root not found") - } - val list = root2?.select("li").orEmpty() - val keySet = HashSet(list.size) - return list.mapNotNullToSet { li -> - val a = li.selectFirst("a") ?: return@mapNotNullToSet null - val href = a.attr("href").removeSuffix("/") - .substringAfterLast(tagPrefix, "") - if (href.isEmpty() || !keySet.add(href)) { - return@mapNotNullToSet null - } - MangaTag( - key = href, - title = a.ownText().trim().ifEmpty { - return@mapNotNullToSet null - }.toTitleCase(), - source = source, - ) - } - } -} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/TatakaeScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/TatakaeScansParser.kt deleted file mode 100644 index 109b13e1..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/TatakaeScansParser.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.madara - -import org.jsoup.nodes.Element -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.util.attrAsAbsoluteUrlOrNull -import org.koitharu.kotatsu.parsers.util.mapToSet -import org.koitharu.kotatsu.parsers.util.selectFirstOrThrow -import java.util.* - -@MangaSourceParser("TATAKAE_SCANS", "Tatakae Scans", "pt") -internal class TatakaeScansParser(context: MangaLoaderContext) : - Madara6Parser(context, MangaSource.TATAKAE_SCANS, "tatakaescan.com", pageSize = 10) { - - override val datePattern: String = "dd 'de' MMMMM 'de' yyyy" - - override fun parseDetails(manga: Manga, body: Element, chapters: List): Manga { - val root = body.selectFirstOrThrow(".site-content") - val postContent = root.selectFirstOrThrow(".post-content") - val tags = postContent.getElementsContainingOwnText("Gênero") - .firstOrNull()?.tableValue() - ?.getElementsByAttributeValueContaining("href", tagPrefix) - ?.mapToSet { a -> a.asMangaTag() } ?: manga.tags - return manga.copy( - largeCoverUrl = root.selectFirst("picture") - ?.selectFirst("img[data-src]") - ?.attrAsAbsoluteUrlOrNull("data-src"), - description = (root.selectFirst(".detail-content") - ?: root.selectFirstOrThrow(".manga-excerpt")).html(), - author = postContent.getElementsContainingOwnText("Autor") - .firstOrNull()?.tableValue()?.text()?.trim(), - state = postContent.getElementsContainingOwnText("Status") - .firstOrNull()?.tableValue()?.text()?.asMangaState(), - tags = tags, - isNsfw = body.hasClass("adult-content"), - chapters = chapters, - ) - } - - override fun String.asMangaState() = when (trim().lowercase(Locale.ROOT)) { - "em lançamento" -> MangaState.ONGOING - - else -> null - } - -} 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 new file mode 100644 index 00000000..f98c5635 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangaLek.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGALEK", "MangaLek", "ar") +internal class MangaLek(context: MangaLoaderContext) : MadaraParser( + context, MangaSource.MANGALEK, "mangalek.com", + pageSize = 10, +) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangalinkParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangalinkParser.kt new file mode 100644 index 00000000..5af97e4f --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ar/MangalinkParser.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.ar + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGALINK_AR", "Mangalink", "ar") +internal class MangalinkParser(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.MANGALINK_AR, "mangalink.online", pageSize = 10) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AllPornComic.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AllPornComic.kt new file mode 100644 index 00000000..dd75f1e8 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AllPornComic.kt @@ -0,0 +1,17 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("ALLPORN_COMIC", "All Porn Comic", "en") +internal class AllPornComic(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.ALLPORN_COMIC, "allporncomic.com", pageSize = 24) { + + override val tagPrefix = "porncomic-genre/" + + override val isNsfwSource = true + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AquaManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AquaManga.kt new file mode 100644 index 00000000..c4ccf495 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/AquaManga.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("AQUAMANGA", "AquaManga", "en") +internal class AquaManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.AQUAMANGA, "aquamanga.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/BibiManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/BibiManga.kt new file mode 100644 index 00000000..47ceed97 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/BibiManga.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("BIBIMANGA", "BibiManga", "en") +internal class BibiManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.BIBIMANGA, "bibimanga.com") { + + override val isNsfwSource = false +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/FreeManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/FreeManga.kt new file mode 100644 index 00000000..0a104842 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/FreeManga.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("FREEMANGA", "FreeManga", "en") +internal class FreeManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.FREEMANGA, "freemanga.me") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HariManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HariManga.kt new file mode 100644 index 00000000..048e6c5e --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/HariManga.kt @@ -0,0 +1,14 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("HARIMANGA", "HariManga", "en") +internal class HariManga(context: MangaLoaderContext) : + MadaraParser( context, MangaSource.HARIMANGA, "harimanga.com", pageSize = 10,) { + + override val datePattern = "MMMM d, yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai20.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai20.kt new file mode 100644 index 00000000..41f6df33 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai20.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("HENTAI20", "Hentai20", "en") +internal class Hentai20(context: MangaLoaderContext) : MadaraParser(context, MangaSource.HENTAI20, "hentai20.io") { + + override val tagPrefix = "manga-genre/" + + override val isNsfwSource = true +} 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 new file mode 100644 index 00000000..d282ff25 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Hentai4Free.kt @@ -0,0 +1,17 @@ +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("HENTAI_4FREE", "Hentai4Free", "en") +internal class Hentai4Free(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.HENTAI_4FREE, "hentai4free.net", pageSize = 24) { + + override val tagPrefix = "hentai-tag/" + + override val isNsfwSource = true + +} 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 new file mode 100644 index 00000000..26395048 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/IsekaiScanEuParser.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.MadaraParser + +@MangaSourceParser("ISEKAISCAN_EU", "IsekaiScan", "en") +internal class IsekaiScanEuParser(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.ISEKAISCAN_EU, "isekaiscan.to") { + + override val datePattern = "MM/dd/yyyy" + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/KissManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/KissManga.kt new file mode 100644 index 00000000..1b082adf --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/KissManga.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("KISSMANGA", "KissManga", "en") +internal class KissManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.KISSMANGA, "kissmanga.in") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga247.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga247.kt new file mode 100644 index 00000000..5b5b7bad --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga247.kt @@ -0,0 +1,12 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGA_247", "247MANGA", "en") +internal class Manga247(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGA_247, "247manga.com") { + override val tagPrefix = "manhwa-genre/" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga365.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga365.kt new file mode 100644 index 00000000..f7e418cc --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga365.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGA_365", "365Manga", "en") +internal class Manga365(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGA_365, "365manga.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga3s.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga3s.kt new file mode 100644 index 00000000..4a843ac5 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Manga3s.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGA_3S", "Manga3s", "en") +internal class Manga3s(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGA_3S, "manga3s.com") { + + override val tagPrefix = "manhwa-genre/" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaCv.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaCv.kt new file mode 100644 index 00000000..ff1b094f --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaCv.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGACV", "Manga Cv", "en") +internal class MangaCv(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGACV, "mangacv.com", pageSize = 10,) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangaDistrict.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDistrict.kt similarity index 93% rename from src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangaDistrict.kt rename to src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDistrict.kt index 30501306..229e12a3 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangaDistrict.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaDistrict.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.parsers.site.madara +package org.koitharu.kotatsu.parsers.site.madara.en import org.jsoup.nodes.Document import org.koitharu.kotatsu.parsers.MangaLoaderContext @@ -6,6 +6,7 @@ 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.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.util.* import java.text.SimpleDateFormat import java.util.* diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaEffect.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaEffect.kt new file mode 100644 index 00000000..3f8e14bd --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaEffect.kt @@ -0,0 +1,12 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGAEFFECT", "MangaEffect", "en") +internal class MangaEffect(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGAEFFECT, "mangaeffect.com") { + override val datePattern = "dd.MM.yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaKomi.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaKomi.kt new file mode 100644 index 00000000..2c87a12c --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaKomi.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGA_KOMI", "MangaKomi", "en") +internal class MangaKomi(context: MangaLoaderContext) : MadaraParser( context, MangaSource.MANGA_KOMI, "mangakomi.io", pageSize = 18,) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaManhua.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaManhua.kt new file mode 100644 index 00000000..114147f8 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaManhua.kt @@ -0,0 +1,14 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGA_MANHUA", "Manga Manhua", "en") +internal class MangaManhua(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.MANGA_MANHUA, "mangamanhua.online", pageSize = 10) +{ + override val datePattern = "d MMMM، yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangaRead.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRead.kt similarity index 93% rename from src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangaRead.kt rename to src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRead.kt index c69709fa..351a2881 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/MangaRead.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRead.kt @@ -1,4 +1,4 @@ -package org.koitharu.kotatsu.parsers.site.madara +package org.koitharu.kotatsu.parsers.site.madara.en import androidx.collection.arraySetOf import org.jsoup.nodes.Element @@ -6,6 +6,7 @@ import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.exception.ParseException import org.koitharu.kotatsu.parsers.model.* +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.util.* import java.util.* @@ -97,15 +98,6 @@ internal class MangaRead(context: MangaLoaderContext) : } } - private fun Element.tableValue(): Element { - for (p in parents()) { - val children = p.children() - if (children.size == 2) { - return children[1] - } - } - parseFailed("Cannot find tableValue for node ${text()}") - } private fun isNsfw(tags: Set): Boolean { return tags.any { it.key in nsfwTags } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRock.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRock.kt new file mode 100644 index 00000000..e9299d1c --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRock.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGAROCK", "MangaRock", "en") +internal class MangaRock(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGAROCK, "mangarockteam.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRosie.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRosie.kt new file mode 100644 index 00000000..999dffd7 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaRosie.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGAROSIE", "MangaRosie", "en") +internal class MangaRosie(context: MangaLoaderContext) : MadaraParser( + context, MangaSource.MANGAROSIE, "mangarosie.in", + pageSize = 16, +) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTx.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTx.kt new file mode 100644 index 00000000..9b1c66b2 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaTx.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGATX", "MangaTx", "en") +internal class MangaTx(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGATX, "mangatx.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaWeebs.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaWeebs.kt new file mode 100644 index 00000000..1b7401a6 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/MangaWeebs.kt @@ -0,0 +1,14 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGAWEEBS", "MangaWeebs", "en") +internal class MangaWeebs(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.MANGAWEEBS, "mangaweebs.in", pageSize = 20,) { + + override val datePattern = "dd MMMM HH:mm" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Mangaclash.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Mangaclash.kt new file mode 100644 index 00000000..056a4d53 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Mangaclash.kt @@ -0,0 +1,12 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANGACLASH", "Mangaclash", "en") +internal class Mangaclash(context: MangaLoaderContext) : MadaraParser(context, MangaSource.MANGACLASH, "mangaclash.com", pageSize = 18,) { + override val datePattern = "MM/dd/yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhwaClan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhwaClan.kt new file mode 100644 index 00000000..dd7b87f5 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhwaClan.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANHWACLAN", "ManhwaClan", "en") +internal class ManhwaClan(context: MangaLoaderContext) : MadaraParser( context, MangaSource.MANHWACLAN, "manhwaclan.com", pageSize = 10,) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhwaKool.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhwaKool.kt new file mode 100644 index 00000000..b50b56c0 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/ManhwaKool.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("MANHWAKOOL", "Manhwa Kool", "en") +internal class ManhwaKool(context: MangaLoaderContext) : MadaraParser( context, MangaSource.MANHWAKOOL, "manhwakool.com", pageSize = 10,) { + + override val datePattern: String = "MMMM d, yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/NeatManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/NeatManga.kt new file mode 100644 index 00000000..8c627d7f --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/NeatManga.kt @@ -0,0 +1,17 @@ +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("NEATMANGA", "NeatManga", "en") +internal class NeatManga(context: MangaLoaderContext) : MadaraParser( + context, MangaSource.NEATMANGA, "neatmangas.com", + pageSize = 20, +) { + + override val datePattern = "dd MMMM yyyy" + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/PianManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/PianManga.kt new file mode 100644 index 00000000..081c6f57 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/PianManga.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.parsers.site.madara.en + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("PIANMANGA", "PianManga", "en") +internal class PianManga(context: MangaLoaderContext) : MadaraParser( + context, MangaSource.PIANMANGA, "pianmanga.me", + pageSize = 10, +) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/S2Manga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/S2Manga.kt new file mode 100644 index 00000000..2160e55a --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/S2Manga.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("S2MANGA", "S2Manga", "en") +internal class S2Manga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.S2MANGA, "s2manga.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Stkissmanga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Stkissmanga.kt new file mode 100644 index 00000000..0cd5c59d --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Stkissmanga.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("STKISSMANGA", "Stkissmanga", "en") +internal class Stkissmanga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.STKISSMANGA, "1stkissmanga.me") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Toonily.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Toonily.kt new file mode 100644 index 00000000..d70a1281 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Toonily.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("TOONILY", "Toonily", "en") +internal class Toonily(context: MangaLoaderContext) : MadaraParser(context, MangaSource.TOONILY, "toonily.com", pageSize = 18,) { + + override val tagPrefix = "webtoon-genre/" + + override val isNsfwSource = false +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt new file mode 100644 index 00000000..7e753c76 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TopManhua.kt @@ -0,0 +1,14 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("TOPMANHUA", "Top Manhua", "en") +internal class TopManhua(context: MangaLoaderContext) : MadaraParser(context, MangaSource.TOPMANHUA, "www.topmanhua.com") { + + override val tagPrefix = "manhua-genre/" + override val datePattern = "MM/dd/yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TreeManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TreeManga.kt new file mode 100644 index 00000000..50e370bc --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/TreeManga.kt @@ -0,0 +1,14 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("TREE_MANGA", "Tree Manga", "en") +internal class TreeManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.TREE_MANGA, "treemanga.com") { + + override val datePattern = "MM/dd/yyyy" + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Zinmanga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Zinmanga.kt new file mode 100644 index 00000000..f27d1067 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/en/Zinmanga.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("ZINMANGA", "ZINMANGA", "en") +internal class Zinmanga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.ZINMANGA, "zinmanga.com") +{ + override val datePattern = "MM/dd/yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/AiyuMangaScanlation.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/AiyuMangaScanlation.kt new file mode 100644 index 00000000..9711d45e --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/es/AiyuMangaScanlation.kt @@ -0,0 +1,14 @@ +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("AIYUMANGASCANLATION", "AiyuMangaScanlation", "es") +internal class AiyuMangaScanlation(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.AIYUMANGASCANLATION, "aiyumangascanlation.com") { + + override val tagPrefix = "manga-genre/" + override val datePattern = "MM/dd/yyyy" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/AstralManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/AstralManga.kt new file mode 100644 index 00000000..ac2c34a6 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/AstralManga.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.parsers.site.madara.fr + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("ASTRALMANGA", "AstralManga", "fr") +internal class AstralManga(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.ASTRALMANGA, "astral-manga.fr", pageSize = 12) { + + override val datePattern = "dd/MM/yyyy" + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/FrScan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/FrScan.kt new file mode 100644 index 00000000..2ef10012 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/FrScan.kt @@ -0,0 +1,16 @@ +package org.koitharu.kotatsu.parsers.site.madara.fr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +import java.util.Locale + +@MangaSourceParser("FRSCAN", "FrScan", "fr") +internal class FrScan(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.FRSCAN, "fr-scan.com") { + + override val datePattern = "MMMM d, yyyy" + override val sourceLocale: Locale = Locale.FRENCH + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/Hentaizone.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/Hentaizone.kt new file mode 100644 index 00000000..09a64cab --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/Hentaizone.kt @@ -0,0 +1,59 @@ +package org.koitharu.kotatsu.parsers.site.madara.fr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaChapter +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +import org.koitharu.kotatsu.parsers.util.* +import java.text.SimpleDateFormat +import java.util.Locale + + +@MangaSourceParser("HENTAIZONE", "Hentaizone", "fr") +internal class Hentaizone(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.HENTAIZONE, "hentaizone.xyz", pageSize = 10) { + + override val datePattern = "MMM d, yyyy" + override val sourceLocale: Locale = Locale.FRENCH + + override val isNsfwSource = true + + + override suspend fun loadChapters(mangaUrl: String): List { + val url = mangaUrl.toAbsoluteUrl(domain).removeSuffix('/') + "/ajax/chapters/" + val dateFormat = SimpleDateFormat(datePattern, sourceLocale) + val doc = webClient.httpPost(url, emptyMap()).parseHtml() + + return doc.select("li.wp-manga-chapter").mapChapters(reversed = true) { i, li -> + val a = li.selectFirstOrThrow("a") + val href = a.attrAsRelativeUrl("href") + "?style=list" + + // correct parse date missing a "." + val date_org = li.selectFirst("span.chapter-release-date i")?.text() ?: "janv 1, 2000" + val date_corect_parse = date_org + .replace("janv", "janv.") + .replace("févr", "févr.") + .replace("avr", "avr.") + .replace("juil", "juil.") + .replace("sept", "sept.") + .replace("nov", "nov.") + .replace("oct", "oct.") + .replace("déc", "déc.") + MangaChapter( + id = generateUid(href), + url = href, + name = a.text(), + number = i + 1, + branch = null, + uploadDate = parseChapterDate( + dateFormat, + date_corect_parse, + ), + scanlator = null, + source = source, + ) + } + } + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/HhentaiFr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/HhentaiFr.kt new file mode 100644 index 00000000..30a00639 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/HhentaiFr.kt @@ -0,0 +1,27 @@ +package org.koitharu.kotatsu.parsers.site.madara.fr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +import org.koitharu.kotatsu.parsers.util.domain +import org.koitharu.kotatsu.parsers.util.insertCookies +import java.util.Locale + + +@MangaSourceParser("HHENTAIFR", "HhentaiFr", "fr") +internal class HhentaiFr(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.HHENTAIFR, "hhentai.fr") { + + override val datePattern = "MMMM d, yyyy" + override val sourceLocale: Locale = Locale.FRENCH + + override val isNsfwSource = true + + init { + context.cookieJar.insertCookies( + domain, + "age_gate=32;", + ) + } +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/MangaScantrad.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/MangaScantrad.kt new file mode 100644 index 00000000..68797b88 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/MangaScantrad.kt @@ -0,0 +1,16 @@ +package org.koitharu.kotatsu.parsers.site.madara.fr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +import java.util.Locale + +@MangaSourceParser("MANGA_SCANTRAD", "Manga Scantrad", "fr") +internal class MangaScantrad(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.MANGA_SCANTRAD, "manga-scantrad.io") { + + override val datePattern = "d MMMM yyyy" + override val sourceLocale: Locale = Locale.FRENCH + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ReaperScansFr.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ReaperScansFr.kt new file mode 100644 index 00000000..4a73d447 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ReaperScansFr.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.parsers.site.madara.fr + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("REAPERSCANS_FR", "ReaperScansFr", "fr") +internal class ReaperScansFr(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.REAPERSCANS_FR, "reaperscans.fr") { + + override val datePattern = "MM/dd/yyyy" + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScantradVf.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScantradVf.kt new file mode 100644 index 00000000..0c11ed32 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/fr/ScantradVf.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.parsers.site.madara.fr + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("SCANTRADVF", "ScantradVf", "fr") +internal class ScantradVf(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.SCANTRADVF, "scantrad-vf.co") { + + override val datePattern = "d MMMM yyyy" + + override val tagPrefix = "genre/" +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/ReaperScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/ReaperScansParser.kt new file mode 100644 index 00000000..d9657b69 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/id/ReaperScansParser.kt @@ -0,0 +1,17 @@ +package org.koitharu.kotatsu.parsers.site.madara.id + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +import java.util.Locale + +@MangaSourceParser("REAPER_SCANS_ID", "ReaperScansID", "id") +internal class ReaperScansParser(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.REAPER_SCANS_ID, "reaperscans.id") { + + override val datePattern = "MMMM dd, yyyy" + override val tagPrefix = "genre/" + override val sourceLocale: Locale = Locale.ENGLISH + +} 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 new file mode 100644 index 00000000..6c6448ee --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/ja/HachiManga.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("HACHIMANGA", "HachiManga", "ja") +internal class HachiManga(context: MangaLoaderContext) : MadaraParser(context, MangaSource.HACHIMANGA, "hachiraw.com") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Atlantisscan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Atlantisscan.kt new file mode 100644 index 00000000..a6735892 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Atlantisscan.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + + +@MangaSourceParser("ATLANTISSCAN", "Atlantisscan", "pt") +internal class Atlantisscan(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.ATLANTISSCAN, "atlantisscan.com") { + + override val datePattern = "dd/MM/yyyy" + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Hentaiteca.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Hentaiteca.kt new file mode 100644 index 00000000..f5a52886 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Hentaiteca.kt @@ -0,0 +1,17 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("HENTAITECA", "Hentaiteca", "pt") +internal class Hentaiteca(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.HENTAITECA, "hentaiteca.net", pageSize = 10) { + + override val datePattern = "MM/dd/yyyy" + + override val tagPrefix = "genero/" + + override val isNsfwSource = true +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Hipercool.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Hipercool.kt new file mode 100644 index 00000000..b1db364a --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/Hipercool.kt @@ -0,0 +1,19 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + + +@MangaSourceParser("HIPERCOOL", "Hipercool", "pt") +internal class Hipercool(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.HIPERCOOL, "hipercool.xyz", pageSize = 20) { + + override val datePattern = "MMMM d, yyyy" + + override val tagPrefix = "manga-tag/" + + override val isNsfwSource = true + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/PrismaScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/PrismaScansParser.kt new file mode 100644 index 00000000..fb55202f --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/PrismaScansParser.kt @@ -0,0 +1,15 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("PRISMA_SCANS", "Prisma Scans", "pt") +internal class PrismaScansParser(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.PRISMA_SCANS, "prismascans.net", 10) { + + override val tagPrefix = "manga-genre/" + override val datePattern = "MMM dd, yyyy" + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/TatakaeScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/TatakaeScansParser.kt new file mode 100644 index 00000000..5cb449aa --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/pt/TatakaeScansParser.kt @@ -0,0 +1,16 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("TATAKAE_SCANS", "Tatakae Scans", "pt") +internal class TatakaeScansParser(context: MangaLoaderContext) : + MadaraParser(context, MangaSource.TATAKAE_SCANS, "tatakaescan.com", pageSize = 10) { + + override val datePattern: String = "dd 'de' MMMMM 'de' yyyy" + + +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/BakaMan.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/BakaMan.kt new file mode 100644 index 00000000..9e0d7de1 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/BakaMan.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("BAKAMAN", "BakaMan", "th") +internal class BakaMan(context: MangaLoaderContext) : MadaraParser( context, MangaSource.BAKAMAN, "bakaman.net", pageSize = 18,) { + + override val isNsfwSource = false +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Cat300.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Cat300.kt new file mode 100644 index 00000000..d0f9d089 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/th/Cat300.kt @@ -0,0 +1,13 @@ +package org.koitharu.kotatsu.parsers.site.madara.pt + + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.madara.MadaraParser + +@MangaSourceParser("CAT_300", "Cat300", "th") +internal class Cat300(context: MangaLoaderContext) : MadaraParser(context, MangaSource.CAT_300, "cat300.com") { + + override val isNsfwSource = true +} 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 52b6c55d..f4ea4e9a 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 @@ -14,6 +14,7 @@ import java.text.SimpleDateFormat import java.util.* + internal abstract class MangaReaderParser( context: MangaLoaderContext, source: MangaSource, @@ -63,13 +64,11 @@ internal abstract class MangaReaderParser( val selecttag = if(tablemode != null) { tablemode.select(".seriestugenre > a") - }else { docs.select(".wd-full .mgen > a") - - } + val tags = selecttag.mapNotNullToSet { tagMap[it.text()] } @@ -100,38 +99,13 @@ internal abstract class MangaReaderParser( val mangaState = state?.let { when (it.text()) { - "مستمرة", - "En curso", - "Ongoing", - "On going", - "Ativo", - "En Cours", - "OnGoing", - "Đang tiến hành", - "em lançamento", - "Онгоінг", - "Publishing", - "Devam Ediyor", - "Em Andamento", - "In Corso", - "Güncel", - "Berjalan", + "مستمرة", "En curso", "Ongoing", "On going", + "Ativo", "En Cours", "OnGoing", "Đang tiến hành", "em lançamento", "Онгоінг", "Publishing", + "Devam Ediyor", "Em Andamento", "In Corso", "Güncel", "Berjalan", "Продолжается", "Updating", + "Lançando", "In Arrivo", "Emision", "En emision", "مستمر", "Curso", "En marcha", "Publicandose", "连载中", -> MangaState.ONGOING - "Completed", - "Completo", - "Complété", - "Fini", - "Terminé", - "Tamamlandı", - "Đã hoàn thành", - "مكتملة", - "Завершено", - "Finished", - "Finalizado", - "Completata", - "One-Shot", - "Bitti", - "Tamat", + "Completed", "Completo", "Complété", "Fini", "Terminé", "Tamamlandı", "Đã hoàn thành", "مكتملة", "Завершено", + "Finished", "Finalizado", "Completata", "One-Shot", "Bitti", "Tamat", "Completado", "Concluído", "Concluido", "已完结", -> MangaState.FINISHED else -> null } @@ -239,25 +213,45 @@ internal abstract class MangaReaderParser( override suspend fun getPages(chapter: MangaChapter): List { val chapterUrl = chapter.url.toAbsoluteUrl(domain) val docs = webClient.httpGet(chapterUrl).parseHtml() - val script = docs.selectFirstOrThrow("script:containsData(ts_reader)") - val images = JSONObject(script.data().substringAfter('(').substringBeforeLast(')')) - .getJSONArray("sources") - .getJSONObject(0) - .getJSONArray("images") - - val pages = ArrayList(images.length()) - for (i in 0 until images.length()) { - pages.add( + + val test = docs.select("script:containsData(ts_reader)") + if(test.isNullOrEmpty()) + { + return docs.select("div#readerarea img").map { img -> + val url = img.imageUrl() MangaPage( - id = generateUid(images.getString(i)), - url = images.getString(i), + id = generateUid(url), + url = url, preview = null, source = source, - ), - ) + ) + } + }else + { + val script = docs.selectFirstOrThrow("script:containsData(ts_reader)") + val images = JSONObject(script.data().substringAfter('(').substringBeforeLast(')')) + .getJSONArray("sources") + .getJSONObject(0) + .getJSONArray("images") + val pages = ArrayList(images.length()) + for (i in 0 until images.length()) { + pages.add( + MangaPage( + id = generateUid(images.getString(i)), + url = images.getString(i), + preview = null, + source = source, + ), + ) + } + + return pages + } - return pages + + + } override suspend fun getTags(): Set { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Elarcpage.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Elarcpage.kt index 2beefcef..e4b89fec 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Elarcpage.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/Elarcpage.kt @@ -5,7 +5,8 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.config.ConfigKey import org.koitharu.kotatsu.parsers.model.MangaSource import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - +import java.text.SimpleDateFormat +import java.util.Locale @MangaSourceParser("ELARCPAGE", "Elarcpage", "en") internal class Elarcpage(context: MangaLoaderContext) : @@ -13,4 +14,9 @@ internal class Elarcpage(context: MangaLoaderContext) : override val configKeyDomain: ConfigKey.Domain get() = ConfigKey.Domain("elarcpage.com") + override val listUrl: String + get() = "/series" + + + override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("MMM d, yyyy", Locale.ENGLISH) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/SkyManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/SkyManga.kt new file mode 100644 index 00000000..2b2a5561 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/en/SkyManga.kt @@ -0,0 +1,20 @@ +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.config.ConfigKey +import org.koitharu.kotatsu.parsers.model.MangaSource +import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser +import java.text.SimpleDateFormat +import java.util.Locale + + +@MangaSourceParser("SKY_MANGA", "Sky Manga", "en") +internal class SkyManga(context: MangaLoaderContext) : + MangaReaderParser(context, MangaSource.SKY_MANGA, pageSize = 20, searchPageSize = 20) { + override val configKeyDomain: ConfigKey.Domain + get() = ConfigKey.Domain("skymanga.work") + + override val listUrl = "/manga-list" + override val chapterDateFormat: SimpleDateFormat = SimpleDateFormat("DD-MM-yyy", Locale.ENGLISH) +} diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KumaPoiParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KumaPoiParser.kt deleted file mode 100644 index 5ddb8062..00000000 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/KumaPoiParser.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.koitharu.kotatsu.parsers.site.mangareader.id - -import org.koitharu.kotatsu.parsers.MangaLoaderContext -import org.koitharu.kotatsu.parsers.MangaSourceParser -import org.koitharu.kotatsu.parsers.config.ConfigKey -import org.koitharu.kotatsu.parsers.model.MangaSource -import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser - - -@MangaSourceParser("KUMAPOI", "KumaPoi", "id") -internal class KumaPoiParser(context: MangaLoaderContext) : - MangaReaderParser(context, MangaSource.KUMAPOI, pageSize = 20, searchPageSize = 10) { - override val configKeyDomain: ConfigKey.Domain - get() = ConfigKey.Domain("kumapoi.me") - -}