Merge branch 'master' of github.com:KotatsuApp/kotatsu-parsers into feature/advanced_filter

Koitharu 2 years ago
commit ab1b549a64
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

@ -22,15 +22,26 @@ private const val CHAPTERS_MAX_PAGE_SIZE = 500
private const val CHAPTERS_PARALLELISM = 3 private const val CHAPTERS_PARALLELISM = 3
private const val CHAPTERS_MAX_COUNT = 10_000 // strange api behavior, looks like a bug private const val CHAPTERS_MAX_COUNT = 10_000 // strange api behavior, looks like a bug
private const val LOCALE_FALLBACK = "en" private const val LOCALE_FALLBACK = "en"
private const val SERVER_DATA = "data"
private const val SERVER_DATA_SAVER = "data-saver"
@MangaSourceParser("MANGADEX", "MangaDex") @MangaSourceParser("MANGADEX", "MangaDex")
internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context, MangaParserSource.MANGADEX) { internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context, MangaParserSource.MANGADEX) {
override val configKeyDomain = ConfigKey.Domain("mangadex.org") override val configKeyDomain = ConfigKey.Domain("mangadex.org")
private val preferredServerKey = ConfigKey.PreferredImageServer(
presetValues = mapOf(
SERVER_DATA to "Original quality",
SERVER_DATA_SAVER to "Compressed quality",
),
defaultValue = SERVER_DATA,
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) { override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys) super.onCreateConfig(keys)
keys.add(userAgentKey) keys.add(userAgentKey)
keys.add(preferredServerKey)
} }
override val filterCapabilities: MangaListFilterCapabilities override val filterCapabilities: MangaListFilterCapabilities
@ -231,12 +242,15 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context
} }
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> { override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
val domain = domain val json = webClient.httpGet(
val chapterJson = webClient.httpGet("https://api.$domain/at-home/server/${chapter.url}?forcePort443=false") "https://api.$domain/at-home/server/${chapter.url}?forcePort443=false",
.parseJson() ).parseJson()
.getJSONObject("chapter") val chapterJson = json.getJSONObject("chapter")
val pages = chapterJson.getJSONArray("data") val server = config[preferredServerKey] ?: SERVER_DATA
val prefix = "https://uploads.$domain/data/${chapterJson.getString("hash")}/" val pages = chapterJson.getJSONArray(
if (server == SERVER_DATA_SAVER) "dataSaver" else "data",
)
val prefix = "${json.getString("baseUrl")}/$server/${chapterJson.getString("hash")}/"
return List(pages.length()) { i -> return List(pages.length()) { i ->
val url = prefix + pages.getString(i) val url = prefix + pages.getString(i)
MangaPage( MangaPage(

@ -64,7 +64,7 @@ internal abstract class HeanCms(
val url = buildString { val url = buildString {
append("https://") append("https://")
append(apiPath) append(apiPath)
append("/query?query_string=") append("/query?query_string=&series_type=Comic&perPage=$pageSize")
when { when {
!filter.query.isNullOrEmpty() -> { !filter.query.isNullOrEmpty() -> {
append(filter.query.urlEncoded()) append(filter.query.urlEncoded())
@ -97,13 +97,10 @@ internal abstract class HeanCms(
SortOrder.ALPHABETICAL_DESC -> append("title&order=desc") SortOrder.ALPHABETICAL_DESC -> append("title&order=desc")
else -> append("latest&order=desc") else -> append("latest&order=desc")
} }
append("&series_type=Comic&perPage=20")
append("&tags_ids=") append("&tags_ids=")
append("[".urlEncoded()) append("[".urlEncoded())
append(filter.tags.joinToString(",") { it.key }) append(filter.tags.joinToString(",") { it.key })
append("]".urlEncoded()) append("]".urlEncoded())
} }
} }
append("&page=") append("&page=")
@ -195,10 +192,16 @@ internal abstract class HeanCms(
private suspend fun fetchAvailableTags(): Set<MangaTag> { private suspend fun fetchAvailableTags(): Set<MangaTag> {
val doc = webClient.httpGet("https://$domain/comics").parseHtml() val doc = webClient.httpGet("https://$domain/comics").parseHtml()
val regex = Regex("\"tags\\\\.*?(\\[.+?])") val regex = Regex("\"tags\\\\?\":\\s*\\[(.+?)]\\s*[},]")
val tags = doc.select("script").firstNotNullOf { script -> val tags = doc.select("script").joinToString("") { it.html() }
regex.find(script.html())?.groupValues?.getOrNull(1) .let { fullHtml ->
}.unescapeJson() regex.find(fullHtml)?.groupValues?.getOrNull(1)
}
?.unescapeJson()
?.replace(Regex(""""]\)\s*self\.__next_f\.push\(\[\d+,""""), "")
?.let { "[$it]" }
?: return emptySet()
return JSONArray(tags).mapJSON { return JSONArray(tags).mapJSON {
MangaTag( MangaTag(
key = it.getInt("id").toString(), key = it.getInt("id").toString(),
@ -207,4 +210,5 @@ internal abstract class HeanCms(
) )
}.toSet() }.toSet()
} }
} }

@ -12,7 +12,7 @@ import org.koitharu.kotatsu.parsers.util.*
@MangaSourceParser("HENTAICUBE", "HentaiCube", "vi", ContentType.HENTAI) @MangaSourceParser("HENTAICUBE", "HentaiCube", "vi", ContentType.HENTAI)
internal class HentaiCube(context: MangaLoaderContext) : internal class HentaiCube(context: MangaLoaderContext) :
MadaraParser(context, MangaParserSource.HENTAICUBE, "hentaicb.mom") { MadaraParser(context, MangaParserSource.HENTAICUBE, "hentaicb.lol") {
override val datePattern = "dd/MM/yyyy" override val datePattern = "dd/MM/yyyy"
override val tagPrefix = "the-loai/" override val tagPrefix = "the-loai/"

@ -6,9 +6,9 @@ import org.koitharu.kotatsu.parsers.model.ContentType
import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.model.MangaParserSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("HENTAIVNCAFE", "HentaiVnCafe", "vi", ContentType.HENTAI) @MangaSourceParser("HENTAIVNFIT", "HentaiVnFit", "vi", ContentType.HENTAI)
internal class HentaiVnCafe(context: MangaLoaderContext) : internal class HentaiVnCafe(context: MangaLoaderContext) :
MadaraParser(context, MangaParserSource.HENTAIVNCAFE, "hentaivn.cafe", 24) { MadaraParser(context, MangaParserSource.HENTAIVNFIT, "hentaivn.fit", 24) {
override val listUrl = "truyen-hentai/" override val listUrl = "truyen-hentai/"
override val tagPrefix = "the-loai/" override val tagPrefix = "the-loai/"
override val datePattern = "dd/MM/yyyy" override val datePattern = "dd/MM/yyyy"

@ -4,7 +4,9 @@ import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.model.MangaParserSource
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.Broken
@Broken
@MangaSourceParser("PINKTEACOMIC", "PinkTeaComic", "vi") @MangaSourceParser("PINKTEACOMIC", "PinkTeaComic", "vi")
internal class PinkTeaComic(context: MangaLoaderContext) : internal class PinkTeaComic(context: MangaLoaderContext) :
MadaraParser(context, MangaParserSource.PINKTEACOMIC, "pinkteacomics.com") { MadaraParser(context, MangaParserSource.PINKTEACOMIC, "pinkteacomics.com") {

@ -8,7 +8,7 @@ import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
@MangaSourceParser("TRUYENVN", "TruyenVn", "vi", ContentType.HENTAI) @MangaSourceParser("TRUYENVN", "TruyenVn", "vi", ContentType.HENTAI)
internal class TruyenVn(context: MangaLoaderContext) : internal class TruyenVn(context: MangaLoaderContext) :
MadaraParser(context, MangaParserSource.TRUYENVN, "truyenvn.mobi", 20) { MadaraParser(context, MangaParserSource.TRUYENVN, "truyenvn.fit", 20) {
override val listUrl = "truyen-tranh/" override val listUrl = "truyen-tranh/"
override val tagPrefix = "the-loai/" override val tagPrefix = "the-loai/"
override val datePattern = "dd/MM/yyyy" override val datePattern = "dd/MM/yyyy"

@ -21,7 +21,7 @@ private const val SEARCH_PAGE_SIZE = 10
@MangaSourceParser("HENTAIVN", "HentaiVN", "vi", type = ContentType.HENTAI) @MangaSourceParser("HENTAIVN", "HentaiVN", "vi", type = ContentType.HENTAI)
internal class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaParserSource.HENTAIVN) { internal class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaParserSource.HENTAIVN) {
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("hentaiayame.com") override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("hentaiayame.net")
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) { override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys) super.onCreateConfig(keys)

@ -10,6 +10,6 @@ import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser
internal class NetTruyen(context: MangaLoaderContext) : internal class NetTruyen(context: MangaLoaderContext) :
WpComicsParser(context, MangaParserSource.NETTRUYEN, "www.nettruyenupp.com", 44) { WpComicsParser(context, MangaParserSource.NETTRUYEN, "www.nettruyenupp.com", 44) {
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain( override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain(
"www.nettruyenupp.com", "nettruyenaa.com", "nettruyenx.com", "www.nettruyenupp.com", "nettruyenww.com", "nettruyenx.com",
) )
} }

@ -8,8 +8,10 @@ import org.koitharu.kotatsu.parsers.exception.NotFoundException
import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser
import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.*
import java.util.* import java.util.EnumSet
import org.koitharu.kotatsu.parsers.Broken
@Broken
@MangaSourceParser("NETTRUYENLL", "NetTruyenLL", "vi") @MangaSourceParser("NETTRUYENLL", "NetTruyenLL", "vi")
internal class NetTruyenLL(context: MangaLoaderContext) : internal class NetTruyenLL(context: MangaLoaderContext) :
WpComicsParser(context, MangaParserSource.NETTRUYENLL, "nettruyenll.com", 20) { WpComicsParser(context, MangaParserSource.NETTRUYENLL, "nettruyenll.com", 20) {

@ -8,8 +8,10 @@ import org.koitharu.kotatsu.parsers.exception.NotFoundException
import org.koitharu.kotatsu.parsers.model.* import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser
import org.koitharu.kotatsu.parsers.util.* import org.koitharu.kotatsu.parsers.util.*
import java.util.* import org.koitharu.kotatsu.parsers.Broken
import java.util.EnumSet
@Broken
@MangaSourceParser("NETTRUYENSSR", "NetTruyenSSR", "vi") @MangaSourceParser("NETTRUYENSSR", "NetTruyenSSR", "vi")
internal class NetTruyenSSR(context: MangaLoaderContext) : internal class NetTruyenSSR(context: MangaLoaderContext) :
WpComicsParser(context, MangaParserSource.NETTRUYENSSR, "nettruyenssr.com", 20) { WpComicsParser(context, MangaParserSource.NETTRUYENSSR, "nettruyenssr.com", 20) {

Loading…
Cancel
Save