diff --git a/GuardaSerieProvider/build.gradle.kts b/GuardaSerieProvider/build.gradle.kts new file mode 100644 index 0000000..d95fc03 --- /dev/null +++ b/GuardaSerieProvider/build.gradle.kts @@ -0,0 +1,26 @@ +// 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=guardaserie.golf&sz=%size%" +} \ No newline at end of file diff --git a/GuardaSerieProvider/src/main/AndroidManifest.xml b/GuardaSerieProvider/src/main/AndroidManifest.xml new file mode 100644 index 0000000..29aec9d --- /dev/null +++ b/GuardaSerieProvider/src/main/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/GuardaSerieProvider/src/main/kotlin/com/lagradost/GuardaSerieProvider.kt b/GuardaSerieProvider/src/main/kotlin/com/lagradost/GuardaSerieProvider.kt new file mode 100644 index 0000000..026c69d --- /dev/null +++ b/GuardaSerieProvider/src/main/kotlin/com/lagradost/GuardaSerieProvider.kt @@ -0,0 +1,204 @@ +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 val hasMainPage = true + override val hasQuickSearch = 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 + ) + + + 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 { + val url = request.data + page + val soup = app.get(url).document + + 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( + title, + link, + this.name, + TvType.Movie, + image, + null, + null, + quality, + ) + } + 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 + ) { + posterUrl = fixUrlNull(poster) + this.year = year + this.plot = description + this.rating = rating + this.recommendations = recomm + this.duration = duration + this.actors = actors + this.tags = tags + } + } + 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 loadLinks( + data: String, + isCasting: Boolean, + 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) + } +} \ No newline at end of file diff --git a/GuardaSerieProvider/src/main/kotlin/com/lagradost/GuardaSerieProviderPlugin.kt b/GuardaSerieProvider/src/main/kotlin/com/lagradost/GuardaSerieProviderPlugin.kt new file mode 100644 index 0000000..c0a0708 --- /dev/null +++ b/GuardaSerieProvider/src/main/kotlin/com/lagradost/GuardaSerieProviderPlugin.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 GuardaSerieProviderPlugin: Plugin() { + override fun load(context: Context) { + // All providers should be added in this manner. Please don't edit the providers list directly. + registerMainAPI(GuardaSerieProvider()) + } +} \ No newline at end of file