diff --git a/app/src/main/java/com/lagradost/cloudstream3/extractors/Streamlare.kt b/app/src/main/java/com/lagradost/cloudstream3/extractors/Streamlare.kt new file mode 100644 index 00000000..396327ba --- /dev/null +++ b/app/src/main/java/com/lagradost/cloudstream3/extractors/Streamlare.kt @@ -0,0 +1,60 @@ +package com.lagradost.cloudstream3.extractors + +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.app +import com.lagradost.cloudstream3.utils.ExtractorApi +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.Qualities +import com.lagradost.nicehttp.RequestBodyTypes +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.RequestBody.Companion.toRequestBody + + +class Streamlare : Slmaxed() { + override val mainUrl = "https://streamlare.com/" +} + +open class Slmaxed : ExtractorApi() { + override val name = "Streamlare" + override val mainUrl = "https://slmaxed.com/" + override val requiresReferer = true + + // https://slmaxed.com/e/oLvgezw3LjPzbp8E -> oLvgezw3LjPzbp8E + val embedRegex = Regex("""/e/([^/]*)""") + + + data class JsonResponse( + @JsonProperty val status: String? = null, + @JsonProperty val message: String? = null, + @JsonProperty val type: String? = null, + @JsonProperty val token: String? = null, + @JsonProperty val result: Map? = null + ) + + data class Result( + @JsonProperty val label: String? = null, + @JsonProperty val file: String? = null, + @JsonProperty val type: String? = null + ) + + override suspend fun getUrl(url: String, referer: String?): List? { + val id = embedRegex.find(url)!!.groupValues[1] + val json = app.post( + "${mainUrl}api/video/stream/get", + requestBody = """{"id":"$id"}""".toRequestBody(RequestBodyTypes.JSON.toMediaTypeOrNull()) + ).parsed() + return json.result?.mapNotNull { + it.value.let { result -> + ExtractorLink( + this.name, + this.name, + result.file ?: return@mapNotNull null, + url, + result.label?.replace("p", "", ignoreCase = true)?.trim()?.toIntOrNull() + ?: Qualities.Unknown.value, + isM3u8 = result.type?.contains("hls", ignoreCase = true) == true + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt index 5536906d..aba04ad5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/movieproviders/SflixProvider.kt @@ -16,12 +16,15 @@ import com.lagradost.cloudstream3.utils.Coroutines.ioSafe import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.M3u8Helper import com.lagradost.cloudstream3.utils.getQualityFromName +import com.lagradost.cloudstream3.utils.loadExtractor import com.lagradost.nicehttp.NiceResponse import kotlinx.coroutines.delay import okhttp3.RequestBody.Companion.toRequestBody import org.jsoup.Jsoup import org.jsoup.nodes.Element import java.net.URI +import java.util.* +import kotlin.collections.ArrayList import kotlin.system.measureTimeMillis open class SflixProvider : MainAPI() { @@ -342,7 +345,11 @@ open class SflixProvider : MainAPI() { val extractorData = "https://ws11.rabbitstream.net/socket.io/?EIO=4&transport=polling" - extractRabbitStream(iframeLink, subtitleCallback, callback, false) { it } + if (iframeLink.contains("streamlare", ignoreCase = true)) { + loadExtractor(iframeLink, null).forEach(callback) + } else { + extractRabbitStream(iframeLink, subtitleCallback, callback, false) { it } + } } } @@ -571,18 +578,14 @@ open class SflixProvider : MainAPI() { } } + // Only scrape servers with these names fun String?.isValidServer(): Boolean { - if (this.isNullOrEmpty()) return false - if (this.equals("UpCloud", ignoreCase = true) || this.equals( - "Vidcloud", - ignoreCase = true - ) || this.equals("RapidStream", ignoreCase = true) - ) return true - return false + val list = listOf("upcloud", "vidcloud", "streamlare") + return list.contains(this?.lowercase(Locale.ROOT)) } // For re-use in Zoro - fun Sources.toExtractorLink( + private fun Sources.toExtractorLink( caller: MainAPI, name: String, extractorData: String? = null, diff --git a/app/src/main/java/com/lagradost/cloudstream3/network/WebViewResolver.kt b/app/src/main/java/com/lagradost/cloudstream3/network/WebViewResolver.kt index c6c02e6f..7bd66ce5 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/network/WebViewResolver.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/network/WebViewResolver.kt @@ -33,6 +33,17 @@ class WebViewResolver(val interceptUrl: Regex, val additionalUrls: List = } } + suspend fun resolveUsingWebView( + url: String, + referer: String? = null, + method: String = "GET", + requestCallBack: (Request) -> Boolean = { false }, + ) : Pair> { + return resolveUsingWebView( + requestCreator(method, url, referer = referer), requestCallBack + ) + } + /** * @param requestCallBack asynchronously return matched requests by either interceptUrl or additionalUrls. If true, destroy WebView. * @return the final request (by interceptUrl) and all the collected urls (by additionalUrls). diff --git a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt index 1bb6dbb0..d60b157e 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/utils/ExtractorApi.kt @@ -294,6 +294,7 @@ val extractorApis: Array = arrayOf( YoutubeExtractor(), YoutubeShortLinkExtractor(), + Streamlare() ) fun getExtractorApiFromName(name: String): ExtractorApi {