forked from recloudstream/cloudstream
Fixed loading disabled plugins on download
This commit is contained in:
parent
657971d008
commit
308affb6aa
4 changed files with 60 additions and 69 deletions
|
@ -255,11 +255,12 @@ object PluginManager {
|
||||||
//updatedPlugins.add(activity.getString(R.string.single_plugin_disabled, pluginData.onlineData.second.name))
|
//updatedPlugins.add(activity.getString(R.string.single_plugin_disabled, pluginData.onlineData.second.name))
|
||||||
unloadPlugin(pluginData.savedData.filePath)
|
unloadPlugin(pluginData.savedData.filePath)
|
||||||
} else if (pluginData.isOutdated) {
|
} else if (pluginData.isOutdated) {
|
||||||
downloadAndLoadPlugin(
|
downloadPlugin(
|
||||||
activity,
|
activity,
|
||||||
pluginData.onlineData.second.url,
|
pluginData.onlineData.second.url,
|
||||||
pluginData.savedData.internalName,
|
pluginData.savedData.internalName,
|
||||||
File(pluginData.savedData.filePath)
|
File(pluginData.savedData.filePath),
|
||||||
|
true
|
||||||
).let { success ->
|
).let { success ->
|
||||||
if (success)
|
if (success)
|
||||||
updatedPlugins.add(pluginData.onlineData.second.name)
|
updatedPlugins.add(pluginData.onlineData.second.name)
|
||||||
|
@ -341,11 +342,12 @@ object PluginManager {
|
||||||
//Log.i(TAG, "notDownloadedPlugins => ${notDownloadedPlugins.toJson()}")
|
//Log.i(TAG, "notDownloadedPlugins => ${notDownloadedPlugins.toJson()}")
|
||||||
|
|
||||||
notDownloadedPlugins.apmap { pluginData ->
|
notDownloadedPlugins.apmap { pluginData ->
|
||||||
downloadAndLoadPlugin(
|
downloadPlugin(
|
||||||
activity,
|
activity,
|
||||||
pluginData.onlineData.second.url,
|
pluginData.onlineData.second.url,
|
||||||
pluginData.savedData.internalName,
|
pluginData.savedData.internalName,
|
||||||
pluginData.onlineData.first
|
pluginData.onlineData.first,
|
||||||
|
!pluginData.isDisabled
|
||||||
).let { success ->
|
).let { success ->
|
||||||
if (success)
|
if (success)
|
||||||
newDownloadPlugins.add(pluginData.onlineData.second.name)
|
newDownloadPlugins.add(pluginData.onlineData.second.name)
|
||||||
|
@ -496,7 +498,7 @@ object PluginManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unloadPlugin(absolutePath: String) {
|
fun unloadPlugin(absolutePath: String) {
|
||||||
Log.i(TAG, "Unloading plugin: $absolutePath")
|
Log.i(TAG, "Unloading plugin: $absolutePath")
|
||||||
val plugin = plugins[absolutePath]
|
val plugin = plugins[absolutePath]
|
||||||
if (plugin == null) {
|
if (plugin == null) {
|
||||||
|
@ -547,49 +549,48 @@ object PluginManager {
|
||||||
return File("${context.filesDir}/${ONLINE_PLUGINS_FOLDER}/${folderName}/$fileName.cs3")
|
return File("${context.filesDir}/${ONLINE_PLUGINS_FOLDER}/${folderName}/$fileName.cs3")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
suspend fun downloadPlugin(
|
||||||
* Used for fresh installs
|
|
||||||
* */
|
|
||||||
suspend fun downloadAndLoadPlugin(
|
|
||||||
activity: Activity,
|
activity: Activity,
|
||||||
pluginUrl: String,
|
pluginUrl: String,
|
||||||
internalName: String,
|
internalName: String,
|
||||||
repositoryUrl: String
|
repositoryUrl: String,
|
||||||
|
loadPlugin: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val file = getPluginPath(activity, internalName, repositoryUrl)
|
val file = getPluginPath(activity, internalName, repositoryUrl)
|
||||||
downloadAndLoadPlugin(activity, pluginUrl, internalName, file)
|
return downloadPlugin(activity, pluginUrl, internalName, file, loadPlugin)
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
suspend fun downloadPlugin(
|
||||||
* 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,
|
activity: Activity,
|
||||||
pluginUrl: String,
|
pluginUrl: String,
|
||||||
internalName: String,
|
internalName: String,
|
||||||
file: File,
|
file: File,
|
||||||
|
loadPlugin: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
try {
|
try {
|
||||||
unloadPlugin(file.absolutePath)
|
|
||||||
|
|
||||||
Log.d(TAG, "Downloading plugin: $pluginUrl to ${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
|
// The plugin file needs to be salted with the repository url hash as to allow multiple repositories with the same internal plugin names
|
||||||
val newFile = downloadPluginToFile(pluginUrl, file)
|
val newFile = downloadPluginToFile(pluginUrl, file) ?: return false
|
||||||
return loadPlugin(
|
|
||||||
activity,
|
val data = PluginData(
|
||||||
newFile ?: return false,
|
|
||||||
PluginData(
|
|
||||||
internalName,
|
internalName,
|
||||||
pluginUrl,
|
pluginUrl,
|
||||||
true,
|
true,
|
||||||
newFile.absolutePath,
|
newFile.absolutePath,
|
||||||
PLUGIN_VERSION_NOT_SET
|
PLUGIN_VERSION_NOT_SET
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return if (loadPlugin) {
|
||||||
|
unloadPlugin(file.absolutePath)
|
||||||
|
loadPlugin(
|
||||||
|
activity,
|
||||||
|
newFile,
|
||||||
|
data
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
setPluginData(data)
|
||||||
|
true
|
||||||
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
logError(e)
|
logError(e)
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -7,8 +7,10 @@ import com.lagradost.cloudstream3.AcraApplication.Companion.setKey
|
||||||
import com.lagradost.cloudstream3.amap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.app
|
import com.lagradost.cloudstream3.app
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
import com.lagradost.cloudstream3.mvvm.logError
|
||||||
|
import com.lagradost.cloudstream3.mvvm.normalSafeApiCall
|
||||||
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
|
import com.lagradost.cloudstream3.mvvm.suspendSafeApiCall
|
||||||
import com.lagradost.cloudstream3.plugins.PluginManager.getPluginSanitizedFileName
|
import com.lagradost.cloudstream3.plugins.PluginManager.getPluginSanitizedFileName
|
||||||
|
import com.lagradost.cloudstream3.plugins.PluginManager.unloadPlugin
|
||||||
import com.lagradost.cloudstream3.ui.settings.extensions.REPOSITORIES_KEY
|
import com.lagradost.cloudstream3.ui.settings.extensions.REPOSITORIES_KEY
|
||||||
import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
|
import com.lagradost.cloudstream3.ui.settings.extensions.RepositoryData
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
import com.lagradost.cloudstream3.utils.AppUtils.tryParseJson
|
||||||
|
@ -132,7 +134,9 @@ object RepositoryManager {
|
||||||
file.mkdirs()
|
file.mkdirs()
|
||||||
|
|
||||||
// Overwrite if exists
|
// Overwrite if exists
|
||||||
if (file.exists()) { file.delete() }
|
if (file.exists()) {
|
||||||
|
file.delete()
|
||||||
|
}
|
||||||
file.createNewFile()
|
file.createNewFile()
|
||||||
|
|
||||||
val body = app.get(pluginUrl).okhttpResponse.body
|
val body = app.get(pluginUrl).okhttpResponse.body
|
||||||
|
@ -141,34 +145,6 @@ object RepositoryManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun downloadPluginToFile(
|
|
||||||
context: Context,
|
|
||||||
pluginUrl: String,
|
|
||||||
/** Filename without .cs3 */
|
|
||||||
fileName: String,
|
|
||||||
folder: String
|
|
||||||
): File? {
|
|
||||||
return suspendSafeApiCall {
|
|
||||||
val extensionsDir = File(context.filesDir, ONLINE_PLUGINS_FOLDER)
|
|
||||||
if (!extensionsDir.exists())
|
|
||||||
extensionsDir.mkdirs()
|
|
||||||
|
|
||||||
val newDir = File(extensionsDir, folder)
|
|
||||||
newDir.mkdirs()
|
|
||||||
|
|
||||||
val newFile = File(newDir, "${fileName}.cs3")
|
|
||||||
// Overwrite if exists
|
|
||||||
if (newFile.exists()) {
|
|
||||||
newFile.delete()
|
|
||||||
}
|
|
||||||
newFile.createNewFile()
|
|
||||||
|
|
||||||
val body = app.get(pluginUrl).okhttpResponse.body
|
|
||||||
write(body.byteStream(), newFile.outputStream())
|
|
||||||
newFile
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getRepositories(): Array<RepositoryData> {
|
fun getRepositories(): Array<RepositoryData> {
|
||||||
return getKey(REPOSITORIES_KEY) ?: emptyArray()
|
return getKey(REPOSITORIES_KEY) ?: emptyArray()
|
||||||
}
|
}
|
||||||
|
@ -200,9 +176,17 @@ object RepositoryManager {
|
||||||
extensionsDir,
|
extensionsDir,
|
||||||
getPluginSanitizedFileName(repository.url)
|
getPluginSanitizedFileName(repository.url)
|
||||||
)
|
)
|
||||||
PluginManager.deleteRepositoryData(file.absolutePath)
|
|
||||||
|
|
||||||
file.delete()
|
// Unload all plugins, not using deletePlugin since we
|
||||||
|
// delete all data and files in deleteRepositoryData
|
||||||
|
normalSafeApiCall {
|
||||||
|
file.listFiles { plugin: File ->
|
||||||
|
unloadPlugin(plugin.absolutePath)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PluginManager.deleteRepositoryData(file.absolutePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun write(stream: InputStream, output: OutputStream) {
|
private fun write(stream: InputStream, output: OutputStream) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.lagradost.cloudstream3.CommonActivity.showToast
|
import com.lagradost.cloudstream3.CommonActivity.showToast
|
||||||
|
import com.lagradost.cloudstream3.PROVIDER_STATUS_DOWN
|
||||||
import com.lagradost.cloudstream3.R
|
import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.amap
|
import com.lagradost.cloudstream3.amap
|
||||||
import com.lagradost.cloudstream3.mvvm.launchSafe
|
import com.lagradost.cloudstream3.mvvm.launchSafe
|
||||||
|
@ -102,11 +103,12 @@ class PluginsViewModel : ViewModel() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}.amap { (repo, metadata) ->
|
}.amap { (repo, metadata) ->
|
||||||
PluginManager.downloadAndLoadPlugin(
|
PluginManager.downloadPlugin(
|
||||||
activity,
|
activity,
|
||||||
metadata.url,
|
metadata.url,
|
||||||
metadata.internalName,
|
metadata.internalName,
|
||||||
repo
|
repo,
|
||||||
|
metadata.status != PROVIDER_STATUS_DOWN
|
||||||
)
|
)
|
||||||
}.main { list ->
|
}.main { list ->
|
||||||
if (list.any { it }) {
|
if (list.any { it }) {
|
||||||
|
@ -151,12 +153,15 @@ class PluginsViewModel : ViewModel() {
|
||||||
val (success, message) = if (file.exists()) {
|
val (success, message) = if (file.exists()) {
|
||||||
PluginManager.deletePlugin(file) to R.string.plugin_deleted
|
PluginManager.deletePlugin(file) to R.string.plugin_deleted
|
||||||
} else {
|
} else {
|
||||||
PluginManager.downloadAndLoadPlugin(
|
val isEnabled = plugin.second.status != PROVIDER_STATUS_DOWN
|
||||||
|
val message = if (isEnabled) R.string.plugin_loaded else R.string.plugin_downloaded
|
||||||
|
PluginManager.downloadPlugin(
|
||||||
activity,
|
activity,
|
||||||
metadata.url,
|
metadata.url,
|
||||||
metadata.name,
|
metadata.name,
|
||||||
repo
|
repo,
|
||||||
) to R.string.plugin_loaded
|
isEnabled
|
||||||
|
) to message
|
||||||
}
|
}
|
||||||
|
|
||||||
runOnMainThread {
|
runOnMainThread {
|
||||||
|
|
|
@ -539,6 +539,7 @@
|
||||||
<string name="repository_name_hint">Repository name</string>
|
<string name="repository_name_hint">Repository name</string>
|
||||||
<string name="repository_url_hint">Repository URL</string>
|
<string name="repository_url_hint">Repository URL</string>
|
||||||
<string name="plugin_loaded">Plugin Loaded</string>
|
<string name="plugin_loaded">Plugin Loaded</string>
|
||||||
|
<string name="plugin_downloaded">Plugin Downloaded</string>
|
||||||
<string name="plugin_deleted">Plugin Deleted</string>
|
<string name="plugin_deleted">Plugin Deleted</string>
|
||||||
<string name="plugin_load_fail" formatted="true">Could not load %s</string>
|
<string name="plugin_load_fail" formatted="true">Could not load %s</string>
|
||||||
<string name="is_adult">18+</string>
|
<string name="is_adult">18+</string>
|
||||||
|
|
Loading…
Reference in a new issue