From 5aa10f47aa7a647e07cbfa424c3b89b32d2937c0 Mon Sep 17 00:00:00 2001 From: antonydp <38143733+antonydp@users.noreply.github.com> Date: Sat, 15 Oct 2022 22:54:43 +0200 Subject: [PATCH] CineBlog01Provider, Guardaserie fix and small generic fixes (#34) --- CineBlog01Provider/build.gradle.kts | 27 ++ .../src/main/AndroidManifest.xml | 2 + .../kotlin/com/lagradost/CineBlogProvider.kt | 111 ++++++++ .../com/lagradost/CineBlogProviderPlugin.kt | 14 + CineBlogProvider/build.gradle.kts | 2 +- .../kotlin/com/lagradost/CineBlogProvider.kt | 2 +- FilmpertuttiProvider/build.gradle.kts | 2 +- .../com/lagradost/FilmpertuttiProvider.kt | 8 +- GuardaSerieProvider/build.gradle.kts | 2 +- .../com/lagradost/GuardaSerieProvider.kt | 241 ++++++------------ .../build.gradle.kts | 2 +- .../IlGenioDelloStreamingProvider.kt | 12 +- 12 files changed, 247 insertions(+), 178 deletions(-) create mode 100644 CineBlog01Provider/build.gradle.kts create mode 100644 CineBlog01Provider/src/main/AndroidManifest.xml create mode 100644 CineBlog01Provider/src/main/kotlin/com/lagradost/CineBlogProvider.kt create mode 100644 CineBlog01Provider/src/main/kotlin/com/lagradost/CineBlogProviderPlugin.kt diff --git a/CineBlog01Provider/build.gradle.kts b/CineBlog01Provider/build.gradle.kts new file mode 100644 index 0000000..9e63de9 --- /dev/null +++ b/CineBlog01Provider/build.gradle.kts @@ -0,0 +1,27 @@ +// use an integer for version numbers +version = 1 + + +cloudstream { + language = "it" + // All of these properties are optional, you can safely remove them + + // description = "Lorem Ipsum" + authors = listOf("Adippe") + + /** + * Status int as the following: + * 0: Down + * 1: Ok + * 2: Slow + * 3: Beta only + * */ + status = 1 // will be 3 if unspecified + tvTypes = listOf( + "TvSeries", + "Movie", + ) + + + iconUrl = "https://www.google.com/s2/favicons?domain=cineblog01.legal&sz=%size%" +} \ No newline at end of file diff --git a/CineBlog01Provider/src/main/AndroidManifest.xml b/CineBlog01Provider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/CineBlog01Provider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/CineBlog01Provider/src/main/kotlin/com/lagradost/CineBlogProvider.kt b/CineBlog01Provider/src/main/kotlin/com/lagradost/CineBlogProvider.kt new file mode 100644 index 0000000..9923a53 --- /dev/null +++ b/CineBlog01Provider/src/main/kotlin/com/lagradost/CineBlogProvider.kt @@ -0,0 +1,111 @@ +package com.lagradost + +import com.lagradost.cloudstream3.* +import com.lagradost.cloudstream3.utils.ExtractorLink +import com.lagradost.cloudstream3.utils.loadExtractor + +class CineBlog01Provider : MainAPI() { + override var lang = "it" + override var mainUrl = "https://www.cineblog01.legal" + override var name = "CineBlog01" + override val hasMainPage = true + override val hasChromecastSupport = true + override var sequentialMainPage = true + override val supportedTypes = setOf( + TvType.Movie, + ) + override val mainPage = mainPageOf( + Pair("$mainUrl/page/", "Film Popolari"), + Pair("$mainUrl/film-sub-ita/page/", "Film Sub-ita") + ) + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { + val url = request.data + page + val soup = app.get(url).document + + val home = soup.select("div.filmbox").map { series -> + val title = series.selectFirst("img")!!.attr("alt") + val link = series.selectFirst("a")!!.attr("href") + val posterUrl = fixUrl(series.selectFirst("img")!!.attr("src")) + val quality = Regex("\\[([^\\]]*)]").find(series.selectFirst("h1")!!.text())?.groupValues?.get(1) + val year = Regex("\\(([^)]*)\\)").find(series.selectFirst("h1")!!.text())?.groupValues?.get(1)?.toIntOrNull() + + newMovieSearchResponse( + title, + link, + TvType.TvSeries + ) { + this.posterUrl = posterUrl + this.quality = getQualityFromString(quality) + this.year = year + } + } + return newHomePageResponse(request.name, home) + } + + override suspend fun search(query: String): List { + val doc = app.post( + "$mainUrl/index.php?do=search", data = mapOf( + "do" to "search", + "subaction" to "search", + "story" to query + ) + ).document + return doc.select("div.filmbox").map { series -> + val title = series.selectFirst("img")!!.attr("alt") + val link = series.selectFirst("a")!!.attr("href") + val posterUrl = fixUrl(series.selectFirst("img")!!.attr("src")) + var quality = Regex("\\[([^\\]]*)]").find(series.selectFirst("h1")!!.text())?.groupValues?.get(1) + var year = Regex("\\(([^)]*)\\)").find(series.selectFirst("h1")!!.text())?.groupValues?.get(1)?.toIntOrNull() + + newMovieSearchResponse( + title, + link, + TvType.TvSeries + ) { + this.posterUrl = posterUrl + this.quality = getQualityFromString(quality) + this.year = year + } + + } + } + + override suspend fun load(url: String): LoadResponse { + val document = app.get(url).document + val title = document.selectFirst("div.imgrow > img")!!.attr("alt") + val description = document.selectFirst("div.fstory")?.text()?.removeSuffix(" +Info »")?.substringAfter("′ - ") + var year = document.selectFirst("div.filmboxfull")?.getElementsByAttributeValueContaining("href" , "/anno/")?.text()?.toIntOrNull() + val poster = fixUrl(document.selectFirst("div.imgrow > img")!!.attr("src")) + val dataUrl = document.select("ul.mirrors-list__list > li").map { + it.select("a").attr("href") + }.drop(1).joinToString (",") + return newMovieLoadResponse( + title, + url, + TvType.Movie, + dataUrl = dataUrl + ) { + + this.plot = description + this.year = year + this.posterUrl = poster + } + } + + override suspend fun loadLinks( + data: String, + isCasting: Boolean, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit + ): Boolean { + val links = data.split(",") + links.map { url -> + loadExtractor(fixUrl(url), fixUrl(url), subtitleCallback, callback) + } + return true + } +} \ No newline at end of file diff --git a/CineBlog01Provider/src/main/kotlin/com/lagradost/CineBlogProviderPlugin.kt b/CineBlog01Provider/src/main/kotlin/com/lagradost/CineBlogProviderPlugin.kt new file mode 100644 index 0000000..be3aadd --- /dev/null +++ b/CineBlog01Provider/src/main/kotlin/com/lagradost/CineBlogProviderPlugin.kt @@ -0,0 +1,14 @@ + +package com.lagradost + +import com.lagradost.cloudstream3.plugins.CloudstreamPlugin +import com.lagradost.cloudstream3.plugins.Plugin +import android.content.Context + +@CloudstreamPlugin +class CineBlog01ProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(CineBlog01Provider()) + } +} \ No newline at end of file diff --git a/CineBlogProvider/build.gradle.kts b/CineBlogProvider/build.gradle.kts index f4c36d0..ed9e440 100644 --- a/CineBlogProvider/build.gradle.kts +++ b/CineBlogProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { diff --git a/CineBlogProvider/src/main/kotlin/com/lagradost/CineBlogProvider.kt b/CineBlogProvider/src/main/kotlin/com/lagradost/CineBlogProvider.kt index 7ab87cd..b98033a 100644 --- a/CineBlogProvider/src/main/kotlin/com/lagradost/CineBlogProvider.kt +++ b/CineBlogProvider/src/main/kotlin/com/lagradost/CineBlogProvider.kt @@ -8,7 +8,7 @@ import com.lagradost.cloudstream3.utils.loadExtractor class CineBlogProvider : MainAPI() { override var lang = "it" override var mainUrl = "https://cb01.rip" - override var name = "CineBlog" + override var name = "CB01" override val hasMainPage = true override val hasChromecastSupport = true override val supportedTypes = setOf( diff --git a/FilmpertuttiProvider/build.gradle.kts b/FilmpertuttiProvider/build.gradle.kts index 49de879..d6467d7 100644 --- a/FilmpertuttiProvider/build.gradle.kts +++ b/FilmpertuttiProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 2 +version = 3 cloudstream { diff --git a/FilmpertuttiProvider/src/main/kotlin/com/lagradost/FilmpertuttiProvider.kt b/FilmpertuttiProvider/src/main/kotlin/com/lagradost/FilmpertuttiProvider.kt index 470e393..31e1a3d 100644 --- a/FilmpertuttiProvider/src/main/kotlin/com/lagradost/FilmpertuttiProvider.kt +++ b/FilmpertuttiProvider/src/main/kotlin/com/lagradost/FilmpertuttiProvider.kt @@ -11,6 +11,7 @@ import com.lagradost.cloudstream3.utils.ShortLink import com.lagradost.cloudstream3.utils.loadExtractor import org.jsoup.nodes.Element import com.lagradost.cloudstream3.utils.AppUtils.html +import com.lagradost.cloudstream3.network.CloudflareKiller class FilmpertuttiProvider : MainAPI() { @@ -30,12 +31,13 @@ class FilmpertuttiProvider : MainAPI() { Pair("$mainUrl/prime-visioni/", "Ultime uscite") ) + private val interceptor = CloudflareKiller() override suspend fun getMainPage( page: Int, request: MainPageRequest ): HomePageResponse { val url = request.data + page - val soup = app.get(url, referer = mainUrl).document + val soup = app.get(url, interceptor = interceptor, referer = mainUrl).document val home = soup.select("ul.posts > li").map { val title = it.selectFirst("div.title")!!.text().substringBeforeLast("(") .substringBeforeLast("[") @@ -62,7 +64,7 @@ class FilmpertuttiProvider : MainAPI() { override suspend fun search(query: String): List { val queryformatted = query.replace(" ", "+") val url = "$mainUrl/?s=$queryformatted" - val doc = app.get(url).document + val doc = app.get(url, interceptor = interceptor).document return doc.select("ul.posts > li").map { val title = it.selectFirst("div.title")!!.text().substringBeforeLast("(") .substringBeforeLast("[") @@ -81,7 +83,7 @@ class FilmpertuttiProvider : MainAPI() { } override suspend fun load(url: String): LoadResponse { - val document = app.get(url).document + val document = app.get(url, interceptor = interceptor).document val type = if (document.selectFirst("a.taxonomy.category")!!.attr("href").contains("serie-tv") .not() diff --git a/GuardaSerieProvider/build.gradle.kts b/GuardaSerieProvider/build.gradle.kts index d95fc03..71e7f14 100644 --- a/GuardaSerieProvider/build.gradle.kts +++ b/GuardaSerieProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 1 +version = 2 cloudstream { diff --git a/GuardaSerieProvider/src/main/kotlin/com/lagradost/GuardaSerieProvider.kt b/GuardaSerieProvider/src/main/kotlin/com/lagradost/GuardaSerieProvider.kt index 026c69d..1851199 100644 --- a/GuardaSerieProvider/src/main/kotlin/com/lagradost/GuardaSerieProvider.kt +++ b/GuardaSerieProvider/src/main/kotlin/com/lagradost/GuardaSerieProvider.kt @@ -1,181 +1,108 @@ package com.lagradost -import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId -import com.lagradost.cloudstream3.LoadResponse.Companion.addDuration -import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId import com.lagradost.cloudstream3.LoadResponse.Companion.addRating -import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer -import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson -import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.ExtractorLink -import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.loadExtractor -import com.lagradost.nicehttp.NiceResponse -import org.jsoup.nodes.Element -import org.mozilla.javascript.ConsString -import org.mozilla.javascript.Context -import org.mozilla.javascript.Scriptable + class GuardaSerieProvider : MainAPI() { - override var mainUrl = "https://guardaserie.golf" - override var name = "GuardaSerie" override var lang = "it" + override var mainUrl = "https://guardaserie.skin" + override var name = "GuardaSerie" override val hasMainPage = true - override val hasQuickSearch = true + override val hasChromecastSupport = true + override var sequentialMainPage = true override val supportedTypes = setOf( TvType.TvSeries, - TvType.Movie ) override val mainPage = mainPageOf( - Pair("$mainUrl/stagioni/page/", "Ultime Serie Tv"), - Pair("$mainUrl/viste/page/", "Film e Serie più viste"), - Pair("$mainUrl/votati/page/", "Ora al cinema") - ) - companion object { - private lateinit var token : String - } - - data class QuickSearchParser ( - @JsonProperty ("title") val title : String? = null, - @JsonProperty ("url") val url : String? = null, - @JsonProperty ("img") val img : String? = null + Pair("$mainUrl/serietv-popolari/page/", "Serie Tv Popolari"), + Pair("$mainUrl/serietv-streaming/page/", "Ultime Serie Tv"), + Pair("$mainUrl/top-imdb/page/", "Top IMDB") ) - override suspend fun search(query: String): List { - val queryFormatted = query.replace(" ", "+") - val url = "$mainUrl?s=$queryFormatted" - val doc = app.get(url,referer= mainUrl ).document - return doc.select("div.result-item").map { - val href = it.selectFirst("div.image > div > a")!!.attr("href") - val poster = it.selectFirst("div.image > div > a > img")!!.attr("src") - val name = it.selectFirst("div.details > div.title > a")!!.text().substringBefore("(") - MovieSearchResponse( - name, - href, - this.name, - TvType.Movie, - poster - ) - - } - } - - override suspend fun quickSearch(query: String): List? { - val response = app.get("$mainUrl/wp-json/dooplay/search/?keyword=$query&nonce=$token").text - val p = tryParseJson>(response)?.values?.map { - MovieSearchResponse( - name = it.title!!, - url = it.url!!, - posterUrl = it.img!!, - type = TvType.Movie, - apiName = this.name - ) - } - - return p - } - override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { + override suspend fun getMainPage( + page: Int, + request: MainPageRequest + ): HomePageResponse { val url = request.data + page val soup = app.get(url).document + val home = soup.select("div.mlnew").drop(1).map { series -> + val title = series.selectFirst("div.mlnh-2")!!.text() + val link = series.selectFirst("div.mlnh-2 > h2 > a")!!.attr("href") + val posterUrl = fixUrl(series.selectFirst("img")!!.attr("src")) - token = Regex("nonce\":\"[^\"]*").find(app.get(mainUrl).toString())?.value?.drop(8)?:"" - val home = soup.select("article").map { - val title = it.selectFirst("img")!!.attr("alt") - val link = it.selectFirst("a")!!.attr("href") - val image = it.selectFirst("img")!!.attr("src") - val quality = getQualityFromString(it.selectFirst("span.quality")?.text()) - - MovieSearchResponse( + newTvSeriesSearchResponse( title, link, - this.name, - TvType.Movie, - image, - null, - null, - quality, - ) + TvType.TvSeries + ) { + this.posterUrl = posterUrl + } + } return newHomePageResponse(request.name, home) } - override suspend fun load(url: String): LoadResponse { - val document = app.get(url).document - val name = document.selectFirst("h1")!!.text() - val poster = document.selectFirst("div.poster")?.selectFirst("img")!!.attr("src") - val rating = document.selectFirst("span.dt_rating_vgs")!!.text().toIntOrNull() - val tags = document.select("div.sgeneros > a").map { it.text() } - val actors = document.select("div.person").map { - val actorName = it.selectFirst("div.name > a")!!.text() - val actorPoster = it.selectFirst("img")?.attr("src") - val role = it.selectFirst("div.caracter")?.text() - ActorData(Actor(actorName, actorPoster), roleString = role ) - } - if(url.contains("/film/")){ - val description = document.selectFirst("div.wp-content > p")!!.text() - val year = document.selectFirst("span.date")!!.text().substringAfterLast(" ").toIntOrNull() - val recomm = document.selectFirst("div.sbox.srelacionados")?.select("article")?.map{ - MovieSearchResponse( - name = it.selectFirst("img")!!.attr("alt"), - url = it.selectFirst("a")!!.attr("href"), - this.name, - TvType.Movie, - posterUrl = it.selectFirst("img")!!.attr("src"), - null - ) - } - val duration = document.selectFirst("div.runtime")?.text()?.filter { it.isDigit() }?.toIntOrNull() - return newMovieLoadResponse( - name = name, - url = url, - type = TvType.Movie, - dataUrl = url + override suspend fun search(query: String): List { + val doc = app.post( + mainUrl, data = mapOf( + "do" to "search", + "subaction" to "search", + "story" to query + ) + ).document + return doc.select("div.mlnew").drop(1).map { series -> + val title = series.selectFirst("div.mlnh-2")!!.text() + val link = series.selectFirst("div.mlnh-2 > h2 > a")!!.attr("href") + val posterUrl = fixUrl(series.selectFirst("img")!!.attr("src")) + newMovieSearchResponse( + title, + link, + TvType.Movie ) { - posterUrl = fixUrlNull(poster) - this.year = year - this.plot = description - this.rating = rating - this.recommendations = recomm - this.duration = duration - this.actors = actors - this.tags = tags + this.posterUrl = posterUrl } - } - else{ - val episodes = document.select("#seasons > div").reversed().mapIndexed{season, data-> - data.select("li").mapIndexed { epNum , ep -> - val href = ep.selectFirst("a")!!.attr("href") - val epTitle = ep.selectFirst("a")?.text() - val posterUrl = ep.selectFirst("img")?.attr("src") - Episode( - href, - epTitle, - season + 1, - epNum + 1, - posterUrl, - ) - } - } - val plot = document.selectFirst("#info > div.wp-content > p")?.text() - return newTvSeriesLoadResponse( - name = name, - url = url, - type = TvType.TvSeries, - episodes = episodes.flatten(), - ){ - this.posterUrl = poster - this.rating = rating - this.tags = tags - this.actors = actors - this.plot = plot - } } } + override suspend fun load(url: String): LoadResponse { + val document = app.get(url).document + val title = document.selectFirst("h1")!!.text().removeSuffix(" streaming") + val description = document.selectFirst("div.tv_info_right")?.textNodes()?.joinToString("") + val rating = document.selectFirst("span.post-ratings")?.text() + var year = document.select("div.tv_info_list > ul").find { it.text().contains("Anno") }?.text()?.substringBefore("-")?.filter { it.isDigit() }?.toIntOrNull() + val poster = fixUrl(document.selectFirst("#cover")!!.attr("src")).replace("/141x200-0-85/", "/60x85-0-85/") + + val episodeList = document.select("div.tab-content > div").mapIndexed { season, data -> + data.select("li").mapIndexed { epNum, epData -> + val epName = epData.selectFirst("a")?.attr("data-title") + val data = epData.select("div.mirrors > a").map { it.attr("data-link") } + .joinToString ( "," ) + Episode( + data = data, + name = epName, + season = season + 1, + episode = epNum + 1, + ) + } + }.flatten() + + return newTvSeriesLoadResponse( + title, + url, + TvType.TvSeries, + episodeList + ) { + addRating(rating) + this.plot = description + this.year = year + this.posterUrl = poster + } + } override suspend fun loadLinks( data: String, @@ -183,22 +110,10 @@ class GuardaSerieProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - val doc = app.get(data).document - val type = if( data.contains("film") ){"movie"} else {"tv"} - val idpost = doc.select("#player-option-1").attr("data-post") - val postInfo = app.post("$mainUrl/wp-admin/admin-ajax.php", headers = mapOf( - "content-type" to "application/x-www-form-urlencoded; charset=UTF-8", - "accept" to "*/*", - "X-Requested-With" to "XMLHttpRequest", - ), data = mapOf( - "action" to "doo_player_ajax", - "post" to idpost, - "nume" to "1", - "type" to type, - )) - - val url= Regex("""src='((.|\\n)*?)'""").find(postInfo.text)?.groups?.get(1)?.value.toString() - val streamUrl = app.get(url, headers = mapOf("referer" to mainUrl)).url - return loadExtractor(streamUrl, data, subtitleCallback, callback) + val links = data.split(",") + links.map { url -> + loadExtractor(fixUrl(url), fixUrl(url), subtitleCallback, callback) + } + return true } } \ No newline at end of file diff --git a/IlGenioDelloStreamingProvider/build.gradle.kts b/IlGenioDelloStreamingProvider/build.gradle.kts index 314240c..5b315ec 100644 --- a/IlGenioDelloStreamingProvider/build.gradle.kts +++ b/IlGenioDelloStreamingProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 3 +version = 4 cloudstream { diff --git a/IlGenioDelloStreamingProvider/src/main/kotlin/com/lagradost/IlGenioDelloStreamingProvider.kt b/IlGenioDelloStreamingProvider/src/main/kotlin/com/lagradost/IlGenioDelloStreamingProvider.kt index 9f14dc8..71d89e8 100644 --- a/IlGenioDelloStreamingProvider/src/main/kotlin/com/lagradost/IlGenioDelloStreamingProvider.kt +++ b/IlGenioDelloStreamingProvider/src/main/kotlin/com/lagradost/IlGenioDelloStreamingProvider.kt @@ -2,6 +2,7 @@ package com.lagradost import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.LoadResponse.Companion.addRating +import com.lagradost.cloudstream3.network.CloudflareKiller import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.ExtractorLink @@ -27,13 +28,13 @@ class IlGenioDelloStreamingProvider : MainAPI() { Pair("$mainUrl/the-most-voted/page/", "I più votati"), Pair("$mainUrl/prime-visioni/page/", "Ultime uscite"), ) - + private val interceptor = CloudflareKiller() 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.items > article.item").map { val title = it.selectFirst("div.data > h3 > a")!!.text().substringBeforeLast("(").substringBeforeLast("[") val link = it.selectFirst("div.poster > a")!!.attr("href") @@ -55,7 +56,7 @@ class IlGenioDelloStreamingProvider : MainAPI() { override suspend fun search(query: String): List { val queryformatted = query.replace(" ", "+") val url = "$mainUrl?s=$queryformatted" - val doc = app.get(url,referer= mainUrl ).document + val doc = app.get(url, interceptor = interceptor, referer = mainUrl).document return doc.select("div.result-item").map { val href = it.selectFirst("div.image > div > a")!!.attr("href") val poster = it.selectFirst("div.image > div > a > img")!!.attr("src") @@ -72,7 +73,7 @@ class IlGenioDelloStreamingProvider : MainAPI() { } override suspend fun load(url: String): LoadResponse { - val page = app.get(url) + val page = app.get(url, interceptor = interceptor) val document = page.document val type = if (document.select("div.seasons-wraper").isNotEmpty()){TvType.TvSeries} else{TvType.Movie} val title = document.selectFirst("div.data > h1")!!.text().substringBefore("(").substringBefore("[") @@ -127,9 +128,6 @@ class IlGenioDelloStreamingProvider : MainAPI() { )) } - - - } }