Skip to content

Commit

Permalink
Switch to StorageManager class
Browse files Browse the repository at this point in the history
  • Loading branch information
nonproto committed Feb 6, 2024
1 parent 2fba550 commit 5da9734
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 65 deletions.
3 changes: 3 additions & 0 deletions app/src/main/java/eu/kanade/tachiyomi/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import org.nekomanga.domain.backup.BackupPreferences
import org.nekomanga.domain.details.MangaDetailsPreferences
import org.nekomanga.domain.library.LibraryPreferences
import org.nekomanga.domain.reader.ReaderPreferences
import org.nekomanga.domain.storage.StorageManager
import org.nekomanga.domain.storage.StoragePreferences
import tachiyomi.core.preference.AndroidPreferenceStore
import tachiyomi.core.preference.PreferenceStore
Expand Down Expand Up @@ -146,6 +147,8 @@ class AppModule(val app: Application) : InjektModule {

addSingletonFactory { MangaShortcutManager() }

addSingletonFactory { StorageManager(app, get()) }

// Asynchronously init expensive components for a faster cold start
ContextCompat.getMainExecutor(app).execute {
get<NetworkHelper>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import okio.buffer
import okio.gzip
import okio.sink
import org.nekomanga.R
import org.nekomanga.domain.storage.StoragePreferences
import org.nekomanga.domain.storage.StorageManager
import org.nekomanga.logging.TimberKt
import uy.kohesive.injekt.injectLazy

Expand All @@ -40,6 +40,7 @@ class BackupCreator(val context: Context) {
internal val databaseHelper: DatabaseHelper by injectLazy()
internal val sourceManager: SourceManager by injectLazy()
internal val trackManager: TrackManager by injectLazy()
internal val storageManager: StorageManager by injectLazy()

private val MAX_AUTO_BACKUPS: Int = 6

Expand Down Expand Up @@ -75,10 +76,7 @@ class BackupCreator(val context: Context) {
file =
(if (isAutoBackup) {
// Get dir of file and create
val dir =
UniFile.fromUri(context, uri)!!.createDirectory(
StoragePreferences.AUTOMATIC_DIR
)!!
val dir = storageManager.getAutomaticBackupsDirectory()!!

// Delete older backups
dir.listFiles { _, filename -> Backup.filenameRegex.matches(filename) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.system.notificationManager
import java.util.concurrent.TimeUnit
import org.nekomanga.domain.storage.StoragePreferences
import org.nekomanga.domain.storage.StorageManager
import org.nekomanga.logging.TimberKt
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
Expand Down Expand Up @@ -49,14 +49,8 @@ class BackupCreatorJob(private val context: Context, workerParams: WorkerParamet
}

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
}
val storageManager = Injekt.get<StorageManager>()
return storageManager.getBackupDirectory()!!.uri
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package eu.kanade.tachiyomi.data.download

import android.content.Context
import androidx.core.net.toUri
import androidx.core.text.isDigitsOnly
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.data.database.DatabaseHelper
Expand All @@ -18,10 +17,10 @@ import java.util.concurrent.TimeUnit
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.nekomanga.domain.storage.StoragePreferences
import org.nekomanga.domain.storage.StorageManager
import org.nekomanga.logging.TimberKt
import tachiyomi.core.util.storage.DiskUtil
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
Expand All @@ -43,7 +42,7 @@ class DownloadCache(
private val provider: DownloadProvider,
private val sourceManager: SourceManager,
private val preferences: PreferencesHelper = Injekt.get(),
private val storagePreferences: StoragePreferences = Injekt.get(),
private val storageManager: StorageManager = Injekt.get(),
) {

/**
Expand All @@ -61,24 +60,11 @@ class DownloadCache(
val scope = CoroutineScope(Job() + Dispatchers.IO)

init {

storagePreferences
.baseStorageDirectory()
.changes()
.drop(1)
.onEach { lastRenew = 0L } // invalidate cache
storageManager.baseDirChanges
.onEach { forceRenewCache() } // invalidate cache
.launchIn(scope)
}

/** Returns the downloads directory from the user's preferences. */
private fun getDirectoryFromPreference(): UniFile {
return storagePreferences.baseStorageDirectory().get().let {
UniFile.fromUri(context, it.toUri())!!.also { uniFile ->
uniFile.createDirectory(StoragePreferences.DOWNLOADS_DIR)
}
}
}

/**
* Returns true if the chapter is downloaded.
*
Expand Down Expand Up @@ -176,10 +162,12 @@ class DownloadCache(

/** Renews the downloads cache. */
private fun renew() {
TimberKt.d { "Renewing cache" }
val onlineSources = listOf(sourceManager.mangaDex)

val sourceDirs =
getDirectoryFromPreference()
storageManager
.getDownloadsDirectory()!!
.listFiles()
.orEmpty()
.associate { it.name to SourceDirectory(it) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package eu.kanade.tachiyomi.data.download

import android.content.Context
import androidx.core.net.toUri
import androidx.core.text.isDigitsOnly
import com.hippo.unifile.UniFile
import eu.kanade.tachiyomi.data.database.models.Chapter
Expand All @@ -12,7 +11,7 @@ import eu.kanade.tachiyomi.source.model.isMergedChapter
import eu.kanade.tachiyomi.source.online.merged.mangalife.MangaLife
import eu.kanade.tachiyomi.util.lang.isUUID
import org.nekomanga.R
import org.nekomanga.domain.storage.StoragePreferences
import org.nekomanga.domain.storage.StorageManager
import org.nekomanga.logging.TimberKt
import tachiyomi.core.util.storage.DiskUtil
import tachiyomi.core.util.storage.displayablePath
Expand All @@ -28,20 +27,15 @@ import uy.kohesive.injekt.api.get
*/
class DownloadProvider(
private val context: Context,
private val storagePreferences: StoragePreferences = Injekt.get()
private val storageManager: StorageManager = Injekt.get()
) {

/** Preferences helper. */
private val source = Injekt.get<SourceManager>().mangaDex

/** The root directory for downloads. */
private val downloadsDir: UniFile?
get() =
storagePreferences.baseStorageDirectory().get().let {
UniFile.fromUri(context, it.toUri())
?.createDirectory(StoragePreferences.DOWNLOADS_DIR)
?.also { dir -> DiskUtil.createNoMediaFile(dir, context) }
}
get() = storageManager.getDownloadsDirectory()

/**
* Returns the download directory for a manga. For internal use only.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ import org.nekomanga.domain.manga.Artwork
import org.nekomanga.domain.manga.Stats
import org.nekomanga.domain.network.message
import org.nekomanga.domain.snackbar.SnackbarState
import org.nekomanga.domain.storage.StoragePreferences
import org.nekomanga.domain.storage.StorageManager
import org.nekomanga.domain.track.TrackServiceItem
import org.nekomanga.domain.track.toDbTrack
import org.nekomanga.domain.track.toTrackItem
Expand All @@ -115,7 +115,7 @@ class MangaDetailPresenter(
private val trackManager: TrackManager = Injekt.get(),
private val mangaUpdateCoordinator: MangaUpdateCoordinator = Injekt.get(),
private val trackingCoordinator: TrackingCoordinator = Injekt.get(),
private val storagePreferences: StoragePreferences = Injekt.get(),
private val storageManager: StorageManager = Injekt.get(),
) : BaseCoroutinePresenter<MangaDetailController>(), DownloadQueue.DownloadListener {

private val _currentManga = MutableStateFlow<Manga?>(null)
Expand Down Expand Up @@ -527,11 +527,7 @@ class MangaDetailPresenter(
fun saveCover(artwork: Artwork, destDir: UniFile? = null) {
presenterScope.launchIO {
try {
val directory =
destDir
?: storagePreferences
.baseStorageDirectoryAsUniFile()
.createDirectory(StoragePreferences.COVER_DIR)!!
val directory = destDir ?: storageManager.getCoverDirectory()!!

val destinationUri = saveCover(directory, artwork)
launchUI {
Expand Down
14 changes: 4 additions & 10 deletions app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ import org.nekomanga.domain.chapter.ChapterItem as DomainChapterItem
import org.nekomanga.domain.chapter.toSimpleChapter
import org.nekomanga.domain.network.message
import org.nekomanga.domain.reader.ReaderPreferences
import org.nekomanga.domain.storage.StoragePreferences
import org.nekomanga.domain.storage.StorageManager
import org.nekomanga.logging.TimberKt
import tachiyomi.core.util.storage.DiskUtil
import uy.kohesive.injekt.Injekt
Expand All @@ -95,7 +95,7 @@ class ReaderViewModel(
private val securityPreferences: SecurityPreferences = Injekt.get(),
private val chapterFilter: ChapterFilter = Injekt.get(),
private val chapterItemFilter: ChapterItemFilter = Injekt.get(),
private val storagePreferences: StoragePreferences = Injekt.get(),
private val storageManager: StorageManager = Injekt.get(),
) : ViewModel() {

private val mutableState = MutableStateFlow(State())
Expand Down Expand Up @@ -827,10 +827,7 @@ class ReaderViewModel(
val notifier = SaveImageNotifier(context)
notifier.onClear()

var directory =
storagePreferences
.baseStorageDirectoryAsUniFile()
.createDirectory(StoragePreferences.PAGES_DIR)!!
var directory = storageManager.getPagesDirectory()!!

if (preferences.folderPerManga().get()) {
directory = directory.createDirectory(DiskUtil.buildValidFilename(manga.title))!!
Expand Down Expand Up @@ -867,10 +864,7 @@ class ReaderViewModel(
val notifier = SaveImageNotifier(context)
notifier.onClear()

var directory =
storagePreferences
.baseStorageDirectoryAsUniFile()
.createDirectory(StoragePreferences.PAGES_DIR)!!
var directory = storageManager.getPagesDirectory()!!

if (preferences.folderPerManga().get()) {
directory = directory.createDirectory(DiskUtil.buildValidFilename(manga.title))!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.provider.DocumentsContract
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
Expand All @@ -27,12 +28,14 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.nekomanga.R
import org.nekomanga.domain.backup.BackupPreferences
import org.nekomanga.domain.storage.StorageManager
import org.nekomanga.domain.storage.StoragePreferences
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get

class SettingsDataController : SettingsController() {
private val storagePreferences: StoragePreferences = Injekt.get()
private val storageManager: StorageManager = Injekt.get()
private val backupPreferences: BackupPreferences = Injekt.get()

/** Flags containing information of what to backup. */
Expand Down Expand Up @@ -183,10 +186,15 @@ class SettingsDataController : SettingsController() {
try {
// Use Android's built-in file creator
val intent =
Intent(Intent.ACTION_CREATE_DOCUMENT)
.addCategory(Intent.CATEGORY_OPENABLE)
.setType("application/*")
.putExtra(Intent.EXTRA_TITLE, Backup.getBackupFilename())
Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
setDataAndType(storageManager.getBackupDirectory()!!.uri, "application/*")
putExtra(Intent.EXTRA_TITLE, Backup.getBackupFilename())
putExtra(
DocumentsContract.EXTRA_INITIAL_URI,
storageManager.getBackupDirectory()!!.uri
)
}

startActivityForResult(intent, CODE_BACKUP_CREATE)
} catch (e: ActivityNotFoundException) {
Expand Down
84 changes: 84 additions & 0 deletions app/src/main/java/org/nekomanga/domain/storage/StorageManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.nekomanga.domain.storage

import android.content.Context
import androidx.core.net.toUri
import com.hippo.unifile.UniFile
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.flow.shareIn
import tachiyomi.core.util.storage.DiskUtil

class StorageManager(private val context: Context, storagePreferences: StoragePreferences) {

private val BACKUP_DIR = "backup"
private val AUTOMATIC_DIR = "automatic"
private val COVER_DIR = "covers"
private val PAGES_DIR = "pages"
private val SAVED_DIR = "saved"
private val DOWNLOADS_DIR = "downloads"

private val scope = CoroutineScope(Dispatchers.IO)

private var baseDir: UniFile? = getBaseDir(storagePreferences.baseStorageDirectory().get())

private val _changes: Channel<Unit> = Channel(Channel.UNLIMITED)
val baseDirChanges = _changes.receiveAsFlow().shareIn(scope, SharingStarted.Lazily, 1)

init {
storagePreferences
.baseStorageDirectory()
.changes()
.drop(1)
.distinctUntilChanged()
.onEach { uri ->
baseDir = getBaseDir(uri)
baseDir?.let { parent ->
parent.createDirectory(BACKUP_DIR).also { it!!.createDirectory(AUTOMATIC_DIR) }
parent.createDirectory(SAVED_DIR).also {
it!!.createDirectory(COVER_DIR)
it.createDirectory(PAGES_DIR)
}
parent.createDirectory(DOWNLOADS_DIR).also {
DiskUtil.createNoMediaFile(it, context)
}
}
_changes.send(Unit)
}
.launchIn(scope)
}

private fun getBaseDir(uri: String): UniFile? {
return UniFile.fromUri(context, uri.toUri()).takeIf { it?.exists() == true }
}

fun getAutomaticBackupsDirectory(): UniFile? {
return getBackupDirectory()?.createDirectory(AUTOMATIC_DIR)
}

fun getSavedDir(): UniFile? {
return baseDir?.createDirectory(SAVED_DIR)
}

fun getDownloadsDirectory(): UniFile? {
return baseDir?.createDirectory(DOWNLOADS_DIR)
}

fun getBackupDirectory(): UniFile? {
return baseDir?.createDirectory(BACKUP_DIR)
}

fun getCoverDirectory(): UniFile? {
return getSavedDir()?.createDirectory(COVER_DIR)
}

fun getPagesDirectory(): UniFile? {
return getSavedDir()?.createDirectory(PAGES_DIR)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ import timber.log.Timber

class DebugReportingTree : Timber.DebugTree() {
override fun createStackElementTag(element: StackTraceElement): String {
return "(${element.fileName}:${element.lineNumber})#${element.methodName}"
return "(${element.fileName}.${element.methodName}"
}
}

0 comments on commit 5da9734

Please sign in to comment.