mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-04-20 03:24:50 +00:00
ManagedDBSTore delete corrupted items, Fix serialized content serializer, Fix notifications wrong intent
This commit is contained in:
parent
7cde8ed538
commit
cbf2712654
15 changed files with 64 additions and 16 deletions
|
@ -6,9 +6,13 @@ import com.futo.platformplayer.api.media.models.locked.IPlatformLockedContent
|
|||
import com.futo.platformplayer.api.media.models.nested.IPlatformNestedContent
|
||||
import com.futo.platformplayer.api.media.models.post.IPlatformPost
|
||||
import com.futo.platformplayer.serializers.PlatformContentSerializer
|
||||
import kotlinx.serialization.EncodeDefault
|
||||
import kotlinx.serialization.SerialName
|
||||
|
||||
@kotlinx.serialization.Serializable(with = PlatformContentSerializer::class)
|
||||
interface SerializedPlatformContent: IPlatformContent {
|
||||
override val contentType: ContentType;
|
||||
|
||||
fun toJson() : String;
|
||||
fun fromJson(str : String) : SerializedPlatformContent;
|
||||
fun fromJsonArray(str : String) : Array<SerializedPlatformContent>;
|
||||
|
|
|
@ -30,7 +30,7 @@ open class SerializedPlatformLockedContent(
|
|||
override val unlockUrl: String? = null,
|
||||
override val contentThumbnails: Thumbnails
|
||||
) : IPlatformLockedContent, SerializedPlatformContent {
|
||||
final override val contentType: ContentType get() = ContentType.LOCKED;
|
||||
override val contentType: ContentType = ContentType.LOCKED;
|
||||
|
||||
override fun toJson() : String {
|
||||
return Json.encodeToString(this);
|
||||
|
|
|
@ -30,7 +30,7 @@ open class SerializedPlatformNestedContent(
|
|||
override val contentProvider: String?,
|
||||
override val contentThumbnails: Thumbnails
|
||||
) : IPlatformNestedContent, SerializedPlatformContent {
|
||||
final override val contentType: ContentType get() = ContentType.NESTED_VIDEO;
|
||||
final override val contentType: ContentType = ContentType.NESTED_VIDEO;
|
||||
|
||||
override val contentPlugin: String? = StatePlatform.instance.getContentClientOrNull(contentUrl)?.id;
|
||||
override val contentSupported: Boolean get() = contentPlugin != null;
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.futo.platformplayer.api.media.models.contents.ContentType
|
|||
import com.futo.platformplayer.api.media.models.post.IPlatformPost
|
||||
import com.futo.platformplayer.serializers.OffsetDateTimeNullableSerializer
|
||||
import com.futo.polycentric.core.combineHashCodes
|
||||
import kotlinx.serialization.EncodeDefault
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
|
@ -26,7 +27,7 @@ open class SerializedPlatformPost(
|
|||
override val thumbnails: List<Thumbnails?>,
|
||||
override val images: List<String>
|
||||
) : IPlatformPost, SerializedPlatformContent {
|
||||
final override val contentType: ContentType get() = ContentType.POST;
|
||||
override val contentType: ContentType = ContentType.POST;
|
||||
|
||||
override fun toJson() : String {
|
||||
return Json.encodeToString(this);
|
||||
|
|
|
@ -26,7 +26,7 @@ open class SerializedPlatformVideo(
|
|||
override val duration: Long,
|
||||
override val viewCount: Long,
|
||||
) : IPlatformVideo, SerializedPlatformContent {
|
||||
final override val contentType: ContentType get() = ContentType.MEDIA;
|
||||
override val contentType: ContentType = ContentType.MEDIA;
|
||||
|
||||
override val isLive: Boolean = false;
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ class BackgroundWorker(private val appContext: Context, private val workerParams
|
|||
//Only for testing notifications
|
||||
val testNotifs = 0;
|
||||
if(contentNotifs.size == 0 && testNotifs > 0) {
|
||||
results.first.getResults().filter { it is IPlatformVideo && it.datetime?.let { it < now } == true }
|
||||
results.first.getResults().filter { it is IPlatformVideo }
|
||||
.take(testNotifs).forEach {
|
||||
contentNotifs.add(Pair(StateSubscriptions.instance.getSubscriptions().first(), it));
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.futo.platformplayer.engine.internal.V8BindObject
|
|||
import com.futo.platformplayer.getOrThrow
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import java.net.SocketTimeoutException
|
||||
import kotlin.streams.asSequence
|
||||
import kotlin.streams.toList
|
||||
|
||||
class PackageHttp: V8Package {
|
||||
|
@ -171,7 +172,9 @@ class PackageHttp: V8Package {
|
|||
return@map it.first.requestWithBody(it.second.method, it.second.url, it.second.body!!, it.second.headers);
|
||||
else
|
||||
return@map it.first.request(it.second.method, it.second.url, it.second.headers);
|
||||
}.toList();
|
||||
}
|
||||
.asSequence()
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.futo.platformplayer.serializers
|
|||
import com.futo.platformplayer.api.media.models.contents.ContentType
|
||||
import com.futo.platformplayer.api.media.models.video.SerializedPlatformContent
|
||||
import com.futo.platformplayer.api.media.models.video.SerializedPlatformNestedContent
|
||||
import com.futo.platformplayer.api.media.models.video.SerializedPlatformPost
|
||||
import com.futo.platformplayer.api.media.models.video.SerializedPlatformVideo
|
||||
import kotlinx.serialization.DeserializationStrategy
|
||||
import kotlinx.serialization.json.*
|
||||
|
@ -22,7 +23,7 @@ class PlatformContentSerializer() : JsonContentPolymorphicSerializer<SerializedP
|
|||
"MEDIA" -> SerializedPlatformVideo.serializer();
|
||||
"NESTED_VIDEO" -> SerializedPlatformNestedContent.serializer();
|
||||
"ARTICLE" -> throw NotImplementedError("Articles not yet implemented");
|
||||
"POST" -> throw NotImplementedError("Post not yet implemented");
|
||||
"POST" -> SerializedPlatformPost.serializer();
|
||||
else -> throw NotImplementedError("Unknown Content Type Value: ${obj?.jsonPrimitive?.contentOrNull}")
|
||||
};
|
||||
else
|
||||
|
@ -30,7 +31,7 @@ class PlatformContentSerializer() : JsonContentPolymorphicSerializer<SerializedP
|
|||
ContentType.MEDIA.value -> SerializedPlatformVideo.serializer();
|
||||
ContentType.NESTED_VIDEO.value -> SerializedPlatformNestedContent.serializer();
|
||||
ContentType.ARTICLE.value -> throw NotImplementedError("Articles not yet implemented");
|
||||
ContentType.POST.value -> throw NotImplementedError("Post not yet implemented");
|
||||
ContentType.POST.value -> SerializedPlatformPost.serializer();
|
||||
else -> throw NotImplementedError("Unknown Content Type Value: ${obj?.jsonPrimitive?.int}")
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import android.net.NetworkRequest
|
|||
import android.net.Uri
|
||||
import android.provider.DocumentsContract
|
||||
import android.util.DisplayMetrics
|
||||
import android.util.Xml
|
||||
import androidx.documentfile.provider.DocumentFile
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
|
@ -22,6 +23,7 @@ import com.futo.platformplayer.R
|
|||
import com.futo.platformplayer.activities.CaptchaActivity
|
||||
import com.futo.platformplayer.activities.IWithResultLauncher
|
||||
import com.futo.platformplayer.activities.MainActivity
|
||||
import com.futo.platformplayer.api.media.models.video.SerializedPlatformContent
|
||||
import com.futo.platformplayer.api.media.models.video.SerializedPlatformVideo
|
||||
import com.futo.platformplayer.api.media.platforms.js.DevJSClient
|
||||
import com.futo.platformplayer.api.media.platforms.js.JSClient
|
||||
|
@ -37,9 +39,12 @@ import com.futo.platformplayer.logging.LogLevel
|
|||
import com.futo.platformplayer.logging.Logger
|
||||
import com.futo.platformplayer.models.HistoryVideo
|
||||
import com.futo.platformplayer.receivers.AudioNoisyReceiver
|
||||
import com.futo.platformplayer.serializers.PlatformContentSerializer
|
||||
import com.futo.platformplayer.services.DownloadService
|
||||
import com.futo.platformplayer.stores.FragmentedStorage
|
||||
import com.futo.platformplayer.stores.db.ManagedDBStore
|
||||
import com.futo.platformplayer.stores.db.types.DBHistory
|
||||
import com.futo.platformplayer.stores.v2.JsonStoreSerializer
|
||||
import com.futo.platformplayer.stores.v2.ManagedStore
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.serialization.decodeFromString
|
||||
|
@ -548,6 +553,7 @@ class StateApp {
|
|||
}
|
||||
*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun mainAppStartedWithExternalFiles(context: Context) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.futo.platformplayer.states
|
||||
|
||||
import com.futo.platformplayer.api.media.models.contents.ContentType
|
||||
import com.futo.platformplayer.api.media.models.contents.IPlatformContent
|
||||
import com.futo.platformplayer.api.media.models.video.SerializedPlatformContent
|
||||
import com.futo.platformplayer.api.media.structures.DedupContentPager
|
||||
|
@ -11,10 +12,15 @@ import com.futo.platformplayer.resolveChannelUrl
|
|||
import com.futo.platformplayer.serializers.PlatformContentSerializer
|
||||
import com.futo.platformplayer.stores.db.ManagedDBStore
|
||||
import com.futo.platformplayer.stores.db.types.DBSubscriptionCache
|
||||
import com.futo.platformplayer.stores.v2.JsonStoreSerializer
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.serialization.encodeToString
|
||||
import kotlinx.serialization.json.Json
|
||||
import java.time.OffsetDateTime
|
||||
import kotlin.streams.asSequence
|
||||
import kotlin.streams.toList
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
class StateCache {
|
||||
|
@ -34,6 +40,8 @@ class StateCache {
|
|||
|
||||
fun getChannelCachePager(channelUrl: String): IPager<IPlatformContent> {
|
||||
return _subscriptionCache.queryPager(DBSubscriptionCache.Index::channelUrl, channelUrl, 20) {
|
||||
if(it.objOrNull?.contentType == ContentType.POST)
|
||||
Logger.i(TAG, "FOUND CACHED POST\n (${it.objOrNull?.name})");
|
||||
it.obj;
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +64,10 @@ class StateCache {
|
|||
}.flatten().distinct();
|
||||
|
||||
Logger.i(TAG, "Subscriptions CachePager get pagers");
|
||||
val pagers = allUrls.parallelStream().map { getChannelCachePager(it) }.toList();
|
||||
val pagers = allUrls.parallelStream()
|
||||
.map { getChannelCachePager(it) }
|
||||
.asSequence()
|
||||
.toList();
|
||||
|
||||
Logger.i(TAG, "Subscriptions CachePager compiling");
|
||||
val pager = MultiChronoContentPager(pagers, false, 20);
|
||||
|
|
|
@ -117,7 +117,7 @@ class StateNotifications {
|
|||
.setContentText("${content.name}")
|
||||
.setSubText(content.datetime?.toHumanNowDiffStringMinDay())
|
||||
.setSilent(true)
|
||||
.setContentIntent(PendingIntent.getActivity(context, 0, MainActivity.getVideoIntent(context, content.url),
|
||||
.setContentIntent(PendingIntent.getActivity(context, content.hashCode(), MainActivity.getVideoIntent(context, content.url),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE))
|
||||
.setChannelId(notificationChannel.id);
|
||||
if(thumbnail != null) {
|
||||
|
|
|
@ -42,6 +42,7 @@ import kotlinx.coroutines.*
|
|||
import okhttp3.internal.concat
|
||||
import java.time.OffsetDateTime
|
||||
import kotlin.reflect.jvm.internal.impl.builtins.jvm.JavaToKotlinClassMap.PlatformMutabilityMapping
|
||||
import kotlin.streams.asSequence
|
||||
import kotlin.streams.toList
|
||||
|
||||
/***
|
||||
|
@ -389,6 +390,7 @@ class StatePlatform {
|
|||
}
|
||||
return@map homeResult;
|
||||
}
|
||||
.asSequence()
|
||||
.toList()
|
||||
.associateWith { 1f };
|
||||
|
||||
|
@ -709,6 +711,7 @@ class StatePlatform {
|
|||
}
|
||||
return@map results;
|
||||
}
|
||||
.asSequence()
|
||||
.toList();
|
||||
|
||||
val pager = MultiChronoContentPager(pagers.toTypedArray());
|
||||
|
|
|
@ -38,6 +38,7 @@ import java.util.concurrent.ForkJoinTask
|
|||
import kotlin.collections.ArrayList
|
||||
import kotlin.coroutines.resumeWithException
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlin.streams.asSequence
|
||||
import kotlin.streams.toList
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
|
@ -258,7 +259,9 @@ class StateSubscriptions {
|
|||
Pair(it, StatePolycentric.instance.getChannelUrls(it.channel.url, it.channel.id));
|
||||
else
|
||||
Pair(it, listOf(it.channel.url));
|
||||
}.toList().associate { it };
|
||||
}.asSequence()
|
||||
.toList()
|
||||
.associate { it };
|
||||
|
||||
val result = algo.getSubscriptions(subUrls);
|
||||
return Pair(result.pager, result.exceptions);
|
||||
|
|
|
@ -14,10 +14,15 @@ open class ManagedDBIndex<T> {
|
|||
|
||||
@Ignore
|
||||
private var _obj: T? = null;
|
||||
@Ignore
|
||||
var isCorrupted: Boolean = false;
|
||||
|
||||
@get:Ignore
|
||||
val obj: T get() = _obj ?: throw IllegalStateException("Attempted to access serialized object on a index-only instance");
|
||||
|
||||
@get:Ignore
|
||||
val objOrNull: T? get() = _obj;
|
||||
|
||||
fun setInstance(obj: T) {
|
||||
this._obj = obj;
|
||||
}
|
||||
|
|
|
@ -361,22 +361,33 @@ class ManagedDBStore<I: ManagedDBIndex<T>, T, D: ManagedDBDatabase<T, I, DA>, DA
|
|||
}
|
||||
|
||||
fun convertObject(index: I): T? {
|
||||
return index.obj ?: deserializeIndex(index).obj;
|
||||
return index.objOrNull ?: deserializeIndex(index).obj;
|
||||
}
|
||||
fun convertObjects(indexes: List<I>): List<T> {
|
||||
return indexes.mapNotNull { it.obj ?: convertObject(it) };
|
||||
return indexes.mapNotNull { it.objOrNull ?: convertObject(it) };
|
||||
}
|
||||
fun deserializeIndex(index: I): I {
|
||||
if(index.isCorrupted)
|
||||
return index;
|
||||
if(index.serialized == null) throw IllegalStateException("Cannot deserialize index-only items from [${name}]");
|
||||
val obj = _serializer.deserialize(_class, index.serialized!!);
|
||||
index.setInstance(obj);
|
||||
try {
|
||||
val obj = _serializer.deserialize(_class, index.serialized!!);
|
||||
index.setInstance(obj);
|
||||
}
|
||||
catch(ex: Throwable) {
|
||||
if(index.serialized != null && index.serialized!!.size > 0) {
|
||||
Logger.w("ManagedDBStore", "Corrupted object in ${name} found [${index.id}], deleting due to ${ex.message}", ex);
|
||||
index.isCorrupted = true;
|
||||
delete(index.id!!);
|
||||
}
|
||||
}
|
||||
index.serialized = null;
|
||||
return index;
|
||||
}
|
||||
fun deserializeIndexes(indexes: List<I>): List<I> {
|
||||
for(index in indexes)
|
||||
deserializeIndex(index);
|
||||
return indexes;
|
||||
return indexes.filter { !it.isCorrupted }
|
||||
}
|
||||
|
||||
fun serialize(obj: T): ByteArray {
|
||||
|
|
Loading…
Add table
Reference in a new issue