From 9686f75a2d560ac955289761c50253cbe77d1a2b Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Mon, 18 May 2026 20:05:21 +0200 Subject: [PATCH] Fix/losing downloads on manga rename during update (#2051) * Fix renaming manga download dir * Simplify manga download dir rename function --------- Co-authored-by: Mitchell Syer --- CHANGELOG.md | 1 + .../suwayomi/tachidesk/manga/impl/Manga.kt | 2 +- .../tachidesk/manga/impl/util/DirName.kt | 39 ++++++++++--------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af1f545aa..72864c60e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). - (**WebUI**) Handle serving non-default webui with "bundled" - (**WebUI**) Wait until WebUI is ready to open in browser - (**Downloads**) Truncate filenames by byte length to prevent "File name too long" IO errors +- (**Downloads**) Fix being unable to find downloads after manga was renamed during an update - (**Downloads**) Fix preserving chapter download states during an update - (**Extension**) Do not indicate an update is available when the extension is not installed - (**Chapter**) Fix losing chapter data on failed chapter list update diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Manga.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Manga.kt index c76eee888..9ccf91930 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Manga.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Manga.kt @@ -133,7 +133,7 @@ object Manga { "" } if (remoteTitle.isNotEmpty() && remoteTitle != mangaEntry[MangaTable.title]) { - val canUpdateTitle = updateMangaDownloadDir(mangaId, remoteTitle) + val canUpdateTitle = updateMangaDownloadDir(mangaEntry[MangaTable.title], source.toString(), remoteTitle) if (canUpdateTitle) { it[MangaTable.title] = remoteTitle diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/DirName.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/DirName.kt index 82d14d3fa..59dc1b2d2 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/DirName.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/util/DirName.kt @@ -24,14 +24,22 @@ private val applicationDirs: ApplicationDirs by injectLazy() private val logger = KotlinLogging.logger { } +private fun getMangaDir( + title: String, + sourceName: String, +): String { + val sourceDir = SafePath.buildValidFilename(sourceName) + val mangaDir = SafePath.buildValidFilename(title) + + return "$sourceDir/$mangaDir" +} + private fun getMangaDir(mangaId: Int): String = transaction { val mangaEntry = MangaTable.selectAll().where { MangaTable.id eq mangaId }.first() val source = GetCatalogueSource.getCatalogueSourceOrStub(mangaEntry[MangaTable.sourceReference]) - val sourceDir = SafePath.buildValidFilename(source.toString()) - val mangaDir = SafePath.buildValidFilename(mangaEntry[MangaTable.title]) - "$sourceDir/$mangaDir" + getMangaDir(mangaEntry[MangaTable.title], source.toString()) } private fun getChapterDir( @@ -62,6 +70,11 @@ private fun getChapterDir( fun getThumbnailDownloadPath(mangaId: Int): String = applicationDirs.thumbnailDownloadsRoot + "/$mangaId" +fun getMangaDownloadDir( + title: String, + sourceName: String, +): String = applicationDirs.mangaDownloadsRoot + "/" + getMangaDir(title, sourceName) + fun getMangaDownloadDir(mangaId: Int): String = applicationDirs.mangaDownloadsRoot + "/" + getMangaDir(mangaId) fun getChapterDownloadPath( @@ -81,24 +94,12 @@ fun getChapterCachePath( /** return value says if rename/move was successful */ fun updateMangaDownloadDir( - mangaId: Int, + title: String, + sourceName: String, newTitle: String, ): Boolean { - // Get current manga directory (uses its own transaction) - val currentMangaDir = getMangaDir(mangaId) - - // Build new directory path - val newMangaDir = - transaction { - val mangaEntry = MangaTable.selectAll().where { MangaTable.id eq mangaId }.first() - val source = GetCatalogueSource.getCatalogueSourceOrStub(mangaEntry[MangaTable.sourceReference]) - val sourceDir = SafePath.buildValidFilename(source.toString()) - val newMangaDirName = SafePath.buildValidFilename(newTitle) - "$sourceDir/$newMangaDirName" - } - - val oldDir = "${applicationDirs.downloadsRoot}/$currentMangaDir" - val newDir = "${applicationDirs.downloadsRoot}/$newMangaDir" + val oldDir = getMangaDownloadDir(title, sourceName) + val newDir = getMangaDownloadDir(newTitle, sourceName) val oldDirFile = File(oldDir) val newDirFile = File(newDir)