added new sources into SoraExtractor

This commit is contained in:
hexated 2022-10-27 15:46:19 +07:00
parent c87b3dd0df
commit 5f37e5be53
3 changed files with 162 additions and 11 deletions

View File

@ -1,5 +1,5 @@
// use an integer for version numbers // use an integer for version numbers
version = 11 version = 12
cloudstream { cloudstream {

View File

@ -1,11 +1,12 @@
package com.hexated package com.hexated
import com.fasterxml.jackson.annotation.JsonProperty
import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.network.WebViewResolver import com.lagradost.cloudstream3.network.WebViewResolver
import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
import com.lagradost.nicehttp.requestCreator import com.lagradost.nicehttp.requestCreator
import java.net.URI import java.net.URI
import java.util.ArrayList
object SoraExtractor : SoraStream() { object SoraExtractor : SoraStream() {
@ -22,7 +23,7 @@ object SoraExtractor : SoraStream() {
val sourcesData = script?.substringAfter("\"sources\":[")?.substringBefore("],") val sourcesData = script?.substringAfter("\"sources\":[")?.substringBefore("],")
val subData = script?.substringAfter("\"subtitles\":[")?.substringBefore("],") val subData = script?.substringAfter("\"subtitles\":[")?.substringBefore("],")
AppUtils.tryParseJson<List<Sources>>("[$sourcesData]")?.map { source -> tryParseJson<List<Sources>>("[$sourcesData]")?.map { source ->
callback.invoke( callback.invoke(
ExtractorLink( ExtractorLink(
this.name, this.name,
@ -36,7 +37,7 @@ object SoraExtractor : SoraStream() {
) )
} }
AppUtils.tryParseJson<List<Subtitles>>("[$subData]")?.map { sub -> tryParseJson<List<Subtitles>>("[$subData]")?.map { sub ->
subtitleCallback.invoke( subtitleCallback.invoke(
SubtitleFile( SubtitleFile(
sub.lang.toString(), sub.lang.toString(),
@ -261,6 +262,21 @@ object SoraExtractor : SoraStream() {
} }
} }
suspend fun invokeDatabaseGdrive(
imdbId: String? = null,
season: Int? = null,
episode: Int? = null,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val url = if (season == null) {
"$databaseGdriveAPI/player.php?imdb=$imdbId"
} else {
"$databaseGdriveAPI/player.php?type=series&imdb=$imdbId&season=$season&episode=$episode"
}
loadExtractor(url, databaseGdriveAPI, subtitleCallback, callback)
}
suspend fun invokeSoraVIP( suspend fun invokeSoraVIP(
id: Int? = null, id: Int? = null,
season: Int? = null, season: Int? = null,
@ -350,8 +366,110 @@ object SoraExtractor : SoraStream() {
} }
suspend fun invokeHDMovieBox(
title: String? = null,
season: Int? = null,
episode: Int? = null,
callback: (ExtractorLink) -> Unit
) {
val fixTitle = title?.replace(":", "")?.replace(" ", "-")?.lowercase()
val url = "$hdMovieBoxAPI/watch/$fixTitle"
val ref = if (season == null) {
"$hdMovieBoxAPI/watch/$fixTitle"
} else {
"$hdMovieBoxAPI/watch/$fixTitle/season-$season/episode-$episode"
}
val doc = app.get(url).document
val id = if (season == null) {
doc.selectFirst("div.player div#not-loaded")?.attr("data-whatwehave")
} else {
doc.select("div.season-list-column div[data-season=$season] div.list div.item")[episode?.minus(
1
) ?: 0].selectFirst("div.ui.checkbox")?.attr("data-episode")
}
val iframeUrl = app.post(
"$hdMovieBoxAPI/ajax/service", data = mapOf(
"e_id" to "$id",
"v_lang" to "en",
"type" to "get_whatwehave",
), headers = mapOf("X-Requested-With" to "XMLHttpRequest")
).parsedSafe<HdMovieBoxIframe>()?.apiIframe ?: return
val iframe = app.get(iframeUrl, referer = "$hdMovieBoxAPI/").document.selectFirst("iframe")
?.attr("src")
val script = app.get(
iframe ?: return,
referer = "$hdMovieBoxAPI/"
).document.selectFirst("script:containsData(var vhash =)")?.data()
?.substringAfter("vhash, {")?.substringBefore("}, false")
tryParseJson<HdMovieBoxSource>("{$script}").let { source ->
val link = getBaseUrl(iframe) + source?.videoUrl?.replace(
"\\",
""
) + "?s=${source?.videoServer}&d=${base64Encode(source?.videoDisk?.toByteArray() ?: return)}"
callback.invoke(
ExtractorLink(
"HDMovieBox",
"HDMovieBox",
link,
iframe,
Qualities.P1080.value,
isM3u8 = true,
)
)
}
}
suspend fun invokeSeries9(
title: String? = null,
season: Int? = null,
episode: Int? = null,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val fixTitle = title?.replace(":", "")?.replace(" ", "-")?.lowercase()
val url = if (season == null) {
"$series9API/film/$fixTitle/watching.html"
} else {
"$series9API/film/$fixTitle-season-$season/watching.html"
}
val res = app.get(url).document
val sources : ArrayList<String?> = arrayListOf()
if (season == null) {
val xstreamcdn = res.selectFirst("div#list-eps div#server-29 a")?.attr("player-data")?.let {
Regex("(.*?)((\\?cap)|(\\?sub)|(#cap)|(#sub))").find(it)?.groupValues?.get(1)
}
val streamsb = res.selectFirst("div#list-eps div#server-13 a")?.attr("player-data")
val doodstream = res.selectFirst("div#list-eps div#server-14 a")?.attr("player-data")
sources.addAll(listOf(xstreamcdn, streamsb, doodstream))
} else {
val xstreamcdn = res.selectFirst("div#list-eps div#server-29 a[episode-data=$episode]")?.attr("player-data")?.let {
Regex("(.*?)((\\?cap)|(\\?sub)|(#cap)|(#sub))").find(it)?.groupValues?.get(1)
}
val streamsb = res.selectFirst("div#list-eps div#server-13 a[episode-data=$episode]")?.attr("player-data")
val doodstream = res.selectFirst("div#list-eps div#server-14 a[episode-data=$episode]")?.attr("player-data")
sources.addAll(listOf(xstreamcdn, streamsb, doodstream))
}
sources.apmap { link ->
loadExtractor(link ?: return@apmap null, url, subtitleCallback, callback)
}
}
} }
//private fun getHdMovieBoxUrl(link: String?): String? {
// if (link == null) return null
// return if (link.startsWith("/")) "https://image.tmdb.org/t/p/w500/$link" else link
//}
private fun getQuality(str: String): Int { private fun getQuality(str: String): Int {
return when (str) { return when (str) {
"360p" -> Qualities.P240.value "360p" -> Qualities.P240.value
@ -424,3 +542,13 @@ suspend fun loadLinksWithWebView(
) )
} }
data class HdMovieBoxSource(
@JsonProperty("videoUrl") val videoUrl: String? = null,
@JsonProperty("videoServer") val videoServer: String? = null,
@JsonProperty("videoDisk") val videoDisk: String? = null,
)
data class HdMovieBoxIframe(
@JsonProperty("api_iframe") val apiIframe: String? = null,
)

View File

@ -3,11 +3,14 @@ package com.hexated
import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.annotation.JsonProperty
import com.hexated.RandomUserAgent.getRandomUserAgent import com.hexated.RandomUserAgent.getRandomUserAgent
import com.hexated.SoraExtractor.invoke123Movie import com.hexated.SoraExtractor.invoke123Movie
import com.hexated.SoraExtractor.invokeDatabaseGdrive
import com.hexated.SoraExtractor.invokeDbgo import com.hexated.SoraExtractor.invokeDbgo
import com.hexated.SoraExtractor.invokeGogo import com.hexated.SoraExtractor.invokeGogo
import com.hexated.SoraExtractor.invokeHDMovieBox
import com.hexated.SoraExtractor.invokeLocalSources import com.hexated.SoraExtractor.invokeLocalSources
import com.hexated.SoraExtractor.invokeMovieHab import com.hexated.SoraExtractor.invokeMovieHab
import com.hexated.SoraExtractor.invokeOlgply import com.hexated.SoraExtractor.invokeOlgply
import com.hexated.SoraExtractor.invokeSeries9
import com.hexated.SoraExtractor.invokeSoraVIP import com.hexated.SoraExtractor.invokeSoraVIP
import com.hexated.SoraExtractor.invokeTwoEmbed import com.hexated.SoraExtractor.invokeTwoEmbed
import com.hexated.SoraExtractor.invokeVidSrc import com.hexated.SoraExtractor.invokeVidSrc
@ -15,7 +18,6 @@ import com.lagradost.cloudstream3.*
import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId import com.lagradost.cloudstream3.LoadResponse.Companion.addAniListId
import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId import com.lagradost.cloudstream3.LoadResponse.Companion.addMalId
import com.lagradost.cloudstream3.metaproviders.TmdbProvider import com.lagradost.cloudstream3.metaproviders.TmdbProvider
import com.lagradost.cloudstream3.mvvm.safeApiCall
import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.toJson import com.lagradost.cloudstream3.utils.AppUtils.toJson
import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLink
@ -46,6 +48,9 @@ open class SoraStream : TmdbProvider() {
const val dbgoAPI = "https://dbgo.fun" const val dbgoAPI = "https://dbgo.fun"
const val movie123API = "https://api.123movie.cc" const val movie123API = "https://api.123movie.cc"
const val movieHabAPI = "https://moviehab.com" const val movieHabAPI = "https://moviehab.com"
const val databaseGdriveAPI = "https://databasegdriveplayer.co"
const val hdMovieBoxAPI = "https://hdmoviebox.net"
const val series9API = "https://series9.la"
fun getType(t: String?): TvType { fun getType(t: String?): TvType {
return when (t) { return when (t) {
@ -186,6 +191,7 @@ open class SoraStream : TmdbProvider() {
.parsedSafe<Detail>()?.pageProps .parsedSafe<Detail>()?.pageProps
?: throw ErrorLoadingException("Invalid Json Response") ?: throw ErrorLoadingException("Invalid Json Response")
val res = responses.result ?: return null val res = responses.result ?: return null
val title = res.title ?: res.name ?: res.originalTitle ?: res.originalName ?: return null
val type = getType(data.type) val type = getType(data.type)
val actors = responses.cast?.mapNotNull { cast -> val actors = responses.cast?.mapNotNull { cast ->
ActorData( ActorData(
@ -210,7 +216,8 @@ open class SoraStream : TmdbProvider() {
responses.imdbId, responses.imdbId,
data.type, data.type,
eps.seasonNumber, eps.seasonNumber,
eps.episodeNumber eps.episodeNumber,
title = title,
).toJson(), ).toJson(),
name = eps.name, name = eps.name,
season = eps.seasonNumber, season = eps.seasonNumber,
@ -224,7 +231,7 @@ open class SoraStream : TmdbProvider() {
} }
} }
newTvSeriesLoadResponse( newTvSeriesLoadResponse(
res.title ?: res.name ?: res.originalTitle ?: res.originalName ?: return null, title,
url, url,
TvType.TvSeries, TvType.TvSeries,
episodes episodes
@ -240,13 +247,14 @@ open class SoraStream : TmdbProvider() {
} }
} else { } else {
newMovieLoadResponse( newMovieLoadResponse(
res.title ?: res.name ?: res.originalTitle ?: res.originalName ?: return null, title,
url, url,
TvType.Movie, TvType.Movie,
LinkData( LinkData(
data.id, data.id,
responses.imdbId, responses.imdbId,
data.type, data.type,
title = title,
).toJson(), ).toJson(),
) { ) {
this.posterUrl = getImageUrl(res.posterPath) this.posterUrl = getImageUrl(res.posterPath)
@ -341,11 +349,25 @@ open class SoraStream : TmdbProvider() {
{ {
invokeMovieHab(res.id, res.season, res.episode, subtitleCallback, callback) invokeMovieHab(res.id, res.season, res.episode, subtitleCallback, callback)
}, },
// {
// invokeDatabaseGdrive(
// res.imdbId,
// res.season,
// res.episode,
// subtitleCallback,
// callback
// )
// },
{ {
if (res.aniId?.isNotEmpty() == true) invokeGogo(res.aniId, res.animeId, callback) if (res.aniId?.isNotEmpty() == true) invokeGogo(res.aniId, res.animeId, callback)
}) },
{
invokeHDMovieBox(res.title, res.season, res.episode, callback)
},
{
invokeSeries9(res.title, res.season, res.episode, subtitleCallback, callback)
}
)
return true return true
} }
@ -358,6 +380,7 @@ open class SoraStream : TmdbProvider() {
val episode: Int? = null, val episode: Int? = null,
val aniId: String? = null, val aniId: String? = null,
val animeId: String? = null, val animeId: String? = null,
val title: String? = null,
) )
data class Data( data class Data(