[Grouple] Added Seimanga support

Koitharu 2 years ago
parent ba8682f79e
commit 39ae6a406c
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -94,6 +94,7 @@ class Manga(
largeCoverUrl: String? = this.largeCoverUrl, largeCoverUrl: String? = this.largeCoverUrl,
description: String? = this.description, description: String? = this.description,
chapters: List<MangaChapter>? = this.chapters, chapters: List<MangaChapter>? = this.chapters,
source: MangaSource = this.source,
) = Manga( ) = Manga(
id = id, id = id,
title = title, title = title,
@ -109,7 +110,7 @@ class Manga(
largeCoverUrl = largeCoverUrl, largeCoverUrl = largeCoverUrl,
description = description, description = description,
chapters = chapters, chapters = chapters,
source = source source = source,
) )
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {

@ -4,6 +4,7 @@ import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.Interceptor import okhttp3.Interceptor
@ -112,7 +113,8 @@ internal abstract class GroupleParser(
} }
override suspend fun getDetails(manga: Manga): Manga { override suspend fun getDetails(manga: Manga): Manga {
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).checkAuthRequired().parseHtml() val response = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).checkAuthRequired()
val doc = response.parseHtml()
val root = doc.body().requireElementById("mangaBox").selectFirstOrThrow("div.leftContent") val root = doc.body().requireElementById("mangaBox").selectFirstOrThrow("div.leftContent")
val dateFormat = SimpleDateFormat("dd.MM.yy", Locale.US) val dateFormat = SimpleDateFormat("dd.MM.yy", Locale.US)
val coverImg = root.selectFirst("div.subject-cover")?.selectFirst("img") val coverImg = root.selectFirst("div.subject-cover")?.selectFirst("img")
@ -125,7 +127,9 @@ internal abstract class GroupleParser(
} else { } else {
null null
} }
val newSource = getSource(response.request.url)
return manga.copy( return manga.copy(
source = newSource,
description = root.selectFirst("div.manga-description")?.html(), description = root.selectFirst("div.manga-description")?.html(),
largeCoverUrl = coverImg?.attr("data-full"), largeCoverUrl = coverImg?.attr("data-full"),
coverUrl = coverImg?.attr("data-thumb") ?: manga.coverUrl, coverUrl = coverImg?.attr("data-thumb") ?: manga.coverUrl,
@ -160,7 +164,7 @@ internal abstract class GroupleParser(
url = href, url = href,
uploadDate = dateFormat.tryParse(tr.selectFirst("td.date")?.text()), uploadDate = dateFormat.tryParse(tr.selectFirst("td.date")?.text()),
scanlator = translators, scanlator = translators,
source = source, source = newSource,
branch = null, branch = null,
), ),
) )
@ -177,7 +181,7 @@ internal abstract class GroupleParser(
url = link, url = link,
uploadDate = dateFormat.tryParse(jo.getStringOrNull("dateCreated")), uploadDate = dateFormat.tryParse(jo.getStringOrNull("dateCreated")),
scanlator = null, scanlator = null,
source = source, source = newSource,
branch = translations[personId], branch = translations[personId],
) )
} }
@ -187,7 +191,11 @@ internal abstract class GroupleParser(
} }
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> { override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val doc = webClient.httpGet(chapter.url.toAbsoluteUrl(domain) + "?mtr=1").checkAuthRequired().parseHtml() if (chapter.source != source) { // handle redirects between websites
return context.newParserInstance(chapter.source).getPages(chapter)
}
val url = chapter.url.toAbsoluteUrl(domain).toHttpUrl().newBuilder().setQueryParameter("mtr", "1").build()
val doc = webClient.httpGet(url).checkAuthRequired().parseHtml()
val scripts = doc.select("script") val scripts = doc.select("script")
for (script in scripts) { for (script in scripts) {
val data = script.html() val data = script.html()
@ -292,6 +300,14 @@ internal abstract class GroupleParser(
return root.select("div.tile").mapNotNull(::parseManga) return root.select("div.tile").mapNotNull(::parseManga)
} }
protected open fun getSource(url: HttpUrl): MangaSource = when (url.host) {
in SeiMangaParser.domains -> MangaSource.SEIMANGA
in MintMangaParser.domains -> MangaSource.MINTMANGA
in ReadmangaParser.domains -> MangaSource.READMANGA_RU
in SelfMangaParser.domains -> MangaSource.SELFMANGA
else -> source
}
private fun getSortKey(sortOrder: SortOrder) = when (sortOrder) { private fun getSortKey(sortOrder: SortOrder) = when (sortOrder) {
SortOrder.ALPHABETICAL -> "name" SortOrder.ALPHABETICAL -> "name"
SortOrder.POPULARITY -> "rate" SortOrder.POPULARITY -> "rate"

@ -10,9 +10,14 @@ internal class MintMangaParser(
context: MangaLoaderContext, context: MangaLoaderContext,
) : GroupleParser(context, MangaSource.MINTMANGA, 2) { ) : GroupleParser(context, MangaSource.MINTMANGA, 2) {
override val configKeyDomain = ConfigKey.Domain( override val configKeyDomain = ConfigKey.Domain(*domains)
companion object {
val domains = arrayOf(
"24.mintmanga.one", "24.mintmanga.one",
"mintmanga.live", "mintmanga.live",
"mintmanga.com", "mintmanga.com",
) )
} }
}

@ -10,9 +10,14 @@ internal class ReadmangaParser(
context: MangaLoaderContext, context: MangaLoaderContext,
) : GroupleParser(context, MangaSource.READMANGA_RU, 1) { ) : GroupleParser(context, MangaSource.READMANGA_RU, 1) {
override val configKeyDomain = ConfigKey.Domain( override val configKeyDomain = ConfigKey.Domain(*domains)
companion object {
val domains = arrayOf(
"readmanga.live", "readmanga.live",
"readmanga.io", "readmanga.io",
"readmanga.me", "readmanga.me",
) )
} }
}

@ -0,0 +1,21 @@
package org.koitharu.kotatsu.parsers.site.ru.grouple
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
@MangaSourceParser("SEIMANGA", "SeiManga", "ru")
internal class SeiMangaParser(
context: MangaLoaderContext,
) : GroupleParser(context, MangaSource.SEIMANGA, 21) {
override val configKeyDomain = ConfigKey.Domain(*domains)
companion object {
val domains = arrayOf(
"seimanga.me",
)
}
}

@ -11,6 +11,12 @@ internal class SelfMangaParser(
context: MangaLoaderContext, context: MangaLoaderContext,
) : GroupleParser(context, MangaSource.SELFMANGA, 3) { ) : GroupleParser(context, MangaSource.SELFMANGA, 3) {
override val configKeyDomain = ConfigKey.Domain("selfmanga.live") override val configKeyDomain = ConfigKey.Domain(*domains)
companion object {
val domains = arrayOf(
"selfmanga.live",
)
}
} }

Loading…
Cancel
Save