fix(src/all): Fixes for MissAv & javGuru (#3077)

This commit is contained in:
AwkwardPeak7 2024-03-23 15:31:12 +05:00 committed by GitHub
parent 1ff2f39b63
commit cee4220477
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 51 deletions

View File

@ -9,44 +9,15 @@ import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.FormBody import okhttp3.FormBody
import okhttp3.Interceptor import okhttp3.Request
import okhttp3.Response
import okhttp3.internal.commonEmptyHeaders import okhttp3.internal.commonEmptyHeaders
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.io.IOException
object JavCoverFetcher { object JavCoverFetcher {
private val CLIENT by lazy { private val CLIENT by lazy {
Injekt.get<NetworkHelper>().client.newBuilder() Injekt.get<NetworkHelper>().client
.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)
} }
/** /**
@ -89,7 +60,7 @@ object JavCoverFetcher {
private fun getJPTitleFromID(javId: String): String? { private fun getJPTitleFromID(javId: String): String? {
val url = "https://www.javlibrary.com/ja/vl_searchbyid.php?keyword=$javId" 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() val response = CLIENT.newCall(request).execute()
@ -100,7 +71,7 @@ object JavCoverFetcher {
val targetUrl = document.selectFirst(".videos a[href*=\"?v=\"]")?.attr("abs:href") val targetUrl = document.selectFirst(".videos a[href*=\"?v=\"]")?.attr("abs:href")
?: return null ?: 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() val dirtyTitle = document.selectFirst(".post-title")?.text()
@ -111,13 +82,27 @@ object JavCoverFetcher {
} }
private fun getDDGSearchResult(jpTitle: String): String? { private fun getDDGSearchResult(jpTitle: String): String? {
val url = "https://lite.duckduckgo.com/lite" val url = "https://lite.duckduckgo.com/lite/"
val form = FormBody.Builder() val form = FormBody.Builder()
.add("q", "site:amazon.co.jp inurl:/dp/$jpTitle") .add("q", "site:amazon.co.jp inurl:/dp/$jpTitle")
.build() .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() val response = CLIENT.newCall(request).execute()
@ -127,22 +112,41 @@ object JavCoverFetcher {
} }
private fun getHDCoverFromAmazonUrl(amazonUrl: String): String? { 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) { fun addPreferenceToScreen(screen: PreferenceScreen) {
SwitchPreferenceCompat(screen.context).apply { SwitchPreferenceCompat(screen.context).apply {
key = "JavCoverFetcherPref" key = "JavCoverFetcherPref"
title = "Fetch HD covers from Amazon" 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) setDefaultValue(false)
}.also(screen::addPreference) }.also(screen::addPreference)
} }

View File

@ -272,7 +272,13 @@ class JavGuru : AnimeHttpSource(), ConfigurableAnimeSource {
return redirectUrl 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 streamTapeExtractor by lazy { StreamTapeExtractor(client) }
private val doodExtractor by lazy { DoodExtractor(client) } private val doodExtractor by lazy { DoodExtractor(client) }
private val mixDropExtractor by lazy { MixDropExtractor(client) } private val mixDropExtractor by lazy { MixDropExtractor(client) }
@ -281,7 +287,7 @@ class JavGuru : AnimeHttpSource(), ConfigurableAnimeSource {
private fun getVideos(hosterUrl: String): List<Video> { private fun getVideos(hosterUrl: String): List<Video> {
return when { return when {
hosterUrl.contains("javplaya") -> { listOf("javplaya", "javclan").any { it in hosterUrl } -> {
streamWishExtractor.videosFromUrl(hosterUrl) streamWishExtractor.videosFromUrl(hosterUrl)
} }
@ -289,11 +295,11 @@ class JavGuru : AnimeHttpSource(), ConfigurableAnimeSource {
streamTapeExtractor.videoFromUrl(hosterUrl).let(::listOfNotNull) streamTapeExtractor.videoFromUrl(hosterUrl).let(::listOfNotNull)
} }
hosterUrl.contains("dood") -> { listOf("dood", "ds2play").any { it in hosterUrl } -> {
doodExtractor.videosFromUrl(hosterUrl) doodExtractor.videosFromUrl(hosterUrl)
} }
MIXDROP_DOMAINS.any { it in hosterUrl } -> { listOf("mixdrop", "mixdroop").any { it in hosterUrl } -> {
mixDropExtractor.videoFromUrl(hosterUrl) mixDropExtractor.videoFromUrl(hosterUrl)
} }
@ -364,11 +370,6 @@ class JavGuru : AnimeHttpSource(), ConfigurableAnimeSource {
private val IFRAME_OLID_REGEX = Regex("""var OLID = '([^']+)'""") private val IFRAME_OLID_REGEX = Regex("""var OLID = '([^']+)'""")
private val IFRAME_OLID_URL = Regex("""src="([^"]+)"""") 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 = "preferred_quality"
private const val PREF_QUALITY_TITLE = "Preferred quality" private const val PREF_QUALITY_TITLE = "Preferred quality"
private const val PREF_QUALITY_DEFAULT = "720" private const val PREF_QUALITY_DEFAULT = "720"

View File

@ -152,7 +152,7 @@ class MissAV : AnimeHttpSource(), ConfigurableAnimeSource {
val masterPlaylist = playlists.substringAfter("source=\"").substringBefore("\";") val masterPlaylist = playlists.substringAfter("source=\"").substringBefore("\";")
return playlistExtractor.extractFromHls(masterPlaylist) return playlistExtractor.extractFromHls(masterPlaylist, referer = "$baseUrl/")
} }
override fun List<Video>.sort(): List<Video> { override fun List<Video>.sort(): List<Video> {