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:
Secozzi
2023-10-20 18:49:47 +00:00
committed by GitHub
parent 86fa5b7ec1
commit d56976e5de
5 changed files with 34 additions and 15 deletions

View File

@ -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'
} }

View File

@ -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)

View File

@ -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) {

View File

@ -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'
} }

View File

@ -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
} }