From 4ae5c3bf58afbba48e11096fc3955b28582d17bf Mon Sep 17 00:00:00 2001 From: Timo Bryant Date: Tue, 2 Jan 2024 22:50:52 +0100 Subject: [PATCH] implement fileystem asset manager --- libraries/assetmanager/build.gradle.kts | 2 + .../implementation/FilesystemAssetManager.kt | 83 +++++++++++++++++++ .../assetmanager/interfaces/AssetManager.kt | 3 +- .../de/itkl/core_api/interfaces/Resource.kt | 1 + .../core_api/interfaces/ResourceFactory.kt | 5 ++ 5 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 libraries/assetmanager/src/main/kotlin/de/itkl/assetmanager/implementation/FilesystemAssetManager.kt diff --git a/libraries/assetmanager/build.gradle.kts b/libraries/assetmanager/build.gradle.kts index 0e40257..49383e6 100644 --- a/libraries/assetmanager/build.gradle.kts +++ b/libraries/assetmanager/build.gradle.kts @@ -1,3 +1,5 @@ dependencies { api(project(":libraries:core-api")) + // used for contentType + api("io.ktor:ktor-http-jvm:2.3.7") } diff --git a/libraries/assetmanager/src/main/kotlin/de/itkl/assetmanager/implementation/FilesystemAssetManager.kt b/libraries/assetmanager/src/main/kotlin/de/itkl/assetmanager/implementation/FilesystemAssetManager.kt new file mode 100644 index 0000000..5185097 --- /dev/null +++ b/libraries/assetmanager/src/main/kotlin/de/itkl/assetmanager/implementation/FilesystemAssetManager.kt @@ -0,0 +1,83 @@ +package de.itkl.assetmanager.implementation + +import de.itkl.assetmanager.interfaces.AssetManager +import de.itkl.assetmanager.interfaces.Assets +import de.itkl.core_api.interfaces.Resource +import de.itkl.core_api.interfaces.ResourceFactory +import io.github.oshai.kotlinlogging.KotlinLogging +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.FlowCollector +import kotlinx.coroutines.flow.emitAll +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.stream.consumeAsFlow +import kotlinx.coroutines.withContext +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths +import kotlin.io.path.deleteExisting +import kotlin.io.path.exists +import kotlin.io.path.outputStream + +private val Log = KotlinLogging.logger { } +class FilesystemAssetManager : AssetManager { + override suspend fun assets(name: String): Assets { + val path = createAssetsPath(name) + withContext(Dispatchers.IO) { + Files.createDirectories(path) + } + return FilesystemAssets(path) + } + + override suspend fun delete(name: String) { + val path = createAssetsPath(name) + withContext(Dispatchers.IO) { + Files.delete(path) + } + } + + private fun createAssetsPath(name: String): Path { + return Paths.get("$name.assets.d").toAbsolutePath() + } +} + +class FilesystemAssets(private val baseDir: Path) : Assets, KoinComponent { + + private val resourceFactory by inject() + override suspend fun store(resource: Resource) { + val destination = baseDir.resolve(resource.filename) + resource.read().use { source -> + destination.outputStream().use {output -> + withContext(Dispatchers.IO) { + source.copyTo(output) + } + } + } + } + + override suspend fun retrieve(name: String): Resource? { + val destination = baseDir.resolve(name) + if (!destination.exists()) { + return null + } + val resource = resourceFactory.file(destination) + return resource + } + + + override suspend fun delete(name: String) { + val destination = baseDir.resolve(name) + withContext(Dispatchers.IO) { + destination.deleteExisting() + } + } + + override suspend fun collect(collector: FlowCollector) { + val flow = withContext(Dispatchers.IO) { + Files.list(baseDir).consumeAsFlow() + } + .map { path -> resourceFactory.file(path) } + collector.emitAll(flow) + } +} \ No newline at end of file diff --git a/libraries/assetmanager/src/main/kotlin/de/itkl/assetmanager/interfaces/AssetManager.kt b/libraries/assetmanager/src/main/kotlin/de/itkl/assetmanager/interfaces/AssetManager.kt index ebf33c4..04f5e69 100644 --- a/libraries/assetmanager/src/main/kotlin/de/itkl/assetmanager/interfaces/AssetManager.kt +++ b/libraries/assetmanager/src/main/kotlin/de/itkl/assetmanager/interfaces/AssetManager.kt @@ -1,4 +1,5 @@ package de.itkl.assetmanager.interfaces interface AssetManager { - fun assets(name: String): Assets + suspend fun assets(name: String): Assets + suspend fun delete(name: String) } \ No newline at end of file diff --git a/libraries/core-api/src/main/kotlin/de/itkl/core_api/interfaces/Resource.kt b/libraries/core-api/src/main/kotlin/de/itkl/core_api/interfaces/Resource.kt index 3ee0703..bde4f94 100644 --- a/libraries/core-api/src/main/kotlin/de/itkl/core_api/interfaces/Resource.kt +++ b/libraries/core-api/src/main/kotlin/de/itkl/core_api/interfaces/Resource.kt @@ -15,6 +15,7 @@ interface Resource { val file: File? val path: Path? fun read(): InputStream + } /** diff --git a/libraries/core-api/src/main/kotlin/de/itkl/core_api/interfaces/ResourceFactory.kt b/libraries/core-api/src/main/kotlin/de/itkl/core_api/interfaces/ResourceFactory.kt index 643e2cf..2ac8201 100644 --- a/libraries/core-api/src/main/kotlin/de/itkl/core_api/interfaces/ResourceFactory.kt +++ b/libraries/core-api/src/main/kotlin/de/itkl/core_api/interfaces/ResourceFactory.kt @@ -5,10 +5,15 @@ import de.itkl.core_api.implementation.ProgressResource import org.koin.core.component.KoinComponent import org.koin.core.component.inject import java.io.File +import java.nio.file.Path class ResourceFactory : KoinComponent { private val progressBarFactory by inject() + + fun file(path: Path): Resource { + return file(path.toFile()) + } fun file(file: File): Resource { val resource = FileResource(file) return ProgressResource(resource, progressBarFactory)