From 7a640b58cb84458e495d0c52beed39667ffb0ee2 Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Fri, 23 Sep 2022 12:24:41 +0200 Subject: [PATCH 1/4] Fix app not responding when clicking extensions in settings --- .../ui/settings/extensions/ExtensionsViewModel.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsViewModel.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsViewModel.kt index b5f82ae8..897e7366 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsViewModel.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsViewModel.kt @@ -3,21 +3,19 @@ package com.lagradost.cloudstream3.ui.settings.extensions import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.AcraApplication.Companion.getKey import com.lagradost.cloudstream3.R import com.lagradost.cloudstream3.apmap import com.lagradost.cloudstream3.mvvm.Some import com.lagradost.cloudstream3.mvvm.debugAssert -import com.lagradost.cloudstream3.mvvm.launchSafe import com.lagradost.cloudstream3.plugins.PluginManager import com.lagradost.cloudstream3.plugins.PluginManager.getPluginsOnline import com.lagradost.cloudstream3.plugins.RepositoryManager import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES import com.lagradost.cloudstream3.ui.result.UiText import com.lagradost.cloudstream3.ui.result.txt -import kotlinx.coroutines.launch +import com.lagradost.cloudstream3.utils.Coroutines.ioSafe data class RepositoryData( @JsonProperty("name") val name: String, @@ -46,7 +44,8 @@ class ExtensionsViewModel : ViewModel() { val pluginStats: LiveData> = _pluginStats //TODO CACHE GET REQUESTS - fun loadStats() = viewModelScope.launchSafe { + // DO not use viewModelScope.launchSafe, it will ANR on slow internet + fun loadStats() = ioSafe { val urls = (getKey>(REPOSITORIES_KEY) ?: emptyArray()) + PREBUILT_REPOSITORIES @@ -61,6 +60,7 @@ class ExtensionsViewModel : ViewModel() { PluginManager.OnlinePluginData(savedData, onlineData) } }.flatten().distinctBy { it.onlineData.second.url } + val total = onlinePlugins.count() val disabled = outdatedPlugins.count { it.isDisabled } val downloadedTotal = outdatedPlugins.count() From c4295f55ae21923f8c6d56c18b8452ce50f06ed0 Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Fri, 23 Sep 2022 14:20:53 +0200 Subject: [PATCH 2/4] Fix internal plugin updater --- .../cloudstream3/mvvm/ArchComponentExt.kt | 7 +++ .../cloudstream3/plugins/PluginManager.kt | 62 +++++++++++++------ .../cloudstream3/plugins/RepositoryManager.kt | 20 +++++- 3 files changed, 69 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/mvvm/ArchComponentExt.kt b/app/src/main/java/com/lagradost/cloudstream3/mvvm/ArchComponentExt.kt index 5c3276fa..e5c03d64 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/mvvm/ArchComponentExt.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/mvvm/ArchComponentExt.kt @@ -15,6 +15,7 @@ import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext const val DEBUG_EXCEPTION = "THIS IS A DEBUG EXCEPTION!" +const val DEBUG_PRINT = "DEBUG PRINT" class DebugException(message: String) : Exception("$DEBUG_EXCEPTION\n$message") @@ -24,6 +25,12 @@ inline fun debugException(message: () -> String) { } } +inline fun debugPrint(tag: String = DEBUG_PRINT, message: () -> String) { + if (BuildConfig.DEBUG) { + Log.d(tag, message.invoke()) + } +} + inline fun debugWarning(message: () -> String) { if (BuildConfig.DEBUG) { logError(DebugException(message.invoke())) diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt index c4d1f66f..bf7e694c 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt @@ -8,12 +8,10 @@ import android.content.res.Resources import android.os.Environment import android.widget.Toast import android.content.Context -import android.content.Intent import android.os.Build import android.util.Log import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat -import androidx.core.net.toUri import com.fasterxml.jackson.annotation.JsonProperty import com.lagradost.cloudstream3.* import com.lagradost.cloudstream3.AcraApplication.Companion.getKey @@ -28,6 +26,7 @@ import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData import com.lagradost.cloudstream3.utils.VideoDownloadManager.sanitizeFilename import com.lagradost.cloudstream3.APIHolder.removePluginMapping import com.lagradost.cloudstream3.MainActivity.Companion.afterPluginsLoadedEvent +import com.lagradost.cloudstream3.mvvm.debugPrint import com.lagradost.cloudstream3.mvvm.logError import com.lagradost.cloudstream3.plugins.RepositoryManager.PREBUILT_REPOSITORIES import com.lagradost.cloudstream3.utils.Coroutines.ioSafe @@ -37,7 +36,6 @@ import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute import com.lagradost.cloudstream3.utils.extractorApis import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import org.acra.log.debug import java.io.File import java.io.InputStreamReader import java.util.* @@ -223,13 +221,14 @@ object PluginManager { // Iterates over all offline plugins, compares to remote repo and returns the plugins which are outdated val outdatedPlugins = getPluginsOnline().map { savedData -> - onlinePlugins.filter { onlineData -> savedData.internalName == onlineData.second.internalName } + onlinePlugins + .filter { onlineData -> savedData.internalName == onlineData.second.internalName } .map { onlineData -> OnlinePluginData(savedData, onlineData) } }.flatten().distinctBy { it.onlineData.second.url } - debug { + debugPrint { "Outdated plugins: ${outdatedPlugins.filter { it.isOutdated }}" } @@ -244,7 +243,7 @@ object PluginManager { activity, pluginData.onlineData.second.url, pluginData.savedData.internalName, - pluginData.onlineData.first + File(pluginData.savedData.filePath) ).let { success -> if (success) updatedPlugins.add(pluginData.onlineData.second.name) @@ -417,24 +416,45 @@ object PluginManager { ) + "." + name.hashCode() } + + /** + * Used for fresh installs + * */ suspend fun downloadAndLoadPlugin( activity: Activity, pluginUrl: String, internalName: String, repositoryUrl: String ): Boolean { - try { - val folderName = getPluginSanitizedFileName(repositoryUrl) // Guaranteed unique - val fileName = getPluginSanitizedFileName(internalName) - unloadPlugin("${activity.filesDir}/${ONLINE_PLUGINS_FOLDER}/${folderName}/$fileName.cs3") + val folderName = getPluginSanitizedFileName(repositoryUrl) // Guaranteed unique + val fileName = getPluginSanitizedFileName(internalName) + val file = File("${activity.filesDir}/${ONLINE_PLUGINS_FOLDER}/${folderName}/$fileName.cs3") + downloadAndLoadPlugin(activity, pluginUrl, internalName, file) + return true + } - Log.d(TAG, "Downloading plugin: $pluginUrl to $folderName/$fileName") + /** + * Used for updates. + * + * Uses a file instead of repository url, as extensions can get moved it is better to directly + * update the files instead of getting the filepath from repo url. + * */ + private suspend fun downloadAndLoadPlugin( + activity: Activity, + pluginUrl: String, + internalName: String, + file: File, + ): Boolean { + try { + unloadPlugin(file.absolutePath) + + Log.d(TAG, "Downloading plugin: $pluginUrl to ${file.absolutePath}") // The plugin file needs to be salted with the repository url hash as to allow multiple repositories with the same internal plugin names - val file = downloadPluginToFile(activity, pluginUrl, fileName, folderName) + val newFile = downloadPluginToFile(pluginUrl, file) return loadPlugin( activity, - file ?: return false, - PluginData(internalName, pluginUrl, true, file.absolutePath, PLUGIN_VERSION_NOT_SET) + newFile ?: return false, + PluginData(internalName, pluginUrl, true, newFile.absolutePath, PLUGIN_VERSION_NOT_SET) ) } catch (e: Exception) { logError(e) @@ -468,7 +488,8 @@ object PluginManager { // the NotificationChannel class is new and not in the support library if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { val name = EXTENSIONS_CHANNEL_NAME //getString(R.string.channel_name) - val descriptionText = EXTENSIONS_CHANNEL_DESCRIPT//getString(R.string.channel_description) + val descriptionText = + EXTENSIONS_CHANNEL_DESCRIPT//getString(R.string.channel_description) val importance = NotificationManager.IMPORTANCE_LOW val channel = NotificationChannel(EXTENSIONS_CHANNEL_ID, name, importance).apply { description = descriptionText @@ -479,10 +500,11 @@ object PluginManager { notificationManager.createNotificationChannel(channel) } } + private fun createNotification( context: Context, extensionNames: List - ): Notification? { + ): Notification? { try { if (extensionNames.isEmpty()) return null @@ -497,8 +519,10 @@ object PluginManager { .setColor(context.colorFromAttribute(R.attr.colorPrimary)) .setContentTitle(context.getString(R.string.plugins_updated, extensionNames.size)) .setSmallIcon(R.drawable.ic_baseline_extension_24) - .setStyle(NotificationCompat.BigTextStyle() - .bigText(content)) + .setStyle( + NotificationCompat.BigTextStyle() + .bigText(content) + ) .setContentText(content) if (!hasCreatedNotChanel) { @@ -508,7 +532,7 @@ object PluginManager { val notification = builder.build() with(NotificationManagerCompat.from(context)) { // notificationId is a unique int for each notification that you must define - notify((System.currentTimeMillis()/1000).toInt(), notification) + notify((System.currentTimeMillis() / 1000).toInt(), notification) } return notification } catch (e: Exception) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt index ee0b60b8..e3203787 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt @@ -84,7 +84,7 @@ object RepositoryManager { // Normal parsed function not working? // return response.parsedSafe() tryParseJson>(response.text)?.toList() ?: emptyList() - } catch (t : Throwable) { + } catch (t: Throwable) { logError(t) emptyList() } @@ -102,9 +102,27 @@ object RepositoryManager { }.flatten() } + suspend fun downloadPluginToFile( + pluginUrl: String, + file: File + ): File? { + return suspendSafeApiCall { + file.mkdirs() + + // Overwrite if exists + if (file.exists()) { file.delete() } + file.createNewFile() + + val body = app.get(pluginUrl).okhttpResponse.body + write(body.byteStream(), file.outputStream()) + file + } + } + suspend fun downloadPluginToFile( context: Context, pluginUrl: String, + /** Filename without .cs3 */ fileName: String, folder: String ): File? { From c714b77687c6c3751ef84ea864cafbae4c568080 Mon Sep 17 00:00:00 2001 From: Cloudburst <18114966+C10udburst@users.noreply.github.com> Date: Fri, 23 Sep 2022 16:32:38 +0200 Subject: [PATCH 3/4] add "material you" theme --- .../lagradost/cloudstream3/CommonActivity.kt | 2 ++ app/src/main/res/values-es/array.xml | 17 ++++------------ app/src/main/res/values-pl/array.xml | 4 ++++ app/src/main/res/values-tr/array.xml | 17 ++++------------ app/src/main/res/values-vi/array.xml | 16 ++++----------- app/src/main/res/values/array.xml | 4 ++++ app/src/main/res/values/styles.xml | 20 +++++++++++++++++++ 7 files changed, 42 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt b/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt index 49143498..6bd41f39 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/CommonActivity.kt @@ -166,12 +166,14 @@ object CommonActivity { "Light" -> R.style.LightMode "Amoled" -> R.style.AmoledMode "AmoledLight" -> R.style.AmoledModeLight + "Monet" -> R.style.MonetMode else -> R.style.AppTheme } val currentOverlayTheme = when (settingsManager.getString(act.getString(R.string.primary_color_key), "Normal")) { "Normal" -> R.style.OverlayPrimaryColorNormal + "Monet" -> R.style.OverlayPrimaryColorMonet "CarnationPink" -> R.style.OverlayPrimaryColorCarnationPink "DarkGreen" -> R.style.OverlayPrimaryColorDarkGreen "Maroon" -> R.style.OverlayPrimaryColorMaroon diff --git a/app/src/main/res/values-es/array.xml b/app/src/main/res/values-es/array.xml index 658ba7ae..47e747fd 100644 --- a/app/src/main/res/values-es/array.xml +++ b/app/src/main/res/values-es/array.xml @@ -14,19 +14,6 @@ @id/cast_button_type_forward_30_seconds - - Todos - Películas y TV - Anime - Documental - - - 0 - 1 - 2 - 3 - - @string/resolution_and_title @string/title @@ -207,6 +194,7 @@ Normal + Material You Rosa clavel Verde oscuro Vino @@ -225,6 +213,7 @@ Normal + Monet CarnationPink DarkGreen Maroon @@ -247,12 +236,14 @@ Gris Amoled Destello + Material You AmoledLight Black Amoled Light + Monet diff --git a/app/src/main/res/values-pl/array.xml b/app/src/main/res/values-pl/array.xml index c40b7f87..abf5b582 100644 --- a/app/src/main/res/values-pl/array.xml +++ b/app/src/main/res/values-pl/array.xml @@ -203,6 +203,7 @@ Normalny + Material You Goździk różowy Ciemnozielony Kasztanowaty @@ -221,6 +222,7 @@ Normal + Monet CarnationPink DarkGreen Maroon @@ -243,12 +245,14 @@ Szary Amoled Flashbang + Material You AmoledLight Black Amoled Light + Monet diff --git a/app/src/main/res/values-tr/array.xml b/app/src/main/res/values-tr/array.xml index ec9acd0e..e5bb2be2 100644 --- a/app/src/main/res/values-tr/array.xml +++ b/app/src/main/res/values-tr/array.xml @@ -14,19 +14,6 @@ @id/cast_button_type_forward_30_seconds - - Hepsi - Film ve Dizi - Anime - Belgesel - - - 0 - 1 - 2 - 3 - - @string/resolution_and_title @string/title @@ -207,6 +194,7 @@ Normal + Material You Karanfil Pembesi Koyu Yeşil Kestane @@ -225,6 +213,7 @@ Normal + Monet CarnationPink DarkGreen Maroon @@ -247,12 +236,14 @@ Gri Amoled Flaş Bombası + Material You AmoledLight Black Amoled Light + Monet diff --git a/app/src/main/res/values-vi/array.xml b/app/src/main/res/values-vi/array.xml index 5e70223b..dbdc7a0d 100644 --- a/app/src/main/res/values-vi/array.xml +++ b/app/src/main/res/values-vi/array.xml @@ -14,18 +14,6 @@ @id/cast_button_type_forward_30_seconds - - Tất cả - Phim lẻ và Phim bộ - Anime - Phim tài liệu - - - 0 - 1 - 2 - 3 - @string/resolution_and_title @@ -207,6 +195,7 @@ Mặc định + Material You Hồng nhạt Xanh lam đậm Nâu sẫm @@ -225,6 +214,7 @@ Normal + Monet CarnationPink DarkGreen Maroon @@ -247,12 +237,14 @@ Xám Amoled Sáng + Material You AmoledLight Black Amoled Light + Monet diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index 13d4f2dc..df97a741 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -213,6 +213,7 @@ Normal + Material You Carnation Pink Dark Green Maroon @@ -231,6 +232,7 @@ Normal + Monet CarnationPink DarkGreen Maroon @@ -253,12 +255,14 @@ Gray Amoled Flashbang + Material You AmoledLight Black Amoled Light + Monet diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 2fb9b5b4..26c6b36c 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -95,6 +95,16 @@ #000 + + + + + +