mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
[Sora] added Chillmovies
This commit is contained in:
parent
0a993d13ec
commit
a91cfbcf66
3 changed files with 133 additions and 41 deletions
|
@ -2088,42 +2088,9 @@ object SoraExtractor : SoraStream() {
|
||||||
"Origin" to baymovies,
|
"Origin" to baymovies,
|
||||||
"cf_cache_token" to "UKsVpQqBMxB56gBfhYKbfCVkRIXMh42pk6G4DdkXXoVh7j4BjV"
|
"cf_cache_token" to "UKsVpQqBMxB56gBfhYKbfCVkRIXMh42pk6G4DdkXXoVh7j4BjV"
|
||||||
)
|
)
|
||||||
|
val query = getIndexQuery(title, year, season, episode)
|
||||||
val dotSlug = title.fixTitle()?.replace("-", ".") ?: return
|
val search = app.get("$baymoviesAPI//0:search?q=$query&page_token=&page_index=0", headers = headers)
|
||||||
val spaceSlug = title.fixTitle()?.replace("-", " ") ?: return
|
val media = searchIndex(title, season, episode, year, search) ?: return
|
||||||
val (episodeSlug, seasonSlug) = if (season == null) {
|
|
||||||
listOf("", "")
|
|
||||||
} else {
|
|
||||||
listOf(
|
|
||||||
if (episode!! < 10) "0$episode" else episode,
|
|
||||||
if (season < 10) "0$season" else season
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val query = if (season == null) {
|
|
||||||
"$title $year"
|
|
||||||
} else {
|
|
||||||
"$title S${seasonSlug}E${episodeSlug}"
|
|
||||||
}
|
|
||||||
|
|
||||||
val media =
|
|
||||||
app.get("$baymoviesAPI//0:search?q=$query&page_token=&page_index=0", headers = headers)
|
|
||||||
.parsedSafe<BaymoviesSearch>()?.data?.files?.filter { media ->
|
|
||||||
(if (season == null) {
|
|
||||||
media.name?.contains("$year") == true
|
|
||||||
} else {
|
|
||||||
media.name?.contains(Regex("(?i)S${seasonSlug}.?E${episodeSlug}")) == true
|
|
||||||
}) && media.name?.contains(
|
|
||||||
"720p",
|
|
||||||
true
|
|
||||||
) == false && (media.mimeType == "video/x-matroska" || media.mimeType == "video/mp4") && (media.name.replace(
|
|
||||||
"-",
|
|
||||||
"."
|
|
||||||
).contains(
|
|
||||||
dotSlug,
|
|
||||||
true
|
|
||||||
) || media.name.contains(spaceSlug, true))
|
|
||||||
}?.distinctBy { it.name } ?: return
|
|
||||||
|
|
||||||
media.apmap { file ->
|
media.apmap { file ->
|
||||||
val expiry = (System.currentTimeMillis() + 345600000).toString()
|
val expiry = (System.currentTimeMillis() + 345600000).toString()
|
||||||
|
@ -2161,6 +2128,49 @@ object SoraExtractor : SoraStream() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun invokeChillmovies(
|
||||||
|
title: String? = null,
|
||||||
|
year: Int? = null,
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null,
|
||||||
|
callback: (ExtractorLink) -> Unit,
|
||||||
|
) {
|
||||||
|
val query = getIndexQuery(title, year, season, episode)
|
||||||
|
val body =
|
||||||
|
"""{"q":"$query","password":null,"page_token":null,"page_index":0}""".toRequestBody(
|
||||||
|
RequestBodyTypes.JSON.toMediaTypeOrNull()
|
||||||
|
)
|
||||||
|
val search = app.post("$chillmoviesAPI/0:search", requestBody = body)
|
||||||
|
val media = searchIndex(title, season, episode, year, search) ?: return
|
||||||
|
media.apmap { file ->
|
||||||
|
val pathBody = """{"id":"${file.id ?: return@apmap null}"}""".toRequestBody(
|
||||||
|
RequestBodyTypes.JSON.toMediaTypeOrNull()
|
||||||
|
)
|
||||||
|
val path = app.post("$chillmoviesAPI/0:id2path", requestBody = pathBody).text.let {
|
||||||
|
fixUrl(it, "$chillmoviesAPI/0:")
|
||||||
|
}.encodeUrl()
|
||||||
|
val size = file.size?.toDouble() ?: return@apmap null
|
||||||
|
val sizeFile = "%.2f GB".format(bytesToGigaBytes(size))
|
||||||
|
val quality =
|
||||||
|
Regex("(\\d{3,4})[pP]").find(
|
||||||
|
file.name ?: return@apmap null
|
||||||
|
)?.groupValues?.getOrNull(1)?.toIntOrNull()
|
||||||
|
?: Qualities.P1080.value
|
||||||
|
|
||||||
|
callback.invoke(
|
||||||
|
ExtractorLink(
|
||||||
|
"Chillmovies [$sizeFile]",
|
||||||
|
"Chillmovies [$sizeFile]",
|
||||||
|
path,
|
||||||
|
"",
|
||||||
|
quality,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamM4u : XStreamCdn() {
|
class StreamM4u : XStreamCdn() {
|
||||||
|
@ -2471,7 +2481,7 @@ data class WatchsomuchSubResponses(
|
||||||
@JsonProperty("subtitles") val subtitles: ArrayList<WatchsomuchSubtitles>? = arrayListOf(),
|
@JsonProperty("subtitles") val subtitles: ArrayList<WatchsomuchSubtitles>? = arrayListOf(),
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Baymovies(
|
data class IndexMedia(
|
||||||
@JsonProperty("id") val id: String? = null,
|
@JsonProperty("id") val id: String? = null,
|
||||||
@JsonProperty("driveId") val driveId: String? = null,
|
@JsonProperty("driveId") val driveId: String? = null,
|
||||||
@JsonProperty("mimeType") val mimeType: String? = null,
|
@JsonProperty("mimeType") val mimeType: String? = null,
|
||||||
|
@ -2480,10 +2490,10 @@ data class Baymovies(
|
||||||
@JsonProperty("modifiedTime") val modifiedTime: String? = null,
|
@JsonProperty("modifiedTime") val modifiedTime: String? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class BaymoviesData(
|
data class IndexData(
|
||||||
@JsonProperty("files") val files: ArrayList<Baymovies>? = arrayListOf(),
|
@JsonProperty("files") val files: ArrayList<IndexMedia>? = arrayListOf(),
|
||||||
)
|
)
|
||||||
|
|
||||||
data class BaymoviesSearch(
|
data class IndexSearch(
|
||||||
@JsonProperty("data") val data: BaymoviesData? = null,
|
@JsonProperty("data") val data: IndexData? = null,
|
||||||
)
|
)
|
|
@ -5,6 +5,7 @@ import com.hexated.SoraExtractor.invoke123Movie
|
||||||
import com.hexated.SoraExtractor.invokeAnimes
|
import com.hexated.SoraExtractor.invokeAnimes
|
||||||
import com.hexated.SoraExtractor.invokeBaymovies
|
import com.hexated.SoraExtractor.invokeBaymovies
|
||||||
import com.hexated.SoraExtractor.invokeBollyMaza
|
import com.hexated.SoraExtractor.invokeBollyMaza
|
||||||
|
import com.hexated.SoraExtractor.invokeChillmovies
|
||||||
import com.hexated.SoraExtractor.invokeDbgo
|
import com.hexated.SoraExtractor.invokeDbgo
|
||||||
import com.hexated.SoraExtractor.invokeFilmxy
|
import com.hexated.SoraExtractor.invokeFilmxy
|
||||||
import com.hexated.SoraExtractor.invokeFlixhq
|
import com.hexated.SoraExtractor.invokeFlixhq
|
||||||
|
@ -106,6 +107,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 baymoviesAPI = "https://thebayindexpublicgroupapi.zindex.eu.org"
|
const val baymoviesAPI = "https://thebayindexpublicgroupapi.zindex.eu.org"
|
||||||
|
const val chillmoviesAPI = "https://chill.aicirou.workers.dev"
|
||||||
|
|
||||||
fun getType(t: String?): TvType {
|
fun getType(t: String?): TvType {
|
||||||
return when (t) {
|
return when (t) {
|
||||||
|
@ -539,6 +541,15 @@ open class SoraStream : TmdbProvider() {
|
||||||
res.episode,
|
res.episode,
|
||||||
callback
|
callback
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
invokeChillmovies (
|
||||||
|
res.title,
|
||||||
|
res.year,
|
||||||
|
res.season,
|
||||||
|
res.episode,
|
||||||
|
callback
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull
|
||||||
import okhttp3.RequestBody.Companion.toRequestBody
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
data class FilmxyCookies(
|
data class FilmxyCookies(
|
||||||
val phpsessid: String? = null,
|
val phpsessid: String? = null,
|
||||||
|
@ -598,6 +599,70 @@ fun List<HashMap<String, String>>?.matchingEpisode(episode: Int?): String? {
|
||||||
}?.get("id")
|
}?.get("id")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getEpisodeSlug(
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null,
|
||||||
|
): Pair<String, String> {
|
||||||
|
return if (season == null && episode == null) {
|
||||||
|
"" to ""
|
||||||
|
} else {
|
||||||
|
(if (season!! < 10) "0$season" else "$season") to (if (episode!! < 10) "0$episode" else "$episode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTitleSlug(title: String? = null): Pair<String?, String?> {
|
||||||
|
return title.fixTitle()?.replace("-", ".") to title.fixTitle()?.replace("-", " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getIndexQuery(
|
||||||
|
title: String? = null,
|
||||||
|
year: Int? = null,
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null
|
||||||
|
): String {
|
||||||
|
val (seasonSlug, episodeSlug) = getEpisodeSlug(season, episode)
|
||||||
|
return if (season == null) {
|
||||||
|
"$title $year"
|
||||||
|
} else {
|
||||||
|
"$title S${seasonSlug}E${episodeSlug}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun searchIndex(
|
||||||
|
title: String? = null,
|
||||||
|
season: Int? = null,
|
||||||
|
episode: Int? = null,
|
||||||
|
year: Int? = null,
|
||||||
|
response: NiceResponse
|
||||||
|
): List<IndexMedia>? {
|
||||||
|
val (dotSlug, spaceSlug) = getTitleSlug(title)
|
||||||
|
val (seasonSlug, episodeSlug) = getEpisodeSlug(season, episode)
|
||||||
|
val mimeType = arrayOf(
|
||||||
|
"video/x-matroska",
|
||||||
|
"video/mp4",
|
||||||
|
"video/x-msvideo"
|
||||||
|
)
|
||||||
|
return response.parsedSafe<IndexSearch>()?.data?.files?.filter { media ->
|
||||||
|
(if (season == null) {
|
||||||
|
media.name?.contains("$year") == true
|
||||||
|
} else {
|
||||||
|
media.name?.contains(Regex("(?i)S${seasonSlug}.?E${episodeSlug}")) == true
|
||||||
|
}) && media.name?.contains(
|
||||||
|
"720p",
|
||||||
|
true
|
||||||
|
) == false && (media.mimeType in mimeType) && (media.name.replace(
|
||||||
|
"-",
|
||||||
|
"."
|
||||||
|
).contains(
|
||||||
|
"$dotSlug",
|
||||||
|
true
|
||||||
|
) || media.name.replace(
|
||||||
|
"-",
|
||||||
|
" "
|
||||||
|
).contains("$spaceSlug", true))
|
||||||
|
}?.distinctBy { it.name }
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun getConfig(): BaymoviesConfig {
|
suspend fun getConfig(): BaymoviesConfig {
|
||||||
val regex = """const country = "(.*?)";
|
val regex = """const country = "(.*?)";
|
||||||
const downloadtime = "(.*?)";
|
const downloadtime = "(.*?)";
|
||||||
|
@ -687,6 +752,12 @@ fun getDbgoLanguage(str: String): String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun String.encodeUrl() : String {
|
||||||
|
val url = URL(this)
|
||||||
|
val uri = URI(url.protocol, url.userInfo, url.host, url.port, url.path, url.query, url.ref)
|
||||||
|
return uri.toURL().toString()
|
||||||
|
}
|
||||||
|
|
||||||
fun getBaseUrl(url: String): String {
|
fun getBaseUrl(url: String): String {
|
||||||
return URI(url).let {
|
return URI(url).let {
|
||||||
"${it.scheme}://${it.host}"
|
"${it.scheme}://${it.host}"
|
||||||
|
|
Loading…
Reference in a new issue