diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Acefile.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Acefile.kt index a86c5f01a83..5b214c5dd1b 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Acefile.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Acefile.kt @@ -1,8 +1,11 @@ package com.lagradost.cloudstream3.extractors +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.* +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class Acefile : ExtractorApi() { override val name = "Acefile" @@ -13,7 +16,7 @@ open class Acefile : ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val id = "/(?:d|download|player|f|file)/(\\w+)".toRegex().find(url)?.groupValues?.get(1) val script = getAndUnpack(app.get("$mainUrl/player/${id ?: return}").text) @@ -27,14 +30,14 @@ open class Acefile : ExtractorApi() { newExtractorLink( this.name, this.name, - video ?: return + video ?: return, ) ) } + @Serializable data class Source( - val data: String? = null, + @JsonProperty("data") @SerialName("data") val data: String? = null, ) - -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Blogger.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Blogger.kt index a9f4a3eb99a..e00ffcb576d 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Blogger.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Blogger.kt @@ -4,6 +4,8 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class Blogger : ExtractorApi() { override val name = "Blogger" @@ -22,10 +24,10 @@ open class Blogger : ExtractorApi() { newExtractorLink( name, name, - it.play_url, + it.playUrl, ) { this.referer = "https://www.youtube.com/" - this.quality = when (it.format_id) { + this.quality = when (it.formatId) { 18 -> 360 22 -> 720 else -> Qualities.Unknown.value @@ -36,11 +38,13 @@ open class Blogger : ExtractorApi() { } } } + return sources } + @Serializable private data class ResponseSource( - @JsonProperty("play_url") val play_url: String, - @JsonProperty("format_id") val format_id: Int + @JsonProperty("play_url") @SerialName("play_url") val playUrl: String, + @JsonProperty("format_id") @SerialName("format_id") val formatId: Int, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/ByseSX.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/ByseSX.kt index 248b94a7350..92362ac3949 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/ByseSX.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/ByseSX.kt @@ -13,30 +13,32 @@ import dev.whyoleg.cryptography.DelicateCryptographyApi import dev.whyoleg.cryptography.algorithms.AES import io.ktor.http.Url import io.ktor.http.decodeURLPart +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable class Bysezejataos : ByseSX() { - override var name = "Bysezejataos" - override var mainUrl = "https://bysezejataos.com" + override val name = "Bysezejataos" + override val mainUrl = "https://bysezejataos.com" } class ByseBuho : ByseSX() { - override var name = "ByseBuho" - override var mainUrl = "https://bysebuho.com" + override val name = "ByseBuho" + override val mainUrl = "https://bysebuho.com" } class ByseVepoin : ByseSX() { - override var name = "ByseVepoin" - override var mainUrl = "https://bysevepoin.com" + override val name = "ByseVepoin" + override val mainUrl = "https://bysevepoin.com" } class ByseQekaho : ByseSX() { - override var name = "ByseQekaho" - override var mainUrl = "https://byseqekaho.com" + override val name = "ByseQekaho" + override val mainUrl = "https://byseqekaho.com" } open class ByseSX : ExtractorApi() { - override var name = "Byse" - override var mainUrl = "https://byse.sx" + override val name = "Byse" + override val mainUrl = "https://byse.sx" override val requiresReferer = true private val aesGcm = CryptographyProvider.Default.get(AES.GCM) @@ -112,7 +114,7 @@ open class ByseSX : ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val refererUrl = getBaseUrl(url) val playbackRoot = getPlayback(url) ?: return @@ -123,64 +125,58 @@ open class ByseSX : ExtractorApi() { name, streamUrl, mainUrl, - headers = headers + headers = headers, ).forEach(callback) } } +@Serializable data class DetailsRoot( - val id: Long, - val code: String, - val title: String, - @JsonProperty("poster_url") - val posterUrl: String, - val description: String, - @JsonProperty("created_at") - val createdAt: String, - @JsonProperty("owner_private") - val ownerPrivate: Boolean, - @JsonProperty("embed_frame_url") - val embedFrameUrl: String, + @JsonProperty("id") @SerialName("id") val id: Long, + @JsonProperty("code") @SerialName("code") val code: String, + @JsonProperty("title") @SerialName("title") val title: String, + @JsonProperty("poster_url") @SerialName("poster_url") val posterUrl: String, + @JsonProperty("description") @SerialName("description") val description: String, + @JsonProperty("created_at") @SerialName("created_at") val createdAt: String, + @JsonProperty("owner_private") @SerialName("owner_private") val ownerPrivate: Boolean, + @JsonProperty("embed_frame_url") @SerialName("embed_frame_url") val embedFrameUrl: String, ) +@Serializable data class PlaybackRoot( - val playback: Playback, + @JsonProperty("playback") @SerialName("playback") val playback: Playback, ) +@Serializable data class Playback( - val algorithm: String, - val iv: String, - val payload: String, - @JsonProperty("key_parts") - val keyParts: List, - @JsonProperty("expires_at") - val expiresAt: String, - @JsonProperty("decrypt_keys") - val decryptKeys: DecryptKeys, - val iv2: String, - val payload2: String, + @JsonProperty("algorithm") @SerialName("algorithm") val algorithm: String, + @JsonProperty("iv") @SerialName("iv") val iv: String, + @JsonProperty("payload") @SerialName("payload") val payload: String, + @JsonProperty("key_parts") @SerialName("key_parts") val keyParts: List, + @JsonProperty("expires_at") @SerialName("expires_at") val expiresAt: String, + @JsonProperty("decrypt_keys") @SerialName("decrypt_keys") val decryptKeys: DecryptKeys, + @JsonProperty("iv2") @SerialName("iv2") val iv2: String, + @JsonProperty("payload2") @SerialName("payload2") val payload2: String, ) +@Serializable data class DecryptKeys( - @JsonProperty("edge_1") - val edge1: String, - @JsonProperty("edge_2") - val edge2: String, - @JsonProperty("legacy_fallback") - val legacyFallback: String, + @JsonProperty("edge_1") @SerialName("edge_1") val edge1: String, + @JsonProperty("edge_2") @SerialName("edge_2") val edge2: String, + @JsonProperty("legacy_fallback") @SerialName("legacy_fallback") val legacyFallback: String, ) +@Serializable data class PlaybackDecrypt( - val sources: List, + @JsonProperty("sources") @SerialName("sources") val sources: List, ) +@Serializable data class PlaybackDecryptSource( - val quality: String, - val label: String, - @JsonProperty("mime_type") - val mimeType: String, - val url: String, - @JsonProperty("bitrate_kbps") - val bitrateKbps: Long, - val height: Any?, + @JsonProperty("quality") @SerialName("quality") val quality: String, + @JsonProperty("label") @SerialName("label") val label: String, + @JsonProperty("mime_type") @SerialName("mime_type") val mimeType: String, + @JsonProperty("url") @SerialName("url") val url: String, + @JsonProperty("bitrate_kbps") @SerialName("bitrate_kbps") val bitrateKbps: Long, + @JsonProperty("height") @SerialName("height") val height: Int?, ) diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Cda.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Cda.kt index 5c9f58efca9..3b5189f0e58 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Cda.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Cda.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.extractors +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.USER_AGENT import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson @@ -8,6 +9,8 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.StringUtils.decodeUrl import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class Cda : ExtractorApi() { override var mainUrl = "https://ebd.cda.pl" @@ -22,7 +25,7 @@ open class Cda : ExtractorApi() { "https://ebd.cda.pl/647x500/$mediaId", headers = mapOf( "Referer" to "https://ebd.cda.pl/647x500/$mediaId", "User-Agent" to USER_AGENT, - "Cookie" to "cda.player=html5" + "Cookie" to "cda.player=html5", ) ).document val dataRaw = doc.selectFirst("[player_data]")?.attr("player_data") ?: return null @@ -86,15 +89,17 @@ open class Cda : ExtractorApi() { else -> a } + @Serializable data class VideoPlayerData( - val file: String, - val qualities: Map = mapOf(), - val quality: String?, - val ts: Int?, - val hash2: String? + @JsonProperty("file") @SerialName("file") val file: String, + @JsonProperty("qualities") @SerialName("qualities") val qualities: Map = mapOf(), + @JsonProperty("quality") @SerialName("quality") val quality: String?, + @JsonProperty("ts") @SerialName("ts") val ts: Int?, + @JsonProperty("hash2") @SerialName("hash2") val hash2: String?, ) + @Serializable data class PlayerData( - val video: VideoPlayerData + @JsonProperty("video") @SerialName("video") val video: VideoPlayerData, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Firestream.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Firestream.kt index c8ef5d0ac31..8946f3348ed 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Firestream.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Firestream.kt @@ -1,5 +1,6 @@ package com.lagradost.cloudstream3.extractors +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.Prerelease import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app @@ -11,31 +12,29 @@ import kotlinx.serialization.Serializable @Prerelease class Firestream : ExtractorApi() { - override val name: String = "Firestream" - override val mainUrl: String = "https://firestream.to" - override val requiresReferer: Boolean = false + override val name = "Firestream" + override val mainUrl = "https://firestream.to" + override val requiresReferer = false override suspend fun getUrl( url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val id = url.removeSuffix("/").substringAfterLast("/") val url = getExtractorUrl(id) val doc = app.get(url).document val token = doc.selectFirst("script[id=token-blob]")!!.data() - - val videoResponse = - app.post("$mainUrl/api/videos/$id/resolve", json = mapOf("blob" to token)) - .parsed() + val videoResponse = app.post("$mainUrl/api/videos/$id/resolve", json = mapOf("blob" to token)) + .parsed() callback.invoke( newExtractorLink( source = name, name = name, - url = videoResponse.signedVideoUrl + url = videoResponse.signedVideoUrl, ) ) } @@ -46,7 +45,6 @@ class Firestream : ExtractorApi() { @Serializable private data class VideoResponse( - @SerialName("signedVideoUrl") - val signedVideoUrl: String, + @JsonProperty("signedVideoUrl") @SerialName("signedVideoUrl") val signedVideoUrl: String, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Flyfile.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Flyfile.kt index eb6d474a544..92dc99ca305 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Flyfile.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Flyfile.kt @@ -12,16 +12,16 @@ import kotlinx.serialization.Serializable @Prerelease open class Flyfile : ExtractorApi() { - override val name: String = "FlyFile" - override val mainUrl: String = "https://flyfile.app" + override val name = "FlyFile" + override val mainUrl = "https://flyfile.app" + override val requiresReferer = false open val apiUrl: String = "https://api.flyfile.app" - override val requiresReferer: Boolean = false override suspend fun getUrl( url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val videoId = url.substringAfterLast("/") val videoInfo = app.get("$apiUrl/api/streaming/assign/$videoId") @@ -33,16 +33,14 @@ open class Flyfile : ExtractorApi() { source = name, name = name, url = streamUrl, - type = ExtractorLinkType.M3U8 + type = ExtractorLinkType.M3U8, ) ) } @Serializable private data class StreamInfo( - @SerialName("url") - val url: String, - @SerialName("token") - val token: String + @SerialName("url") val url: String, + @SerialName("token") val token: String, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/GUpload.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/GUpload.kt index 7daaa55cc94..33e5ebac13d 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/GUpload.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/GUpload.kt @@ -4,11 +4,14 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.base64Decode -import com.lagradost.cloudstream3.utils.AppUtils +import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement open class GUpload: ExtractorApi() { override val name: String = "GUpload" @@ -19,14 +22,12 @@ open class GUpload: ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val response = app.get(url, referer = referer).text - val playerConfigEncoded = response.substringAfter("decodePayload('").substringBefore("');") val playerConfigString = base64Decode(playerConfigEncoded).substringAfter("|") - - val playerConfig = AppUtils.parseJson(playerConfigString) + val playerConfig = parseJson(playerConfigString) callback.invoke( newExtractorLink( @@ -41,14 +42,15 @@ open class GUpload: ExtractorApi() { ) } + @Serializable private data class VideoInfo( - @JsonProperty("videoUrl") val videoUrl: String, - @JsonProperty("posterUrl") val posterUrl: String? = null, - @JsonProperty("videoId") val videoId: String? = null, - @JsonProperty("primaryColor") val primaryColor: String? = null, - @JsonProperty("audioTracks") val audioTracks: List = emptyList(), - @JsonProperty("subtitleTracks") val subtitleTracks: List = emptyList(), - @JsonProperty("vastFallbackList") val vastFallbackList: List = emptyList(), - @JsonProperty("videoOwnerId") val videoOwnerId: Long = 0, + @JsonProperty("videoUrl") @SerialName("videoUrl") val videoUrl: String, + @JsonProperty("posterUrl") @SerialName("posterUrl") val posterUrl: String? = null, + @JsonProperty("videoId") @SerialName("videoId") val videoId: String? = null, + @JsonProperty("primaryColor") @SerialName("primaryColor") val primaryColor: String? = null, + @JsonProperty("audioTracks") @SerialName("audioTracks") val audioTracks: List = emptyList(), + @JsonProperty("subtitleTracks") @SerialName("subtitleTracks") val subtitleTracks: List = emptyList(), + @JsonProperty("vastFallbackList") @SerialName("vastFallbackList") val vastFallbackList: List = emptyList(), + @JsonProperty("videoOwnerId") @SerialName("videoOwnerId") val videoOwnerId: Long = 0, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gdriveplayer.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gdriveplayer.kt index f484d766c5d..10abcce31d3 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gdriveplayer.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gdriveplayer.kt @@ -5,14 +5,16 @@ import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.extractors.helper.AesHelper.cryptoAESHandler import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable import org.jsoup.nodes.Element class DatabaseGdrive2 : Gdriveplayer() { - override var mainUrl = "https://databasegdriveplayer.co" + override val mainUrl = "https://databasegdriveplayer.co" } class DatabaseGdrive : Gdriveplayer() { - override var mainUrl = "https://series.databasegdriveplayer.co" + override val mainUrl = "https://series.databasegdriveplayer.co" } class Gdriveplayerapi : Gdriveplayer() { @@ -73,10 +75,9 @@ open class Gdriveplayer : ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val document = app.get(url).document - val eval = unpackJs(document)?.replace("\\", "") ?: return val data = Regex("data='(\\S+?)'").first(eval) ?: return val password = Regex("null,['|\"](\\w+)['|\"]").first(eval) @@ -84,9 +85,9 @@ open class Gdriveplayer : ExtractorApi() { ?.joinToString("") { it.toInt().toChar().toString() }.let { Regex("var pass = \"(\\S+?)\"").first(it ?: return)?.encodeToByteArray() } - ?: throw ErrorLoadingException("can't find password") - val decryptedData = cryptoAESHandler(data, password, false, false)?.let { getAndUnpack(it) }?.replace("\\", "") + ?: throw ErrorLoadingException("can't find password") + val decryptedData = cryptoAESHandler(data, password, false, false)?.let { getAndUnpack(it) }?.replace("\\", "") val sourceData = decryptedData?.substringAfter("sources:[")?.substringBefore("],") val subData = decryptedData?.substringAfter("tracks:[")?.substringBefore("],") @@ -111,16 +112,17 @@ open class Gdriveplayer : ExtractorApi() { subtitleCallback.invoke( newSubtitleFile( sub.label, - httpsify(sub.file) + httpsify(sub.file), ) ) } } } + @Serializable data class Tracks( - @JsonProperty("file") val file: String, - @JsonProperty("kind") val kind: String, - @JsonProperty("label") val label: String, + @JsonProperty("file") @SerialName("file") val file: String, + @JsonProperty("kind") @SerialName("kind") val kind: String, + @JsonProperty("label") @SerialName("label") val label: String, ) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gofile.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gofile.kt index 2b42e42c77e..9edc54a4175 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gofile.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Gofile.kt @@ -8,6 +8,8 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.ExtractorLinkType import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable import kotlin.math.round open class Gofile : ExtractorApi() { @@ -20,20 +22,18 @@ open class Gofile : ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val id = Regex("/(?:\\?c=|d/)([\\da-zA-Z-]+)").find(url)?.groupValues?.get(1) ?: return - val token = app.post( "$mainApi/accounts", ).parsedSafe()?.data?.token ?: return val globalRes = app.get("$mainUrl/dist/js/config.js").text val wt = Regex("""appdata\.wt\s*=\s*[\"']([^\"']+)[\"']""").find(globalRes)?.groupValues?.get(1) ?: return - val headers = mapOf( "Authorization" to "Bearer $token", - "X-Website-Token" to wt + "X-Website-Token" to wt, ) val parsedResponse = app.get( @@ -42,7 +42,6 @@ open class Gofile : ExtractorApi() { ).parsedSafe() val childrenMap = parsedResponse?.data?.children ?: return - for ((_, file) in childrenMap) { if (file.link.isNullOrEmpty() || file.type != "file") continue val fileName = file.name ?: "" @@ -54,7 +53,7 @@ open class Gofile : ExtractorApi() { "Gofile", "[Gofile] $fileName [$formattedSize]", file.link, - ExtractorLinkType.VIDEO + ExtractorLinkType.VIDEO, ) { this.quality = getQuality(fileName) this.headers = mapOf("Cookie" to "accountToken=$token") @@ -84,26 +83,31 @@ open class Gofile : ExtractorApi() { } } + @Serializable data class AccountResponse( - @JsonProperty("data") val data: AccountData? = null + @JsonProperty("data") @SerialName("data") val data: AccountData? = null, ) + @Serializable data class AccountData( - @JsonProperty("token") val token: String? = null + @JsonProperty("token") @SerialName("token") val token: String? = null, ) + @Serializable data class GofileResponse( - @JsonProperty("data") val data: GofileData? = null + @JsonProperty("data") @SerialName("data") val data: GofileData? = null, ) + @Serializable data class GofileData( - @JsonProperty("children") val children: Map? = null + @JsonProperty("children") @SerialName("children") val children: Map? = null, ) + @Serializable data class GofileFile( - @JsonProperty("type") val type: String? = null, - @JsonProperty("name") val name: String? = null, - @JsonProperty("link") val link: String? = null, - @JsonProperty("size") val size: Long? = 0L + @JsonProperty("type") @SerialName("type") val type: String? = null, + @JsonProperty("name") @SerialName("name") val name: String? = null, + @JsonProperty("link") @SerialName("link") val link: String? = null, + @JsonProperty("size") @SerialName("size") val size: Long? = 0L, ) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/HDMomPlayerExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/HDMomPlayerExtractor.kt index 1ccd3e4d510..f7fa2bef1c2 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/HDMomPlayerExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/HDMomPlayerExtractor.kt @@ -8,39 +8,41 @@ import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.extractors.helper.AesHelper import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class HDMomPlayer : ExtractorApi() { - override val name = "HDMomPlayer" - override val mainUrl = "https://hdmomplayer.com" + override val name = "HDMomPlayer" + override val mainUrl = "https://hdmomplayer.com" override val requiresReferer = true - override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) { - val m3uLink:String? - val extRef = referer ?: "" - val iSource = app.get(url, referer=extRef).text - + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { + val m3uLink: String? + val extRef = referer ?: "" + val iSource = app.get(url, referer = extRef).text val bePlayer = Regex("""bePlayer\('([^']+)',\s*'(\{[^\}]+\})'\);""").find(iSource)?.groupValues if (bePlayer != null) { val bePlayerPass = bePlayer.get(1) val bePlayerData = bePlayer.get(2) - val encrypted = AesHelper.cryptoAESHandler(bePlayerData, bePlayerPass.encodeToByteArray(), false)?.replace("\\", "") ?: throw ErrorLoadingException("failed to decrypt") - + val encrypted = AesHelper.cryptoAESHandler(bePlayerData, bePlayerPass.encodeToByteArray(), false)?.replace("\\", "") ?: throw ErrorLoadingException("failed to decrypt") m3uLink = Regex("""video_location\":\"([^\"]+)""").find(encrypted)?.groupValues?.get(1) } else { m3uLink = Regex("""file:\"([^\"]+)""").find(iSource)?.groupValues?.get(1) - val trackStr = Regex("""tracks:\[([^\]]+)""").find(iSource)?.groupValues?.get(1) if (trackStr != null) { - val tracks:List = parseJson>("[${trackStr}]") - + val tracks = parseJson>("[${trackStr}]") for (track in tracks) { if (track.file == null || track.label == null) continue if (track.label.contains("Forced")) continue - subtitleCallback.invoke( newSubtitleFile( lang = track.label, - url = fixUrl(mainUrl + track.file) + url = fixUrl(mainUrl + track.file), ) ) } @@ -49,10 +51,10 @@ open class HDMomPlayer : ExtractorApi() { callback.invoke( newExtractorLink( - source = this.name, - name = this.name, - url = m3uLink ?: throw ErrorLoadingException("m3u link not found"), - type = ExtractorLinkType.M3U8 + source = this.name, + name = this.name, + url = m3uLink ?: throw ErrorLoadingException("m3u link not found"), + type = ExtractorLinkType.M3U8, ) { this.referer = url this.quality = Qualities.Unknown.value @@ -60,11 +62,12 @@ open class HDMomPlayer : ExtractorApi() { ) } + @Serializable data class Track( - @JsonProperty("file") val file: String?, - @JsonProperty("label") val label: String?, - @JsonProperty("kind") val kind: String?, - @JsonProperty("language") val language: String?, - @JsonProperty("default") val default: String? + @JsonProperty("file") @SerialName("file") val file: String?, + @JsonProperty("label") @SerialName("label") val label: String?, + @JsonProperty("kind") @SerialName("kind") val kind: String?, + @JsonProperty("language") @SerialName("language") val language: String?, + @JsonProperty("default") @SerialName("default") val default: String?, ) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/HDPlayerSystemExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/HDPlayerSystemExtractor.kt index 9cff2049fac..58cfb7c49ef 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/HDPlayerSystemExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/HDPlayerSystemExtractor.kt @@ -2,56 +2,58 @@ package com.lagradost.cloudstream3.extractors +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.api.Log import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.* -import com.fasterxml.jackson.annotation.JsonProperty +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class HDPlayerSystem : ExtractorApi() { - override val name = "HDPlayerSystem" - override val mainUrl = "https://hdplayersystem.live" + override val name = "HDPlayerSystem" + override val mainUrl = "https://hdplayersystem.live" override val requiresReferer = true - override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) { - val extRef = referer ?: "" - val vidId = if (url.contains("video/")) { + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { + val extRef = referer ?: "" + val vidId = if (url.contains("video/")) { url.substringAfter("video/") - } else { - url.substringAfter("?data=") - } - val postUrl = "${mainUrl}/player/index.php?data=${vidId}&do=getVideo" - + } else url.substringAfter("?data=") + val postUrl = "$mainUrl/player/index.php?data=$vidId&do=getVideo" val response = app.post( postUrl, data = mapOf( "hash" to vidId, - "r" to extRef + "r" to extRef, ), referer = extRef, headers = mapOf( - "Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8", - "X-Requested-With" to "XMLHttpRequest" + "Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8", + "X-Requested-With" to "XMLHttpRequest", ) ) val videoResponse = response.parsedSafe() ?: throw ErrorLoadingException("failed to parse response") - val m3uLink = videoResponse.securedLink - + val m3uLink = videoResponse.securedLink callback.invoke( newExtractorLink( - source = this.name, - name = this.name, - url = m3uLink - ) { - this.referer = extRef - } + source = this.name, + name = this.name, + url = m3uLink, + ) { this.referer = extRef } ) } + @Serializable data class SystemResponse( - @JsonProperty("hls") val hls: String, - @JsonProperty("videoImage") val videoImage: String? = null, - @JsonProperty("videoSource") val videoSource: String, - @JsonProperty("securedLink") val securedLink: String + @JsonProperty("hls") @SerialName("hls") val hls: String, + @JsonProperty("videoImage") @SerialName("videoImage") val videoImage: String? = null, + @JsonProperty("videoSource") @SerialName("videoSource") val videoSource: String, + @JsonProperty("securedLink") @SerialName("securedLink") val securedLink: String, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Jeniusplay.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Jeniusplay.kt index 896228b5110..9f66867f6c8 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Jeniusplay.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Jeniusplay.kt @@ -9,6 +9,8 @@ import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.M3u8Helper import com.lagradost.cloudstream3.utils.getAndUnpack import com.lagradost.cloudstream3.utils.getPacked +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class Jeniusplay : ExtractorApi() { override val name = "Jeniusplay" @@ -19,16 +21,15 @@ open class Jeniusplay : ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val document = app.get(url, referer = "$mainUrl/").document val hash = url.split("/").last().substringAfter("data=") - val m3uLink = app.post( url = "$mainUrl/player/index.php?data=$hash&do=getVideo", data = mapOf("hash" to hash, "r" to "$referer"), referer = url, - headers = mapOf("X-Requested-With" to "XMLHttpRequest") + headers = mapOf("X-Requested-With" to "XMLHttpRequest"), ).parsed().videoSource M3u8Helper.generateM3u8( @@ -36,7 +37,6 @@ open class Jeniusplay : ExtractorApi() { m3uLink, url, ).forEach(callback) - document.select("script").map { script -> if (getPacked(script.data()) != null) { val unpacked = getAndUnpack(script.data()) @@ -45,9 +45,10 @@ open class Jeniusplay : ExtractorApi() { } } + @Serializable data class ResponseSource( - @JsonProperty("hls") val hls: Boolean, - @JsonProperty("videoSource") val videoSource: String, - @JsonProperty("securedLink") val securedLink: String?, + @JsonProperty("hls") @SerialName("hls") val hls: Boolean, + @JsonProperty("videoSource") @SerialName("videoSource") val videoSource: String, + @JsonProperty("securedLink") @SerialName("securedLink") val securedLink: String?, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Linkbox.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Linkbox.kt index bfa94326aae..91b34ac2c42 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Linkbox.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Linkbox.kt @@ -7,6 +7,8 @@ import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class Linkbox : ExtractorApi() { override val name = "Linkbox" @@ -17,7 +19,7 @@ open class Linkbox : ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val token = Regex("""(?:/f/|/file/|\?id=)(\w+)""").find(url)?.groupValues?.get(1) val id = app.get("$mainUrl/api/file/share_out_list/?sortField=utime&sortAsc=0&pageNo=1&pageSize=50&shareToken=$token").parsedSafe()?.data?.itemId @@ -36,22 +38,25 @@ open class Linkbox : ExtractorApi() { } } + @Serializable data class Resolutions( - @JsonProperty("url") val url: String? = null, - @JsonProperty("resolution") val resolution: String? = null, + @JsonProperty("url") @SerialName("url") val url: String? = null, + @JsonProperty("resolution") @SerialName("resolution") val resolution: String? = null, ) + @Serializable data class ItemInfo( - @JsonProperty("resolutionList") val resolutionList: ArrayList? = arrayListOf(), + @JsonProperty("resolutionList") @SerialName("resolutionList") val resolutionList: ArrayList? = arrayListOf(), ) + @Serializable data class Data( - @JsonProperty("itemInfo") val itemInfo: ItemInfo? = null, - @JsonProperty("itemId") val itemId: String? = null, + @JsonProperty("itemInfo") @SerialName("itemInfo") val itemInfo: ItemInfo? = null, + @JsonProperty("itemId") @SerialName("itemId") val itemId: String? = null, ) + @Serializable data class Responses( - @JsonProperty("data") val data: Data? = null, + @JsonProperty("data") @SerialName("data") val data: Data? = null, ) - -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/MailRuExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/MailRuExtractor.kt index f1fd1288caf..899c6ced514 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/MailRuExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/MailRuExtractor.kt @@ -2,51 +2,57 @@ package com.lagradost.cloudstream3.extractors +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.api.Log import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.* -import com.fasterxml.jackson.annotation.JsonProperty +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class MailRu : ExtractorApi() { - override val name = "MailRu" - override val mainUrl = "https://my.mail.ru" + override val name = "MailRu" + override val mainUrl = "https://my.mail.ru" override val requiresReferer = false - override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) { + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { val extRef = referer ?: "" - - val vidId = url.substringAfter("video/embed/").trim() - val videoReq = app.get("${mainUrl}/+/video/meta/${vidId}", referer=url) - val videoKey = videoReq.cookies["video_key"].toString() - - val videoData = AppUtils.tryParseJson(videoReq.text) ?: throw ErrorLoadingException("Video not found") + val vidId = url.substringAfter("video/embed/").trim() + val videoReq = app.get("$mainUrl/+/video/meta/$vidId", referer = url) + val videoKey = videoReq.cookies["video_key"].toString() + val videoData = AppUtils.tryParseJson(videoReq.text) ?: + throw ErrorLoadingException("Video not found") for (video in videoData.videos) { - val videoUrl = if (video.url.startsWith("//")) "https:${video.url}" else video.url - callback.invoke( newExtractorLink( - source = this.name, - name = this.name, - url = videoUrl, - type = ExtractorLinkType.M3U8 + source = this.name, + name = this.name, + url = videoUrl, + type = ExtractorLinkType.M3U8, ) { this.referer = url - this.headers = mapOf("Cookie" to "video_key=${videoKey}") + this.headers = mapOf("Cookie" to "video_key=$videoKey") this.quality = getQualityFromName(video.key) } ) } } + @Serializable data class MailRuData( - @JsonProperty("provider") val provider: String, - @JsonProperty("videos") val videos: List + @JsonProperty("provider") @SerialName("provider") val provider: String, + @JsonProperty("videos") @SerialName("videos") val videos: List, ) + @Serializable data class MailRuVideoData( - @JsonProperty("url") val url: String, - @JsonProperty("key") val key: String + @JsonProperty("url") @SerialName("url") val url: String, + @JsonProperty("key") @SerialName("key") val key: String, ) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/OdnoklassnikiExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/OdnoklassnikiExtractor.kt index 69c3b775978..fd845e1a0f6 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/OdnoklassnikiExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/OdnoklassnikiExtractor.kt @@ -7,19 +7,26 @@ import com.lagradost.cloudstream3.ErrorLoadingException import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.USER_AGENT import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.utils.AppUtils +import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.INFER_TYPE import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class Odnoklassniki : ExtractorApi() { - override val name = "Odnoklassniki" - override val mainUrl = "https://odnoklassniki.ru" + override val name = "Odnoklassniki" + override val mainUrl = "https://odnoklassniki.ru" override val requiresReferer = false - override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) { + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { val headers = mapOf( "Accept" to "*/*", "Connection" to "keep-alive", @@ -29,34 +36,33 @@ open class Odnoklassniki : ExtractorApi() { "Origin" to mainUrl, "User-Agent" to USER_AGENT, ) - val embedUrl = url.replace("/video/","/videoembed/") - val videoReq = app.get(embedUrl, headers=headers).text.replace("\\"", "\"").replace("\\\\", "\\") + + val embedUrl = url.replace("/video/", "/videoembed/") + val videoReq = app.get(embedUrl, headers = headers).text.replace("\\"", "\"").replace("\\\\", "\\") .replace(Regex("\\\\u([0-9A-Fa-f]{4})")) { matchResult -> matchResult.groupValues[1].toInt(16).toChar().toString() } - val videosStr = Regex(""""videos":(\[[^]]*])""").find(videoReq)?.groupValues?.get(1) ?: throw ErrorLoadingException("Video not found") - val videos = AppUtils.tryParseJson>(videosStr) ?: throw ErrorLoadingException("Video not found") + val videosStr = Regex(""""videos":(\[[^]]*])""").find(videoReq)?.groupValues?.get(1) ?: throw ErrorLoadingException("Video not found") + val videos = tryParseJson>(videosStr) ?: throw ErrorLoadingException("Video not found") for (video in videos) { - - val videoUrl = if (video.url.startsWith("//")) "https:${video.url}" else video.url - - val quality = video.name.uppercase() + val videoUrl = if (video.url.startsWith("//")) "https:${video.url}" else video.url + val quality = video.name.uppercase() .replace("MOBILE", "144p") .replace("LOWEST", "240p") - .replace("LOW", "360p") - .replace("SD", "480p") - .replace("HD", "720p") - .replace("FULL", "1080p") - .replace("QUAD", "1440p") - .replace("ULTRA", "4k") + .replace("LOW", "360p") + .replace("SD", "480p") + .replace("HD", "720p") + .replace("FULL", "1080p") + .replace("QUAD", "1440p") + .replace("ULTRA", "4k") callback.invoke( newExtractorLink( - source = this.name, - name = this.name, - url = videoUrl, - type = INFER_TYPE + source = this.name, + name = this.name, + url = videoUrl, + type = INFER_TYPE, ) { this.referer = "$mainUrl/" this.quality = getQualityFromName(quality) @@ -66,8 +72,9 @@ open class Odnoklassniki : ExtractorApi() { } } + @Serializable data class OkRuVideo( - @JsonProperty("name") val name: String, - @JsonProperty("url") val url: String, + @JsonProperty("name") @SerialName("name") val name: String, + @JsonProperty("url") @SerialName("url") val url: String, ) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/PeaceMakerstExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/PeaceMakerstExtractor.kt index f96387d75c1..05bbc233e28 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/PeaceMakerstExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/PeaceMakerstExtractor.kt @@ -2,57 +2,61 @@ package com.lagradost.cloudstream3.extractors +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.api.Log import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.* -import com.fasterxml.jackson.annotation.JsonProperty +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class PeaceMakerst : ExtractorApi() { - override val name = "PeaceMakerst" - override val mainUrl = "https://peacemakerst.com" + override val name = "PeaceMakerst" + override val mainUrl = "https://peacemakerst.com" override val requiresReferer = true - override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) { - val m3uLink:String? - val extRef = referer ?: "" - val postUrl = "${url}?do=getVideo" - + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { + val m3uLink: String? + val extRef = referer ?: "" + val postUrl = "$url?do=getVideo" val response = app.post( postUrl, data = mapOf( "hash" to url.substringAfter("video/"), - "r" to extRef, - "s" to "" + "r" to extRef, + "s" to "", ), referer = extRef, headers = mapOf( - "Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8", - "X-Requested-With" to "XMLHttpRequest" - ) + "Content-Type" to "application/x-www-form-urlencoded; charset=UTF-8", + "X-Requested-With" to "XMLHttpRequest", + ), ) + if (response.text.contains("teve2.com.tr\\/embed\\/")) { - val teve2Id = response.text.substringAfter("teve2.com.tr\\/embed\\/").substringBefore("\"") + val teve2Id = response.text.substringAfter("teve2.com.tr\\/embed\\/").substringBefore("\"") val teve2Response = app.get( - "https://www.teve2.com.tr/action/media/${teve2Id}", - referer = "https://www.teve2.com.tr/embed/${teve2Id}" + "https://www.teve2.com.tr/action/media/$teve2Id", + referer = "https://www.teve2.com.tr/embed/$teve2Id", ).parsedSafe() ?: throw ErrorLoadingException("teve2 response is null") - - m3uLink = teve2Response.media.link.serviceUrl + "//" + teve2Response.media.link.securePath + m3uLink = teve2Response.media.link.serviceUrl + "//" + teve2Response.media.link.securePath } else { val videoResponse = response.parsedSafe() ?: throw ErrorLoadingException("peace response is null") - val videoSources = videoResponse.videoSources + val videoSources = videoResponse.videoSources if (videoSources.isNotEmpty()) { m3uLink = videoSources.lastOrNull()?.file - } else { - m3uLink = null - } + } else m3uLink = null } callback.invoke( newExtractorLink( - source = this.name, - name = this.name, - url = m3uLink ?: throw ErrorLoadingException("m3u link not found"), + source = this.name, + name = this.name, + url = m3uLink ?: throw ErrorLoadingException("m3u link not found"), ) { this.referer = extRef this.quality = Qualities.Unknown.value @@ -60,29 +64,34 @@ open class PeaceMakerst : ExtractorApi() { ) } + @Serializable data class PeaceResponse( - @JsonProperty("videoImage") val videoImage: String?, - @JsonProperty("videoSources") val videoSources: List, - @JsonProperty("sIndex") val sIndex: String, - @JsonProperty("sourceList") val sourceList: Map + @JsonProperty("videoImage") @SerialName("videoImage") val videoImage: String?, + @JsonProperty("videoSources") @SerialName("videoSources") val videoSources: List, + @JsonProperty("sIndex") @SerialName("sIndex") val sourceIndex: String, + @JsonProperty("sourceList") @SerialName("sourceList") val sourceList: Map, ) + @Serializable data class VideoSource( - @JsonProperty("file") val file: String, - @JsonProperty("label") val label: String, - @JsonProperty("type") val type: String + @JsonProperty("file") @SerialName("file") val file: String, + @JsonProperty("label") @SerialName("label") val label: String, + @JsonProperty("type") @SerialName("type") val type: String, ) + @Serializable data class Teve2ApiResponse( - @JsonProperty("Media") val media: Teve2Media + @JsonProperty("Media") @SerialName("Media") val media: Teve2Media, ) + @Serializable data class Teve2Media( - @JsonProperty("Link") val link: Teve2Link + @JsonProperty("Link") @SerialName("Link") val link: Teve2Link, ) + @Serializable data class Teve2Link( - @JsonProperty("ServiceUrl") val serviceUrl: String, - @JsonProperty("SecurePath") val securePath: String + @JsonProperty("ServiceUrl") @SerialName("ServiceUrl") val serviceUrl: String, + @JsonProperty("SecurePath") @SerialName("SecurePath") val securePath: String, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/PlayLtXyz.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/PlayLtXyz.kt index c59022abbb7..dc5195b0819 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/PlayLtXyz.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/PlayLtXyz.kt @@ -1,33 +1,28 @@ package com.lagradost.cloudstream3.extractors -import com.lagradost.api.Log import com.fasterxml.jackson.annotation.JsonProperty +import com.lagradost.api.Log import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable -open class PlayLtXyz: ExtractorApi() { - override val name: String = "PlayLt" - override val mainUrl: String = "https://play.playlt.xyz" +open class PlayLtXyz : ExtractorApi() { + override val name = "PlayLt" + override val mainUrl = "https://play.playlt.xyz" override val requiresReferer = true - private data class ResponseData( - @JsonProperty("data") val data: String? = null - ) - override suspend fun getUrl(url: String, referer: String?): List { val extractedLinksList = mutableListOf() - //Log.i(this.name, "Result => (url) $url") var idUser = "" var idFile = "" var bodyText = "" val doc = app.get(url, referer = referer).document - //Log.i(this.name, "Result => (url, script) $url / ${doc.select("script")}") bodyText = doc.select("script").firstOrNull { val text = it.toString() text.contains("var idUser") }?.toString() ?: "" - //Log.i(this.name, "Result => (bodyText) $bodyText") if (bodyText.isNotBlank()) { idUser = "(?<=var idUser = \")(.*)(?=\";)".toRegex().find(bodyText) ?.groupValues?.get(0) ?: "" @@ -35,29 +30,27 @@ open class PlayLtXyz: ExtractorApi() { idFile = "(?<=var idfile = \")(.*)(?=\";)".toRegex().find(bodyText) ?.groupValues?.get(0) ?: "" } - //Log.i(this.name, "Result => (idUser, idFile) $idUser / $idFile") + if (idUser.isNotBlank() && idFile.isNotBlank()) { - //val sess = HttpSession() val ajaxHead = mapOf( Pair("Origin", mainUrl), Pair("Referer", mainUrl), Pair("Sec-Fetch-Site", "same-site"), Pair("Sec-Fetch-Mode", "cors"), - Pair("Sec-Fetch-Dest", "empty") + Pair("Sec-Fetch-Dest", "empty"), ) + val ajaxData = mapOf( Pair("referrer", referer ?: mainUrl), - Pair("typeend", "html") + Pair("typeend", "html"), ) - //idUser = 608f7c85cf0743547f1f1b4e - val posturl = "https://api-plhq.playlt.xyz/apiv5/$idUser/$idFile" - val data = app.post(posturl, headers = ajaxHead, data = ajaxData) - //Log.i(this.name, "Result => (posturl) $posturl") + val postUrl = "https://api-plhq.playlt.xyz/apiv5/$idUser/$idFile" + val data = app.post(postUrl, headers = ajaxHead, data = ajaxData) if (data.isSuccessful) { - val itemstr = data.text - Log.i(this.name, "Result => (data) $itemstr") - tryParseJson(itemstr)?.let { item -> + val itemStr = data.text + Log.i(this.name, "Result => (data) $itemStr") + tryParseJson(itemStr)?.let { item -> val linkUrl = item.data ?: "" if (linkUrl.isNotBlank()) { extractedLinksList.add( @@ -65,7 +58,7 @@ open class PlayLtXyz: ExtractorApi() { source = name, name = name, url = linkUrl, - type = ExtractorLinkType.M3U8 + type = ExtractorLinkType.M3U8, ) { this.referer = url this.quality = Qualities.Unknown.value @@ -75,6 +68,12 @@ open class PlayLtXyz: ExtractorApi() { } } } + return extractedLinksList } -} \ No newline at end of file + + @Serializable + private data class ResponseData( + @JsonProperty("data") @SerialName("data") val data: String? = null, + ) +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Rabbitstream.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Rabbitstream.kt index fe96244300d..418e9994776 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Rabbitstream.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Rabbitstream.kt @@ -7,8 +7,8 @@ import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.base64DecodeArray import com.lagradost.cloudstream3.base64Encode import com.lagradost.cloudstream3.newSubtitleFile -import com.lagradost.cloudstream3.utils.AppUtils import com.lagradost.cloudstream3.utils.AppUtils.parseJson +import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.M3u8Helper @@ -16,6 +16,8 @@ import dev.whyoleg.cryptography.CryptographyProvider import dev.whyoleg.cryptography.DelicateCryptographyApi import dev.whyoleg.cryptography.algorithms.AES import dev.whyoleg.cryptography.algorithms.MD5 +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable class Megacloud : Rabbitstream() { override val name = "Megacloud" @@ -36,6 +38,7 @@ class Megacloud : Rabbitstream() { extractedKey += sourcesArray[i].toString() sourcesArray[i] = ' ' } + currentIndex += index[1] } @@ -55,7 +58,7 @@ class Megacloud : Rabbitstream() { val matchKey2 = matchingKey(match.groupValues[2]) try { listOf(matchKey1.toInt(16), matchKey2.toInt(16)) - } catch (e: NumberFormatException) { + } catch (_: NumberFormatException) { emptyList() } }.filter { it.isNotEmpty() } @@ -86,14 +89,13 @@ open class Rabbitstream : ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val id = url.substringAfterLast("/").substringBefore("?") - val response = app.get( "$mainUrl/$embed/getSources?id=$id", referer = mainUrl, - headers = mapOf("X-Requested-With" to "XMLHttpRequest") + headers = mapOf("X-Requested-With" to "XMLHttpRequest"), ) val encryptedMap = response.parsedSafe() @@ -105,7 +107,7 @@ open class Rabbitstream : ExtractorApi() { val decrypted = decryptMapped>(encData, key) SourcesResponses( sources = decrypted, - tracks = encryptedMap.tracks + tracks = encryptedMap.tracks, ) } @@ -121,7 +123,7 @@ open class Rabbitstream : ExtractorApi() { subtitleCallback.invoke( newSubtitleFile( track?.label ?: return@map, - track.file ?: return@map + track.file ?: return@map, ) ) } @@ -135,14 +137,14 @@ open class Rabbitstream : ExtractorApi() { private inline fun decryptMapped(input: String, key: String): T? { val decrypt = decrypt(input, key) - return AppUtils.tryParseJson(decrypt) + return tryParseJson(decrypt) } private fun decrypt(input: String, key: String): String { return decryptSourceUrl( generateKey( salt = base64DecodeArray(input).copyOfRange(8, 16), - secret = key.encodeToByteArray() + secret = key.encodeToByteArray(), ), input ) } @@ -154,6 +156,7 @@ open class Rabbitstream : ExtractorApi() { key = md5(key + secret + salt) currentKey += key } + return currentKey } @@ -172,26 +175,30 @@ open class Rabbitstream : ExtractorApi() { return decryptedData.decodeToString() } + @Serializable data class Tracks( - @JsonProperty("file") val file: String? = null, - @JsonProperty("label") val label: String? = null, - @JsonProperty("kind") val kind: String? = null, + @JsonProperty("file") @SerialName("file") val file: String? = null, + @JsonProperty("label") @SerialName("label") val label: String? = null, + @JsonProperty("kind") @SerialName("kind") val kind: String? = null, ) + @Serializable data class Sources( - @JsonProperty("file") val file: String? = null, - @JsonProperty("type") val type: String? = null, - @JsonProperty("label") val label: String? = null, + @JsonProperty("file") @SerialName("file") val file: String? = null, + @JsonProperty("type") @SerialName("type") val type: String? = null, + @JsonProperty("label") @SerialName("label") val label: String? = null, ) + @Serializable data class SourcesResponses( - @JsonProperty("sources") val sources: List? = emptyList(), - @JsonProperty("tracks") val tracks: List? = emptyList(), + @JsonProperty("sources") @SerialName("sources") val sources: List? = emptyList(), + @JsonProperty("tracks") @SerialName("tracks") val tracks: List? = emptyList(), ) + @Serializable data class SourcesEncrypted( - @JsonProperty("sources") val sources: String? = null, - @JsonProperty("encrypted") val encrypted: Boolean? = null, - @JsonProperty("tracks") val tracks: List? = emptyList(), + @JsonProperty("sources") @SerialName("sources") val sources: String? = null, + @JsonProperty("encrypted") @SerialName("encrypted") val encrypted: Boolean? = null, + @JsonProperty("tracks") @SerialName("tracks") val tracks: List? = emptyList(), ) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/SobreatsesuypExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/SobreatsesuypExtractor.kt index be95940e0c1..0c5d7c97486 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/SobreatsesuypExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/SobreatsesuypExtractor.kt @@ -2,51 +2,53 @@ package com.lagradost.cloudstream3.extractors +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.* -import com.fasterxml.jackson.annotation.JsonProperty +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement open class Sobreatsesuyp : ExtractorApi() { - override val name = "Sobreatsesuyp" - override val mainUrl = "https://sobreatsesuyp.com" + override val name = "Sobreatsesuyp" + override val mainUrl = "https://sobreatsesuyp.com" override val requiresReferer = true - override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) { + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { val extRef = referer ?: "" - val videoReq = app.get(url, referer = extRef).text - - val file = Regex("""file\":\"([^\"]+)""").find(videoReq)?.groupValues?.get(1) ?: throw ErrorLoadingException("File not found") - val postLink = "${mainUrl}/" + file.replace("\\", "") - val rawList = app.post(postLink, referer = extRef).parsedSafe>() ?: throw ErrorLoadingException("Post link not found") - + val file = Regex("""file\":\"([^\"]+)""").find(videoReq)?.groupValues?.get(1) ?: throw ErrorLoadingException("File not found") + val postLink = "$mainUrl/" + file.replace("\\", "") + val rawList = app.post(postLink, referer = extRef).parsedSafe>() ?: throw ErrorLoadingException("Post link not found") val postJson: List = rawList.drop(1).map { item -> val mapItem = item as Map<*, *> SobreatsesuypVideoData( title = mapItem["title"] as? String, - file = mapItem["file"] as? String + file = mapItem["file"] as? String, ) } for (item in postJson) { if (item.file == null || item.title == null) continue - - val videoData = app.post("${mainUrl}/playlist/${item.file.substring(1)}.txt", referer = extRef).text - + val videoData = app.post("$mainUrl/playlist/${item.file.substring(1)}.txt", referer = extRef).text callback.invoke( newExtractorLink( - source = this.name, - name = "${this.name} - ${item.title}", - url = videoData, - ) { - this.referer = extRef - } + source = this.name, + name = "${this.name} - ${item.title}", + url = videoData, + ) { this.referer = extRef } ) } } + @Serializable data class SobreatsesuypVideoData( - @JsonProperty("title") val title: String? = null, - @JsonProperty("file") val file: String? = null + @JsonProperty("title") @SerialName("title") val title: String? = null, + @JsonProperty("file") @SerialName("file") val file: String? = null, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/StreamEmbed.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/StreamEmbed.kt index c89f4d226cb..8c5eb5d6cb1 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/StreamEmbed.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/StreamEmbed.kt @@ -7,22 +7,23 @@ import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.M3u8Helper +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class StreamEmbed : ExtractorApi() { - override var name = "StreamEmbed" - override var mainUrl = "https://watch.gxplayer.xyz" + override val name = "StreamEmbed" + override val mainUrl = "https://watch.gxplayer.xyz" override val requiresReferer = true override suspend fun getUrl( url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val jsonString = app.get(url, referer = mainUrl).text .substringAfter("var video = ").substringBefore(";") val video = parseJson
(jsonString) - M3u8Helper.generateM3u8( this.name, "$mainUrl/m3u8/${video.uid}/${video.md5}/master.txt?s=1&id=${video.id}&cache=${video.status}", @@ -30,14 +31,15 @@ open class StreamEmbed : ExtractorApi() { ).forEach(callback) } + @Serializable private data class Details( - @JsonProperty("id") val id: String, - @JsonProperty("uid") val uid: String, - @JsonProperty("slug") val slug: String, - @JsonProperty("title") val title: String, - @JsonProperty("quality") val quality: String, - @JsonProperty("type") val type: String, - @JsonProperty("status") val status: String, - @JsonProperty("md5") val md5: String, + @JsonProperty("id") @SerialName("id") val id: String, + @JsonProperty("uid") @SerialName("uid") val uid: String, + @JsonProperty("slug") @SerialName("slug") val slug: String, + @JsonProperty("title") @SerialName("title") val title: String, + @JsonProperty("quality") @SerialName("quality") val quality: String, + @JsonProperty("type") @SerialName("type") val type: String, + @JsonProperty("status") @SerialName("status") val status: String, + @JsonProperty("md5") @SerialName("md5") val md5: String, ) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/StreamSB.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/StreamSB.kt index 67cf1f8da9c..a7584d708b1 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/StreamSB.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/StreamSB.kt @@ -7,6 +7,8 @@ import com.lagradost.cloudstream3.newSubtitleFile import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.M3u8Helper +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable import kotlin.random.Random class Sblona : StreamSB() { @@ -141,17 +143,15 @@ open class StreamSB : ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { - val regexID = + val regexId = Regex("(embed-[a-zA-Z\\d]{0,8}[a-zA-Z\\d_-]+|/e/[a-zA-Z\\d]{0,8}[a-zA-Z\\d_-]+)") - val id = regexID.findAll(url).map { + val id = regexId.findAll(url).map { it.value.replace(Regex("(embed-|/e/)"), "") }.first() val master = "$mainUrl/375664356a494546326c4b797c7c6e756577776778623171737/${encodeId(id)}" - val headers = mapOf( - "watchsb" to "sbstream", - ) + val headers = mapOf("watchsb" to "sbstream") val mapped = app.get( master.lowercase(), headers = headers, @@ -161,9 +161,8 @@ open class StreamSB : ExtractorApi() { name, mapped?.streamData?.file ?: return, url, - headers = headers + headers = headers, ).forEach(callback) - mapped.streamData.subs?.map {sub -> subtitleCallback.invoke( newSubtitleFile( @@ -189,25 +188,27 @@ open class StreamSB : ExtractorApi() { } } - data class Subs ( - @JsonProperty("file") val file: String? = null, - @JsonProperty("label") val label: String? = null, + @Serializable + data class Subs( + @JsonProperty("file") @SerialName("file") val file: String? = null, + @JsonProperty("label") @SerialName("label") val label: String? = null, ) - data class StreamData ( - @JsonProperty("file") val file: String, - @JsonProperty("cdn_img") val cdnImg: String, - @JsonProperty("hash") val hash: String, - @JsonProperty("subs") val subs: ArrayList? = arrayListOf(), - @JsonProperty("length") val length: String, - @JsonProperty("id") val id: String, - @JsonProperty("title") val title: String, - @JsonProperty("backup") val backup: String, + @Serializable + data class StreamData( + @JsonProperty("file") @SerialName("file") val file: String, + @JsonProperty("cdn_img") @SerialName("cdn_img") val cdnImg: String, + @JsonProperty("hash") @SerialName("hash") val hash: String, + @JsonProperty("subs") @SerialName("subs") val subs: ArrayList? = arrayListOf(), + @JsonProperty("length") @SerialName("length") val length: String, + @JsonProperty("id") @SerialName("id") val id: String, + @JsonProperty("title") @SerialName("title") val title: String, + @JsonProperty("backup") @SerialName("backup") val backup: String, ) - data class Main ( - @JsonProperty("stream_data") val streamData: StreamData, - @JsonProperty("status_code") val statusCode: Int, + @Serializable + data class Main( + @JsonProperty("stream_data") @SerialName("stream_data") val streamData: StreamData, + @JsonProperty("status_code") @SerialName("status_code") val statusCode: Int, ) - } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Streamlare.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Streamlare.kt index da2dd62bef5..d17e59c821f 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Streamlare.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Streamlare.kt @@ -9,10 +9,11 @@ import com.lagradost.cloudstream3.utils.INFER_TYPE import com.lagradost.cloudstream3.utils.newExtractorLink import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.nicehttp.RequestBodyTypes +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody.Companion.toRequestBody - class Streamlare : Slmaxed() { override val mainUrl = "https://streamlare.com/" } @@ -24,27 +25,11 @@ open class Slmaxed : ExtractorApi() { // https://slmaxed.com/e/oLvgezw3LjPzbp8E -> oLvgezw3LjPzbp8E val embedRegex = Regex("""/e/([^/]*)""") - - - data class JsonResponse( - @JsonProperty val status: String? = null, - @JsonProperty val message: String? = null, - @JsonProperty val type: String? = null, - @JsonProperty val token: String? = null, - @JsonProperty val result: Map? = null - ) - - data class Result( - @JsonProperty val label: String? = null, - @JsonProperty val file: String? = null, - @JsonProperty val type: String? = null - ) - override suspend fun getUrl(url: String, referer: String?): List? { val id = embedRegex.find(url)!!.groupValues[1] val json = app.post( "${mainUrl}api/video/stream/get", - requestBody = """{"id":"$id"}""".toRequestBody(RequestBodyTypes.JSON.toMediaTypeOrNull()) + requestBody = """{"id":"$id"}""".toRequestBody(RequestBodyTypes.JSON.toMediaTypeOrNull()), ).parsed() return json.result?.mapNotNull { it.value.let { result -> @@ -52,18 +37,29 @@ open class Slmaxed : ExtractorApi() { this.name, this.name, result.file ?: return@mapNotNull null, - type = if (result.type?.contains( - "hls", - ignoreCase = true - ) == true - ) ExtractorLinkType.M3U8 else INFER_TYPE + type = if (result.type?.contains("hls", ignoreCase = true) == true) ExtractorLinkType.M3U8 else INFER_TYPE, ) { this.referer = url - this.quality = - result.label?.replace("p", "", ignoreCase = true)?.trim()?.toIntOrNull() - ?: Qualities.Unknown.value + this.quality = result.label?.replace("p", "", ignoreCase = true)?.trim()?.toIntOrNull() + ?: Qualities.Unknown.value } } } } -} \ No newline at end of file + + @Serializable + data class JsonResponse( + @JsonProperty("status") @SerialName("status") val status: String? = null, + @JsonProperty("message") @SerialName("message") val message: String? = null, + @JsonProperty("type") @SerialName("type") val type: String? = null, + @JsonProperty("token") @SerialName("token") val token: String? = null, + @JsonProperty("result") @SerialName("result") val result: Map? = null, + ) + + @Serializable + data class Result( + @JsonProperty("label") @SerialName("label") val label: String? = null, + @JsonProperty("file") @SerialName("file") val file: String? = null, + @JsonProperty("type") @SerialName("type") val type: String? = null, + ) +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Streamplay.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Streamplay.kt index 9886300aa18..1bcf9966b91 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Streamplay.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Streamplay.kt @@ -8,6 +8,8 @@ import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import io.ktor.http.Url +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class Streamplay : ExtractorApi() { override val name = "Streamplay" @@ -18,37 +20,36 @@ open class Streamplay : ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val request = app.get(url, referer = referer) val redirectUrl = request.url val mainServer = Url(redirectUrl).let { "${it.protocol.name}://${it.host}" } val key = redirectUrl.substringAfter("embed-").substringBefore(".html") - val token = - request.document.select("script").find { it.data().contains("sitekey:") }?.data() - ?.substringAfterLast("sitekey: '")?.substringBefore("',")?.let { captchaKey -> - getCaptchaToken( - redirectUrl, - captchaKey, - referer = "$mainServer/" - ) - } ?: throw ErrorLoadingException("can't bypass captcha") + val token = request.document.select("script").find { it.data().contains("sitekey:") }?.data() + ?.substringAfterLast("sitekey: '")?.substringBefore("',")?.let { captchaKey -> + getCaptchaToken( + redirectUrl, + captchaKey, + referer = "$mainServer/", + ) + } ?: throw ErrorLoadingException("can't bypass captcha") + app.post( "$mainServer/player-$key-488x286.html", data = mapOf( "op" to "embed", - "token" to token + "token" to token, ), referer = redirectUrl, headers = mapOf( "Accept" to "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", - "Content-Type" to "application/x-www-form-urlencoded" - ) + "Content-Type" to "application/x-www-form-urlencoded", + ), ).document.select("script").find { script -> script.data().contains("eval(function(p,a,c,k,e,d)") }?.let { val data = getAndUnpack(it.data()).substringAfter("sources=[").substringBefore(",desc") - .replace("file", "\"file\"") - .replace("label", "\"label\"") + .replace("file", "\"file\"").replace("label", "\"label\"") tryParseJson>("[$data}]")?.map { res -> callback.invoke( newExtractorLink( @@ -57,24 +58,21 @@ open class Streamplay : ExtractorApi() { res.file ?: return@map null, ) { this.referer = "$mainServer/" + this.headers = mapOf("Range" to "bytes=0-") this.quality = when (res.label) { "HD" -> Qualities.P720.value "SD" -> Qualities.P480.value else -> Qualities.Unknown.value } - this.headers = mapOf( - "Range" to "bytes=0-" - ) } ) } } - } + @Serializable data class Source( - @JsonProperty("file") val file: String? = null, - @JsonProperty("label") val label: String? = null, + @JsonProperty("file") @SerialName("file") val file: String? = null, + @JsonProperty("label") @SerialName("label") val label: String? = null, ) - } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/TRsTXExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/TRsTXExtractor.kt index 1348f74d501..6014105d83f 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/TRsTXExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/TRsTXExtractor.kt @@ -2,68 +2,68 @@ package com.lagradost.cloudstream3.extractors +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.api.Log import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.* -import com.fasterxml.jackson.annotation.JsonProperty +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement open class TRsTX : ExtractorApi() { - override val name = "TRsTX" - override val mainUrl = "https://trstx.org" + override val name = "TRsTX" + override val mainUrl = "https://trstx.org" override val requiresReferer = true - override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) { + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { val extRef = referer ?: "" - - val videoReq = app.get(url, referer=extRef).text - - val file = Regex("""file\":\"([^\"]+)""").find(videoReq)?.groupValues?.get(1) ?: throw ErrorLoadingException("File not found") - val postLink = "${mainUrl}/" + file.replace("\\", "") - val rawList = app.post(postLink, referer=extRef).parsedSafe>() ?: throw ErrorLoadingException("Post link not found") - + val videoReq = app.get(url, referer = extRef).text + val file = Regex("""file\":\"([^\"]+)""").find(videoReq)?.groupValues?.get(1) ?: throw ErrorLoadingException("File not found") + val postLink = "$mainUrl/" + file.replace("\\", "") + val rawList = app.post(postLink, referer = extRef).parsedSafe>() ?: throw ErrorLoadingException("Post link not found") val postJson: List = rawList.drop(1).map { item -> val mapItem = item as Map<*, *> TrstxVideoData( title = mapItem["title"] as? String, - file = mapItem["file"] as? String + file = mapItem["file"] as? String, ) } val vidLinks = mutableSetOf() - val vidMap = mutableListOf>() + val vidMap = mutableListOf>() for (item in postJson) { if (item.file == null || item.title == null) continue - - val fileUrl = "${mainUrl}/playlist/" + item.file.substring(1) + ".txt" - val videoData = app.post(fileUrl, referer=extRef).text - - if (videoData in vidLinks) { continue } + val fileUrl = "$mainUrl/playlist/" + item.file.substring(1) + ".txt" + val videoData = app.post(fileUrl, referer = extRef).text + if (videoData in vidLinks) continue vidLinks.add(videoData) - vidMap.add(mapOf( - "title" to item.title, - "videoData" to videoData + "title" to item.title, + "videoData" to videoData, )) } for (mapEntry in vidMap) { - val title = mapEntry["title"] ?: continue + val title = mapEntry["title"] ?: continue val m3uLink = mapEntry["videoData"] ?: continue - callback.invoke( newExtractorLink( - source = this.name, - name = "${this.name} - ${title}", - url = m3uLink, - ) { - this.referer = extRef - } + source = this.name, + name = "${this.name} - $title", + url = m3uLink, + ) { this.referer = extRef } ) } } + @Serializable data class TrstxVideoData( - @JsonProperty("title") val title: String? = null, - @JsonProperty("file") val file: String? = null + @JsonProperty("title") @SerialName("title") val title: String? = null, + @JsonProperty("file") @SerialName("file") val file: String? = null, ) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Tantifilm.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Tantifilm.kt index 4e330d1a77a..e8022b3230f 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Tantifilm.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Tantifilm.kt @@ -6,38 +6,42 @@ import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class Tantifilm : ExtractorApi() { - override var name = "Tantifilm" - override var mainUrl = "https://cercafilm.net" + override val name = "Tantifilm" + override val mainUrl = "https://cercafilm.net" override val requiresReferer = false - data class TantifilmJsonData ( - @JsonProperty("success") val success : Boolean, - @JsonProperty("data") val data : List, - @JsonProperty("captions")val captions : List, - @JsonProperty("is_vr") val is_vr : Boolean - ) - - data class TantifilmData ( - @JsonProperty("file") val file : String, - @JsonProperty("label") val label : String, - @JsonProperty("type") val type : String - ) - override suspend fun getUrl(url: String, referer: String?): List? { val link = "$mainUrl/api/source/${url.substringAfterLast("/")}" val response = app.post(link).text.replace("""\""","") - val jsonvideodata = parseJson(response) - return jsonvideodata.data.map { + val jsonVideoData = parseJson(response) + return jsonVideoData.data.map { newExtractorLink( this.name, this.name, - it.file+".${it.type}" + it.file + ".${it.type}", ) { this.referer = mainUrl this.quality = it.label.filter{ it.isDigit() }.toInt() } } } -} \ No newline at end of file + + @Serializable + data class TantifilmJsonData( + @JsonProperty("success") @SerialName("success") val success: Boolean, + @JsonProperty("data") @SerialName("data") val data: List, + @JsonProperty("captions") @SerialName("captions") val captions: List, + @JsonProperty("is_vr") @SerialName("is_vr") val isVr: Boolean, + ) + + @Serializable + data class TantifilmData( + @JsonProperty("file") @SerialName("file") val file: String, + @JsonProperty("label") @SerialName("label") val label: String, + @JsonProperty("type") @SerialName("type") val type: String, + ) +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/TauVideoExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/TauVideoExtractor.kt index 1c9cce2a834..9133ca99c3d 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/TauVideoExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/TauVideoExtractor.kt @@ -2,29 +2,35 @@ package com.lagradost.cloudstream3.extractors +import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.api.Log import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.* -import com.fasterxml.jackson.annotation.JsonProperty +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class TauVideo : ExtractorApi() { - override val name = "TauVideo" - override val mainUrl = "https://tau-video.xyz" + override val name = "TauVideo" + override val mainUrl = "https://tau-video.xyz" override val requiresReferer = true - override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) { - val extRef = referer ?: "" + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { + val extRef = referer ?: "" val videoKey = url.split("/").last() - val videoUrl = "${mainUrl}/api/video/${videoKey}" - + val videoUrl = "$mainUrl/api/video/$videoKey" val api = app.get(videoUrl).parsedSafe() ?: throw ErrorLoadingException("TauVideo") for (video in api.urls) { callback.invoke( newExtractorLink( - source = this.name, - name = this.name, - url = video.url, + source = this.name, + name = this.name, + url = video.url, ) { this.referer = extRef this.quality = getQualityFromName(video.label) @@ -33,12 +39,14 @@ open class TauVideo : ExtractorApi() { } } + @Serializable data class TauVideoUrls( - @JsonProperty("urls") val urls: List + @JsonProperty("urls") @SerialName("urls") val urls: List, ) + @Serializable data class TauVideoData( - @JsonProperty("url") val url: String, - @JsonProperty("label") val label: String, + @JsonProperty("url") @SerialName("url") val url: String, + @JsonProperty("label") @SerialName("label") val label: String, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Uservideo.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Uservideo.kt index 307825998b1..97922127d60 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Uservideo.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Uservideo.kt @@ -3,51 +3,51 @@ package com.lagradost.cloudstream3.extractors import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.utils.AppUtils +import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class Uservideo : ExtractorApi() { - override val name: String = "Uservideo" - override val mainUrl: String = "https://uservideo.xyz" + override val name = "Uservideo" + override val mainUrl = "https://uservideo.xyz" override val requiresReferer = false override suspend fun getUrl( url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val script = app.get(url).document.selectFirst("script:containsData(hosts =)")?.data() val host = script?.substringAfter("hosts = [\"")?.substringBefore("\"];") val servers = script?.substringAfter("servers = \"")?.substringBefore("\";") - + val quality = Regex("(\\d{3,4})[Pp]").find(url)?.groupValues?.getOrNull(1)?.toIntOrNull() val sources = app.get("$host/s/$servers").text.substringAfter("\"sources\":[").substringBefore("],").let { - AppUtils.tryParseJson>("[$it]") + tryParseJson>("[$it]") } - val quality = Regex("(\\d{3,4})[Pp]").find(url)?.groupValues?.getOrNull(1)?.toIntOrNull() sources?.map { source -> callback.invoke( newExtractorLink( name, name, - source.src ?: return@map null + source.src ?: return@map null, ) { this.referer = url this.quality = quality ?: Qualities.Unknown.value } ) } - } + @Serializable data class Sources( - @JsonProperty("src") val src: String? = null, - @JsonProperty("type") val type: String? = null, - @JsonProperty("label") val label: String? = null, + @JsonProperty("src") @SerialName("src") val src: String? = null, + @JsonProperty("type") @SerialName("type") val type: String? = null, + @JsonProperty("label") @SerialName("label") val label: String? = null, ) - -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vicloud.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vicloud.kt index 6b82ee454e8..b3082cea6cc 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vicloud.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vicloud.kt @@ -8,25 +8,25 @@ import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class Vicloud : ExtractorApi() { - override val name: String = "Vicloud" - override val mainUrl: String = "https://vicloud.sbs" + override val name = "Vicloud" + override val mainUrl = "https://vicloud.sbs" override val requiresReferer = false override suspend fun getUrl( url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val id = Regex("\"apiQuery\":\"(.*?)\"").find(app.get(url).text)?.groupValues?.getOrNull(1) app.get( "$mainUrl/api/?$id=&_=$unixTimeMS", - headers = mapOf( - "X-Requested-With" to "XMLHttpRequest" - ), - referer = url + headers = mapOf("X-Requested-With" to "XMLHttpRequest"), + referer = url, ).parsedSafe()?.sources?.map { source -> callback.invoke( newExtractorLink( @@ -39,16 +39,16 @@ open class Vicloud : ExtractorApi() { } ) } - } + @Serializable private data class Sources( - @JsonProperty("file") val file: String? = null, - @JsonProperty("label") val label: String? = null, + @JsonProperty("file") @SerialName("file") val file: String? = null, + @JsonProperty("label") @SerialName("label") val label: String? = null, ) + @Serializable private data class Responses( - @JsonProperty("sources") val sources: List? = arrayListOf(), + @JsonProperty("sources") @SerialName("sources") val sources: List? = arrayListOf(), ) - -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vidara.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vidara.kt index d74a1ccd61b..04c60675ebd 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vidara.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vidara.kt @@ -44,27 +44,29 @@ class VidaraSo : Vidara() { } open class Vidara : ExtractorApi() { - override val name: String = "Vidara" + override val name = "Vidara" override val mainUrl = "https://vidara.to" - override val requiresReferer: Boolean = false + override val requiresReferer = false override suspend fun getUrl( url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val fileCode = url.substringAfterLast("/") - val fileInfo = - app.post("$mainUrl/api/stream", json = mapOf("filecode" to fileCode, "device" to "web")) - .parsed() - + val fileInfo = app.post( + "$mainUrl/api/stream", json = mapOf( + "filecode" to fileCode, + "device" to "web" + ) + ).parsed() callback.invoke( newExtractorLink( source = name, name = name, url = fileInfo.streamingUrl, - type = ExtractorLinkType.M3U8 + type = ExtractorLinkType.M3U8, ) ) @@ -77,19 +79,15 @@ open class Vidara : ExtractorApi() { @Serializable private data class StreamUpFileInfo( - val title: String, - val thumbnail: String, - @SerialName("streaming_url") - @JsonProperty("streaming_url") - val streamingUrl: String, - val subtitles: List? + @JsonProperty("title") @SerialName("title") val title: String, + @JsonProperty("thumbnail") @SerialName("thumbnail") val thumbnail: String, + @JsonProperty("streaming_url") @SerialName("streaming_url") val streamingUrl: String, + @JsonProperty("subtitles") @SerialName("subtitles") val subtitles: List?, ) @Serializable private data class StreamUpSubtitle( - @SerialName("file_path") - @JsonProperty("file_path") - val filePath: String, - val language: String, + @JsonProperty("file_path") @SerialName("file_path") val filePath: String, + @JsonProperty("language") @SerialName("language") val language: String, ) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/VideoSeyredExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/VideoSeyredExtractor.kt index bc94ae0cc2a..0c8e41ab797 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/VideoSeyredExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/VideoSeyredExtractor.kt @@ -7,27 +7,32 @@ import com.lagradost.api.Log import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.utils.* import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable open class VideoSeyred : ExtractorApi() { - override val name = "VideoSeyred" - override val mainUrl = "https://videoseyred.in" + override val name = "VideoSeyred" + override val mainUrl = "https://videoseyred.in" override val requiresReferer = true - override suspend fun getUrl(url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, callback: (ExtractorLink) -> Unit) { - val extRef = referer ?: "" - val videoId = url.substringAfter("embed/").substringBefore("?") - val videoUrl = "${mainUrl}/playlist/${videoId}.json" - - val responseRaw = app.get(videoUrl) - val responseList: List = tryParseJson>(responseRaw.text) ?: throw ErrorLoadingException("VideoSeyred") - val response = responseList[0] - + override suspend fun getUrl( + url: String, + referer: String?, + subtitleCallback: (SubtitleFile) -> Unit, + callback: (ExtractorLink) -> Unit, + ) { + val extRef = referer ?: "" + val videoId = url.substringAfter("embed/").substringBefore("?") + val videoUrl = "$mainUrl/playlist/$videoId.json" + val responseRaw = app.get(videoUrl) + val responseList = tryParseJson>(responseRaw.text) ?: throw ErrorLoadingException("VideoSeyred") + val response = responseList[0] for (track in response.tracks) { if (track.label != null && track.kind == "captions") { subtitleCallback.invoke( newSubtitleFile( lang = track.label, - url = fixUrl(track.file) + url = fixUrl(track.file), ) ) } @@ -36,35 +41,38 @@ open class VideoSeyred : ExtractorApi() { for (source in response.sources) { callback.invoke( newExtractorLink( - source = this.name, - name = this.name, - url = source.file, + source = this.name, + name = this.name, + url = source.file, ) { - this.referer = "${mainUrl}/" + this.referer = "$mainUrl/" this.quality = Qualities.Unknown.value } ) } } + @Serializable data class VideoSeyredSource( - @JsonProperty("image") val image: String, - @JsonProperty("title") val title: String, - @JsonProperty("sources") val sources: List, - @JsonProperty("tracks") val tracks: List + @JsonProperty("image") @SerialName("image") val image: String, + @JsonProperty("title") @SerialName("title") val title: String, + @JsonProperty("sources") @SerialName("sources") val sources: List, + @JsonProperty("tracks") @SerialName("tracks") val tracks: List, ) + @Serializable data class VSSource( - @JsonProperty("file") val file: String, - @JsonProperty("type") val type: String, - @JsonProperty("default") val default: String + @JsonProperty("file") @SerialName("file") val file: String, + @JsonProperty("type") @SerialName("type") val type: String, + @JsonProperty("default") @SerialName("default") val default: String, ) + @Serializable data class VSTrack( - @JsonProperty("file") val file: String, - @JsonProperty("kind") val kind: String, - @JsonProperty("language") val language: String? = null, - @JsonProperty("label") val label: String? = null, - @JsonProperty("default") val default: String? = null + @JsonProperty("file") @SerialName("file") val file: String, + @JsonProperty("kind") @SerialName("kind") val kind: String, + @JsonProperty("language") @SerialName("language") val language: String? = null, + @JsonProperty("label") @SerialName("label") val label: String? = null, + @JsonProperty("default") @SerialName("default") val default: String? = null, ) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vidoza.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vidoza.kt index df663f97f6c..5cb1706cd77 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vidoza.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vidoza.kt @@ -4,26 +4,28 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.api.Log import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app -import com.lagradost.cloudstream3.utils.AppUtils +import com.lagradost.cloudstream3.utils.AppUtils.parseJson import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable -class Videzz: Vidoza() { - override val mainUrl: String = "https://videzz.net" +class Videzz : Vidoza() { + override val mainUrl = "https://videzz.net" } -open class Vidoza: ExtractorApi() { - override val name: String = "Vidoza" - override val mainUrl: String = "https://vidoza.net" - override val requiresReferer: Boolean = false +open class Vidoza : ExtractorApi() { + override val name = "Vidoza" + override val mainUrl = "https://vidoza.net" + override val requiresReferer = false override suspend fun getUrl( url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val response = app.get(url).document val script = response.selectFirst("script:containsData(sourcesCode)")?.data() @@ -32,31 +34,27 @@ open class Vidoza: ExtractorApi() { // e.g. sourcesCode: [{ src: "https://str38.vidoza.net/vod/v2/.../v.mp4", type: "video/mp4", label:"SD", res:"720"}], var sourcesArray = script.substringAfter("sourcesCode:").substringBefore("\n") arrayOf("src", "type", "label", "res").forEach { - // add missing quotation marks, e.g. src: "https..." -> "src": "https..." - sourcesArray = sourcesArray - .replace(Regex(""""?$it"?:"""), """"$it":""") + // Add missing quotation marks, e.g. src: "https..." -> "src": "https..." + sourcesArray = sourcesArray.replace(Regex(""""?$it"?:"""), """"$it":""") } - val videoData = AppUtils.parseJson(sourcesArray) + val videoData = parseJson>(sourcesArray) for (stream in videoData) { callback.invoke( newExtractorLink( source = name, name = name, - url = stream.source - ) { - quality = getQualityFromName(stream.resolution) - } + url = stream.source, + ) { quality = getQualityFromName(stream.resolution) } ) } } - private class VinovoDataList: ArrayList() - + @Serializable private data class VinovoVideoData( - @JsonProperty("src") val source: String, - @JsonProperty("type") val type: String?, - @JsonProperty("label") val label: String?, - @JsonProperty("res") val resolution: String?, + @JsonProperty("src") @SerialName("src") val source: String, + @JsonProperty("type") @SerialName("type") val type: String?, + @JsonProperty("label") @SerialName("label") val label: String?, + @JsonProperty("res") @SerialName("res") val resolution: String?, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vinovo.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vinovo.kt index e905543a83a..8fc42d65a31 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vinovo.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vinovo.kt @@ -1,32 +1,33 @@ package com.lagradost.cloudstream3.extractors import com.fasterxml.jackson.annotation.JsonProperty -import com.lagradost.cloudstream3.APIHolder +import com.lagradost.cloudstream3.APIHolder.getCaptchaToken import com.lagradost.cloudstream3.SubtitleFile import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.Qualities import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable class VinovoSi : VinovoTo() { - override var name = "VinovoSi" - override var mainUrl = "https://vinovo.si" + override val name = "VinovoSi" + override val mainUrl = "https://vinovo.si" } open class VinovoTo : ExtractorApi() { - override val mainUrl: String = "https://vinovo.to" - override val name: String = "VinovoTo" - override val requiresReferer: Boolean = false + override val mainUrl = "https://vinovo.to" + override val name = "VinovoTo" + override val requiresReferer = false override suspend fun getUrl( url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val fixedUrl = url.replace("/d/", "/e/") - val resp = app.get(fixedUrl, referer = referer) val doc = resp.document @@ -35,21 +36,20 @@ open class VinovoTo : ExtractorApi() { val fileCode = doc.selectFirst("meta[name=\"file_code\"]")?.attr("content") ?: return val captchaToken = doc.selectFirst("meta[name=recaptcha]")?.attr("content") ?: return - val captchaSolution = - APIHolder.getCaptchaToken(fixedUrl, captchaToken, "$mainUrl/") ?: return + val captchaSolution = getCaptchaToken(fixedUrl, captchaToken, "$mainUrl/") ?: return val streamInfo = app.post( url = "$mainUrl/api/file/url/$fileCode", data = mapOf("token" to videoToken, "recaptcha" to captchaSolution), headers = mapOf( "Origin" to mainUrl, - "X-Requested-With" to "XMLHttpRequest" + "X-Requested-With" to "XMLHttpRequest", ), cookies = resp.cookies, - referer = fixedUrl + referer = fixedUrl, ).parsed() - val fileUrl = "$videoBaseUrl/stream/${streamInfo.token}" + val fileUrl = "$videoBaseUrl/stream/${streamInfo.token}" callback.invoke( newExtractorLink(source = name, name = name, url = fileUrl) { val dataTitle = doc.selectFirst("video")?.attr("data-title").orEmpty() @@ -59,8 +59,9 @@ open class VinovoTo : ExtractorApi() { ) } + @Serializable private data class VinovoFileResp( - @JsonProperty("status") val status: String, - @JsonProperty("token") val token: String, + @JsonProperty("status") @SerialName("status") val status: String, + @JsonProperty("token") @SerialName("token") val token: String, ) -} \ No newline at end of file +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/XStreamCdn.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/XStreamCdn.kt index 6e3a8126def..69ee25d51ef 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/XStreamCdn.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/XStreamCdn.kt @@ -9,96 +9,74 @@ import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable class StreamM4u : XStreamCdn() { - override val name: String = "StreamM4u" - override val mainUrl: String = "https://streamm4u.club" + override val name = "StreamM4u" + override val mainUrl = "https://streamm4u.club" } class Fembed9hd : XStreamCdn() { - override var mainUrl = "https://fembed9hd.com" - override var name = "Fembed9hd" + override val name = "Fembed9hd" + override val mainUrl = "https://fembed9hd.com" } -class Cdnplayer: XStreamCdn() { - override val name: String = "Cdnplayer" - override val mainUrl: String = "https://cdnplayer.online" +class Cdnplayer : XStreamCdn() { + override val name = "Cdnplayer" + override val mainUrl = "https://cdnplayer.online" } -class Kotakajair: XStreamCdn() { - override val name: String = "Kotakajair" - override val mainUrl: String = "https://kotakajair.xyz" +class Kotakajair : XStreamCdn() { + override val name = "Kotakajair" + override val mainUrl = "https://kotakajair.xyz" } -class FEnet: XStreamCdn() { - override val name: String = "FEnet" - override val mainUrl: String = "https://fembed.net" +class FEnet : XStreamCdn() { + override val name = "FEnet" + override val mainUrl = "https://fembed.net" } -class Rasacintaku: XStreamCdn() { - override val mainUrl: String = "https://rasa-cintaku-semakin-berantai.xyz" +class Rasacintaku : XStreamCdn() { + override val mainUrl = "https://rasa-cintaku-semakin-berantai.xyz" } -class LayarKaca: XStreamCdn() { - override val name: String = "LayarKaca-xxi" - override val mainUrl: String = "https://layarkacaxxi.icu" +class LayarKaca : XStreamCdn() { + override val name = "LayarKaca-xxi" + override val mainUrl = "https://layarkacaxxi.icu" } -class DBfilm: XStreamCdn() { - override val name: String = "DBfilm" - override val mainUrl: String = "https://dbfilm.bar" +class DBfilm : XStreamCdn() { + override val name = "DBfilm" + override val mainUrl = "https://dbfilm.bar" } -class Luxubu : XStreamCdn(){ - override val name: String = "FE" - override val mainUrl: String = "https://www.luxubu.review" +class Luxubu : XStreamCdn() { + override val name = "FE" + override val mainUrl = "https://www.luxubu.review" } -class FEmbed: XStreamCdn() { - override val name: String = "FEmbed" - override val mainUrl: String = "https://www.fembed.com" +class FEmbed : XStreamCdn() { + override val name = "FEmbed" + override val mainUrl = "https://www.fembed.com" } -class Fplayer: XStreamCdn() { - override val name: String = "Fplayer" - override val mainUrl: String = "https://fplayer.info" +class Fplayer : XStreamCdn() { + override val name = "Fplayer" + override val mainUrl = "https://fplayer.info" } -class FeHD: XStreamCdn() { - override val name: String = "FeHD" - override val mainUrl: String = "https://fembed-hd.com" - override var domainUrl: String = "fembed-hd.com" +class FeHD : XStreamCdn() { + override val name = "FeHD" + override val mainUrl = "https://fembed-hd.com" + override val domainUrl = "fembed-hd.com" } open class XStreamCdn : ExtractorApi() { - override val name: String = "XStreamCdn" - override val mainUrl: String = "https://embedsito.com" + override val name = "XStreamCdn" + override val mainUrl = "https://embedsito.com" override val requiresReferer = false - open var domainUrl: String = "embedsito.com" - - private data class ResponseData( - @JsonProperty("file") val file: String, - @JsonProperty("label") val label: String, - //val type: String // Mp4 - ) - - private data class Player( - @JsonProperty("poster_file") val poster_file: String? = null, - ) - - private data class ResponseJson( - @JsonProperty("success") val success: Boolean, - @JsonProperty("player") val player: Player? = null, - @JsonProperty("data") val data: List?, - @JsonProperty("captions") val captions: List?, - ) - - private data class Captions( - @JsonProperty("id") val id: String, - @JsonProperty("hash") val hash: String, - @JsonProperty("language") val language: String, - @JsonProperty("extension") val extension: String - ) + open val domainUrl = "embedsito.com" override fun getExtractorUrl(id: String): String { return "$domainUrl/api/source/$id" @@ -108,14 +86,15 @@ open class XStreamCdn : ExtractorApi() { url: String, referer: String?, subtitleCallback: (SubtitleFile) -> Unit, - callback: (ExtractorLink) -> Unit + callback: (ExtractorLink) -> Unit, ) { val headers = mapOf( "Referer" to url, "User-Agent" to "Mozilla/5.0 (Windows NT 10.0; rv:78.0) Gecko/20100101 Firefox/78.0", ) + val id = url.trimEnd('/').split("/").last() - val newUrl = "https://${domainUrl}/api/source/${id}" + val newUrl = "https://$domainUrl/api/source/$id" app.post(newUrl, headers = headers).let { res -> val sources = tryParseJson(res.text) sources?.let { @@ -135,7 +114,7 @@ open class XStreamCdn : ExtractorApi() { } } - val userData = sources?.player?.poster_file?.split("/")?.get(2) + val userData = sources?.player?.posterFile?.split("/")?.get(2) sources?.captions?.map { subtitleCallback.invoke( newSubtitleFile( @@ -146,4 +125,31 @@ open class XStreamCdn : ExtractorApi() { } } } -} \ No newline at end of file + + @Serializable + private data class ResponseData( + @JsonProperty("file") @SerialName("file") val file: String, + @JsonProperty("label") @SerialName("label") val label: String, + ) + + @Serializable + private data class Player( + @JsonProperty("poster_file") @SerialName("poster_file") val posterFile: String? = null, + ) + + @Serializable + private data class ResponseJson( + @JsonProperty("success") @SerialName("success") val success: Boolean, + @JsonProperty("player") @SerialName("player") val player: Player? = null, + @JsonProperty("data") @SerialName("data") val data: List?, + @JsonProperty("captions") @SerialName("captions") val captions: List?, + ) + + @Serializable + private data class Captions( + @JsonProperty("id") @SerialName("id") val id: String, + @JsonProperty("hash") @SerialName("hash") val hash: String, + @JsonProperty("language") @SerialName("language") val language: String, + @JsonProperty("extension") @SerialName("extension") val extension: String, + ) +} diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/YourUpload.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/YourUpload.kt index 9f2d6bde042..88eb58333d2 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/YourUpload.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/YourUpload.kt @@ -7,8 +7,10 @@ import com.lagradost.cloudstream3.utils.ExtractorApi import com.lagradost.cloudstream3.utils.ExtractorLink import com.lagradost.cloudstream3.utils.getQualityFromName import com.lagradost.cloudstream3.utils.newExtractorLink +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable -open class YourUpload: ExtractorApi() { +open class YourUpload : ExtractorApi() { override val name = "Yourupload" override val mainUrl = "https://www.yourupload.com" override val requiresReferer = false @@ -19,13 +21,11 @@ open class YourUpload: ExtractorApi() { val quality = Regex("\\d{3,4}p").find(this.select("title").text())?.groupValues?.get(0) this.select("script").map { script -> if (script.data().contains("var jwplayerOptions = {")) { - val data = - script.data().substringAfter("var jwplayerOptions = {").substringBefore(",\n") + val data = script.data().substringAfter("var jwplayerOptions = {").substringBefore(",\n") val link = tryParseJson( - "{${ - data.replace("file", "\"file\"").replace("'", "\"") - }}" + "{${data.replace("file", "\"file\"").replace("'", "\"")}}" ) + sources.add( newExtractorLink( source = name, @@ -39,11 +39,12 @@ open class YourUpload: ExtractorApi() { } } } + return sources } + @Serializable private data class ResponseSource( - @JsonProperty("file") val file: String, + @JsonProperty("file") @SerialName("file") val file: String, ) - -} \ No newline at end of file +}