From bea5a27196cb68abe28f9d8abd427374b609b6fe Mon Sep 17 00:00:00 2001 From: Zaw <42999156+ImZaw@users.noreply.github.com> Date: Sat, 26 Nov 2022 19:33:53 +0300 Subject: [PATCH 1/6] ninegoal --- NineGoalProvider/build.gradle.kts | 12 ++ NineGoalProvider/src/main/AndroidManifest.xml | 2 + .../main/kotlin/com/ninegoal/9GoalPlugin.kt | 12 ++ .../main/kotlin/com/ninegoal/9GoalProvider.kt | 135 ++++++++++++++++++ 4 files changed, 161 insertions(+) create mode 100644 NineGoalProvider/build.gradle.kts create mode 100644 NineGoalProvider/src/main/AndroidManifest.xml create mode 100644 NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalPlugin.kt create mode 100644 NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt diff --git a/NineGoalProvider/build.gradle.kts b/NineGoalProvider/build.gradle.kts new file mode 100644 index 0000000..fe7c8d0 --- /dev/null +++ b/NineGoalProvider/build.gradle.kts @@ -0,0 +1,12 @@ +version = 1 + +cloudstream { + description = "" + authors = listOf( "ImZaw" ) + + status = 1 + + tvTypes = listOf( "Live" ) + + iconUrl = "https://www.google.com/s2/favicons?domain=9goaltv.to&sz=%size%" +} \ No newline at end of file diff --git a/NineGoalProvider/src/main/AndroidManifest.xml b/NineGoalProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..263556b --- /dev/null +++ b/NineGoalProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalPlugin.kt b/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalPlugin.kt new file mode 100644 index 0000000..c9a5e9e --- /dev/null +++ b/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalPlugin.kt @@ -0,0 +1,12 @@ +package com.ninegoal + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class NineGoalPlugin: Plugin() { + override fun load(context: Context) { + registerMainAPI(NineGoal()) + } +} \ No newline at end of file diff --git a/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt b/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt new file mode 100644 index 0000000..73a8397 --- /dev/null +++ b/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt @@ -0,0 +1,135 @@ +package com.ninegoal + +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.Qualities +import java.util.* + +data class Data ( + @JsonProperty("id" ) var id : String? = null, + @JsonProperty("name" ) var name : String? = null, + @JsonProperty("slug" ) var slug : String? = null, + @JsonProperty("home" ) var home : Home? = Home(), + @JsonProperty("away" ) var away : Away? = Away(), + @JsonProperty("scores" ) var scores : Scores? = Scores(), + @JsonProperty("is_live" ) var isLive : Boolean? = null +) +data class Home ( + @JsonProperty("model_id" ) var modelId : String? = null, + @JsonProperty("name" ) var name : String? = null, + @JsonProperty("slug" ) var slug : String? = null, + @JsonProperty("logo" ) var logo : String? = null +) +data class Away ( + @JsonProperty("model_id" ) var modelId : String? = null, + @JsonProperty("name" ) var name : String? = null, + @JsonProperty("slug" ) var slug : String? = null, + @JsonProperty("logo" ) var logo : String? = null +) +data class Scores ( + @JsonProperty("home" ) var home : Int? = null, + @JsonProperty("away" ) var away : Int? = null +) +data class matchesJSON ( + @JsonProperty("data" ) var data : ArrayList = arrayListOf() +) +data class oneMatch ( + @JsonProperty("data" ) var data : Data? = Data() +) + + +data class PlayUrls ( + @JsonProperty("name" ) var name : String? = null, + @JsonProperty("cdn" ) var cdn : String? = null, + @JsonProperty("slug" ) var slug : String? = null, + @JsonProperty("url" ) var url : String? = null, + @JsonProperty("role" ) var role : String? = null +) +data class sourceData ( + @JsonProperty("id" ) var id : String? = null, + @JsonProperty("name" ) var name : String? = null, + @JsonProperty("slug" ) var slug : String? = null, + @JsonProperty("has_lineup" ) var hasLineup : Boolean? = null, + @JsonProperty("has_tracker" ) var hasTracker : Boolean? = null, + @JsonProperty("play_urls" ) var playUrls : ArrayList = arrayListOf() +) +data class sourcesJSON ( + @JsonProperty("data" ) var data : sourceData? = sourceData() +) +class NineGoal : MainAPI() { + override var mainUrl = "https://9goaltv.to" + override var name = "9Goal" + override var lang = "en" + override val hasDownloadSupport = false + override val hasMainPage = true + override val supportedTypes = setOf( + TvType.Live + ) + + private fun String.getDomainFromUrl(): String? { + return Regex("""^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n\?\=]+)""").find(this)?.groupValues?.firstOrNull() + } + + override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { + val doc = app.get(mainUrl).document + val apiUrl = doc.select("head > script").first()?.html()?.substringAfter("window.api_base_url = \"")?.substringBefore("\";") + val matchesData = parseJson(app.get("$apiUrl/v1/match/featured").text) + val liveHomePageList = matchesData.data.filter { it.isLive == true }.map { + LiveSearchResponse( + it.name.toString(), + apiUrl + "/v1/match/" + it.id, + this@NineGoal.name, + TvType.Live, + "https://img.zr5.repl.co/vs?title=${it.name}&home=${it.home?.logo}&away=${it.away?.logo}&live=true", + ) + } + val featuredHomePageList = matchesData.data.filter { it.isLive == false }.map { + LiveSearchResponse( + it.name.toString(), + apiUrl + "/v1/match/" + it.id, + this@NineGoal.name, + TvType.Live, + "https://img.zr5.repl.co/vs?title=${it.name}&home=${it.home?.logo}&away=${it.away?.logo}", + ) + } + return HomePageResponse( + arrayListOf( + HomePageList("Live", liveHomePageList, isHorizontalImages = true), + HomePageList("Featured", featuredHomePageList, isHorizontalImages = true) + ) + ) + } + + override suspend fun load(url: String): LoadResponse { + val json = parseJson(app.get(url).text).data + return LiveStreamLoadResponse( + json?.name.toString(), + url, + this.name, + "$url/stream", + ) + } + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + val sourcesData = parseJson(app.get(data).text).data + sourcesData?.playUrls?.apmap { + callback.invoke( + ExtractorLink( + this.name, + "${this.name} ${it.name} - ${sourcesData.name}", + it.url.toString(), + fixUrl(it.url?.getDomainFromUrl().toString()), + Qualities.Unknown.value, + isM3u8 = true, + ) + ) + } + return true + } +} From b25de372c5bbf9c25d18d576688ef623504c9c05 Mon Sep 17 00:00:00 2001 From: Zaw <42999156+ImZaw@users.noreply.github.com> Date: Sat, 26 Nov 2022 20:21:57 +0300 Subject: [PATCH 2/6] logo didnt work wtf anyways logo kekw (#53) Co-authored-by: Cloudburst <18114966+C10udburst@users.noreply.github.com> --- NineGoalProvider/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NineGoalProvider/build.gradle.kts b/NineGoalProvider/build.gradle.kts index fe7c8d0..9067683 100644 --- a/NineGoalProvider/build.gradle.kts +++ b/NineGoalProvider/build.gradle.kts @@ -8,5 +8,5 @@ cloudstream { tvTypes = listOf( "Live" ) - iconUrl = "https://www.google.com/s2/favicons?domain=9goaltv.to&sz=%size%" -} \ No newline at end of file + iconUrl = "https://media.discordapp.net/attachments/1027568249900109875/1046110428402561025/JK8J1KX.png?width=%size%&height=%size%" +} From e9d0a83d8094c7126522d78e6ea28abdb23450d6 Mon Sep 17 00:00:00 2001 From: Zaw <42999156+ImZaw@users.noreply.github.com> Date: Sat, 26 Nov 2022 23:43:53 +0300 Subject: [PATCH 3/6] ninegoal fix access denied urls (#55) * ninegoal * kekw logo * Update build.gradle.kts * kekw * Update build.gradle.kts Co-authored-by: Cloudburst <18114966+C10udburst@users.noreply.github.com> --- NineGoalProvider/build.gradle.kts | 2 +- .../src/main/kotlin/com/ninegoal/9GoalProvider.kt | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/NineGoalProvider/build.gradle.kts b/NineGoalProvider/build.gradle.kts index 9067683..9fb7518 100644 --- a/NineGoalProvider/build.gradle.kts +++ b/NineGoalProvider/build.gradle.kts @@ -1,4 +1,4 @@ -version = 1 +version = 2 cloudstream { description = "" diff --git a/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt b/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt index 73a8397..d221166 100644 --- a/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt +++ b/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt @@ -68,10 +68,6 @@ class NineGoal : MainAPI() { TvType.Live ) - private fun String.getDomainFromUrl(): String? { - return Regex("""^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:\/\n\?\=]+)""").find(this)?.groupValues?.firstOrNull() - } - override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { val doc = app.get(mainUrl).document val apiUrl = doc.select("head > script").first()?.html()?.substringAfter("window.api_base_url = \"")?.substringBefore("\";") @@ -124,7 +120,7 @@ class NineGoal : MainAPI() { this.name, "${this.name} ${it.name} - ${sourcesData.name}", it.url.toString(), - fixUrl(it.url?.getDomainFromUrl().toString()), + "$mainUrl/", Qualities.Unknown.value, isM3u8 = true, ) From 8bf7b6d22c07e1d62c3d1fdbc53d9e53925ae973 Mon Sep 17 00:00:00 2001 From: Zaw <42999156+ImZaw@users.noreply.github.com> Date: Sun, 27 Nov 2022 16:57:40 +0300 Subject: [PATCH 4/6] ffs mfs has a broke domain, fix ninegoal (#57) Co-authored-by: Cloudburst <18114966+C10udburst@users.noreply.github.com> --- NineGoalProvider/build.gradle.kts | 2 +- .../main/kotlin/com/ninegoal/9GoalProvider.kt | 40 ++++++++++++++----- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/NineGoalProvider/build.gradle.kts b/NineGoalProvider/build.gradle.kts index 9fb7518..bd90dd4 100644 --- a/NineGoalProvider/build.gradle.kts +++ b/NineGoalProvider/build.gradle.kts @@ -1,4 +1,4 @@ -version = 2 +version = 3 cloudstream { description = "" diff --git a/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt b/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt index d221166..77e190d 100644 --- a/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt +++ b/NineGoalProvider/src/main/kotlin/com/ninegoal/9GoalProvider.kt @@ -115,16 +115,38 @@ class NineGoal : MainAPI() { ): Boolean { val sourcesData = parseJson(app.get(data).text).data sourcesData?.playUrls?.apmap { - callback.invoke( - ExtractorLink( - this.name, - "${this.name} ${it.name} - ${sourcesData.name}", - it.url.toString(), - "$mainUrl/", - Qualities.Unknown.value, - isM3u8 = true, + val brokenDomain = "canyou.letmestreamyou.net" + if(it.url.toString().startsWith("https://$brokenDomain")) { + mapOf( + "smoothlikebutterstream" to "playing.smoothlikebutterstream.com", + "tunnelcdnsw" to "playing.tunnelcdnsw.net", + "goforfreedomwme" to "playing.goforfreedomwme.net", + "gameon" to "turnthe.gameon.tel", + "whydontyoustreamwme" to "playing.whydontyoustreamwme.com" + ).apmap { (name, value) -> + callback.invoke( + ExtractorLink( + this.name, + "${this.name} ${it.name} - ${name}", + it.url.toString().replace(brokenDomain, value), + "$mainUrl/", + Qualities.Unknown.value, + isM3u8 = true, + ) + ) + } + } else { + callback.invoke( + ExtractorLink( + this.name, + "${this.name} ${it.name} - ${sourcesData.name}", + it.url.toString(), + "$mainUrl/", + Qualities.Unknown.value, + isM3u8 = true, + ) ) - ) + } } return true } From 29a1e11e4ec5e60b545e65a945b583d09c72a3db Mon Sep 17 00:00:00 2001 From: LikDev-256 <81100289+LikDev-256@users.noreply.github.com> Date: Tue, 29 Nov 2022 15:44:42 +0530 Subject: [PATCH 5/6] Better code and fully fix Eurostreaming + verbump (#59) Co-authored-by: Cloudburst <18114966+C10udburst@users.noreply.github.com> --- EurostreamingProvider/build.gradle.kts | 3 +- .../com/lagradost/EurostreamingProvider.kt | 77 +++++++++---------- 2 files changed, 39 insertions(+), 41 deletions(-) diff --git a/EurostreamingProvider/build.gradle.kts b/EurostreamingProvider/build.gradle.kts index 62f8d76..46e2d8e 100644 --- a/EurostreamingProvider/build.gradle.kts +++ b/EurostreamingProvider/build.gradle.kts @@ -1,6 +1,5 @@ // use an integer for version numbers -version = 1 - +version = 2 cloudstream { language = "it" diff --git a/EurostreamingProvider/src/main/kotlin/com/lagradost/EurostreamingProvider.kt b/EurostreamingProvider/src/main/kotlin/com/lagradost/EurostreamingProvider.kt index ec81f4e..415c9a9 100644 --- a/EurostreamingProvider/src/main/kotlin/com/lagradost/EurostreamingProvider.kt +++ b/EurostreamingProvider/src/main/kotlin/com/lagradost/EurostreamingProvider.kt @@ -5,70 +5,68 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.loadExtractor import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.toJson - +import com.lagradost.cloudstream3.network.CloudflareKiller +import okhttp3.FormBody +import org.jsoup.nodes.Element class EurostreamingProvider : MainAPI() { override var lang = "it" - override var mainUrl = "https://eurostreaming.social" + override var mainUrl = "https://eurostreaming.taxi" override var name = "Eurostreaming" override val hasMainPage = true override val hasChromecastSupport = true + private val interceptor = CloudflareKiller() override val supportedTypes = setOf( TvType.TvSeries ) override val mainPage = mainPageOf( - Pair("$mainUrl/serie-tv-archive/page/", "Ultime serie Tv"), - Pair("$mainUrl/animazione/page/", "Ultime serie Animazione"), - + "$mainUrl/serie-tv-archive/page/" to "Ultime serie Tv", + "$mainUrl/animazione/page/" to "Ultime serie Animazione", ) override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse { val url = request.data + page - val soup = app.get(url).document + val soup = app.get(url, interceptor = interceptor).document val home = soup.select("div.post-thumb").map { - val title = it.selectFirst("img")!!.attr("alt") - val link = it.selectFirst("a")!!.attr("href") - val image = fixUrl(it.selectFirst("img")!!.attr("src")) - - MovieSearchResponse( - title, - link, - this.name, - TvType.Movie, - image - ) + it.toSearchResult() + } + return newHomePageResponse(arrayListOf(HomePageList(request.name, home)), hasNext = true) + } + + private fun Element.toSearchResult(): SearchResponse { + val title = this.selectFirst("a")?.attr("title") + val link = this.selectFirst("a")?.attr("href") + val image = fixUrlNull(mainUrl + this.selectFirst("img")?.attr("src")?.trim()) + + return newTvSeriesSearchResponse(title, link, TvType.TvSeries){ + this.posterUrl = image + this.posterHeaders = interceptor.getCookieHeaders(mainUrl).toMap() } - return newHomePageResponse(request.name, home) } override suspend fun search(query: String): List { - val doc = app.post( - "$mainUrl/index.php", data = mapOf( - "do" to "search", - "subaction" to "search", - "story" to query, - "sortby" to "news_read" - ) - ).document - return doc.select("div.post-thumb").map { - val title = it.selectFirst("img")!!.attr("alt") - val link = it.selectFirst("a")!!.attr("href") - val image = mainUrl + it.selectFirst("img")!!.attr("src") + val body = FormBody.Builder() + .addEncoded("do", "search") + .addEncoded("subaction", "search") + .addEncoded("story", query) + .addEncoded("sortby", "news_read") + .build() - MovieSearchResponse( - title, - link, - this.name, - TvType.Movie, - image - ) + val doc = app.post( + "$mainUrl/index.php", + requestBody = body, + interceptor = interceptor + ).document + + return doc.select("div.post-thumb").mapNotNull { + it?.toSearchResult() } } override suspend fun load(url: String): LoadResponse { - val page = app.get(url) + val page = app.get(url, interceptor = interceptor) val document = page.document val title = document.selectFirst("h2")!!.text().replace("^([1-9+]]$","") val style = document.selectFirst("div.entry-cover")!!.attr("style") @@ -93,7 +91,8 @@ class EurostreamingProvider : MainAPI() { } } return newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodeList) { - posterUrl = poster + this.posterUrl = poster + this.posterHeaders = interceptor.getCookieHeaders(mainUrl).toMap() } } From 89b344b132d88ef247711eb99e55c3a90dae5d92 Mon Sep 17 00:00:00 2001 From: Cloudburst <18114966+C10udburst@users.noreply.github.com> Date: Tue, 29 Nov 2022 11:37:41 +0100 Subject: [PATCH 6/6] Update EurostreamingProvider.kt --- .../main/kotlin/com/lagradost/EurostreamingProvider.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/EurostreamingProvider/src/main/kotlin/com/lagradost/EurostreamingProvider.kt b/EurostreamingProvider/src/main/kotlin/com/lagradost/EurostreamingProvider.kt index 415c9a9..ef507c0 100644 --- a/EurostreamingProvider/src/main/kotlin/com/lagradost/EurostreamingProvider.kt +++ b/EurostreamingProvider/src/main/kotlin/com/lagradost/EurostreamingProvider.kt @@ -29,15 +29,15 @@ class EurostreamingProvider : MainAPI() { val url = request.data + page val soup = app.get(url, interceptor = interceptor).document - val home = soup.select("div.post-thumb").map { + val home = soup.select("div.post-thumb").mapNotNull { it.toSearchResult() } return newHomePageResponse(arrayListOf(HomePageList(request.name, home)), hasNext = true) } - private fun Element.toSearchResult(): SearchResponse { - val title = this.selectFirst("a")?.attr("title") - val link = this.selectFirst("a")?.attr("href") + private fun Element.toSearchResult(): SearchResponse? { + val title = this.selectFirst("a")?.attr("title") ?: return null + val link = this.selectFirst("a")?.attr("href") ?: return null val image = fixUrlNull(mainUrl + this.selectFirst("img")?.attr("src")?.trim()) return newTvSeriesSearchResponse(title, link, TvType.TvSeries){