mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
sora-lite: added Gomovies
This commit is contained in:
parent
812d0f28ba
commit
5eafdd6e4b
5 changed files with 129 additions and 3 deletions
|
@ -1,5 +1,5 @@
|
||||||
// use an integer for version numbers
|
// use an integer for version numbers
|
||||||
version = 89
|
version = 90
|
||||||
|
|
||||||
|
|
||||||
cloudstream {
|
cloudstream {
|
||||||
|
|
|
@ -2415,6 +2415,88 @@ object SoraExtractor : SoraStream() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun invokeGomovies(
|
||||||
|
title: String? = null,
|
||||||
|
year: Int? = null,
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null,
|
||||||
|
callback: (ExtractorLink) -> Unit,
|
||||||
|
) {
|
||||||
|
val query = if (season == null) {
|
||||||
|
title
|
||||||
|
} else {
|
||||||
|
"$title Season $season"
|
||||||
|
}
|
||||||
|
|
||||||
|
val doc = app.get("$gomoviesAPI/search/$query").document
|
||||||
|
|
||||||
|
val media = doc.select("div._gory div.g_yFsxmKnYLvpKDTrdbizeYMWy").map {
|
||||||
|
Triple(
|
||||||
|
it.attr("data-filmName"),
|
||||||
|
it.attr("data-year"),
|
||||||
|
it.select("a").attr("href")
|
||||||
|
)
|
||||||
|
}.find {
|
||||||
|
if (season == null) {
|
||||||
|
(it.first.equals(title, true) || it.first.equals(
|
||||||
|
"$title ($year)",
|
||||||
|
true
|
||||||
|
)) && it.second.equals("$year")
|
||||||
|
} else {
|
||||||
|
it.first.equals("$title - Season $season", true) && it.second.equals("$year")
|
||||||
|
}
|
||||||
|
} ?: return
|
||||||
|
|
||||||
|
val iframe = if (season == null) {
|
||||||
|
media.third
|
||||||
|
} else {
|
||||||
|
app.get(
|
||||||
|
fixUrl(
|
||||||
|
media.third,
|
||||||
|
gomoviesAPI
|
||||||
|
)
|
||||||
|
).document.selectFirst("div#g_MXOzFGouZrOAUioXjpddqkZK a:nth-child($episode)")
|
||||||
|
?.attr("href")
|
||||||
|
} ?: return
|
||||||
|
|
||||||
|
val res = app.get(fixUrl(iframe, gomoviesAPI), verify = false)
|
||||||
|
val match = "var url = '(/user/servers/.*?\\?ep=.*?)';".toRegex().find(res.text)
|
||||||
|
val serverUrl = match?.groupValues?.get(1) ?: return
|
||||||
|
val cookies = res.okhttpResponse.headers.getPutlockerCookies()
|
||||||
|
val url = res.document.select("meta[property=og:url]").attr("content")
|
||||||
|
val headers = mapOf("X-Requested-With" to "XMLHttpRequest")
|
||||||
|
val qualities = intArrayOf(2160, 1440, 1080, 720, 480, 360)
|
||||||
|
app.get(
|
||||||
|
"$gomoviesAPI$serverUrl",
|
||||||
|
cookies = cookies, referer = url, headers = headers
|
||||||
|
).document.select("ul li").amap { el ->
|
||||||
|
val server = el.attr("data-value")
|
||||||
|
val encryptedData = app.get(
|
||||||
|
"$url?server=$server&_=${System.currentTimeMillis()}",
|
||||||
|
cookies = cookies,
|
||||||
|
referer = url,
|
||||||
|
headers = headers
|
||||||
|
).text
|
||||||
|
val json = base64Decode(encryptedData).putlockerDecrypt()
|
||||||
|
val links = tryParseJson<List<GomoviesSources>>(json) ?: return@amap
|
||||||
|
links.forEach { video ->
|
||||||
|
qualities.filter { it <= video.max.toInt() }.forEach {
|
||||||
|
callback(
|
||||||
|
ExtractorLink(
|
||||||
|
"Gomovies",
|
||||||
|
"Gomovies",
|
||||||
|
video.src.split("360", limit = 3).joinToString(it.toString()),
|
||||||
|
"$gomoviesAPI/",
|
||||||
|
it
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamM4u : XStreamCdn() {
|
class StreamM4u : XStreamCdn() {
|
||||||
|
@ -2453,6 +2535,14 @@ data class Movie123Search(
|
||||||
@JsonProperty("data") val data: ArrayList<Movie123Data>? = arrayListOf(),
|
@JsonProperty("data") val data: ArrayList<Movie123Data>? = arrayListOf(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
data class GomoviesSources(
|
||||||
|
@JsonProperty("src") val src: String,
|
||||||
|
@JsonProperty("file") val file: String? = null,
|
||||||
|
@JsonProperty("label") val label: Int? = null,
|
||||||
|
@JsonProperty("max") val max: String,
|
||||||
|
@JsonProperty("size") val size: String,
|
||||||
|
)
|
||||||
|
|
||||||
data class UHDBackupUrl(
|
data class UHDBackupUrl(
|
||||||
@JsonProperty("url") val url: String? = null,
|
@JsonProperty("url") val url: String? = null,
|
||||||
)
|
)
|
||||||
|
|
|
@ -110,6 +110,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
const val movie123NetAPI = "https://ww7.0123movie.net"
|
const val movie123NetAPI = "https://ww7.0123movie.net"
|
||||||
const val smashyStreamAPI = "https://embed.smashystream.com"
|
const val smashyStreamAPI = "https://embed.smashystream.com"
|
||||||
const val watchSomuchAPI = "https://watchsomuch.tv" // sub only
|
const val watchSomuchAPI = "https://watchsomuch.tv" // sub only
|
||||||
|
const val gomoviesAPI = "https://gomovies-online.com"
|
||||||
const val baymoviesAPI = "https://opengatewayindex.pages.dev" // dead
|
const val baymoviesAPI = "https://opengatewayindex.pages.dev" // dead
|
||||||
const val chillmovies0API = "https://chill.aicirou.workers.dev/0:" // dead
|
const val chillmovies0API = "https://chill.aicirou.workers.dev/0:" // dead
|
||||||
const val chillmovies1API = "https://chill.aicirou.workers.dev/1:" // dead
|
const val chillmovies1API = "https://chill.aicirou.workers.dev/1:" // dead
|
||||||
|
@ -709,7 +710,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
res.episode,
|
res.episode,
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
},
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -8,6 +8,7 @@ import com.hexated.SoraExtractor.invokeFilmxy
|
||||||
import com.hexated.SoraExtractor.invokeFlixhq
|
import com.hexated.SoraExtractor.invokeFlixhq
|
||||||
import com.hexated.SoraExtractor.invokeFlixon
|
import com.hexated.SoraExtractor.invokeFlixon
|
||||||
import com.hexated.SoraExtractor.invokeFwatayako
|
import com.hexated.SoraExtractor.invokeFwatayako
|
||||||
|
import com.hexated.SoraExtractor.invokeGomovies
|
||||||
import com.hexated.SoraExtractor.invokeHDMovieBox
|
import com.hexated.SoraExtractor.invokeHDMovieBox
|
||||||
import com.hexated.SoraExtractor.invokeIdlix
|
import com.hexated.SoraExtractor.invokeIdlix
|
||||||
import com.hexated.SoraExtractor.invokeKimcartoon
|
import com.hexated.SoraExtractor.invokeKimcartoon
|
||||||
|
@ -207,6 +208,9 @@ class SoraStreamLite : SoraStream() {
|
||||||
{
|
{
|
||||||
invokeFlixon(res.id, res.imdbId, res.season, res.episode, callback)
|
invokeFlixon(res.id, res.imdbId, res.season, res.episode, callback)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
invokeGomovies(res.title, res.year, res.season, res.episode, callback)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -16,6 +16,7 @@ import com.lagradost.nicehttp.RequestBodyTypes
|
||||||
import com.lagradost.nicehttp.requestCreator
|
import com.lagradost.nicehttp.requestCreator
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import okhttp3.FormBody
|
import okhttp3.FormBody
|
||||||
|
import okhttp3.Headers
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
@ -644,12 +645,42 @@ var arrayofworkers = (.*)""".toRegex()
|
||||||
return BaymoviesConfig(country, downloadTime, workers)
|
return BaymoviesConfig(country, downloadTime, workers)
|
||||||
}
|
}
|
||||||
|
|
||||||
// taken from https://github.com/821938089/cloudstream-extensions/blob/6e41697cbf816d2f57d9922d813c538e3192f708/PiousIndexProvider/src/main/kotlin/com/horis/cloudstreamplugins/PiousIndexProvider.kt#L175-L179
|
/** taken from https://github.com/821938089/cloudstream-extensions/blob/6e41697cbf816d2f57d9922d813c538e3192f708/PiousIndexProvider/src/main/kotlin/com/horis/cloudstreamplugins/PiousIndexProvider.kt#L175-L179
|
||||||
|
- Credits to Horis
|
||||||
|
**/
|
||||||
fun decodeIndexJson(json: String): String {
|
fun decodeIndexJson(json: String): String {
|
||||||
val slug = json.reversed().substring(24)
|
val slug = json.reversed().substring(24)
|
||||||
return base64Decode(slug.substring(0, slug.length - 20))
|
return base64Decode(slug.substring(0, slug.length - 20))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** taken from https://github.com/821938089/cloudstream-extensions/blob/23dae833a48fb329d4c67dd77ac1e8bb592ac5a9/Movie123Provider/src/main/kotlin/com/horis/cloudstreamplugins/Movie123Provider.kt#L138-L150
|
||||||
|
- Credits to Horis
|
||||||
|
**/
|
||||||
|
fun String.putlockerDecrypt(key: String = "123"): String {
|
||||||
|
val sb = StringBuilder()
|
||||||
|
var i = 0
|
||||||
|
while (i < this.length) {
|
||||||
|
var j = 0
|
||||||
|
while (j < key.length && i < this.length) {
|
||||||
|
sb.append((this[i].code xor key[j].code).toChar())
|
||||||
|
j++
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Headers.getPutlockerCookies(cookieKey: String = "set-cookie"): Map<String, String> {
|
||||||
|
val cookieList =
|
||||||
|
this.filter { it.first.equals(cookieKey, ignoreCase = true) }.mapNotNull {
|
||||||
|
it.second.split(";").firstOrNull()
|
||||||
|
}
|
||||||
|
return cookieList.associate {
|
||||||
|
val split = it.split("=", limit = 2)
|
||||||
|
(split.getOrNull(0)?.trim() ?: "") to (split.getOrNull(1)?.trim() ?: "")
|
||||||
|
}.filter { it.key.isNotBlank() && it.value.isNotBlank() }
|
||||||
|
}
|
||||||
|
|
||||||
fun String?.createSlug(): String? {
|
fun String?.createSlug(): String? {
|
||||||
return this?.replace(Regex("[!%:'?,]|( &)"), "")?.replace(" ", "-")?.lowercase()
|
return this?.replace(Regex("[!%:'?,]|( &)"), "")?.replace(" ", "-")?.lowercase()
|
||||||
?.replace("-–-", "-")
|
?.replace("-–-", "-")
|
||||||
|
|
Loading…
Reference in a new issue