mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
[Sora-test] adding TVMovies
This commit is contained in:
parent
85d2e334f6
commit
62506de4da
3 changed files with 141 additions and 15 deletions
|
@ -12,6 +12,7 @@ import com.lagradost.cloudstream3.extractors.XStreamCdn
|
||||||
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 okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
|
||||||
|
@ -792,25 +793,34 @@ object SoraExtractor : SoraStream() {
|
||||||
}
|
}
|
||||||
|
|
||||||
val script = if (scriptData.size == 1) {
|
val script = if (scriptData.size == 1) {
|
||||||
scriptData.first()
|
scriptData.firstOrNull()
|
||||||
} else {
|
} else {
|
||||||
scriptData.first {
|
scriptData.find {
|
||||||
if (season == null) {
|
when (season) {
|
||||||
|
null -> {
|
||||||
it.first.equals(
|
it.first.equals(
|
||||||
title,
|
title,
|
||||||
true
|
true
|
||||||
) && it.second == year
|
) && it.second == year
|
||||||
} else {
|
}
|
||||||
|
1 -> {
|
||||||
it.first.contains(
|
it.first.contains(
|
||||||
"$title",
|
"$title",
|
||||||
true
|
true
|
||||||
) && (it.second == year || it.first.contains("Season $season", true))
|
) && (it.second == year || it.first.contains("Season $season", true))
|
||||||
}
|
}
|
||||||
|
else -> {
|
||||||
|
it.first.contains(
|
||||||
|
"$title",
|
||||||
|
true
|
||||||
|
) && it.second == year && it.first.contains("Season $season", true)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val id = script.third?.last()
|
val id = script?.third?.last() ?: return
|
||||||
val type = script.third?.get(2)
|
val type = script.third?.get(2) ?: return
|
||||||
|
|
||||||
val jsonResponse = app.get(
|
val jsonResponse = app.get(
|
||||||
"$vipAPI/movieDrama/get?id=${id}&category=${type}",
|
"$vipAPI/movieDrama/get?id=${id}&category=${type}",
|
||||||
|
@ -1491,6 +1501,81 @@ object SoraExtractor : SoraStream() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun invokeTvMovies(
|
||||||
|
title: String? = null,
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null,
|
||||||
|
subtitleCallback: (SubtitleFile) -> Unit,
|
||||||
|
callback: (ExtractorLink) -> Unit
|
||||||
|
) {
|
||||||
|
val fixTitle = title.fixTitle()
|
||||||
|
val url = if (season == null) {
|
||||||
|
"$tvMoviesAPI/show/$fixTitle"
|
||||||
|
} else {
|
||||||
|
"$tvMoviesAPI/show/index-of-$fixTitle"
|
||||||
|
}
|
||||||
|
|
||||||
|
val server = getTvMoviesServer(url, season, episode) ?: return
|
||||||
|
|
||||||
|
val request = session.get(server.second ?: return, referer = "$tvMoviesAPI/")
|
||||||
|
var filehosting = session.baseClient.cookieJar.loadForRequest(url.toHttpUrl())
|
||||||
|
.find { it.name == "filehosting" }?.value
|
||||||
|
val iframe = request.document.findTvMoviesIframe()
|
||||||
|
delay(10000)
|
||||||
|
val request2 = session.get(
|
||||||
|
iframe ?: return, referer = url, headers = mapOf(
|
||||||
|
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
||||||
|
"Connection" to "keep-alive",
|
||||||
|
"Cookie" to "filehosting=$filehosting",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
filehosting = session.baseClient.cookieJar.loadForRequest(url.toHttpUrl())
|
||||||
|
.find { it.name == "filehosting" }?.value
|
||||||
|
val iframe2 = request2.document.findTvMoviesIframe()
|
||||||
|
delay(11000)
|
||||||
|
val request3 = session.get(
|
||||||
|
iframe2 ?: return, referer = iframe, headers = mapOf(
|
||||||
|
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
||||||
|
"Connection" to "keep-alive",
|
||||||
|
"Cookie" to "filehosting=$filehosting",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
filehosting = session.baseClient.cookieJar.loadForRequest(url.toHttpUrl())
|
||||||
|
.find { it.name == "filehosting" }?.value
|
||||||
|
val response = request3.document
|
||||||
|
val videoLink =
|
||||||
|
response.selectFirst("button.btn.btn--primary")?.attr("onclick")
|
||||||
|
?.substringAfter("location = '")?.substringBefore("';")?.let {
|
||||||
|
app.get(
|
||||||
|
it, referer = iframe2, headers = mapOf(
|
||||||
|
"Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
|
||||||
|
"Connection" to "keep-alive",
|
||||||
|
"Cookie" to "filehosting=$filehosting",
|
||||||
|
)
|
||||||
|
).url
|
||||||
|
}
|
||||||
|
|
||||||
|
val quality =
|
||||||
|
Regex("([0-9]{3,4})p").find(server.first)?.groupValues?.getOrNull(1)?.toIntOrNull()
|
||||||
|
val size =
|
||||||
|
response.selectFirst("ul.row--list li:contains(Filesize) span:last-child")
|
||||||
|
?.text()
|
||||||
|
|
||||||
|
callback.invoke(
|
||||||
|
ExtractorLink(
|
||||||
|
"TVMovies [$size]",
|
||||||
|
"TVMovies [$size]",
|
||||||
|
videoLink ?: return,
|
||||||
|
"",
|
||||||
|
quality ?: Qualities.Unknown.value
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamM4u: XStreamCdn() {
|
class StreamM4u: XStreamCdn() {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import com.hexated.SoraExtractor.invokeFwatayako
|
||||||
import com.hexated.SoraExtractor.invokeGMovies
|
import com.hexated.SoraExtractor.invokeGMovies
|
||||||
import com.hexated.SoraExtractor.invokeLing
|
import com.hexated.SoraExtractor.invokeLing
|
||||||
import com.hexated.SoraExtractor.invokeM4uhd
|
import com.hexated.SoraExtractor.invokeM4uhd
|
||||||
|
import com.hexated.SoraExtractor.invokeTvMovies
|
||||||
import com.hexated.SoraExtractor.invokeUhdmovies
|
import com.hexated.SoraExtractor.invokeUhdmovies
|
||||||
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
|
||||||
|
@ -78,6 +79,7 @@ open class SoraStream : TmdbProvider() {
|
||||||
const val gMoviesAPI = "https://gdrivemovies.xyz"
|
const val gMoviesAPI = "https://gdrivemovies.xyz"
|
||||||
const val fdMoviesAPI = "https://freedrivemovie.com"
|
const val fdMoviesAPI = "https://freedrivemovie.com"
|
||||||
const val m4uhdAPI = "https://m4uhd.tv"
|
const val m4uhdAPI = "https://m4uhd.tv"
|
||||||
|
const val tvMoviesAPI = "https://www.tvseriesnmovies.com"
|
||||||
|
|
||||||
fun getType(t: String?): TvType {
|
fun getType(t: String?): TvType {
|
||||||
return when (t) {
|
return when (t) {
|
||||||
|
@ -430,7 +432,10 @@ open class SoraStream : TmdbProvider() {
|
||||||
// },
|
// },
|
||||||
{
|
{
|
||||||
invokeM4uhd(res.title, res.year, res.season, res.episode, subtitleCallback, callback)
|
invokeM4uhd(res.title, res.year, res.season, res.episode, subtitleCallback, callback)
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
invokeTvMovies(res.title, res.season, res.episode, subtitleCallback, callback)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -17,6 +17,7 @@ import okhttp3.FormBody
|
||||||
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
|
||||||
|
import org.jsoup.nodes.Document
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
|
||||||
data class FilmxyCookies(
|
data class FilmxyCookies(
|
||||||
|
@ -222,6 +223,36 @@ suspend fun bypassFdAds(url: String): String? {
|
||||||
return app.get(finalLink ?: return null, verify = false).url
|
return app.get(finalLink ?: return null, verify = false).url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getTvMoviesServer(url: String, season: Int?, episode: Int?): Pair<String, String?>? {
|
||||||
|
|
||||||
|
val req = app.get(url)
|
||||||
|
if(!req.isSuccessful) return null
|
||||||
|
val doc = req.document
|
||||||
|
|
||||||
|
return if (season == null) {
|
||||||
|
doc.select("table.wp-block-table tr:last-child td:first-child").text() to
|
||||||
|
doc.selectFirst("table.wp-block-table tr a")?.attr("href").let { link ->
|
||||||
|
app.get(link ?: return null).document.select("div#text-url a")
|
||||||
|
.mapIndexed { index, element ->
|
||||||
|
element.attr("href") to element.parent()?.textNodes()?.getOrNull(index)
|
||||||
|
?.text()
|
||||||
|
}.filter { it.second?.contains("Subtitles", true) == false }
|
||||||
|
.map { it.first }
|
||||||
|
}.lastOrNull()
|
||||||
|
} else {
|
||||||
|
doc.select("div.vc_tta-panels div#Season-$season table.wp-block-table tr:last-child td:first-child")
|
||||||
|
.text() to
|
||||||
|
doc.select("div.vc_tta-panels div#Season-$season table.wp-block-table tr a")
|
||||||
|
.mapNotNull { ele ->
|
||||||
|
app.get(ele.attr("href")).document.select("div#text-url a")
|
||||||
|
.mapIndexed { index, element ->
|
||||||
|
element.attr("href") to element.parent()?.textNodes()
|
||||||
|
?.getOrNull(index)?.text()
|
||||||
|
}.find { it.second?.contains("Episode $episode", true) == true }?.first
|
||||||
|
}.lastOrNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -269,6 +300,11 @@ suspend fun getFilmxyCookies(imdbId: String? = null, season: Int? = null): Filmx
|
||||||
return FilmxyCookies(phpsessid, wLog, wSec)
|
return FilmxyCookies(phpsessid, wLog, wSec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Document.findTvMoviesIframe(): String? {
|
||||||
|
return this.selectFirst("script:containsData(var seconds)")?.data()?.substringAfter("href='")
|
||||||
|
?.substringBefore("'>")
|
||||||
|
}
|
||||||
|
|
||||||
fun String?.fixTitle(): String? {
|
fun String?.fixTitle(): String? {
|
||||||
return this?.replace(Regex("[!%:]|( &)"), "")?.replace(" ", "-")?.lowercase()
|
return this?.replace(Regex("[!%:]|( &)"), "")?.replace(" ", "-")?.lowercase()
|
||||||
?.replace("-–-", "-")
|
?.replace("-–-", "-")
|
||||||
|
|
Loading…
Reference in a new issue