Remove remaining Jackson code.

This commit is contained in:
Isira Seneviratne 2023-01-19 14:08:21 +05:30
parent e047d5babd
commit 60706c2d87
26 changed files with 136 additions and 145 deletions

View File

@ -108,10 +108,8 @@ dependencies {
implementation libs.exoplayer.extension.mediasession implementation libs.exoplayer.extension.mediasession
implementation libs.exoplayer.dash implementation libs.exoplayer.dash
/* Retrofit and Jackson */ /* Retrofit and Kotlinx Serialization */
implementation libs.square.retrofit implementation libs.square.retrofit
implementation libs.square.retrofit.converterJackson
implementation libs.jacksonAnnotations
implementation libs.kotlinx.serialization implementation libs.kotlinx.serialization
implementation libs.kotlinx.datetime implementation libs.kotlinx.datetime
implementation libs.kotlinx.serialization.retrofit implementation libs.kotlinx.serialization.retrofit

View File

@ -0,0 +1,9 @@
package com.github.libretube.api
import kotlinx.serialization.json.Json
object JsonHelper {
val json = Json {
ignoreUnknownKeys = true
}
}

View File

@ -4,28 +4,22 @@ import com.github.libretube.constants.PIPED_API_URL
import com.github.libretube.constants.PreferenceKeys import com.github.libretube.constants.PreferenceKeys
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import retrofit2.Retrofit import retrofit2.Retrofit
import retrofit2.converter.jackson.JacksonConverterFactory
import retrofit2.create import retrofit2.create
object RetrofitInstance { object RetrofitInstance {
lateinit var url: String lateinit var url: String
lateinit var authUrl: String lateinit var authUrl: String
val lazyMgr = resettableManager() val lazyMgr = resettableManager()
private val jacksonConverterFactory = JacksonConverterFactory.create() private val kotlinxConverterFactory = JsonHelper.json
private val json = Json { .asConverterFactory("application/json".toMediaType())
ignoreUnknownKeys = true
}
private val kotlinxConverterFactory = json.asConverterFactory("application/json".toMediaType())
val api by resettableLazy(lazyMgr) { val api by resettableLazy(lazyMgr) {
Retrofit.Builder() Retrofit.Builder()
.baseUrl(url) .baseUrl(url)
.callFactory(CronetHelper.callFactory) .callFactory(CronetHelper.callFactory)
.addConverterFactory(kotlinxConverterFactory) .addConverterFactory(kotlinxConverterFactory)
.addConverterFactory(jacksonConverterFactory)
.build() .build()
.create<PipedApi>() .create<PipedApi>()
} }
@ -35,7 +29,6 @@ object RetrofitInstance {
.baseUrl(authUrl) .baseUrl(authUrl)
.callFactory(CronetHelper.callFactory) .callFactory(CronetHelper.callFactory)
.addConverterFactory(kotlinxConverterFactory) .addConverterFactory(kotlinxConverterFactory)
.addConverterFactory(jacksonConverterFactory)
.build() .build()
.create<PipedApi>() .create<PipedApi>()
} }
@ -45,7 +38,6 @@ object RetrofitInstance {
.baseUrl(url) .baseUrl(url)
.callFactory(CronetHelper.callFactory) .callFactory(CronetHelper.callFactory)
.addConverterFactory(kotlinxConverterFactory) .addConverterFactory(kotlinxConverterFactory)
.addConverterFactory(jacksonConverterFactory)
.build() .build()
.create<ExternalApi>() .create<ExternalApi>()
} }

View File

@ -3,7 +3,9 @@ package com.github.libretube.db.obj
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
@Serializable
@Entity(tableName = "customInstance") @Entity(tableName = "customInstance")
class CustomInstance( class CustomInstance(
@PrimaryKey var name: String = "", @PrimaryKey var name: String = "",

View File

@ -2,7 +2,9 @@ package com.github.libretube.db.obj
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
@Serializable
@Entity @Entity
data class LocalPlaylist( data class LocalPlaylist(
@PrimaryKey(autoGenerate = true) @PrimaryKey(autoGenerate = true)

View File

@ -3,7 +3,9 @@ package com.github.libretube.db.obj
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
@Serializable
@Entity @Entity
data class LocalPlaylistItem( data class LocalPlaylistItem(
@PrimaryKey(autoGenerate = true) val id: Int = 0, @PrimaryKey(autoGenerate = true) val id: Int = 0,

View File

@ -2,7 +2,9 @@ package com.github.libretube.db.obj
import androidx.room.Embedded import androidx.room.Embedded
import androidx.room.Relation import androidx.room.Relation
import kotlinx.serialization.Serializable
@Serializable
data class LocalPlaylistWithVideos( data class LocalPlaylistWithVideos(
@Embedded val playlist: LocalPlaylist = LocalPlaylist(), @Embedded val playlist: LocalPlaylist = LocalPlaylist(),
@Relation( @Relation(

View File

@ -2,7 +2,9 @@ package com.github.libretube.db.obj
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
@Serializable
@Entity(tableName = "localSubscription") @Entity(tableName = "localSubscription")
data class LocalSubscription( data class LocalSubscription(
@PrimaryKey val channelId: String = "" @PrimaryKey val channelId: String = ""

View File

@ -2,7 +2,9 @@ package com.github.libretube.db.obj
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
@Serializable
@Entity(tableName = "playlistBookmark") @Entity(tableName = "playlistBookmark")
data class PlaylistBookmark( data class PlaylistBookmark(
@PrimaryKey @PrimaryKey

View File

@ -2,7 +2,9 @@ package com.github.libretube.db.obj
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
@Serializable
@Entity(tableName = "searchHistoryItem") @Entity(tableName = "searchHistoryItem")
data class SearchHistoryItem( data class SearchHistoryItem(
@PrimaryKey val query: String = "" @PrimaryKey val query: String = ""

View File

@ -3,7 +3,9 @@ package com.github.libretube.db.obj
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
@Serializable
@Entity(tableName = "watchHistoryItem") @Entity(tableName = "watchHistoryItem")
data class WatchHistoryItem( data class WatchHistoryItem(
@PrimaryKey val videoId: String = "", @PrimaryKey val videoId: String = "",

View File

@ -3,7 +3,9 @@ package com.github.libretube.db.obj
import androidx.room.ColumnInfo import androidx.room.ColumnInfo
import androidx.room.Entity import androidx.room.Entity
import androidx.room.PrimaryKey import androidx.room.PrimaryKey
import kotlinx.serialization.Serializable
@Serializable
@Entity(tableName = "watchPosition") @Entity(tableName = "watchPosition")
data class WatchPosition( data class WatchPosition(
@PrimaryKey val videoId: String = "", @PrimaryKey val videoId: String = "",

View File

@ -7,14 +7,16 @@ import com.github.libretube.db.obj.PlaylistBookmark
import com.github.libretube.db.obj.SearchHistoryItem import com.github.libretube.db.obj.SearchHistoryItem
import com.github.libretube.db.obj.WatchHistoryItem import com.github.libretube.db.obj.WatchHistoryItem
import com.github.libretube.db.obj.WatchPosition import com.github.libretube.db.obj.WatchPosition
import kotlinx.serialization.Serializable
@Serializable
data class BackupFile( data class BackupFile(
var watchHistory: List<WatchHistoryItem>? = null, var watchHistory: List<WatchHistoryItem> = emptyList(),
var watchPositions: List<WatchPosition>? = null, var watchPositions: List<WatchPosition> = emptyList(),
var searchHistory: List<SearchHistoryItem>? = null, var searchHistory: List<SearchHistoryItem> = emptyList(),
var localSubscriptions: List<LocalSubscription>? = null, var localSubscriptions: List<LocalSubscription> = emptyList(),
var customInstances: List<CustomInstance>? = null, var customInstances: List<CustomInstance> = emptyList(),
var playlistBookmarks: List<PlaylistBookmark>? = null, var playlistBookmarks: List<PlaylistBookmark> = emptyList(),
var localPlaylists: List<LocalPlaylistWithVideos>? = null, var localPlaylists: List<LocalPlaylistWithVideos> = emptyList(),
var preferences: List<PreferenceItem>? = null var preferences: List<PreferenceItem> = emptyList()
) )

View File

@ -3,5 +3,5 @@ package com.github.libretube.obj
data class ImportPlaylistFile( data class ImportPlaylistFile(
val format: String? = null, val format: String? = null,
val version: Int? = null, val version: Int? = null,
val playlists: List<ImportPlaylist>? = null val playlists: List<ImportPlaylist> = emptyList()
) )

View File

@ -1,5 +1,8 @@
package com.github.libretube.obj package com.github.libretube.obj
import kotlinx.serialization.Serializable
@Serializable
data class NewPipeSubscription( data class NewPipeSubscription(
val name: String? = null, val name: String? = null,
val service_id: Int? = null, val service_id: Int? = null,

View File

@ -1,7 +1,10 @@
package com.github.libretube.obj package com.github.libretube.obj
import kotlinx.serialization.Serializable
@Serializable
data class NewPipeSubscriptions( data class NewPipeSubscriptions(
val app_version: String = "", val app_version: String = "",
val app_version_int: Int = 0, val app_version_int: Int = 0,
val subscriptions: List<NewPipeSubscription>? = null val subscriptions: List<NewPipeSubscription> = emptyList()
) )

View File

@ -1,6 +1,11 @@
package com.github.libretube.obj package com.github.libretube.obj
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonPrimitive
@Serializable
data class PreferenceItem( data class PreferenceItem(
val key: String? = null, val key: String? = null,
val value: Any? = null val value: JsonPrimitive = JsonNull
) )

View File

@ -3,6 +3,8 @@ package com.github.libretube.obj.update
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonNull
@Serializable @Serializable
data class Asset( data class Asset(
@ -11,7 +13,7 @@ data class Asset(
@SerialName("created_at") val createdAt: Instant, @SerialName("created_at") val createdAt: Instant,
@SerialName("download_count") val downloadCount: Int, @SerialName("download_count") val downloadCount: Int,
val id: Int, val id: Int,
val label: String? = null, val label: JsonElement = JsonNull,
val name: String, val name: String,
@SerialName("node_id") val nodeId: String, @SerialName("node_id") val nodeId: String,
val size: Int, val size: Int,

View File

@ -13,8 +13,8 @@ import android.os.Looper
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import androidx.core.app.ServiceCompat import androidx.core.app.ServiceCompat
import com.fasterxml.jackson.databind.ObjectMapper
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.JsonHelper
import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.obj.Segment import com.github.libretube.api.obj.Segment
import com.github.libretube.api.obj.SegmentData 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.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.serialization.encodeToString
/** /**
* Loads the selected videos audio in background mode with a notification area. * Loads the selected videos audio in background mode with a notification area.
@ -335,11 +336,10 @@ class BackgroundMode : Service() {
runCatching { runCatching {
val categories = PlayerHelper.getSponsorBlockCategories() val categories = PlayerHelper.getSponsorBlockCategories()
if (categories.isEmpty()) return@runCatching if (categories.isEmpty()) return@runCatching
segmentData = segmentData = RetrofitInstance.api.getSegments(
RetrofitInstance.api.getSegments( videoId,
videoId, JsonHelper.json.encodeToString(categories)
ObjectMapper().writeValueAsString(categories) )
)
checkForSegments() checkForSegments()
} }
} }

View File

@ -11,6 +11,8 @@ import com.github.libretube.obj.BackupFile
import com.github.libretube.obj.PreferenceItem import com.github.libretube.obj.PreferenceItem
import com.github.libretube.util.PreferenceHelper import com.github.libretube.util.PreferenceHelper
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonPrimitive
class BackupDialog( class BackupDialog(
private val createBackupFile: (BackupFile) -> Unit private val createBackupFile: (BackupFile) -> Unit
@ -45,8 +47,14 @@ class BackupDialog(
}) })
object Preferences : BackupOption(R.string.preferences, onSelected = { file -> object Preferences : BackupOption(R.string.preferences, onSelected = { file ->
file.preferences = PreferenceHelper.settings.all.map { file.preferences = PreferenceHelper.settings.all.map { (key, value) ->
PreferenceItem(it.key, it.value) val jsonValue = when (value) {
is Number -> JsonPrimitive(value)
is Boolean -> JsonPrimitive(value)
is String -> JsonPrimitive(value)
else -> JsonNull
}
PreferenceItem(key, jsonValue)
} }
}) })
} }

View File

@ -34,9 +34,9 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.fasterxml.jackson.databind.ObjectMapper
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.CronetHelper import com.github.libretube.api.CronetHelper
import com.github.libretube.api.JsonHelper
import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.obj.ChapterSegment import com.github.libretube.api.obj.ChapterSegment
import com.github.libretube.api.obj.PipedStream import com.github.libretube.api.obj.PipedStream
@ -117,6 +117,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.datetime.LocalDate import kotlinx.datetime.LocalDate
import kotlinx.serialization.encodeToString
import org.chromium.net.CronetEngine import org.chromium.net.CronetEngine
import retrofit2.HttpException import retrofit2.HttpException
@ -744,7 +745,7 @@ class PlayerFragment : BaseFragment(), OnlinePlayerOptions {
segmentData = segmentData =
RetrofitInstance.api.getSegments( RetrofitInstance.api.getSegments(
videoId!!, videoId!!,
ObjectMapper().writeValueAsString(categories) JsonHelper.json.encodeToString(categories)
) )
if (segmentData.segments.isEmpty()) return@runCatching if (segmentData.segments.isEmpty()) return@runCatching
playerBinding.exoProgress.setSegments(segmentData.segments) playerBinding.exoProgress.setSegments(segmentData.segments)

View File

@ -68,7 +68,7 @@ class BackupRestoreSettings : BasePreferenceFragment() {
createBackupFile = registerForActivityResult( createBackupFile = registerForActivityResult(
CreateDocument("application/json") CreateDocument("application/json")
) { uri: Uri? -> ) { uri: Uri? ->
BackupHelper(requireContext()).advancedBackup(uri, backupFile) BackupHelper(requireContext()).createAdvancedBackup(uri, backupFile)
} }
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)

View File

@ -2,15 +2,23 @@ package com.github.libretube.util
import android.content.Context import android.content.Context
import android.net.Uri import android.net.Uri
import android.util.Log
import androidx.core.content.edit import androidx.core.content.edit
import androidx.preference.PreferenceManager 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.constants.PreferenceKeys
import com.github.libretube.db.DatabaseHolder.Companion.Database import com.github.libretube.db.DatabaseHolder.Companion.Database
import com.github.libretube.extensions.TAG
import com.github.libretube.extensions.query import com.github.libretube.extensions.query
import com.github.libretube.obj.BackupFile import com.github.libretube.obj.BackupFile
import com.github.libretube.obj.PreferenceItem 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 * 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 * Write a [BackupFile] containing the database content as well as the preferences
*/ */
fun advancedBackup(uri: Uri?, backupFile: BackupFile) { fun createAdvancedBackup(uri: Uri?, backupFile: BackupFile) {
if (uri == null) return uri?.let {
try { try {
context.contentResolver.openFileDescriptor(uri, "w")?.use { context.contentResolver.openOutputStream(it)?.use { outputStream ->
FileOutputStream(it.fileDescriptor).use { fileOutputStream -> JsonHelper.json.encodeToStream(backupFile, outputStream)
fileOutputStream.write(
ObjectMapper().writeValueAsBytes(backupFile)
)
} }
} 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] * Restore data from a [BackupFile]
*/ */
fun restoreAdvancedBackup(uri: Uri?) { fun restoreAdvancedBackup(uri: Uri?) {
if (uri == null) return val backupFile = uri?.let {
context.contentResolver.openInputStream(it)?.use { inputStream ->
val mapper = ObjectMapper() JsonHelper.json.decodeFromStream<BackupFile>(inputStream)
val json = context.contentResolver.openInputStream(uri)?.use { }
it.bufferedReader().use { reader -> reader.readText() } } ?: return
}.orEmpty()
val backupFile = mapper.readValue(json, BackupFile::class.java)
query { query {
Database.watchHistoryDao().insertAll( Database.watchHistoryDao().insertAll(
*backupFile.watchHistory.orEmpty().toTypedArray() *backupFile.watchHistory.toTypedArray()
) )
Database.searchHistoryDao().insertAll( Database.searchHistoryDao().insertAll(
*backupFile.searchHistory.orEmpty().toTypedArray() *backupFile.searchHistory.toTypedArray()
) )
Database.watchPositionDao().insertAll( Database.watchPositionDao().insertAll(
*backupFile.watchPositions.orEmpty().toTypedArray() *backupFile.watchPositions.toTypedArray()
) )
Database.localSubscriptionDao().insertAll( Database.localSubscriptionDao().insertAll(
*backupFile.localSubscriptions.orEmpty().toTypedArray() *backupFile.localSubscriptions.toTypedArray()
) )
Database.customInstanceDao().insertAll( Database.customInstanceDao().insertAll(
*backupFile.customInstances.orEmpty().toTypedArray() *backupFile.customInstances.toTypedArray()
) )
Database.playlistBookmarkDao().insertAll( Database.playlistBookmarkDao().insertAll(
*backupFile.playlistBookmarks.orEmpty().toTypedArray() *backupFile.playlistBookmarks.toTypedArray()
) )
backupFile.localPlaylists?.forEach { backupFile.localPlaylists.forEach {
Database.localPlaylistsDao().createPlaylist(it.playlist) Database.localPlaylistsDao().createPlaylist(it.playlist)
val playlistId = Database.localPlaylistsDao().getAll().last().playlist.id val playlistId = Database.localPlaylistsDao().getAll().last().playlist.id
it.videos.forEach { 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 // decide for each preference which type it is and save it to the preferences
preferences.forEach { preferences.forEach {
when (it.value) { val value = it.value.booleanOrNull
is Boolean -> putBoolean(it.key, it.value) ?: it.value.floatOrNull
is Float -> putFloat(it.key, it.value) ?: it.value.longOrNull
is Long -> putLong(it.key, it.value) ?: 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 -> { is Int -> {
when (it.key) { when (it.key) {
PreferenceKeys.START_FRAGMENT -> putInt(it.key, it.value) PreferenceKeys.START_FRAGMENT -> putInt(it.key, value)
else -> putLong(it.key, it.value.toLong()) else -> putLong(it.key, value.toLong())
} }
} }
is String -> putString(it.key, it.value) is String -> putString(it.key, value)
} }
} }
} }

View File

@ -4,8 +4,8 @@ import android.app.Activity
import android.net.Uri import android.net.Uri
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import com.fasterxml.jackson.databind.ObjectMapper
import com.github.libretube.R import com.github.libretube.R
import com.github.libretube.api.JsonHelper
import com.github.libretube.api.PlaylistsHelper import com.github.libretube.api.PlaylistsHelper
import com.github.libretube.api.RetrofitInstance import com.github.libretube.api.RetrofitInstance
import com.github.libretube.api.SubscriptionHelper 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.ImportPlaylistFile
import com.github.libretube.obj.NewPipeSubscription import com.github.libretube.obj.NewPipeSubscription
import com.github.libretube.obj.NewPipeSubscriptions import com.github.libretube.obj.NewPipeSubscriptions
import java.io.FileOutputStream
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.encodeToStream
import okio.use
class ImportHelper( class ImportHelper(
private val activity: Activity private val activity: Activity
@ -56,11 +59,10 @@ class ImportHelper(
return when (val fileType = activity.contentResolver.getType(uri)) { return when (val fileType = activity.contentResolver.getType(uri)) {
"application/json", "application/*", "application/octet-stream" -> { "application/json", "application/*", "application/octet-stream" -> {
// NewPipe subscriptions format // NewPipe subscriptions format
val subscriptions = ObjectMapper().readValue( val subscriptions = activity.contentResolver.openInputStream(uri)?.use {
uri.readText(), JsonHelper.json.decodeFromStream<NewPipeSubscriptions>(it)
NewPipeSubscriptions::class.java }
) subscriptions?.subscriptions.orEmpty().map {
subscriptions.subscriptions.orEmpty().map {
it.url!!.replace("https://www.youtube.com/channel/", "") it.url!!.replace("https://www.youtube.com/channel/", "")
} }
} }
@ -104,7 +106,9 @@ class ImportHelper(
subscriptions = newPipeChannels subscriptions = newPipeChannels
) )
uri.write(newPipeSubscriptions) activity.contentResolver.openOutputStream(uri)?.use {
JsonHelper.json.encodeToStream<Any>(newPipeSubscriptions, it)
}
activity.toastFromMainThread(R.string.exportsuccess) activity.toastFromMainThread(R.string.exportsuccess)
} }
@ -134,11 +138,9 @@ class ImportHelper(
} }
} }
"application/json", "application/*", "application/octet-stream" -> { "application/json", "application/*", "application/octet-stream" -> {
val playlistFile = ObjectMapper().readValue( val playlistFile = JsonHelper.json
uri.readText(), .decodeFromString<ImportPlaylistFile>(uri.readText())
ImportPlaylistFile::class.java importPlaylists.addAll(playlistFile.playlists)
)
importPlaylists.addAll(playlistFile.playlists.orEmpty())
} }
else -> { else -> {
activity.applicationContext.toastFromMainThread("Unsupported file type $fileType") activity.applicationContext.toastFromMainThread("Unsupported file type $fileType")
@ -173,7 +175,9 @@ class ImportHelper(
playlists = playlists playlists = playlists
) )
uri.write(playlistFile) activity.contentResolver.openOutputStream(uri)?.use {
JsonHelper.json.encodeToStream<Any>(playlistFile, it)
}
activity.toastFromMainThread(R.string.exportsuccess) activity.toastFromMainThread(R.string.exportsuccess)
} }
@ -184,14 +188,4 @@ class ImportHelper(
it.bufferedReader().use { reader -> reader.readText() } it.bufferedReader().use { reader -> reader.readText() }
}.orEmpty() }.orEmpty()
} }
private fun Uri.write(text: Any) {
activity.contentResolver.openFileDescriptor(this, "w")?.use {
FileOutputStream(it.fileDescriptor).use { fileOutputStream ->
fileOutputStream.write(
ObjectMapper().writeValueAsBytes(text)
)
}
}
}
} }

View File

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

View File

@ -11,7 +11,6 @@ espresso = "3.5.1"
workRuntime = "2.7.1" workRuntime = "2.7.1"
exoplayer = "2.18.2" exoplayer = "2.18.2"
retrofit = "2.9.0" retrofit = "2.9.0"
jacksonAnnotations = "2.13.4"
desugaring = "1.2.2" desugaring = "1.2.2"
cronetEmbedded = "108.5359.79" cronetEmbedded = "108.5359.79"
cronetOkHttp = "0.1.0" 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 = { group = "com.google.android.exoplayer", name = "exoplayer", version.ref = "exoplayer" }
exoplayer-extension-mediasession = { group = "com.google.android.exoplayer", name = "extension-mediasession", 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 = { 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" } 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-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" } exoplayer-dash = { group = "com.google.android.exoplayer", name = "exoplayer-dash", version.ref = "exoplayer" }