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
|
* 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/. */
|
* 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 ch.qos.logback.classic.Level
|
||||||
import com.typesafe.config.ConfigRenderOptions
|
import com.typesafe.config.ConfigRenderOptions
|
||||||
import eu.kanade.tachiyomi.App
|
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.generated.BuildConfig
|
||||||
import suwayomi.tachidesk.server.util.AppMutex.handleAppMutex
|
import suwayomi.tachidesk.server.util.AppMutex.handleAppMutex
|
||||||
import suwayomi.tachidesk.server.util.SystemTray
|
import suwayomi.tachidesk.server.util.SystemTray
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import xyz.nulldev.androidcompat.AndroidCompat
|
import xyz.nulldev.androidcompat.AndroidCompat
|
||||||
import xyz.nulldev.androidcompat.AndroidCompatInitializer
|
import xyz.nulldev.androidcompat.AndroidCompatInitializer
|
||||||
@@ -47,7 +44,6 @@ import xyz.nulldev.ts.config.setLogLevelFor
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.security.Security
|
import java.security.Security
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.prefs.Preferences
|
|
||||||
|
|
||||||
private val logger = KotlinLogging.logger {}
|
private val logger = KotlinLogging.logger {}
|
||||||
|
|
||||||
@@ -126,23 +122,6 @@ fun applicationSetup() {
|
|||||||
File("$ApplicationRootDir/manga-local").renameTo(applicationDirs.localMangaRoot)
|
File("$ApplicationRootDir/manga-local").renameTo(applicationDirs.localMangaRoot)
|
||||||
File("$ApplicationRootDir/anime-thumbnails").delete()
|
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
|
// make dirs we need
|
||||||
listOf(
|
listOf(
|
||||||
applicationDirs.dataRoot,
|
applicationDirs.dataRoot,
|
||||||
@@ -217,13 +196,7 @@ fun applicationSetup() {
|
|||||||
}
|
}
|
||||||
}, ignoreInitialValue = false)
|
}, ignoreInitialValue = false)
|
||||||
|
|
||||||
val prefRootNode = "suwayomi/tachidesk"
|
runMigrations(applicationDirs)
|
||||||
val isMigrationRequired = Preferences.userRoot().nodeExists(prefRootNode)
|
|
||||||
if (isMigrationRequired) {
|
|
||||||
val preferences = Preferences.userRoot().node(prefRootNode)
|
|
||||||
migratePreferences(null, preferences)
|
|
||||||
preferences.removeNode()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable jetty's logging
|
// Disable jetty's logging
|
||||||
System.setProperty("org.eclipse.jetty.util.log.announce", "false")
|
System.setProperty("org.eclipse.jetty.util.log.announce", "false")
|
||||||
@@ -265,36 +238,3 @@ fun applicationSetup() {
|
|||||||
// start DownloadManager and restore + resume downloads
|
// start DownloadManager and restore + resume downloads
|
||||||
DownloadManager.restoreAndResumeDownloads()
|
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