From 72dc24c455ab42b0030d8bab546679473cf0758b Mon Sep 17 00:00:00 2001 From: Blatzar <46196380+Blatzar@users.noreply.github.com> Date: Mon, 8 Aug 2022 20:14:57 +0200 Subject: [PATCH] Remove plugins when repo is deleted --- .../cloudstream3/plugins/PluginManager.kt | 18 +++++++---- .../cloudstream3/plugins/RepositoryManager.kt | 20 +++++++++++-- .../settings/extensions/ExtensionsFragment.kt | 30 +++++++++++++++---- app/src/main/res/values/strings.xml | 6 ++-- 4 files changed, 60 insertions(+), 14 deletions(-) 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 c52ca3c9..801910ea 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/PluginManager.kt @@ -249,17 +249,25 @@ object PluginManager { } } + /** + * Spits out a unique and safe filename based on name. + * Used for repo folders (using repo url) and plugin file names (using internalName) + * */ + fun getPluginSanitizedFileName(name: String): String { + return sanitizeFilename( + name, + true + ) + "." + name.hashCode() + } + suspend fun downloadAndLoadPlugin( activity: Activity, pluginUrl: String, internalName: String, repositoryUrl: String ): Boolean { - val folderName = (sanitizeFilename( - repositoryUrl, - true - ) + "." + repositoryUrl.hashCode()) // Guaranteed unique - val fileName = (sanitizeFilename(internalName, true) + "." + internalName.hashCode()) + val folderName = getPluginSanitizedFileName(repositoryUrl) // Guaranteed unique + val fileName = getPluginSanitizedFileName(internalName) Log.i(TAG, "Downloading plugin: $pluginUrl to $folderName/$fileName") // 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) 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 92fb9fe0..72573274 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/plugins/RepositoryManager.kt @@ -7,6 +7,7 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.setKey import com.lagradost.cloudstream3.apmapIndexed import com.lagradost.cloudstream3.app import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall +import com.lagradost.cloudstream3.plugins.PluginManager.getPluginSanitizedFileName import com.lagradost.cloudstream3.ui.settings.extensions.REPOSITORIES_KEY import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson @@ -89,7 +90,12 @@ object RepositoryManager { }.flatten() } - suspend fun downloadPluginToFile(context: Context, pluginUrl: String, fileName: String, folder: String): File? { + suspend fun downloadPluginToFile( + context: Context, + pluginUrl: String, + fileName: String, + folder: String + ): File? { return suspendSafeApiCall { val extensionsDir = File(context.filesDir, ONLINE_PLUGINS_FOLDER) if (!extensionsDir.exists()) @@ -121,13 +127,23 @@ object RepositoryManager { } } - suspend fun removeRepository(repository: RepositoryData) { + /** + * Also deletes downloaded repository plugins + * */ + suspend fun removeRepository(context: Context, repository: RepositoryData) { + val extensionsDir = File(context.filesDir, ONLINE_PLUGINS_FOLDER) + repoLock.withLock { val currentRepos = getKey>(REPOSITORIES_KEY) ?: emptyArray() // No duplicates val newRepos = currentRepos.filter { it.url != repository.url } setKey(REPOSITORIES_KEY, newRepos) } + + File( + extensionsDir, + getPluginSanitizedFileName(repository.url) + ).delete() } private fun write(stream: InputStream, output: OutputStream) { diff --git a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt index 4136c782..3276dd9a 100644 --- a/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt +++ b/app/src/main/java/com/lagradost/cloudstream3/ui/settings/extensions/ExtensionsFragment.kt @@ -2,6 +2,7 @@ package com.lagradost.cloudstream3.ui.settings.extensions import android.content.ClipboardManager import android.content.Context +import android.content.DialogInterface import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -17,13 +18,12 @@ import com.lagradost.cloudstream3.mvvm.observe import com.lagradost.cloudstream3.plugins.RepositoryManager import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.setUpToolbar import com.lagradost.cloudstream3.utils.Coroutines.ioSafe +import com.lagradost.cloudstream3.utils.Coroutines.main import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe -import com.lagradost.cloudstream3.utils.UIHelper.fixPaddingStatusbar import kotlinx.android.synthetic.main.add_repo_input.* import kotlinx.android.synthetic.main.add_repo_input.apply_btt import kotlinx.android.synthetic.main.add_repo_input.cancel_btt import kotlinx.android.synthetic.main.fragment_extensions.* -import kotlinx.android.synthetic.main.stream_input.* class ExtensionsFragment : Fragment() { override fun onCreateView( @@ -50,9 +50,29 @@ class ExtensionsFragment : Fragment() { putString(PLUGINS_BUNDLE_URL, it.url) }) }, { repo -> - ioSafe { - RepositoryManager.removeRepository(repo) - extensionViewModel.loadRepositories() + // Prompt user before deleting repo + main { + val builder = AlertDialog.Builder(context ?: view.context) + val dialogClickListener = + DialogInterface.OnClickListener { _, which -> + when (which) { + DialogInterface.BUTTON_POSITIVE -> { + ioSafe { + RepositoryManager.removeRepository(view.context, repo) + extensionViewModel.loadRepositories() + } + } + DialogInterface.BUTTON_NEGATIVE -> {} + } + } + + builder.setTitle(R.string.delete_repository) + .setMessage( + context?.getString(R.string.delete_repository_plugins) + ) + .setPositiveButton(R.string.delete, dialogClickListener) + .setNegativeButton(R.string.cancel, dialogClickListener) + .show() } }) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2c437cf5..d39d1eae 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -581,6 +581,8 @@ Downloaded %d %s successfully All %s already downloaded Batch download - plugin - plugins + plugin + plugins + This will also delete all repository plugins + Delete repository