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,