sora: fix some sources & solved #299

This commit is contained in:
helo 2023-09-28 21:05:17 +07:00
parent 39de0eb2b6
commit ab50fee8a5
18 changed files with 110 additions and 152 deletions

View file

@ -1,7 +1,7 @@
import org.jetbrains.kotlin.konan.properties.Properties
// use an integer for version numbers
version = 175
version = 176
android {
defaultConfig {

View file

@ -1653,15 +1653,12 @@ object SoraExtractor : SoraStream() {
"$rStreamAPI/e/?tmdb=$id&s=$season&e=$episode"
}
val res = app.get(url).text
val res = app.get(url, referer = "https://watcha.movie/").text
val link = Regex("\"file\":\"(http.*?)\"").find(res)?.groupValues?.getOrNull(1) ?: return
delay(1000)
if (!app.get(link, referer = rStreamAPI).isSuccessful) return
callback.invoke(
ExtractorLink(
"RStream", "RStream", link, rStreamAPI, Qualities.P720.value, link.contains(".m3u8")
"RStream", "RStream", link, rStreamAPI, Qualities.P720.value, INFER_TYPE
)
)
}
@ -2057,7 +2054,7 @@ object SoraExtractor : SoraStream() {
)
}
suspend fun invokePrimewire(
suspend fun invokeGomovies(
title: String? = null,
year: Int? = null,
season: Int? = null,
@ -2070,10 +2067,10 @@ object SoraExtractor : SoraStream() {
season,
episode,
callback,
primewireAPI,
"Primewire",
"RvnMfoxhgm",
"vvqUtffkId"
gomoviesAPI,
"Gomovies",
"_smQamBQsETb",
"_sBWcqbTBMaT"
)
}
@ -2175,7 +2172,6 @@ object SoraExtractor : SoraStream() {
suspend fun invokeWatchOnline(
imdbId: String? = null,
tmdbId: Int? = null,
title: String? = null,
year: Int? = null,
season: Int? = null,
@ -2186,98 +2182,59 @@ object SoraExtractor : SoraStream() {
val id = imdbId?.removePrefix("tt")
val slug = title.createSlug()
val url = if (season == null) {
"$watchOnlineAPI/movies/view/$id-$slug-$year"
"$watchOnlineAPI/movies/play/$id-$slug-$year"
} else {
"$watchOnlineAPI/shows/view/$id-$slug-$year"
"$watchOnlineAPI/shows/play/$id-$slug-$year"
}
var res = app.get(url)
if (res.code == 403) return
if (!res.isSuccessful) res = searchWatchOnline(title, season, imdbId, tmdbId) ?: return
if (!res.isSuccessful) res = searchWatchOnline(title, season, year) ?: return
val doc = res.document
val episodeId = if (season == null) {
doc.selectFirst("div.movie__buttons-items a")?.attr("data-watch-list-media-id")
} else {
doc.select("ul[data-season-episodes=$season] li").find {
it.select("div.episodes__number").text().equals("Episode $episode", true)
}?.attr("data-id-episode")
} ?: return
argamap({
invokeMonster(res.url.substringAfterLast("/"), episodeId, season, callback)
}, {
val videoUrl = if (season == null) {
"$watchOnlineAPI/api/v1/security/movie-access?id_movie=$episodeId"
} else {
"$watchOnlineAPI/api/v1/security/episode-access?id=$episodeId"
}
val json = app.get(videoUrl, referer = url).parsedSafe<WatchOnlineResponse>()
json?.streams?.mapKeys { source ->
callback.invoke(
ExtractorLink(
"WatchOnline",
"WatchOnline",
source.value,
"$watchOnlineAPI/",
getQualityFromName(source.key),
true
)
)
}
val subtitles = json?.subtitles as ArrayList<HashMap<String, String>>
subtitles.map { sub ->
subtitleCallback.invoke(
SubtitleFile(
sub["language"] ?: return@map,
fixUrl(sub["url"] ?: return@map, watchOnlineAPI)
)
)
}
})
}
private suspend fun invokeMonster(
urlSlug: String? = null,
episodeId: String? = null,
season: Int? = null,
callback: (ExtractorLink) -> Unit,
) {
val monsterMainUrl = "https://lookmovie.foundation"
val viewSlug = if (season == null) {
"movies/view/$urlSlug"
} else {
"shows/view/$urlSlug"
}
val streamUrl =
app.get("$monsterMainUrl/$viewSlug").document.select("a.round-button:first-child")
.attr("href")
val res = app.get(fixUrl(streamUrl, monsterMainUrl)).document
val script = res.selectFirst("script:containsData(hash:)")?.data()
val script = doc.selectFirst("script:containsData(hash:)")?.data()
val hash = Regex("hash:\\s*['\"](\\S+)['\"]").find(script ?: return)?.groupValues?.get(1)
val expires = Regex("expires:\\s*(\\d+)").find(script)?.groupValues?.get(1)
val episodeId = (if(season == null) {
"""id_movie:\s*(\d+)"""
} else {
"""episode:\s*['"]$episode['"],[\n\s]+id_episode:\s*(\d+),[\n\s]+season:\s*['"]$season['"]"""
}).let { it.toRegex().find(script)?.groupValues?.get(1) }
val videoUrl = if (season == null) {
"$monsterMainUrl/api/v1/security/movie-access?id_movie=$episodeId&hash=$hash&expires=$expires"
"$watchOnlineAPI/api/v1/security/movie-access?id_movie=$episodeId&hash=$hash&expires=$expires"
} else {
"$monsterMainUrl/api/v1/security/episode-access?id_episode=$episodeId&hash=$hash&expires=$expires"
"$watchOnlineAPI/api/v1/security/episode-access?id_episode=$episodeId&hash=$hash&expires=$expires"
}
app.get(
videoUrl, referer = streamUrl, headers = mapOf("X-Requested-With" to "XMLHttpRequest")
).parsedSafe<WatchOnlineResponse>()?.streams?.mapKeys { source ->
val sources = app.get(
videoUrl,
referer = url,
headers = mapOf("X-Requested-With" to "XMLHttpRequest")
).parsedSafe<WatchOnlineResponse>()
sources?.streams?.mapKeys { source ->
callback.invoke(
ExtractorLink(
"WatchOnline",
"WatchOnline",
source.value,
"$monsterMainUrl/",
"$watchOnlineAPI/",
getQualityFromName(source.key),
true
)
)
}
sources?.subtitles?.map { sub ->
val file = sub.file.toString()
subtitleCallback.invoke(
SubtitleFile(
sub.language ?: return@map,
if(file.startsWith("[")) return@map else fixUrl(file, watchOnlineAPI),
)
)
}
}
suspend fun invokeNinetv(

View file

@ -195,19 +195,25 @@ data class JikanResponse(
@JsonProperty("data") val data: JikanData? = null,
)
data class WatchOnlineItems(
data class WatchOnlineResults(
@JsonProperty("slug") val slug: String? = null,
@JsonProperty("tmdb_id") val tmdb_id: Int? = null,
@JsonProperty("imdb_id") val imdb_id: String? = null,
@JsonProperty("title") val title: String? = null,
@JsonProperty("year") val year: String? = null,
)
data class WatchOnlineSearch(
@JsonProperty("items") val items: ArrayList<WatchOnlineItems>? = arrayListOf(),
@JsonProperty("result") val result: ArrayList<WatchOnlineResults>? = arrayListOf(),
)
data class WatchOnlineSubtitles(
@JsonProperty("language") val language: String? = null,
@JsonProperty("file") val file: Any? = null,
)
data class WatchOnlineResponse(
@JsonProperty("streams") val streams: HashMap<String, String>? = null,
@JsonProperty("subtitles") val subtitles: Any? = null,
@JsonProperty("subtitles") val subtitles: ArrayList<WatchOnlineSubtitles>? = arrayListOf(),
)
data class CryMoviesProxyHeaders(

View file

@ -42,7 +42,7 @@ import com.hexated.SoraExtractor.invokeMultimovies
import com.hexated.SoraExtractor.invokeNetflix
import com.hexated.SoraExtractor.invokeNetmovies
import com.hexated.SoraExtractor.invokePobmovies
import com.hexated.SoraExtractor.invokePrimewire
import com.hexated.SoraExtractor.invokeGomovies
import com.hexated.SoraExtractor.invokePutactor
import com.hexated.SoraExtractor.invokeTvMovies
import com.hexated.SoraExtractor.invokeUhdmovies
@ -109,7 +109,7 @@ open class SoraStream : TmdbProvider() {
const val flixonAPI = "https://flixon.lol"
const val smashyStreamAPI = "https://embed.smashystream.com"
const val watchSomuchAPI = "https://watchsomuch.tv" // sub only
const val watchOnlineAPI = "https://watchonline.ag"
const val watchOnlineAPI = "https://lookmovie.foundation"
const val nineTvAPI = "https://moviesapi.club"
const val nowTvAPI = "https://myfilestorage.xyz"
const val gokuAPI = "https://goku.sx"
@ -121,7 +121,6 @@ open class SoraStream : TmdbProvider() {
const val netmoviesAPI = "https://netmovies.to"
const val momentAPI = "https://moment-explanation-i-244.site"
const val doomoviesAPI = "https://doomovies.net"
const val primewireAPI = "https://real-primewire.club"
const val vidsrctoAPI = "https://vidsrc.to"
const val dramadayAPI = "https://dramaday.me"
const val animetoshoAPI = "https://animetosho.org"
@ -132,6 +131,7 @@ open class SoraStream : TmdbProvider() {
const val netflixAPI = "https://m.netflixmirror.com"
const val hdmovies4uAPI = "https://hdmovies4u.name"
const val watchflxAPI = "https://watchflx.tv"
const val gomoviesAPI = "https://gomovies-online.cam"
const val dotmoviesAPI = "https://dotmovies.today"
// INDEX SITE
@ -585,7 +585,7 @@ open class SoraStream : TmdbProvider() {
)
},
{
if (!res.isAnime) invokePrimewire(res.title, res.year, res.season, res.episode, callback)
if (!res.isAnime) invokeGomovies(res.title, res.year, res.season, res.episode, callback)
},
{
if (!res.isAnime) invokePutactor(res.title, res.year, res.season, res.episode, callback)
@ -604,7 +604,6 @@ open class SoraStream : TmdbProvider() {
{
invokeWatchOnline(
res.imdbId,
res.id,
res.title,
res.airedYear ?: res.year,
res.season,

View file

@ -27,7 +27,7 @@ import com.hexated.SoraExtractor.invokeMoment
import com.hexated.SoraExtractor.invokeMultimovies
import com.hexated.SoraExtractor.invokeNetflix
import com.hexated.SoraExtractor.invokeNetmovies
import com.hexated.SoraExtractor.invokePrimewire
import com.hexated.SoraExtractor.invokeGomovies
import com.hexated.SoraExtractor.invokePutactor
import com.hexated.SoraExtractor.invokeVidSrc
import com.hexated.SoraExtractor.invokeVidsrcto
@ -207,7 +207,7 @@ class SoraStreamLite : SoraStream() {
if (!res.isAnime) invokeFlixon(res.id, res.imdbId, res.season, res.episode, callback)
},
{
if (!res.isAnime) invokePrimewire(res.title, res.year, res.season, res.episode, callback)
if (!res.isAnime) invokeGomovies(res.title, res.year, res.season, res.episode, callback)
},
{
if (!res.isAnime) invokePutactor(res.title, res.year, res.season, res.episode, callback)
@ -215,7 +215,6 @@ class SoraStreamLite : SoraStream() {
{
invokeWatchOnline(
res.imdbId,
res.id,
res.title,
res.airedYear ?: res.year,
res.season,

View file

@ -841,26 +841,25 @@ fun Document.findTvMoviesIframe(): String? {
suspend fun searchWatchOnline(
title: String? = null,
season: Int? = null,
imdbId: String? = null,
tmdbId: Int? = null,
year: Int? = null,
): NiceResponse? {
val wTitle = title?.dropLast(1) // weird but this will make search working
val mediaId = app.get(
if (season == null) {
"${watchOnlineAPI}/api/v1/movies?filters[q]=$wTitle"
"${watchOnlineAPI}/api/v1/do-search/?q=$wTitle"
} else {
"${watchOnlineAPI}/api/v1/shows?filters[q]=$wTitle"
"${watchOnlineAPI}/api/v1/do-search/?q=$wTitle"
}
).parsedSafe<WatchOnlineSearch>()?.items?.find {
it.imdb_id == imdbId || it.tmdb_id == tmdbId || it.imdb_id == imdbId?.removePrefix("tt")
).parsedSafe<WatchOnlineSearch>()?.result?.find {
it.title.equals(title, true) && it.year.equals("$year")
}?.slug
return app.get(
fixUrl(
mediaId ?: return null, if (season == null) {
"${watchOnlineAPI}/movies/view"
"${watchOnlineAPI}/movies/play"
} else {
"${watchOnlineAPI}/shows/view"
"${watchOnlineAPI}/shows/play"
}
)
)