diff --git a/src/en/kickassanime/build.gradle b/src/en/kickassanime/build.gradle index 173bb1a0a..053b5dabb 100644 --- a/src/en/kickassanime/build.gradle +++ b/src/en/kickassanime/build.gradle @@ -1,15 +1,17 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' +apply plugin: 'kotlinx-serialization' ext { extName = 'KickAssAnime' pkgNameSuffix = 'en.kickassanime' extClass = '.KickAssAnime' - extVersionCode = 13 + extVersionCode = 14 libVersion = '13' } dependencies { + compileOnly libs.bundles.coroutines implementation(project(':lib-streamsb-extractor')) implementation(project(':lib-dood-extractor')) } diff --git a/src/en/kickassanime/src/eu/kanade/tachiyomi/animeextension/en/kickassanime/KickAssAnime.kt b/src/en/kickassanime/src/eu/kanade/tachiyomi/animeextension/en/kickassanime/KickAssAnime.kt index b24be1183..24da2229b 100644 --- a/src/en/kickassanime/src/eu/kanade/tachiyomi/animeextension/en/kickassanime/KickAssAnime.kt +++ b/src/en/kickassanime/src/eu/kanade/tachiyomi/animeextension/en/kickassanime/KickAssAnime.kt @@ -19,7 +19,13 @@ import eu.kanade.tachiyomi.lib.doodextractor.DoodExtractor import eu.kanade.tachiyomi.lib.streamsbextractor.StreamSBExtractor import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.util.asJsoup +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.runBlocking import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonArray @@ -29,6 +35,7 @@ import kotlinx.serialization.json.jsonArray import kotlinx.serialization.json.jsonObject import kotlinx.serialization.json.jsonPrimitive import okhttp3.Headers +import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response @@ -45,7 +52,12 @@ class KickAssAnime : ConfigurableAnimeSource, AnimeHttpSource() { override val name = "KickAssAnime" - override val baseUrl by lazy { preferences.getString("preferred_domain", "https://www2.kickassanime.ro")!! } + override val baseUrl by lazy { + preferences.getString( + "preferred_domain", + "https://www2.kickassanime.ro" + )!! + } override val lang = "en" @@ -67,24 +79,30 @@ class KickAssAnime : ConfigurableAnimeSource, AnimeHttpSource() { // Add non working server names here private val deadServers = listOf( - "BETA-SERVER", "BETASERVER1", "BETASERVER3", "DEVSTREAM", - "THETA-ORIGINAL-V4", "DAILYMOTION", "KICKASSANIME1" + "BETASERVER1", "BETASERVER3", "DEVSTREAM", + "THETA-ORIGINAL-V4", "KICKASSANIME1" ) private val workingServers = arrayOf( - "StreamSB", "PINK-BIRD", "Doodstream", "MAVERICKKI", + "StreamSB", "PINK-BIRD", "Doodstream", "MAVERICKKI", "BETA-SERVER", "DAILYMOTION", "BETAPLAYER", "Vidstreaming", "SAPPHIRE-DUCK", "KICKASSANIMEV2", "ORIGINAL-QUALITY-V2" ) - override fun popularAnimeRequest(page: Int): Request = GET("$baseUrl/api/get_anime_list/all/$page") + override fun popularAnimeRequest(page: Int): Request = + GET("$baseUrl/api/get_anime_list/all/$page") override fun popularAnimeParse(response: Response): AnimesPage { val responseObject = json.decodeFromString(response.body!!.string()) val data = responseObject["data"]!!.jsonArray val animes = data.map { item -> SAnime.create().apply { - setUrlWithoutDomain(item.jsonObject["slug"]!!.jsonPrimitive.content.substringBefore("/episode")) - thumbnail_url = "$baseUrl/uploads/" + item.jsonObject["poster"]!!.jsonPrimitive.content + setUrlWithoutDomain( + item.jsonObject["slug"]!!.jsonPrimitive.content.substringBefore( + "/episode" + ) + ) + thumbnail_url = + "$baseUrl/uploads/" + item.jsonObject["poster"]!!.jsonPrimitive.content title = item.jsonObject["name"]!!.jsonPrimitive.content } } @@ -149,35 +167,45 @@ class KickAssAnime : ConfigurableAnimeSource, AnimeHttpSource() { val resp = client.newCall(GET(link)).execute() val sources = getVideoSource(resp.asJsoup()) - sources.forEach { source -> - when (source.jsonObject["name"]!!.jsonPrimitive.content) { - in deadServers -> {} - "BETAPLAYER" -> { - videoList.addAll( - extractBetaVideo( - source.jsonObject["src"]!!.jsonPrimitive.content, - source.jsonObject["name"]!!.jsonPrimitive.content - ) - ) - } - "KICKASSANIMEV2", "ORIGINAL-QUALITY-V2" -> { - videoList.addAll( - extractKickasssVideo( - source.jsonObject["src"]!!.jsonPrimitive.content, - source.jsonObject["name"]!!.jsonPrimitive.content - ) - ) - } - else -> { - videoList.addAll( - extractVideo( - source.jsonObject["src"]!!.jsonPrimitive.content, - source.jsonObject["name"]!!.jsonPrimitive.content - ) - ) - } - } - } + videoList.addAll( + sources.parallelMap { source -> + runCatching { + when (source.jsonObject["name"]!!.jsonPrimitive.content) { + in deadServers -> { null } + "SAPPHIRE-DUCK" -> { + extractSapphireVideo( + source.jsonObject["src"]!!.jsonPrimitive.content, + source.jsonObject["name"]!!.jsonPrimitive.content + ) + } + "BETAPLAYER" -> { + extractBetaVideo( + source.jsonObject["src"]!!.jsonPrimitive.content, + source.jsonObject["name"]!!.jsonPrimitive.content + ) + } + "KICKASSANIMEV2", "ORIGINAL-QUALITY-V2", "BETA-SERVER" -> { + extractKickasssVideo( + source.jsonObject["src"]!!.jsonPrimitive.content, + source.jsonObject["name"]!!.jsonPrimitive.content + ) + } + "DAILYMOTION" -> { + extractDailymotion( + source.jsonObject["src"]!!.jsonPrimitive.content, + source.jsonObject["name"]!!.jsonPrimitive.content + ) + } + else -> { + extractVideo( + source.jsonObject["src"]!!.jsonPrimitive.content, + source.jsonObject["name"]!!.jsonPrimitive.content + ) + } + } + }.getOrNull() + }.filterNotNull().flatten() + ) } } return videoList @@ -186,13 +214,13 @@ class KickAssAnime : ConfigurableAnimeSource, AnimeHttpSource() { private fun extractVideo(serverLink: String, server: String): List