Fix broken search and chapter images at MP. (#7580)

This commit is contained in:
Alessandro Jean 2021-06-09 18:46:25 -03:00 committed by GitHub
parent d6cd87b712
commit ca27731aa8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 186 additions and 206 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'MangaPark v3' extName = 'MangaPark v3'
pkgNameSuffix = 'all.mangapark' pkgNameSuffix = 'all.mangapark'
extClass = '.MangaParkFactory' extClass = '.MangaParkFactory'
extVersionCode = 5 extVersionCode = 6
libVersion = '1.2' libVersion = '1.2'
containsNsfw = true containsNsfw = true
} }

View File

@ -21,31 +21,31 @@ import kotlinx.serialization.json.put
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import org.jsoup.Jsoup import org.jsoup.Jsoup
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import java.util.Calendar
import java.util.concurrent.TimeUnit
import okhttp3.Response
import rx.Observable import rx.Observable
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
import java.util.Calendar
import java.util.concurrent.TimeUnit
open class MangaPark( open class MangaPark(
override val lang: String, override val lang: String,
private val siteLang: String private val siteLang: String
) : ParsedHttpSource() { ) : ParsedHttpSource() {
override val name : String = "MangaPark v3" override val name: String = "MangaPark v3"
override val baseUrl : String = "https://mangapark.net" override val baseUrl: String = "https://mangapark.net"
override val supportsLatest = true override val supportsLatest = true
private val json : Json by injectLazy() private val json: Json by injectLazy()
override val client : OkHttpClient = network.cloudflareClient.newBuilder() override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.connectTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS)
.build() .build()
@ -92,7 +92,7 @@ open class MangaPark(
val url = "$baseUrl/search?word=$query&page=$page" val url = "$baseUrl/search?word=$query&page=$page"
client.newCall(GET(url, headers)).asObservableSuccess() client.newCall(GET(url, headers)).asObservableSuccess()
.map { response -> .map { response ->
searchParse(response) searchMangaParse(response)
} }
} }
@ -106,20 +106,21 @@ open class MangaPark(
val url = "$baseUrl/browse".toHttpUrlOrNull()!!.newBuilder() val url = "$baseUrl/browse".toHttpUrlOrNull()!!.newBuilder()
url.addQueryParameter("page", page.toString()) url.addQueryParameter("page", page.toString())
with (sortFilter) { with(sortFilter) {
if (reverseSortFilter.state) { if (reverseSortFilter.state) {
url.addQueryParameter("sort","${this.selected}.az") url.addQueryParameter("sort", "${this.selected}.az")
} else { } else {
url.addQueryParameter("sort","${this.selected}.za") url.addQueryParameter("sort", "${this.selected}.za")
} }
} }
with (genreFilter) { with(genreFilter) {
url.addQueryParameter("genres", included.joinToString(",") + "|" + excluded.joinToString(",") url.addQueryParameter(
"genres", included.joinToString(",") + "|" + excluded.joinToString(",")
) )
} }
with (statusFilter) { with(statusFilter) {
url.addQueryParameter("release", this.selected) url.addQueryParameter("release", this.selected)
} }
@ -129,7 +130,7 @@ open class MangaPark(
client.newCall(GET(url.build().toString(), headers)).asObservableSuccess() client.newCall(GET(url.build().toString(), headers)).asObservableSuccess()
.map { response -> .map { response ->
searchParse(response) searchMangaParse(response)
} }
} }
} }
@ -146,41 +147,30 @@ open class MangaPark(
return MangasPage(listOf(manga), false) return MangasPage(listOf(manga), false)
} }
private fun searchParse(response: Response): MangasPage {
val mangas = mutableListOf<SManga>()
response.asJsoup().select("div#search-list div.col").forEach { element ->
mangas.add(latestUpdatesFromElement(element))
}
val nextPage = response.asJsoup().select(latestUpdatesNextPageSelector()).first() != null
return MangasPage(mangas, nextPage)
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException("Not used") override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException("Not used")
override fun searchMangaSelector() = throw UnsupportedOperationException("Not used")
override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException("Not used") override fun searchMangaSelector() = "div#search-list div.col"
override fun searchMangaNextPageSelector() = throw UnsupportedOperationException("Not used")
override fun searchMangaFromElement(element: Element) = latestUpdatesFromElement(element)
override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector()
override fun mangaDetailsParse(document: Document): SManga { override fun mangaDetailsParse(document: Document): SManga {
val infoElement = document.select("div#mainer div.container-fluid") val infoElement = document.select("div#mainer div.container-fluid")
val genreList = mutableListOf<String>()
val statusStr = infoElement.select("div.attr-item:contains(status) span").text() val statusStr = infoElement.select("div.attr-item:contains(status) span").text()
infoElement.select("div.attr-item:contains(genres) span span").forEach { element ->
genreList.add(element.text())
}
return SManga.create().apply { return SManga.create().apply {
title = infoElement.select("h3.item-title").text() title = infoElement.select("h3.item-title").text()
description = infoElement.select("div.limit-height-body").select("h5.text-muted, div.limit-html").joinToString("\n\n") { it.text() } description = infoElement.select("div.limit-height-body")
author = infoElement.select("div.attr-item:contains(author)").text().split("/").joinToString(", ") { it.trim() } .select("h5.text-muted, div.limit-html")
.joinToString("\n\n") { it.text() }
author = infoElement.select("div.attr-item:contains(author) a")
.joinToString { it.text().trim() }
status = parseStatus(statusStr) status = parseStatus(statusStr)
thumbnail_url = infoElement.select("div.detail-set div.attr-cover img").attr("abs:src") thumbnail_url = infoElement.select("div.detail-set div.attr-cover img").attr("abs:src")
genre = genreList.joinToString(", ") { it.trim() } genre = infoElement.select("div.attr-item:contains(genres) span span")
.joinToString { it.text().trim() }
} }
} }
private fun parseStatus(status: String?) = when { private fun parseStatus(status: String?) = when {
@ -272,32 +262,25 @@ open class MangaPark(
} }
override fun pageListParse(document: Document): List<Page> { override fun pageListParse(document: Document): List<Page> {
val pages = mutableListOf<Page>()
val duktape = Duktape.create() val duktape = Duktape.create()
val script = document.select("script").html() val script = document.select("script").html()
val imgCdnHost = script.substringAfter("const imgCdnHost = ").substringBefore(";") val imgCdnHost = script.substringAfter("const imgCdnHost = \"").substringBefore("\";")
val imgPathLisRaw = script.substringAfter("const imgPathLis = ").substringBefore(";") val imgPathLisRaw = script.substringAfter("const imgPathLis = ").substringBefore(";")
val imgPathLis = json.parseToJsonElement(imgPathLisRaw).jsonArray val imgPathLis = json.parseToJsonElement(imgPathLisRaw).jsonArray
val amPass = duktape.evaluate(script.substringAfter("const amPass = ").substringBefore(";")).toString() val amPass = script.substringAfter("const amPass = ").substringBefore(";")
val amWord = script.substringAfter("const amWord = ").substringBefore(";") val amWord = script.substringAfter("const amWord = ").substringBefore(";")
val decryptScript = cryptoJS + "CryptoJS.AES.decrypt($amWord, \"$amPass\").toString(CryptoJS.enc.Utf8);" val decryptScript = cryptoJS + "CryptoJS.AES.decrypt($amWord, $amPass).toString(CryptoJS.enc.Utf8);"
val imgWordLisRaw = duktape.evaluate(decryptScript).toString() val imgWordLisRaw = duktape.evaluate(decryptScript).toString()
val imgWordLis = json.parseToJsonElement(imgWordLisRaw).jsonArray val imgWordLis = json.parseToJsonElement(imgWordLisRaw).jsonArray
imgPathLis.mapIndexed { i, imgPathE -> return imgWordLis.mapIndexed { i, imgWordE ->
val imgPath = imgPathE.jsonPrimitive.content val imgPath = imgPathLis[i].jsonPrimitive.content
val imgWordE = imgWordLis.elementAt(i)
val imgWord = imgWordE.jsonPrimitive.content val imgWord = imgWordE.jsonPrimitive.content
val page = "$imgCdnHost$imgPath?$imgWord" Page(i, "", "$imgCdnHost$imgPath?$imgWord")
pages.add(Page(i, "", "$page"))
} }
return pages
} }
private val cryptoJS by lazy { private val cryptoJS by lazy {
@ -311,9 +294,8 @@ open class MangaPark(
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
override fun getFilterList() = FilterList( override fun getFilterList() = FilterList(
//LetterFilter(), // LetterFilter(),
Filter.Header("NOTE: Ignored if using text search!"), Filter.Header("NOTE: Ignored if using text search!"),
Filter.Separator(), Filter.Separator(),
SortFilter(getSortFilter(), 10), SortFilter(getSortFilter(), 10),
@ -381,110 +363,110 @@ open class MangaPark(
) )
private fun getGenreFilter() = listOf( private fun getGenreFilter() = listOf(
TriStateFilterOption("artbook","Artbook"), TriStateFilterOption("artbook", "Artbook"),
TriStateFilterOption("cartoon","Cartoon"), TriStateFilterOption("cartoon", "Cartoon"),
TriStateFilterOption("comic","Comic"), TriStateFilterOption("comic", "Comic"),
TriStateFilterOption("doujinshi","Doujinshi"), TriStateFilterOption("doujinshi", "Doujinshi"),
TriStateFilterOption("imageset","Imageset"), TriStateFilterOption("imageset", "Imageset"),
TriStateFilterOption("manga","Manga"), TriStateFilterOption("manga", "Manga"),
TriStateFilterOption("manhua","Manhua"), TriStateFilterOption("manhua", "Manhua"),
TriStateFilterOption("manhwa","Manhwa"), TriStateFilterOption("manhwa", "Manhwa"),
TriStateFilterOption("webtoon","Webtoon"), TriStateFilterOption("webtoon", "Webtoon"),
TriStateFilterOption("western","Western"), TriStateFilterOption("western", "Western"),
TriStateFilterOption("josei","Josei"), TriStateFilterOption("josei", "Josei"),
TriStateFilterOption("seinen","Seinen"), TriStateFilterOption("seinen", "Seinen"),
TriStateFilterOption("shoujo","Shoujo"), TriStateFilterOption("shoujo", "Shoujo"),
TriStateFilterOption("shoujo_ai","Shoujo ai"), TriStateFilterOption("shoujo_ai", "Shoujo ai"),
TriStateFilterOption("shounen","Shounen"), TriStateFilterOption("shounen", "Shounen"),
TriStateFilterOption("shounen_ai","Shounen ai"), TriStateFilterOption("shounen_ai", "Shounen ai"),
TriStateFilterOption("yaoi","Yaoi"), TriStateFilterOption("yaoi", "Yaoi"),
TriStateFilterOption("yuri","Yuri"), TriStateFilterOption("yuri", "Yuri"),
TriStateFilterOption("ecchi","Ecchi"), TriStateFilterOption("ecchi", "Ecchi"),
TriStateFilterOption("mature","Mature"), TriStateFilterOption("mature", "Mature"),
TriStateFilterOption("adult","Adult"), TriStateFilterOption("adult", "Adult"),
TriStateFilterOption("gore","Gore"), TriStateFilterOption("gore", "Gore"),
TriStateFilterOption("violence","Violence"), TriStateFilterOption("violence", "Violence"),
TriStateFilterOption("smut","Smut"), TriStateFilterOption("smut", "Smut"),
TriStateFilterOption("hentai","Hentai"), TriStateFilterOption("hentai", "Hentai"),
TriStateFilterOption("_4_koma","4-Koma"), TriStateFilterOption("_4_koma", "4-Koma"),
TriStateFilterOption("action","Action"), TriStateFilterOption("action", "Action"),
TriStateFilterOption("adaptation","Adaptation"), TriStateFilterOption("adaptation", "Adaptation"),
TriStateFilterOption("adventure","Adventure"), TriStateFilterOption("adventure", "Adventure"),
TriStateFilterOption("aliens","Aliens"), TriStateFilterOption("aliens", "Aliens"),
TriStateFilterOption("animals","Animals"), TriStateFilterOption("animals", "Animals"),
TriStateFilterOption("anthology","Anthology"), TriStateFilterOption("anthology", "Anthology"),
TriStateFilterOption("cars","cars"), TriStateFilterOption("cars", "cars"),
TriStateFilterOption("comedy","Comedy"), TriStateFilterOption("comedy", "Comedy"),
TriStateFilterOption("cooking","Cooking"), TriStateFilterOption("cooking", "Cooking"),
TriStateFilterOption("crime","crime"), TriStateFilterOption("crime", "crime"),
TriStateFilterOption("crossdressing","Crossdressing"), TriStateFilterOption("crossdressing", "Crossdressing"),
TriStateFilterOption("delinquents","Delinquents"), TriStateFilterOption("delinquents", "Delinquents"),
TriStateFilterOption("dementia","Dementia"), TriStateFilterOption("dementia", "Dementia"),
TriStateFilterOption("demons","Demons"), TriStateFilterOption("demons", "Demons"),
TriStateFilterOption("drama","Drama"), TriStateFilterOption("drama", "Drama"),
TriStateFilterOption("fantasy","Fantasy"), TriStateFilterOption("fantasy", "Fantasy"),
TriStateFilterOption("fan_colored","Fan-Colored"), TriStateFilterOption("fan_colored", "Fan-Colored"),
TriStateFilterOption("full_color","Full Color"), TriStateFilterOption("full_color", "Full Color"),
TriStateFilterOption("game","Game"), TriStateFilterOption("game", "Game"),
TriStateFilterOption("gender_bender","Gender Bender"), TriStateFilterOption("gender_bender", "Gender Bender"),
TriStateFilterOption("genderswap","Genderswap"), TriStateFilterOption("genderswap", "Genderswap"),
TriStateFilterOption("ghosts","Ghosts"), TriStateFilterOption("ghosts", "Ghosts"),
TriStateFilterOption("gyaru","Gyaru"), TriStateFilterOption("gyaru", "Gyaru"),
TriStateFilterOption("harem","Harem"), TriStateFilterOption("harem", "Harem"),
TriStateFilterOption("harlequin","Harlequin"), TriStateFilterOption("harlequin", "Harlequin"),
TriStateFilterOption("historical","Historical"), TriStateFilterOption("historical", "Historical"),
TriStateFilterOption("horror","Horror"), TriStateFilterOption("horror", "Horror"),
TriStateFilterOption("incest","Incest"), TriStateFilterOption("incest", "Incest"),
TriStateFilterOption("isekai","Isekai"), TriStateFilterOption("isekai", "Isekai"),
TriStateFilterOption("kids","Kids"), TriStateFilterOption("kids", "Kids"),
TriStateFilterOption("loli","Loli"), TriStateFilterOption("loli", "Loli"),
TriStateFilterOption("lolicon","lolicon"), TriStateFilterOption("lolicon", "lolicon"),
TriStateFilterOption("magic","Magic"), TriStateFilterOption("magic", "Magic"),
TriStateFilterOption("magical_girls","Magical Girls"), TriStateFilterOption("magical_girls", "Magical Girls"),
TriStateFilterOption("martial_arts","Martial Arts"), TriStateFilterOption("martial_arts", "Martial Arts"),
TriStateFilterOption("mecha","Mecha"), TriStateFilterOption("mecha", "Mecha"),
TriStateFilterOption("medical","Medical"), TriStateFilterOption("medical", "Medical"),
TriStateFilterOption("military","Military"), TriStateFilterOption("military", "Military"),
TriStateFilterOption("monster_girls","Monster Girls"), TriStateFilterOption("monster_girls", "Monster Girls"),
TriStateFilterOption("monsters","Monsters"), TriStateFilterOption("monsters", "Monsters"),
TriStateFilterOption("music","Music"), TriStateFilterOption("music", "Music"),
TriStateFilterOption("mystery","Mystery"), TriStateFilterOption("mystery", "Mystery"),
TriStateFilterOption("netorare","Netorare/NTR"), TriStateFilterOption("netorare", "Netorare/NTR"),
TriStateFilterOption("ninja","Ninja"), TriStateFilterOption("ninja", "Ninja"),
TriStateFilterOption("office_workers","Office Workers"), TriStateFilterOption("office_workers", "Office Workers"),
TriStateFilterOption("oneshot","Oneshot"), TriStateFilterOption("oneshot", "Oneshot"),
TriStateFilterOption("parody","parody"), TriStateFilterOption("parody", "parody"),
TriStateFilterOption("philosophical","Philosophical"), TriStateFilterOption("philosophical", "Philosophical"),
TriStateFilterOption("police","Police"), TriStateFilterOption("police", "Police"),
TriStateFilterOption("post_apocalyptic","Post-Apocalyptic"), TriStateFilterOption("post_apocalyptic", "Post-Apocalyptic"),
TriStateFilterOption("psychological","Psychological"), TriStateFilterOption("psychological", "Psychological"),
TriStateFilterOption("reincarnation","Reincarnation"), TriStateFilterOption("reincarnation", "Reincarnation"),
TriStateFilterOption("reverse_harem","Reverse Harem"), TriStateFilterOption("reverse_harem", "Reverse Harem"),
TriStateFilterOption("romance","Romance"), TriStateFilterOption("romance", "Romance"),
TriStateFilterOption("samurai","Samurai"), TriStateFilterOption("samurai", "Samurai"),
TriStateFilterOption("school_life","School Life"), TriStateFilterOption("school_life", "School Life"),
TriStateFilterOption("sci_fi","Sci-Fi"), TriStateFilterOption("sci_fi", "Sci-Fi"),
TriStateFilterOption("shota","Shota"), TriStateFilterOption("shota", "Shota"),
TriStateFilterOption("shotacon","shotacon"), TriStateFilterOption("shotacon", "shotacon"),
TriStateFilterOption("slice_of_life","Slice of Life"), TriStateFilterOption("slice_of_life", "Slice of Life"),
TriStateFilterOption("sm_bdsm","SM/BDSM"), TriStateFilterOption("sm_bdsm", "SM/BDSM"),
TriStateFilterOption("space","Space"), TriStateFilterOption("space", "Space"),
TriStateFilterOption("sports","Sports"), TriStateFilterOption("sports", "Sports"),
TriStateFilterOption("super_power","Super Power"), TriStateFilterOption("super_power", "Super Power"),
TriStateFilterOption("superhero","Superhero"), TriStateFilterOption("superhero", "Superhero"),
TriStateFilterOption("supernatural","Supernatural"), TriStateFilterOption("supernatural", "Supernatural"),
TriStateFilterOption("survival","Survival"), TriStateFilterOption("survival", "Survival"),
TriStateFilterOption("thriller","Thriller"), TriStateFilterOption("thriller", "Thriller"),
TriStateFilterOption("time_travel","Time Travel"), TriStateFilterOption("time_travel", "Time Travel"),
TriStateFilterOption("traditional_games","Traditional Games"), TriStateFilterOption("traditional_games", "Traditional Games"),
TriStateFilterOption("tragedy","Tragedy"), TriStateFilterOption("tragedy", "Tragedy"),
TriStateFilterOption("vampires","Vampires"), TriStateFilterOption("vampires", "Vampires"),
TriStateFilterOption("video_games","Video Games"), TriStateFilterOption("video_games", "Video Games"),
TriStateFilterOption("virtual_reality","Virtual Reality"), TriStateFilterOption("virtual_reality", "Virtual Reality"),
TriStateFilterOption("wuxia","Wuxia"), TriStateFilterOption("wuxia", "Wuxia"),
TriStateFilterOption("xianxia","Xianxia"), TriStateFilterOption("xianxia", "Xianxia"),
TriStateFilterOption("xuanhuan","Xuanhuan"), TriStateFilterOption("xuanhuan", "Xuanhuan"),
TriStateFilterOption("zombies","Zombies"), TriStateFilterOption("zombies", "Zombies"),
// Hidden Genres // Hidden Genres
TriStateFilterOption("award_winning", "Award Winning"), TriStateFilterOption("award_winning", "Award Winning"),
TriStateFilterOption("youkai", "Youkai"), TriStateFilterOption("youkai", "Youkai"),
@ -498,7 +480,5 @@ open class MangaPark(
const val PREFIX_ID_SEARCH = "id:" const val PREFIX_ID_SEARCH = "id:"
const val CryptoJSUrl = "https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js" const val CryptoJSUrl = "https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"
} }
} }

View File

@ -11,7 +11,7 @@ class MangaParkFactory : SourceFactory {
class LanguageOption(val lang: String, val siteLang: String = lang) class LanguageOption(val lang: String, val siteLang: String = lang)
private val languages = listOf( private val languages = listOf(
//LanguageOption("<Language Format>","<Language Format used in site.>"), // LanguageOption("<Language Format>","<Language Format used in site.>"),
LanguageOption("en"), LanguageOption("en"),
LanguageOption("ar"), LanguageOption("ar"),
LanguageOption("bg"), LanguageOption("bg"),
@ -34,11 +34,11 @@ private val languages = listOf(
LanguageOption("ms"), LanguageOption("ms"),
LanguageOption("pl"), LanguageOption("pl"),
LanguageOption("pt"), LanguageOption("pt"),
LanguageOption("pt-BR","pt_br"), LanguageOption("pt-BR", "pt_br"),
LanguageOption("ro"), LanguageOption("ro"),
LanguageOption("ru"), LanguageOption("ru"),
LanguageOption("es"), LanguageOption("es"),
LanguageOption("es-419","es_419"), LanguageOption("es-419", "es_419"),
LanguageOption("sv"), LanguageOption("sv"),
LanguageOption("th"), LanguageOption("th"),
LanguageOption("tr"), LanguageOption("tr"),
@ -56,10 +56,10 @@ private val languages = listOf(
LanguageOption("km"), LanguageOption("km"),
LanguageOption("ca"), LanguageOption("ca"),
LanguageOption("ceb"), LanguageOption("ceb"),
LanguageOption("zh-rHK","zh_hk"), LanguageOption("zh-rHK", "zh_hk"),
LanguageOption("zh-rTW","zh_tw"), LanguageOption("zh-rTW", "zh_tw"),
LanguageOption("hr"), LanguageOption("hr"),
LanguageOption("en-US","en_us"), LanguageOption("en-US", "en_us"),
LanguageOption("eo"), LanguageOption("eo"),
LanguageOption("et"), LanguageOption("et"),
LanguageOption("fo"), LanguageOption("fo"),
@ -116,5 +116,5 @@ private val languages = listOf(
LanguageOption("zu"), LanguageOption("zu"),
LanguageOption("other", "_t"), LanguageOption("other", "_t"),
LanguageOption("eu"), LanguageOption("eu"),
LanguageOption("pt-PT","pt_pt") LanguageOption("pt-PT", "pt_pt")
) )