Minor download location cleanup
This commit is contained in:
parent
f1778ac5b4
commit
21ae04d25d
2 changed files with 54 additions and 41 deletions
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.download
|
|||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import androidx.core.net.toUri
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.extension.ExtensionManager
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
|
@ -19,6 +18,7 @@ import kotlinx.coroutines.ensureActive
|
|||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.drop
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
|
@ -64,7 +64,7 @@ class DownloadCache(
|
|||
private val provider: DownloadProvider = Injekt.get(),
|
||||
private val sourceManager: SourceManager = Injekt.get(),
|
||||
private val extensionManager: ExtensionManager = Injekt.get(),
|
||||
private val storagePreferences: StoragePreferences = Injekt.get(),
|
||||
storagePreferences: StoragePreferences = Injekt.get(),
|
||||
) {
|
||||
|
||||
private val scope = CoroutineScope(Dispatchers.IO)
|
||||
|
@ -95,16 +95,9 @@ class DownloadCache(
|
|||
get() = File(context.cacheDir, "dl_index_cache")
|
||||
|
||||
private val rootDownloadsDirLock = Mutex()
|
||||
private var rootDownloadsDir = RootDirectory(getDirectoryFromPreference())
|
||||
private var rootDownloadsDir = RootDirectory(provider.downloadsDir)
|
||||
|
||||
init {
|
||||
storagePreferences.baseStorageDirectory().changes()
|
||||
.onEach {
|
||||
rootDownloadsDir = RootDirectory(getDirectoryFromPreference())
|
||||
invalidateCache()
|
||||
}
|
||||
.launchIn(scope)
|
||||
|
||||
// Attempt to read cache file
|
||||
scope.launch {
|
||||
rootDownloadsDirLock.withLock {
|
||||
|
@ -119,6 +112,14 @@ class DownloadCache(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
storagePreferences.baseStorageDirectory().changes()
|
||||
.drop(1)
|
||||
.onEach {
|
||||
rootDownloadsDir = RootDirectory(provider.downloadsDir)
|
||||
invalidateCache()
|
||||
}
|
||||
.launchIn(scope)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -293,17 +294,6 @@ class DownloadCache(
|
|||
renewalJob?.cancel()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the downloads directory from the user's preferences.
|
||||
*/
|
||||
private fun getDirectoryFromPreference(): UniFile {
|
||||
return storagePreferences.baseStorageDirectory().get().let {
|
||||
UniFile.fromUri(context, it.toUri()).also {
|
||||
it?.createDirectory(StoragePreferences.DOWNLOADS_DIR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renews the downloads cache.
|
||||
*/
|
||||
|
@ -335,7 +325,7 @@ class DownloadCache(
|
|||
val sourceMap = sources.associate { provider.getSourceDirName(it).lowercase() to it.id }
|
||||
|
||||
rootDownloadsDirLock.withLock {
|
||||
val sourceDirs = rootDownloadsDir.dir.listFiles().orEmpty()
|
||||
val sourceDirs = rootDownloadsDir.dir?.listFiles().orEmpty()
|
||||
.filter { it.isDirectory && !it.name.isNullOrBlank() }
|
||||
.mapNotNull { dir ->
|
||||
val sourceId = sourceMap[dir.name!!.lowercase()]
|
||||
|
@ -348,12 +338,12 @@ class DownloadCache(
|
|||
sourceDirs.values
|
||||
.map { sourceDir ->
|
||||
async {
|
||||
sourceDir.mangaDirs = sourceDir.dir.listFiles().orEmpty()
|
||||
sourceDir.mangaDirs = sourceDir.dir?.listFiles().orEmpty()
|
||||
.filter { it.isDirectory && !it.name.isNullOrBlank() }
|
||||
.associate { it.name!! to MangaDirectory(it) }
|
||||
|
||||
sourceDir.mangaDirs.values.forEach { mangaDir ->
|
||||
val chapterDirs = mangaDir.dir.listFiles().orEmpty()
|
||||
val chapterDirs = mangaDir.dir?.listFiles().orEmpty()
|
||||
.mapNotNull {
|
||||
when {
|
||||
// Ignore incomplete downloads
|
||||
|
@ -430,7 +420,7 @@ class DownloadCache(
|
|||
@Serializable
|
||||
private class RootDirectory(
|
||||
@Serializable(with = UniFileAsStringSerializer::class)
|
||||
val dir: UniFile,
|
||||
val dir: UniFile?,
|
||||
var sourceDirs: Map<Long, SourceDirectory> = mapOf(),
|
||||
)
|
||||
|
||||
|
@ -440,7 +430,7 @@ private class RootDirectory(
|
|||
@Serializable
|
||||
private class SourceDirectory(
|
||||
@Serializable(with = UniFileAsStringSerializer::class)
|
||||
val dir: UniFile,
|
||||
val dir: UniFile?,
|
||||
var mangaDirs: Map<String, MangaDirectory> = mapOf(),
|
||||
)
|
||||
|
||||
|
@ -450,17 +440,26 @@ private class SourceDirectory(
|
|||
@Serializable
|
||||
private class MangaDirectory(
|
||||
@Serializable(with = UniFileAsStringSerializer::class)
|
||||
val dir: UniFile,
|
||||
val dir: UniFile?,
|
||||
var chapterDirs: MutableSet<String> = mutableSetOf(),
|
||||
)
|
||||
|
||||
private object UniFileAsStringSerializer : KSerializer<UniFile> {
|
||||
private object UniFileAsStringSerializer : KSerializer<UniFile?> {
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("UniFile", PrimitiveKind.STRING)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: UniFile) {
|
||||
return encoder.encodeString(value.uri.toString())
|
||||
override fun serialize(encoder: Encoder, value: UniFile?) {
|
||||
return if (value == null) {
|
||||
encoder.encodeNull()
|
||||
} else {
|
||||
encoder.encodeString(value.uri.toString())
|
||||
}
|
||||
}
|
||||
override fun deserialize(decoder: Decoder): UniFile {
|
||||
return UniFile.fromUri(Injekt.get<Application>(), Uri.parse(decoder.decodeString()))
|
||||
|
||||
override fun deserialize(decoder: Decoder): UniFile? {
|
||||
return if (decoder.decodeNotNullMark()) {
|
||||
UniFile.fromUri(Injekt.get<Application>(), Uri.parse(decoder.decodeString()))
|
||||
} else {
|
||||
decoder.decodeNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,10 @@ import androidx.core.net.toUri
|
|||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.util.storage.DiskUtil
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import logcat.LogPriority
|
||||
import tachiyomi.core.i18n.stringResource
|
||||
import tachiyomi.core.util.system.logcat
|
||||
|
@ -23,17 +27,27 @@ import uy.kohesive.injekt.api.get
|
|||
*/
|
||||
class DownloadProvider(
|
||||
private val context: Context,
|
||||
private val storagePreferences: StoragePreferences = Injekt.get(),
|
||||
storagePreferences: StoragePreferences = Injekt.get(),
|
||||
) {
|
||||
|
||||
private val downloadsDir: UniFile?
|
||||
get() = storagePreferences.baseStorageDirectory().get().let {
|
||||
UniFile.fromUri(context, it.toUri())
|
||||
?.createDirectory(StoragePreferences.DOWNLOADS_DIR)
|
||||
?.also { dir ->
|
||||
DiskUtil.createNoMediaFile(dir, context)
|
||||
}
|
||||
}
|
||||
private val scope = CoroutineScope(Dispatchers.IO)
|
||||
|
||||
private var _downloadsDir: UniFile? =
|
||||
storagePreferences.baseStorageDirectory().get().let(::getDownloadsLocation)
|
||||
val downloadsDir: UniFile?
|
||||
get() = _downloadsDir
|
||||
|
||||
init {
|
||||
storagePreferences.baseStorageDirectory().changes()
|
||||
.onEach { _downloadsDir = getDownloadsLocation(it) }
|
||||
.launchIn(scope)
|
||||
}
|
||||
|
||||
private fun getDownloadsLocation(dir: String): UniFile? {
|
||||
return UniFile.fromUri(context, dir.toUri())
|
||||
?.createDirectory(StoragePreferences.DOWNLOADS_DIR)
|
||||
?.also { DiskUtil.createNoMediaFile(it, context) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the download directory for a manga. For internal use only.
|
||||
|
|
Reference in a new issue