mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-23 12:41:50 +01:00
Added toasts to cleanup download
This commit is contained in:
parent
0577c45194
commit
24f5351701
@ -43,6 +43,7 @@ import uy.kohesive.injekt.injectLazy
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Restores backup from json file
|
||||
@ -117,7 +118,7 @@ class BackupRestoreService : Service() {
|
||||
startForeground(Notifications.ID_RESTORE_PROGRESS, progressNotification.build())
|
||||
wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(
|
||||
PowerManager.PARTIAL_WAKE_LOCK, "BackupRestoreService:WakeLock")
|
||||
wakeLock.acquire()
|
||||
wakeLock.acquire(TimeUnit.HOURS.toMillis(3))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -217,6 +217,17 @@ class DownloadCache(
|
||||
}
|
||||
}
|
||||
|
||||
fun removeFolders(folders: List<String>, manga: Manga) {
|
||||
val sourceDir = rootDir.files[manga.source] ?: return
|
||||
val mangaDir = sourceDir.files[provider.getMangaDirName(manga)] ?: return
|
||||
for (chapter in folders) {
|
||||
if (chapter in mangaDir.files) {
|
||||
mangaDir.files -= chapter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes a manga that has been deleted from this cache.
|
||||
*
|
||||
|
@ -219,16 +219,21 @@ class DownloadManager(val context: Context) {
|
||||
* @param manga the manga of the chapters.
|
||||
* @param source the source of the chapters.
|
||||
*/
|
||||
fun cleanupChapters(allChapters: List<Chapter>, manga: Manga, source: Source) {
|
||||
fun cleanupChapters(allChapters: List<Chapter>, manga: Manga, source: Source): Int {
|
||||
var cleaned = 0
|
||||
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 (cache.getDownloadCount(manga) == 0) {
|
||||
provider.findChapterDirs(allChapters, manga, source).firstOrNull()?.parentFile?.delete()// Delete manga directory if empty
|
||||
}
|
||||
return cleaned
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,13 +142,11 @@ class DownloadProvider(private val context: Context) {
|
||||
fun findUnmatchedChapterDirs(chapters: List<Chapter>, manga: Manga, source: Source): List<UniFile> {
|
||||
val mangaDir = findMangaDir(manga, source) ?: return emptyList()
|
||||
return mangaDir.listFiles()!!.asList().filter {
|
||||
chapters.find { chp ->
|
||||
(getValidChapterDirNames(chp) + "${getChapterDirName(chp)}_tmp").any { dir ->
|
||||
mangaDir.findFile(
|
||||
dir
|
||||
) != null
|
||||
(chapters.find { chp ->
|
||||
getValidChapterDirNames(chp).any { dir ->
|
||||
mangaDir.findFile(dir) != null
|
||||
}
|
||||
} == null
|
||||
} == null) || it.name?.endsWith("_tmp") == true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,9 +40,6 @@ import eu.kanade.tachiyomi.util.notification
|
||||
import eu.kanade.tachiyomi.util.notificationManager
|
||||
import eu.kanade.tachiyomi.util.syncChaptersWithSource
|
||||
import kotlinx.coroutines.CoroutineExceptionHandler
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import rx.Observable
|
||||
import rx.Subscription
|
||||
import rx.schedulers.Schedulers
|
||||
@ -52,6 +49,7 @@ import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
import java.util.ArrayList
|
||||
import java.util.Date
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
||||
/**
|
||||
@ -80,8 +78,6 @@ class LibraryUpdateService(
|
||||
*/
|
||||
private var subscription: Subscription? = null
|
||||
|
||||
var job: Job? = null
|
||||
|
||||
|
||||
/**
|
||||
* Pending intent of action that cancels the library update
|
||||
@ -116,8 +112,7 @@ class LibraryUpdateService(
|
||||
enum class Target {
|
||||
CHAPTERS, // Manga chapters
|
||||
DETAILS, // Manga metadata
|
||||
TRACKING, // Tracking metadata
|
||||
CLEANUP // Clean up downloads
|
||||
TRACKING // Tracking metadata
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -184,7 +179,7 @@ class LibraryUpdateService(
|
||||
startForeground(Notifications.ID_LIBRARY_PROGRESS, progressNotification.build())
|
||||
wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(
|
||||
PowerManager.PARTIAL_WAKE_LOCK, "LibraryUpdateService:WakeLock")
|
||||
wakeLock.acquire()
|
||||
wakeLock.acquire(TimeUnit.MINUTES.toMillis(30))
|
||||
}
|
||||
|
||||
/**
|
||||
@ -222,22 +217,16 @@ class LibraryUpdateService(
|
||||
// Unsubscribe from any previous subscription if needed.
|
||||
subscription?.unsubscribe()
|
||||
|
||||
val selectedScheme = preferences.libraryUpdatePrioritization().getOrDefault()
|
||||
// Update favorite manga. Destroy service when completed or in case of an error.
|
||||
val mangaList = getMangaToUpdate(intent, target)
|
||||
.sortedWith(rankingScheme[selectedScheme])
|
||||
|
||||
val handler = CoroutineExceptionHandler { _, exception ->
|
||||
Timber.e(exception)
|
||||
stopSelf(startId)
|
||||
}
|
||||
// Update either chapter list or manga details.
|
||||
if (target == Target.CLEANUP) {
|
||||
job = GlobalScope.launch(handler) {
|
||||
cleanupDownloads()
|
||||
}
|
||||
job?.invokeOnCompletion { stopSelf(startId) }
|
||||
} else {
|
||||
val selectedScheme = preferences.libraryUpdatePrioritization().getOrDefault()
|
||||
// Update favorite manga. Destroy service when completed or in case of an error.
|
||||
val mangaList = getMangaToUpdate(intent, target)
|
||||
.sortedWith(rankingScheme[selectedScheme])
|
||||
subscription = Observable.defer {
|
||||
when (target) {
|
||||
Target.CHAPTERS -> updateChapterList(mangaList)
|
||||
@ -250,7 +239,6 @@ class LibraryUpdateService(
|
||||
}, {
|
||||
stopSelf(startId)
|
||||
})
|
||||
}
|
||||
return START_REDELIVER_INTENT
|
||||
}
|
||||
|
||||
@ -360,11 +348,13 @@ class LibraryUpdateService(
|
||||
|
||||
private fun cleanupDownloads() {
|
||||
val mangaList = db.getMangas().executeAsBlocking()
|
||||
var foldersCleared = 0
|
||||
for (manga in mangaList) {
|
||||
val chapterList = db.getChapters(manga).executeAsBlocking()
|
||||
val source = sourceManager.getOrStub(manga.source)
|
||||
downloadManager.cleanupChapters(chapterList, manga, source)
|
||||
foldersCleared += downloadManager.cleanupChapters(chapterList, manga, source)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
|
||||
|
@ -4,21 +4,33 @@ import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import androidx.preference.PreferenceScreen
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.bluelinelabs.conductor.RouterTransaction
|
||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.cache.ChapterCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService
|
||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Target
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.library.LibraryController
|
||||
import eu.kanade.tachiyomi.util.launchUI
|
||||
import eu.kanade.tachiyomi.util.toast
|
||||
import kotlinx.coroutines.CoroutineStart
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import rx.Observable
|
||||
import rx.android.schedulers.AndroidSchedulers
|
||||
import rx.schedulers.Schedulers
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class SettingsAdvancedController : SettingsController() {
|
||||
@ -74,10 +86,33 @@ class SettingsAdvancedController : SettingsController() {
|
||||
|
||||
summaryRes = R.string.pref_clean_downloads_summary
|
||||
|
||||
onClick { LibraryUpdateService.start(context, target = Target.CLEANUP) }
|
||||
onClick { cleanupDownloads() }
|
||||
}
|
||||
}
|
||||
|
||||
private fun cleanupDownloads() {
|
||||
if (job?.isActive == true) return
|
||||
activity?.toast(R.string.starting_cleanup)
|
||||
job = GlobalScope.launch(Dispatchers.IO, CoroutineStart.DEFAULT) {
|
||||
val mangaList = db.getMangas().executeAsBlocking()
|
||||
val sourceManager: SourceManager = Injekt.get()
|
||||
val downloadManager: DownloadManager = Injekt.get()
|
||||
var foldersCleared = 0
|
||||
for (manga in mangaList) {
|
||||
val chapterList = db.getChapters(manga).executeAsBlocking()
|
||||
val source = sourceManager.getOrStub(manga.source)
|
||||
foldersCleared += downloadManager.cleanupChapters(chapterList, manga, source)
|
||||
}
|
||||
launchUI {
|
||||
val activity = activity ?: return@launchUI
|
||||
val cleanupString = if (foldersCleared == 0) activity.getString(R.string.no_cleanup_done)
|
||||
else resources!!.getQuantityString(R.plurals.cleanup_done, foldersCleared, foldersCleared)
|
||||
activity.toast(cleanupString, Toast.LENGTH_LONG)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun clearChapterCache() {
|
||||
if (activity == null) return
|
||||
val files = chapterCache.cacheDir.listFiles() ?: return
|
||||
@ -128,5 +163,7 @@ class SettingsAdvancedController : SettingsController() {
|
||||
|
||||
private companion object {
|
||||
const val CLEAR_CACHE_KEY = "pref_clear_cache_key"
|
||||
|
||||
private var job: Job? = null
|
||||
}
|
||||
}
|
||||
|
@ -355,9 +355,16 @@
|
||||
<string name="pref_refresh_library_tracking">Refresh tracking metadata</string>
|
||||
<string name="pref_refresh_library_tracking_summary">Updates status, score and last chapter read from the tracking services</string>
|
||||
<string name="pref_clean_downloads">Clean up downloaded chapters</string>
|
||||
<string name="pref_clean_downloads_summary">Deletes non-existent, partially downloaded,
|
||||
<string name="pref_clean_downloads_summary">Delete non-existent, partially downloaded,
|
||||
and read chapter folders</string>
|
||||
|
||||
<string name="starting_cleanup">Starting cleanup</string>
|
||||
<string name="no_cleanup_done">No folders to cleanup</string>
|
||||
<plurals name="cleanup_done">
|
||||
<item quantity="one">Cleanup done. Removed %d folder</item>
|
||||
<item quantity="other">Cleanup done. Removed %d folders</item>
|
||||
</plurals>
|
||||
|
||||
<!-- About section -->
|
||||
<string name="version">Version</string>
|
||||
<string name="build_time">Build time</string>
|
||||
|
Loading…
Reference in New Issue
Block a user