Don't rely on cache when deleting empty manga folders

In case the cache hasn't actually been indexed yet. Maybe fixes #8438.
This commit is contained in:
arkon 2022-11-14 22:42:36 -05:00
parent 10e349f76e
commit f5873d70c6
4 changed files with 61 additions and 65 deletions

View file

@ -214,12 +214,8 @@ class DownloadCache(
}
@Synchronized
fun removeSourceIfEmpty(source: Source) {
val sourceDir = provider.findSourceDir(source)
if (sourceDir?.listFiles()?.isEmpty() == true) {
sourceDir.delete()
fun removeSource(source: Source) {
rootDownloadsDir.sourceDirs -= source.id
}
notifyChanges()
}

View file

@ -247,21 +247,27 @@ class DownloadManager(
getChaptersToDelete(chapters, manga)
}
if (filteredChapters.isNotEmpty()) {
launchIO {
removeFromDownloadQueue(filteredChapters)
val chapterDirs = provider.findChapterDirs(filteredChapters, manga, source)
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()
if (mangaDir?.listFiles()?.isEmpty() == true) {
mangaDir.delete()
cache.removeManga(manga)
}
// Delete source directory if empty
cache.removeSourceIfEmpty(source)
val sourceDir = provider.findSourceDir(source)
if (sourceDir?.listFiles()?.isEmpty() == true) {
sourceDir.delete()
cache.removeSource(source)
}
}
}
}
return filteredChapters
@ -334,13 +340,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}." }
}
}

View file

@ -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,36 @@ class DownloadPendingDeleter(context: Context) {
return newList
}
/**
* Returns a manga entry from a manga model.
*/
private fun Manga.toEntry() = MangaEntry(id, url, title, 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,
title = title,
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.
*/
@ -150,42 +182,4 @@ class DownloadPendingDeleter(context: Context) {
val title: String,
val source: Long,
)
/**
* Returns a manga entry from a manga model.
*/
private fun Manga.toEntry(): MangaEntry {
return MangaEntry(id, url, title, source)
}
/**
* Returns a chapter entry from a chapter model.
*/
private fun Chapter.toEntry(): ChapterEntry {
return ChapterEntry(id!!, url, name, scanlator)
}
/**
* Returns a manga model from a manga entry.
*/
private fun MangaEntry.toModel(): Manga {
return Manga.create().copy(
url = url,
title = title,
source = source,
id = id,
)
}
/**
* Returns a chapter model from a chapter entry.
*/
private fun ChapterEntry.toModel(): Chapter {
return Chapter.create().copy(
id = id,
url = url,
name = name,
scanlator = scanlator,
)
}
}

View file

@ -104,9 +104,9 @@ class DownloadProvider(
* @param manga the manga of the chapter.
* @param source the source of the chapter.
*/
fun findChapterDirs(chapters: List<Chapter>, manga: Manga, source: Source): List<UniFile> {
val mangaDir = findMangaDir(manga.title, source) ?: return emptyList()
return chapters.mapNotNull { chapter ->
fun findChapterDirs(chapters: List<Chapter>, manga: Manga, source: Source): Pair<UniFile?, List<UniFile>> {
val mangaDir = findMangaDir(manga.title, source) ?: return null to emptyList()
return mangaDir to chapters.mapNotNull { chapter ->
getValidChapterDirNames(chapter.name, chapter.scanlator).asSequence()
.mapNotNull { mangaDir.findFile(it) }
.firstOrNull()