diff --git a/AnimeDekhoProvider/build.gradle.kts b/AnimeDekhoProvider/build.gradle.kts index 224fc347..934a2bd4 100644 --- a/AnimeDekhoProvider/build.gradle.kts +++ b/AnimeDekhoProvider/build.gradle.kts @@ -1,8 +1,7 @@ -version = 2 +version = 3 cloudstream { language = "hi" - description = "SKIP ADS on the SITE every 24 hours to Play, has Hindi Dubbed Cartoons" authors = listOf("anon") /** diff --git a/AnimeDekhoProvider/src/main/kotlin/com/anon/AnimeDekhoProvider.kt b/AnimeDekhoProvider/src/main/kotlin/com/anon/AnimeDekhoProvider.kt index 0f024ddc..fb50b44c 100644 --- a/AnimeDekhoProvider/src/main/kotlin/com/anon/AnimeDekhoProvider.kt +++ b/AnimeDekhoProvider/src/main/kotlin/com/anon/AnimeDekhoProvider.kt @@ -1,26 +1,11 @@ package com.anon -import android.util.Log -import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* -import com.lagradost.cloudstream3.extractors.DoodLaExtractor +import com.lagradost.cloudstream3.extractors.helper.AesHelper.cryptoAESHandler import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.parseJson -import com.lagradost.nicehttp.Requests -import com.lagradost.nicehttp.Session -import kotlinx.coroutines.delay -import org.jsoup.nodes.Element -import com.lagradost.cloudstream3.network.WebViewResolver -import com.lagradost.nicehttp.requestCreator -import org.jsoup.Jsoup -import java.util.regex.Pattern -import okhttp3.Interceptor -import okhttp3.Response -import okhttp3.MediaType.Companion.toMediaTypeOrNull import com.lagradost.cloudstream3.utils.AppUtils.toJson -import com.lagradost.nicehttp.RequestBodyTypes -import okhttp3.RequestBody.Companion.toRequestBody -import com.lagradost.cloudstream3.extractors.helper.AesHelper.cryptoAESHandler +import org.jsoup.nodes.Element class AnimeDekhoProvider : MainAPI() { override var mainUrl = "https://animedekho.com" @@ -28,83 +13,85 @@ class AnimeDekhoProvider : MainAPI() { override val hasMainPage = true override var lang = "hi" override val hasDownloadSupport = true + private val serverUrl = "https://vidxstream.xyz" - override val supportedTypes = setOf( - TvType.Cartoon, - TvType.Anime, - TvType.AnimeMovie, - TvType.Movie - ) - - override val mainPage = mainPageOf( - "/series/" to "Series", - "/movie/" to "Movies", - "/category/anime/" to "Anime", - "/category/cartoon/" to "Cartoon", + override val supportedTypes = + setOf( + TvType.Cartoon, + TvType.Anime, + TvType.AnimeMovie, + TvType.Movie, ) - override suspend fun getMainPage(page: Int, request: MainPageRequest): HomePageResponse { + override val mainPage = + mainPageOf( + "/series/" to "Series", + "/movie/" to "Movies", + "/category/anime/" to "Anime", + "/category/cartoon/" to "Cartoon", + ) + + override suspend fun getMainPage( + page: Int, + request: MainPageRequest, + ): HomePageResponse { val link = "$mainUrl${request.data}" val document = app.get(link).document - val home = document.select("article").mapNotNull { - it.toSearchResult() - } + val home = + document.select("article").mapNotNull { + it.toSearchResult() + } return newHomePageResponse(request.name, home) } private fun Element.toSearchResult(): AnimeSearchResponse? { - //val href = fixUrl(this.selectFirst("a")?.attr("href") ?: return null) - val href = this.selectFirst("a.lnk-blk")?.attr("href") ?: "null" - var title = this.selectFirst("header h2")?.text() ?: "null" - val posterUrl = this.selectFirst("div figure img")?.attr("src") ?: "null" + val href = this.selectFirst("a.lnk-blk")?.attr("href") ?: return null + val title = this.selectFirst("header h2")?.text() ?: "null" + val posterUrl = this.selectFirst("div figure img")?.attr("src") - return newAnimeSearchResponse(title, href, TvType.Anime) { + return newAnimeSearchResponse(title, Media(href, posterUrl).toJson(), TvType.Anime) { this.posterUrl = posterUrl } } override suspend fun search(query: String): List { val document = app.get("$mainUrl/?s=$query").document - //return document.select("div.post-filter-image").mapNotNull { return document.select("ul[data-results] li article").mapNotNull { it.toSearchResult() } } - override suspend fun load(url: String): LoadResponse? { - - val document = app.get(url).document + override suspend fun load(url: String): LoadResponse { - var title = document?.selectFirst("h1.entry-title")?.text()?.trim() ?: (document?.selectFirst("h3")?.text()?.trim() ?: "Null title") - val poster = document?.selectFirst("div.post-thumbnail figure img")?.attr("src") ?: "null" - val plot = document?.selectFirst("div.entry-content p")?.text()?.trim() ?: "null" - val year = document?.selectFirst("span.year")?.text()?.trim()?.toInt() ?: 1990 - var episodes = mutableListOf() + val media = parseJson(url) + val document = app.get(media.url).document - val items = document.select("ul.seasons-lst li").mapNotNull { - val name = it?.selectFirst("h3.title")?.text() ?: "null" - val tempstring = it?.selectFirst("a")?.attr("href") ?: "null" + val title = document.selectFirst("h1.entry-title")?.text()?.trim() + ?: document.selectFirst("meta[property=og:image:alt]")?.attr("content") ?: "No Title" + val poster = fixUrlNull(document.selectFirst("div.post-thumbnail figure img")?.attr("src") ?: media.poster) + val plot = document.selectFirst("div.entry-content p")?.text()?.trim() + ?: document.selectFirst("meta[name=twitter:description]")?.attr("content") + val year = (document.selectFirst("span.year")?.text()?.trim() + ?: document.selectFirst("meta[property=og:updated_time]")?.attr("content") + ?.substringBefore("-"))?.toIntOrNull() + val lst = document.select("ul.seasons-lst li") - episodes.add( Episode(tempstring, name) ) - } - - if(items.size==0){ - val vidtoonoid = document?.selectFirst("iframe")?.attr("src") ?: "NULL" - val vidlink = app.get(vidtoonoid)?.document?.selectFirst("div iframe")?.attr("src") ?: "null" - return newMovieLoadResponse(title, vidlink, TvType.Movie, vidlink) { - this.posterUrl = poster.toString() + return if (lst.isEmpty()) { + newMovieLoadResponse(title, media.url, TvType.Movie, Media(media.url, mediaType = 1).toJson()) { + this.posterUrl = poster this.plot = plot this.year = year - //this.recommendations = recommendations } - } - - else{ - return newTvSeriesLoadResponse(title, url, TvType.TvSeries, episodes) { - this.posterUrl = poster.toString() + } else { + val episodes = document.select("ul.seasons-lst li").mapNotNull { + val name = it.selectFirst("h3.title")?.text() ?: "null" + val href = it.selectFirst("a")?.attr("href") ?: return@mapNotNull null + Episode(Media(href, mediaType = 2).toJson(), name) + } + newTvSeriesLoadResponse(title, media.url, TvType.TvSeries, episodes) { + this.posterUrl = poster this.plot = plot this.year = year - //this.recommendations = recommendations } } } @@ -113,56 +100,48 @@ class AnimeDekhoProvider : MainAPI() { data: String, isCasting: Boolean, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ): Boolean { + val media = parseJson(data) + val body = app.get(media.url).document.selectFirst("body")?.attr("class") ?: return false + val term = Regex("""(?:term|postid)-(\d+)""").find(body)?.groupValues?.get(1) ?: throw ErrorLoadingException("no id found") + val vidLink = app.get("$mainUrl/?trembed=0&trid=$term&trtype=${media.mediaType}") + .document.selectFirst("iframe")?.attr("src") + ?: throw ErrorLoadingException("no iframe found") - var vidlink = "" + val doc = app.get(vidLink).text + val master = Regex("""JScript[\w+]?\s*=\s*'([^']+)""").find(doc)!!.groupValues[1] + val decrypt = cryptoAESHandler(master, "a7igbpIApajDyNe".toByteArray(), false)?.replace("\\", "") + ?: throw ErrorLoadingException("error decrypting") + val vidFinal = Regex("""file:\s*"(https:[^"]+)"""").find(decrypt)!!.groupValues[1] - if(data.contains("https://vidxstream.xyz")){ - vidlink = data - } - else{ - - val page1 = app.get(data).document - - val name = page1?.selectFirst("body")?.attr("class") ?: "null" - - var term = Regex("""\bterm-(\d+)\b""").find(name)?.value!!?.replace("term-","") - - vidlink = app.get("https://animedekho.com/?trembed=0&trid="+term) - .document?.selectFirst("iframe")?.attr("src") ?: "null" - } - - //Log.d("TAGNAME", "vidlink $vidlink") //https://vidxstream.xyz/v/H0Rh3ixVLJKk/ - val body = app.get(vidlink).text - val master = Regex("""JScript[\w+]?\s*=\s*'([^']+)""").find(body)!!.groupValues?.get(1) - val decrypt = cryptoAESHandler(master ?: return false, "4MmH9EsZrq0WEekn".toByteArray(), false)?.replace("\\", "") ?: "ERROR" - val vidfinal = Regex("""file:\s*\"(https:[^\"]+)\"""").find(decrypt)!!.groupValues?.get(1) - - val headers = mapOf( - "accept" to "*/*", - "accept-language" to "en-US,en;q=0.5", - "Origin" to "https://vidxstream.xyz", - "Accept-Encoding" to "gzip, deflate, br", - "Connection" to "keep-alive", - //"Referer" to "https://vidxstream.xyz/", - "Sec-Fetch-Dest" to "empty", - "Sec-Fetch-Mode" to "cors", - "Sec-Fetch-Site" to "cross-site", - "user-agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0", - ) - - callback.invoke(ExtractorLink - ( - source = "Toon", - name = "Toon", - url = vidfinal!!, - referer = "https://vidxstream.xyz/", - quality = Qualities.Unknown.value, - isM3u8 = true, - headers = headers, + val headers = + mapOf( + "accept" to "*/*", + "accept-language" to "en-US,en;q=0.5", + "Origin" to serverUrl, + "Accept-Encoding" to "gzip, deflate, br", + "Connection" to "keep-alive", + // "Referer" to "https://vidxstream.xyz/", + "Sec-Fetch-Dest" to "empty", + "Sec-Fetch-Mode" to "cors", + "Sec-Fetch-Site" to "cross-site", + "user-agent" to "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0", ) + + callback.invoke( + ExtractorLink( + source = "Toon", + name = "Toon", + url = vidFinal, + referer = "$serverUrl/", + quality = Qualities.Unknown.value, + isM3u8 = true, + headers = headers, + ), ) return true } + + data class Media(val url: String, val poster: String? = null, val mediaType: Int? = null) } \ No newline at end of file