mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
added GMovies into Sora
This commit is contained in:
parent
f8662ed783
commit
5b55117250
4 changed files with 132 additions and 4 deletions
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 41
|
version = 42
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -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)
|
||||||
|
@ -1092,7 +1093,10 @@ object SoraExtractor : SoraStream() {
|
||||||
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(
|
||||||
|
japTitle,
|
||||||
|
true
|
||||||
|
)) && it.type == "TV"
|
||||||
}?.id ?: return
|
}?.id ?: return
|
||||||
|
|
||||||
val episodeId = app.get("$consumetZoroAPI/info?id=$animeId")
|
val episodeId = app.get("$consumetZoroAPI/info?id=$animeId")
|
||||||
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}"
|
||||||
|
|
Loading…
Reference in a new issue