From ebb89face331fccb155c2ade75e2df768eff2362 Mon Sep 17 00:00:00 2001 From: hexated Date: Fri, 23 Dec 2022 19:02:01 +0700 Subject: [PATCH] :tada: ruin sora with dub --- .../main/kotlin/com/hexated/SoraExtractor.kt | 89 +++++++++++-------- .../src/main/kotlin/com/hexated/SoraStream.kt | 9 +- build.gradle.kts | 9 +- 3 files changed, 58 insertions(+), 49 deletions(-) diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt index efeb2ab6..7af1aaed 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraExtractor.kt @@ -1014,31 +1014,36 @@ object SoraExtractor : SoraStream() { val episodeId = app.get("$consumetAnilistAPI/info/$anilistId?provider=zoro") .parsedSafe()?.episodes?.find { it.number == episode - }?.id ?: return + }?.id?.substringBeforeLast("$") ?: return - val sources = app.get("$consumetZoroAPI/watch?episodeId=$episodeId", timeout = 120L) - .parsedSafe() ?: return + listOf( + "$episodeId\$sub" to "Subbed", + "$episodeId\$dub" to "English Dub", + ).apmap { (id, type) -> + val sources = app.get("$consumetZoroAPI/watch?episodeId=$id") + .parsedSafe() ?: return@apmap null - sources.sources?.map { - callback.invoke( - ExtractorLink( - "Zoro", - "Zoro", - it.url ?: return@map null, - "", - getQualityFromName(it.quality), - it.isM3U8 ?: true + sources.sources?.map sources@{ + callback.invoke( + ExtractorLink( + "Zoro [$type]", + "Zoro [$type]", + it.url ?: return@sources null, + "", + getQualityFromName(it.quality), + it.isM3U8 ?: true + ) ) - ) - } + } - sources.subtitles?.map { - subtitleCallback.invoke( - SubtitleFile( - it.lang ?: "", - it.url ?: return@map null + sources.subtitles?.map subtitles@{ + subtitleCallback.invoke( + SubtitleFile( + it.lang ?: "", + it.url ?: return@subtitles null + ) ) - ) + } } @@ -1476,30 +1481,36 @@ object SoraExtractor : SoraStream() { val detail = app.get("$consumetCrunchyrollAPI/info?id=${id.id}&mediaType=series").text val episodeId = tryParseJson(detail)?.episodes?.filter { - (it.number == episode || it.title.equals(epsTitle, true)) && it.type == "Subbed" - }?.map { it.id }?.getOrNull(season?.minus(1) ?: 0) ?: return - - val json = app.get("$consumetCrunchyrollAPI/watch?episodeId=$episodeId&format=srt") - .parsedSafe() - - json?.sources?.map source@{ source -> - M3u8Helper.generateM3u8( - "Crunchyroll", - source.url ?: return@source null, - "", - ).forEach(callback) + (it.number == episode || it.title.equals(epsTitle, true)) + }?.let { eps -> + listOf(eps.filter { it.type == "Subbed" }.map { it.id } + .getOrNull(season?.minus(1) ?: 0) to "Subbed", + eps.filter { it.type == "English Dub" }.map { it.id } + .getOrNull(season?.minus(1) ?: 0) to "English Dub") } - json?.subtitles?.map subtitle@{ sub -> - subtitleCallback.invoke( - SubtitleFile( - sub.lang?.replace(Regex("\\[\\S+]"), "")?.trim() ?: "", - sub.url ?: return@subtitle null + episodeId?.apmap { (id, type) -> + val json = app.get("$consumetCrunchyrollAPI/watch?episodeId=${id ?: return@apmap null}&format=srt") + .parsedSafe() + + json?.sources?.map source@{ source -> + M3u8Helper.generateM3u8( + "Crunchyroll [$type]", + source.url ?: return@source null, + "", + ).forEach(callback) + } + + json?.subtitles?.map subtitle@{ sub -> + subtitleCallback.invoke( + SubtitleFile( + sub.lang?.replace(Regex("\\[\\S+]"), "")?.trim() ?: "", + sub.url ?: return@subtitle null + ) ) - ) + } } - } } diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index e1ae6536..bd7ca745 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -208,12 +208,11 @@ open class SoraStream : TmdbProvider() { ?.randomOrNull() return if (type == TvType.TvSeries) { - val episodes = mutableListOf() val lastSeason = res.seasons?.lastOrNull()?.seasonNumber - res.seasons?.apmap { season -> + val episodes = res.seasons?.mapNotNull { season -> app.get("$tmdbAPI/${data.type}/${data.id}/season/${season.seasonNumber}?api_key=$apiKey") .parsedSafe()?.episodes?.map { eps -> - episodes.add(Episode( + Episode( LinkData( data.id, res.external_ids?.imdb_id, @@ -236,9 +235,9 @@ open class SoraStream : TmdbProvider() { description = eps.overview ).apply { this.addDate(eps.airDate) - }) + } } - } + }?.flatten() ?: listOf() newTvSeriesLoadResponse( title, url, diff --git a/build.gradle.kts b/build.gradle.kts index 1330ebd8..f32d7c85 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,5 @@ import com.lagradost.cloudstream3.gradle.CloudstreamExtension import com.android.build.gradle.BaseExtension -import java.util.Properties buildscript { repositories { @@ -43,11 +42,11 @@ subprojects { } android { - compileSdkVersion(32) + compileSdkVersion(33) defaultConfig { minSdk = 21 - targetSdk = 32 + targetSdk = 33 // val properties = Properties() // properties.load(project.rootProject.file("local.properties").inputStream()) @@ -84,8 +83,8 @@ subprojects { // but you dont need to include any of them if you dont need them // https://github.com/recloudstream/cloudstream/blob/master/app/build.gradle implementation(kotlin("stdlib")) // adds standard kotlin features, like listOf, mapOf etc - implementation("com.github.Blatzar:NiceHttp:0.3.5") // http library - implementation("org.jsoup:jsoup:1.13.1") // html parser + implementation("com.github.Blatzar:NiceHttp:0.4.1") // http library + implementation("org.jsoup:jsoup:1.15.3") // html parser implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.1") implementation("io.karn:khttp-android:0.1.2") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4") // html parser