From b4e73cb1eb3b86f9a0275706ef8a924679272527 Mon Sep 17 00:00:00 2001 From: Jobobby04 Date: Sat, 5 Sep 2020 19:43:12 -0400 Subject: [PATCH] Upgrade the cleanup downloads to the new J2k version --- .../data/download/DownloadManager.kt | 41 ++++++++++++++--- .../data/download/DownloadProvider.kt | 2 +- .../ui/setting/SettingsAdvancedController.kt | 45 ++++++++++++++++--- app/src/main/res/values/arrays_sy.xml | 8 ++++ app/src/main/res/values/strings_sy.xml | 3 ++ 5 files changed, 85 insertions(+), 14 deletions(-) create mode 100644 app/src/main/res/values/arrays_sy.xml 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 c2ba2b393..c872ee31f 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 @@ -214,6 +214,13 @@ class DownloadManager(/* SY private */ val context: Context) { } // SY --> + /** + * return the list of all manga folders + */ + fun getMangaFolders(source: Source): List { + return provider.findSourceDir(source)?.listFiles()?.toList() ?: emptyList() + } + /** * Deletes the directories of chapters that were read or have no match * @@ -221,19 +228,39 @@ class DownloadManager(/* SY private */ val context: Context) { * @param manga the manga of the chapters. * @param source the source of the chapters. */ - fun cleanupChapters(allChapters: List, manga: Manga, source: Source): Int { + fun cleanupChapters(allChapters: List, manga: Manga, source: Source, removeRead: Boolean, removeNonFavorite: Boolean): Int { var cleaned = 0 + + if (removeNonFavorite && !manga.favorite) { + val mangaFolder = provider.getMangaDir(manga, source) + cleaned += 1 + (mangaFolder.listFiles()?.size ?: 0) + mangaFolder.delete() + cache.removeManga(manga) + return cleaned + } + val filesWithNoChapter = provider.findUnmatchedChapterDirs(allChapters, manga, source) cleaned += filesWithNoChapter.size cache.removeFolders(filesWithNoChapter.mapNotNull { it.name }, manga) filesWithNoChapter.forEach { it.delete() } - val readChapters = allChapters.filter { it.read } - val readChapterDirs = provider.findChapterDirs(readChapters, manga, source) - readChapterDirs.forEach { it.delete() } - cleaned += readChapterDirs.size - cache.removeChapters(readChapters, manga) + + if (removeRead) { + val readChapters = allChapters.filter { it.read } + val readChapterDirs = provider.findChapterDirs(readChapters, manga, source) + readChapterDirs.forEach { it.delete() } + cleaned += readChapterDirs.size + cache.removeChapters(readChapters, manga) + } + if (cache.getDownloadCount(manga) == 0) { - provider.findChapterDirs(allChapters, manga, source).firstOrNull()?.parentFile?.delete() // Delete manga directory if empty + val mangaFolder = provider.getMangaDir(manga, source) + val size = mangaFolder.listFiles()?.size ?: 0 + if (size == 0) { + mangaFolder.delete() + cache.removeManga(manga) + } else { + Timber.e("Cache and download folder doesn't match for %s", manga.title) + } } return cleaned } 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 310b64db2..5b7dd1a85 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 @@ -130,7 +130,7 @@ class DownloadProvider(private val context: Context) { mangaDir.findFile(dir) ?: mangaDir.findFile("$dir.cbz") != null } } == null - ) || it.name?.endsWith("_tmp") == true + ) || it.name?.endsWith(Downloader.TMP_DIR_SUFFIX) == true } } // SY <-- diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt index dec8598b8..207492600 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsAdvancedController.kt @@ -12,6 +12,7 @@ import androidx.core.net.toUri import androidx.core.text.HtmlCompat import androidx.preference.PreferenceScreen import com.afollestad.materialdialogs.MaterialDialog +import com.afollestad.materialdialogs.list.listItemsMultiChoice import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.cache.ChapterCache import eu.kanade.tachiyomi.data.database.DatabaseHelper @@ -157,7 +158,11 @@ class SettingsAdvancedController : SettingsController() { titleRes = R.string.clean_up_downloaded_chapters summaryRes = R.string.delete_unused_chapters - onClick { cleanupDownloads() } + onClick { + val ctrl = CleanupDownloadsDialogController() + ctrl.targetController = this@SettingsAdvancedController + ctrl.showDialog(router) + } } } @@ -299,7 +304,22 @@ class SettingsAdvancedController : SettingsController() { } // SY --> - private fun cleanupDownloads() { + class CleanupDownloadsDialogController : DialogController() { + override fun onCreateDialog(savedViewState: Bundle?): Dialog { + return MaterialDialog(activity!!).show { + title(R.string.clean_up_downloaded_chapters) + .listItemsMultiChoice(R.array.clean_up_downloads, disabledIndices = intArrayOf(0), initialSelection = intArrayOf(0, 1, 2)) { _, selections, _ -> + val deleteRead = selections.contains(1) + val deleteNonFavorite = selections.contains(2) + (targetController as? SettingsAdvancedController)?.cleanupDownloads(deleteRead, deleteNonFavorite) + } + positiveButton(android.R.string.ok) + negativeButton(android.R.string.cancel) + } + } + } + + private fun cleanupDownloads(removeRead: Boolean, removeNonFavorite: Boolean) { if (job?.isActive == true) return activity?.toast(R.string.starting_cleanup) job = GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) { @@ -307,10 +327,23 @@ class SettingsAdvancedController : SettingsController() { val sourceManager: SourceManager = Injekt.get() val downloadManager: DownloadManager = Injekt.get() var foldersCleared = 0 - mangaList.forEach { manga -> - val chapterList = db.getChapters(manga).executeAsBlocking() - val source = sourceManager.getOrStub(manga.source) - foldersCleared += downloadManager.cleanupChapters(chapterList, manga, source) + val sources = sourceManager.getOnlineSources() + + for (source in sources) { + val mangaFolders = downloadManager.getMangaFolders(source) + val sourceManga = mangaList.filter { it.source == source.id } + + for (mangaFolder in mangaFolders) { + val manga = sourceManga.find { it.originalTitle == mangaFolder.name } + if (manga == null) { + // download is orphaned delete it + foldersCleared += 1 + (mangaFolder.listFiles()?.size ?: 0) + mangaFolder.delete() + continue + } + val chapterList = db.getChapters(manga).executeAsBlocking() + foldersCleared += downloadManager.cleanupChapters(chapterList, manga, source, removeRead, removeNonFavorite) + } } launchUI { val activity = activity ?: return@launchUI diff --git a/app/src/main/res/values/arrays_sy.xml b/app/src/main/res/values/arrays_sy.xml new file mode 100644 index 000000000..06ca2a26e --- /dev/null +++ b/app/src/main/res/values/arrays_sy.xml @@ -0,0 +1,8 @@ + + + + @string/clean_orphaned_downloads + @string/clean_read_downloads + @string/clean_read_manga_not_in_library + + \ No newline at end of file diff --git a/app/src/main/res/values/strings_sy.xml b/app/src/main/res/values/strings_sy.xml index ef705fa33..154715def 100644 --- a/app/src/main/res/values/strings_sy.xml +++ b/app/src/main/res/values/strings_sy.xml @@ -130,6 +130,9 @@ Clean up downloaded chapters Delete non-existent, partially downloaded, and read chapter folders No folders to cleanup + Clean orphaned + Clean read + Clean manga not in library Cleanup done. Removed %d folder Cleanup done. Removed %d folders