mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-09-10 22:23:15 +02:00
Reworking cache logic
This commit is contained in:
parent
723cf74b6d
commit
fda8a85882
@ -3,16 +3,16 @@ package eu.kanade.tachiyomi.data.download
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import com.hippo.unifile.UniFile
|
import com.hippo.unifile.UniFile
|
||||||
|
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
import eu.kanade.tachiyomi.data.database.models.Chapter
|
||||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||||
import eu.kanade.tachiyomi.source.Source
|
|
||||||
import eu.kanade.tachiyomi.source.SourceManager
|
import eu.kanade.tachiyomi.source.SourceManager
|
||||||
import eu.kanade.tachiyomi.util.DiskUtil
|
import eu.kanade.tachiyomi.util.DiskUtil
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.io.File
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,14 +47,15 @@ class DownloadCache(
|
|||||||
/**
|
/**
|
||||||
* The root directory for downloads.
|
* The root directory for downloads.
|
||||||
*/
|
*/
|
||||||
private var rootDir = RootDirectory(getDirectoryFromPreference())
|
//private var rootDir = RootDirectory(getDirectoryFromPreference())
|
||||||
|
private var mangaFiles: MutableMap<Long, MutableSet<String>> = mutableMapOf()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
preferences.downloadsDirectory().asObservable()
|
preferences.downloadsDirectory().asObservable()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.subscribe {
|
.subscribe {
|
||||||
lastRenew = 0L // invalidate cache
|
lastRenew = 0L // invalidate cache
|
||||||
rootDir = RootDirectory(getDirectoryFromPreference())
|
//rootDir = RootDirectory(getDirectoryFromPreference())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,14 +82,8 @@ class DownloadCache(
|
|||||||
|
|
||||||
checkRenew()
|
checkRenew()
|
||||||
|
|
||||||
val sourceDir = rootDir.files[manga.source]
|
val files = mangaFiles[manga.id] ?: return false
|
||||||
if (sourceDir != null) {
|
return files.any { it in provider.getValidChapterDirNames(chapter) }
|
||||||
val mangaDir = sourceDir.files[provider.getMangaDirName(manga)]
|
|
||||||
if (mangaDir != null) {
|
|
||||||
return mangaDir.files.any { it in provider.getValidChapterDirNames(chapter) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,16 +94,8 @@ class DownloadCache(
|
|||||||
fun getDownloadCount(manga: Manga): Int {
|
fun getDownloadCount(manga: Manga): Int {
|
||||||
checkRenew()
|
checkRenew()
|
||||||
|
|
||||||
val sourceDir = rootDir.files[manga.source]
|
val files = mangaFiles[manga.id] ?: return 0
|
||||||
if (sourceDir != null) {
|
return files.filter { !it.endsWith(Downloader.TMP_DIR_SUFFIX) }.size
|
||||||
val mangaDir = sourceDir.files[provider.getMangaDirName(manga)]
|
|
||||||
if (mangaDir != null) {
|
|
||||||
return mangaDir.files
|
|
||||||
.filter { !it.endsWith(Downloader.TMP_DIR_SUFFIX) }
|
|
||||||
.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,30 +115,47 @@ class DownloadCache(
|
|||||||
private fun renew() {
|
private fun renew() {
|
||||||
val onlineSources = sourceManager.getOnlineSources()
|
val onlineSources = sourceManager.getOnlineSources()
|
||||||
|
|
||||||
val sourceDirs = rootDir.dir.listFiles()
|
val sourceDirs = getDirectoryFromPreference().listFiles()
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
.associate { it.name to SourceDirectory(it) }
|
.associate { it.name to SourceDirectory(it) }
|
||||||
.mapNotNullKeys { entry ->
|
.mapNotNullKeys { entry ->
|
||||||
onlineSources.find { provider.getSourceDirName(it) == entry.key }?.id
|
onlineSources.find { provider.getSourceDirName(it) == entry.key }?.id
|
||||||
}
|
}
|
||||||
|
//Timber.i("Sources: ${sourceDirs.map { it.value.dir.filePath }.joinToString(", ")}")
|
||||||
|
|
||||||
rootDir.files = sourceDirs
|
//rootDir.files = sourceDirs
|
||||||
|
|
||||||
sourceDirs.values.forEach { sourceDir ->
|
val db:DatabaseHelper by injectLazy()
|
||||||
|
val mangas = db.getLibraryMangas().executeAsBlocking()
|
||||||
|
|
||||||
|
sourceDirs.forEach { sourceValue ->
|
||||||
|
val sourceDir = sourceValue.value
|
||||||
val mangaDirs = sourceDir.dir.listFiles()
|
val mangaDirs = sourceDir.dir.listFiles()
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
.associateNotNullKeys { it.name to MangaDirectory(it) }
|
.mapNotNull {
|
||||||
|
val name = it.name ?: return@mapNotNull null
|
||||||
|
name to MangaDirectory(it) }.toMap()
|
||||||
|
|
||||||
sourceDir.files = mangaDirs
|
// Timber.i("${sourceDir.dir.name}: ${mangaDirs.map {
|
||||||
|
// it.key + " :: " + it.value.dir.filePath }.joinToString(", ")}")
|
||||||
|
|
||||||
mangaDirs.values.forEach { mangaDir ->
|
mangaDirs.values.forEach { mangaDir ->
|
||||||
val chapterDirs = mangaDir.dir.listFiles()
|
val chapterDirs = mangaDir.dir.listFiles()
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
.mapNotNull { it.name }
|
.mapNotNull { it.name }
|
||||||
.toHashSet()
|
.toHashSet()
|
||||||
|
// Timber.i("${mangaDir.dir.name}: ${chapterDirs.joinToString(", ")}")
|
||||||
mangaDir.files = chapterDirs
|
mangaDir.files = chapterDirs
|
||||||
}
|
}
|
||||||
|
val trueMangaDirs = mangaDirs.mapNotNull { mangaDir ->
|
||||||
|
val manga = mangas.find { DiskUtil.buildValidFilename(it.originalTitle()) ==
|
||||||
|
mangaDir.key && it.source == sourceValue.key }
|
||||||
|
val id = manga?.id ?: return@mapNotNull null
|
||||||
|
id to mangaDir.value.files
|
||||||
|
}.toMap()
|
||||||
|
|
||||||
|
//sourceDir.files = trueMangaDirs
|
||||||
|
mangaFiles.putAll(trueMangaDirs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,40 +168,14 @@ class DownloadCache(
|
|||||||
*/
|
*/
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun addChapter(chapterDirName: String, mangaUniFile: UniFile, manga: Manga) {
|
fun addChapter(chapterDirName: String, mangaUniFile: UniFile, manga: Manga) {
|
||||||
// Retrieve the cached source directory or cache a new one
|
|
||||||
var sourceDir = rootDir.files[manga.source]
|
|
||||||
if (sourceDir == null) {
|
|
||||||
val source = sourceManager.get(manga.source) ?: return
|
|
||||||
val sourceUniFile = provider.findSourceDir(source) ?: return
|
|
||||||
sourceDir = SourceDirectory(sourceUniFile)
|
|
||||||
rootDir.files += manga.source to sourceDir
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the cached manga directory or cache a new one
|
val id = manga.id ?: return
|
||||||
val mangaDirName = provider.getMangaDirName(manga)
|
val files = mangaFiles[id]
|
||||||
var mangaDir = sourceDir.files[mangaDirName]
|
if (files == null) {
|
||||||
if (mangaDir == null) {
|
mangaFiles[id] = mutableSetOf(chapterDirName)
|
||||||
mangaDir = MangaDirectory(mangaUniFile)
|
|
||||||
sourceDir.files += mangaDirName to mangaDir
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
// Save the chapter directory
|
mangaFiles[id]?.add(chapterDirName)
|
||||||
mangaDir.files += chapterDirName
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a chapter that has been deleted from this cache.
|
|
||||||
*
|
|
||||||
* @param chapter the chapter to remove.
|
|
||||||
* @param manga the manga of the chapter.
|
|
||||||
*/
|
|
||||||
@Synchronized
|
|
||||||
fun removeChapter(chapter: Chapter, manga: Manga) {
|
|
||||||
val sourceDir = rootDir.files[manga.source] ?: return
|
|
||||||
val mangaDir = sourceDir.files[provider.getMangaDirName(manga)] ?: return
|
|
||||||
val chapterDirName = provider.getChapterDirName(chapter)
|
|
||||||
if (chapterDirName in mangaDir.files) {
|
|
||||||
mangaDir.files -= chapterDirName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,29 +187,27 @@ class DownloadCache(
|
|||||||
*/
|
*/
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun removeChapters(chapters: List<Chapter>, manga: Manga) {
|
fun removeChapters(chapters: List<Chapter>, manga: Manga) {
|
||||||
val sourceDir = rootDir.files[manga.source] ?: return
|
val id = manga.id ?: return
|
||||||
val mangaDir = sourceDir.files[provider.getMangaDirName(manga)] ?: return
|
|
||||||
for (chapter in chapters) {
|
for (chapter in chapters) {
|
||||||
val list = provider.getValidChapterDirNames(chapter)
|
val list = provider.getValidChapterDirNames(chapter)
|
||||||
list.forEach {
|
list.forEach {
|
||||||
if (it in mangaDir.files) {
|
if (mangaFiles[id] != null && it in mangaFiles[id]!!) {
|
||||||
mangaDir.files -= it
|
mangaFiles[id]?.remove(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeFolders(folders: List<String>, manga: Manga) {
|
fun removeFolders(folders: List<String>, manga: Manga) {
|
||||||
val sourceDir = rootDir.files[manga.source] ?: return
|
val id = manga.id ?: return
|
||||||
val mangaDir = sourceDir.files[provider.getMangaDirName(manga)] ?: return
|
|
||||||
for (chapter in folders) {
|
for (chapter in folders) {
|
||||||
if (chapter in mangaDir.files) {
|
if (mangaFiles[id] != null && chapter in mangaFiles[id]!!) {
|
||||||
mangaDir.files -= chapter
|
mangaFiles[id]?.remove(chapter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun renameFolder(from: String, to: String, source: Long) {
|
/*fun renameFolder(from: String, to: String, source: Long) {
|
||||||
val sourceDir = rootDir.files[source] ?: return
|
val sourceDir = rootDir.files[source] ?: return
|
||||||
val list = sourceDir.files.toMutableMap()
|
val list = sourceDir.files.toMutableMap()
|
||||||
val mangaFiles = sourceDir.files[DiskUtil.buildValidFilename(from)] ?: return
|
val mangaFiles = sourceDir.files[DiskUtil.buildValidFilename(from)] ?: return
|
||||||
@ -242,7 +218,7 @@ class DownloadCache(
|
|||||||
list.remove(DiskUtil.buildValidFilename(from))
|
list.remove(DiskUtil.buildValidFilename(from))
|
||||||
list[to] = newDir
|
list[to] = newDir
|
||||||
sourceDir.files = list
|
sourceDir.files = list
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -252,11 +228,7 @@ class DownloadCache(
|
|||||||
*/
|
*/
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun removeManga(manga: Manga) {
|
fun removeManga(manga: Manga) {
|
||||||
val sourceDir = rootDir.files[manga.source] ?: return
|
mangaFiles.remove(manga.id)
|
||||||
val mangaDirName = provider.getMangaDirName(manga)
|
|
||||||
if (mangaDirName in sourceDir.files) {
|
|
||||||
sourceDir.files -= mangaDirName
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -269,13 +241,13 @@ class DownloadCache(
|
|||||||
* Class to store the files under a source directory.
|
* Class to store the files under a source directory.
|
||||||
*/
|
*/
|
||||||
private class SourceDirectory(val dir: UniFile,
|
private class SourceDirectory(val dir: UniFile,
|
||||||
var files: Map<String, MangaDirectory> = hashMapOf())
|
var files: Map<Long, MutableSet<String>> = hashMapOf())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to store the files under a manga directory.
|
* Class to store the files under a manga directory.
|
||||||
*/
|
*/
|
||||||
private class MangaDirectory(val dir: UniFile,
|
private class MangaDirectory(val dir: UniFile,
|
||||||
var files: Set<String> = hashSetOf())
|
var files: MutableSet<String> = hashSetOf())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new map containing only the key entries of [transform] that are not null.
|
* Returns a new map containing only the key entries of [transform] that are not null.
|
||||||
|
@ -182,9 +182,9 @@ class DownloadManager(val context: Context) {
|
|||||||
return cache.getDownloadCount(manga)
|
return cache.getDownloadCount(manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun renameCache(from: String, to: String, source: Long) {
|
/*fun renameCache(from: String, to: String, source: Long) {
|
||||||
cache.renameFolder(from, to, source)
|
cache.renameFolder(from, to, source)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calls delete chapter, which deletes temp downloads
|
* Calls delete chapter, which deletes temp downloads
|
||||||
|
@ -136,8 +136,8 @@ class DownloadProvider(private val context: Context) {
|
|||||||
val sourceDir = findSourceDir(source)
|
val sourceDir = findSourceDir(source)
|
||||||
val mangaDir = sourceDir?.findFile(DiskUtil.buildValidFilename(from))
|
val mangaDir = sourceDir?.findFile(DiskUtil.buildValidFilename(from))
|
||||||
mangaDir?.renameTo(to)
|
mangaDir?.renameTo(to)
|
||||||
val downloadManager:DownloadManager by injectLazy()
|
// val downloadManager:DownloadManager by injectLazy()
|
||||||
downloadManager.renameCache(from, to, sourceId)
|
// downloadManager.renameCache(from, to, sourceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -558,6 +558,9 @@ open class BrowseCatalogueController(bundle: Bundle) :
|
|||||||
presenter.moveMangaToCategory(manga, null)
|
presenter.moveMangaToCategory(manga, null)
|
||||||
else -> {
|
else -> {
|
||||||
val ids = presenter.getMangaCategoryIds(manga)
|
val ids = presenter.getMangaCategoryIds(manga)
|
||||||
|
if (ids.isNullOrEmpty()) {
|
||||||
|
presenter.moveMangaToCategory(manga, null)
|
||||||
|
}
|
||||||
val preselected = ids.mapNotNull { id ->
|
val preselected = ids.mapNotNull { id ->
|
||||||
categories.indexOfFirst { it.id == id }.takeIf { it != -1 }
|
categories.indexOfFirst { it.id == id }.takeIf { it != -1 }
|
||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
|
Loading…
Reference in New Issue
Block a user