added GMovies into Sora

This commit is contained in:
hexated 2022-12-02 23:50:56 +07:00
parent f8662ed783
commit 5b55117250
4 changed files with 132 additions and 4 deletions

View file

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

View file

@ -9,6 +9,7 @@ import com.lagradost.nicehttp.Session
import com.google.gson.JsonParser import com.google.gson.JsonParser
import com.lagradost.cloudstream3.network.CloudflareKiller import com.lagradost.cloudstream3.network.CloudflareKiller
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import okhttp3.FormBody
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
val session = Session(Requests().baseClient) val session = Session(Requests().baseClient)
@ -1091,9 +1092,12 @@ object SoraExtractor : SoraStream() {
val animeId = val animeId =
app.get("$consumetZoroAPI/$japTitle") app.get("$consumetZoroAPI/$japTitle")
.parsedSafe<ConsumetSearchResponse>()?.results?.find { .parsedSafe<ConsumetSearchResponse>()?.results?.find {
val title = it.title ?: return val title = it.title ?: return
(title.equals(engTitle, true) || title.equals(japTitle, true)) && it.type == "TV" (title.equals(engTitle, true) || title.equals(
}?.id ?: return japTitle,
true
)) && it.type == "TV"
}?.id ?: return
val episodeId = app.get("$consumetZoroAPI/info?id=$animeId") val episodeId = app.get("$consumetZoroAPI/info?id=$animeId")
.parsedSafe<ConsumetDetails>()?.episodes?.find { .parsedSafe<ConsumetDetails>()?.episodes?.find {
@ -1334,8 +1338,86 @@ object SoraExtractor : SoraStream() {
} }
} }
suspend fun invokeGMovies(
title: String? = null,
year: Int? = null,
season: Int? = null,
episode: Int? = null,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val fixTitle = title.fixTitle()
val url = if (season == null) {
"$gMoviesAPI/$fixTitle-$year"
} else {
"$gMoviesAPI/$fixTitle-$year-season-$season"
}
val doc = app.get(url).document
val iframe = (if (season == null) {
doc.select("div.is-content-justification-center div.wp-block-button").map {
it.select("a").attr("href") to it.text()
}
} else {
doc.select("div.is-content-justification-center").find {
it.previousElementSibling()?.text()?.contains("episode $episode", true) == true
}?.select("div.wp-block-button")?.map {
it.select("a").attr("href") to it.text()
}
})?.filter { it.first.contains("gdtot") } ?: return
iframe.apmap { (iframeLink, title) ->
val gdBotLink = extractGdbot(iframeLink)
val iframeGdbot = app.get(
gdBotLink ?: return@apmap null
).document.selectFirst("ul.divide-y li.flex.flex-col a:contains(Drivebot)")
?.attr("href")
val driveDoc = app.get(iframeGdbot ?: return@apmap null)
val ssid = driveDoc.cookies["PHPSESSID"]
val script = driveDoc.document.selectFirst("script:containsData(var formData)")?.data()
val baseUrl = getBaseUrl(iframeGdbot)
val token = script?.substringAfter("'token', '")?.substringBefore("');")
val link = script?.substringAfter("fetch('")?.substringBefore("',").let { "$baseUrl$it" }
val body = FormBody.Builder()
.addEncoded("token", "$token")
.build()
val cookies = mapOf("PHPSESSID" to "$ssid")
val size = Regex("(?i)\\s(\\S+gb|mb)").find(title)?.groupValues?.getOrNull(1)?.let { "[$it]" } ?: ""
app.post(
link,
requestBody = body,
headers = mapOf(
"Accept" to "*/*",
"Origin" to baseUrl,
"Sec-Fetch-Site" to "same-origin"
),
cookies = cookies
).parsedSafe<GdBotLink>()?.url?.let { videoLink ->
callback.invoke(
ExtractorLink(
"GMovies $size",
"GMovies $size",
videoLink,
"",
getGMoviesQuality(title)
)
)
}
}
}
} }
data class GdBotLink(
@JsonProperty("url") val url: String? = null,
)
data class HdMovieBoxSource( data class HdMovieBoxSource(
@JsonProperty("videoUrl") val videoUrl: String? = null, @JsonProperty("videoUrl") val videoUrl: String? = null,
@JsonProperty("videoServer") val videoServer: String? = null, @JsonProperty("videoServer") val videoServer: String? = null,

View file

@ -23,6 +23,7 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.metaproviders.TmdbProvider import com.lagradost.cloudstream3.metaproviders.TmdbProvider
import com.hexated.SoraExtractor.invoZoro import com.hexated.SoraExtractor.invoZoro
import com.hexated.SoraExtractor.invokeFwatayako import com.hexated.SoraExtractor.invokeFwatayako
import com.hexated.SoraExtractor.invokeGMovies
import com.hexated.SoraExtractor.invokeLing import com.hexated.SoraExtractor.invokeLing
import com.hexated.SoraExtractor.invokeUhdmovies import com.hexated.SoraExtractor.invokeUhdmovies
import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.AppUtils.parseJson
@ -48,6 +49,7 @@ open class SoraStream : TmdbProvider() {
private const val tmdbAPI = "https://api.themoviedb.org/3" private const val tmdbAPI = "https://api.themoviedb.org/3"
private val apiKey = base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL private val apiKey = base64DecodeAPI("ZTM=NTg=MjM=MjM=ODc=MzI=OGQ=MmE=Nzk=Nzk=ZjI=NTA=NDY=NDA=MzA=YjA=") // PLEASE DON'T STEAL
const val tmdb2mal = "https://tmdb2mal.slidemovies.org" const val tmdb2mal = "https://tmdb2mal.slidemovies.org"
const val gdbot = "https://gdbot.xyz"
private val mainAPI = base64DecodeAPI("cHA=LmE=ZWw=cmM=dmU=aC4=dGM=d2E=eHA=Ly8=czo=dHA=aHQ=") private val mainAPI = base64DecodeAPI("cHA=LmE=ZWw=cmM=dmU=aC4=dGM=d2E=eHA=Ly8=czo=dHA=aHQ=")
private var mainServerAPI = base64DecodeAPI("cA==YXA=bC4=Y2U=ZXI=LnY=aWU=b3Y=LW0=cmE=c28=Ly8=czo=dHA=aHQ=") private var mainServerAPI = base64DecodeAPI("cA==YXA=bC4=Y2U=ZXI=LnY=aWU=b3Y=LW0=cmE=c28=Ly8=czo=dHA=aHQ=")
@ -72,6 +74,7 @@ open class SoraStream : TmdbProvider() {
const val lingAPI = "https://ling-online.net" const val lingAPI = "https://ling-online.net"
const val uhdmoviesAPI = "https://uhdmovies.site" const val uhdmoviesAPI = "https://uhdmovies.site"
const val fwatayakoAPI = "https://5100.svetacdn.in" const val fwatayakoAPI = "https://5100.svetacdn.in"
const val gMoviesAPI = "https://gdrivemovies.xyz"
fun getType(t: String?): TvType { fun getType(t: String?): TvType {
return when (t) { return when (t) {
@ -451,6 +454,9 @@ open class SoraStream : TmdbProvider() {
{ {
invokeFwatayako(res.imdbId, res.season, res.episode, subtitleCallback, callback) invokeFwatayako(res.imdbId, res.season, res.episode, subtitleCallback, callback)
}, },
{
invokeGMovies(res.title, res.year, res.season, res.episode, subtitleCallback, callback)
},
) )
return true return true

View file

@ -1,5 +1,7 @@
package com.hexated package com.hexated
import com.hexated.SoraStream.Companion.gdbot
import com.lagradost.cloudstream3.app
import com.lagradost.cloudstream3.base64Decode import com.lagradost.cloudstream3.base64Decode
import com.lagradost.cloudstream3.base64Encode import com.lagradost.cloudstream3.base64Encode
import com.lagradost.cloudstream3.network.WebViewResolver import com.lagradost.cloudstream3.network.WebViewResolver
@ -51,6 +53,34 @@ fun String.filterMedia(title: String?, yearNum: Int?, seasonNum: Int?): Boolean
} }
} }
suspend fun extractGdbot(url: String): String? {
val headers = mapOf(
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
)
val res = app.get(
"$gdbot/", headers = headers
)
val token = res.document.selectFirst("input[name=_token]")?.attr("value")
val cookiesSet = res.headers.filter { it.first == "set-cookie" }
val xsrf = cookiesSet.find { it.second.contains("XSRF-TOKEN") }?.second?.substringAfter("XSRF-TOKEN=")
?.substringBefore(";")
val session = cookiesSet.find { it.second.contains("gdtot_proxy_session") }?.second?.substringAfter("gdtot_proxy_session=")
?.substringBefore(";")
val cookies = mapOf(
"gdtot_proxy_session" to "$session",
"XSRF-TOKEN" to "$xsrf"
)
val requestFile = app.post(
"$gdbot/file", data = mapOf(
"link" to url,
"_token" to "$token"
), headers = headers, referer = "$gdbot/", cookies = cookies
).document
return requestFile.selectFirst("div.mt-8 a.float-right")?.attr("href")
}
suspend fun getFilmxyCookies(imdbId: String? = null, season: Int? = null): FilmxyCookies? { suspend fun getFilmxyCookies(imdbId: String? = null, season: Int? = null): FilmxyCookies? {
val url = if (season == null) { val url = if (season == null) {
@ -122,6 +152,16 @@ fun getQuality(str: String): Int {
} }
} }
fun getGMoviesQuality(str: String): Int {
return when {
str.contains("480P", true) -> Qualities.P480.value
str.contains("720P", true) -> Qualities.P720.value
str.contains("1080", true) -> Qualities.P1080.value
str.contains("4K", true) -> Qualities.P2160.value
else -> Qualities.Unknown.value
}
}
fun getBaseUrl(url: String): String { fun getBaseUrl(url: String): String {
return URI(url).let { return URI(url).let {
"${it.scheme}://${it.host}" "${it.scheme}://${it.host}"