feat(en/aniwave,fmovies): Minor improvements (#2402)
* Adds descriptive user-agent for enimax * Aniwave * Don't spam preferences when loading episode list * Make lang preference take precedence, helpful for the (very few) cases where sub and dub have different resolutions available * Fix video name for filemoon
This commit is contained in:
@ -8,7 +8,7 @@ ext {
|
|||||||
extName = 'Aniwave'
|
extName = 'Aniwave'
|
||||||
pkgNameSuffix = 'en.nineanime'
|
pkgNameSuffix = 'en.nineanime'
|
||||||
extClass = '.Aniwave'
|
extClass = '.Aniwave'
|
||||||
extVersionCode = 55
|
extVersionCode = 56
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +63,8 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
add("Referer", "$baseUrl/")
|
add("Referer", "$baseUrl/")
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
|
private val markFiller by lazy { preferences.getBoolean(PREF_MARK_FILLERS_KEY, PREF_MARK_FILLERS_DEFAULT) }
|
||||||
|
|
||||||
// ============================== Popular ===============================
|
// ============================== Popular ===============================
|
||||||
|
|
||||||
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/filter?sort=trending&page=$page", refererHeaders)
|
override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/filter?sort=trending&page=$page", refererHeaders)
|
||||||
@ -177,7 +179,7 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
val dub = if (element.attr("data-dub").toInt().toBoolean()) "Dub" else ""
|
val dub = if (element.attr("data-dub").toInt().toBoolean()) "Dub" else ""
|
||||||
val softSub = if (SOFTSUB_REGEX.find(title) != null) "SoftSub" else ""
|
val softSub = if (SOFTSUB_REGEX.find(title) != null) "SoftSub" else ""
|
||||||
|
|
||||||
val extraInfo = if (element.hasClass("filler") && preferences.getBoolean(PREF_MARK_FILLERS_KEY, PREF_MARK_FILLERS_DEFAULT)) {
|
val extraInfo = if (element.hasClass("filler") && markFiller) {
|
||||||
" • Filler Episode"
|
" • Filler Episode"
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
@ -226,7 +228,7 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
val hosterSelection = preferences.getStringSet(PREF_HOSTER_KEY, PREF_HOSTER_DEFAULT)!!
|
val hosterSelection = preferences.getStringSet(PREF_HOSTER_KEY, PREF_HOSTER_DEFAULT)!!
|
||||||
val typeSelection = preferences.getStringSet(PREF_TYPE_TOGGLE_KEY, PREF_TYPES_TOGGLE_DEFAULT)!!
|
val typeSelection = preferences.getStringSet(PREF_TYPE_TOGGLE_KEY, PREF_TYPES_TOGGLE_DEFAULT)!!
|
||||||
|
|
||||||
return document.select("div.servers > div").parallelMap { elem ->
|
return document.select("div.servers > div").parallelFlatMap { elem ->
|
||||||
val type = elem.attr("data-type").replaceFirstChar { it.uppercase() }
|
val type = elem.attr("data-type").replaceFirstChar { it.uppercase() }
|
||||||
elem.select("li").mapNotNull { serverElement ->
|
elem.select("li").mapNotNull { serverElement ->
|
||||||
val serverId = serverElement.attr("data-link-id")
|
val serverId = serverElement.attr("data-link-id")
|
||||||
@ -237,9 +239,7 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
VideoData(type, serverId, serverName)
|
VideoData(type, serverId, serverName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.flatten()
|
.parallelFlatMap { extractVideo(it, epurl) }
|
||||||
.parallelMap { extractVideo(it, epurl) }
|
|
||||||
.flatten()
|
|
||||||
.ifEmpty { throw Exception("Failed to fetch videos") }
|
.ifEmpty { throw Exception("Failed to fetch videos") }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
val embedLink = utils.callEnimax(parsed.result.url, "decrypt")
|
val embedLink = utils.callEnimax(parsed.result.url, "decrypt")
|
||||||
when (server.serverName) {
|
when (server.serverName) {
|
||||||
"vidplay", "mycloud" -> vidsrcExtractor.videosFromUrl(embedLink, server.serverName, server.type)
|
"vidplay", "mycloud" -> vidsrcExtractor.videosFromUrl(embedLink, server.serverName, server.type)
|
||||||
"filemoon" -> filemoonExtractor.videosFromUrl(embedLink, "Filemoon - ${server.type}")
|
"filemoon" -> filemoonExtractor.videosFromUrl(embedLink, "Filemoon - ${server.type} - ")
|
||||||
"streamtape" -> streamtapeExtractor.videoFromUrl(embedLink, "StreamTape - ${server.type}")?.let(::listOf) ?: emptyList()
|
"streamtape" -> streamtapeExtractor.videoFromUrl(embedLink, "StreamTape - ${server.type}")?.let(::listOf) ?: emptyList()
|
||||||
"mp4upload" -> mp4uploadExtractor.videosFromUrl(embedLink, headers, suffix = " - ${server.type}")
|
"mp4upload" -> mp4uploadExtractor.videosFromUrl(embedLink, headers, suffix = " - ${server.type}")
|
||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
@ -295,9 +295,9 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
val server = preferences.getString(PREF_SERVER_KEY, PREF_SERVER_DEFAULT)!!
|
val server = preferences.getString(PREF_SERVER_KEY, PREF_SERVER_DEFAULT)!!
|
||||||
|
|
||||||
return this.sortedWith(
|
return this.sortedWith(
|
||||||
compareByDescending<Video> { it.quality.contains(quality) }
|
compareByDescending<Video> { it.quality.contains(lang) }
|
||||||
.thenByDescending { it.quality.contains(server, true) }
|
.thenByDescending { it.quality.contains(quality) }
|
||||||
.thenByDescending { it.quality.contains(lang) },
|
.thenByDescending { it.quality.contains(server, true) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,6 +319,11 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
map { async(Dispatchers.Default) { f(it) } }.awaitAll()
|
map { async(Dispatchers.Default) { f(it) } }.awaitAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun <A, B> Iterable<A>.parallelFlatMap(crossinline f: suspend (A) -> Iterable<B>): List<B> =
|
||||||
|
runBlocking {
|
||||||
|
map { async(Dispatchers.Default) { f(it) } }.awaitAll().flatten()
|
||||||
|
}
|
||||||
|
|
||||||
private inline fun <reified T> Response.parseAs(): T {
|
private inline fun <reified T> Response.parseAs(): T {
|
||||||
val responseBody = use { it.body.string() }
|
val responseBody = use { it.body.string() }
|
||||||
return json.decodeFromString(responseBody)
|
return json.decodeFromString(responseBody)
|
||||||
@ -442,6 +447,7 @@ class Aniwave : ConfigurableAnimeSource, ParsedAnimeHttpSource() {
|
|||||||
title = "Mark filler episodes"
|
title = "Mark filler episodes"
|
||||||
setDefaultValue(PREF_MARK_FILLERS_DEFAULT)
|
setDefaultValue(PREF_MARK_FILLERS_DEFAULT)
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
Toast.makeText(screen.context, "Restart Aniyomi to apply new setting.", Toast.LENGTH_LONG).show()
|
||||||
preferences.edit().putBoolean(key, newValue as Boolean).commit()
|
preferences.edit().putBoolean(key, newValue as Boolean).commit()
|
||||||
}
|
}
|
||||||
}.also(screen::addPreference)
|
}.also(screen::addPreference)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.animeextension.en.nineanime
|
package eu.kanade.tachiyomi.animeextension.en.nineanime
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.AppInfo
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
@ -13,6 +14,11 @@ class AniwaveUtils(private val client: OkHttpClient, private val headers: Header
|
|||||||
|
|
||||||
val json: Json by injectLazy()
|
val json: Json by injectLazy()
|
||||||
|
|
||||||
|
private val userAgent = Headers.headersOf(
|
||||||
|
"User-Agent",
|
||||||
|
"Aniyomi/${AppInfo.getVersionName()} (AniWave)",
|
||||||
|
)
|
||||||
|
|
||||||
fun callEnimax(query: String, action: String): String {
|
fun callEnimax(query: String, action: String): String {
|
||||||
return if (action in listOf("rawVizcloud", "rawMcloud")) {
|
return if (action in listOf("rawVizcloud", "rawMcloud")) {
|
||||||
val referer = if (action == "rawVizcloud") "https://vidstream.pro/" else "https://mcloud.to/"
|
val referer = if (action == "rawVizcloud") "https://vidstream.pro/" else "https://mcloud.to/"
|
||||||
@ -27,11 +33,12 @@ class AniwaveUtils(private val client: OkHttpClient, private val headers: Header
|
|||||||
POST(
|
POST(
|
||||||
url = "https://9anime.eltik.net/$action?apikey=aniyomi",
|
url = "https://9anime.eltik.net/$action?apikey=aniyomi",
|
||||||
body = formBody,
|
body = formBody,
|
||||||
|
headers = userAgent,
|
||||||
),
|
),
|
||||||
).execute().parseAs<RawResponse>().rawURL
|
).execute().parseAs<RawResponse>().rawURL
|
||||||
} else {
|
} else {
|
||||||
client.newCall(
|
client.newCall(
|
||||||
GET("https://9anime.eltik.net/$action?query=$query&apikey=aniyomi"),
|
GET("https://9anime.eltik.net/$action?query=$query&apikey=aniyomi", userAgent),
|
||||||
).execute().use {
|
).execute().use {
|
||||||
val body = it.body.string()
|
val body = it.body.string()
|
||||||
when (action) {
|
when (action) {
|
||||||
|
@ -8,7 +8,7 @@ ext {
|
|||||||
extName = 'FMovies'
|
extName = 'FMovies'
|
||||||
pkgNameSuffix = 'en.fmovies'
|
pkgNameSuffix = 'en.fmovies'
|
||||||
extClass = '.FMovies'
|
extClass = '.FMovies'
|
||||||
extVersionCode = 12
|
extVersionCode = 13
|
||||||
libVersion = '13'
|
libVersion = '13'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package eu.kanade.tachiyomi.animeextension.en.fmovies
|
package eu.kanade.tachiyomi.animeextension.en.fmovies
|
||||||
|
|
||||||
|
import eu.kanade.tachiyomi.AppInfo
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.POST
|
import eu.kanade.tachiyomi.network.POST
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
@ -15,6 +16,11 @@ class FMoviesHelper(private val client: OkHttpClient, private val headers: Heade
|
|||||||
|
|
||||||
private val json: Json by injectLazy()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
|
private val userAgent = Headers.headersOf(
|
||||||
|
"User-Agent",
|
||||||
|
"Aniyomi/${AppInfo.getVersionName()} (FMovies)",
|
||||||
|
)
|
||||||
|
|
||||||
fun getVrf(id: String): String {
|
fun getVrf(id: String): String {
|
||||||
val url = API_URL.newBuilder().apply {
|
val url = API_URL.newBuilder().apply {
|
||||||
addPathSegment("fmovies-vrf")
|
addPathSegment("fmovies-vrf")
|
||||||
@ -22,7 +28,7 @@ class FMoviesHelper(private val client: OkHttpClient, private val headers: Heade
|
|||||||
addQueryParameter("apikey", API_KEY)
|
addQueryParameter("apikey", API_KEY)
|
||||||
}.build().toString()
|
}.build().toString()
|
||||||
|
|
||||||
return client.newCall(GET(url)).execute().parseAs<VrfResponse>().let {
|
return client.newCall(GET(url, userAgent)).execute().parseAs<VrfResponse>().let {
|
||||||
URLEncoder.encode(it.url, "utf-8")
|
URLEncoder.encode(it.url, "utf-8")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,7 +40,7 @@ class FMoviesHelper(private val client: OkHttpClient, private val headers: Heade
|
|||||||
addQueryParameter("apikey", API_KEY)
|
addQueryParameter("apikey", API_KEY)
|
||||||
}.build().toString()
|
}.build().toString()
|
||||||
|
|
||||||
return client.newCall(GET(url)).execute().parseAs<VrfResponse>().url
|
return client.newCall(GET(url, userAgent)).execute().parseAs<VrfResponse>().url
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getVidSrc(query: String, host: String): String {
|
fun getVidSrc(query: String, host: String): String {
|
||||||
@ -53,7 +59,7 @@ class FMoviesHelper(private val client: OkHttpClient, private val headers: Heade
|
|||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
return client.newCall(
|
return client.newCall(
|
||||||
POST(url, body = body),
|
POST(url, body = body, headers = userAgent),
|
||||||
).execute().parseAs<RawResponse>().rawURL
|
).execute().parseAs<RawResponse>().rawURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user