Начало LocalVault

This commit is contained in:
Roman Pytkov
2024-12-20 19:57:42 +03:00
parent 576fc4020c
commit a481868039
18 changed files with 246 additions and 92 deletions

View File

@@ -1,23 +0,0 @@
package com.github.nullptroma.wallenc.data
import com.github.nullptroma.wallenc.domain.models.IStorage
import com.github.nullptroma.wallenc.domain.models.IStorageAccessor
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import java.util.UUID
class MockStorage(
override val size: StateFlow<Int?> = MutableStateFlow(null),
override val numberOfFiles: StateFlow<Int?> = MutableStateFlow(null),
override val uuid: UUID,
override val name: StateFlow<String> = MutableStateFlow(""),
override val totalSpace: StateFlow<Int?> = MutableStateFlow(null),
override val availableSpace: StateFlow<Int?> = MutableStateFlow(null),
override val isAvailable: StateFlow<Boolean> = MutableStateFlow(false),
override val accessor: IStorageAccessor
) : IStorage {
override suspend fun rename(newName: String) {
TODO("Not yet implemented")
}
}

View File

@@ -0,0 +1,7 @@
package com.github.nullptroma.wallenc.data.vaults
interface IStorageCallbackHandler {
fun changeSize(delta: Int)
fun changeNumOfFiles(delta: Int)
}

View File

@@ -0,0 +1,28 @@
package com.github.nullptroma.wallenc.data.vaults.local
import com.github.nullptroma.wallenc.domain.models.IStorage
import com.github.nullptroma.wallenc.domain.models.IStorageAccessor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.StateFlow
import java.util.UUID
class LocalStorage(
override val uuid: UUID,
absolutePath: String,
ioDispatcher: CoroutineDispatcher
) : IStorage {
override val size: StateFlow<Long?>
get() = accessor.size
override val numberOfFiles: StateFlow<Int?>
get() = accessor.numberOfFiles
override val name: StateFlow<String>
get() = TODO("Добавить класс в Domain, который с помощью accessor будет читать и сохранять имя в скрытую папку")
override val isAvailable: StateFlow<Boolean>
get() = accessor.isAvailable
override val accessor: IStorageAccessor = LocalStorageAccessor(absolutePath, ioDispatcher)
override suspend fun rename(newName: String) {
TODO("Not yet implemented")
}
}

View File

