[test] Adding UHDMovies into SoraExtractor

This commit is contained in:
hexated 2022-11-21 17:27:07 +07:00
parent de52441ad0
commit 6c10e59ee5
9 changed files with 135 additions and 17 deletions

View file

@ -7,7 +7,7 @@ cloudstream {
// All of these properties are optional, you can safely remove them
description = "Premium porn with 4K support (use VPN if links not working)"
authors = listOf("Hexated")
authors = listOf("Sora")
/**
* Status int as the following:

View file

@ -7,7 +7,7 @@ cloudstream {
// All of these properties are optional, you can safely remove them
// description = "Lorem Ipsum"
authors = listOf("Hexated")
authors = listOf("Sora")
/**
* Status int as the following:

View file

@ -6,7 +6,7 @@ cloudstream {
language = "en"
// All of these properties are optional, you can safely remove them
description = "#1 best extension based on Loklok API"
description = "#2 best extension based on Loklok API"
authors = listOf("Hexated")
/**

View file

@ -7,7 +7,7 @@ cloudstream {
// All of these properties are optional, you can safely remove them
description = "Series porn (use VPN if links not working)"
authors = listOf("Hexated")
authors = listOf("Sora")
/**
* Status int as the following:

View file

@ -1,12 +1,12 @@
// use an integer for version numbers
version = 32
version = 33
cloudstream {
language = "en"
// All of these properties are optional, you can safely remove them
description = "#2 best extention based on MultiAPI"
description = "#1 best extention based on MultiAPI"
authors = listOf("Hexated", "Sora")
/**

View file

@ -1163,18 +1163,13 @@ object SoraExtractor : SoraStream() {
val source = app.get(iframe ?: return)
val link = Regex("((https:|http:)//.*\\.mp4)").find(source.text)?.value ?: return
val quality = when {
link.contains("1080p") -> Qualities.P1080.value
link.contains("720p") -> Qualities.P720.value
else -> Qualities.Unknown.value
}
callback.invoke(
ExtractorLink(
"Ling",
"Ling",
link,
"$lingAPI/",
quality,
Qualities.Unknown.value,
headers = mapOf(
"Range" to "bytes=0-"
)
@ -1192,6 +1187,81 @@ object SoraExtractor : SoraStream() {
}
suspend fun invokeUhdmovies(
title: String? = null,
year: Int? = null,
season: Int? = null,
lastSeason: Int? = null,
episode: Int? = null,
subtitleCallback: (SubtitleFile) -> Unit,
callback: (ExtractorLink) -> Unit
) {
val doc = app.get("$uhdmoviesAPI/?s=$title").document
val scriptData = doc.select("div.row.gridlove-posts article").map {
it.selectFirst("a")?.attr("href") to it.selectFirst("h1")?.text()
}
val script = if (scriptData.size == 1) {
scriptData.first()
} else {
scriptData.find { it.second?.filterMedia(title, year, lastSeason) == true }
}
val detailDoc = app.get(script?.first ?: return).document
val iframe =
detailDoc.select("div.entry-content p").map { it }
.filter { it.text().filterIframe(season, year) }
.mapNotNull {
if (season == null) {
Triple(
it.ownText(),
it.selectFirst("span")?.text(),
it.nextElementSibling()?.select("a")?.attr("href")
)
} else {
Triple(
it.ownText(),
it.selectFirst("span")?.text(),
it.nextElementSibling()?.select("a:contains(Episode $episode)")
?.attr("href")
)
}
}
iframe.apmap { (quality, size, link) ->
val res = app.get(link ?: return@apmap null).document
val base = getBaseUrl(link)
val bitLink =
res.selectFirst("a.btn.btn-outline-success")?.attr("href") ?: return@apmap null
val downLink =
app.get(fixUrl(bitLink, base)).document.selectFirst("div.mb-4 a")?.attr("href")
val mirrorLink = app.get(
downLink ?: return@apmap null
).document.selectFirst("form[method=post] a.btn.btn-primary")
?.attr("onclick")?.substringAfter("Openblank('")?.substringBefore("')")?.let {
app.get(it).document.selectFirst("script:containsData(input.value =)")
?.data()?.substringAfter("input.value = '")?.substringBefore("';")
}
val videoQuality = Regex("(\\d{3,4})p").find(quality)?.groupValues?.getOrNull(1)?.toIntOrNull()
?: Qualities.Unknown.value
val videoSize = size?.substringBeforeLast("/")
callback.invoke(
ExtractorLink(
"UHDMovies [$videoSize]",
"UHDMovies [$videoSize]",
mirrorLink ?: return@apmap null,
"",
videoQuality
)
)
}
}
}
data class FilmxyCookies(
@ -1200,6 +1270,31 @@ data class FilmxyCookies(
val wSec: String? = null,
)
fun String.filterIframe(seasonNum: Int?, year: Int?): Boolean {
return if (seasonNum != null) {
this.contains(Regex("(?i)(S0?$seasonNum)")) && !this.contains("Download", true)
} else {
this.contains("$year", true) && !this.contains("Download", true)
}
}
fun String.filterMedia(title: String?, yearNum: Int?, seasonNum: Int?): Boolean {
return if (seasonNum != null) {
when {
seasonNum > 1 -> this.contains(Regex("(?i)(Season\\s0?1-0?$seasonNum)|(S0?1-S?0?$seasonNum)")) && this.contains(
"$title",
true
) && this.contains("$yearNum")
else -> this.contains(Regex("(?i)(Season\\s0?1)|(S0?1)")) && this.contains(
"$title",
true
) && this.contains("$yearNum")
}
} else {
this.contains("$title", true) && this.contains("$yearNum")
}
}
suspend fun getFilmxyCookies(imdbId: String? = null, season: Int? = null): FilmxyCookies? {
val url = if (season == null) {

View file

@ -23,6 +23,7 @@ import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
import com.lagradost.cloudstream3.metaproviders.TmdbProvider
import com.hexated.SoraExtractor.invoZoro
import com.hexated.SoraExtractor.invokeLing
import com.hexated.SoraExtractor.invokeUhdmovies
import com.lagradost.cloudstream3.utils.AppUtils.parseJson
import com.lagradost.cloudstream3.utils.AppUtils.toJson
import com.lagradost.cloudstream3.utils.ExtractorLink
@ -69,6 +70,7 @@ open class SoraStream : TmdbProvider() {
const val consumetZoroAPI = "https://api.consumet.org/anime/zoro"
const val kissKhAPI = "https://kisskh.me"
const val lingAPI = "https://ling-online.net"
const val uhdmoviesAPI = "https://uhdmovies.site"
fun getType(t: String?): TvType {
return when (t) {
@ -209,6 +211,7 @@ open class SoraStream : TmdbProvider() {
return if (type == TvType.TvSeries) {
val episodes = mutableListOf<Episode>()
val lastSeason = res.seasons?.lastOrNull()?.seasonNumber
res.seasons?.apmap { season ->
app.get("$tmdbAPI/${data.type}/${data.id}/season/${season.seasonNumber}?api_key=$apiKey")
.parsedSafe<MediaDetailEpisodes>()?.episodes?.map { eps ->
@ -223,7 +226,8 @@ open class SoraStream : TmdbProvider() {
year = season.airDate?.split("-")?.first()?.toIntOrNull(),
orgTitle = orgTitle,
show = show,
airedYear = year
airedYear = year,
lastSeason = lastSeason
).toJson(),
name = eps.name,
season = eps.seasonNumber,
@ -342,9 +346,9 @@ open class SoraStream : TmdbProvider() {
{
invokeVidSrc(res.id, res.season, res.episode, subtitleCallback, callback)
},
{
invokeOlgply(res.id, res.season, res.episode, callback)
},
// {
// invokeOlgply(res.id, res.season, res.episode, callback)
// },
{
invokeDbgo(res.imdbId, res.season, res.episode, subtitleCallback, callback)
},
@ -447,6 +451,17 @@ open class SoraStream : TmdbProvider() {
callback
)
},
{
invokeUhdmovies(
res.title,
res.year,
res.season,
res.lastSeason,
res.episode,
subtitleCallback,
callback
)
},
)
return true
@ -465,6 +480,7 @@ open class SoraStream : TmdbProvider() {
val orgTitle: String? = null,
val show: String? = null,
val airedYear: Int? = null,
val lastSeason: Int? = null,
)
data class Data(

View file

@ -149,7 +149,7 @@ class WcofunProvider : MainAPI() {
"${this.name} ${source.second}",
"${this.name} ${source.second}",
"${it.server}/getvid?evid=${source.first}",
mainUrl,
referer = mainUrl,
if (source.second == "HD") Qualities.P720.value else Qualities.P480.value
)
)

View file

@ -1,5 +1,6 @@
import com.lagradost.cloudstream3.gradle.CloudstreamExtension
import com.android.build.gradle.BaseExtension
import java.util.Properties
buildscript {
repositories {
@ -47,6 +48,12 @@ subprojects {
defaultConfig {
minSdk = 21
targetSdk = 32
// val properties = Properties()
// properties.load(project.rootProject.file("local.properties").inputStream())
//
// buildConfigField("String", "API_KEY", "\"${properties.getProperty("API_KEY")}\"")
}
compileOptions {