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 1/2] 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() { )) } - - - } } From f2933f5c6a4221d9d0d8a79ae35c1332f27eceb3 Mon Sep 17 00:00:00 2001 From: Davide <49226282+pizidavi@users.noreply.github.com> Date: Sat, 15 Oct 2022 23:03:13 +0200 Subject: [PATCH 2/2] AnimeSaturn (#36) Added lasted episode Added trailer & recommendations Updated mainUrl --- AnimeSaturnProvider/build.gradle.kts | 2 +- .../com/lagradost/AnimeSaturnProvider.kt | 97 ++++++++++++------- 2 files changed, 62 insertions(+), 37 deletions(-) diff --git a/AnimeSaturnProvider/build.gradle.kts b/AnimeSaturnProvider/build.gradle.kts index dcb2306..d27f120 100644 --- a/AnimeSaturnProvider/build.gradle.kts +++ b/AnimeSaturnProvider/build.gradle.kts @@ -1,5 +1,5 @@ // use an integer for version numbers -version = 2 +version = 3 cloudstream { diff --git a/AnimeSaturnProvider/src/main/kotlin/com/lagradost/AnimeSaturnProvider.kt b/AnimeSaturnProvider/src/main/kotlin/com/lagradost/AnimeSaturnProvider.kt index 39ac195..f5647af 100644 --- a/AnimeSaturnProvider/src/main/kotlin/com/lagradost/AnimeSaturnProvider.kt +++ b/AnimeSaturnProvider/src/main/kotlin/com/lagradost/AnimeSaturnProvider.kt @@ -6,13 +6,14 @@ 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.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import org.jsoup.nodes.Element class AnimeSaturnProvider : MainAPI() { - override var mainUrl = "https://www.animesaturn.cc" + override var mainUrl = "https://www.animesaturn.in" override var name = "AnimeSaturn" override var lang = "it" override val hasMainPage = true @@ -40,8 +41,22 @@ class AnimeSaturnProvider : MainAPI() { } } - private fun Element.toSearchResult(): AnimeSearchResponse { + private fun Element.toSearchResponse(): AnimeSearchResponse? { + val url = this.select("a").first()?.attr("href") + ?: return null + val title = this.select("a[title]").first()?.attr("title")?.removeSuffix("(ITA)") + ?: return null + val posterUrl = this.select("img.new-anime").first()!!.attr("src") + val isDubbed = this.select("a[title]").first()?.attr("title")?.contains("(ITA)") + ?: false + return newAnimeSearchResponse(title, url, TvType.Anime){ + addDubStatus(isDubbed) + addPoster(posterUrl) + } + } + + private fun Element.toSearchResult(): AnimeSearchResponse { var title = this.select("a.badge-archivio").first()!!.text() var isDubbed = false @@ -51,19 +66,18 @@ class AnimeSaturnProvider : MainAPI() { } val url = this.select("a.badge-archivio").first()!!.attr("href") - val posterUrl = this.select("img.locandina-archivio[src]").first()!!.attr("src") return newAnimeSearchResponse(title, url, TvType.Anime) { addDubStatus(isDubbed) - this.posterUrl = posterUrl + addPoster(posterUrl) } } private fun Element.toEpisode(): Episode? { var episode = this.text().split(" ")[1] - if(episode.contains(".")) return null - if(episode.contains("-")) + if (episode.contains(".")) return null + if (episode.contains("-")) episode = episode.split("-")[0] return Episode( @@ -74,26 +88,36 @@ class AnimeSaturnProvider : MainAPI() { } override suspend fun getMainPage(page: Int, request : MainPageRequest): HomePageResponse { + val list = mutableListOf() + + val documentLastEpisode = app.get("$mainUrl/fetch_pages.php?request=episodes", + headers = mapOf("x-requested-with" to "XMLHttpRequest") + ).document + val lastedEpisode = documentLastEpisode.select(".anime-card").mapNotNull { + val url = it.select("a").first()?.attr("href")?.let { href -> + href.split("-ep-")[0].replace("/ep/", "/anime/") + } ?: return@mapNotNull null + val title = it.select("a").first()?.attr("title")?.removeSuffix(" (ITA)") + ?: return@mapNotNull null + val posterUrl = it.select("img").first()?.attr("src") + + val dub = it.select("a").first()?.attr("title")?.contains("(ITA)") ?: false + val episode = it.select(".anime-episode").text().split(" ").last().toIntOrNull() + + newAnimeSearchResponse(title, url, TvType.Anime) { + addPoster(posterUrl) + addDubStatus(dub, episode) + } + } + list.add(HomePageList("Ultimi episodi", lastedEpisode, isHorizontalImages = true)) + val document = app.get(mainUrl).document - val list = ArrayList() document.select("div.container:has(span.badge-saturn)").forEach { val tabName = it.select("span.badge-saturn").first()!!.text() if (tabName.equals("Ultimi episodi")) return@forEach - val results = ArrayList() - it.select(".main-anime-card").forEach { card -> - var title = card.select("a[title]").first()!!.attr("title") - var isDubbed = false - if(title.contains(" (ITA)")){ - title = title.replace(" (ITA)", "") - isDubbed = true - } - val posterUrl = card.select("img.new-anime").first()!!.attr("src") - val url = card.select("a").first()!!.attr("href") - results.add(newAnimeSearchResponse(title, url, TvType.Anime){ - addDubStatus(isDubbed) - this.posterUrl = posterUrl - }) + val results = it.select(".main-anime-card").mapNotNull { card -> + card.toSearchResponse() } list.add(HomePageList(tabName, results)) } @@ -103,9 +127,9 @@ class AnimeSaturnProvider : MainAPI() { override suspend fun quickSearch(query: String): List? { val quickSearchJ = app.get("$mainUrl/index.php?search=1&key=$query").text return tryParseJson>(quickSearchJ)?.map { - newAnimeSearchResponse(it.name.replace(" (ITA)", ""), it.link, TvType.Anime) { + newAnimeSearchResponse(it.name.removeSuffix("(ITA)"), it.link, TvType.Anime) { addDubStatus(it.name.contains(" (ITA)")) - this.posterUrl = it.image + addPoster(it.image) } } @@ -119,11 +143,10 @@ class AnimeSaturnProvider : MainAPI() { } override suspend fun load(url: String): LoadResponse { - val document = app.get(url).document - val title = document.select("img.cover-anime").first()!!.attr("alt") - val japTitle = document.select("div.box-trasparente-alternativo").first()!!.text() + val title = document.select("img.cover-anime").first()!!.attr("alt").removeSuffix("(ITA)") + val japTitle = document.select("div.box-trasparente-alternativo").first()!!.text().removeSuffix("(ITA)") val posterUrl = document.select("img.cover-anime[src]").first()!!.attr("src") var malId : Int? = null var aniListId : Int? = null @@ -136,8 +159,9 @@ class AnimeSaturnProvider : MainAPI() { } val plot = document.select("div#shown-trama").first()?.text() - val tags = document.select("a.generi-as").map { it.text() } + val isDubbed = document.select("div.anime-title-as").first()!!.text().contains("(ITA)") + val trailerUrl = document.select("#trailer-iframe").first()?.attr("src") val details : List? = document.select("div.container:contains(Stato: )").first()?.text()?.split(" ") var status : String? = null @@ -145,8 +169,6 @@ class AnimeSaturnProvider : MainAPI() { var year : String? = null var score : String? = null - val isDubbed = document.select("div.anime-title-as").first()!!.text().contains("(ITA)") - if (!details.isNullOrEmpty()) { details.forEach { val index = details.indexOf(it) +1 @@ -162,6 +184,10 @@ class AnimeSaturnProvider : MainAPI() { val episodes = document.select("a.bottone-ep").mapNotNull{ it.toEpisode() } + val recommendations = document.select("#carousel > .main-anime-card").mapNotNull { + it.toSearchResponse() + } + return newAnimeLoadResponse(title, url, TvType.Anime) { this.engName = title this.japName = japTitle @@ -175,6 +201,8 @@ class AnimeSaturnProvider : MainAPI() { addMalId(malId) addAniListId(aniListId) addDuration(duration) + addTrailer(trailerUrl) + this.recommendations = recommendations } } @@ -184,20 +212,18 @@ class AnimeSaturnProvider : MainAPI() { subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit ): Boolean { - val page = app.get(data).document val episodeLink = page.select("div.card-body > a[href]").find {it1 -> it1.attr("href").contains("watch?") - }?.attr("href") + }?.attr("href") ?: return false - val episodePage = app.get(episodeLink!!).document + val episodePage = app.get(episodeLink).document val episodeUrl: String? var isM3U8 = false - if(episodePage.select("video.afterglow > source").isNotEmpty()) //Old player + if (episodePage.select("video.afterglow > source").isNotEmpty()) // Old player episodeUrl = episodePage.select("video.afterglow > source").first()!!.attr("src") - - else{ //New player + else { // New player val script = episodePage.select("script").find { it.toString().contains("jwplayer('player_hls').setup({") }!!.toString() @@ -205,7 +231,6 @@ class AnimeSaturnProvider : MainAPI() { isM3U8 = true } - callback.invoke( ExtractorLink( name,