[MF] Fix page list, added support for age-restricted chapters (#15275)

* [MF] Fix page list, added support for age-restricted chapters

* remove unused imports

* i guess we should add this?
This commit is contained in:
beerpsi 2023-02-08 22:33:48 +07:00 committed by GitHub
parent 9ee381f459
commit eff7f0680f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 9 deletions

View File

@ -6,7 +6,12 @@ ext {
extName = 'MangaFox' extName = 'MangaFox'
pkgNameSuffix = 'en.mangafox' pkgNameSuffix = 'en.mangafox'
extClass = '.MangaFox' extClass = '.MangaFox'
extVersionCode = 5 extVersionCode = 6
isNsfw = true
}
dependencies {
implementation(project(":lib-unpacker"))
} }
apply from: "$rootDir/common.gradle" apply from: "$rootDir/common.gradle"

View File

@ -1,5 +1,7 @@
package eu.kanade.tachiyomi.extension.en.mangafox package eu.kanade.tachiyomi.extension.en.mangafox
import android.webkit.CookieManager
import eu.kanade.tachiyomi.lib.unpacker.Unpacker
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.interceptor.rateLimit import eu.kanade.tachiyomi.network.interceptor.rateLimit
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
@ -8,12 +10,19 @@ import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.ParsedHttpSource
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.Cookie
import okhttp3.CookieJar
import okhttp3.Headers import okhttp3.Headers
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import org.jsoup.nodes.Document import org.jsoup.nodes.Document
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import uy.kohesive.injekt.injectLazy
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Calendar import java.util.Calendar
import java.util.Locale import java.util.Locale
@ -30,8 +39,36 @@ class MangaFox : ParsedHttpSource() {
override val supportsLatest: Boolean = true override val supportsLatest: Boolean = true
private val json by injectLazy<Json>()
override val client: OkHttpClient = network.cloudflareClient.newBuilder() override val client: OkHttpClient = network.cloudflareClient.newBuilder()
.rateLimit(1, 1) .rateLimit(1, 1)
// Force readway=2 cookie to get all page URLs at once
.cookieJar(object : CookieJar {
private val cookieManager by lazy { CookieManager.getInstance() }
init {
cookieManager.setCookie(mobileUrl.toHttpUrl().host, "readway=2")
cookieManager.setCookie(baseUrl.toHttpUrl().host, "isAdult=1")
}
override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
val urlString = url.toString()
cookies.forEach { cookieManager.setCookie(urlString, it.toString()) }
}
override fun loadForRequest(url: HttpUrl): List<Cookie> {
val cookies = cookieManager.getCookie(url.toString())
return if (cookies != null && cookies.isNotEmpty()) {
cookies.split(";").mapNotNull {
Cookie.parse(url, it)
}
} else {
emptyList()
}
}
})
.build() .build()
override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", "$baseUrl/") override fun headersBuilder(): Headers.Builder = super.headersBuilder().add("Referer", "$baseUrl/")
@ -149,16 +186,26 @@ class MangaFox : ParsedHttpSource() {
} }
override fun pageListRequest(chapter: SChapter): Request { override fun pageListRequest(chapter: SChapter): Request {
val mobilePath = chapter.url.replace("/manga/", "/roll_manga/") val headers = headersBuilder()
.set("Referer", "$mobileUrl/")
val headers = headersBuilder().set("Referer", "$mobileUrl/").build() .build()
return GET("$mobileUrl${chapter.url}", headers)
return GET("$mobileUrl$mobilePath", headers)
} }
override fun pageListParse(document: Document): List<Page> = override fun pageListParse(document: Document): List<Page> {
document.select("#viewer img").mapIndexed { idx, it -> val packed = document.selectFirst("script:containsData(p,a,c,k,e)").data()
Page(idx, imageUrl = it.attr("abs:data-original")) val imagesRaw = Unpacker.unpack(packed)
.substringAfter("newImgs=")
.substringBefore(";")
return json.parseToJsonElement(imagesRaw).jsonArray.mapIndexed { idx, it ->
val rawImageUrl = it.jsonPrimitive.content
val imageUrl = if (rawImageUrl.startsWith("http")) {
rawImageUrl
} else {
"${mobileUrl.substringBefore("://")}:$rawImageUrl"
}
Page(idx, imageUrl = imageUrl)
}
} }
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used") override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")