sora: fix several sources

This commit is contained in:
hexated 2023-04-19 16:52:31 +07:00
parent 8d20beab6b
commit 9df7df0cd7
5 changed files with 92 additions and 56 deletions

View File

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

View File

@ -40,6 +40,11 @@ class FileMoonIn : Filesim() {
override val name = "FileMoon"
}
class StreamhideCom : Filesim() {
override var name: String = "Streamhide"
override var mainUrl: String = "https://streamhide.com"
}
class Watchx : Chillx() {
override val name = "Watchx"
override val mainUrl = "https://watchx.top"

View File

@ -827,8 +827,9 @@ object SoraExtractor : SoraStream() {
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val query = title?.replace(Regex("[^\\w-\\s]"), "")
val html =
app.get("https://fmovies.to/ajax/film/search?vrf=${encodeVrf("$title")}&keyword=$title")
app.get("https://fmovies.to/ajax/film/search?vrf=${encodeVrf("$query")}&keyword=$query")
.parsedSafe<FmoviesSearch>()?.html
val mediaId = Jsoup.parse(html ?: return).select("a.item").map {
@ -2935,40 +2936,49 @@ object SoraExtractor : SoraStream() {
val res = app.get(url)
if (season == null) {
res.document.select("table.rwd-table tr").map { el ->
val name = el.select("td[data-th=File Name]").text()
val quality = getIndexQuality(name)
val tags = getIndexQualityTags(name)
val size = el.select("td[data-th=Size]").text()
val videoUrl = el.select("div.play_with_vlc_button > a").lastOrNull()?.attr("href")
callback.invoke(
ExtractorLink(
"Shivamhw",
"Shivamhw $tags [${size}]",
videoUrl?.removePrefix("vlc://")?.encodeUrl() ?: return@map,
"",
quality,
)
val media = if(season == null) {
res.document.select("table.rwd-table tr").map {
Triple(
it.select("td[data-th=File Name]").text(),
it.select("td[data-th=Size]").text(),
it.select("div.play_with_vlc_button > a").lastOrNull()?.attr("href")
)
}
} else {
tryParseJson<ArrayList<ShivamhwSources>>(res.text)?.map { source ->
val quality = getIndexQuality(source.name)
val tags = getIndexQualityTags(source.name)
callback.invoke(
ExtractorLink(
"Shivamhw",
"Shivamhw $tags [${source.size}]",
source.stream_link?.encodeUrl() ?: return@map,
"",
quality,
)
tryParseJson<ArrayList<ShivamhwSources>>(res.text)?.map {
Triple(
it.name,
it.size,
it.stream_link,
)
}
}
media?.filter {
matchingIndex(
it.first,
null,
title,
year,
season,
episode,
true
)
}?.sortedByDescending {
it.second.getFileSize()
}?.map { source ->
val quality = getIndexQuality(source.first)
val tags = getIndexQualityTags(source.first)
callback.invoke(
ExtractorLink(
"Shivamhw",
"Shivamhw $tags [${source.second}]",
source.third?.removePrefix("vlc://") ?: return@map,
"",
quality,
)
)
}
}
suspend fun invokeCryMovies(
@ -2978,8 +2988,8 @@ object SoraExtractor : SoraStream() {
app.get("$cryMoviesAPI/stream/movie/$imdbId.json")
.parsedSafe<CryMoviesResponse>()?.streams?.map { stream ->
val quality = getIndexQuality(stream.title)
val tags = getIndexQualityTags(stream.title)
val size = stream.title?.substringAfter("\uD83D\uDCBE")?.trim()
val tags = getIndexQualityTags(stream.title, true)
val size = getIndexSize(stream.title)
val headers = stream.behaviorHints?.proxyHeaders?.request ?: mapOf()
callback.invoke(
@ -3484,8 +3494,8 @@ data class AllanimeResponses(
data class ShivamhwSources(
@JsonProperty("id") val id: String? = null,
@JsonProperty("stream_link") val stream_link: String? = null,
@JsonProperty("name") val name: String? = null,
@JsonProperty("size") val size: String? = null,
@JsonProperty("name") val name: String,
@JsonProperty("size") val size: String,
)
data class CryMoviesProxyHeaders(

View File

@ -18,5 +18,6 @@ class SoraStreamPlugin: Plugin() {
registerExtractorAPI(Sbnet())
registerExtractorAPI(Chillx())
registerExtractorAPI(Watchx())
registerExtractorAPI(StreamhideCom())
}
}

View File

@ -40,7 +40,8 @@ import javax.crypto.spec.SecretKeySpec
import kotlin.collections.ArrayList
import kotlin.math.min
val soraAPI = base64DecodeAPI("cA==YXA=cy8=Y20=di8=LnQ=b2s=a2w=bG8=aS4=YXA=ZS0=aWw=b2I=LW0=Z2E=Ly8=czo=dHA=aHQ=")
val soraAPI =
base64DecodeAPI("cA==YXA=cy8=Y20=di8=LnQ=b2s=a2w=bG8=aS4=YXA=ZS0=aWw=b2I=LW0=Z2E=Ly8=czo=dHA=aHQ=")
val soraBackupAPI = base64DecodeAPI("dHY=bC4=aWw=Y2g=c3Q=anU=MS4=b2s=a2w=bG8=Ly8=czo=dHA=aHQ=")
val soraHeaders = mapOf(
@ -402,7 +403,8 @@ suspend fun invokeSmashyOne(
url: String,
callback: (ExtractorLink) -> Unit,
) {
val script = app.get(url).document.selectFirst("script:containsData(player =)")?.data() ?: return
val script =
app.get(url).document.selectFirst("script:containsData(player =)")?.data() ?: return
val source =
Regex("file:\\s['\"](\\S+?)['|\"]").find(script)?.groupValues?.get(
@ -444,7 +446,7 @@ suspend fun invokeSmashyTwo(
).parsedSafe<Smashy1Source>() ?: return
val videoUrl = base64Decode(source.file ?: return)
if(videoUrl.contains("/bug")) return
if (videoUrl.contains("/bug")) return
val quality =
Regex("(\\d{3,4})[Pp]").find(videoUrl)?.groupValues?.getOrNull(1)?.toIntOrNull()
?: Qualities.P720.value
@ -473,15 +475,16 @@ suspend fun invokeSmashyThree(
tryParseJson<ArrayList<DudetvSources>>(source)?.filter { it.title == "English" }?.map {
M3u8Helper.generateM3u8(
"Smashy [Player 2]",
it.file ?: return@map ,
it.file ?: return@map,
""
).forEach(callback)
}
}
suspend fun getSoraIdAndType(title: String?, year: Int?, season: Int?) : Pair<String, String>? {
val doc = app.get("${base64DecodeAPI("b20=LmM=b2s=a2w=bG8=Ly8=czo=dHA=aHQ=")}/search?keyword=$title").document
suspend fun getSoraIdAndType(title: String?, year: Int?, season: Int?): Pair<String, String>? {
val doc =
app.get("${base64DecodeAPI("b20=LmM=b2s=a2w=bG8=Ly8=czo=dHA=aHQ=")}/search?keyword=$title").document
val scriptData = doc.select("div.search-list div.search-video-card").map {
Triple(
it.selectFirst("h2.title")?.text().toString(),
@ -523,7 +526,7 @@ suspend fun getSoraIdAndType(title: String?, year: Int?, season: Int?) : Pair<St
return id to type
}
suspend fun fetchSoraEpisodes(id: String, type: String, episode: Int?) : EpisodeVo? {
suspend fun fetchSoraEpisodes(id: String, type: String, episode: Int?): EpisodeVo? {
return app.get(
"$soraAPI/movieDrama/get?id=${id}&category=${type}",
headers = soraHeaders
@ -634,7 +637,7 @@ suspend fun bypassHrefli(url: String): String? {
return fixUrl(path, getBaseUrl(driveUrl))
}
suspend fun bypassTechmny(url: String) : String? {
suspend fun bypassTechmny(url: String): String? {
val postUrl = url.substringBefore("?id=").substringAfter("/?")
var res = app.post(
postUrl, data = mapOf(
@ -656,14 +659,16 @@ suspend fun bypassTechmny(url: String) : String? {
val newLongC = "$goToken=" + longC2.substringAfter("=")
headers = mapOf("Cookie" to "$catC; rdst_post=; $newLongC")
val driveUrl = app.get(tokenUrl, headers = headers).document.selectFirst("meta[http-equiv=refresh]")?.attr("content")?.substringAfter("url=")
val driveUrl =
app.get(tokenUrl, headers = headers).document.selectFirst("meta[http-equiv=refresh]")
?.attr("content")?.substringAfter("url=")
val path = app.get(driveUrl ?: return null).text.substringAfter("replace(\"")
.substringBefore("\")")
if (path == "/404") return null
return fixUrl(path, getBaseUrl(driveUrl))
}
suspend fun bypassDriveleech(url: String) : String? {
suspend fun bypassDriveleech(url: String): String? {
val path = app.get(url).text.substringAfter("replace(\"")
.substringBefore("\")")
if (path == "/404") return null
@ -682,14 +687,18 @@ private fun getTechmnyCookies(page: String): Triple<String, String, String> {
.substringBefore(";").let {
"$cat=$it"
}
} else { "" }
} else {
""
}
val postC = if (page.contains("$post=")) {
page.substringAfterLast("$post=")
.substringBefore(";").let {
"$post=$it"
}
} else { "" }
} else {
""
}
return Triple(longC, catC, postC)
}
@ -805,7 +814,7 @@ suspend fun searchWatchOnline(
}
suspend fun searchCrunchyrollAnimeId(title: String): String? {
val res = app.get("${consumetCrunchyrollAPI}/search/$title",timeout = 600L)
val res = app.get("${consumetCrunchyrollAPI}/search/$title", timeout = 600L)
.parsedSafe<ConsumetSearchResponse>()?.results
return (if (res?.size == 1) {
res.firstOrNull()
@ -825,8 +834,10 @@ fun CrunchyrollDetails.findCrunchyrollId(
episode: Int?,
epsTitle: String?
): List<Pair<CrunchyrollEpisodes?, String?>?> {
val sub = this.episodes?.filterKeys { it.contains("subbed") }.matchingEpisode(epsTitle, season, episode) to "Raw"
val dub = this.episodes?.filterKeys { it.contains("English Dub") }.matchingEpisode(epsTitle, season, episode) to "English Dub"
val sub = this.episodes?.filterKeys { it.contains("subbed") }
.matchingEpisode(epsTitle, season, episode) to "Raw"
val dub = this.episodes?.filterKeys { it.contains("English Dub") }
.matchingEpisode(epsTitle, season, episode) to "English Dub"
return listOf(sub, dub)
}
@ -894,7 +905,7 @@ suspend fun PutlockerResponses?.callback(
fun getPutlockerQuality(quality: String): Int {
return when {
quality.contains("NAME=\"1080p\"") || quality.contains("RESOLUTION=1920x1080") -> Qualities.P1080.value
quality.contains("NAME=\"720p\"") || quality.contains("RESOLUTION=1280x720")-> Qualities.P720.value
quality.contains("NAME=\"720p\"") || quality.contains("RESOLUTION=1280x720") -> Qualities.P720.value
else -> Qualities.P480.value
}
}
@ -1045,17 +1056,21 @@ fun getKisskhTitle(str: String?): String? {
return str?.replace(Regex("[^a-zA-Z\\d]"), "-")
}
fun String.getFileSize() : Float? {
val size = Regex("(\\d+\\.?\\d+\\sGB|MB)").find(this)?.groupValues?.get(0)?.trim()
val num = Regex("(\\d+\\.?\\d+)").find(size ?: return null)?.groupValues?.get(0)?.toFloat() ?: return null
fun String.getFileSize(): Float? {
val size = Regex("(?i)(\\d+\\.?\\d+\\sGB|MB)").find(this)?.groupValues?.get(0)?.trim()
val num = Regex("(\\d+\\.?\\d+)").find(size ?: return null)?.groupValues?.get(0)?.toFloat()
?: return null
return when {
size.contains("GB") -> num * 1000000
else -> num * 1000
}
}
fun getIndexQualityTags(str: String?): String {
return Regex("(?i)\\d{3,4}[pP]\\.?(.*?)\\.(mkv|mp4|avi)").find(str ?: "")?.groupValues?.getOrNull(1)
fun getIndexQualityTags(str: String?, fullTag: Boolean = false): String {
return if (fullTag) Regex("(?i)(.*)\\.(?:mkv|mp4|avi)").find(str ?: "")?.groupValues?.get(1)
?.trim() ?: str ?: "" else Regex("(?i)\\d{3,4}[pP]\\.?(.*?)\\.(mkv|mp4|avi)").find(
str ?: ""
)?.groupValues?.getOrNull(1)
?.replace(".", " ")?.trim() ?: str ?: ""
}
@ -1064,6 +1079,10 @@ fun getIndexQuality(str: String?): Int {
?: Qualities.Unknown.value
}
fun getIndexSize(str: String?): String? {
return Regex("(?i)([\\d.]+\\s*(?:gb|mb))").find(str ?: "")?.groupValues?.getOrNull(1)?.trim()
}
fun getQuality(str: String): Int {
return when (str) {
"360p" -> Qualities.P240.value
@ -1424,7 +1443,8 @@ object CryptoAES {
}
}
private fun ByteArray.toHex(): String = joinToString(separator = "") { eachByte -> "%02x".format(eachByte) }
private fun ByteArray.toHex(): String =
joinToString(separator = "") { eachByte -> "%02x".format(eachByte) }
private fun String.toHex(): String = toByteArray().toHex()