mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-05-25 11:02:08 +02:00
WIP updating block for subscriptions
This commit is contained in:
parent
965e74c7e2
commit
dc9cc7b00f
@ -19,6 +19,7 @@ import com.futo.platformplayer.stores.PluginIconStorage
|
|||||||
import com.futo.platformplayer.stores.PluginScriptsDirectory
|
import com.futo.platformplayer.stores.PluginScriptsDirectory
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -47,6 +48,8 @@ class StatePlugins {
|
|||||||
|
|
||||||
private var _updatesAvailableMap: HashSet<String> = hashSetOf();
|
private var _updatesAvailableMap: HashSet<String> = hashSetOf();
|
||||||
|
|
||||||
|
private val _isUpdating: HashSet<String> = hashSetOf();
|
||||||
|
|
||||||
fun getPluginIconOrNull(id: String): ImageVariable? {
|
fun getPluginIconOrNull(id: String): ImageVariable? {
|
||||||
if(iconsDir.hasIcon(id))
|
if(iconsDir.hasIcon(id))
|
||||||
return iconsDir.getIconBinary(id);
|
return iconsDir.getIconBinary(id);
|
||||||
@ -58,6 +61,38 @@ class StatePlugins {
|
|||||||
.load();
|
.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isUpdating(id: String): Boolean{
|
||||||
|
synchronized(_isUpdating){
|
||||||
|
return _isUpdating.contains(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun setIsUpdating(id: String, value: Boolean){
|
||||||
|
synchronized(_isUpdating){
|
||||||
|
if(value && !_isUpdating.contains(id)) {
|
||||||
|
Logger.i(TAG, "PLUGIN [${id}] UPDATING");
|
||||||
|
_isUpdating.add(id);
|
||||||
|
}
|
||||||
|
if(!value && _isUpdating.contains(id)) {
|
||||||
|
Logger.i(TAG, "PLUGIN [${id}] NOT UPDATING");
|
||||||
|
_isUpdating.remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
suspend fun whileUpdating(id: String, handle: suspend ()->Unit){
|
||||||
|
try {
|
||||||
|
setIsUpdating(id, true);
|
||||||
|
handle();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
setIsUpdating(id, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun clearUpdating(){
|
||||||
|
synchronized(_isUpdating) {
|
||||||
|
_isUpdating.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
suspend fun checkForUpdates(): List<Pair<SourcePluginConfig, SourcePluginConfig>> = withContext(Dispatchers.IO) {
|
suspend fun checkForUpdates(): List<Pair<SourcePluginConfig, SourcePluginConfig>> = withContext(Dispatchers.IO) {
|
||||||
var configs = mutableListOf<Pair<SourcePluginConfig, SourcePluginConfig>>()
|
var configs = mutableListOf<Pair<SourcePluginConfig, SourcePluginConfig>>()
|
||||||
@ -430,42 +465,49 @@ class StatePlugins {
|
|||||||
|
|
||||||
fun installPluginBackground(context: Context, scope: CoroutineScope, config: SourcePluginConfig, script: String, onProgress: (text: String, progress: Double)->Unit, onConcluded: (ex: Throwable?)->Unit) {
|
fun installPluginBackground(context: Context, scope: CoroutineScope, config: SourcePluginConfig, script: String, onProgress: (text: String, progress: Double)->Unit, onConcluded: (ex: Throwable?)->Unit) {
|
||||||
scope.launch(Dispatchers.IO) {
|
scope.launch(Dispatchers.IO) {
|
||||||
val client = ManagedHttpClient();
|
whileUpdating(config.id) {
|
||||||
try {
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
onProgress.invoke("Validating script", 0.25);
|
onProgress.invoke("Waiting for plugins to finish", 0.1);
|
||||||
}
|
}
|
||||||
|
delay(500);
|
||||||
|
|
||||||
val tempDescriptor = SourcePluginDescriptor(config);
|
val client = ManagedHttpClient();
|
||||||
val plugin = JSClient(context, tempDescriptor, null, script);
|
try {
|
||||||
plugin.validate();
|
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
onProgress.invoke("Downloading Icon", 0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
val icon = config.absoluteIconUrl?.let { absIconUrl ->
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
onProgress.invoke("Saving plugin", 0.75);
|
onProgress.invoke("Validating script", 0.25);
|
||||||
}
|
}
|
||||||
val iconResp = client.get(absIconUrl);
|
|
||||||
if(iconResp.isOk)
|
|
||||||
return@let iconResp.body?.byteStream()?.use { it.readBytes() };
|
|
||||||
return@let null;
|
|
||||||
}
|
|
||||||
val installEx = StatePlugins.instance.createPlugin(config, script, icon, true);
|
|
||||||
if(installEx != null)
|
|
||||||
throw installEx;
|
|
||||||
StatePlatform.instance.updateAvailableClients(context);
|
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
val tempDescriptor = SourcePluginDescriptor(config);
|
||||||
onProgress.invoke("Finished", 1.0)
|
val plugin = JSClient(context, tempDescriptor, null, script);
|
||||||
onConcluded.invoke(null);
|
plugin.validate();
|
||||||
}
|
|
||||||
} catch (ex: Exception) {
|
withContext(Dispatchers.Main) {
|
||||||
Logger.e(TAG, ex.message ?: "null", ex);
|
onProgress.invoke("Downloading Icon", 0.5);
|
||||||
withContext(Dispatchers.Main) {
|
}
|
||||||
onConcluded.invoke(ex);
|
|
||||||
|
val icon = config.absoluteIconUrl?.let { absIconUrl ->
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
onProgress.invoke("Saving plugin", 0.75);
|
||||||
|
}
|
||||||
|
val iconResp = client.get(absIconUrl);
|
||||||
|
if (iconResp.isOk)
|
||||||
|
return@let iconResp.body?.byteStream()?.use { it.readBytes() };
|
||||||
|
return@let null;
|
||||||
|
}
|
||||||
|
val installEx = StatePlugins.instance.createPlugin(config, script, icon, true);
|
||||||
|
if (installEx != null)
|
||||||
|
throw installEx;
|
||||||
|
StatePlatform.instance.updateAvailableClients(context);
|
||||||
|
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
onProgress.invoke("Finished", 1.0)
|
||||||
|
onConcluded.invoke(null);
|
||||||
|
}
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
Logger.e(TAG, ex.message ?: "null", ex);
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
onConcluded.invoke(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import com.futo.platformplayer.models.Subscription
|
|||||||
import com.futo.platformplayer.states.StateApp
|
import com.futo.platformplayer.states.StateApp
|
||||||
import com.futo.platformplayer.states.StateCache
|
import com.futo.platformplayer.states.StateCache
|
||||||
import com.futo.platformplayer.states.StatePlatform
|
import com.futo.platformplayer.states.StatePlatform
|
||||||
|
import com.futo.platformplayer.states.StatePlugins
|
||||||
import com.futo.platformplayer.states.StateSubscriptions
|
import com.futo.platformplayer.states.StateSubscriptions
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import java.time.OffsetDateTime
|
import java.time.OffsetDateTime
|
||||||
@ -138,6 +139,18 @@ abstract class SubscriptionsTaskFetchAlgorithm(
|
|||||||
|
|
||||||
for(task in tasks) {
|
for(task in tasks) {
|
||||||
val forkTask = threadPool.submit<SubscriptionTaskResult> {
|
val forkTask = threadPool.submit<SubscriptionTaskResult> {
|
||||||
|
if(StatePlugins.instance.isUpdating(task.client.id)){
|
||||||
|
val isUpdatingException = ScriptCriticalException(task.client.config, "Plugin is updating");
|
||||||
|
synchronized(failedPlugins) {
|
||||||
|
//Fail all subscription calls to plugin if it has a critical issue
|
||||||
|
if(isUpdatingException.config is SourcePluginConfig && !failedPlugins.contains(isUpdatingException.config.id)) {
|
||||||
|
Logger.w(StateSubscriptions.TAG, "Subscriptions ignoring plugin [${isUpdatingException.config.name}] due to critical exception:\n" + isUpdatingException.message);
|
||||||
|
failedPlugins.add(isUpdatingException.config.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return@submit SubscriptionTaskResult(task, StateCache.instance.getChannelCachePager(task.sub.channel.url), isUpdatingException);
|
||||||
|
}
|
||||||
|
|
||||||
if(task.fromPeek) {
|
if(task.fromPeek) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user