add default input providers

This commit is contained in:
2022-03-06 18:06:57 +06:00
parent 91927d3b50
commit f5b71dcb84
11 changed files with 78 additions and 34 deletions
client/src/jsMain/kotlin/dev/inmo/postssystem/client/utils
features
common
common
build.gradle
src
commonMain
kotlin
dev
inmo
postssystem
features
jsMain
kotlin
dev
inmo
postssystem
features
jvmMain
kotlin
dev
inmo
postssystem
features
files
common
src
jvmMain
kotlin
dev
inmo
postssystem
features
gradle.properties
gradle
server/src/main/resources/web
services/posts
client
src
commonMain
kotlin
dev
inmo
postssystem
services
server
src
jvmMain
kotlin
dev
inmo
postssystem

@ -5,6 +5,7 @@ import dev.inmo.postssystem.features.files.common.FullFileInfo
import dev.inmo.micro_utils.common.* import dev.inmo.micro_utils.common.*
import dev.inmo.micro_utils.mime_types.KnownMimeTypes import dev.inmo.micro_utils.mime_types.KnownMimeTypes
import dev.inmo.micro_utils.mime_types.findBuiltinMimeType import dev.inmo.micro_utils.mime_types.findBuiltinMimeType
import dev.inmo.postssystem.features.common.common.BytesBasedInputProvider
import io.ktor.utils.io.core.ByteReadPacket import io.ktor.utils.io.core.ByteReadPacket
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import org.khronos.webgl.ArrayBuffer import org.khronos.webgl.ArrayBuffer
@ -27,9 +28,8 @@ fun uploadFileCallbackForHTMLInputChange(
FullFileInfo( FullFileInfo(
FileName(file.name), FileName(file.name),
findBuiltinMimeType(file.type) ?: KnownMimeTypes.Any, findBuiltinMimeType(file.type) ?: KnownMimeTypes.Any,
) { BytesBasedInputProvider(bytes)
ByteReadPacket(bytes) )
}
) )
} }

@ -12,9 +12,9 @@ kotlin {
dependencies { dependencies {
api libs.microutils.common api libs.microutils.common
api libs.microutils.serialization.typedserializer api libs.microutils.serialization.typedserializer
api libs.klock
api "io.insert-koin:koin-core:$koin_version" api "io.insert-koin:koin-core:$koin_version"
api "com.benasher44:uuid:$uuid_version" api "com.benasher44:uuid:$uuid_version"
api "com.soywiz.korlibs.klock:klock:$klock_version"
api "io.ktor:ktor-http:$ktor_version" api "io.ktor:ktor-http:$ktor_version"
} }
} }

@ -1,30 +1,47 @@
package dev.inmo.postssystem.features.common.common package dev.inmo.postssystem.features.common.common
import dev.inmo.micro_utils.common.ByteArrayAllocatorSerializer import dev.inmo.micro_utils.common.MPPFile
import io.ktor.utils.io.core.* import io.ktor.utils.io.core.*
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.builtins.ByteArraySerializer
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.Serializable
typealias SimpleInputProvider = () -> Input @Serializable(SimpleInputProviderSerializer::class)
interface SimpleInputProvider {
operator fun invoke(): Input
}
@Serializable
class BytesBasedInputProvider(
private val bytes: ByteArray
) : SimpleInputProvider {
override fun invoke(): Input {
return ByteReadPacket(bytes)
}
}
@Serializable(SimpleInputProviderSerializer::class)
expect class FileBasedInputProvider : SimpleInputProvider {
val file: MPPFile
}
object SimpleInputProviderSerializer : KSerializer<SimpleInputProvider> { object SimpleInputProviderSerializer : KSerializer<SimpleInputProvider> {
private val serializer = ByteArraySerializer()
override val descriptor: SerialDescriptor override val descriptor: SerialDescriptor
get() = ByteArrayAllocatorSerializer.descriptor get() = serializer.descriptor
override fun deserialize(decoder: Decoder): SimpleInputProvider { override fun deserialize(decoder: Decoder): SimpleInputProvider {
val allocator = ByteArrayAllocatorSerializer.deserialize(decoder) val bytes = serializer.deserialize(decoder)
return { return BytesBasedInputProvider(bytes)
ByteReadPacket(allocator.invoke())
}
} }
override fun serialize(encoder: Encoder, value: SimpleInputProvider) { override fun serialize(encoder: Encoder, value: SimpleInputProvider) {
ByteArrayAllocatorSerializer.serialize( serializer.serialize(
encoder encoder,
) {
value().readBytes() value().readBytes()
} )
} }
} }

@ -0,0 +1,14 @@
package dev.inmo.postssystem.features.common.common
import dev.inmo.micro_utils.common.MPPFile
import io.ktor.utils.io.core.ByteReadPacket
import io.ktor.utils.io.core.Input
import kotlinx.serialization.Serializable
@Serializable(SimpleInputProviderSerializer::class)
actual class FileBasedInputProvider internal constructor(
actual val file: MPPFile,
private val bytes: ByteArray
) : SimpleInputProvider {
override fun invoke(): Input = ByteReadPacket(bytes)
}

@ -0,0 +1,13 @@
package dev.inmo.postssystem.features.common.common
import dev.inmo.micro_utils.common.MPPFile
import io.ktor.utils.io.core.Input
import io.ktor.utils.io.streams.asInput
import kotlinx.serialization.Serializable
@Serializable(SimpleInputProviderSerializer::class)
actual class FileBasedInputProvider(
actual val file: MPPFile
) : SimpleInputProvider {
override fun invoke(): Input = file.inputStream().asInput()
}

@ -3,6 +3,7 @@ package dev.inmo.postssystem.features.files.common
import dev.inmo.postssystem.features.files.common.storage.ReadFilesStorage import dev.inmo.postssystem.features.files.common.storage.ReadFilesStorage
import dev.inmo.micro_utils.pagination.* import dev.inmo.micro_utils.pagination.*
import dev.inmo.micro_utils.repos.ReadKeyValueRepo import dev.inmo.micro_utils.repos.ReadKeyValueRepo
import dev.inmo.postssystem.features.common.common.FileBasedInputProvider
import io.ktor.utils.io.streams.asInput import io.ktor.utils.io.streams.asInput
import java.io.File import java.io.File
@ -37,10 +38,9 @@ class DiskReadFilesStorage(
id, id,
FullFileInfo( FullFileInfo(
it.fileInfo.name, it.fileInfo.name,
it.fileInfo.mimeType it.fileInfo.mimeType,
) { FileBasedInputProvider(id.file)
id.file.inputStream().asInput() )
}
) )
} }

@ -16,12 +16,6 @@ koin_version=3.1.2
ktor_version=1.6.7 ktor_version=1.6.7
logback_version=1.2.10 logback_version=1.2.10
uuid_version=0.3.1 uuid_version=0.3.1
klock_version=2.5.2
# Server
kotlin_exposed_version=0.37.3
psql_version=42.3.0
# JS # JS

@ -2,11 +2,12 @@
kotlin = "1.6.10" kotlin = "1.6.10"
kotlin-serialization = "1.3.2" kotlin-serialization = "1.3.2"
jsuikit = "0.0.41" jsuikit = "0.0.42"
compose = "1.1.0" compose = "1.1.0"
microutils = "0.9.9" microutils = "0.9.10"
tgbotapi = "0.38.6" tgbotapi = "0.38.6"
ktor = "1.6.7" ktor = "1.6.7"
klock = "2.6.1"
exposed = "0.37.3" exposed = "0.37.3"
psql = "42.3.0" psql = "42.3.0"
@ -46,6 +47,8 @@ microutils-serialization-typedserializer = { module = "dev.inmo:micro_utils.seri
tgbotapi = { module = "dev.inmo:tgbotapi", version.ref = "tgbotapi" } tgbotapi = { module = "dev.inmo:tgbotapi", version.ref = "tgbotapi" }
klock = { module = "com.soywiz.korlibs.klock:klock", version.ref = "klock" }
androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "android-test-junit" } androidx-test-junit = { module = "androidx.test.ext:junit", version.ref = "android-test-junit" }
androidx-espresso = { module = "androidx.test.espresso:espresso-core", version.ref = "android-espresso-core" } androidx-espresso = { module = "androidx.test.espresso:espresso-core", version.ref = "android-espresso-core" }

File diff suppressed because one or more lines are too long

@ -45,7 +45,7 @@ class ClientWritePostsService(
when (content) { when (content) {
is BinaryContent -> append( is BinaryContent -> append(
i.toString(), i.toString(),
InputProvider(block = content.inputProvider), InputProvider(block = content.inputProvider::invoke),
headers { headers {
append(HttpHeaders.ContentType, content.mimeType.raw) append(HttpHeaders.ContentType, content.mimeType.raw)
append(HttpHeaders.ContentDisposition, "filename=\"${content.filename.name}\"") append(HttpHeaders.ContentDisposition, "filename=\"${content.filename.name}\"")
@ -86,7 +86,7 @@ class ClientWritePostsService(
when (it) { when (it) {
is BinaryContent -> append( is BinaryContent -> append(
i.toString(), i.toString(),
InputProvider(block = it.inputProvider), InputProvider(block = it.inputProvider::invoke),
headers { headers {
append(HttpHeaders.ContentType, it.mimeType.raw) append(HttpHeaders.ContentType, it.mimeType.raw)
append(HttpHeaders.ContentDisposition, "filename=\"${it.filename.name}\"") append(HttpHeaders.ContentDisposition, "filename=\"${it.filename.name}\"")

@ -9,6 +9,7 @@ import dev.inmo.micro_utils.repos.ktor.common.crud.createRouting
import dev.inmo.micro_utils.repos.ktor.common.crud.updateRouting import dev.inmo.micro_utils.repos.ktor.common.crud.updateRouting
import dev.inmo.micro_utils.repos.ktor.common.one_to_many.removeRoute import dev.inmo.micro_utils.repos.ktor.common.one_to_many.removeRoute
import dev.inmo.micro_utils.repos.ktor.server.crud.configureReadStandardCrudRepoRoutes import dev.inmo.micro_utils.repos.ktor.server.crud.configureReadStandardCrudRepoRoutes
import dev.inmo.postssystem.features.common.common.FileBasedInputProvider
import dev.inmo.postssystem.features.content.common.* import dev.inmo.postssystem.features.content.common.*
import dev.inmo.postssystem.features.posts.common.* import dev.inmo.postssystem.features.posts.common.*
import dev.inmo.postssystem.services.posts.common.* import dev.inmo.postssystem.services.posts.common.*
@ -78,8 +79,9 @@ class ServerPostsServiceRoutingConfigurator(
list.add( list.add(
name to BinaryContent( name to BinaryContent(
filename, filename,
mimeType mimeType,
) { resultInput.inputStream().asInput() } FileBasedInputProvider(resultInput)
)
) )
} }
else -> {} else -> {}
@ -139,8 +141,9 @@ class ServerPostsServiceRoutingConfigurator(
list.add( list.add(
name to BinaryContent( name to BinaryContent(
filename, filename,
mimeType mimeType,
) { resultInput.inputStream().asInput() }.either() FileBasedInputProvider(resultInput)
).either()
) )
} }
else -> {} else -> {}