mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
sora: fix some sources
This commit is contained in:
parent
4bf526dc36
commit
47a2aa381a
8 changed files with 131 additions and 28 deletions
|
@ -147,16 +147,8 @@ class Anichi : MainAPI() {
|
|||
if (it == null) return@let Pair(null, null)
|
||||
if (showData.Id == null) return@let Pair(null, null)
|
||||
Pair(
|
||||
it.sub.map { eps ->
|
||||
Episode(
|
||||
AnichiLoadData(showData.Id, "sub", eps).toJson(), eps
|
||||
)
|
||||
}.reversed(),
|
||||
it.dub.map { eps ->
|
||||
Episode(
|
||||
AnichiLoadData(showData.Id, "dub", eps).toJson(), eps
|
||||
)
|
||||
}.reversed()
|
||||
it.getEpisode("sub", showData.Id),
|
||||
it.getEpisode("dub", showData.Id),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -315,6 +307,19 @@ class Anichi : MainAPI() {
|
|||
return false
|
||||
}
|
||||
|
||||
private fun AvailableEpisodesDetail.getEpisode(
|
||||
lang: String,
|
||||
id: String
|
||||
): List<com.lagradost.cloudstream3.Episode> {
|
||||
val meta = if (lang == "sub") this.sub else this.dub
|
||||
return meta.map { eps ->
|
||||
Episode(
|
||||
AnichiLoadData(id, lang, eps).toJson(),
|
||||
"Ep $eps"
|
||||
)
|
||||
}.reversed()
|
||||
}
|
||||
|
||||
private suspend fun getM3u8Qualities(
|
||||
m3u8Link: String,
|
||||
referer: String,
|
||||
|
|
|
@ -23,5 +23,5 @@ cloudstream {
|
|||
"OVA",
|
||||
)
|
||||
|
||||
iconUrl = "https://www.google.com/s2/favicons?domain=65.108.132.145&sz=%size%"
|
||||
iconUrl = "https://www.google.com/s2/favicons?domain=oploverz.care&sz=%size%"
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import org.jetbrains.kotlin.konan.properties.Properties
|
||||
|
||||
// use an integer for version numbers
|
||||
version = 141
|
||||
version = 142
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
|
|
|
@ -831,31 +831,36 @@ object SoraExtractor : SoraStream() {
|
|||
title: String? = null,
|
||||
season: Int? = null,
|
||||
episode: Int? = null,
|
||||
isAnime: Boolean = false,
|
||||
lastSeason: Int? = null,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val fixTitle = title?.replace("–", "-")
|
||||
val slug = title.createSlug() ?: return
|
||||
val type = when {
|
||||
isAnime -> "3"
|
||||
season == null -> "2"
|
||||
else -> "1"
|
||||
}
|
||||
val res = app.get(
|
||||
"$kissKhAPI/api/DramaList/Search?q=$title&type=0", referer = "$kissKhAPI/"
|
||||
"$kissKhAPI/api/DramaList/Search?q=$title&type=$type", referer = "$kissKhAPI/"
|
||||
).text.let {
|
||||
tryParseJson<ArrayList<KisskhResults>>(it)
|
||||
} ?: return
|
||||
|
||||
val (id, contentTitle) = if (res.size == 1) {
|
||||
res.first().id to res.first().title
|
||||
} else {
|
||||
if (season == null) {
|
||||
val data = res.find { it.title.equals(fixTitle, true) }
|
||||
data?.id to data?.title
|
||||
} else {
|
||||
val data = res.find {
|
||||
it.title?.contains(
|
||||
"$fixTitle", true
|
||||
) == true && it.title.contains("Season $season", true)
|
||||
val slugTitle = it.title.createSlug()
|
||||
when {
|
||||
season == null -> slugTitle?.equals(slug) == true
|
||||
lastSeason == 1 -> slugTitle?.contains(slug) == true
|
||||
else -> slugTitle?.contains(slug) == true && it.title?.contains("Season $season", true) == true
|
||||
}
|
||||
}
|
||||
data?.id to data?.title
|
||||
}
|
||||
}
|
||||
|
||||
val resDetail = app.get(
|
||||
"$kissKhAPI/api/DramaList/Drama/$id?isq=false", referer = "$kissKhAPI/Drama/${
|
||||
|
@ -3033,6 +3038,70 @@ object SoraExtractor : SoraStream() {
|
|||
|
||||
}
|
||||
|
||||
suspend fun invokeEmovies(
|
||||
title: String? = null,
|
||||
year: Int? = null,
|
||||
season: Int? = null,
|
||||
episode: Int? = null,
|
||||
subtitleCallback: (SubtitleFile) -> Unit,
|
||||
callback: (ExtractorLink) -> Unit,
|
||||
) {
|
||||
val slug = title.createSlug()
|
||||
val url = if (season == null) {
|
||||
"$emoviesAPI/watch-$slug-$year-1080p-hd-online-free/watching.html"
|
||||
} else {
|
||||
val first = "$emoviesAPI/watch-$slug-season-$season-$year-1080p-hd-online-free.html"
|
||||
val second = "$emoviesAPI/watch-$slug-$year-1080p-hd-online-free.html"
|
||||
if (app.get(first).isSuccessful) first else second
|
||||
}
|
||||
|
||||
val res = app.get(url).document
|
||||
val id = (if (season == null) {
|
||||
res.selectFirst("select#selectServer option[sv=oserver]")?.attr("value")
|
||||
} else {
|
||||
res.select("div.le-server a").find {
|
||||
val num =
|
||||
Regex("Episode (\\d+)").find(it.text())?.groupValues?.get(1)?.toIntOrNull()
|
||||
num == episode
|
||||
}?.attr("href")
|
||||
})?.substringAfter("id=")?.substringBefore("&")
|
||||
|
||||
val server =
|
||||
app.get(
|
||||
"$emoviesAPI/ajax/v4_get_sources?s=oserver&id=${id ?: return}&_=${APIHolder.unixTimeMS}",
|
||||
headers = mapOf(
|
||||
"X-Requested-With" to "XMLHttpRequest"
|
||||
)
|
||||
).parsedSafe<EMovieServer>()?.value
|
||||
|
||||
val script = app.get(server ?: return, referer = "$emoviesAPI/").document.selectFirst("script:containsData(sources:)")?.data() ?: return
|
||||
val sources = Regex("sources:\\s*\\[(.*)],").find(script)?.groupValues?.get(1)?.let {
|
||||
tryParseJson<List<EMovieSources>>("[$it]")
|
||||
}
|
||||
val tracks = Regex("tracks:\\s*\\[(.*)],").find(script)?.groupValues?.get(1)?.let {
|
||||
tryParseJson<List<EMovieTraks>>("[$it]")
|
||||
}
|
||||
|
||||
sources?.map { source ->
|
||||
M3u8Helper.generateM3u8(
|
||||
"Emovies",
|
||||
source.file ?: return@map,
|
||||
"https://embed.vodstream.xyz/"
|
||||
).forEach(callback)
|
||||
}
|
||||
|
||||
tracks?.map { track ->
|
||||
subtitleCallback.invoke(
|
||||
SubtitleFile(
|
||||
track.label ?: "",
|
||||
track.file ?: return@map,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -487,3 +487,16 @@ data class EpisodeVo(
|
|||
data class DumpMediaDetail(
|
||||
@JsonProperty("episodeVo") val episodeVo: ArrayList<EpisodeVo>? = arrayListOf(),
|
||||
)
|
||||
|
||||
data class EMovieServer(
|
||||
@JsonProperty("value") val value: String? = null,
|
||||
)
|
||||
|
||||
data class EMovieSources(
|
||||
@JsonProperty("file") val file: String? = null,
|
||||
)
|
||||
|
||||
data class EMovieTraks(
|
||||
@JsonProperty("file") val file: String? = null,
|
||||
@JsonProperty("label") val label: String? = null,
|
||||
)
|
||||
|
|
|
@ -49,6 +49,7 @@ import com.hexated.SoraExtractor.invokeShinobiMovies
|
|||
import com.hexated.SoraExtractor.invokeShivamhw
|
||||
import com.hexated.SoraExtractor.invokeSmashyStream
|
||||
import com.hexated.SoraExtractor.invokeDumpStream
|
||||
import com.hexated.SoraExtractor.invokeEmovies
|
||||
import com.hexated.SoraExtractor.invokeTvMovies
|
||||
import com.hexated.SoraExtractor.invokeUhdmovies
|
||||
import com.hexated.SoraExtractor.invokeVitoenMovies
|
||||
|
@ -97,7 +98,7 @@ open class SoraStream : TmdbProvider() {
|
|||
const val filmxyAPI = "https://www.filmxy.vip"
|
||||
const val kimcartoonAPI = "https://kimcartoon.li"
|
||||
const val xMovieAPI = "https://xemovies.to"
|
||||
const val zoroAPI = "https://sanji.to"
|
||||
const val zoroAPI = "https://aniwatch.to"
|
||||
const val crunchyrollAPI = "https://beta-api.crunchyroll.com"
|
||||
const val kissKhAPI = "https://kisskh.co"
|
||||
const val lingAPI = "https://ling-online.net"
|
||||
|
@ -127,6 +128,7 @@ open class SoraStream : TmdbProvider() {
|
|||
const val gokuAPI = "https://goku.sx"
|
||||
const val ridomoviesAPI = "https://ridomovies.pw"
|
||||
const val navyAPI = "https://navy-issue-i-239.site"
|
||||
const val emoviesAPI = "https://emovies.si"
|
||||
|
||||
// INDEX SITE
|
||||
const val blackMoviesAPI = "https://dl.blacklistedbois.workers.dev/0:"
|
||||
|
@ -516,7 +518,7 @@ open class SoraStream : TmdbProvider() {
|
|||
)
|
||||
},
|
||||
{
|
||||
invokeKisskh(res.title, res.season, res.episode, subtitleCallback, callback)
|
||||
invokeKisskh(res.title, res.season, res.episode, res.isAnime, res.lastSeason, subtitleCallback, callback)
|
||||
},
|
||||
{
|
||||
invokeLing(
|
||||
|
@ -803,6 +805,9 @@ open class SoraStream : TmdbProvider() {
|
|||
{
|
||||
invokeNavy(res.imdbId, res.season, res.episode, callback)
|
||||
},
|
||||
{
|
||||
invokeEmovies(res.title, res.year, res.season, res.episode, subtitleCallback, callback)
|
||||
},
|
||||
)
|
||||
|
||||
return true
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.hexated.SoraExtractor.invokeRidomovies
|
|||
import com.hexated.SoraExtractor.invokeSeries9
|
||||
import com.hexated.SoraExtractor.invokeSmashyStream
|
||||
import com.hexated.SoraExtractor.invokeDumpStream
|
||||
import com.hexated.SoraExtractor.invokeEmovies
|
||||
import com.hexated.SoraExtractor.invokeVidSrc
|
||||
import com.hexated.SoraExtractor.invokeWatchOnline
|
||||
import com.hexated.SoraExtractor.invokeWatchsomuch
|
||||
|
@ -219,7 +220,7 @@ class SoraStreamLite : SoraStream() {
|
|||
)
|
||||
},
|
||||
{
|
||||
invokeKisskh(res.title, res.season, res.episode, subtitleCallback, callback)
|
||||
invokeKisskh(res.title, res.season, res.episode, res.isAnime, res.lastSeason, subtitleCallback, callback)
|
||||
},
|
||||
{
|
||||
invokeLing(
|
||||
|
@ -287,7 +288,17 @@ class SoraStreamLite : SoraStream() {
|
|||
res.year,
|
||||
callback
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
invokeEmovies(
|
||||
res.title,
|
||||
res.year,
|
||||
res.season,
|
||||
res.episode,
|
||||
subtitleCallback,
|
||||
callback
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
return true
|
||||
|
|
|
@ -6,7 +6,7 @@ cloudstream {
|
|||
language = "en"
|
||||
// All of these properties are optional, you can safely remove them
|
||||
|
||||
description = "- StremioX allows you to use stream addons \n- StremioC allows you to use catalog addons \n<!> Requires Setup"
|
||||
description = "[!] Requires Setup \n- StremioX allows you to use stream addons \n- StremioC allows you to use catalog addons"
|
||||
authors = listOf("Hexated")
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue