From b6e5943e155c9d49a2cdafaa782b058037fbdebc Mon Sep 17 00:00:00 2001 From: AntsyLich <59261191+AntsyLich@users.noreply.github.com> Date: Mon, 5 May 2025 01:02:08 +0600 Subject: [PATCH] Fix downloader stopping after failing to create download directory of a manga (#2068) (cherry picked from commit 536393a6d9941fac282f10b825aa611b91e1fcdb) # Conflicts: # CHANGELOG.md # app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt # app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt --- .../data/download/DownloadManager.kt | 20 +++++---- .../data/download/DownloadProvider.kt | 41 +++++++++++++------ .../tachiyomi/data/download/Downloader.kt | 6 ++- .../moko-resources/base/strings.xml | 2 + 4 files changed, 49 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt index 33c504b29..f70c2afc1 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadManager.kt @@ -316,10 +316,13 @@ class DownloadManager( if (removeNonFavorite && !manga.favorite) { val mangaFolder = provider.getMangaDir(/* SY --> */ manga.ogTitle /* SY <-- */, source) - cleaned += 1 + mangaFolder.listFiles().orEmpty().size - mangaFolder.delete() - cache.removeManga(manga) - return cleaned + .getOrNull() + if (mangaFolder != null) { + cleaned += 1 + mangaFolder.listFiles().orEmpty().size + mangaFolder.delete() + cache.removeManga(manga) + return cleaned + } } val filesWithNoChapter = provider.findUnmatchedChapterDirs(allChapters, manga, source) @@ -336,8 +339,8 @@ class DownloadManager( } if (cache.getDownloadCount(manga) == 0) { - val mangaFolder = provider.getMangaDir(/* SY --> */ manga.ogTitle /* SY <-- */, source) - if (!mangaFolder.listFiles().isNullOrEmpty()) { + val mangaFolder = provider.getMangaDir(/* SY --> */ manga.ogTitle /* SY <-- */, source).getOrNull() + if (mangaFolder != null && !mangaFolder.listFiles().isNullOrEmpty()) { mangaFolder.delete() cache.removeManga(manga) } else { @@ -405,7 +408,10 @@ class DownloadManager( */ suspend fun renameChapter(source: Source, manga: Manga, oldChapter: Chapter, newChapter: Chapter) { val oldNames = provider.getValidChapterDirNames(oldChapter.name, oldChapter.scanlator) - val mangaDir = provider.getMangaDir(/* SY --> */ manga.ogTitle /* SY <-- */, source) + val mangaDir = provider.getMangaDir(/* SY --> */ manga.ogTitle /* SY <-- */, source).getOrElse { e -> + logcat(LogPriority.ERROR, e) { "Manga download folder doesn't exist. Skipping renaming after source sync" } + return + } // Assume there's only 1 version of the chapter name formats present val oldDownload = oldNames.asSequence() diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt index d2179ef49..1dcf9e129 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt @@ -14,6 +14,7 @@ import tachiyomi.domain.storage.service.StorageManager import tachiyomi.i18n.MR import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.api.get +import java.io.IOException /** * This class is used to provide the directories where the downloads should be saved. @@ -35,20 +36,36 @@ class DownloadProvider( * @param mangaTitle the title of the manga to query. * @param source the source of the manga. */ - internal fun getMangaDir(mangaTitle: String, source: Source): UniFile { - try { - return downloadsDir!! - .createDirectory(getSourceDirName(source))!! - .createDirectory(getMangaDirName(mangaTitle))!! - } catch (e: Throwable) { - logcat(LogPriority.ERROR, e) { "Invalid download directory" } - throw Exception( - context.stringResource( - MR.strings.invalid_location, - downloadsDir?.displayablePath ?: "", - ), + internal fun getMangaDir(mangaTitle: String, source: Source): Result { + val downloadsDir = downloadsDir + if (downloadsDir == null) { + logcat(LogPriority.ERROR) { "Failed to create download directory" } + return Result.failure( + IOException(context.stringResource(MR.strings.storage_failed_to_create_download_directory)), ) } + + val sourceDirName = getSourceDirName(source) + val sourceDir = downloadsDir.createDirectory(sourceDirName) + if (sourceDir == null) { + val displayablePath = downloadsDir.displayablePath + "/$sourceDirName" + logcat(LogPriority.ERROR) { "Failed to create source download directory: $displayablePath" } + return Result.failure( + IOException(context.stringResource(MR.strings.storage_failed_to_create_directory, displayablePath)), + ) + } + + val mangaDirName = getMangaDirName(mangaTitle) + val mangaDir = sourceDir.createDirectory(mangaDirName) + if (mangaDir == null) { + val displayablePath = sourceDir.displayablePath + "/$mangaDirName" + logcat(LogPriority.ERROR) { "Failed to create manga download directory: $displayablePath" } + return Result.failure( + IOException(context.stringResource(MR.strings.storage_failed_to_create_directory, displayablePath)), + ) + } + + return Result.success(mangaDir) } /** diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt index c53b8def1..3ac53ee2d 100755 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/Downloader.kt @@ -327,7 +327,11 @@ class Downloader( * @param download the chapter to be downloaded. */ private suspend fun downloadChapter(download: Download) { - val mangaDir = provider.getMangaDir(/* SY --> */ download.manga.ogTitle /* SY <-- */, download.source) + val mangaDir = provider.getMangaDir(/* SY --> */ download.manga.ogTitle /* SY <-- */, download.source).getOrElse { e -> + download.status = Download.State.ERROR + notifier.onError(e.message, download.chapter.name, download.manga.title, download.manga.id) + return + } val availSpace = DiskUtil.getAvailableStorageSpace(mangaDir) if (availSpace != -1L && availSpace < MIN_DISK_SPACE) { diff --git a/i18n/src/commonMain/moko-resources/base/strings.xml b/i18n/src/commonMain/moko-resources/base/strings.xml index d0baa3160..d698f6aca 100755 --- a/i18n/src/commonMain/moko-resources/base/strings.xml +++ b/i18n/src/commonMain/moko-resources/base/strings.xml @@ -498,6 +498,8 @@ Excluded categories No storage location set Invalid location: %s + Failed to create download directory + Failed to create directory: %s Disabled Last read chapter Second to last read chapter