mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	Merge branch 'master' into feature/discord/reset-subdelay-nextepisode
This commit is contained in:
		
						commit
						81180bd063
					
				
					 16 changed files with 197 additions and 46 deletions
				
			
		
							
								
								
									
										7
									
								
								.idea/gradle.xml
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								.idea/gradle.xml
									
										
									
										generated
									
									
									
								
							|  | @ -4,17 +4,16 @@ | |||
|   <component name="GradleSettings"> | ||||
|     <option name="linkedExternalProjectsSettings"> | ||||
|       <GradleProjectSettings> | ||||
|         <option name="delegatedBuild" value="true" /> | ||||
|         <option name="testRunner" value="GRADLE" /> | ||||
|         <option name="distributionType" value="DEFAULT_WRAPPED" /> | ||||
|         <option name="externalProjectPath" value="$PROJECT_DIR$" /> | ||||
|         <option name="gradleJvm" value="jbr-17" /> | ||||
|         <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" /> | ||||
|         <option name="modules"> | ||||
|           <set> | ||||
|             <option value="$PROJECT_DIR$" /> | ||||
|             <option value="$PROJECT_DIR$/app" /> | ||||
|             <option value="$PROJECT_DIR$/library" /> | ||||
|           </set> | ||||
|         </option> | ||||
|         <option name="resolveExternalAnnotations" value="false" /> | ||||
|       </GradleProjectSettings> | ||||
|     </option> | ||||
|   </component> | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| import com.android.build.gradle.internal.cxx.configure.gradleLocalProperties | ||||
| import org.jetbrains.dokka.gradle.DokkaTask | ||||
| import org.jetbrains.kotlin.gradle.plugin.mpp.pm20.util.archivesName | ||||
| import org.jetbrains.kotlin.gradle.tasks.KotlinCompile | ||||
| import java.io.ByteArrayOutputStream | ||||
| import java.net.URL | ||||
|  | @ -13,6 +14,7 @@ plugins { | |||
| 
 | ||||
| val tmpFilePath = System.getProperty("user.home") + "/work/_temp/keystore/" | ||||
| val prereleaseStoreFile: File? = File(tmpFilePath).listFiles()?.first() | ||||
| var isLibraryDebug = false | ||||
| 
 | ||||
| fun String.execute() = ByteArrayOutputStream().use { baot -> | ||||
|     if (project.exec { | ||||
|  | @ -103,6 +105,7 @@ android { | |||
|             ) | ||||
|         } | ||||
|         debug { | ||||
|             isLibraryDebug = true | ||||
|             isDebuggable = true | ||||
|             applicationIdSuffix = ".debug" | ||||
|             proguardFiles( | ||||
|  | @ -199,7 +202,7 @@ dependencies { | |||
|     // PlayBack | ||||
|     implementation("com.jaredrummler:colorpicker:1.1.0") // Subtitle Color Picker | ||||
|     implementation("com.github.recloudstream:media-ffmpeg:1.1.0") // Custom FF-MPEG Lib for Audio Codecs | ||||
|     implementation("com.github.teamnewpipe:NewPipeExtractor:6dc25f7") /* For Trailers | ||||
|     implementation("com.github.TeamNewPipe.NewPipeExtractor:NewPipeExtractor:6dc25f7b97") /* For Trailers | ||||
|     ^ Update to Latest Commits if Trailers Misbehave, github.com/TeamNewPipe/NewPipeExtractor/commits/dev */ | ||||
|     implementation("com.github.albfernandez:juniversalchardet:2.4.0") // Subtitle Decoding | ||||
| 
 | ||||
|  | @ -232,18 +235,37 @@ dependencies { | |||
|     implementation("androidx.work:work-runtime:2.9.0") | ||||
|     implementation("androidx.work:work-runtime-ktx:2.9.0") | ||||
|     implementation("com.github.Blatzar:NiceHttp:0.4.11") // HTTP Lib | ||||
| 
 | ||||
|     implementation(project(":library") { | ||||
|         this.extra.set("isDebug", isLibraryDebug) | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
| tasks.register("androidSourcesJar", Jar::class) { | ||||
| tasks.register<Jar>("androidSourcesJar") { | ||||
|     archiveClassifier.set("sources") | ||||
|     from(android.sourceSets.getByName("main").java.srcDirs) // Full Sources | ||||
| } | ||||
| 
 | ||||
| // For GradLew Plugin | ||||
| tasks.register("makeJar", Copy::class) { | ||||
|     from("build/intermediates/compile_app_classes_jar/prereleaseDebug") | ||||
|     into("build") | ||||
|     include("classes.jar") | ||||
| tasks.register<Copy>("copyJar") { | ||||
|     from( | ||||
|         "build/intermediates/compile_app_classes_jar/prereleaseDebug", | ||||
|         "../library/build/libs" | ||||
|     ) | ||||
|     into("build/app-classes") | ||||
|     include("classes.jar", "library-jvm*.jar") | ||||
|     // Remove the version | ||||
|     rename("library-jvm.*.jar", "library-jvm.jar") | ||||
| } | ||||
| 
 | ||||
| // Merge the app classes and the library classes into classes.jar | ||||
| tasks.register<Jar>("makeJar") { | ||||
|     dependsOn(tasks.getByName("copyJar")) | ||||
|     from( | ||||
|         zipTree("build/app-classes/classes.jar"), | ||||
|         zipTree("build/app-classes/library-jvm.jar") | ||||
|     ) | ||||
|     destinationDirectory.set(layout.buildDirectory) | ||||
|     archivesName = "classes" | ||||
| } | ||||
| 
 | ||||
| tasks.withType<KotlinCompile> { | ||||
|  |  | |||
|  | @ -743,8 +743,6 @@ fun base64Encode(array: ByteArray): String { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| class ErrorLoadingException(message: String? = null) : Exception(message) | ||||
| 
 | ||||
| fun MainAPI.fixUrlNull(url: String?): String? { | ||||
|     if (url.isNullOrEmpty()) { | ||||
|         return null | ||||
|  |  | |||
|  | @ -25,9 +25,13 @@ open class Vidmoly : ExtractorApi() { | |||
|         subtitleCallback: (SubtitleFile) -> Unit, | ||||
|         callback: (ExtractorLink) -> Unit | ||||
|     ) { | ||||
| 
 | ||||
|         val headers  = mapOf( | ||||
|             "User-Agent"     to "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36", | ||||
|             "Sec-Fetch-Dest" to "iframe" | ||||
|         ) | ||||
|         val script = app.get( | ||||
|             url, | ||||
|             headers = headers, | ||||
|             referer = referer, | ||||
|         ).document.select("script") | ||||
|             .find { it.data().contains("sources:") }?.data() | ||||
|  | @ -66,4 +70,4 @@ open class Vidmoly : ExtractorApi() { | |||
|         @JsonProperty("kind") val kind: String? = null, | ||||
|     ) | ||||
| 
 | ||||
| } | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,16 @@ | |||
| package com.lagradost.cloudstream3.mvvm | ||||
| 
 | ||||
| import androidx.lifecycle.LifecycleOwner | ||||
| import androidx.lifecycle.LiveData | ||||
| 
 | ||||
| /** NOTE: Only one observer at a time per value */ | ||||
| fun <T> LifecycleOwner.observe(liveData: LiveData<T>, action: (t: T) -> Unit) { | ||||
|     liveData.removeObservers(this) | ||||
|     liveData.observe(this) { it?.let { t -> action(t) } } | ||||
| } | ||||
| 
 | ||||
| /** NOTE: Only one observer at a time per value */ | ||||
| fun <T> LifecycleOwner.observeNullable(liveData: LiveData<T>, action: (t: T) -> Unit) { | ||||
|     liveData.removeObservers(this) | ||||
|     liveData.observe(this) { action(it) } | ||||
| } | ||||
|  | @ -783,7 +783,10 @@ class ResultFragmentTv : Fragment() { | |||
|                 //    resultEpisodeLoading.isVisible = episodes is Resource.Loading | ||||
|                 if (episodes is Resource.Success) { | ||||
| 
 | ||||
|                     val lastWatchedIndex = episodes.value.indexOfLast { ep -> ep.getWatchProgress() >= NEXT_WATCH_EPISODE_PERCENTAGE.toFloat() / 100.0f } | ||||
|                     val lastWatchedIndex = episodes.value.indexOfLast { ep -> | ||||
|                         ep.getWatchProgress() >= NEXT_WATCH_EPISODE_PERCENTAGE.toFloat() / 100.0f || ep.videoWatchState == VideoWatchState.Watched | ||||
|                     } | ||||
| 
 | ||||
|                     val firstUnwatched = episodes.value.getOrElse(lastWatchedIndex + 1) { episodes.value.firstOrNull() } | ||||
| 
 | ||||
|                     if (firstUnwatched != null) { | ||||
|  |  | |||
|  | @ -50,7 +50,7 @@ class JsUnpacker(packedJS: String?) { | |||
|                     throw Exception("Unknown p.a.c.k.e.r. encoding") | ||||
|                 } | ||||
|                 val unbase = Unbase(radix) | ||||
|                 p = Pattern.compile("\\b\\w+\\b") | ||||
|                 p = Pattern.compile("""\b[a-zA-Z0-9_]+\b""") | ||||
|                 m = p.matcher(payload) | ||||
|                 val decoded = StringBuilder(payload) | ||||
|                 var replaceOffset = 0 | ||||
|  |  | |||
|  | @ -8,6 +8,8 @@ buildscript { | |||
|         classpath("com.android.tools.build:gradle:8.2.2") | ||||
|         classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22") | ||||
|         classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.9.10") | ||||
|         // Universal build config | ||||
|         classpath("com.codingfeline.buildkonfig:buildkonfig-gradle-plugin:0.15.1") | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -22,6 +24,6 @@ plugins { | |||
|     id("com.google.devtools.ksp") version "1.9.22-1.0.17" apply false | ||||
| } | ||||
| 
 | ||||
| tasks.register<Delete>("clean") { | ||||
|     delete(rootProject.layout.buildDirectory) | ||||
| } | ||||
| //tasks.register<Delete>("clean") { | ||||
| //    delete(rootProject.layout.buildDirectory) | ||||
| //} | ||||
|  |  | |||
							
								
								
									
										68
									
								
								library/build.gradle.kts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								library/build.gradle.kts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,68 @@ | |||
| import com.codingfeline.buildkonfig.compiler.FieldSpec | ||||
| 
 | ||||
| plugins { | ||||
|     kotlin("multiplatform") | ||||
|     id("maven-publish") | ||||
|     id("com.android.library") | ||||
|     id("com.codingfeline.buildkonfig") | ||||
| } | ||||
| 
 | ||||
| kotlin { | ||||
|     version = "1.0.0" | ||||
|     androidTarget() | ||||
|     jvm() | ||||
| 
 | ||||
|     sourceSets { | ||||
|         commonMain.dependencies { | ||||
|             implementation("com.github.Blatzar:NiceHttp:0.4.11") // HTTP Lib | ||||
|             implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.13.1") /* JSON Parser | ||||
|             ^ Don't Bump Jackson above 2.13.1 , Crashes on Android TV's and FireSticks that have Min API | ||||
|             Level 25 or Less. */ | ||||
|             implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| repositories { | ||||
|     mavenLocal() | ||||
|     maven("https://jitpack.io") | ||||
| } | ||||
| 
 | ||||
| tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> { | ||||
|     kotlinOptions.jvmTarget = JavaVersion.VERSION_1_8.toString() | ||||
| } | ||||
| 
 | ||||
| buildkonfig { | ||||
|     packageName = "com.lagradost.api" | ||||
|     exposeObjectWithName = "BuildConfig" | ||||
| 
 | ||||
|     defaultConfigs { | ||||
|         val isDebug = kotlin.runCatching { extra.get("isDebug") }.getOrNull() == true | ||||
|         buildConfigField(FieldSpec.Type.BOOLEAN, "DEBUG", isDebug.toString()) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| android { | ||||
|     compileSdk = 34 | ||||
|     sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") | ||||
| 
 | ||||
|     defaultConfig { | ||||
|         minSdk = 21 | ||||
|         targetSdk = 33 | ||||
|     } | ||||
| 
 | ||||
|     // If this is the same com.lagradost.cloudstream3.R stops working | ||||
|     namespace = "com.lagradost.api" | ||||
| 
 | ||||
|     compileOptions { | ||||
|         sourceCompatibility = JavaVersion.VERSION_1_8 | ||||
|         targetCompatibility = JavaVersion.VERSION_1_8 | ||||
|     } | ||||
| } | ||||
| publishing { | ||||
|     publications { | ||||
|         withType<MavenPublication> { | ||||
|             groupId = "com.lagradost.api" | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										2
									
								
								library/src/androidMain/AndroidManifest.xml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								library/src/androidMain/AndroidManifest.xml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <manifest /> | ||||
							
								
								
									
										21
									
								
								library/src/androidMain/kotlin/com/lagradost/api/Log.kt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								library/src/androidMain/kotlin/com/lagradost/api/Log.kt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | |||
| package com.lagradost.api | ||||
| 
 | ||||
| import android.util.Log | ||||
| 
 | ||||
| actual object Log { | ||||
|     actual fun d(tag: String, message: String) { | ||||
|         Log.d(tag, message) | ||||
|     } | ||||
| 
 | ||||
|     actual fun i(tag: String, message: String) { | ||||
|         Log.i(tag, message) | ||||
|     } | ||||
| 
 | ||||
|     actual fun w(tag: String, message: String) { | ||||
|         Log.w(tag, message) | ||||
|     } | ||||
| 
 | ||||
|     actual fun e(tag: String, message: String) { | ||||
|         Log.e(tag, message) | ||||
|     } | ||||
| } | ||||
							
								
								
									
										8
									
								
								library/src/commonMain/kotlin/com/lagradost/api/Log.kt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								library/src/commonMain/kotlin/com/lagradost/api/Log.kt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| package com.lagradost.api | ||||
| 
 | ||||
| expect object Log { | ||||
|     fun d(tag: String, message: String) | ||||
|     fun i(tag: String, message: String) | ||||
|     fun w(tag: String, message: String) | ||||
|     fun e(tag: String, message: String) | ||||
| } | ||||
|  | @ -0,0 +1,3 @@ | |||
| package com.lagradost.cloudstream3 | ||||
| 
 | ||||
| class ErrorLoadingException(message: String? = null) : Exception(message) | ||||
|  | @ -1,10 +1,7 @@ | |||
| package com.lagradost.cloudstream3.mvvm | ||||
| 
 | ||||
| import android.util.Log | ||||
| import androidx.lifecycle.LifecycleOwner | ||||
| import androidx.lifecycle.LiveData | ||||
| import com.bumptech.glide.load.HttpException | ||||
| import com.lagradost.cloudstream3.BuildConfig | ||||
| import com.lagradost.api.BuildConfig | ||||
| import com.lagradost.api.Log | ||||
| import com.lagradost.cloudstream3.ErrorLoadingException | ||||
| import kotlinx.coroutines.* | ||||
| import java.io.InterruptedIOException | ||||
|  | @ -49,18 +46,6 @@ inline fun debugWarning(assert: () -> Boolean, message: () -> String) { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| /** NOTE: Only one observer at a time per value */ | ||||
| fun <T> LifecycleOwner.observe(liveData: LiveData<T>, action: (t: T) -> Unit) { | ||||
|     liveData.removeObservers(this) | ||||
|     liveData.observe(this) { it?.let { t -> action(t) } } | ||||
| } | ||||
| 
 | ||||
| /** NOTE: Only one observer at a time per value */ | ||||
| fun <T> LifecycleOwner.observeNullable(liveData: LiveData<T>, action: (t: T) -> Unit) { | ||||
|     liveData.removeObservers(this) | ||||
|     liveData.observe(this) { action(it) } | ||||
| } | ||||
| 
 | ||||
| sealed class Resource<out T> { | ||||
|     data class Success<out T>(val value: T) : Resource<T>() | ||||
|     data class Failure( | ||||
|  | @ -158,14 +143,14 @@ fun<T> throwAbleToResource( | |||
|                 "Connection Timeout\nPlease try again later." | ||||
|             ) | ||||
|         } | ||||
|         is HttpException -> { | ||||
|             Resource.Failure( | ||||
|                 false, | ||||
|                 throwable.statusCode, | ||||
|                 null, | ||||
|                 throwable.message ?: "HttpException" | ||||
|             ) | ||||
|         } | ||||
| //        is HttpException -> { | ||||
| //            Resource.Failure( | ||||
| //                false, | ||||
| //                throwable.statusCode, | ||||
| //                null, | ||||
| //                throwable.message ?: "HttpException" | ||||
| //            ) | ||||
| //        } | ||||
|         is UnknownHostException -> { | ||||
|             Resource.Failure(true, null, null, "Cannot connect to server, try again later.\n${throwable.message}") | ||||
|         } | ||||
							
								
								
									
										19
									
								
								library/src/jvmMain/kotlin/com/lagradost/api/Log.kt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								library/src/jvmMain/kotlin/com/lagradost/api/Log.kt
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,19 @@ | |||
| package com.lagradost.api | ||||
| 
 | ||||
| actual object Log { | ||||
|     actual fun d(tag: String, message: String) { | ||||
|         println("DEBUG $tag: $message") | ||||
|     } | ||||
| 
 | ||||
|     actual fun i(tag: String, message: String) { | ||||
|         println("INFO $tag: $message") | ||||
|     } | ||||
| 
 | ||||
|     actual fun w(tag: String, message: String) { | ||||
|         println("WARNING $tag: $message") | ||||
|     } | ||||
| 
 | ||||
|     actual fun e(tag: String, message: String) { | ||||
|         println("ERROR $tag: $message") | ||||
|     } | ||||
| } | ||||
|  | @ -1,3 +1,4 @@ | |||
| rootProject.name = "CloudStream" | ||||
| 
 | ||||
| include(":app") | ||||
| include(":app") | ||||
| include(":library") | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue