Remove plugins when repo is deleted

This commit is contained in:
Blatzar 2022-08-08 20:14:57 +02:00
parent 32d9aea02c
commit 72dc24c455
4 changed files with 60 additions and 14 deletions

View File

@ -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)

View File

@ -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<Array<RepositoryData>>(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) {

View File

@ -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()
}
})

View File

@ -581,6 +581,8 @@
<string name="batch_download_finish_format" formatted="true">Downloaded %d %s successfully</string>
<string name="batch_download_nothing_to_download_format" formatted="true">All %s already downloaded</string>
<string name="batch_download">Batch download</string>
<string name="plugin_singular" formatted="true">plugin</string>
<string name="plugin" formatted="true">plugins</string>
<string name="plugin_singular">plugin</string>
<string name="plugin">plugins</string>
<string name="delete_repository_plugins">This will also delete all repository plugins</string>
<string name="delete_repository">Delete repository</string>
</resources>