diff --git a/build.gradle b/build.gradle index 319391dab6..78c107f9c6 100644 --- a/build.gradle +++ b/build.gradle @@ -40,3 +40,9 @@ dependencies { // Use JUnit test framework testImplementation 'junit:junit:4.12' } + +compileKotlin { + kotlinOptions { + freeCompilerArgs = [ disableImplicitReflectionSerializerAnnotation ] + } +} diff --git a/gradle.properties b/gradle.properties index ca94a1211a..30d76e621e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,3 +6,5 @@ joda_time_version=2.10.1 ktor_version=1.1.2 gradle_bintray_plugin_version=1.8.4 + +disableImplicitReflectionSerializerAnnotation=-Xexperimental=kotlinx.serialization.ImplicitReflectionSerializer diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/MultipartRequestCallFactory.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/MultipartRequestCallFactory.kt index 80c2b5f8df..41d4f8be9e 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/MultipartRequestCallFactory.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/base/MultipartRequestCallFactory.kt @@ -33,7 +33,7 @@ class MultipartRequestCallFactory : KtorCallFactory { when (value) { is MultipartFile -> append( key, - value.file.inputStream().asInput(), + value.file.asInput(), Headers.build { append(HttpHeaders.ContentType, value.mimeType) append(HttpHeaders.ContentDisposition, "filename=${value.fileId}") diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests/abstracts/InputFile.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests/abstracts/InputFile.kt index 5488db6c0b..fcc7c627ba 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests/abstracts/InputFile.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/requests/abstracts/InputFile.kt @@ -1,5 +1,6 @@ package com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts +import com.github.insanusmokrassar.TelegramBotAPI.utils.StorageFile import kotlinx.serialization.* import java.io.File import java.nio.file.Files @@ -30,16 +31,15 @@ object FileIdSerializer : KSerializer { /** * Contains info about file for sending */ +@Serializable data class MultipartFile ( - val file: File, - val mimeType: String = Files.probeContentType(file.toPath()), - val filename: String = file.name + val file: StorageFile, + val mimeType: String = file.contentType, + val filename: String = file.fileName ) : InputFile() { - override val fileId: String by lazy { - "${UUID.randomUUID()}.${file.extension}" - } + override val fileId: String = file.generateCustomName() } fun File.toInputFile(): InputFile = MultipartFile( - this + StorageFile(this) ) diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/InputMessageContentSerializer.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/InputMessageContentSerializer.kt new file mode 100644 index 0000000000..2114cea456 --- /dev/null +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/InputMessageContentSerializer.kt @@ -0,0 +1,20 @@ +package com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries + +import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.InputMessageContent.* +import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.abstracts.InputMessageContent +import kotlinx.serialization.* + +@Serializer(InputMessageContent::class) +object InputMessageContentSerializer : KSerializer { + override fun serialize(encoder: Encoder, obj: InputMessageContent) { + when (obj) { + is InputContactMessageContent -> InputContactMessageContent.serializer().serialize(encoder, obj) + is InputLocationMessageContent -> InputLocationMessageContent.serializer().serialize(encoder, obj) + is InputTextMessageContent -> InputTextMessageContent.serializer().serialize(encoder, obj) + is InputVenueMessageContent -> InputVenueMessageContent.serializer().serialize(encoder, obj) + else -> throw IllegalArgumentException("Unknown for serializing InputContactMessageContent") + } + } + + override fun deserialize(decoder: Decoder): InputMessageContent = throw IllegalStateException("Object can't be deserialized") +} diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/abstracts/InputMessageContent.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/abstracts/InputMessageContent.kt index f36cbb3a20..4b7ad7902a 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/abstracts/InputMessageContent.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InlineQueries/abstracts/InputMessageContent.kt @@ -1,3 +1,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.abstracts +import com.github.insanusmokrassar.TelegramBotAPI.types.InlineQueries.InputMessageContentSerializer +import kotlinx.serialization.Serializable + +@Serializable(InputMessageContentSerializer::class) interface InputMessageContent diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InputMedia/InputMedia.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InputMedia/InputMedia.kt index 03388e0ba5..41ec671ded 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InputMedia/InputMedia.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InputMedia/InputMedia.kt @@ -1,9 +1,11 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.InputFile +import kotlinx.serialization.Serializable const val inputMediaFileAttachmentNameTemplate = "attach://%s" +@Serializable(InputMediaSerializer::class) interface InputMedia { val type: String val file: InputFile diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InputMedia/InputMediaSerializer.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InputMedia/InputMediaSerializer.kt new file mode 100644 index 0000000000..f63bad756b --- /dev/null +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/InputMedia/InputMediaSerializer.kt @@ -0,0 +1,21 @@ +package com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia + +import kotlinx.serialization.* + +@Serializer(InputMedia::class) +object InputMediaSerializer : KSerializer { + override fun serialize(encoder: Encoder, obj: InputMedia) { + when (obj) { + is InputMediaVideo -> InputMediaVideo.serializer().serialize(encoder, obj) + is InputMediaAudio -> InputMediaAudio.serializer().serialize(encoder, obj) + is InputMediaPhoto -> InputMediaPhoto.serializer().serialize(encoder, obj) + is InputMediaAnimation -> InputMediaAnimation.serializer().serialize(encoder, obj) + is InputMediaDocument -> InputMediaDocument.serializer().serialize(encoder, obj) + else -> throw IllegalArgumentException("Can't perform and serialize $obj") + } + } + + override fun deserialize(decoder: Decoder): InputMedia { + throw IllegalStateException("Object can't be deserialized") + } +} diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardMarkup.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardMarkup.kt index 7c5e9e590e..39c5bea691 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardMarkup.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/InlineKeyboardMarkup.kt @@ -1,11 +1,16 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.buttons import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardButtons.InlineKeyboardButton -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable +import kotlinx.serialization.* +import kotlinx.serialization.internal.ArrayListSerializer @Serializable data class InlineKeyboardMarkup( @SerialName("inline_keyboard") + @Serializable(with = KeyboardSerializer::class) val keyboard: Matrix ) : KeyboardMarkup + +object KeyboardSerializer : KSerializer> by ArrayListSerializer( + ArrayListSerializer(ContextSerializer(InlineKeyboardButton::class)) +) diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/KeyboardMarkup.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/KeyboardMarkup.kt index 09629a51be..a8702a797a 100644 --- a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/KeyboardMarkup.kt +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/KeyboardMarkup.kt @@ -1,3 +1,6 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.buttons +import kotlinx.serialization.Serializable + +@Serializable(KeyboardMarkupSerializer::class) interface KeyboardMarkup diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/KeyboardMarkupSerializer.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/KeyboardMarkupSerializer.kt new file mode 100644 index 0000000000..97de7e2ef1 --- /dev/null +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/buttons/KeyboardMarkupSerializer.kt @@ -0,0 +1,15 @@ +package com.github.insanusmokrassar.TelegramBotAPI.types.buttons + +import kotlinx.serialization.* + +@Serializer(KeyboardMarkup::class) +object KeyboardMarkupSerializer : KSerializer { + override fun serialize(encoder: Encoder, obj: KeyboardMarkup) { + when(obj) { + is ForceReply -> ForceReply.serializer().serialize(encoder, obj) + is InlineKeyboardMarkup -> InlineKeyboardMarkup.serializer().serialize(encoder, obj) + is ReplyKeyboardMarkup -> ReplyKeyboardMarkup.serializer().serialize(encoder, obj) + is ReplyKeyboardRemove -> ReplyKeyboardRemove.serializer().serialize(encoder, obj) + } + } +} diff --git a/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StorageFile.kt b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StorageFile.kt new file mode 100644 index 0000000000..4173370af3 --- /dev/null +++ b/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StorageFile.kt @@ -0,0 +1,20 @@ +package com.github.insanusmokrassar.TelegramBotAPI.utils + +import kotlinx.io.core.Input +import kotlinx.io.streams.asInput +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import java.io.File +import java.nio.file.Files +import java.util.* + +@Serializable +data class StorageFile( + @Transient + private val file: File = throw IllegalStateException("Can't create object without file") +) { + val contentType: String = Files.probeContentType(file.toPath()) + val fileName: String = file.name + fun generateCustomName(): String = "${UUID.randomUUID()}.${file.extension}" + fun asInput(): Input = Files.newInputStream(file.toPath()).asInput() +}