diff --git a/GoodPorn/src/main/kotlin/com/hexated/GoodPorn.kt b/GoodPorn/src/main/kotlin/com/hexated/GoodPorn.kt index 5b10f331..3c7ef280 100644 --- a/GoodPorn/src/main/kotlin/com/hexated/GoodPorn.kt +++ b/GoodPorn/src/main/kotlin/com/hexated/GoodPorn.kt @@ -3,6 +3,8 @@ package com.hexated import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.LoadResponse.Companion.addActors import com.lagradost.cloudstream3.utils.* +import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.AppUtils.toJson import org.jsoup.nodes.Element import java.util.* @@ -50,7 +52,8 @@ class GoodPorn : MainAPI() { val title = this.selectFirst("strong.title")?.text() ?: return null val href = fixUrl(this.selectFirst("a")!!.attr("href")) val posterUrl = fixUrlNull(this.select("div.img > img").attr("data-original")) - return newMovieSearchResponse(title, href, TvType.Movie) { + val previewUrl = fixUrlNull(this.select("div.img > img").attr("data-preview")) + return newMovieSearchResponse(title, LoadData(href, previewUrl).toJson(), TvType.Movie) { this.posterUrl = posterUrl } @@ -76,7 +79,8 @@ class GoodPorn : MainAPI() { } override suspend fun load(url: String): LoadResponse { - val document = app.get(url).document + val res = parseJson(url) + val document = app.get(res.url.toString()).document val title = document.selectFirst("div.headline > h1")?.text()?.trim().toString() val poster = @@ -89,12 +93,19 @@ class GoodPorn : MainAPI() { it.toSearchResult() } - return newMovieLoadResponse(title, url, TvType.Movie, url) { + return newMovieLoadResponse(title, url, TvType.Movie, LoadData(res.url, res.trailer).toJson()) { this.posterUrl = poster this.plot = description this.tags = tags addActors(actors) this.recommendations = recommendations + this.trailers = mutableListOf( + TrailerData( + res.trailer.toString(), + referer = "$mainUrl/", + raw = true + ) + ) } } @@ -104,8 +115,8 @@ class GoodPorn : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - - val document = app.get(data).document + val res = parseJson(data) + val document = app.get(res.url.toString()).document document.select("div.info div:last-child a").map { res -> callback.invoke( ExtractorLink( @@ -121,6 +132,22 @@ class GoodPorn : MainAPI() { ) } + callback.invoke( + ExtractorLink( + "Preview", + "Preview", + res.trailer.toString(), + referer = data, + quality = Qualities.Unknown.value, + headers = mapOf("Range" to "bytes=0-"), + ) + ) + return true } + + data class LoadData( + val url: String? = null, + val trailer: String? = null, + ) } \ No newline at end of file diff --git a/SoraStream/build.gradle.kts b/SoraStream/build.gradle.kts index 3dc70bd1..c6830e6f 100644 --- a/SoraStream/build.gradle.kts +++ b/SoraStream/build.gradle.kts @@ -1,12 +1,12 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { language = "en" // All of these properties are optional, you can safely remove them - description = "Experimental" + description = "#2 best extention based on MultiAPI" authors = listOf("Hexated", "Sora") /** diff --git a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt index 8cd2a1fd..3a274b6b 100644 --- a/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt +++ b/SoraStream/src/main/kotlin/com/hexated/SoraStream.kt @@ -4,6 +4,7 @@ import android.util.Log import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.metaproviders.TmdbProvider +import com.lagradost.cloudstream3.utils.AppUtils import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.ExtractorLink @@ -217,6 +218,41 @@ class SoraStream : TmdbProvider() { } } + private suspend fun invokeLocalSources( + url: String, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ) { + val doc = app.get(url).document + val script = doc.select("script").find { it.data().contains("\"sources\":[") }?.data() + val sourcesData = script?.substringAfter("\"sources\":[")?.substringBefore("],") + val subData = script?.substringAfter("\"subtitles\":[")?.substringBefore("],") + + AppUtils.tryParseJson>("[$sourcesData]")?.map { source -> + callback.invoke( + ExtractorLink( + this.name, + this.name, + source.url ?: return@map null, + "$mainServerAPI/", + source.quality?.toIntOrNull() ?: Qualities.Unknown.value, + isM3u8 = source.isM3U8, + headers = mapOf("Origin" to mainServerAPI) + ) + ) + } + + AppUtils.tryParseJson>("[$subData]")?.map { sub -> + subtitleCallback.invoke( + SubtitleFile( + sub.lang.toString(), + sub.url ?: return@map null + ) + ) + } + + } + override suspend fun loadLinks( data: String, isCasting: Boolean, @@ -242,7 +278,8 @@ class SoraStream : TmdbProvider() { ).parsedSafe() if (json?.sources.isNullOrEmpty()) { - invokeTwoEmbed(res.id, res.season, res.episode, subtitleCallback, callback) +// invokeTwoEmbed(res.id, res.season, res.episode, subtitleCallback, callback) + invokeLocalSources(referer, subtitleCallback, callback) } else { json?.sources?.map { source -> callback.invoke(