mirror of
https://github.com/Suwayomi/Tachidesk.git
synced 2025-12-23 21:12:37 +01:00
Seperate out migrations to allow run-once migrations (#882)
* Seperate out migrations to allow run-once migrations * Previous * Move migrations to a new file
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package suwayomi.tachidesk.server
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import mu.KotlinLogging
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
import java.util.prefs.Preferences
|
||||
|
||||
private fun migratePreferences(
|
||||
parent: String?,
|
||||
rootNode: Preferences,
|
||||
) {
|
||||
val subNodes = rootNode.childrenNames()
|
||||
|
||||
for (subNodeName in subNodes) {
|
||||
val subNode = rootNode.node(subNodeName)
|
||||
val key =
|
||||
if (parent != null) {
|
||||
"$parent/$subNodeName"
|
||||
} else {
|
||||
subNodeName
|
||||
}
|
||||
val preferences = Injekt.get<Application>().getSharedPreferences(key, Context.MODE_PRIVATE)
|
||||
|
||||
val items: Map<String, String?> =
|
||||
subNode.keys().associateWith {
|
||||
subNode[it, null]?.ifBlank { null }
|
||||
}
|
||||
|
||||
preferences.edit().apply {
|
||||
items.forEach { (key, value) ->
|
||||
if (value != null) {
|
||||
putString(key, value)
|
||||
}
|
||||
}
|
||||
}.apply()
|
||||
|
||||
migratePreferences(key, subNode) // Recursively migrate sub-level nodes
|
||||
}
|
||||
}
|
||||
|
||||
const val MIGRATION_VERSION = 1
|
||||
|
||||
fun runMigrations(applicationDirs: ApplicationDirs) {
|
||||
val migrationPreferences =
|
||||
Injekt.get<Application>()
|
||||
.getSharedPreferences(
|
||||
"migrations",
|
||||
Context.MODE_PRIVATE,
|
||||
)
|
||||
val version = migrationPreferences.getInt("version", 0)
|
||||
val logger = KotlinLogging.logger("Migration")
|
||||
logger.info { "Running migrations, previous version $version, target version $MIGRATION_VERSION" }
|
||||
|
||||
if (version < 1) {
|
||||
logger.info { "Running migration for version: 1" }
|
||||
val oldMangaDownloadDir = File(applicationDirs.downloadsRoot)
|
||||
val newMangaDownloadDir = File(applicationDirs.mangaDownloadsRoot)
|
||||
val downloadDirs = oldMangaDownloadDir.listFiles().orEmpty()
|
||||
|
||||
val moveDownloadsToNewFolder = !newMangaDownloadDir.exists() && downloadDirs.isNotEmpty()
|
||||
if (moveDownloadsToNewFolder) {
|
||||
newMangaDownloadDir.mkdirs()
|
||||
|
||||
for (downloadDir in downloadDirs) {
|
||||
if (downloadDir == File(applicationDirs.thumbnailDownloadsRoot)) {
|
||||
continue
|
||||
}
|
||||
|
||||
downloadDir.renameTo(File(newMangaDownloadDir, downloadDir.name))
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate from old preferences api
|
||||
val prefRootNode = "suwayomi/tachidesk"
|
||||
val isMigrationRequired = Preferences.userRoot().nodeExists(prefRootNode)
|
||||
if (isMigrationRequired) {
|
||||
val preferences = Preferences.userRoot().node(prefRootNode)
|
||||
migratePreferences(null, preferences)
|
||||
preferences.removeNode()
|
||||
}
|
||||
}
|
||||
migrationPreferences.edit().putInt("version", MIGRATION_VERSION).apply()
|
||||
}
|
||||
@@ -7,8 +7,6 @@ package suwayomi.tachidesk.server
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import ch.qos.logback.classic.Level
|
||||
import com.typesafe.config.ConfigRenderOptions
|
||||
import eu.kanade.tachiyomi.App
|
||||
@@ -34,7 +32,6 @@ import suwayomi.tachidesk.server.database.databaseUp
|
||||
import suwayomi.tachidesk.server.generated.BuildConfig
|
||||
import suwayomi.tachidesk.server.util.AppMutex.handleAppMutex
|
||||
import suwayomi.tachidesk.server.util.SystemTray
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import xyz.nulldev.androidcompat.AndroidCompat
|
||||
import xyz.nulldev.androidcompat.AndroidCompatInitializer
|
||||
@@ -47,7 +44,6 @@ import xyz.nulldev.ts.config.setLogLevelFor
|
||||
import java.io.File
|
||||
import java.security.Security
|
||||
import java.util.Locale
|
||||
import java.util.prefs.Preferences
|
||||
|
||||
private val logger = KotlinLogging.logger {}
|
||||
|
||||
@@ -126,23 +122,6 @@ fun applicationSetup() {
|
||||
File("$ApplicationRootDir/manga-local").renameTo(applicationDirs.localMangaRoot)
|
||||
File("$ApplicationRootDir/anime-thumbnails").delete()
|
||||
|
||||
val oldMangaDownloadDir = File(applicationDirs.downloadsRoot)
|
||||
val newMangaDownloadDir = File(applicationDirs.mangaDownloadsRoot)
|
||||
val downloadDirs = oldMangaDownloadDir.listFiles().orEmpty()
|
||||
|
||||
val moveDownloadsToNewFolder = !newMangaDownloadDir.exists() && downloadDirs.isNotEmpty()
|
||||
if (moveDownloadsToNewFolder) {
|
||||
newMangaDownloadDir.mkdirs()
|
||||
|
||||
for (downloadDir in downloadDirs) {
|
||||
if (downloadDir == File(applicationDirs.thumbnailDownloadsRoot)) {
|
||||
continue
|
||||
}
|
||||
|
||||
downloadDir.renameTo(File(newMangaDownloadDir, downloadDir.name))
|
||||
}
|
||||
}
|
||||
|
||||
// make dirs we need
|
||||
listOf(
|
||||
applicationDirs.dataRoot,
|
||||
@@ -217,13 +196,7 @@ fun applicationSetup() {
|
||||
}
|
||||
}, ignoreInitialValue = false)
|
||||
|
||||
val prefRootNode = "suwayomi/tachidesk"
|
||||
val isMigrationRequired = Preferences.userRoot().nodeExists(prefRootNode)
|
||||
if (isMigrationRequired) {
|
||||
val preferences = Preferences.userRoot().node(prefRootNode)
|
||||
migratePreferences(null, preferences)
|
||||
preferences.removeNode()
|
||||
}
|
||||
runMigrations(applicationDirs)
|
||||
|
||||
// Disable jetty's logging
|
||||
System.setProperty("org.eclipse.jetty.util.log.announce", "false")
|
||||
@@ -265,36 +238,3 @@ fun applicationSetup() {
|
||||
// start DownloadManager and restore + resume downloads
|
||||
DownloadManager.restoreAndResumeDownloads()
|
||||
}
|
||||
|
||||
fun migratePreferences(
|
||||
parent: String?,
|
||||
rootNode: Preferences,
|
||||
) {
|
||||
val subNodes = rootNode.childrenNames()
|
||||
|
||||
for (subNodeName in subNodes) {
|
||||
val subNode = rootNode.node(subNodeName)
|
||||
val key =
|
||||
if (parent != null) {
|
||||
"$parent/$subNodeName"
|
||||
} else {
|
||||
subNodeName
|
||||
}
|
||||
val preferences = Injekt.get<Application>().getSharedPreferences(key, Context.MODE_PRIVATE)
|
||||
|
||||
val items: Map<String, String?> =
|
||||
subNode.keys().associateWith {
|
||||
subNode[it, null]?.ifBlank { null }
|
||||
}
|
||||
|
||||
preferences.edit().apply {
|
||||
items.forEach { (key, value) ->
|
||||
if (value != null) {
|
||||
putString(key, value)
|
||||
}
|
||||
}
|
||||
}.apply()
|
||||
|
||||
migratePreferences(key, subNode) // Recursively migrate sub-level nodes
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user