better setting export

This commit is contained in:
rebelonion 2024-02-03 00:43:20 -06:00
parent 54b53dbe56
commit aa8d41eecf
5 changed files with 135 additions and 88 deletions

View file

@ -5,6 +5,7 @@ import android.content.SharedPreferences
import android.util.Base64
import ani.dantotsu.settings.saving.internal.Compat
import ani.dantotsu.settings.saving.internal.Location
import ani.dantotsu.settings.saving.internal.PreferencePackager
import ani.dantotsu.snackString
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
@ -237,18 +238,10 @@ object PrefManager {
fun getAnimeDownloadPreferences(): SharedPreferences = animeDownloadsPreferences!! //needs to be used externally
fun exportAllPrefs(prefLocation: Location): Map<String, *>{
val pref = getPrefLocation(prefLocation)
val typedMap = mutableMapOf<String, Any>()
pref.all.forEach { (key, value) ->
val typeValueMap = mapOf(
"type" to value?.javaClass?.kotlin?.qualifiedName,
"value" to value
)
typedMap[key] = typeValueMap
}
return typedMap
fun exportAllPrefs(prefLocation: List<Location>): String {
return PreferencePackager.pack(
prefLocation.associateWith { getPrefLocation(it) }
)
}
@Suppress("UNCHECKED_CAST")

View file

@ -0,0 +1,82 @@
package ani.dantotsu.settings.saving.internal
import android.content.SharedPreferences
import ani.dantotsu.settings.saving.PrefManager
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
class PreferencePackager {
//map one or more preference maps for import/export
companion object {
fun pack(map: Map<Location, SharedPreferences>): String {
val prefsMap = packagePreferences(map)
val gson = Gson()
return gson.toJson(prefsMap)
}
fun unpack(decryptedJson: String): Boolean {
val gson = Gson()
val type = object : TypeToken<Map<String, Map<String, Map<String, Any>>>>() {}.type //oh god...
val rawPrefsMap: Map<String, Map<String, Map<String, Any>>> = gson.fromJson(decryptedJson, type)
val deserializedMap = mutableMapOf<String, Map<String, Any?>>()
rawPrefsMap.forEach { (prefName, prefValueMap) ->
val innerMap = mutableMapOf<String, Any?>()
prefValueMap.forEach { (key, typeValueMap) ->
val typeName = typeValueMap["type"] as? String
val value = typeValueMap["value"]
innerMap[key] =
when (typeName) { //wierdly null sometimes so cast to string
"kotlin.Int" -> (value as? Double)?.toInt()
"kotlin.String" -> value.toString()
"kotlin.Boolean" -> value as? Boolean
"kotlin.Float" -> value.toString().toFloatOrNull()
"kotlin.Long" -> (value as? Double)?.toLong()
"java.util.HashSet" -> value as? ArrayList<*>
else -> null
}
}
deserializedMap[prefName] = innerMap
}
return unpackagePreferences(deserializedMap)
}
private fun packagePreferences(map: Map<Location, SharedPreferences>): Map<String, Map<String, *>> {
val result = mutableMapOf<String, Map<String, *>>()
for ((location, preferences) in map) {
val prefMap = mutableMapOf<String, Any>()
preferences.all.forEach { (key, value) ->
val typeValueMap = mapOf(
"type" to value?.javaClass?.kotlin?.qualifiedName,
"value" to value
)
prefMap[key] = typeValueMap
}
result[location.name] = prefMap
}
return result
}
private fun unpackagePreferences(map: Map<String, Map<String, *>>): Boolean {
var failed = false
map.forEach { (location, prefMap) ->
val locationEnum = locationFromString(location)
if (!PrefManager.importAllPrefs(prefMap, locationEnum))
failed = true
}
return failed
}
private fun locationFromString(location: String): Location {
val loc = Location.entries.find { it.name == location }
return loc ?: throw IllegalArgumentException("Location not found")
}
}
}