Skip to content

Commit

Permalink
Seperate out migrations to allow run-once migrations (#882)
Browse files Browse the repository at this point in the history
* Seperate out migrations to allow run-once migrations

* Previous

* Move migrations to a new file
  • Loading branch information
Syer10 authored Feb 19, 2024
1 parent 525a974 commit dda86cd
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 61 deletions.
86 changes: 86 additions & 0 deletions server/src/main/kotlin/suwayomi/tachidesk/server/Migration.kt
Original file line number Diff line number Diff line change
@@ -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()
}
62 changes: 1 addition & 61 deletions server/src/main/kotlin/suwayomi/tachidesk/server/ServerSetup.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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 {}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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
}
}

0 comments on commit dda86cd

Please sign in to comment.