fix(en/animeflix): Update baseUrl (#2437)
This commit is contained in:
@ -8,7 +8,7 @@ ext {
|
|||||||
extName = 'AnimeFlix'
|
extName = 'AnimeFlix'
|
||||||
pkgNameSuffix = 'en.animeflix'
|
pkgNameSuffix = 'en.animeflix'
|
||||||
extClass = '.AnimeFlix'
|
extClass = '.AnimeFlix'
|
||||||
extVersionCode = 6
|
extVersionCode = 7
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.animesource.model.SEpisode
|
|||||||
import eu.kanade.tachiyomi.animesource.model.Video
|
import eu.kanade.tachiyomi.animesource.model.Video
|
||||||
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import eu.kanade.tachiyomi.util.asJsoup
|
import eu.kanade.tachiyomi.util.asJsoup
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
@ -21,6 +22,7 @@ import kotlinx.serialization.Serializable
|
|||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
|
import okhttp3.MultipartBody
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
@ -34,7 +36,7 @@ class AnimeFlix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
override val name = "AnimeFlix"
|
override val name = "AnimeFlix"
|
||||||
|
|
||||||
override val baseUrl = "https://animeflix.net.in"
|
override val baseUrl = "https://animeflix.mobi"
|
||||||
|
|
||||||
override val lang = "en"
|
override val lang = "en"
|
||||||
|
|
||||||
@ -250,7 +252,13 @@ class AnimeFlix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
if (url.url.toHttpUrl().encodedPath == "/404") return@runCatching null
|
if (url.url.toHttpUrl().encodedPath == "/404") return@runCatching null
|
||||||
val (videos, mediaUrl) = extractVideo(url)
|
val (videos, mediaUrl) = extractVideo(url)
|
||||||
when {
|
when {
|
||||||
videos.isEmpty() -> extractGDriveLink(mediaUrl, url.quality)
|
videos.isEmpty() -> {
|
||||||
|
extractGDriveLink(mediaUrl, url.quality).ifEmpty {
|
||||||
|
getDirectLink(mediaUrl, "instant", "/mfile/")?.let {
|
||||||
|
listOf(Video(it, "${url.quality}p - GDrive Instant link", it))
|
||||||
|
} ?: emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> videos
|
else -> videos
|
||||||
}
|
}
|
||||||
}.getOrNull()
|
}.getOrNull()
|
||||||
@ -293,15 +301,37 @@ class AnimeFlix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
|
|
||||||
Video(
|
Video(
|
||||||
url = decodedLink,
|
url = decodedLink,
|
||||||
quality = "$quality - CF $type Worker ${index + 1}$size",
|
quality = "${quality}p - CF $type Worker ${index + 1}$size",
|
||||||
videoUrl = decodedLink,
|
videoUrl = decodedLink,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getDirectLink(url: String, action: String = "direct", newPath: String = "/file/"): String? {
|
||||||
|
val doc = client.newCall(GET(url, headers)).execute().use { it.asJsoup() }
|
||||||
|
val script = doc.selectFirst("script:containsData(async function taskaction)")
|
||||||
|
?.data()
|
||||||
|
?: return url
|
||||||
|
|
||||||
|
val key = script.substringAfter("key\", \"").substringBefore('"')
|
||||||
|
val form = MultipartBody.Builder()
|
||||||
|
.setType(MultipartBody.FORM)
|
||||||
|
.addFormDataPart("action", action)
|
||||||
|
.addFormDataPart("key", key)
|
||||||
|
.addFormDataPart("action_token", "")
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val headers = headersBuilder().set("x-token", url.toHttpUrl().host).build()
|
||||||
|
|
||||||
|
val req = client.newCall(POST(url.replace("/file/", newPath), headers, form)).execute()
|
||||||
|
return runCatching {
|
||||||
|
json.decodeFromString<DriveLeechDirect>(req.use { it.body.string() }).url
|
||||||
|
}.getOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
private fun extractGDriveLink(mediaUrl: String, quality: String): List<Video> {
|
private fun extractGDriveLink(mediaUrl: String, quality: String): List<Video> {
|
||||||
val tokenClient = client.newBuilder().addInterceptor(TokenInterceptor()).build()
|
val neoUrl = getDirectLink(mediaUrl) ?: mediaUrl
|
||||||
val response = tokenClient.newCall(GET(mediaUrl)).execute().use { it.asJsoup() }
|
val response = client.newCall(GET(neoUrl)).execute().use { it.asJsoup() }
|
||||||
val gdBtn = response.selectFirst("div.card-body a.btn")!!
|
val gdBtn = response.selectFirst("div.card-body a.btn")!!
|
||||||
val gdLink = gdBtn.attr("href")
|
val gdLink = gdBtn.attr("href")
|
||||||
val sizeMatch = SIZE_REGEX.find(gdBtn.text())
|
val sizeMatch = SIZE_REGEX.find(gdBtn.text())
|
||||||
@ -345,6 +375,9 @@ class AnimeFlix : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
val name: String,
|
val name: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class DriveLeechDirect(val url: String? = null)
|
||||||
|
|
||||||
// From Dopebox
|
// From Dopebox
|
||||||
private inline fun <A, B> Iterable<A>.parallelMap(crossinline f: suspend (A) -> B): List<B> =
|
private inline fun <A, B> Iterable<A>.parallelMap(crossinline f: suspend (A) -> B): List<B> =
|
||||||
runBlocking {
|
runBlocking {
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
package eu.kanade.tachiyomi.animeextension.en.animeflix
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Application
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.webkit.JavascriptInterface
|
|
||||||
import android.webkit.WebView
|
|
||||||
import android.webkit.WebViewClient
|
|
||||||
import eu.kanade.tachiyomi.network.GET
|
|
||||||
import okhttp3.Interceptor
|
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.Response
|
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
|
||||||
import java.util.concurrent.CountDownLatch
|
|
||||||
|
|
||||||
class TokenInterceptor : Interceptor {
|
|
||||||
|
|
||||||
private val context = Injekt.get<Application>()
|
|
||||||
private val handler by lazy { Handler(Looper.getMainLooper()) }
|
|
||||||
|
|
||||||
class JsObject(private val latch: CountDownLatch, var payload: String = "") {
|
|
||||||
@JavascriptInterface
|
|
||||||
fun passPayload(passedPayload: String) {
|
|
||||||
payload = passedPayload
|
|
||||||
latch.countDown()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun intercept(chain: Interceptor.Chain): Response {
|
|
||||||
val originalRequest = chain.request()
|
|
||||||
|
|
||||||
val newRequest = resolveWithWebView(originalRequest) ?: originalRequest
|
|
||||||
|
|
||||||
return chain.proceed(newRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SetJavaScriptEnabled")
|
|
||||||
private fun resolveWithWebView(request: Request): Request? {
|
|
||||||
val latch = CountDownLatch(1)
|
|
||||||
|
|
||||||
var webView: WebView? = null
|
|
||||||
|
|
||||||
val origRequestUrl = request.url.toString()
|
|
||||||
|
|
||||||
val jsinterface = JsObject(latch)
|
|
||||||
|
|
||||||
// Get url with token with promise
|
|
||||||
val jsScript = """
|
|
||||||
(async () => {
|
|
||||||
var data = await generate("direct");
|
|
||||||
window.android.passPayload(data.url);
|
|
||||||
})();""".trim()
|
|
||||||
|
|
||||||
val headers = request.headers.toMultimap().mapValues { it.value.getOrNull(0) ?: "" }.toMutableMap()
|
|
||||||
|
|
||||||
handler.post {
|
|
||||||
val webview = WebView(context)
|
|
||||||
webView = webview
|
|
||||||
with(webview.settings) {
|
|
||||||
javaScriptEnabled = true
|
|
||||||
domStorageEnabled = true
|
|
||||||
databaseEnabled = true
|
|
||||||
useWideViewPort = false
|
|
||||||
loadWithOverviewMode = false
|
|
||||||
userAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/109.0"
|
|
||||||
webview.addJavascriptInterface(jsinterface, "android")
|
|
||||||
webview.webViewClient = object : WebViewClient() {
|
|
||||||
override fun onPageFinished(view: WebView?, url: String?) {
|
|
||||||
view?.evaluateJavascript(jsScript) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
webView?.loadUrl(origRequestUrl, headers)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
latch.await()
|
|
||||||
|
|
||||||
handler.post {
|
|
||||||
webView?.stopLoading()
|
|
||||||
webView?.destroy()
|
|
||||||
webView = null
|
|
||||||
}
|
|
||||||
return if (jsinterface.payload.isNotBlank()) GET(jsinterface.payload) else null
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user