diff --git a/build.gradle.kts b/build.gradle.kts index defd2851502..cca263dd422 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,6 @@ plugins { alias(libs.plugins.android.application) apply false + alias(libs.plugins.android.lint) apply false alias(libs.plugins.android.multiplatform.library) apply false alias(libs.plugins.buildkonfig) apply false // Universal build config alias(libs.plugins.dokka) apply false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1d29aab0495..24f69824c86 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -112,6 +112,7 @@ work-runtime-ktx = { module = "androidx.work:work-runtime-ktx", version.ref = "w [plugins] android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" } +android-lint = { id = "com.android.lint", version.ref = "androidGradlePlugin" } android-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "androidGradlePlugin" } buildkonfig = { id = "com.codingfeline.buildkonfig", version.ref = "buildkonfigGradlePlugin" } dokka = { id = "org.jetbrains.dokka", version.ref = "dokkaGradlePlugin" } diff --git a/library/build.gradle.kts b/library/build.gradle.kts index 5e2b5909882..392552739ff 100644 --- a/library/build.gradle.kts +++ b/library/build.gradle.kts @@ -7,6 +7,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile plugins { id("maven-publish") // Gradle core plugin + alias(libs.plugins.android.lint) alias(libs.plugins.kotlin.multiplatform) alias(libs.plugins.android.multiplatform.library) alias(libs.plugins.buildkonfig) diff --git a/library/lint.xml b/library/lint.xml new file mode 100644 index 00000000000..6f4e202227b --- /dev/null +++ b/library/lint.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt index 43f7f4070ed..ada8d5cd893 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/MainAPI.kt @@ -2502,7 +2502,7 @@ constructor( fun Episode.addDate(date: String?, format: String = "yyyy-MM-dd") { try { - this.date = SimpleDateFormat(format).parse(date ?: return)?.time + this.date = SimpleDateFormat(format, Locale.getDefault()).parse(date ?: return)?.time } catch (e: Exception) { logError(e) } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/ContentXExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/ContentXExtractor.kt index 06c5ec321c5..dba2e926787 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/ContentXExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/ContentXExtractor.kt @@ -17,12 +17,12 @@ open class ContentX : ExtractorApi() { val iSource = app.get(url, referer=extRef).text val iExtract = Regex("""window\.openPlayer\('([^']+)'""").find(iSource)!!.groups[1]?.value ?: throw ErrorLoadingException("iExtract is null") - val subUrls = mutableSetOf() + val subUrls = mutableSetOf() Regex("""\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(iSource).forEach { val (subUrl, subLang) = it.destructured - if (subUrl in subUrls) { return@forEach } - subUrls.add(subUrl) + if (subUrl in subUrls) { return@forEach } + subUrls.add(subUrl) subtitleCallback.invoke( newSubtitleFile( diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/DoodExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/DoodExtractor.kt index 58b6396a85a..e1fd47fffab 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/DoodExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/DoodExtractor.kt @@ -77,7 +77,7 @@ open class DoodLaExtractor : ExtractorApi() { override var name = "DoodStream" override var mainUrl = "https://dood.la" override val requiresReferer = false - + private val alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" override suspend fun getUrl( @@ -87,18 +87,17 @@ open class DoodLaExtractor : ExtractorApi() { callback: (ExtractorLink) -> Unit ) { val embedUrl = url.replace("/d/", "/e/") - val req = app.get(embedUrl) + val req = app.get(embedUrl) val host = getBaseUrl(req.url) val response0 = req.text - val md5 = host + (Regex("/pass_md5/[^']*").find(response0)?.value ?: return) + val md5 = host + (Regex("/pass_md5/[^']*").find(response0)?.value ?: return) val trueUrl = app.get(md5, referer = req.url).text + createHashTable() + "?token=" + md5.substringAfterLast("/") - - val quality = Regex("\\d{3,4}p") + val quality = Regex("\\d{3,4}p") .find(response0.substringAfter("").substringBefore("")) ?.groupValues ?.getOrNull(0) - - callback.invoke( + + callback.invoke( newExtractorLink( this.name, this.name, @@ -108,19 +107,17 @@ open class DoodLaExtractor : ExtractorApi() { this.quality = getQualityFromName(quality) } ) - } - -private fun createHashTable(): String { - return buildString { - repeat(10) { - append(alphabet.random()) + + private fun createHashTable(): String { + return buildString { + repeat(10) { + append(alphabet.random()) + } } } -} - -private fun getBaseUrl(url: String): String { + private fun getBaseUrl(url: String): String { return URI(url).let { "${it.scheme}://${it.host}" } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Filegram.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Filegram.kt index df7e0337365..7baa62710ba 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Filegram.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Filegram.kt @@ -32,32 +32,29 @@ open class Filegram : ExtractorApi() { "Sec-Fetch-Site" to "same-site", "user-agent" to USER_AGENT, ) - + val doc = app.get(getEmbedUrl(url), referer = referer).document val unpackedJs = unpackJs(doc).toString() - val videoUrl = Regex("""file:\s*"([^"]+\.m3u8[^"]*)"""").find(unpackedJs)?.groupValues?.get(1) + val videoUrl = Regex("""file:\s*"([^"]+\.m3u8[^"]*)"""").find(unpackedJs)?.groupValues?.get(1) if (videoUrl != null) { M3u8Helper.generateM3u8( - this.name, - fixUrl(videoUrl), - "$mainUrl/", - headers = header - ).forEach(callback) + this.name, + fixUrl(videoUrl), + "$mainUrl/", + headers = header + ).forEach(callback) } } - private fun unpackJs(script: Element): String? { - return script.select("script").find { it.data().contains("eval(function(p,a,c,k,e,d)") } - ?.data()?.let { getAndUnpack(it) } - } - - private fun getEmbedUrl(url: String): String { - return if (!url.contains("/embed-")) { - val videoId = url.substringAfter("$mainUrl/") - "$mainUrl/embed-$videoId" - } else { - url - } - } + private fun unpackJs(script: Element): String? { + return script.select("script").find { it.data().contains("eval(function(p,a,c,k,e,d)") } + ?.data()?.let { getAndUnpack(it) } + } + private fun getEmbedUrl(url: String): String { + return if (!url.contains("/embed-")) { + val videoId = url.substringAfter("$mainUrl/") + "$mainUrl/embed-$videoId" + } else url + } } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/RapidVidExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/RapidVidExtractor.kt index bacd658bbad..9654e5f3805 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/RapidVidExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/RapidVidExtractor.kt @@ -15,12 +15,12 @@ open class RapidVid : ExtractorApi() { val extRef = referer ?: "" val videoReq = app.get(url, referer=extRef).text - val subUrls = mutableSetOf() + val subUrls = mutableSetOf() Regex("""captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(videoReq).forEach { val (subUrl, subLang) = it.destructured - if (subUrl in subUrls) { return@forEach } - subUrls.add(subUrl) + if (subUrl in subUrls) { return@forEach } + subUrls.add(subUrl) subtitleCallback.invoke( newSubtitleFile( 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 c8796896c09..1348f74d501 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/TRsTXExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/TRsTXExtractor.kt @@ -29,7 +29,7 @@ open class TRsTX : ExtractorApi() { ) } - val vidLinks = mutableSetOf() + val vidLinks = mutableSetOf() val vidMap = mutableListOf>() for (item in postJson) { if (item.file == null || item.title == null) continue @@ -37,8 +37,8 @@ open class TRsTX : ExtractorApi() { 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) + if (videoData in vidLinks) { continue } + vidLinks.add(videoData) vidMap.add(mapOf( "title" to item.title, @@ -46,12 +46,11 @@ open class TRsTX : ExtractorApi() { )) } - for (mapEntry in vidMap) { val title = mapEntry["title"] ?: continue val m3uLink = mapEntry["videoData"] ?: continue - callback.invoke( + callback.invoke( newExtractorLink( source = this.name, name = "${this.name} - ${title}", diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/VidMoxyExtractor.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/VidMoxyExtractor.kt index e4cb696037d..36acf7f7ad5 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/VidMoxyExtractor.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/VidMoxyExtractor.kt @@ -15,12 +15,12 @@ open class VidMoxy : ExtractorApi() { val extRef = referer ?: "" val videoReq = app.get(url, referer=extRef).text - val subUrls = mutableSetOf() + val subUrls = mutableSetOf() Regex("""captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"""").findAll(videoReq).forEach { val (subUrl, subLang) = it.destructured - if (subUrl in subUrls) { return@forEach } - subUrls.add(subUrl) + if (subUrl in subUrls) { return@forEach } + subUrls.add(subUrl) subtitleCallback.invoke( newSubtitleFile( diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vtbe.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vtbe.kt index 0f078b3bb9f..37b8ecb239e 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vtbe.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vtbe.kt @@ -20,20 +20,20 @@ open class Vtbe : ExtractorApi() { override suspend fun getUrl(url: String, referer: String?): List? { val response = app.get(url,referer=mainUrl).document val extractedpack =response.selectFirst("script:containsData(function(p,a,c,k,e,d))")?.data().toString() - JsUnpacker(extractedpack).unpack()?.let { unPacked -> - Regex("sources:\\[\\{file:\"(.*?)\"").find(unPacked)?.groupValues?.get(1)?.let { link -> - return listOf( - newExtractorLink( - this.name, - this.name, - link, - ) { - this.referer = referer ?: "" - this.quality = Qualities.Unknown.value - } - ) - } + JsUnpacker(extractedpack).unpack()?.let { unPacked -> + Regex("sources:\\[\\{file:\"(.*?)\"").find(unPacked)?.groupValues?.get(1)?.let { link -> + return listOf( + newExtractorLink( + this.name, + this.name, + link, + ) { + this.referer = referer ?: "" + this.quality = Qualities.Unknown.value + } + ) } - return null + } + return null } } diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/helper/CryptoJSHelper.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/helper/CryptoJSHelper.kt index a13db65cc36..af59b6f7d2d 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/helper/CryptoJSHelper.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/helper/CryptoJSHelper.kt @@ -1,7 +1,8 @@ package com.lagradost.cloudstream3.extractors.helper +import com.lagradost.cloudstream3.base64DecodeArray +import com.lagradost.cloudstream3.base64Encode import java.util.Arrays -import java.util.Base64 import java.security.MessageDigest import java.security.SecureRandom import javax.crypto.Cipher @@ -51,8 +52,7 @@ object CryptoJS { System.arraycopy(saltBytes, 0, b, sBytes.size, saltBytes.size) System.arraycopy(cipherText, 0, b, sBytes.size + saltBytes.size, cipherText.size) - val bEncode = Base64.getEncoder().encode(b) - return String(bEncode) + return base64Encode(b) } /** @@ -62,7 +62,7 @@ object CryptoJS { * @param cipherText encrypted string */ fun decrypt(password: String, cipherText: String): String { - val ctBytes = Base64.getDecoder().decode(cipherText.toByteArray()) + val ctBytes = base64DecodeArray(cipherText) val saltBytes = Arrays.copyOfRange(ctBytes, 8, 16) val cipherTextBytes = Arrays.copyOfRange(ctBytes, 16, ctBytes.size) diff --git a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/HlsPlaylistParser.kt b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/HlsPlaylistParser.kt index dbc3c92f6f2..01e5bb86295 100644 --- a/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/HlsPlaylistParser.kt +++ b/library/src/commonMain/kotlin/com/lagradost/cloudstream3/utils/HlsPlaylistParser.kt @@ -222,7 +222,7 @@ object HlsPlaylistParser { if (codecs.isNullOrEmpty()) { return arrayOf() } - return split(codecs.trim { it <= ' ' }, "(\\s*,\\s*)") + return split(codecs.trim(), "(\\s*,\\s*)") } fun getCodecsOfType( @@ -928,7 +928,7 @@ object HlsPlaylistParser { fun getMediaMimeType(codecOrNull: String?): String? { var codec = codecOrNull ?: return null - codec = codec.trim { it <= ' ' }.lowercase() + codec = codec.trim().lowercase() if (codec.startsWith("avc1") || codec.startsWith("avc3")) { return MimeTypes.VIDEO_H264 } else if (codec.startsWith("hev1") || codec.startsWith("hvc1")) {