fix(src/all): Fixes for MissAv & javGuru (#3077)
This commit is contained in:
parent
1ff2f39b63
commit
cee4220477
@ -9,44 +9,15 @@ import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.network.POST
|
||||
import eu.kanade.tachiyomi.util.asJsoup
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.Response
|
||||
import okhttp3.Request
|
||||
import okhttp3.internal.commonEmptyHeaders
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.IOException
|
||||
|
||||
object JavCoverFetcher {
|
||||
|
||||
private val CLIENT by lazy {
|
||||
Injekt.get<NetworkHelper>().client.newBuilder()
|
||||
.addInterceptor(::amazonAgeVerifyIntercept)
|
||||
.build()
|
||||
}
|
||||
|
||||
private val HEADERS by lazy {
|
||||
commonEmptyHeaders.newBuilder()
|
||||
.set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36")
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun amazonAgeVerifyIntercept(chain: Interceptor.Chain): Response {
|
||||
val request = chain.request()
|
||||
val response = chain.proceed(request)
|
||||
|
||||
if (!request.url.host.contains("amazon.co.jp") || !response.request.url.pathSegments.contains("black-curtain")) {
|
||||
return response
|
||||
}
|
||||
|
||||
val document = response.asJsoup()
|
||||
val targetUrl = document.selectFirst("#black-curtain-yes-button a")?.attr("abs:href")
|
||||
?: throw IOException("Failed to bypass Amazon Age Gate")
|
||||
|
||||
val newRequest = request.newBuilder().apply {
|
||||
url(targetUrl)
|
||||
}.build()
|
||||
|
||||
return chain.proceed(newRequest)
|
||||
Injekt.get<NetworkHelper>().client
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,7 +60,7 @@ object JavCoverFetcher {
|
||||
private fun getJPTitleFromID(javId: String): String? {
|
||||
val url = "https://www.javlibrary.com/ja/vl_searchbyid.php?keyword=$javId"
|
||||
|
||||
val request = GET(url, HEADERS)
|
||||
val request = GET(url, commonEmptyHeaders)
|
||||
|
||||
val response = CLIENT.newCall(request).execute()
|
||||
|
||||
@ -100,7 +71,7 @@ object JavCoverFetcher {
|
||||
val targetUrl = document.selectFirst(".videos a[href*=\"?v=\"]")?.attr("abs:href")
|
||||
?: return null
|
||||
|
||||
document = CLIENT.newCall(GET(targetUrl, HEADERS)).execute().asJsoup()
|
||||
document = CLIENT.newCall(GET(targetUrl, commonEmptyHeaders)).execute().asJsoup()
|
||||
}
|
||||
|
||||
val dirtyTitle = document.selectFirst(".post-title")?.text()
|
||||
@ -111,13 +82,27 @@ object JavCoverFetcher {
|
||||
}
|
||||
|
||||
private fun getDDGSearchResult(jpTitle: String): String? {
|
||||
val url = "https://lite.duckduckgo.com/lite"
|
||||
val url = "https://lite.duckduckgo.com/lite/"
|
||||
|
||||
val form = FormBody.Builder()
|
||||
.add("q", "site:amazon.co.jp inurl:/dp/$jpTitle")
|
||||
.build()
|
||||
|
||||
val request = POST(url, HEADERS, form)
|
||||
val headers = commonEmptyHeaders.newBuilder().apply {
|
||||
add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8")
|
||||
add("Host", "lite.duckduckgo.com")
|
||||
add("Referer", "https://lite.duckduckgo.com/")
|
||||
add("Origin", "https://lite.duckduckgo.com")
|
||||
add("Accept-Language", "en-US,en;q=0.5")
|
||||
add("DNT", "1")
|
||||
add("Sec-Fetch-Dest", "document")
|
||||
add("Sec-Fetch-Mode", "navigate")
|
||||
add("Sec-Fetch-Site", "same-origin")
|
||||
add("Sec-Fetch-User", "?1")
|
||||
add("TE", "trailers")
|
||||
}.build()
|
||||
|
||||
val request = POST(url, headers, form)
|
||||
|
||||
val response = CLIENT.newCall(request).execute()
|
||||
|
||||
@ -127,22 +112,41 @@ object JavCoverFetcher {
|
||||
}
|
||||
|
||||
private fun getHDCoverFromAmazonUrl(amazonUrl: String): String? {
|
||||
val request = GET(amazonUrl, HEADERS)
|
||||
val basicCoverUrl = "https://m.media-amazon.com/images/P/%s.01.MAIN._SCRM_.jpg"
|
||||
val asinRegex = Regex("""/dp/(\w+)""")
|
||||
|
||||
val response = CLIENT.newCall(request).execute()
|
||||
val asin = asinRegex.find(amazonUrl)?.groupValues?.get(1)
|
||||
?: return null
|
||||
|
||||
val document = response.asJsoup()
|
||||
var cover = basicCoverUrl.replace("%s", asin)
|
||||
|
||||
val smallImage = document.selectFirst("#landingImage")?.attr("src")
|
||||
if (!checkCover(cover)) {
|
||||
cover = cover.replace(".01.", ".")
|
||||
}
|
||||
|
||||
return smallImage?.replace(Regex("""(\._\w+_\.jpg)"""), ".jpg")
|
||||
return cover
|
||||
}
|
||||
|
||||
private fun checkCover(cover: String): Boolean {
|
||||
return getContentLength(cover) > 100
|
||||
}
|
||||
|
||||
private fun getContentLength(url: String): Long {
|
||||
val request = Request.Builder()
|
||||
.head()
|
||||
.url(url)
|
||||
.build()
|
||||
|
||||
val res = CLIENT.newCall(request).execute()
|
||||
|
||||
return res.use { it.headers["content-length"] }?.toLongOrNull() ?: 0
|
||||
}
|
||||
|
||||
fun addPreferenceToScreen(screen: PreferenceScreen) {
|
||||
SwitchPreferenceCompat(screen.context).apply {
|
||||
key = "JavCoverFetcherPref"
|
||||
title = "Fetch HD covers from Amazon"
|
||||
summary = "Attempts to fetch HD covers from Amazon.\nMay result in incorrect cover."
|
||||
summary = "Attempts to fetch vertical HD covers from Amazon.\nMay result in incorrect cover."
|
||||
setDefaultValue(false)
|
||||
}.also(screen::addPreference)
|
||||
}
|
||||
|
@ -272,7 +272,13 @@ class JavGuru : AnimeHttpSource(), ConfigurableAnimeSource {
|
||||
return redirectUrl
|
||||
}
|
||||
|
||||
private val streamWishExtractor by lazy { StreamWishExtractor(client, headers) }
|
||||
private val streamWishExtractor by lazy {
|
||||
val swHeaders = headersBuilder()
|
||||
.set("Referer", "$baseUrl/")
|
||||
.build()
|
||||
|
||||
StreamWishExtractor(client, swHeaders)
|
||||
}
|
||||
private val streamTapeExtractor by lazy { StreamTapeExtractor(client) }
|
||||
private val doodExtractor by lazy { DoodExtractor(client) }
|
||||
private val mixDropExtractor by lazy { MixDropExtractor(client) }
|
||||
@ -281,7 +287,7 @@ class JavGuru : AnimeHttpSource(), ConfigurableAnimeSource {
|
||||
|
||||
private fun getVideos(hosterUrl: String): List<Video> {
|
||||
return when {
|
||||
hosterUrl.contains("javplaya") -> {
|
||||
listOf("javplaya", "javclan").any { it in hosterUrl } -> {
|
||||
streamWishExtractor.videosFromUrl(hosterUrl)
|
||||
}
|
||||
|
||||
@ -289,11 +295,11 @@ class JavGuru : AnimeHttpSource(), ConfigurableAnimeSource {
|
||||
streamTapeExtractor.videoFromUrl(hosterUrl).let(::listOfNotNull)
|
||||
}
|
||||
|
||||
hosterUrl.contains("dood") -> {
|
||||
listOf("dood", "ds2play").any { it in hosterUrl } -> {
|
||||
doodExtractor.videosFromUrl(hosterUrl)
|
||||
}
|
||||
|
||||
MIXDROP_DOMAINS.any { it in hosterUrl } -> {
|
||||
listOf("mixdrop", "mixdroop").any { it in hosterUrl } -> {
|
||||
mixDropExtractor.videoFromUrl(hosterUrl)
|
||||
}
|
||||
|
||||
@ -364,11 +370,6 @@ class JavGuru : AnimeHttpSource(), ConfigurableAnimeSource {
|
||||
private val IFRAME_OLID_REGEX = Regex("""var OLID = '([^']+)'""")
|
||||
private val IFRAME_OLID_URL = Regex("""src="([^"]+)"""")
|
||||
|
||||
private val MIXDROP_DOMAINS = listOf(
|
||||
"mixdrop",
|
||||
"mixdroop",
|
||||
)
|
||||
|
||||
private const val PREF_QUALITY = "preferred_quality"
|
||||
private const val PREF_QUALITY_TITLE = "Preferred quality"
|
||||
private const val PREF_QUALITY_DEFAULT = "720"
|
||||
|
@ -152,7 +152,7 @@ class MissAV : AnimeHttpSource(), ConfigurableAnimeSource {
|
||||
|
||||
val masterPlaylist = playlists.substringAfter("source=\"").substringBefore("\";")
|
||||
|
||||
return playlistExtractor.extractFromHls(masterPlaylist)
|
||||
return playlistExtractor.extractFromHls(masterPlaylist, referer = "$baseUrl/")
|
||||
}
|
||||
|
||||
override fun List<Video>.sort(): List<Video> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user