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:
parent
10e349f76e
commit
f5873d70c6
4 changed files with 61 additions and 65 deletions
|
@ -214,12 +214,8 @@ class DownloadCache(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun removeSourceIfEmpty(source: Source) {
|
fun removeSource(source: Source) {
|
||||||
val sourceDir = provider.findSourceDir(source)
|
|
||||||
if (sourceDir?.listFiles()?.isEmpty() == true) {
|
|
||||||
sourceDir.delete()
|
|
||||||
rootDownloadsDir.sourceDirs -= source.id
|
rootDownloadsDir.sourceDirs -= source.id
|
||||||
}
|
|
||||||
|
|
||||||
notifyChanges()
|
notifyChanges()
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,21 +247,27 @@ class DownloadManager(
|
||||||
getChaptersToDelete(chapters, manga)
|
getChaptersToDelete(chapters, manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filteredChapters.isNotEmpty()) {
|
||||||
launchIO {
|
launchIO {
|
||||||
removeFromDownloadQueue(filteredChapters)
|
removeFromDownloadQueue(filteredChapters)
|
||||||
|
|
||||||
val chapterDirs = provider.findChapterDirs(filteredChapters, manga, source)
|
val (mangaDir, chapterDirs) = provider.findChapterDirs(filteredChapters, manga, source)
|
||||||
chapterDirs.forEach { it.delete() }
|
chapterDirs.forEach { it.delete() }
|
||||||
cache.removeChapters(filteredChapters, manga)
|
cache.removeChapters(filteredChapters, manga)
|
||||||
|
|
||||||
// Delete manga directory if empty
|
// Delete manga directory if empty
|
||||||
if (cache.getDownloadCount(manga) == 0) {
|
if (mangaDir?.listFiles()?.isEmpty() == true) {
|
||||||
chapterDirs.firstOrNull()?.parentFile?.delete()
|
mangaDir.delete()
|
||||||
cache.removeManga(manga)
|
cache.removeManga(manga)
|
||||||
}
|
|
||||||
|
|
||||||
// Delete source directory if empty
|
// 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
|
return filteredChapters
|
||||||
|
@ -334,13 +340,13 @@ class DownloadManager(
|
||||||
if (capitalizationChanged) {
|
if (capitalizationChanged) {
|
||||||
val tempName = newName + "_tmp"
|
val tempName = newName + "_tmp"
|
||||||
if (oldFolder.renameTo(tempName).not()) {
|
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
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldFolder.renameTo(newName).not()) {
|
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}." }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,18 @@ import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
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.
|
* Class used to keep a list of chapters for future deletion.
|
||||||
*
|
*
|
||||||
* @param context the application context.
|
* @param context the application context.
|
||||||
*/
|
*/
|
||||||
class DownloadPendingDeleter(context: Context) {
|
class DownloadPendingDeleter(
|
||||||
|
context: Context,
|
||||||
private val json: Json by injectLazy()
|
private val json: Json = Injekt.get(),
|
||||||
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preferences used to store the list of chapters to delete.
|
* Preferences used to store the list of chapters to delete.
|
||||||
|
@ -120,6 +122,36 @@ class DownloadPendingDeleter(context: Context) {
|
||||||
return newList
|
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.
|
* 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 title: String,
|
||||||
val source: Long,
|
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,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,9 +104,9 @@ class DownloadProvider(
|
||||||
* @param manga the manga of the chapter.
|
* @param manga the manga of the chapter.
|
||||||
* @param source the source of the chapter.
|
* @param source the source of the chapter.
|
||||||
*/
|
*/
|
||||||
fun findChapterDirs(chapters: List<Chapter>, manga: Manga, source: Source): List<UniFile> {
|
fun findChapterDirs(chapters: List<Chapter>, manga: Manga, source: Source): Pair<UniFile?, List<UniFile>> {
|
||||||
val mangaDir = findMangaDir(manga.title, source) ?: return emptyList()
|
val mangaDir = findMangaDir(manga.title, source) ?: return null to emptyList()
|
||||||
return chapters.mapNotNull { chapter ->
|
return mangaDir to chapters.mapNotNull { chapter ->
|
||||||
getValidChapterDirNames(chapter.name, chapter.scanlator).asSequence()
|
getValidChapterDirNames(chapter.name, chapter.scanlator).asSequence()
|
||||||
.mapNotNull { mangaDir.findFile(it) }
|
.mapNotNull { mangaDir.findFile(it) }
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
|
|
Reference in a new issue