mirror of
https://github.com/hexated/cloudstream-extensions-hexated.git
synced 2024-08-15 00:03:22 +00:00
sora: added Pobmovies
This commit is contained in:
parent
04f6dac736
commit
e7777079e6
5 changed files with 115 additions and 28 deletions
|
@ -1,7 +1,7 @@
|
|||
import org.jetbrains.kotlin.konan.properties.Properties
|
||||
|
||||
// use an integer for version numbers
|
||||
version = 141
|
||||
version = 142
|
||||
|
||||
android {
|
||||
defaultConfig {
|
||||
|
|
|
@ -1013,16 +1013,18 @@ object SoraExtractor : SoraStream() {
|
|||
val animeId =
|
||||
app.get("https://raw.githubusercontent.com/MALSync/MAL-Sync-Backup/master/data/anilist/anime/${aniId ?: return}.json")
|
||||
.parsedSafe<MALSyncResponses>()?.pages?.zoro?.keys?.map { it }
|
||||
|
||||
val headers = mapOf(
|
||||
"X-Requested-With" to "XMLHttpRequest",
|
||||
)
|
||||
animeId?.apmap { id ->
|
||||
val episodeId = app.get("$zoroAPI/ajax/v2/episode/list/${id ?: return@apmap}")
|
||||
val episodeId = app.get("$zoroAPI/ajax/v2/episode/list/${id ?: return@apmap}", headers = headers)
|
||||
.parsedSafe<ZoroResponses>()?.html?.let {
|
||||
Jsoup.parse(it)
|
||||
}?.select("div.ss-list a")?.find { it.attr("data-number") == "${episode ?: 1}" }
|
||||
?.attr("data-id")
|
||||
|
||||
val servers =
|
||||
app.get("$zoroAPI/ajax/v2/episode/servers?episodeId=${episodeId ?: return@apmap}")
|
||||
app.get("$zoroAPI/ajax/v2/episode/servers?episodeId=${episodeId ?: return@apmap}", headers = headers)
|
||||
.parsedSafe<ZoroResponses>()?.html?.let { Jsoup.parse(it) }
|
||||
?.select("div.item.server-item")?.map {
|
||||
Triple(
|
||||
|
@ -1034,7 +1036,7 @@ object SoraExtractor : SoraStream() {
|
|||
|
||||
servers?.apmap servers@{ server ->
|
||||
val iframe =
|
||||
app.get("$zoroAPI/ajax/v2/episode/sources?id=${server.second ?: return@servers}")
|
||||
app.get("$zoroAPI/ajax/v2/episode/sources?id=${server.second ?: return@servers}", headers = headers)
|
||||
.parsedSafe<ZoroResponses>()?.link ?: return@servers
|
||||
val audio = if (server.third == "sub") "Raw" else "English Dub"
|
||||
if (server.first == "Vidstreaming" || server.first == "Vidcloud") {
|
||||
|
@ -1260,20 +1262,13 @@ object SoraExtractor : SoraStream() {
|
|||
extractMirrorUHD(bitLink, base)
|
||||
}
|
||||
|
||||
val tags =
|
||||
Regex("\\d{3,4}[Pp]\\.?(.*?)\\[").find(quality)?.groupValues?.getOrNull(1)
|
||||
?.replace(".", " ")?.trim()
|
||||
?: ""
|
||||
val qualities =
|
||||
Regex("(\\d{3,4})[Pp]").find(quality)?.groupValues?.getOrNull(1)?.toIntOrNull()
|
||||
?: Qualities.Unknown.value
|
||||
val size =
|
||||
Regex("(?i)\\[(\\S+\\s?(gb|mb))[]/]").find(quality)?.groupValues?.getOrNull(1)
|
||||
?.let { "[$it]" } ?: quality
|
||||
val tags = getUhdTags(quality)
|
||||
val qualities = getIndexQuality(quality)
|
||||
val size = getIndexSize(quality)
|
||||
callback.invoke(
|
||||
ExtractorLink(
|
||||
"UHDMovies",
|
||||
"UHDMovies $tags $size",
|
||||
"UHDMovies $tags [$size]",
|
||||
downloadLink ?: return@apmap,
|
||||
"",
|
||||
qualities
|
||||
|
@ -1285,6 +1280,72 @@ object SoraExtractor : SoraStream() {
|
|||
|
||||
}
|
||||
|
||||
suspend fun invokePobmovies(
|
||||
title: String? = null,
|
||||
year: Int? = null,
|
||||
callback: (ExtractorLink) -> Unit
|
||||
) {
|
||||
val detailDoc = app.get("$pobmoviesAPI/${title.createSlug()}-$year").document
|
||||
val iframeList = detailDoc.select("div.entry-content p").map { it }
|
||||
.filter { it.text().filterIframe(year = year, title = title) }.mapNotNull {
|
||||
it.text() to it.nextElementSibling()?.select("a")?.attr("href")
|
||||
}.filter { it.second?.contains(Regex("(https:)|(http:)")) == true }
|
||||
|
||||
val sources = mutableListOf<Pair<String, String?>>()
|
||||
if (iframeList.any {
|
||||
it.first.contains(
|
||||
"2160p",
|
||||
true
|
||||
)
|
||||
}) {
|
||||
sources.addAll(iframeList.filter {
|
||||
it.first.contains(
|
||||
"2160p",
|
||||
true
|
||||
)
|
||||
})
|
||||
sources.add(iframeList.first {
|
||||
it.first.contains(
|
||||
"1080p",
|
||||
true
|
||||
)
|
||||
})
|
||||
} else {
|
||||
sources.addAll(iframeList.filter { it.first.contains("1080p", true) })
|
||||
}
|
||||
|
||||
sources.apmap { (name, link) ->
|
||||
if (link.isNullOrEmpty()) return@apmap
|
||||
val videoLink = when {
|
||||
link.contains("gdtot") -> {
|
||||
val gdBotLink = extractGdbot(link)
|
||||
extractGdflix(gdBotLink ?: return@apmap)
|
||||
}
|
||||
link.contains("gdflix") -> {
|
||||
extractGdflix(link)
|
||||
}
|
||||
else -> {
|
||||
return@apmap
|
||||
}
|
||||
}
|
||||
|
||||
val tags = getUhdTags(name)
|
||||
val qualities = getIndexQuality(name)
|
||||
val size = getIndexSize(name)
|
||||
callback.invoke(
|
||||
ExtractorLink(
|
||||
"Pobmovies",
|
||||
"Pobmovies $tags [${size}]",
|
||||
videoLink ?: return@apmap,
|
||||
"",
|
||||
qualities
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
suspend fun invokeFwatayako(
|
||||
imdbId: String? = null,
|
||||
season: Int? = null,
|
||||
|
|
|
@ -50,6 +50,7 @@ import com.hexated.SoraExtractor.invokeShivamhw
|
|||
import com.hexated.SoraExtractor.invokeSmashyStream
|
||||
import com.hexated.SoraExtractor.invokeDumpStream
|
||||
import com.hexated.SoraExtractor.invokeEmovies
|
||||
import com.hexated.SoraExtractor.invokePobmovies
|
||||
import com.hexated.SoraExtractor.invokeTvMovies
|
||||
import com.hexated.SoraExtractor.invokeUhdmovies
|
||||
import com.hexated.SoraExtractor.invokeVitoenMovies
|
||||
|
@ -129,6 +130,7 @@ open class SoraStream : TmdbProvider() {
|
|||
const val ridomoviesAPI = "https://ridomovies.pw"
|
||||
const val navyAPI = "https://navy-issue-i-239.site"
|
||||
const val emoviesAPI = "https://emovies.si"
|
||||
const val pobmoviesAPI = "https://pobmovies.cam"
|
||||
|
||||
// INDEX SITE
|
||||
const val blackMoviesAPI = "https://dl.blacklistedbois.workers.dev/0:"
|
||||
|
@ -806,8 +808,11 @@ open class SoraStream : TmdbProvider() {
|
|||
invokeNavy(res.imdbId, res.season, res.episode, callback)
|
||||
},
|
||||
{
|
||||
invokeEmovies(res.title, res.year, res.season, res.episode, subtitleCallback, callback)
|
||||
if (!res.isAnime) invokeEmovies(res.title, res.year, res.season, res.episode, subtitleCallback, callback)
|
||||
},
|
||||
{
|
||||
if(!res.isAnime && res.season == null) invokePobmovies(res.title, res.year, callback)
|
||||
}
|
||||
)
|
||||
|
||||
return true
|
||||
|
|
|
@ -290,7 +290,7 @@ class SoraStreamLite : SoraStream() {
|
|||
)
|
||||
},
|
||||
{
|
||||
invokeEmovies(
|
||||
if (!res.isAnime) invokeEmovies(
|
||||
res.title,
|
||||
res.year,
|
||||
res.season,
|
||||
|
|
|
@ -111,7 +111,12 @@ data class FilmxyCookies(
|
|||
val wSec: String? = null,
|
||||
)
|
||||
|
||||
fun String.filterIframe(seasonNum: Int?, lastSeason: Int?, year: Int?, title: String?): Boolean {
|
||||
fun String.filterIframe(
|
||||
seasonNum: Int? = null,
|
||||
lastSeason: Int? = null,
|
||||
year: Int?,
|
||||
title: String?
|
||||
): Boolean {
|
||||
val slug = title.createSlug()
|
||||
val dotSlug = slug?.replace("-", ".")
|
||||
val spaceSlug = slug?.replace("-", " ")
|
||||
|
@ -271,8 +276,8 @@ suspend fun extractDrivebot(url: String): String? {
|
|||
|
||||
suspend fun extractGdflix(url: String): String? {
|
||||
val iframeGdflix =
|
||||
app.get(url).document.selectFirst("li.flex.flex-col.py-6 a:contains(GDFlix Direct)")
|
||||
?.attr("href") ?: return null
|
||||
if (!url.contains("gdflix")) app.get(url).document.selectFirst("li.flex.flex-col.py-6 a:contains(GDFlix Direct)")
|
||||
?.attr("href") ?: return null else url
|
||||
val base = getBaseUrl(iframeGdflix)
|
||||
|
||||
val req = app.get(iframeGdflix).document.selectFirst("script:containsData(replace)")?.data()
|
||||
|
@ -586,7 +591,10 @@ suspend fun getDumpIdAndType(title: String?, year: Int?, season: Int?): Pair<Str
|
|||
it.name?.contains(
|
||||
"$title",
|
||||
true
|
||||
) == true && (it.releaseTime == "$year" || it.name.contains("Season $season", true)) && it.domainType == 1
|
||||
) == true && (it.releaseTime == "$year" || it.name.contains(
|
||||
"Season $season",
|
||||
true
|
||||
)) && it.domainType == 1
|
||||
}
|
||||
else -> {
|
||||
it.name?.contains(Regex("(?i)$title\\s?($season|${season.toRomanNumeral()}|Season\\s$season)")) == true && it.releaseTime == "$year" && it.domainType == 1
|
||||
|
@ -744,7 +752,11 @@ suspend fun bypassTechmny(url: String): String? {
|
|||
val thirdPage = secondPage.getNextTechPage().text
|
||||
val goToken = thirdPage.substringAfter("?go=").substringBefore("\"")
|
||||
val tokenUrl = "$postUrl?go=$goToken"
|
||||
val headers = mapOf("Cookie" to "$goToken=${secondPage.select("form#landing input[name=_wp_http2]").attr("value")}")
|
||||
val headers = mapOf(
|
||||
"Cookie" to "$goToken=${
|
||||
secondPage.select("form#landing input[name=_wp_http2]").attr("value")
|
||||
}"
|
||||
)
|
||||
Pair(tokenUrl, headers)
|
||||
}
|
||||
val driveUrl =
|
||||
|
@ -1279,6 +1291,12 @@ fun String.getFileSize(): Float? {
|
|||
}
|
||||
}
|
||||
|
||||
fun getUhdTags(str: String?): String {
|
||||
return Regex("\\d{3,4}[Pp]\\.?(.*?)\\[").find(str ?: "")?.groupValues?.getOrNull(1)
|
||||
?.replace(".", " ")?.trim()
|
||||
?: str ?: ""
|
||||
}
|
||||
|
||||
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(
|
||||
|
@ -1486,12 +1504,13 @@ fun getBaseUrl(url: String): String {
|
|||
}
|
||||
}
|
||||
|
||||
fun isUpcoming(dateString: String?) : Boolean {
|
||||
if(dateString == null) return false
|
||||
fun isUpcoming(dateString: String?): Boolean {
|
||||
if (dateString == null) return false
|
||||
val format = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||
val dateTime = format.parse(dateString)?.time ?: return false
|
||||
return unixTimeMS < dateTime
|
||||
}
|
||||
|
||||
fun decode(input: String): String = URLDecoder.decode(input, "utf-8")
|
||||
|
||||
fun encode(input: String): String = URLEncoder.encode(input, "utf-8").replace("+", "%20")
|
||||
|
@ -2021,8 +2040,9 @@ object DumpUtils {
|
|||
return app.custom(
|
||||
method,
|
||||
url,
|
||||
requestBody = if(method == "POST") params.toJson().toRequestBody(RequestBodyTypes.JSON.toMediaTypeOrNull()) else null,
|
||||
params = if(method == "GET") params else emptyMap(),
|
||||
requestBody = if (method == "POST") params.toJson()
|
||||
.toRequestBody(RequestBodyTypes.JSON.toMediaTypeOrNull()) else null,
|
||||
params = if (method == "GET") params else emptyMap(),
|
||||
headers = createHeaders(params)
|
||||
).parsedSafe<HashMap<String, String>>()?.get("data").let {
|
||||
cryptoHandler(
|
||||
|
@ -2062,7 +2082,8 @@ object DumpUtils {
|
|||
}
|
||||
|
||||
private fun getAesKey(): String? {
|
||||
val publicKey = RSAEncryptionHelper.getPublicKeyFromString(BuildConfig.DUMP_KEY) ?: return null
|
||||
val publicKey =
|
||||
RSAEncryptionHelper.getPublicKeyFromString(BuildConfig.DUMP_KEY) ?: return null
|
||||
return RSAEncryptionHelper.encryptText(deviceId, publicKey)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue