complete preparations for files uploading via posts
This commit is contained in:
parent
99b953635e
commit
38cd186e60
@ -190,7 +190,7 @@ fun getDIModule(
|
|||||||
singleWithBinds { UsersStorageServerRoutesConfigurator(get(), get()) }
|
singleWithBinds { UsersStorageServerRoutesConfigurator(get(), get()) }
|
||||||
singleWithBinds { RolesStorageReadServerRoutesConfigurator<Role>(get(), RoleSerializer, get()) }
|
singleWithBinds { RolesStorageReadServerRoutesConfigurator<Role>(get(), RoleSerializer, get()) }
|
||||||
singleWithBinds { RolesManagerRolesStorageServerRoutesConfigurator(get(), get()) }
|
singleWithBinds { RolesManagerRolesStorageServerRoutesConfigurator(get(), get()) }
|
||||||
singleWithBinds { ServerPostsServiceRoutingConfigurator(get(), get(), get()) }
|
singleWithBinds { ServerPostsServiceRoutingConfigurator(get(), get(), get(), get()) }
|
||||||
|
|
||||||
singleWithBinds { ClientStaticRoutingConfiguration("web") }
|
singleWithBinds { ClientStaticRoutingConfiguration("web") }
|
||||||
singleWithBinds {
|
singleWithBinds {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -19,6 +19,7 @@ import io.ktor.client.request.headers
|
|||||||
import io.ktor.client.request.post
|
import io.ktor.client.request.post
|
||||||
import io.ktor.http.HttpHeaders
|
import io.ktor.http.HttpHeaders
|
||||||
import kotlinx.serialization.builtins.*
|
import kotlinx.serialization.builtins.*
|
||||||
|
import kotlinx.serialization.modules.polymorphic
|
||||||
|
|
||||||
class ClientWritePostsService(
|
class ClientWritePostsService(
|
||||||
private val baseUrl: String,
|
private val baseUrl: String,
|
||||||
@ -28,7 +29,9 @@ class ClientWritePostsService(
|
|||||||
private val unifiedRequester = UnifiedRequester(
|
private val unifiedRequester = UnifiedRequester(
|
||||||
unifiedRequester.client,
|
unifiedRequester.client,
|
||||||
unifiedRequester.serialFormat.createWithSerializerModuleExtension {
|
unifiedRequester.serialFormat.createWithSerializerModuleExtension {
|
||||||
contextual()
|
polymorphic(Content::class) {
|
||||||
|
subclass(BinaryContent::class, BinaryContentSerializer(TempFileIdentifierInputProvider::class, TempFileIdentifierInputProvider.serializer()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package dev.inmo.postssystem.services.posts.common
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.common.FileName
|
||||||
|
import dev.inmo.micro_utils.mime_types.MimeType
|
||||||
|
import dev.inmo.micro_utils.mime_types.MimeTypeSerializer
|
||||||
|
import dev.inmo.postssystem.features.common.common.SimpleInputProvider
|
||||||
|
import dev.inmo.postssystem.features.content.common.BinaryContent
|
||||||
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.descriptors.*
|
||||||
|
import kotlinx.serialization.encoding.*
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
@Serializer(BinaryContent::class)
|
||||||
|
class BinaryContentSerializer<T: SimpleInputProvider>(
|
||||||
|
private val kClass: KClass<T>,
|
||||||
|
private val serializer: KSerializer<T>
|
||||||
|
) : KSerializer<BinaryContent> {
|
||||||
|
@OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class)
|
||||||
|
override val descriptor: SerialDescriptor = buildSerialDescriptor(
|
||||||
|
"BinaryContent",
|
||||||
|
SerialKind.CONTEXTUAL
|
||||||
|
) {
|
||||||
|
element("filename", FileName.serializer().descriptor)
|
||||||
|
element("mimetype", MimeTypeSerializer.descriptor)
|
||||||
|
element("data", serializer.descriptor)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): BinaryContent {
|
||||||
|
return decoder.decodeStructure(descriptor) {
|
||||||
|
var fileName: FileName? = null
|
||||||
|
var mimeType: MimeType? = null
|
||||||
|
var data: T? = null
|
||||||
|
while (true) {
|
||||||
|
when (val index = decodeElementIndex(descriptor)) {
|
||||||
|
0 -> fileName = decodeSerializableElement(descriptor, 0, FileName.serializer())
|
||||||
|
1 -> mimeType = decodeSerializableElement(descriptor, 1, MimeTypeSerializer)
|
||||||
|
2 -> data = decodeSerializableElement(descriptor, 2, serializer)
|
||||||
|
CompositeDecoder.DECODE_DONE -> break
|
||||||
|
else -> error("Unexpected index: $index")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BinaryContent(
|
||||||
|
fileName ?: error("Filename must be presented, but was absent"),
|
||||||
|
mimeType ?: error("Mimetype must be presented, but was absent"),
|
||||||
|
data ?: error("Data must be presented, but was absent")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: BinaryContent) {
|
||||||
|
require(kClass.isInstance(value.inputProvider)) { "${value.inputProvider} do not inherit $kClass" }
|
||||||
|
encoder.encodeStructure(descriptor) {
|
||||||
|
encodeSerializableElement(descriptor, 0, FileName.serializer(), value.filename)
|
||||||
|
encodeSerializableElement(descriptor, 1, MimeTypeSerializer, value.mimeType)
|
||||||
|
encodeSerializableElement(descriptor, 2, serializer, value.inputProvider as T)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,7 @@ package dev.inmo.postssystem.services.posts.common
|
|||||||
|
|
||||||
import kotlinx.serialization.SerialFormat
|
import kotlinx.serialization.SerialFormat
|
||||||
import kotlinx.serialization.cbor.Cbor
|
import kotlinx.serialization.cbor.Cbor
|
||||||
import kotlinx.serialization.modules.SerializersModule
|
import kotlinx.serialization.modules.*
|
||||||
import kotlinx.serialization.modules.SerializersModuleBuilder
|
|
||||||
|
|
||||||
const val postsRootPath = "posts"
|
const val postsRootPath = "posts"
|
||||||
const val postsCreateTempPathPart = "temp"
|
const val postsCreateTempPathPart = "temp"
|
||||||
@ -13,8 +12,10 @@ const val postsPostIdParameter = "postId"
|
|||||||
fun SerialFormat.createWithSerializerModuleExtension(
|
fun SerialFormat.createWithSerializerModuleExtension(
|
||||||
configurator: SerializersModuleBuilder.() -> Unit
|
configurator: SerializersModuleBuilder.() -> Unit
|
||||||
) = Cbor {
|
) = Cbor {
|
||||||
serializersModule = SerializersModule {
|
serializersModule = this@createWithSerializerModuleExtension.serializersModule.overwriteWith(
|
||||||
include(this@createWithSerializerModuleExtension.serializersModule)
|
SerializersModule {
|
||||||
configurator()
|
include(this@createWithSerializerModuleExtension.serializersModule)
|
||||||
}
|
configurator()
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ import kotlinx.coroutines.*
|
|||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.serialization.builtins.*
|
import kotlinx.serialization.builtins.*
|
||||||
|
import kotlinx.serialization.modules.polymorphic
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.attribute.FileTime
|
import java.nio.file.attribute.FileTime
|
||||||
@ -43,8 +44,15 @@ class ServerPostsServiceRoutingConfigurator(
|
|||||||
private val readPostsService: ReadPostsService,
|
private val readPostsService: ReadPostsService,
|
||||||
private val writePostsService: WritePostsService? = readPostsService as? WritePostsService,
|
private val writePostsService: WritePostsService? = readPostsService as? WritePostsService,
|
||||||
private val scope: CoroutineScope,
|
private val scope: CoroutineScope,
|
||||||
private val unifiedRouter: UnifiedRouter
|
unifiedRouter: UnifiedRouter
|
||||||
) : ApplicationRoutingConfigurator.Element {
|
) : ApplicationRoutingConfigurator.Element {
|
||||||
|
private val unifiedRouter = UnifiedRouter(
|
||||||
|
serialFormat = unifiedRouter.serialFormat.createWithSerializerModuleExtension {
|
||||||
|
polymorphic(Content::class) {
|
||||||
|
subclass(BinaryContent::class, BinaryContentSerializer(TempFileIdentifierInputProvider::class, TempFileIdentifierInputProvider.serializer()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
private val contentEitherSerializer = EitherSerializer(ContentId.serializer(), ContentSerializer)
|
private val contentEitherSerializer = EitherSerializer(ContentId.serializer(), ContentSerializer)
|
||||||
private val contentsEitherSerializer = ListSerializer(contentEitherSerializer)
|
private val contentsEitherSerializer = ListSerializer(contentEitherSerializer)
|
||||||
private val contentsSerializer = ListSerializer(ContentSerializer)
|
private val contentsSerializer = ListSerializer(ContentSerializer)
|
||||||
|
@ -22,8 +22,7 @@ class PublicationTargetTelegram(
|
|||||||
) : PublicationTarget {
|
) : PublicationTarget {
|
||||||
override suspend fun publish(post: PublicationPost) {
|
override suspend fun publish(post: PublicationPost) {
|
||||||
post.content.mapNotNull {
|
post.content.mapNotNull {
|
||||||
val content = it.content
|
when (val content = it.content) {
|
||||||
when (content) {
|
|
||||||
is BinaryContent -> {
|
is BinaryContent -> {
|
||||||
val storageFile by lazy {
|
val storageFile by lazy {
|
||||||
StorageFile(content.filename.name, content.inputProvider().readBytes()).asMultipartFile()
|
StorageFile(content.filename.name, content.inputProvider().readBytes()).asMultipartFile()
|
||||||
|
Loading…
Reference in New Issue
Block a user