added Animesaga

This commit is contained in:
jack 2023-12-10 02:06:33 +07:00
parent 96c8017fe8
commit 9b05f65f2c
6 changed files with 123 additions and 81 deletions

View file

@ -1,12 +1,12 @@
// use an integer for version numbers // use an integer for version numbers
version = 54 version = 55
cloudstream { cloudstream {
language = "hi" language = "hi"
// All of these properties are optional, you can safely remove them // All of these properties are optional, you can safely remove them
description = "Include: Hdmovie2" description = "Includes: Hdmovie2, Animesaga"
authors = listOf("Hexated") authors = listOf("Hexated")
/** /**

View file

@ -0,0 +1,17 @@
package com.hexated
import com.lagradost.cloudstream3.mainPageOf
class Animesaga : Movierulzhd() {
override var mainUrl = "https://www.animesaga.in"
override var name = "Animesaga"
override val mainPage = mainPageOf(
"movies" to "Movies",
"tvshows" to "TV-Shows",
"genre/hindi-dub" to "Hindi Dub",
)
}

View file

@ -2,10 +2,9 @@ package com.hexated
import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.SubtitleFile
import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.extractors.Chillx
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
const val twoEmbedAPI = "https://www.2embed.to"
class Sbnmp : ExtractorApi() { class Sbnmp : ExtractorApi() {
override val name = "Sbnmp" override val name = "Sbnmp"
override var mainUrl = "https://sbnmp.bar" override var mainUrl = "https://sbnmp.bar"
@ -66,3 +65,8 @@ open class Akamaicdn : ExtractorApi() {
) )
} }
} }
class AnimesagaStream : Chillx() {
override val name = "AnimesagaStream"
override val mainUrl = "https://stream.animesaga.in"
}

View file

@ -45,7 +45,7 @@ open class Movierulzhd : MainAPI() {
document = app.get(request.data + page, interceptor = interceptor).document document = app.get(request.data + page, interceptor = interceptor).document
} }
val home = val home =
document.select("div.items.normal article, div#archive-content article").mapNotNull { document.select("div.items.normal article, div#archive-content article, div.items.full article").mapNotNull {
it.toSearchResult() it.toSearchResult()
} }
return newHomePageResponse(request.name, home) return newHomePageResponse(request.name, home)
@ -74,7 +74,7 @@ open class Movierulzhd : MainAPI() {
private fun Element.toSearchResult(): SearchResponse? { private fun Element.toSearchResult(): SearchResponse? {
val title = this.selectFirst("h3 > a")?.text() ?: return null val title = this.selectFirst("h3 > a")?.text() ?: return null
val href = getProperLink(fixUrl(this.selectFirst("h3 > a")!!.attr("href"))) val href = getProperLink(fixUrl(this.selectFirst("h3 > a")!!.attr("href")))
val posterUrl = fixUrlNull(this.select("div.poster img").last()?.attr("src")) val posterUrl = fixUrlNull(this.select("div.poster img").last()?.imageFromElement())
val quality = getQualityFromString(this.select("span.quality").text()) val quality = getQualityFromString(this.select("span.quality").text())
return newMovieSearchResponse(title, href, TvType.Movie) { return newMovieSearchResponse(title, href, TvType.Movie) {
this.posterUrl = posterUrl this.posterUrl = posterUrl
@ -112,7 +112,7 @@ open class Movierulzhd : MainAPI() {
directUrl = getBaseUrl(request.url) directUrl = getBaseUrl(request.url)
val title = val title =
document.selectFirst("div.data > h1")?.text()?.trim().toString() document.selectFirst("div.data > h1")?.text()?.trim().toString()
val poster = fixUrlNull(document.select("div.poster img:last-child").attr("src")) val poster = fixUrlNull(document.selectFirst("div.poster img:last-child")?.imageFromElement())
val tags = document.select("div.sgeneros > a").map { it.text() } val tags = document.select("div.sgeneros > a").map { it.text() }
val year = Regex(",\\s?(\\d+)").find( val year = Regex(",\\s?(\\d+)").find(
@ -139,7 +139,7 @@ open class Movierulzhd : MainAPI() {
val recName = val recName =
it.selectFirst("a")!!.attr("href").toString().removeSuffix("/").split("/").last() it.selectFirst("a")!!.attr("href").toString().removeSuffix("/").split("/").last()
val recHref = it.selectFirst("a")!!.attr("href") val recHref = it.selectFirst("a")!!.attr("href")
val recPosterUrl = it.selectFirst("img")?.attr("src").toString() val recPosterUrl = it.selectFirst("img")?.imageFromElement()
newTvSeriesSearchResponse(recName, recHref, TvType.TvSeries) { newTvSeriesSearchResponse(recName, recHref, TvType.TvSeries) {
this.posterUrl = recPosterUrl this.posterUrl = recPosterUrl
posterHeaders = interceptor.getCookieHeaders(url).toMap() posterHeaders = interceptor.getCookieHeaders(url).toMap()
@ -151,7 +151,7 @@ open class Movierulzhd : MainAPI() {
document.select("ul.episodios > li").map { document.select("ul.episodios > li").map {
val href = it.select("a").attr("href") val href = it.select("a").attr("href")
val name = fixTitle(it.select("div.episodiotitle > a").text().trim()) val name = fixTitle(it.select("div.episodiotitle > a").text().trim())
val image = it.select("div.imagen > img").attr("src") val image = it.selectFirst("div.imagen > img")?.imageFromElement()
val episode = val episode =
it.select("div.numerando").text().replace(" ", "").split("-").last() it.select("div.numerando").text().replace(" ", "").split("-").last()
.toIntOrNull() .toIntOrNull()
@ -230,18 +230,20 @@ open class Movierulzhd : MainAPI() {
referer = data, referer = data,
headers = mapOf("X-Requested-With" to "XMLHttpRequest") headers = mapOf("X-Requested-With" to "XMLHttpRequest")
).parsed<ResponseHash>().embed_url ).parsed<ResponseHash>().embed_url
if (!source.contains("youtube")) loadCustomExtractor(loadData?.tag, source, "$directUrl/", subtitleCallback, callback) if (!source.contains("youtube")) loadExtractor(source, "$directUrl/", subtitleCallback, callback)
} else { } else {
var document = app.get(data).document var document = app.get(data).document
if (document.select("title").text() == "Just a moment...") { if (document.select("title").text() == "Just a moment...") {
document = app.get(data, interceptor = interceptor).document document = app.get(data, interceptor = interceptor).document
} }
val id = document.select("meta#dooplay-ajax-counter").attr("data-postid")
val type = if (data.contains("/movies/")) "movie" else "tv"
document.select("ul#playeroptionsul > li").map { document.select("ul#playeroptionsul > li").map {
it.attr("data-nume") to it.select("span.title").text() Triple(
}.apmap { (nume, tag) -> it.attr("data-post"),
it.attr("data-nume"),
it.attr("data-type")
)
}.apmap { (id, nume, type) ->
val source = app.post( val source = app.post(
url = "$directUrl/wp-admin/admin-ajax.php", url = "$directUrl/wp-admin/admin-ajax.php",
data = mapOf( data = mapOf(
@ -255,8 +257,7 @@ open class Movierulzhd : MainAPI() {
).parsed<ResponseHash>().embed_url ).parsed<ResponseHash>().embed_url
when { when {
!source.contains("youtube") -> loadCustomExtractor( !source.contains("youtube") -> loadExtractor(
tag,
source, source,
"$directUrl/", "$directUrl/",
subtitleCallback, subtitleCallback,
@ -269,30 +270,12 @@ open class Movierulzhd : MainAPI() {
return true return true
} }
private suspend fun loadCustomExtractor( private fun Element.imageFromElement(): String? {
name: String? = null, return when {
url: String, this.hasAttr("data-src") -> this.attr("abs:data-src")
referer: String? = null, this.hasAttr("data-lazy-src") -> this.attr("abs:data-lazy-src")
subtitleCallback: (SubtitleFile) -> Unit, this.hasAttr("srcset") -> this.attr("abs:srcset").substringBefore(" ")
callback: (ExtractorLink) -> Unit, else -> this.attr("abs:src")
quality: Int? = null,
) {
loadExtractor(url, referer, subtitleCallback) { link ->
callback.invoke(
ExtractorLink(
name ?: link.source,
name ?: link.name,
link.url,
link.referer,
when (link.type) {
ExtractorLinkType.M3U8 -> link.quality
else -> quality ?: link.quality
},
link.type,
link.headers,
link.extractorData
)
)
} }
} }

View file

@ -11,7 +11,9 @@ class MovierulzhdPlugin: Plugin() {
// All providers should be added in this manner. Please don't edit the providers list directly. // All providers should be added in this manner. Please don't edit the providers list directly.
registerMainAPI(Movierulzhd()) registerMainAPI(Movierulzhd())
registerMainAPI(Hdmovie2()) registerMainAPI(Hdmovie2())
registerMainAPI(Animesaga())
registerExtractorAPI(Sbnmp()) registerExtractorAPI(Sbnmp())
registerExtractorAPI(Akamaicdn()) registerExtractorAPI(Akamaicdn())
registerExtractorAPI(AnimesagaStream())
} }
} }

View file

@ -8,9 +8,11 @@ import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import com.lagradost.nicehttp.Requests import com.lagradost.nicehttp.Requests
import com.lagradost.nicehttp.Session import com.lagradost.nicehttp.Session
import com.lagradost.cloudstream3.extractors.helper.AesHelper.cryptoAESHandler import com.lagradost.cloudstream3.extractors.helper.AesHelper.cryptoAESHandler
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
import com.lagradost.cloudstream3.network.CloudflareKiller import com.lagradost.cloudstream3.network.CloudflareKiller
import com.lagradost.nicehttp.RequestBodyTypes import com.lagradost.nicehttp.RequestBodyTypes
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import org.jsoup.Jsoup import org.jsoup.Jsoup
@ -110,7 +112,8 @@ object SoraExtractor : SoraStream() {
"$vidSrcAPI/embed/tv?tmdb=$id&season=$season&episode=$episode" "$vidSrcAPI/embed/tv?tmdb=$id&season=$season&episode=$episode"
} }
val iframedoc = app.get(url).document.select("iframe#player_iframe").attr("src").let { httpsify(it) } val iframedoc =
app.get(url).document.select("iframe#player_iframe").attr("src").let { httpsify(it) }
val doc = app.get(iframedoc, referer = url).document val doc = app.get(iframedoc, referer = url).document
val index = doc.select("body").attr("data-i") val index = doc.select("body").attr("data-i")
@ -680,12 +683,20 @@ object SoraExtractor : SoraStream() {
"$vidsrctoAPI/embed/tv/$imdbId/$season/$episode" "$vidsrctoAPI/embed/tv/$imdbId/$season/$episode"
} }
val mediaId = app.get(url).document.selectFirst("ul.episodes li a")?.attr("data-id") ?: return val mediaId =
app.get(url).document.selectFirst("ul.episodes li a")?.attr("data-id") ?: return
app.get("$vidsrctoAPI/ajax/embed/episode/$mediaId/sources").parsedSafe<VidsrctoSources>()?.result?.apmap { app.get("$vidsrctoAPI/ajax/embed/episode/$mediaId/sources")
val encUrl = app.get("$vidsrctoAPI/ajax/embed/source/${it.id}").parsedSafe<VidsrctoResponse>()?.result?.url .parsedSafe<VidsrctoSources>()?.result?.apmap {
loadExtractor(vidsrctoDecrypt(encUrl ?: return@apmap), "$vidsrctoAPI/", subtitleCallback, callback) val encUrl = app.get("$vidsrctoAPI/ajax/embed/source/${it.id}")
} .parsedSafe<VidsrctoResponse>()?.result?.url
loadExtractor(
vidsrctoDecrypt(encUrl ?: return@apmap),
"$vidsrctoAPI/",
subtitleCallback,
callback
)
}
val subtitles = app.get("$vidsrctoAPI/ajax/embed/episode/$mediaId/subtitles").text val subtitles = app.get("$vidsrctoAPI/ajax/embed/episode/$mediaId/subtitles").text
tryParseJson<List<VidsrctoSubtitles>>(subtitles)?.map { tryParseJson<List<VidsrctoSubtitles>>(subtitles)?.map {
@ -1107,30 +1118,32 @@ object SoraExtractor : SoraStream() {
val sTag = if (season == null) "" else "(Season $season|S$seasonSlug)" val sTag = if (season == null) "" else "(Season $season|S$seasonSlug)"
res.select("div.entry-content > $hTag:matches((?i)$sTag.*(1080p|2160p))") res.select("div.entry-content > $hTag:matches((?i)$sTag.*(1080p|2160p))")
.filter { element -> !element.text().contains("Download", true) }.apmap { .filter { element -> !element.text().contains("Download", true) }.apmap {
val tags = val tags =
"""(?:1080p|2160p)(.*)""".toRegex().find(it.text())?.groupValues?.get(1)?.trim() """(?:1080p|2160p)(.*)""".toRegex().find(it.text())?.groupValues?.get(1)?.trim()
val href = val href =
it.nextElementSibling()?.select("a:contains($aTag)")?.attr("href")?.let { url -> it.nextElementSibling()?.select("a:contains($aTag)")?.attr("href")?.let { url ->
app.post( app.post(
"${getBaseUrl(url)}/red.php", "${getBaseUrl(url)}/red.php",
data = mapOf("link" to url), data = mapOf("link" to url),
referer = "$api/" referer = "$api/"
).text.substringAfter("location.href = \"").substringBefore("\"") ).text.substringAfter("location.href = \"").substringBefore("\"")
} }
val selector = val selector =
if (season == null) "p a:contains(V-Cloud)" else "h4:matches(0?$episode) + p a:contains(V-Cloud)" if (season == null) "p a:contains(V-Cloud)" else "h4:matches(0?$episode) + p a:contains(V-Cloud)"
val server = val server =
app.get(href ?: return@apmap).document.selectFirst("div.entry-content > $selector") app.get(
?.attr("href") href ?: return@apmap
loadCustomTagExtractor( ).document.selectFirst("div.entry-content > $selector")
tags, ?.attr("href")
server ?: return@apmap, loadCustomTagExtractor(
"$api/", tags,
subtitleCallback, server ?: return@apmap,
callback, "$api/",
getIndexQuality(it.text()) subtitleCallback,
) callback,
} getIndexQuality(it.text())
)
}
} }
suspend fun invokeHdmovies4u( suspend fun invokeHdmovies4u(
@ -1207,7 +1220,14 @@ object SoraExtractor : SoraStream() {
iframe.apmap { (iframeLink, title) -> iframe.apmap { (iframeLink, title) ->
val size = Regex("(?i)\\s(\\S+gb|mb)").find(title)?.groupValues?.getOrNull(1) val size = Regex("(?i)\\s(\\S+gb|mb)").find(title)?.groupValues?.getOrNull(1)
loadCustomTagExtractor("[$size]",iframeLink, "$gMoviesAPI/", subtitleCallback, callback, getIndexQuality(title)) loadCustomTagExtractor(
"[$size]",
iframeLink,
"$gMoviesAPI/",
subtitleCallback,
callback,
getIndexQuality(title)
)
} }
} }
@ -1298,7 +1318,9 @@ object SoraExtractor : SoraStream() {
scriptData.firstOrNull() scriptData.firstOrNull()
} else { } else {
scriptData.find { scriptData.find {
it.first.contains(Regex("(?i)$title \\($year\\s?\\)")) && if(season!=null) it.third?.contains("-tvshow-") == true else it.third?.contains("-movie-") == true it.first.contains(Regex("(?i)$title \\($year\\s?\\)")) && if (season != null) it.third?.contains(
"-tvshow-"
) == true else it.third?.contains("-movie-") == true
} }
} }
@ -1521,10 +1543,16 @@ object SoraExtractor : SoraStream() {
iframe?.apmap { iframe?.apmap {
val iframeDoc = app.get(it?.first ?: return@apmap).document val iframeDoc = app.get(it?.first ?: return@apmap).document
val formUrl = iframeDoc.select("form").attr("action") val formUrl = iframeDoc.select("form").attr("action")
val formData = iframeDoc.select("form button").associate { v -> v.attr("name") to v.attr("value") } val formData =
iframeDoc.select("form button").associate { v -> v.attr("name") to v.attr("value") }
val videoUrl = app.post(formUrl, data = formData, referer = it.first).document.selectFirst("div.d-flex.justify-content-center.flex-wrap a")?.attr("href") val videoUrl = app.post(
val quality = Regex("(\\d{3,4})p").find(it.second)?.groupValues?.getOrNull(1)?.toIntOrNull() formUrl,
data = formData,
referer = it.first
).document.selectFirst("div.d-flex.justify-content-center.flex-wrap a")?.attr("href")
val quality =
Regex("(\\d{3,4})p").find(it.second)?.groupValues?.getOrNull(1)?.toIntOrNull()
val qualityName = it.second.replace("${quality}p", "").trim() val qualityName = it.second.replace("${quality}p", "").trim()
callback.invoke( callback.invoke(
@ -1640,9 +1668,11 @@ object SoraExtractor : SoraStream() {
"Player F" -> { "Player F" -> {
invokeSmashyFfix(it.second, it.first, url, callback) invokeSmashyFfix(it.second, it.first, url, callback)
} }
"Player D (Hindi)" -> { "Player D (Hindi)" -> {
invokeSmashyD(it.first, url, callback) invokeSmashyD(it.first, url, callback)
} }
else -> return@apmap else -> return@apmap
} }
} }
@ -1917,7 +1947,8 @@ object SoraExtractor : SoraStream() {
"$twoEmbedAPI/embedtv/$imdbId&s=$season&e=$episode" "$twoEmbedAPI/embedtv/$imdbId&s=$season&e=$episode"
} }
val framesrc = app.get(url).document.selectFirst("iframe#iframesrc")?.attr("data-src") ?: return val framesrc =
app.get(url).document.selectFirst("iframe#iframesrc")?.attr("data-src") ?: return
val ref = getBaseUrl(framesrc) val ref = getBaseUrl(framesrc)
val id = framesrc.substringAfter("id=").substringBefore("&") val id = framesrc.substringAfter("id=").substringBefore("&")
loadExtractor("https://wishfast.top/e/$id", "$ref/", subtitleCallback, callback) loadExtractor("https://wishfast.top/e/$id", "$ref/", subtitleCallback, callback)
@ -2069,9 +2100,12 @@ object SoraExtractor : SoraStream() {
"$blackvidAPI/v3/tv/sources/$tmdbId/$season/$episode?key=$key" "$blackvidAPI/v3/tv/sources/$tmdbId/$season/$episode?key=$key"
} }
val res = app.get(url, timeout = 120L, referer = ref).okhttpResponse.peekBody(1024 * 512) val data = app.get(
delay(2000) url,
val data = res.bytes().decrypt("2378f8e4e844f2dc839ab48f66e00acc2305a401") timeout = 120L,
referer = ref
).okhttpResponse.peekBody(1024 * 512).source().buffer.readByteArray()
.decrypt("2378f8e4e844f2dc839ab48f66e00acc2305a401")
val json = tryParseJson<BlackvidResponses>(data) val json = tryParseJson<BlackvidResponses>(data)
json?.sources?.map { source -> json?.sources?.map { source ->
@ -2260,9 +2294,11 @@ object SoraExtractor : SoraStream() {
) { ) {
val referer = "https://bflix.gs/" val referer = "https://bflix.gs/"
val slug = getEpisodeSlug(season, episode) val slug = getEpisodeSlug(season, episode)
var url = if (season == null) "$nowTvAPI/$tmdbId.mp4" else "$nowTvAPI/tv/$tmdbId/s${season}e${slug.second}.mp4" var url =
if (season == null) "$nowTvAPI/$tmdbId.mp4" else "$nowTvAPI/tv/$tmdbId/s${season}e${slug.second}.mp4"
if (!app.get(url, referer = referer).isSuccessful) { if (!app.get(url, referer = referer).isSuccessful) {
url = if (season == null) "$nowTvAPI/$imdbId.mp4" else "$nowTvAPI/tv/$imdbId/s${season}e${slug.second}.mp4" url =
if (season == null) "$nowTvAPI/$imdbId.mp4" else "$nowTvAPI/tv/$imdbId/s${season}e${slug.second}.mp4"
if (!app.get(url, referer = referer).isSuccessful) return if (!app.get(url, referer = referer).isSuccessful) return
} }
callback.invoke( callback.invoke(