From a1accd3ed36d204c07a4d0c796a1f0da14210aaa Mon Sep 17 00:00:00 2001 From: arkon Date: Mon, 14 Nov 2022 22:42:36 -0500 Subject: [PATCH] Don't rely on cache when deleting empty manga folders In case the cache hasn't actually been indexed yet. Maybe fixes #8438. (cherry picked from commit f5873d70c640b9deb53a9a62281403b9a657e644) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt # app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadProvider.kt --- .../tachiyomi/data/download/DownloadCache.kt | 8 +--- .../data/download/DownloadManager.kt | 34 ++++++++------- .../data/download/DownloadPendingDeleter.kt | 42 +++++++++++++++++-- .../data/download/DownloadProvider.kt | 6 +-- 4 files changed, 63 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt index 9071a51d8..415f7cdea 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadCache.kt @@ -229,12 +229,8 @@ class DownloadCache( } @Synchronized - fun removeSourceIfEmpty(source: Source) { - val sourceDir = provider.findSourceDir(source) - if (sourceDir?.listFiles()?.isEmpty() == true) { - sourceDir.delete() - rootDownloadsDir.sourceDirs -= source.id - } + fun removeSource(source: Source) { + rootDownloadsDir.sourceDirs -= source.id notifyChanges() } 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 c0e5713a8..0c8a33ef0 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 @@ -250,21 +250,27 @@ class DownloadManager( getChaptersToDelete(chapters, manga) } - launchIO { - removeFromDownloadQueue(filteredChapters) + if (filteredChapters.isNotEmpty()) { + launchIO { + removeFromDownloadQueue(filteredChapters) - val chapterDirs = provider.findChapterDirs(filteredChapters, manga, source) - chapterDirs.forEach { it.delete() } - cache.removeChapters(filteredChapters, manga) + val (mangaDir, chapterDirs) = provider.findChapterDirs(filteredChapters, manga, source) + chapterDirs.forEach { it.delete() } + cache.removeChapters(filteredChapters, manga) - // Delete manga directory if empty - if (cache.getDownloadCount(manga) == 0) { - chapterDirs.firstOrNull()?.parentFile?.delete() - cache.removeManga(manga) + // Delete manga directory if empty + if (mangaDir?.listFiles()?.isEmpty() == true) { + mangaDir.delete() + cache.removeManga(manga) + + // Delete source directory if empty + val sourceDir = provider.findSourceDir(source) + if (sourceDir?.listFiles()?.isEmpty() == true) { + sourceDir.delete() + cache.removeSource(source) + } + } } - - // Delete source directory if empty - cache.removeSourceIfEmpty(source) } return filteredChapters @@ -389,13 +395,13 @@ class DownloadManager( if (capitalizationChanged) { val tempName = newName + "_tmp" if (oldFolder.renameTo(tempName).not()) { - logcat(LogPriority.ERROR) { "Could not rename source download folder: ${oldFolder.name}." } + logcat(LogPriority.ERROR) { "Failed to rename source download folder: ${oldFolder.name}." } return } } if (oldFolder.renameTo(newName).not()) { - logcat(LogPriority.ERROR) { "Could not rename source download folder: ${oldFolder.name}." } + logcat(LogPriority.ERROR) { "Failed to rename source download folder: ${oldFolder.name}." } } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt index 95383ddee..a8d6ad92e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/download/DownloadPendingDeleter.kt @@ -8,16 +8,18 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -import uy.kohesive.injekt.injectLazy +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get /** * Class used to keep a list of chapters for future deletion. * * @param context the application context. */ -class DownloadPendingDeleter(context: Context) { - - private val json: Json by injectLazy() +class DownloadPendingDeleter( + context: Context, + private val json: Json = Injekt.get(), +) { /** * Preferences used to store the list of chapters to delete. @@ -120,6 +122,38 @@ class DownloadPendingDeleter(context: Context) { return newList } + /** + * Returns a manga entry from a manga model. + */ + private fun Manga.toEntry() = MangaEntry(id, url, /* SY --> */ ogTitle /* SY <-- */, source) + + /** + * Returns a chapter entry from a chapter model. + */ + private fun Chapter.toEntry() = ChapterEntry(id, url, name, scanlator) + + /** + * Returns a manga model from a manga entry. + */ + private fun MangaEntry.toModel() = Manga.create().copy( + url = url, + // SY --> + ogTitle = title, + // SY <-- + source = source, + id = id, + ) + + /** + * Returns a chapter model from a chapter entry. + */ + private fun ChapterEntry.toModel() = Chapter.create().copy( + id = id, + url = url, + name = name, + scanlator = scanlator, + ) + /** * Class used to save an entry of chapters with their manga into preferences. */ 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 95de7969c..c294c25b8 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 @@ -104,9 +104,9 @@ class DownloadProvider( * @param manga the manga of the chapter. * @param source the source of the chapter. */ - fun findChapterDirs(chapters: List, manga: Manga, source: Source): List { - val mangaDir = findMangaDir(/* SY --> */ manga.ogTitle /* SY <-- */, source) ?: return emptyList() - return chapters.mapNotNull { chapter -> + fun findChapterDirs(chapters: List, manga: Manga, source: Source): Pair> { + val mangaDir = findMangaDir(/* SY --> */ manga.ogTitle /* SY <-- */, source) ?: return null to emptyList() + return mangaDir to chapters.mapNotNull { chapter -> getValidChapterDirNames(chapter.name, chapter.scanlator).asSequence() .mapNotNull { mangaDir.findFile(it) } .firstOrNull()