@@ -4,30 +4,92 @@ import com.github.nullptroma.wallenc.domain.datatypes.DataPackage
import com.github.nullptroma.wallenc.domain.models.IDirectory
import com.github.nullptroma.wallenc.domain.models.IFile
import com.github.nullptroma.wallenc.domain.models.IStorageAccessor
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.io.InputStream
import java.io.OutputStream
import java.net.URI
import kotlin.io.path.Path
import kotlin.io.path.fileSize
class LocalStorageAccessor : IStorageAccessor {
class LocalStorageAccessor(
private val absolutePath: String,
private val ioDispatcher: CoroutineDispatcher
) : IStorageAccessor {
private val _size = MutableStateFlow<Long?>(null)
private val _numberOfFiles = MutableStateFlow<Int?>(null)
private val _isAvailable = MutableStateFlow(false)
override val size: StateFlow<Long?>
get() = _size
override val numberOfFiles: StateFlow<Int?>
get() = _numberOfFiles
override val isAvailable: StateFlow<Boolean>
get() = TODO("Not yet implemented")
get() = _isAvailable
override val filesUpdates: SharedFlow<DataPackage<IFile>>
get() = TODO("Not yet implemented")
override val dirsUpdates: SharedFlow<DataPackage<IDirectory>>
get() = TODO("Not yet implemented")
init {
CoroutineScope(ioDispatcher).launch {
scanStorage()
}
}
private fun checkAvailable(): Boolean {
_isAvailable.value = File(absolutePath).exists()
return _isAvailable.value
}
private fun forAllFiles(dir: File, callback: (File) -> Unit) {
if (dir.exists() == false)
return
callback(dir)
val nextDirs = dir.listFiles()
if (nextDirs != null) {
for (nextDir in nextDirs) {
forAllFiles(nextDir, callback)
}
}
}
private suspend fun scanStorage() = withContext(ioDispatcher) {
_isAvailable.value = File(absolutePath).exists()
var size = 0L
var numOfFiles = 0
forAllFiles(File(absolutePath)) {
if (it.isFile) {
numOfFiles++
size += Path(it.path).fileSize()
}
}
_size.value = size
_numberOfFiles.value = numOfFiles
}
override suspend fun getAllFiles(): List<IFile> {
if(checkAvailable() == false)
return listOf()
val list = mutableListOf<IFile>()
}
override suspend fun getFiles(path: String): List<IFile> {
TODO("Not yet implemented")
}
override suspend fun getFiles(path: URI): List<IFile> {
TODO("Not yet implemented")
}
override fun getFilesFlow(path: URI): Flow<DataPackage<IFile>> {
override fun getFilesFlow(path: String): Flow<DataPackage<IFile>> {
TODO("Not yet implemented")
}
@@ -35,43 +97,43 @@ class LocalStorageAccessor : IStorageAccessor {
TODO("Not yet implemented")
}
override suspend fun getDirs(path: URI): List<IDirectory> {
override suspend fun getDirs(path: String): List<IDirectory> {
TODO("Not yet implemented")
}
override fun getDirsFlow(path: URI): Flow<DataPackage<IDirectory>> {
override fun getDirsFlow(path: String): Flow<DataPackage<IDirectory>> {
TODO("Not yet implemented")
}
override suspend fun touchFile(path: URI) {
override suspend fun touchFile(path: String) {
TODO("Not yet implemented")
}
override suspend fun touchDir(path: URI) {
override suspend fun touchDir(path: String) {
TODO("Not yet implemented")
}
override suspend fun delete(path: URI) {
override suspend fun delete(path: String) {
TODO("Not yet implemented")
}
override suspend fun getFileInfo(path: URI) {
override suspend fun getFileInfo(path: String) {
TODO("Not yet implemented")
}
override suspend fun getDirInfo(path: URI) {
override suspend fun getDirInfo(path: String) {
TODO("Not yet implemented")
}
override suspend fun openWrite(path: URI): InputStream {
override suspend fun openWrite(path: String): InputStream {
TODO("Not yet implemented")
}
override suspend fun openRead(path: URI): OutputStream {
override suspend fun openRead(path: String): OutputStream {
TODO("Not yet implemented")
}
override suspend fun moveToTrash(path: URI) {
override suspend fun moveToTrash(path: String) {
TODO("Not yet implemented")
}
}

View File

@@ -1,7 +1,6 @@
package com.github.nullptroma.wallenc.data.vaults.local
import android.content.Context
import com.github.nullptroma.wallenc.data.MockStorage
import com.github.nullptroma.wallenc.domain.datatypes.EncryptKey
import com.github.nullptroma.wallenc.domain.enums.VaultType
import com.github.nullptroma.wallenc.domain.models.IStorage
@@ -12,42 +11,64 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
import java.util.UUID
import kotlin.io.path.Path
import kotlin.io.path.createDirectory
import kotlin.io.path.pathString
class LocalVault(private val ioDispatcher: CoroutineDispatcher, context: Context) : IVault {
private val path = context.getExternalFilesDir("LocalVault")
private val _path = MutableStateFlow<File?>(null)
private val _storages = MutableStateFlow(listOf<IStorage>())
private val _totalSpace = MutableStateFlow(null)
private val _availableSpace = MutableStateFlow(null)
private val _isAvailable = MutableStateFlow(false)
init {
CoroutineScope(ioDispatcher).launch {
if(path == null)
return@launch
val dirs = path.listFiles()?.filter { it.isDirectory }
if(dirs != null)
_storages.value = dirs.map {
MockStorage(uuid = UUID.fromString(it.name), accessor = LocalStorageAccessor())
}
val next = Path(path.path, UUID.randomUUID().toString())
next.createDirectory()
_path.value = context.getExternalFilesDir("LocalVault")
_isAvailable.value = _path.value != null
readStorages()
}
}
override suspend fun createStorage(name: String): IStorage = withContext(ioDispatcher) {
TODO("Not yet implemented")
private fun readStorages() {
val path = _path.value
if (path == null || _isAvailable.value == false)
return
val dirs = path.listFiles()?.filter { it.isDirectory }
if (dirs != null) {
_storages.value = dirs.map {
val uuid = UUID.fromString(it.name)
LocalStorage(uuid, it.path, ioDispatcher)
}
}
}
override suspend fun createStorage(): IStorage = withContext(ioDispatcher) {
val path = _path.value
if (path == null || _isAvailable.value == false)
throw Exception("Not available")
val uuid = UUID.randomUUID()
val next = Path(path.path, uuid.toString())
next.createDirectory()
val newStorage = LocalStorage(uuid, next.pathString, ioDispatcher)
_storages.value = _storages.value.toMutableList().apply {
add(newStorage)
}
return@withContext newStorage
}
override suspend fun createStorage(
name: String,
key: EncryptKey
): IStorage = withContext(ioDispatcher) {
TODO("Not yet implemented")
}
override suspend fun createStorage(
name: String,
key: EncryptKey,
uuid: UUID
): IStorage = withContext(ioDispatcher) {
@@ -64,6 +85,9 @@ class LocalVault(private val ioDispatcher: CoroutineDispatcher, context: Context
override val storages: StateFlow<List<IStorage>>
get() = _storages
override val isAvailable: StateFlow<Boolean>
get() = TODO("Not yet implemented")
get() = _isAvailable
override val totalSpace: StateFlow<Int?>
get() = _totalSpace
override val availableSpace: StateFlow<Int?>
get() = _availableSpace
}

View File

@@ -0,0 +1,8 @@
package com.github.nullptroma.wallenc.data.vaults.local.entity
import com.github.nullptroma.wallenc.domain.models.IDirectory
class LocalDirectory(
override val metaInfo: LocalMetaInfo,
override val elementsCount: Int
) : IDirectory

View File

@@ -0,0 +1,5 @@
package com.github.nullptroma.wallenc.data.vaults.local.entity
import com.github.nullptroma.wallenc.domain.models.IFile
class LocalFile(override val metaInfo: LocalMetaInfo) : IFile

View File

@@ -0,0 +1,23 @@
package com.github.nullptroma.wallenc.data.vaults.local.entity
import com.github.nullptroma.wallenc.domain.models.IMetaInfo
import java.time.LocalDateTime
class LocalMetaInfo : IMetaInfo {
init {
}
override val name: String
get() = TODO("Not yet implemented")
override val size: Int
get() = TODO("Not yet implemented")
override val isDeleted: Boolean
get() = TODO("Not yet implemented")
override val isHidden: Boolean
get() = TODO("Not yet implemented")
override val lastModified: LocalDateTime
get() = TODO("Not yet implemented")
override val path: String
get() = TODO("Not yet implemented")
}