Actually use configured storage location for local source

Fixes #10178
This commit is contained in:
arkon 2023-11-25 22:31:26 -05:00
parent ca54984344
commit 27c4db752c
9 changed files with 76 additions and 46 deletions

View file

@ -42,6 +42,7 @@ import eu.kanade.tachiyomi.data.backup.BackupCreateJob
import eu.kanade.tachiyomi.data.backup.BackupFileValidator
import eu.kanade.tachiyomi.data.backup.BackupRestoreJob
import eu.kanade.tachiyomi.data.cache.ChapterCache
import eu.kanade.tachiyomi.data.download.DownloadCache
import eu.kanade.tachiyomi.util.storage.DiskUtil
import eu.kanade.tachiyomi.util.system.DeviceUtil
import eu.kanade.tachiyomi.util.system.copyToClipboard
@ -100,6 +101,7 @@ object SettingsDataScreen : SearchableSettings {
val file = UniFile.fromUri(context, uri)
storageDirPref.set(file.uri.toString())
Injekt.get<DownloadCache>().invalidateCache()
}
}

View file

@ -21,7 +21,7 @@ import eu.kanade.tachiyomi.util.system.workManager
import logcat.LogPriority
import tachiyomi.core.util.system.logcat
import tachiyomi.domain.backup.service.BackupPreferences
import tachiyomi.domain.storage.service.StoragePreferences
import tachiyomi.domain.storage.service.StorageManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.Date
@ -43,6 +43,8 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete
val uri = inputData.getString(LOCATION_URI_KEY)?.toUri()
?: getAutomaticBackupLocation()
?: return Result.failure()
val flags = inputData.getInt(BACKUP_FLAGS_KEY, BackupCreateFlags.AutomaticDefaults)
try {
@ -75,13 +77,9 @@ class BackupCreateJob(private val context: Context, workerParams: WorkerParamete
)
}
private fun getAutomaticBackupLocation(): Uri {
val storagePreferences = Injekt.get<StoragePreferences>()
return storagePreferences.baseStorageDirectory().get().let {
val dir = UniFile.fromUri(context, it.toUri())
.createDirectory(StoragePreferences.BACKUP_DIR)
dir.uri
}
private fun getAutomaticBackupLocation(): Uri? {
val storageManager = Injekt.get<StorageManager>()
return storageManager.getAutomaticBackupsDirectory()?.uri
}
companion object {

View file

@ -1,20 +1,15 @@
package eu.kanade.tachiyomi.data.download
import android.content.Context
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
import tachiyomi.domain.chapter.model.Chapter
import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.storage.service.StoragePreferences
import tachiyomi.domain.storage.service.StorageManager
import tachiyomi.i18n.MR
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@ -27,27 +22,11 @@ import uy.kohesive.injekt.api.get
*/
class DownloadProvider(
private val context: Context,
storagePreferences: StoragePreferences = Injekt.get(),
private val storageManager: StorageManager = Injekt.get(),
) {
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) }
}
get() = storageManager.getDownloadsDirectory()
/**
* Returns the download directory for a manga. For internal use only.

View file

@ -35,6 +35,7 @@ import tachiyomi.data.Mangas
import tachiyomi.data.StringListColumnAdapter
import tachiyomi.data.UpdateStrategyColumnAdapter
import tachiyomi.domain.source.service.SourceManager
import tachiyomi.domain.storage.service.StorageManager
import tachiyomi.source.local.image.LocalCoverManager
import tachiyomi.source.local.io.LocalSourceFileSystem
import uy.kohesive.injekt.api.InjektModule
@ -125,8 +126,9 @@ class AppModule(val app: Application) : InjektModule {
addSingletonFactory { ImageSaver(app) }
addSingletonFactory { AndroidStorageFolderProvider(app) }
addSingletonFactory { LocalSourceFileSystem(app, get<AndroidStorageFolderProvider>()) }
addSingletonFactory { LocalSourceFileSystem(get()) }
addSingletonFactory { LocalCoverManager(app, get()) }
addSingletonFactory { StorageManager(app, get()) }
// Asynchronously init expensive components for a faster cold start
ContextCompat.getMainExecutor(app).execute {

View file

@ -19,6 +19,8 @@ dependencies {
implementation(platform(kotlinx.coroutines.bom))
implementation(kotlinx.bundles.coroutines)
implementation(libs.unifile)
api(libs.sqldelight.android.paging)
testImplementation(libs.bundles.test)

View file

@ -0,0 +1,54 @@
package tachiyomi.domain.storage.service
import android.content.Context
import androidx.core.net.toUri
import com.hippo.unifile.UniFile
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
class StorageManager(
private val context: Context,
storagePreferences: StoragePreferences,
) {
private val scope = CoroutineScope(Dispatchers.IO)
private var baseDir: UniFile? = storagePreferences.baseStorageDirectory().get().let(::getBaseDir)
init {
storagePreferences.baseStorageDirectory().changes()
.onEach { baseDir = getBaseDir(it) }
.launchIn(scope)
}
private fun getBaseDir(path: String): UniFile? {
val file = UniFile.fromUri(context, path.toUri())
return file.takeIf { it?.exists() == true }?.also { parent ->
parent.createDirectory(AUTOMATIC_BACKUPS_PATH)
parent.createDirectory(LOCAL_SOURCE_PATH)
parent.createDirectory(DOWNLOADS_PATH).also {
DiskUtil.createNoMediaFile(it, context)
}
}
}
fun getAutomaticBackupsDirectory(): UniFile? {
return baseDir?.createDirectory(AUTOMATIC_BACKUPS_PATH)
}
fun getDownloadsDirectory(): UniFile? {
return baseDir?.createDirectory(DOWNLOADS_PATH)
}
fun getLocalSourceDirectory(): UniFile? {
return baseDir?.createDirectory(LOCAL_SOURCE_PATH)
}
}
private const val AUTOMATIC_BACKUPS_PATH = "autobackup"
private const val DOWNLOADS_PATH = "downloads"
private const val LOCAL_SOURCE_PATH = "local"

View file

@ -9,9 +9,4 @@ class StoragePreferences(
) {
fun baseStorageDirectory() = preferenceStore.getString("storage_dir", folderProvider.path())
companion object {
const val BACKUP_DIR = "autobackup"
const val DOWNLOADS_DIR = "downloads"
}
}

View file

@ -310,8 +310,10 @@ actual class LocalSource(
fun getFormat(chapter: SChapter): Format {
try {
val (mangaDirName, chapterName) = chapter.url.split(File.separator, limit = 2)
return fileSystem.getBaseDirectory()
?.findFile(chapter.url)
?.findFile(mangaDirName)
?.findFile(chapterName)
?.let(Format.Companion::valueOf)
?: throw Exception(context.stringResource(MR.strings.chapter_not_found))
} catch (e: Format.UnknownFormatException) {

View file

@ -1,18 +1,14 @@
package tachiyomi.source.local.io
import android.content.Context
import androidx.core.net.toUri
import com.hippo.unifile.UniFile
import tachiyomi.core.storage.FolderProvider
import tachiyomi.domain.storage.service.StorageManager
actual class LocalSourceFileSystem(
private val context: Context,
private val folderProvider: FolderProvider,
private val storageManager: StorageManager,
) {
actual fun getBaseDirectory(): UniFile? {
return UniFile.fromUri(context, folderProvider.path().toUri())
?.createDirectory("local")
return storageManager.getLocalSourceDirectory()
}
actual fun getFilesInBaseDirectory(): List<UniFile> {