From 60706c2d874a2af99006afa8314be22b26616013 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Thu, 19 Jan 2023 14:08:21 +0530 Subject: [PATCH] Remove remaining Jackson code. --- app/build.gradle | 4 +- .../com/github/libretube/api/JsonHelper.kt | 9 +++ .../github/libretube/api/RetrofitInstance.kt | 12 +-- .../github/libretube/db/obj/CustomInstance.kt | 2 + .../github/libretube/db/obj/LocalPlaylist.kt | 2 + .../libretube/db/obj/LocalPlaylistItem.kt | 2 + .../db/obj/LocalPlaylistWithVideos.kt | 2 + .../libretube/db/obj/LocalSubscription.kt | 2 + .../libretube/db/obj/PlaylistBookmark.kt | 2 + .../libretube/db/obj/SearchHistoryItem.kt | 2 + .../libretube/db/obj/WatchHistoryItem.kt | 2 + .../github/libretube/db/obj/WatchPosition.kt | 2 + .../com/github/libretube/obj/BackupFile.kt | 18 +++-- .../libretube/obj/ImportPlaylistFile.kt | 2 +- .../libretube/obj/NewPipeSubscription.kt | 3 + .../libretube/obj/NewPipeSubscriptions.kt | 5 +- .../github/libretube/obj/PreferenceItem.kt | 7 +- .../com/github/libretube/obj/update/Asset.kt | 4 +- .../libretube/services/BackgroundMode.kt | 12 +-- .../libretube/ui/dialogs/BackupDialog.kt | 12 ++- .../libretube/ui/fragments/PlayerFragment.kt | 5 +- .../ui/preferences/BackupRestoreSettings.kt | 2 +- .../com/github/libretube/util/BackupHelper.kt | 75 ++++++++++--------- .../com/github/libretube/util/ImportHelper.kt | 42 +++++------ .../github/libretube/util/MetadataHelper.kt | 48 ------------ gradle/libs.versions.toml | 3 - 26 files changed, 136 insertions(+), 145 deletions(-) create mode 100644 app/src/main/java/com/github/libretube/api/JsonHelper.kt delete mode 100644 app/src/main/java/com/github/libretube/util/MetadataHelper.kt diff --git a/app/build.gradle b/app/build.gradle index d6940de7f..71d600d86 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -108,10 +108,8 @@ dependencies { implementation libs.exoplayer.extension.mediasession implementation libs.exoplayer.dash - /* Retrofit and Jackson */ + /* Retrofit and Kotlinx Serialization */ implementation libs.square.retrofit - implementation libs.square.retrofit.converterJackson - implementation libs.jacksonAnnotations implementation libs.kotlinx.serialization implementation libs.kotlinx.datetime implementation libs.kotlinx.serialization.retrofit diff --git a/app/src/main/java/com/github/libretube/api/JsonHelper.kt b/app/src/main/java/com/github/libretube/api/JsonHelper.kt new file mode 100644 index 000000000..bc44741c2 --- /dev/null +++ b/app/src/main/java/com/github/libretube/api/JsonHelper.kt @@ -0,0 +1,9 @@ +package com.github.libretube.api + +import kotlinx.serialization.json.Json + +object JsonHelper { + val json = Json { + ignoreUnknownKeys = true + } +} diff --git a/app/src/main/java/com/github/libretube/api/RetrofitInstance.kt b/app/src/main/java/com/github/libretube/api/RetrofitInstance.kt index 2d95c2b52..743280989 100644 --- a/app/src/main/java/com/github/libretube/api/RetrofitInstance.kt +++ b/app/src/main/java/com/github/libretube/api/RetrofitInstance.kt @@ -4,28 +4,22 @@ import com.github.libretube.constants.PIPED_API_URL import com.github.libretube.constants.PreferenceKeys import com.github.libretube.util.PreferenceHelper import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory -import kotlinx.serialization.json.Json import okhttp3.MediaType.Companion.toMediaType import retrofit2.Retrofit -import retrofit2.converter.jackson.JacksonConverterFactory import retrofit2.create object RetrofitInstance { lateinit var url: String lateinit var authUrl: String val lazyMgr = resettableManager() - private val jacksonConverterFactory = JacksonConverterFactory.create() - private val json = Json { - ignoreUnknownKeys = true - } - private val kotlinxConverterFactory = json.asConverterFactory("application/json".toMediaType()) + private val kotlinxConverterFactory = JsonHelper.json + .asConverterFactory("application/json".toMediaType()) val api by resettableLazy(lazyMgr) { Retrofit.Builder() .baseUrl(url) .callFactory(CronetHelper.callFactory) .addConverterFactory(kotlinxConverterFactory) - .addConverterFactory(jacksonConverterFactory) .build() .create() } @@ -35,7 +29,6 @@ object RetrofitInstance { .baseUrl(authUrl) .callFactory(CronetHelper.callFactory) .addConverterFactory(kotlinxConverterFactory) - .addConverterFactory(jacksonConverterFactory) .build() .create() } @@ -45,7 +38,6 @@ object RetrofitInstance { .baseUrl(url) .callFactory(CronetHelper.callFactory) .addConverterFactory(kotlinxConverterFactory) - .addConverterFactory(jacksonConverterFactory) .build() .create() } diff --git a/app/src/main/java/com/github/libretube/db/obj/CustomInstance.kt b/app/src/main/java/com/github/libretube/db/obj/CustomInstance.kt index 189b24a79..e2d9d9249 100644 --- a/app/src/main/java/com/github/libretube/db/obj/CustomInstance.kt +++ b/app/src/main/java/com/github/libretube/db/obj/CustomInstance.kt @@ -3,7 +3,9 @@ package com.github.libretube.db.obj import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey +import kotlinx.serialization.Serializable +@Serializable @Entity(tableName = "customInstance") class CustomInstance( @PrimaryKey var name: String = "", diff --git a/app/src/main/java/com/github/libretube/db/obj/LocalPlaylist.kt b/app/src/main/java/com/github/libretube/db/obj/LocalPlaylist.kt index 5e027a953..3ef94118b 100644 --- a/app/src/main/java/com/github/libretube/db/obj/LocalPlaylist.kt +++ b/app/src/main/java/com/github/libretube/db/obj/LocalPlaylist.kt @@ -2,7 +2,9 @@ package com.github.libretube.db.obj import androidx.room.Entity import androidx.room.PrimaryKey +import kotlinx.serialization.Serializable +@Serializable @Entity data class LocalPlaylist( @PrimaryKey(autoGenerate = true) diff --git a/app/src/main/java/com/github/libretube/db/obj/LocalPlaylistItem.kt b/app/src/main/java/com/github/libretube/db/obj/LocalPlaylistItem.kt index c87db7b9c..f19effde5 100644 --- a/app/src/main/java/com/github/libretube/db/obj/LocalPlaylistItem.kt +++ b/app/src/main/java/com/github/libretube/db/obj/LocalPlaylistItem.kt @@ -3,7 +3,9 @@ package com.github.libretube.db.obj import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey +import kotlinx.serialization.Serializable +@Serializable @Entity data class LocalPlaylistItem( @PrimaryKey(autoGenerate = true) val id: Int = 0, diff --git a/app/src/main/java/com/github/libretube/db/obj/LocalPlaylistWithVideos.kt b/app/src/main/java/com/github/libretube/db/obj/LocalPlaylistWithVideos.kt index 012617adf..671b477bd 100644 --- a/app/src/main/java/com/github/libretube/db/obj/LocalPlaylistWithVideos.kt +++ b/app/src/main/java/com/github/libretube/db/obj/LocalPlaylistWithVideos.kt @@ -2,7 +2,9 @@ package com.github.libretube.db.obj import androidx.room.Embedded import androidx.room.Relation +import kotlinx.serialization.Serializable +@Serializable data class LocalPlaylistWithVideos( @Embedded val playlist: LocalPlaylist = LocalPlaylist(), @Relation( diff --git a/app/src/main/java/com/github/libretube/db/obj/LocalSubscription.kt b/app/src/main/java/com/github/libretube/db/obj/LocalSubscription.kt index 681779ad0..3fe2a1abb 100644 --- a/app/src/main/java/com/github/libretube/db/obj/LocalSubscription.kt +++ b/app/src/main/java/com/github/libretube/db/obj/LocalSubscription.kt @@ -2,7 +2,9 @@ package com.github.libretube.db.obj import androidx.room.Entity import androidx.room.PrimaryKey +import kotlinx.serialization.Serializable +@Serializable @Entity(tableName = "localSubscription") data class LocalSubscription( @PrimaryKey val channelId: String = "" diff --git a/app/src/main/java/com/github/libretube/db/obj/PlaylistBookmark.kt b/app/src/main/java/com/github/libretube/db/obj/PlaylistBookmark.kt index 328270830..b44e0f5b2 100644 --- a/app/src/main/java/com/github/libretube/db/obj/PlaylistBookmark.kt +++ b/app/src/main/java/com/github/libretube/db/obj/PlaylistBookmark.kt @@ -2,7 +2,9 @@ package com.github.libretube.db.obj import androidx.room.Entity import androidx.room.PrimaryKey +import kotlinx.serialization.Serializable +@Serializable @Entity(tableName = "playlistBookmark") data class PlaylistBookmark( @PrimaryKey diff --git a/app/src/main/java/com/github/libretube/db/obj/SearchHistoryItem.kt b/app/src/main/java/com/github/libretube/db/obj/SearchHistoryItem.kt index 6a7d0d3c2..d677d2dbc 100644 --- a/app/src/main/java/com/github/libretube/db/obj/SearchHistoryItem.kt +++ b/app/src/main/java/com/github/libretube/db/obj/SearchHistoryItem.kt @@ -2,7 +2,9 @@ package com.github.libretube.db.obj import androidx.room.Entity import androidx.room.PrimaryKey +import kotlinx.serialization.Serializable +@Serializable @Entity(tableName = "searchHistoryItem") data class SearchHistoryItem( @PrimaryKey val query: String = "" diff --git a/app/src/main/java/com/github/libretube/db/obj/WatchHistoryItem.kt b/app/src/main/java/com/github/libretube/db/obj/WatchHistoryItem.kt index 45da337df..01a8bdd74 100644 --- a/app/src/main/java/com/github/libretube/db/obj/WatchHistoryItem.kt +++ b/app/src/main/java/com/github/libretube/db/obj/WatchHistoryItem.kt @@ -3,7 +3,9 @@ package com.github.libretube.db.obj import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey +import kotlinx.serialization.Serializable +@Serializable @Entity(tableName = "watchHistoryItem") data class WatchHistoryItem( @PrimaryKey val videoId: String = "", diff --git a/app/src/main/java/com/github/libretube/db/obj/WatchPosition.kt b/app/src/main/java/com/github/libretube/db/obj/WatchPosition.kt index bf6a77396..2f6f0e050 100644 --- a/app/src/main/java/com/github/libretube/db/obj/WatchPosition.kt +++ b/app/src/main/java/com/github/libretube/db/obj/WatchPosition.kt @@ -3,7 +3,9 @@ package com.github.libretube.db.obj import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey +import kotlinx.serialization.Serializable +@Serializable @Entity(tableName = "watchPosition") data class WatchPosition( @PrimaryKey val videoId: String = "", diff --git a/app/src/main/java/com/github/libretube/obj/BackupFile.kt b/app/src/main/java/com/github/libretube/obj/BackupFile.kt index 82e8a75ec..958b04b64 100644 --- a/app/src/main/java/com/github/libretube/obj/BackupFile.kt +++ b/app/src/main/java/com/github/libretube/obj/BackupFile.kt @@ -7,14 +7,16 @@ import com.github.libretube.db.obj.PlaylistBookmark import com.github.libretube.db.obj.SearchHistoryItem import com.github.libretube.db.obj.WatchHistoryItem import com.github.libretube.db.obj.WatchPosition +import kotlinx.serialization.Serializable +@Serializable data class BackupFile( - var watchHistory: List? = null, - var watchPositions: List? = null, - var searchHistory: List? = null, - var localSubscriptions: List? = null, - var customInstances: List? = null, - var playlistBookmarks: List? = null, - var localPlaylists: List? = null, - var preferences: List? = null + var watchHistory: List = emptyList(), + var watchPositions: List = emptyList(), + var searchHistory: List = emptyList(), + var localSubscriptions: List = emptyList(), + var customInstances: List = emptyList(), + var playlistBookmarks: List = emptyList(), + var localPlaylists: List = emptyList(), + var preferences: List = emptyList() ) diff --git a/app/src/main/java/com/github/libretube/obj/ImportPlaylistFile.kt b/app/src/main/java/com/github/libretube/obj/ImportPlaylistFile.kt index 43f9ff4a0..7b531a584 100644 --- a/app/src/main/java/com/github/libretube/obj/ImportPlaylistFile.kt +++ b/app/src/main/java/com/github/libretube/obj/ImportPlaylistFile.kt @@ -3,5 +3,5 @@ package com.github.libretube.obj data class ImportPlaylistFile( val format: String? = null, val version: Int? = null, - val playlists: List? = null + val playlists: List = emptyList() ) diff --git a/app/src/main/java/com/github/libretube/obj/NewPipeSubscription.kt b/app/src/main/java/com/github/libretube/obj/NewPipeSubscription.kt index 1db358271..041703fdc 100644 --- a/app/src/main/java/com/github/libretube/obj/NewPipeSubscription.kt +++ b/app/src/main/java/com/github/libretube/obj/NewPipeSubscription.kt @@ -1,5 +1,8 @@ package com.github.libretube.obj +import kotlinx.serialization.Serializable + +@Serializable data class NewPipeSubscription( val name: String? = null, val service_id: Int? = null, diff --git a/app/src/main/java/com/github/libretube/obj/NewPipeSubscriptions.kt b/app/src/main/java/com/github/libretube/obj/NewPipeSubscriptions.kt index 9c19551d2..edea052fd 100644 --- a/app/src/main/java/com/github/libretube/obj/NewPipeSubscriptions.kt +++ b/app/src/main/java/com/github/libretube/obj/NewPipeSubscriptions.kt @@ -1,7 +1,10 @@ package com.github.libretube.obj +import kotlinx.serialization.Serializable + +@Serializable data class NewPipeSubscriptions( val app_version: String = "", val app_version_int: Int = 0, - val subscriptions: List? = null + val subscriptions: List = emptyList() ) diff --git a/app/src/main/java/com/github/libretube/obj/PreferenceItem.kt b/app/src/main/java/com/github/libretube/obj/PreferenceItem.kt index 7c547fea2..25bfd7ad4 100644 --- a/app/src/main/java/com/github/libretube/obj/PreferenceItem.kt +++ b/app/src/main/java/com/github/libretube/obj/PreferenceItem.kt @@ -1,6 +1,11 @@ package com.github.libretube.obj +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonNull +import kotlinx.serialization.json.JsonPrimitive + +@Serializable data class PreferenceItem( val key: String? = null, - val value: Any? = null + val value: JsonPrimitive = JsonNull ) diff --git a/app/src/main/java/com/github/libretube/obj/update/Asset.kt b/app/src/main/java/com/github/libretube/obj/update/Asset.kt index 2f00db85c..19102970f 100644 --- a/app/src/main/java/com/github/libretube/obj/update/Asset.kt +++ b/app/src/main/java/com/github/libretube/obj/update/Asset.kt @@ -3,6 +3,8 @@ package com.github.libretube.obj.update import kotlinx.datetime.Instant import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonNull @Serializable data class Asset( @@ -11,7 +13,7 @@ data class Asset( @SerialName("created_at") val createdAt: Instant, @SerialName("download_count") val downloadCount: Int, val id: Int, - val label: String? = null, + val label: JsonElement = JsonNull, val name: String, @SerialName("node_id") val nodeId: String, val size: Int, diff --git a/app/src/main/java/com/github/libretube/services/BackgroundMode.kt b/app/src/main/java/com/github/libretube/services/BackgroundMode.kt index dd9e0dbb8..46e8059d0 100644 --- a/app/src/main/java/com/github/libretube/services/BackgroundMode.kt +++ b/app/src/main/java/com/github/libretube/services/BackgroundMode.kt @@ -13,8 +13,8 @@ import android.os.Looper import android.util.Log import android.widget.Toast import androidx.core.app.ServiceCompat -import com.fasterxml.jackson.databind.ObjectMapper import com.github.libretube.R +import com.github.libretube.api.JsonHelper import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.obj.Segment import com.github.libretube.api.obj.SegmentData @@ -43,6 +43,7 @@ import com.google.android.exoplayer2.audio.AudioAttributes import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.serialization.encodeToString /** * Loads the selected videos audio in background mode with a notification area. @@ -335,11 +336,10 @@ class BackgroundMode : Service() { runCatching { val categories = PlayerHelper.getSponsorBlockCategories() if (categories.isEmpty()) return@runCatching - segmentData = - RetrofitInstance.api.getSegments( - videoId, - ObjectMapper().writeValueAsString(categories) - ) + segmentData = RetrofitInstance.api.getSegments( + videoId, + JsonHelper.json.encodeToString(categories) + ) checkForSegments() } } diff --git a/app/src/main/java/com/github/libretube/ui/dialogs/BackupDialog.kt b/app/src/main/java/com/github/libretube/ui/dialogs/BackupDialog.kt index 12e1ab34d..9518fbcc5 100644 --- a/app/src/main/java/com/github/libretube/ui/dialogs/BackupDialog.kt +++ b/app/src/main/java/com/github/libretube/ui/dialogs/BackupDialog.kt @@ -11,6 +11,8 @@ import com.github.libretube.obj.BackupFile import com.github.libretube.obj.PreferenceItem import com.github.libretube.util.PreferenceHelper import com.google.android.material.dialog.MaterialAlertDialogBuilder +import kotlinx.serialization.json.JsonNull +import kotlinx.serialization.json.JsonPrimitive class BackupDialog( private val createBackupFile: (BackupFile) -> Unit @@ -45,8 +47,14 @@ class BackupDialog( }) object Preferences : BackupOption(R.string.preferences, onSelected = { file -> - file.preferences = PreferenceHelper.settings.all.map { - PreferenceItem(it.key, it.value) + file.preferences = PreferenceHelper.settings.all.map { (key, value) -> + val jsonValue = when (value) { + is Number -> JsonPrimitive(value) + is Boolean -> JsonPrimitive(value) + is String -> JsonPrimitive(value) + else -> JsonNull + } + PreferenceItem(key, jsonValue) } }) } diff --git a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt index 4f468efb2..82648596b 100644 --- a/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt +++ b/app/src/main/java/com/github/libretube/ui/fragments/PlayerFragment.kt @@ -34,9 +34,9 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager -import com.fasterxml.jackson.databind.ObjectMapper import com.github.libretube.R import com.github.libretube.api.CronetHelper +import com.github.libretube.api.JsonHelper import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.obj.ChapterSegment import com.github.libretube.api.obj.PipedStream @@ -117,6 +117,7 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.datetime.LocalDate +import kotlinx.serialization.encodeToString import org.chromium.net.CronetEngine import retrofit2.HttpException @@ -744,7 +745,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions { segmentData = RetrofitInstance.api.getSegments( videoId!!, - ObjectMapper().writeValueAsString(categories) + JsonHelper.json.encodeToString(categories) ) if (segmentData.segments.isEmpty()) return@runCatching playerBinding.exoProgress.setSegments(segmentData.segments) diff --git a/app/src/main/java/com/github/libretube/ui/preferences/BackupRestoreSettings.kt b/app/src/main/java/com/github/libretube/ui/preferences/BackupRestoreSettings.kt index 9aa6bb95e..0673081e7 100644 --- a/app/src/main/java/com/github/libretube/ui/preferences/BackupRestoreSettings.kt +++ b/app/src/main/java/com/github/libretube/ui/preferences/BackupRestoreSettings.kt @@ -68,7 +68,7 @@ class BackupRestoreSettings : BasePreferenceFragment() { createBackupFile = registerForActivityResult( CreateDocument("application/json") ) { uri: Uri? -> - BackupHelper(requireContext()).advancedBackup(uri, backupFile) + BackupHelper(requireContext()).createAdvancedBackup(uri, backupFile) } super.onCreate(savedInstanceState) diff --git a/app/src/main/java/com/github/libretube/util/BackupHelper.kt b/app/src/main/java/com/github/libretube/util/BackupHelper.kt index 036d867d4..11fe14cf4 100644 --- a/app/src/main/java/com/github/libretube/util/BackupHelper.kt +++ b/app/src/main/java/com/github/libretube/util/BackupHelper.kt @@ -2,15 +2,23 @@ package com.github.libretube.util import android.content.Context import android.net.Uri +import android.util.Log import androidx.core.content.edit import androidx.preference.PreferenceManager -import com.fasterxml.jackson.databind.ObjectMapper +import com.github.libretube.api.JsonHelper import com.github.libretube.constants.PreferenceKeys import com.github.libretube.db.DatabaseHolder.Companion.Database +import com.github.libretube.extensions.TAG import com.github.libretube.extensions.query import com.github.libretube.obj.BackupFile import com.github.libretube.obj.PreferenceItem -import java.io.FileOutputStream +import kotlinx.serialization.json.booleanOrNull +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.decodeFromStream +import kotlinx.serialization.json.encodeToStream +import kotlinx.serialization.json.floatOrNull +import kotlinx.serialization.json.intOrNull +import kotlinx.serialization.json.longOrNull /** * Backup and restore the preferences @@ -19,18 +27,15 @@ class BackupHelper(private val context: Context) { /** * Write a [BackupFile] containing the database content as well as the preferences */ - fun advancedBackup(uri: Uri?, backupFile: BackupFile) { - if (uri == null) return - try { - context.contentResolver.openFileDescriptor(uri, "w")?.use { - FileOutputStream(it.fileDescriptor).use { fileOutputStream -> - fileOutputStream.write( - ObjectMapper().writeValueAsBytes(backupFile) - ) + fun createAdvancedBackup(uri: Uri?, backupFile: BackupFile) { + uri?.let { + try { + context.contentResolver.openOutputStream(it)?.use { outputStream -> + JsonHelper.json.encodeToStream(backupFile, outputStream) } + } catch (e: Exception) { + Log.e(TAG(), "Error while writing backup: $e") } - } catch (e: Exception) { - e.printStackTrace() } } @@ -38,36 +43,33 @@ class BackupHelper(private val context: Context) { * Restore data from a [BackupFile] */ fun restoreAdvancedBackup(uri: Uri?) { - if (uri == null) return - - val mapper = ObjectMapper() - val json = context.contentResolver.openInputStream(uri)?.use { - it.bufferedReader().use { reader -> reader.readText() } - }.orEmpty() - - val backupFile = mapper.readValue(json, BackupFile::class.java) + val backupFile = uri?.let { + context.contentResolver.openInputStream(it)?.use { inputStream -> + JsonHelper.json.decodeFromStream(inputStream) + } + } ?: return query { Database.watchHistoryDao().insertAll( - *backupFile.watchHistory.orEmpty().toTypedArray() + *backupFile.watchHistory.toTypedArray() ) Database.searchHistoryDao().insertAll( - *backupFile.searchHistory.orEmpty().toTypedArray() + *backupFile.searchHistory.toTypedArray() ) Database.watchPositionDao().insertAll( - *backupFile.watchPositions.orEmpty().toTypedArray() + *backupFile.watchPositions.toTypedArray() ) Database.localSubscriptionDao().insertAll( - *backupFile.localSubscriptions.orEmpty().toTypedArray() + *backupFile.localSubscriptions.toTypedArray() ) Database.customInstanceDao().insertAll( - *backupFile.customInstances.orEmpty().toTypedArray() + *backupFile.customInstances.toTypedArray() ) Database.playlistBookmarkDao().insertAll( - *backupFile.playlistBookmarks.orEmpty().toTypedArray() + *backupFile.playlistBookmarks.toTypedArray() ) - backupFile.localPlaylists?.forEach { + backupFile.localPlaylists.forEach { Database.localPlaylistsDao().createPlaylist(it.playlist) val playlistId = Database.localPlaylistsDao().getAll().last().playlist.id it.videos.forEach { @@ -91,17 +93,22 @@ class BackupHelper(private val context: Context) { // decide for each preference which type it is and save it to the preferences preferences.forEach { - when (it.value) { - is Boolean -> putBoolean(it.key, it.value) - is Float -> putFloat(it.key, it.value) - is Long -> putLong(it.key, it.value) + val value = it.value.booleanOrNull + ?: it.value.floatOrNull + ?: it.value.longOrNull + ?: it.value.intOrNull + ?: it.value.contentOrNull + when (value) { + is Boolean -> putBoolean(it.key, value) + is Float -> putFloat(it.key, value) + is Long -> putLong(it.key, value) is Int -> { when (it.key) { - PreferenceKeys.START_FRAGMENT -> putInt(it.key, it.value) - else -> putLong(it.key, it.value.toLong()) + PreferenceKeys.START_FRAGMENT -> putInt(it.key, value) + else -> putLong(it.key, value.toLong()) } } - is String -> putString(it.key, it.value) + is String -> putString(it.key, value) } } } diff --git a/app/src/main/java/com/github/libretube/util/ImportHelper.kt b/app/src/main/java/com/github/libretube/util/ImportHelper.kt index 0db3c1068..ffca363d0 100644 --- a/app/src/main/java/com/github/libretube/util/ImportHelper.kt +++ b/app/src/main/java/com/github/libretube/util/ImportHelper.kt @@ -4,8 +4,8 @@ import android.app.Activity import android.net.Uri import android.util.Log import android.widget.Toast -import com.fasterxml.jackson.databind.ObjectMapper import com.github.libretube.R +import com.github.libretube.api.JsonHelper import com.github.libretube.api.PlaylistsHelper import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.SubscriptionHelper @@ -15,11 +15,14 @@ import com.github.libretube.obj.ImportPlaylist import com.github.libretube.obj.ImportPlaylistFile import com.github.libretube.obj.NewPipeSubscription import com.github.libretube.obj.NewPipeSubscriptions -import java.io.FileOutputStream import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.decodeFromStream +import kotlinx.serialization.json.encodeToStream +import okio.use class ImportHelper( private val activity: Activity @@ -56,11 +59,10 @@ class ImportHelper( return when (val fileType = activity.contentResolver.getType(uri)) { "application/json", "application/*", "application/octet-stream" -> { // NewPipe subscriptions format - val subscriptions = ObjectMapper().readValue( - uri.readText(), - NewPipeSubscriptions::class.java - ) - subscriptions.subscriptions.orEmpty().map { + val subscriptions = activity.contentResolver.openInputStream(uri)?.use { + JsonHelper.json.decodeFromStream(it) + } + subscriptions?.subscriptions.orEmpty().map { it.url!!.replace("https://www.youtube.com/channel/", "") } } @@ -104,7 +106,9 @@ class ImportHelper( subscriptions = newPipeChannels ) - uri.write(newPipeSubscriptions) + activity.contentResolver.openOutputStream(uri)?.use { + JsonHelper.json.encodeToStream(newPipeSubscriptions, it) + } activity.toastFromMainThread(R.string.exportsuccess) } @@ -134,11 +138,9 @@ class ImportHelper( } } "application/json", "application/*", "application/octet-stream" -> { - val playlistFile = ObjectMapper().readValue( - uri.readText(), - ImportPlaylistFile::class.java - ) - importPlaylists.addAll(playlistFile.playlists.orEmpty()) + val playlistFile = JsonHelper.json + .decodeFromString(uri.readText()) + importPlaylists.addAll(playlistFile.playlists) } else -> { activity.applicationContext.toastFromMainThread("Unsupported file type $fileType") @@ -173,7 +175,9 @@ class ImportHelper( playlists = playlists ) - uri.write(playlistFile) + activity.contentResolver.openOutputStream(uri)?.use { + JsonHelper.json.encodeToStream(playlistFile, it) + } activity.toastFromMainThread(R.string.exportsuccess) } @@ -184,14 +188,4 @@ class ImportHelper( it.bufferedReader().use { reader -> reader.readText() } }.orEmpty() } - - private fun Uri.write(text: Any) { - activity.contentResolver.openFileDescriptor(this, "w")?.use { - FileOutputStream(it.fileDescriptor).use { fileOutputStream -> - fileOutputStream.write( - ObjectMapper().writeValueAsBytes(text) - ) - } - } - } } diff --git a/app/src/main/java/com/github/libretube/util/MetadataHelper.kt b/app/src/main/java/com/github/libretube/util/MetadataHelper.kt deleted file mode 100644 index a2b46d13d..000000000 --- a/app/src/main/java/com/github/libretube/util/MetadataHelper.kt +++ /dev/null @@ -1,48 +0,0 @@ -package com.github.libretube.util - -import android.content.Context -import android.net.Uri -import com.fasterxml.jackson.databind.ObjectMapper -import com.github.libretube.api.obj.Streams -import java.io.File -import java.io.FileOutputStream - -class MetadataHelper( - private val context: Context -) { - private val mapper = ObjectMapper() - private val metadataDir = DownloadHelper.getDownloadDir(context, DownloadHelper.METADATA_DIR) - - fun createMetadata(fileName: String, streams: Streams) { - val targetFile = File(metadataDir, fileName) - targetFile.createNewFile() - - context.contentResolver.openFileDescriptor( - Uri.fromFile(targetFile), - "w" - )?.use { - FileOutputStream(it.fileDescriptor).use { fileOutputStream -> - fileOutputStream.write( - mapper.writeValueAsBytes( - streams - ) - ) - } - } - } - - fun getMetadata(fileName: String): Streams? { - val sourceFile = File(metadataDir, fileName) - - return try { - val json = context.contentResolver.openInputStream( - Uri.fromFile(sourceFile) - )?.use { - it.bufferedReader().use { reader -> reader.readText() } - } - mapper.readValue(json, Streams::class.java) - } catch (e: Exception) { - return null - } - } -} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 43006d4b3..15824d29d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -11,7 +11,6 @@ espresso = "3.5.1" workRuntime = "2.7.1" exoplayer = "2.18.2" retrofit = "2.9.0" -jacksonAnnotations = "2.13.4" desugaring = "1.2.2" cronetEmbedded = "108.5359.79" cronetOkHttp = "0.1.0" @@ -36,8 +35,6 @@ androidx-work-runtime = { group = "androidx.work", name="work-runtime-ktx", vers exoplayer = { group = "com.google.android.exoplayer", name = "exoplayer", version.ref = "exoplayer" } exoplayer-extension-mediasession = { group = "com.google.android.exoplayer", name = "extension-mediasession", version.ref = "exoplayer" } square-retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" } -square-retrofit-converterJackson = { group = "com.squareup.retrofit2", name = "converter-jackson", version.ref = "retrofit" } -jacksonAnnotations = { group = "com.fasterxml.jackson.core", name = "jackson-annotations", version.ref = "jacksonAnnotations" } desugaring = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "desugaring" } exoplayer-extension-cronet = { group = "com.google.android.exoplayer", name = "extension-cronet", version.ref = "exoplayer" } exoplayer-dash = { group = "com.google.android.exoplayer", name = "exoplayer-dash", version.ref = "exoplayer" }