From 8dbdbdee13e472c7baceedea651395914176c33b Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 9 Aug 2021 19:39:03 +0600 Subject: [PATCH 01/20] start 0.35.5 --- CHANGELOG.md | 2 ++ gradle.properties | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e3fd66ea9..9403cd66f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # TelegramBotAPI changelog +## 0.35.5 + ## 0.35.4 Hotfix * `Common`: diff --git a/gradle.properties b/gradle.properties index 907ef3eb80..671a2cfeae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,6 +17,6 @@ micro_utils_version=0.5.19 javax_activation_version=1.1.1 library_group=dev.inmo -library_version=0.35.4 +library_version=0.35.5 github_release_plugin_version=2.2.12 From abc0457a36c9fa15f624481411dd4f8c26312427 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 9 Aug 2021 19:55:08 +0600 Subject: [PATCH 02/20] files downloading improvements --- CHANGELOG.md | 4 ++ .../inmo/tgbotapi/types/files/PathedFile.kt | 11 +++- .../tgbotapi/extensions/api/DownloadFile.kt | 4 +- .../tgbotapi/extensions/api/DownloadFile.kt | 56 +++++++++++++++++++ .../inmo/tgbotapi/types/files/PathedFile.kt | 2 + 5 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 9403cd66f9..81799d5b60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ * `Common`: * `Version`: * `MicroUtils`: `0.5.18` -> `0.5.19` +* `API`: + * New extensions `TelegramBot#downloadFile` for writing of incoming bytes to the file + * `PathedFile#filename` extension has been deprecated, and new property `PathedFile#fileName` has been included + directly in `PathedFile` ## 0.35.3 diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PathedFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PathedFile.kt index 06438895c8..247aa63c12 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PathedFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/files/PathedFile.kt @@ -5,8 +5,7 @@ import dev.inmo.tgbotapi.types.FileUniqueId import dev.inmo.tgbotapi.types.fileUniqueIdField import dev.inmo.tgbotapi.types.files.abstracts.* import dev.inmo.tgbotapi.utils.* -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable +import kotlinx.serialization.* @Serializable data class PathedFile( @@ -18,8 +17,14 @@ data class PathedFile( val filePath: String, @SerialName(fileSizeField) override val fileSize: Long? = null -): TelegramMediaFile +): TelegramMediaFile { + @Transient + val fileName: FileName by lazy(LazyThreadSafetyMode.PUBLICATION) { + filePath.filenameFromUrl + } +} +@Deprecated("Use fileName property instead", ReplaceWith("fileName")) val PathedFile.filename: FileName get() = filePath.filenameFromUrl fun TelegramAPIUrlsKeeper.resolveFileURL(file: PathedFile): String = "$fileBaseUrl/${file.filePath}" diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt index 7f653730b6..3099d46591 100644 --- a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt +++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt @@ -16,8 +16,8 @@ suspend fun TelegramBot.downloadFile( suspend fun TelegramBot.downloadFile( pathedFile: PathedFile -): ByteArray = execute( - DownloadFile(pathedFile.filePath) +): ByteArray = downloadFile( + pathedFile.filePath ) suspend fun TelegramBot.downloadFile( diff --git a/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt b/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt new file mode 100644 index 0000000000..e9e6a23ffb --- /dev/null +++ b/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt @@ -0,0 +1,56 @@ +package dev.inmo.tgbotapi.extensions.api + +import dev.inmo.micro_utils.coroutines.doOutsideOfCoroutine +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo +import dev.inmo.tgbotapi.requests.DownloadFile +import dev.inmo.tgbotapi.requests.abstracts.FileId +import dev.inmo.tgbotapi.types.files.PathedFile +import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile +import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent +import java.io.File + +suspend fun TelegramBot.downloadFile( + filePath: String, + destFile: File +): File { + val bytes = downloadFile(filePath) + destFile.deleteRecursively() + + doOutsideOfCoroutine { destFile.createNewFile() } + destFile.writeBytes(bytes) + + return destFile +} + +suspend fun TelegramBot.downloadFile( + pathedFile: PathedFile, + destFile: File +) = downloadFile( + pathedFile.filePath, + destFile +) + +suspend fun TelegramBot.downloadFile( + fileId: FileId, + destFile: File +) = downloadFile( + getFileAdditionalInfo(fileId), + destFile +) + +suspend fun TelegramBot.downloadFile( + file: TelegramMediaFile, + destFile: File +): File = downloadFile( + getFileAdditionalInfo(file), + destFile +) + +suspend fun TelegramBot.downloadFile( + file: MediaContent, + destFile: File +) = downloadFile( + getFileAdditionalInfo(file.media), + destFile +) diff --git a/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/PathedFile.kt b/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/PathedFile.kt index 507349899d..e0cfe38006 100644 --- a/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/PathedFile.kt +++ b/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/PathedFile.kt @@ -9,6 +9,7 @@ fun PathedFile.asStream( telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper ): InputStream = URL(this.fullUrl(telegramAPIUrlsKeeper)).openStream() +@Deprecated("This api will be removed soon. Use `downloadFile` instead") fun PathedFile.asFile( telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper, dest: File = File.createTempFile(this.fileUniqueId, this.filename), @@ -22,6 +23,7 @@ fun PathedFile.asFile( return dest } +@Deprecated("This api will be removed soon. Use `downloadFile` instead") fun PathedFile.asBytes( telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper ): ByteArray = this.asStream(telegramAPIUrlsKeeper) From af2fabf1cad34d9f6f20438d89d2989c7c0edf5e Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 9 Aug 2021 19:55:51 +0600 Subject: [PATCH 03/20] fix changelog --- CHANGELOG.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81799d5b60..d27698adb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,15 +2,16 @@ ## 0.35.5 +* `API`: + * New extensions `TelegramBot#downloadFile` for writing of incoming bytes to the file + * `PathedFile#filename` extension has been deprecated, and new property `PathedFile#fileName` has been included + directly in `PathedFile` + ## 0.35.4 Hotfix * `Common`: * `Version`: * `MicroUtils`: `0.5.18` -> `0.5.19` -* `API`: - * New extensions `TelegramBot#downloadFile` for writing of incoming bytes to the file - * `PathedFile#filename` extension has been deprecated, and new property `PathedFile#fileName` has been included - directly in `PathedFile` ## 0.35.3 From ea8db5b851cb3627c2085b4701f5f7c963da5bab Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 9 Aug 2021 20:01:26 +0600 Subject: [PATCH 04/20] rename JVM DownloadFile file --- .../extensions/api/{DownloadFile.kt => DownloadFileToFile.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/{DownloadFile.kt => DownloadFileToFile.kt} (100%) diff --git a/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt b/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFileToFile.kt similarity index 100% rename from tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt rename to tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFileToFile.kt From b475976ff10241862b434c3540f809e1105acf85 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 9 Aug 2021 23:22:08 +0600 Subject: [PATCH 05/20] add streaming file downloading feature --- .../tgbotapi/bot/Ktor/KtorRequestsExecutor.kt | 10 ++++- .../DownloadFileChannelRequestCallFactory.kt | 38 +++++++++++++++++++ .../base/DownloadFileRequestCallFactory.kt | 2 +- .../tgbotapi/requests/DownloadFileStream.kt | 15 ++++++++ .../tgbotapi/utils/InputStreamAllocator.kt | 31 +++++++++++++++ .../tgbotapi/utils/TelegramAPIUrlsKeeper.kt | 2 + 6 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/InputStreamAllocator.kt diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt index 65a0f62e2f..ebbc38bebb 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/KtorRequestsExecutor.kt @@ -42,6 +42,14 @@ inline fun telegramBot( crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {} ): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder) +@RiskFeature +fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf( + SimpleRequestCallFactory(), + MultipartRequestCallFactory(), + DownloadFileRequestCallFactory, + DownloadFileChannelRequestCallFactory +) + class KtorRequestsExecutor( telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper, client: HttpClient = HttpClient(), @@ -52,7 +60,7 @@ class KtorRequestsExecutor( ) : BaseRequestsExecutor(telegramAPIUrlsKeeper) { private val callsFactories: List = callsFactories.run { if (!excludeDefaultFactories) { - this + listOf(SimpleRequestCallFactory(), MultipartRequestCallFactory(), DownloadFileRequestCallFactory) + this + createTelegramBotDefaultKtorCallRequestsFactories() } else { this } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt new file mode 100644 index 0000000000..fa8526d5c1 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt @@ -0,0 +1,38 @@ +package dev.inmo.tgbotapi.bot.Ktor.base + +import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory +import dev.inmo.tgbotapi.requests.DownloadFileStream +import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.utils.InputStreamAllocator +import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper +import io.ktor.client.HttpClient +import io.ktor.client.call.receive +import io.ktor.client.request.get +import io.ktor.client.statement.HttpStatement +import io.ktor.utils.io.* +import kotlinx.coroutines.* +import kotlinx.serialization.json.Json +import kotlin.coroutines.coroutineContext + +object DownloadFileChannelRequestCallFactory : KtorCallFactory { + override suspend fun makeCall( + client: HttpClient, + urlsKeeper: TelegramAPIUrlsKeeper, + request: Request, + jsonFormatter: Json + ): T? = (request as? DownloadFileStream) ?.let { + val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath) + + return InputStreamAllocator { + val scope = CoroutineScope(coroutineContext) + val outChannel = ByteChannel() + scope.launch { + client.get(fullUrl).execute { httpResponse -> + val channel: ByteReadChannel = httpResponse.receive() + channel.copyTo(outChannel) + } + } + outChannel + } as T + } +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileRequestCallFactory.kt index cbccc36e5c..aec803e5f8 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileRequestCallFactory.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileRequestCallFactory.kt @@ -16,7 +16,7 @@ object DownloadFileRequestCallFactory : KtorCallFactory { request: Request, jsonFormatter: Json ): T? = (request as? DownloadFile) ?.let { - val fullUrl = "${urlsKeeper.fileBaseUrl}/${it.filePath}" + val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath) return safely { @Suppress("UNCHECKED_CAST") diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt new file mode 100644 index 0000000000..a1be40d3bf --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt @@ -0,0 +1,15 @@ +package dev.inmo.tgbotapi.requests + +import dev.inmo.tgbotapi.requests.abstracts.Request +import dev.inmo.tgbotapi.utils.InputStreamAllocator +import dev.inmo.tgbotapi.utils.InputStreamAllocatorSerializer +import kotlinx.serialization.DeserializationStrategy + +class DownloadFileStream( + val filePath: String +) : Request { + override fun method(): String = filePath + override val resultDeserializer: DeserializationStrategy + get() = InputStreamAllocatorSerializer + +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/InputStreamAllocator.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/InputStreamAllocator.kt new file mode 100644 index 0000000000..6effad4d0c --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/InputStreamAllocator.kt @@ -0,0 +1,31 @@ +package dev.inmo.tgbotapi.utils + +import dev.inmo.micro_utils.common.ByteArrayAllocatorSerializer +import io.ktor.util.toByteArray +import io.ktor.utils.io.ByteReadChannel +import kotlinx.coroutines.* +import kotlinx.serialization.KSerializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +fun interface InputStreamAllocator { + suspend operator fun invoke(): ByteReadChannel +} + +object InputStreamAllocatorSerializer : KSerializer { + override val descriptor: SerialDescriptor = ByteArrayAllocatorSerializer.descriptor + + override fun serialize(encoder: Encoder, value: InputStreamAllocator) { + TODO("Not yet implemented") +// ByteArrayAllocatorSerializer.serialize( +// encoder +// ) { +// } + } + + override fun deserialize(decoder: Decoder): InputStreamAllocator { + val byteArrayAllocator = ByteArrayAllocatorSerializer.deserialize(decoder) + return InputStreamAllocator { ByteReadChannel(byteArrayAllocator()) } + } +} diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/TelegramAPIUrlsKeeper.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/TelegramAPIUrlsKeeper.kt index 100781d435..422634479e 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/TelegramAPIUrlsKeeper.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/TelegramAPIUrlsKeeper.kt @@ -26,4 +26,6 @@ class TelegramAPIUrlsKeeper( commonAPIUrl = "$correctedHost/bot$token" fileBaseUrl = "$correctedHost/file/bot$token" } + + fun createFileLinkUrl(filePath: String) = "${fileBaseUrl}/$filePath" } From c66d64adbcb86cd10f25087f47bb90293027b03d Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Mon, 9 Aug 2021 23:24:12 +0600 Subject: [PATCH 06/20] renames --- .../base/DownloadFileChannelRequestCallFactory.kt | 4 ++-- .../dev/inmo/tgbotapi/requests/DownloadFileStream.kt | 10 +++++----- ...treamAllocator.kt => ByteReadChannelAllocator.kt} | 12 +++++------- 3 files changed, 12 insertions(+), 14 deletions(-) rename tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/{InputStreamAllocator.kt => ByteReadChannelAllocator.kt} (63%) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt index fa8526d5c1..252b228dcf 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt @@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.bot.Ktor.base import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory import dev.inmo.tgbotapi.requests.DownloadFileStream import dev.inmo.tgbotapi.requests.abstracts.Request -import dev.inmo.tgbotapi.utils.InputStreamAllocator +import dev.inmo.tgbotapi.utils.ByteReadChannelAllocator import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper import io.ktor.client.HttpClient import io.ktor.client.call.receive @@ -23,7 +23,7 @@ object DownloadFileChannelRequestCallFactory : KtorCallFactory { ): T? = (request as? DownloadFileStream) ?.let { val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath) - return InputStreamAllocator { + return ByteReadChannelAllocator { val scope = CoroutineScope(coroutineContext) val outChannel = ByteChannel() scope.launch { diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt index a1be40d3bf..5d23f0c64d 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt @@ -1,15 +1,15 @@ package dev.inmo.tgbotapi.requests import dev.inmo.tgbotapi.requests.abstracts.Request -import dev.inmo.tgbotapi.utils.InputStreamAllocator -import dev.inmo.tgbotapi.utils.InputStreamAllocatorSerializer +import dev.inmo.tgbotapi.utils.ByteReadChannelAllocator +import dev.inmo.tgbotapi.utils.ByteReadChannelAllocatorSerializer import kotlinx.serialization.DeserializationStrategy class DownloadFileStream( val filePath: String -) : Request { +) : Request { override fun method(): String = filePath - override val resultDeserializer: DeserializationStrategy - get() = InputStreamAllocatorSerializer + override val resultDeserializer: DeserializationStrategy + get() = ByteReadChannelAllocatorSerializer } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/InputStreamAllocator.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelAllocator.kt similarity index 63% rename from tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/InputStreamAllocator.kt rename to tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelAllocator.kt index 6effad4d0c..260cba6f13 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/InputStreamAllocator.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelAllocator.kt @@ -1,22 +1,20 @@ package dev.inmo.tgbotapi.utils import dev.inmo.micro_utils.common.ByteArrayAllocatorSerializer -import io.ktor.util.toByteArray import io.ktor.utils.io.ByteReadChannel -import kotlinx.coroutines.* import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -fun interface InputStreamAllocator { +fun interface ByteReadChannelAllocator { suspend operator fun invoke(): ByteReadChannel } -object InputStreamAllocatorSerializer : KSerializer { +object ByteReadChannelAllocatorSerializer : KSerializer { override val descriptor: SerialDescriptor = ByteArrayAllocatorSerializer.descriptor - override fun serialize(encoder: Encoder, value: InputStreamAllocator) { + override fun serialize(encoder: Encoder, value: ByteReadChannelAllocator) { TODO("Not yet implemented") // ByteArrayAllocatorSerializer.serialize( // encoder @@ -24,8 +22,8 @@ object InputStreamAllocatorSerializer : KSerializer { // } } - override fun deserialize(decoder: Decoder): InputStreamAllocator { + override fun deserialize(decoder: Decoder): ByteReadChannelAllocator { val byteArrayAllocator = ByteArrayAllocatorSerializer.deserialize(decoder) - return InputStreamAllocator { ByteReadChannel(byteArrayAllocator()) } + return ByteReadChannelAllocator { ByteReadChannel(byteArrayAllocator()) } } } From c8ad68ea6906dc2281a5de4438fa9597969ec792 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 10 Aug 2021 10:12:22 +0600 Subject: [PATCH 07/20] make ByteReadChannelAllocatorSerializer -> ByteReadChannelAllocatorDeserializationStrategy --- .../dev/inmo/tgbotapi/requests/DownloadFileStream.kt | 4 ++-- .../inmo/tgbotapi/utils/ByteReadChannelAllocator.kt | 11 ++--------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt index 5d23f0c64d..c9ba0606bf 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/DownloadFileStream.kt @@ -2,7 +2,7 @@ package dev.inmo.tgbotapi.requests import dev.inmo.tgbotapi.requests.abstracts.Request import dev.inmo.tgbotapi.utils.ByteReadChannelAllocator -import dev.inmo.tgbotapi.utils.ByteReadChannelAllocatorSerializer +import dev.inmo.tgbotapi.utils.ByteReadChannelAllocatorDeserializationStrategy import kotlinx.serialization.DeserializationStrategy class DownloadFileStream( @@ -10,6 +10,6 @@ class DownloadFileStream( ) : Request { override fun method(): String = filePath override val resultDeserializer: DeserializationStrategy - get() = ByteReadChannelAllocatorSerializer + get() = ByteReadChannelAllocatorDeserializationStrategy } diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelAllocator.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelAllocator.kt index 260cba6f13..7df9343cde 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelAllocator.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelAllocator.kt @@ -2,6 +2,7 @@ package dev.inmo.tgbotapi.utils import dev.inmo.micro_utils.common.ByteArrayAllocatorSerializer import io.ktor.utils.io.ByteReadChannel +import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.KSerializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder @@ -11,17 +12,9 @@ fun interface ByteReadChannelAllocator { suspend operator fun invoke(): ByteReadChannel } -object ByteReadChannelAllocatorSerializer : KSerializer { +object ByteReadChannelAllocatorDeserializationStrategy : DeserializationStrategy { override val descriptor: SerialDescriptor = ByteArrayAllocatorSerializer.descriptor - override fun serialize(encoder: Encoder, value: ByteReadChannelAllocator) { - TODO("Not yet implemented") -// ByteArrayAllocatorSerializer.serialize( -// encoder -// ) { -// } - } - override fun deserialize(decoder: Decoder): ByteReadChannelAllocator { val byteArrayAllocator = ByteArrayAllocatorSerializer.deserialize(decoder) return ByteReadChannelAllocator { ByteReadChannel(byteArrayAllocator()) } From 40d94cca705202734d33b3f2af5b595b16a4f9de Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 10 Aug 2021 10:34:59 +0600 Subject: [PATCH 08/20] improvements in files downloading api --- CHANGELOG.md | 4 ++ .../tgbotapi/extensions/api/DownloadFile.kt | 28 ++++++------- .../extensions/api/files/DownloadFile.kt | 39 +++++++++++++++++++ .../api/files/DownloadFileStream.kt | 29 ++++++++++++++ .../api/files/DownloadFileStreamAllocator.kt | 29 ++++++++++++++ .../api/{ => files}/DownloadFileToFile.kt | 15 ++++--- 6 files changed, 122 insertions(+), 22 deletions(-) create mode 100644 tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFile.kt create mode 100644 tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileStream.kt create mode 100644 tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileStreamAllocator.kt rename tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/{ => files}/DownloadFileToFile.kt (78%) diff --git a/CHANGELOG.md b/CHANGELOG.md index d27698adb1..7ddd062828 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ * `API`: * New extensions `TelegramBot#downloadFile` for writing of incoming bytes to the file + * New extensions `TelegramBot#downloadFileStream` and `TelegramBot#downloadFileStreamAllocator` for getting of input + streams instead of whole bytes arrays + * Old extensions `TelegramBot#downloadFile` has been replaced to the new package. Migration: replace in your project + `import dev.inmo.tgbotapi.extensions.api.downloadFile` with `import dev.inmo.tgbotapi.extensions.api.files.downloadFile` * `PathedFile#filename` extension has been deprecated, and new property `PathedFile#fileName` has been included directly in `PathedFile` diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt index 3099d46591..627f75ec8b 100644 --- a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt +++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFile.kt @@ -1,39 +1,33 @@ package dev.inmo.tgbotapi.extensions.api import dev.inmo.tgbotapi.bot.TelegramBot -import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo -import dev.inmo.tgbotapi.requests.DownloadFile +import dev.inmo.tgbotapi.extensions.api.files.downloadFile import dev.inmo.tgbotapi.requests.abstracts.FileId import dev.inmo.tgbotapi.types.files.PathedFile import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent +@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile")) suspend fun TelegramBot.downloadFile( filePath: String -): ByteArray = execute( - DownloadFile(filePath) -) +): ByteArray = downloadFile(filePath) +@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile")) suspend fun TelegramBot.downloadFile( pathedFile: PathedFile -): ByteArray = downloadFile( - pathedFile.filePath -) +): ByteArray = downloadFile(pathedFile) +@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile")) suspend fun TelegramBot.downloadFile( fileId: FileId -): ByteArray = downloadFile( - getFileAdditionalInfo(fileId) -) +): ByteArray = downloadFile(fileId) +@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile")) suspend fun TelegramBot.downloadFile( file: TelegramMediaFile -): ByteArray = downloadFile( - getFileAdditionalInfo(file) -) +): ByteArray = downloadFile(file) +@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile")) suspend fun TelegramBot.downloadFile( file: MediaContent -): ByteArray = downloadFile( - getFileAdditionalInfo(file.media) -) +): ByteArray = downloadFile(file) diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFile.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFile.kt new file mode 100644 index 0000000000..6a69e6b15b --- /dev/null +++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFile.kt @@ -0,0 +1,39 @@ +package dev.inmo.tgbotapi.extensions.api.files + +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo +import dev.inmo.tgbotapi.requests.DownloadFile +import dev.inmo.tgbotapi.requests.abstracts.FileId +import dev.inmo.tgbotapi.types.files.PathedFile +import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile +import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent + +suspend fun TelegramBot.downloadFile( + filePath: String +): ByteArray = execute( + DownloadFile(filePath) +) + +suspend fun TelegramBot.downloadFile( + pathedFile: PathedFile +): ByteArray = downloadFile( + pathedFile.filePath +) + +suspend fun TelegramBot.downloadFile( + fileId: FileId +): ByteArray = downloadFile( + getFileAdditionalInfo(fileId) +) + +suspend fun TelegramBot.downloadFile( + file: TelegramMediaFile +): ByteArray = downloadFile( + getFileAdditionalInfo(file) +) + +suspend fun TelegramBot.downloadFile( + file: MediaContent +): ByteArray = downloadFile( + getFileAdditionalInfo(file.media) +) diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileStream.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileStream.kt new file mode 100644 index 0000000000..f601f643c9 --- /dev/null +++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileStream.kt @@ -0,0 +1,29 @@ +package dev.inmo.tgbotapi.extensions.api.files + +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo +import dev.inmo.tgbotapi.requests.DownloadFileStream +import dev.inmo.tgbotapi.requests.abstracts.FileId +import dev.inmo.tgbotapi.types.files.PathedFile +import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile +import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent + +suspend fun TelegramBot.downloadFileStream( + filePath: String +) = downloadFileStreamAllocator(filePath).invoke() + +suspend fun TelegramBot.downloadFileStream( + pathedFile: PathedFile +) = downloadFileStream(pathedFile.filePath) + +suspend fun TelegramBot.downloadFileStream( + fileId: FileId +) = downloadFileStream(getFileAdditionalInfo(fileId)) + +suspend fun TelegramBot.downloadFileStream( + file: TelegramMediaFile +) = downloadFileStream(getFileAdditionalInfo(file)) + +suspend fun TelegramBot.downloadFileStream( + file: MediaContent +) = downloadFileStream(getFileAdditionalInfo(file.media)) diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileStreamAllocator.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileStreamAllocator.kt new file mode 100644 index 0000000000..8261d4c275 --- /dev/null +++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileStreamAllocator.kt @@ -0,0 +1,29 @@ +package dev.inmo.tgbotapi.extensions.api.files + +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo +import dev.inmo.tgbotapi.requests.DownloadFileStream +import dev.inmo.tgbotapi.requests.abstracts.FileId +import dev.inmo.tgbotapi.types.files.PathedFile +import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile +import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent + +suspend fun TelegramBot.downloadFileStreamAllocator( + filePath: String +) = execute(DownloadFileStream(filePath)) + +suspend fun TelegramBot.downloadFileStreamAllocator( + pathedFile: PathedFile +) = downloadFileStreamAllocator(pathedFile.filePath) + +suspend fun TelegramBot.downloadFileStreamAllocator( + fileId: FileId +) = downloadFileStreamAllocator(getFileAdditionalInfo(fileId)) + +suspend fun TelegramBot.downloadFileStreamAllocator( + file: TelegramMediaFile +) = downloadFileStreamAllocator(getFileAdditionalInfo(file)) + +suspend fun TelegramBot.downloadFileStreamAllocator( + file: MediaContent +) = downloadFileStreamAllocator(getFileAdditionalInfo(file.media)) diff --git a/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFileToFile.kt b/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileToFile.kt similarity index 78% rename from tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFileToFile.kt rename to tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileToFile.kt index e9e6a23ffb..a0934f5247 100644 --- a/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/DownloadFileToFile.kt +++ b/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileToFile.kt @@ -1,24 +1,29 @@ -package dev.inmo.tgbotapi.extensions.api +package dev.inmo.tgbotapi.extensions.api.files import dev.inmo.micro_utils.coroutines.doOutsideOfCoroutine import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo -import dev.inmo.tgbotapi.requests.DownloadFile import dev.inmo.tgbotapi.requests.abstracts.FileId import dev.inmo.tgbotapi.types.files.PathedFile import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent +import io.ktor.util.cio.writeChannel +import io.ktor.utils.io.copyTo +import kotlinx.coroutines.job import java.io.File +import kotlin.coroutines.coroutineContext suspend fun TelegramBot.downloadFile( filePath: String, destFile: File ): File { - val bytes = downloadFile(filePath) - destFile.deleteRecursively() + val readChannel = downloadFileStream(filePath) + destFile.deleteRecursively() + destFile.parentFile.mkdirs() doOutsideOfCoroutine { destFile.createNewFile() } - destFile.writeBytes(bytes) + + readChannel.copyTo(destFile.writeChannel(coroutineContext.job)) return destFile } From 2049fea82af03f6c150a27b50b23cbbf0cfd4d77 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 10 Aug 2021 11:08:08 +0600 Subject: [PATCH 09/20] new asStorageFile --- CHANGELOG.md | 2 ++ .../tgbotapi/utils/ByteReadChannelToInput.kt | 6 ++++ .../dev/inmo/tgbotapi/utils/StorageFile.kt | 31 ++++++++++++++++--- .../kotlin/dev/inmo/tgbotapi/utils/asInput.kt | 8 +++++ .../kotlin/dev/inmo/tgbotapi/utils/asInput.kt | 10 ++++++ .../api/files/DownloadFileToFile.kt | 5 ++- 6 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelToInput.kt create mode 100644 tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/utils/asInput.kt create mode 100644 tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/asInput.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ddd062828..8a921a4196 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.35.5 +* `Core`: + * Several new extensions `ByteReadChannel#asStorageFile` and `ByteReadChannelAllocator#asStorageFile` * `API`: * New extensions `TelegramBot#downloadFile` for writing of incoming bytes to the file * New extensions `TelegramBot#downloadFileStream` and `TelegramBot#downloadFileStreamAllocator` for getting of input diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelToInput.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelToInput.kt new file mode 100644 index 0000000000..e12b6bae15 --- /dev/null +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/ByteReadChannelToInput.kt @@ -0,0 +1,6 @@ +package dev.inmo.tgbotapi.utils + +import io.ktor.utils.io.ByteReadChannel +import io.ktor.utils.io.core.Input + +expect suspend fun ByteReadChannel.asInput(): Input diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt index 6db07683ee..1638729cd7 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt @@ -1,6 +1,7 @@ package dev.inmo.tgbotapi.utils import com.benasher44.uuid.uuid4 +import io.ktor.utils.io.* import io.ktor.utils.io.core.ByteReadPacket import io.ktor.utils.io.core.Input import kotlinx.serialization.Serializable @@ -50,8 +51,30 @@ inline fun StorageFile( ByteReadPacket(bytes) } -/** - * - */ +@Suppress("NOTHING_TO_INLINE") +suspend inline fun StorageFile( + fileName: String, + byteReadChannel: ByteReadChannel, + mimeType: MimeType +) = StorageFile( + StorageFileInfo(mimeType.raw, fileName), + byteReadChannel.asInput().let { { it } } +) + @Suppress("NOTHING_TO_INLINE", "unused") -inline fun ByteArray.asStorageFile(fileName: String, mimeType: MimeType) = StorageFile(fileName, this, mimeType) +inline fun ByteArray.asStorageFile( + fileName: String, + mimeType: MimeType +) = StorageFile(fileName, this, mimeType) + +@Suppress("NOTHING_TO_INLINE", "unused") +suspend inline fun ByteReadChannel.asStorageFile( + fileName: String, + mimeType: MimeType +) = StorageFile(fileName, this, mimeType) + +@Suppress("NOTHING_TO_INLINE", "unused") +suspend inline fun ByteReadChannelAllocator.asStorageFile( + fileName: String, + mimeType: MimeType +) = this.invoke().asStorageFile(fileName, mimeType) diff --git a/tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/utils/asInput.kt b/tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/utils/asInput.kt new file mode 100644 index 0000000000..b64c816a97 --- /dev/null +++ b/tgbotapi.core/src/jsMain/kotlin/dev/inmo/tgbotapi/utils/asInput.kt @@ -0,0 +1,8 @@ +package dev.inmo.tgbotapi.utils + +import io.ktor.util.toByteArray +import io.ktor.utils.io.ByteReadChannel +import io.ktor.utils.io.core.ByteReadPacket +import io.ktor.utils.io.core.Input + +actual suspend fun ByteReadChannel.asInput(): Input = ByteReadPacket(toByteArray()) diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/asInput.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/asInput.kt new file mode 100644 index 0000000000..a68c1f8639 --- /dev/null +++ b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/asInput.kt @@ -0,0 +1,10 @@ +package dev.inmo.tgbotapi.utils + +import io.ktor.utils.io.ByteReadChannel +import io.ktor.utils.io.core.Input +import io.ktor.utils.io.jvm.javaio.toInputStream +import io.ktor.utils.io.streams.asInput +import kotlinx.coroutines.job +import kotlin.coroutines.coroutineContext + +actual suspend fun ByteReadChannel.asInput(): Input = toInputStream(coroutineContext.job).asInput() diff --git a/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileToFile.kt b/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileToFile.kt index a0934f5247..0e12b4c855 100644 --- a/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileToFile.kt +++ b/tgbotapi.extensions.api/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/api/files/DownloadFileToFile.kt @@ -7,6 +7,7 @@ import dev.inmo.tgbotapi.requests.abstracts.FileId import dev.inmo.tgbotapi.types.files.PathedFile import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent +import io.ktor.util.cio.use import io.ktor.util.cio.writeChannel import io.ktor.utils.io.copyTo import kotlinx.coroutines.job @@ -23,7 +24,9 @@ suspend fun TelegramBot.downloadFile( destFile.parentFile.mkdirs() doOutsideOfCoroutine { destFile.createNewFile() } - readChannel.copyTo(destFile.writeChannel(coroutineContext.job)) + destFile.writeChannel(coroutineContext.job).use { + readChannel.copyTo(this) + } return destFile } From 149ecf175bf39bdeae215df9260df1988f320044 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 10 Aug 2021 11:29:46 +0600 Subject: [PATCH 10/20] small improvement of DownloadFileChannelRequestCallFactory --- .../bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt index 252b228dcf..eba7e7d4a1 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt @@ -23,7 +23,7 @@ object DownloadFileChannelRequestCallFactory : KtorCallFactory { ): T? = (request as? DownloadFileStream) ?.let { val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath) - return ByteReadChannelAllocator { + ByteReadChannelAllocator { val scope = CoroutineScope(coroutineContext) val outChannel = ByteChannel() scope.launch { From 9a1493251175bc809fdd54c6838cc49530a7bc44 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 10 Aug 2021 11:32:22 +0600 Subject: [PATCH 11/20] small improvement of DownloadFileRequestCallFactory --- .../tgbotapi/bot/Ktor/base/DownloadFileRequestCallFactory.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileRequestCallFactory.kt index aec803e5f8..bf8e3687d9 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileRequestCallFactory.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileRequestCallFactory.kt @@ -18,7 +18,7 @@ object DownloadFileRequestCallFactory : KtorCallFactory { ): T? = (request as? DownloadFile) ?.let { val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath) - return safely { + safely { @Suppress("UNCHECKED_CAST") client.get(fullUrl) as T // always ByteArray } From f42cf7896995242745696260730f3b11594e1762 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 10 Aug 2021 16:50:50 +0600 Subject: [PATCH 12/20] fixes --- .../bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt index eba7e7d4a1..3532ec5217 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/DownloadFileChannelRequestCallFactory.kt @@ -1,5 +1,6 @@ package dev.inmo.tgbotapi.bot.Ktor.base +import dev.inmo.micro_utils.coroutines.launchSafelyWithoutExceptions import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory import dev.inmo.tgbotapi.requests.DownloadFileStream import dev.inmo.tgbotapi.requests.abstracts.Request @@ -26,10 +27,10 @@ object DownloadFileChannelRequestCallFactory : KtorCallFactory { ByteReadChannelAllocator { val scope = CoroutineScope(coroutineContext) val outChannel = ByteChannel() - scope.launch { + scope.launchSafelyWithoutExceptions { client.get(fullUrl).execute { httpResponse -> val channel: ByteReadChannel = httpResponse.receive() - channel.copyTo(outChannel) + channel.copyAndClose(outChannel) } } outChannel From f7d2c8bbd2294101512118d2c8b88f290b12a623 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Tue, 10 Aug 2021 16:54:15 +0600 Subject: [PATCH 13/20] hotfix --- CHANGELOG.md | 2 ++ .../tgbotapi/requests/abstracts/InputFile.kt | 25 +++++++++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a921a4196..4896601051 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ * `Core`: * Several new extensions `ByteReadChannel#asStorageFile` and `ByteReadChannelAllocator#asStorageFile` + * Several new extensions `ByteArray#asMultipartFile`, `ByteReadChannel#asMultipartFile` and + `ByteReadChannelAllocator#asMultipartFile` * `API`: * New extensions `TelegramBot#downloadFile` for writing of incoming bytes to the file * New extensions `TelegramBot#downloadFileStream` and `TelegramBot#downloadFileStreamAllocator` for getting of input diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt index d6111400e6..986510d47b 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt @@ -1,7 +1,7 @@ package dev.inmo.tgbotapi.requests.abstracts -import dev.inmo.tgbotapi.utils.RiskFeature -import dev.inmo.tgbotapi.utils.StorageFile +import dev.inmo.tgbotapi.utils.* +import io.ktor.utils.io.ByteReadChannel import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.* @@ -42,6 +42,8 @@ object InputFileSerializer : KSerializer { // TODO:: add checks for files size /** * Contains info about file for sending + * + * @see asMultipartFile */ @Serializable(InputFileSerializer::class) data class MultipartFile ( @@ -51,3 +53,22 @@ data class MultipartFile ( ) : InputFile() { override val fileId: String = file.storageFileInfo.generateCustomName() } + + +@Suppress("NOTHING_TO_INLINE", "unused") +inline fun ByteArray.asMultipartFile( + fileName: String, + mimeType: MimeType +) = MultipartFile(asStorageFile(fileName, mimeType)) + +@Suppress("NOTHING_TO_INLINE", "unused") +suspend inline fun ByteReadChannel.asMultipartFile( + fileName: String, + mimeType: MimeType +) = MultipartFile(asStorageFile(fileName, mimeType)) + +@Suppress("NOTHING_TO_INLINE", "unused") +suspend inline fun ByteReadChannelAllocator.asMultipartFile( + fileName: String, + mimeType: MimeType +) = this.invoke().asMultipartFile(fileName, mimeType) From 9eb6008a73a67a5eafa599dc16924b678a3a379b Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 13 Aug 2021 11:37:01 +0600 Subject: [PATCH 14/20] convertToStorageFile --- CHANGELOG.md | 2 + .../tgbotapi/extensions/api/get/GetFile.kt | 5 +++ .../utils/types/files/ContentAsStorageFile.kt | 45 +++++++++++++++++++ .../files/AdditionalContentAsStorageFile.kt | 41 +++++++++++++++++ 4 files changed, 93 insertions(+) create mode 100644 tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/ContentAsStorageFile.kt create mode 100644 tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/AdditionalContentAsStorageFile.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 4896601051..1c69f05405 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ `import dev.inmo.tgbotapi.extensions.api.downloadFile` with `import dev.inmo.tgbotapi.extensions.api.files.downloadFile` * `PathedFile#filename` extension has been deprecated, and new property `PathedFile#fileName` has been included directly in `PathedFile` +* `Utils`: + * Add several functions `convertToStorageFile` and extensions `TelegramBot#convertToStorageFile` ## 0.35.4 Hotfix diff --git a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/get/GetFile.kt b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/get/GetFile.kt index d2515dd8ce..d3ce16dccc 100644 --- a/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/get/GetFile.kt +++ b/tgbotapi.extensions.api/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/api/get/GetFile.kt @@ -4,6 +4,7 @@ import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.requests.abstracts.FileId import dev.inmo.tgbotapi.requests.get.GetFile import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile +import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent suspend fun TelegramBot.getFileAdditionalInfo( fileId: FileId @@ -14,3 +15,7 @@ suspend fun TelegramBot.getFileAdditionalInfo( suspend fun TelegramBot.getFileAdditionalInfo( file: TelegramMediaFile ) = getFileAdditionalInfo(file.fileId) + +suspend fun TelegramBot.getFileAdditionalInfo( + content: MediaContent +) = getFileAdditionalInfo(content.media) diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/ContentAsStorageFile.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/ContentAsStorageFile.kt new file mode 100644 index 0000000000..b9716833eb --- /dev/null +++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/ContentAsStorageFile.kt @@ -0,0 +1,45 @@ +package dev.inmo.tgbotapi.extensions.utils.types.files + +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.requests.DownloadFileStream +import dev.inmo.tgbotapi.requests.abstracts.FileId +import dev.inmo.tgbotapi.requests.get.GetFile +import dev.inmo.tgbotapi.types.files.PathedFile +import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile +import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent +import dev.inmo.tgbotapi.utils.* + +suspend fun convertToStorageFile( + downloadStreamAllocator: ByteReadChannelAllocator, + pathedFile: PathedFile, + mimeType: MimeType +): StorageFile { + return downloadStreamAllocator.asStorageFile( + pathedFile.fileName, + mimeType + ) +} + +suspend fun TelegramBot.convertToStorageFile( + pathedFile: PathedFile, + mimeType: MimeType +): StorageFile = convertToStorageFile( + execute(DownloadFileStream(pathedFile.filePath)), + pathedFile, + mimeType +) + +suspend fun TelegramBot.convertToStorageFile( + fileId: FileId, + mimeType: MimeType +): StorageFile = convertToStorageFile(execute(GetFile(fileId)), mimeType) + +suspend fun TelegramBot.convertToStorageFile( + file: TelegramMediaFile, + mimeType: MimeType +): StorageFile = convertToStorageFile(file.fileId, mimeType) + +suspend fun TelegramBot.convertToStorageFile( + content: MediaContent, + mimeType: MimeType +): StorageFile = convertToStorageFile(content.media, mimeType) diff --git a/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/AdditionalContentAsStorageFile.kt b/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/AdditionalContentAsStorageFile.kt new file mode 100644 index 0000000000..d09cb48ae0 --- /dev/null +++ b/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/AdditionalContentAsStorageFile.kt @@ -0,0 +1,41 @@ +package dev.inmo.tgbotapi.types.files + +import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.requests.DownloadFileStream +import dev.inmo.tgbotapi.requests.abstracts.FileId +import dev.inmo.tgbotapi.requests.get.GetFile +import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile +import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent +import dev.inmo.tgbotapi.utils.* +import java.nio.file.Files +import kotlin.io.path.Path + + +suspend fun convertToStorageFile( + downloadStreamAllocator: ByteReadChannelAllocator, + pathedFile: PathedFile +): StorageFile { + return downloadStreamAllocator.asStorageFile( + pathedFile.fileName, + Files.probeContentType(Path(pathedFile.fileName)).asMimeType() + ) +} + +suspend fun TelegramBot.convertToStorageFile( + pathedFile: PathedFile +): StorageFile = convertToStorageFile( + execute(DownloadFileStream(pathedFile.filePath)), + pathedFile +) + +suspend fun TelegramBot.convertToStorageFile( + fileId: FileId +): StorageFile = convertToStorageFile(execute(GetFile(fileId))) + +suspend fun TelegramBot.convertToStorageFile( + file: TelegramMediaFile +): StorageFile = convertToStorageFile(file.fileId) + +suspend fun TelegramBot.convertToStorageFile( + content: MediaContent +): StorageFile = convertToStorageFile(content.media) From f147a3d620259b9b574fd855c5cfa4c809947bfb Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 13 Aug 2021 11:41:57 +0600 Subject: [PATCH 15/20] fix of package for AdditionalContentAsStorageFile --- .../utils}/types/files/AdditionalContentAsStorageFile.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/{ => extensions/utils}/types/files/AdditionalContentAsStorageFile.kt (92%) diff --git a/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/AdditionalContentAsStorageFile.kt b/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt similarity index 92% rename from tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/AdditionalContentAsStorageFile.kt rename to tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt index d09cb48ae0..db1229cadb 100644 --- a/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/types/files/AdditionalContentAsStorageFile.kt +++ b/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt @@ -1,9 +1,10 @@ -package dev.inmo.tgbotapi.types.files +package dev.inmo.tgbotapi.extensions.utils.types.files import dev.inmo.tgbotapi.bot.TelegramBot import dev.inmo.tgbotapi.requests.DownloadFileStream import dev.inmo.tgbotapi.requests.abstracts.FileId import dev.inmo.tgbotapi.requests.get.GetFile +import dev.inmo.tgbotapi.types.files.PathedFile import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent import dev.inmo.tgbotapi.utils.* From 17806cde25e941d379ea209da23882b415c400ec Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 13 Aug 2021 11:43:36 +0600 Subject: [PATCH 16/20] add calculation of mimed type from TelegramMediaFile when it is MimedFile --- .../utils/types/files/AdditionalContentAsStorageFile.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt b/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt index db1229cadb..927e7d4c19 100644 --- a/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt +++ b/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt @@ -1,6 +1,7 @@ package dev.inmo.tgbotapi.extensions.utils.types.files import dev.inmo.tgbotapi.bot.TelegramBot +import dev.inmo.tgbotapi.extensions.utils.asMimedMediaFile import dev.inmo.tgbotapi.requests.DownloadFileStream import dev.inmo.tgbotapi.requests.abstracts.FileId import dev.inmo.tgbotapi.requests.get.GetFile @@ -35,7 +36,9 @@ suspend fun TelegramBot.convertToStorageFile( suspend fun TelegramBot.convertToStorageFile( file: TelegramMediaFile -): StorageFile = convertToStorageFile(file.fileId) +): StorageFile = file.asMimedMediaFile() ?.mimeType ?.let { + convertToStorageFile(file.fileId, it) +} ?: convertToStorageFile(file.fileId) suspend fun TelegramBot.convertToStorageFile( content: MediaContent From 58dcbe875135d3f246417c70eeda3ac8d9495724 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 13 Aug 2021 11:45:21 +0600 Subject: [PATCH 17/20] StorageFile#asMultipartFile --- CHANGELOG.md | 1 + .../kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c69f05405..0ea7fb9a66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Several new extensions `ByteReadChannel#asStorageFile` and `ByteReadChannelAllocator#asStorageFile` * Several new extensions `ByteArray#asMultipartFile`, `ByteReadChannel#asMultipartFile` and `ByteReadChannelAllocator#asMultipartFile` + * New extension `StorageFile#asMultipartFile` * `API`: * New extensions `TelegramBot#downloadFile` for writing of incoming bytes to the file * New extensions `TelegramBot#downloadFileStream` and `TelegramBot#downloadFileStreamAllocator` for getting of input diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt index 986510d47b..a024cdbcac 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt @@ -54,6 +54,8 @@ data class MultipartFile ( override val fileId: String = file.storageFileInfo.generateCustomName() } +@Suppress("NOTHING_TO_INLINE", "unused") +inline fun StorageFile.asMultipartFile() = MultipartFile(this) @Suppress("NOTHING_TO_INLINE", "unused") inline fun ByteArray.asMultipartFile( From e75c93d6262a46030aeba6bc0a829cfefe24a21e Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 13 Aug 2021 14:02:39 +0600 Subject: [PATCH 18/20] remove mime types from requests --- .../Ktor/base/MultipartRequestCallFactory.kt | 1 - .../tgbotapi/requests/abstracts/InputFile.kt | 17 +++---- .../dev/inmo/tgbotapi/utils/StorageFile.kt | 43 +++++++++++++----- .../inmo/tgbotapi/utils/StorageFileFactory.kt | 5 +-- .../utils/types/files/ContentAsStorageFile.kt | 27 +++++------ .../files/AdditionalContentAsStorageFile.kt | 45 ------------------- 6 files changed, 51 insertions(+), 87 deletions(-) delete mode 100644 tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/MultipartRequestCallFactory.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/MultipartRequestCallFactory.kt index ca41189baf..2d42d15ea9 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/MultipartRequestCallFactory.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/bot/Ktor/base/MultipartRequestCallFactory.kt @@ -24,7 +24,6 @@ class MultipartRequestCallFactory : AbstractRequestCallFactory() { is MultipartFile -> appendInput( key, Headers.build { - append(HttpHeaders.ContentType, value.mimeType) append(HttpHeaders.ContentDisposition, "filename=${value.fileId}") }, block = value.file::input diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt index a024cdbcac..b306112118 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/abstracts/InputFile.kt @@ -48,29 +48,30 @@ object InputFileSerializer : KSerializer { @Serializable(InputFileSerializer::class) data class MultipartFile ( val file: StorageFile, - val mimeType: String = file.storageFileInfo.contentType, val filename: String = file.storageFileInfo.fileName ) : InputFile() { override val fileId: String = file.storageFileInfo.generateCustomName() + + @Deprecated("This constructor is redundant. Use constructor without mime type") + constructor(file: StorageFile, mimeType: String, filename: String): this(file, filename) } @Suppress("NOTHING_TO_INLINE", "unused") inline fun StorageFile.asMultipartFile() = MultipartFile(this) +@Deprecated("This method is redundant. Use asMultipartFile without mime type") @Suppress("NOTHING_TO_INLINE", "unused") inline fun ByteArray.asMultipartFile( fileName: String, mimeType: MimeType -) = MultipartFile(asStorageFile(fileName, mimeType)) +) = MultipartFile(asStorageFile(fileName)) @Suppress("NOTHING_TO_INLINE", "unused") suspend inline fun ByteReadChannel.asMultipartFile( - fileName: String, - mimeType: MimeType -) = MultipartFile(asStorageFile(fileName, mimeType)) + fileName: String +) = MultipartFile(asStorageFile(fileName)) @Suppress("NOTHING_TO_INLINE", "unused") suspend inline fun ByteReadChannelAllocator.asMultipartFile( - fileName: String, - mimeType: MimeType -) = this.invoke().asMultipartFile(fileName, mimeType) + fileName: String +) = this.invoke().asMultipartFile(fileName) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt index 1638729cd7..a67bb9f19e 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/StorageFile.kt @@ -14,9 +14,14 @@ import kotlinx.serialization.Serializable */ @Serializable data class StorageFileInfo( - val contentType: String, val fileName: String ) { + @Deprecated("This constructor is redundant. Use constructor without mime type") + constructor( + contentType: String, + fileName: String + ): this(fileName) + /** * This methods is required for random generation of name for keeping warranties about unique file name */ @@ -40,13 +45,24 @@ data class StorageFile( get() = inputSource() } +@Deprecated("This constructor is redundant. Use constructor without mime type") @Suppress("NOTHING_TO_INLINE") inline fun StorageFile( fileName: String, bytes: ByteArray, mimeType: MimeType ) = StorageFile( - StorageFileInfo(mimeType.raw, fileName) + StorageFileInfo(fileName) +) { + ByteReadPacket(bytes) +} + +@Suppress("NOTHING_TO_INLINE") +inline fun StorageFile( + fileName: String, + bytes: ByteArray +) = StorageFile( + StorageFileInfo(fileName) ) { ByteReadPacket(bytes) } @@ -54,27 +70,30 @@ inline fun StorageFile( @Suppress("NOTHING_TO_INLINE") suspend inline fun StorageFile( fileName: String, - byteReadChannel: ByteReadChannel, - mimeType: MimeType + byteReadChannel: ByteReadChannel ) = StorageFile( - StorageFileInfo(mimeType.raw, fileName), + StorageFileInfo(fileName), byteReadChannel.asInput().let { { it } } ) +@Suppress("NOTHING_TO_INLINE", "unused") +inline fun ByteArray.asStorageFile( + fileName: String +) = StorageFile(fileName, this) + +@Deprecated("This constructor is redundant. Use constructor without mime type") @Suppress("NOTHING_TO_INLINE", "unused") inline fun ByteArray.asStorageFile( fileName: String, mimeType: MimeType -) = StorageFile(fileName, this, mimeType) +) = asStorageFile(fileName) @Suppress("NOTHING_TO_INLINE", "unused") suspend inline fun ByteReadChannel.asStorageFile( - fileName: String, - mimeType: MimeType -) = StorageFile(fileName, this, mimeType) + fileName: String +) = StorageFile(fileName, this) @Suppress("NOTHING_TO_INLINE", "unused") suspend inline fun ByteReadChannelAllocator.asStorageFile( - fileName: String, - mimeType: MimeType -) = this.invoke().asStorageFile(fileName, mimeType) + fileName: String +) = this.invoke().asStorageFile(fileName) diff --git a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/StorageFileFactory.kt b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/StorageFileFactory.kt index 8d7ebe5c53..9d26befaeb 100644 --- a/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/StorageFileFactory.kt +++ b/tgbotapi.core/src/jvmMain/kotlin/dev/inmo/tgbotapi/utils/StorageFileFactory.kt @@ -7,10 +7,7 @@ import java.nio.file.Files fun StorageFile( file: File ) = StorageFile( - StorageFileInfo( - Files.probeContentType(file.toPath()), - file.name - ) + StorageFileInfo(file.name) ) { file.inputStream().asInput() } diff --git a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/ContentAsStorageFile.kt b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/ContentAsStorageFile.kt index b9716833eb..53b192e74e 100644 --- a/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/ContentAsStorageFile.kt +++ b/tgbotapi.extensions.utils/src/commonMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/ContentAsStorageFile.kt @@ -11,35 +11,28 @@ import dev.inmo.tgbotapi.utils.* suspend fun convertToStorageFile( downloadStreamAllocator: ByteReadChannelAllocator, - pathedFile: PathedFile, - mimeType: MimeType + pathedFile: PathedFile ): StorageFile { return downloadStreamAllocator.asStorageFile( - pathedFile.fileName, - mimeType + pathedFile.fileName ) } suspend fun TelegramBot.convertToStorageFile( - pathedFile: PathedFile, - mimeType: MimeType + pathedFile: PathedFile ): StorageFile = convertToStorageFile( execute(DownloadFileStream(pathedFile.filePath)), - pathedFile, - mimeType + pathedFile ) suspend fun TelegramBot.convertToStorageFile( - fileId: FileId, - mimeType: MimeType -): StorageFile = convertToStorageFile(execute(GetFile(fileId)), mimeType) + fileId: FileId +): StorageFile = convertToStorageFile(execute(GetFile(fileId))) suspend fun TelegramBot.convertToStorageFile( - file: TelegramMediaFile, - mimeType: MimeType -): StorageFile = convertToStorageFile(file.fileId, mimeType) + file: TelegramMediaFile +): StorageFile = convertToStorageFile(file.fileId) suspend fun TelegramBot.convertToStorageFile( - content: MediaContent, - mimeType: MimeType -): StorageFile = convertToStorageFile(content.media, mimeType) + content: MediaContent +): StorageFile = convertToStorageFile(content.media) diff --git a/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt b/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt deleted file mode 100644 index 927e7d4c19..0000000000 --- a/tgbotapi.extensions.utils/src/jvmMain/kotlin/dev/inmo/tgbotapi/extensions/utils/types/files/AdditionalContentAsStorageFile.kt +++ /dev/null @@ -1,45 +0,0 @@ -package dev.inmo.tgbotapi.extensions.utils.types.files - -import dev.inmo.tgbotapi.bot.TelegramBot -import dev.inmo.tgbotapi.extensions.utils.asMimedMediaFile -import dev.inmo.tgbotapi.requests.DownloadFileStream -import dev.inmo.tgbotapi.requests.abstracts.FileId -import dev.inmo.tgbotapi.requests.get.GetFile -import dev.inmo.tgbotapi.types.files.PathedFile -import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile -import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent -import dev.inmo.tgbotapi.utils.* -import java.nio.file.Files -import kotlin.io.path.Path - - -suspend fun convertToStorageFile( - downloadStreamAllocator: ByteReadChannelAllocator, - pathedFile: PathedFile -): StorageFile { - return downloadStreamAllocator.asStorageFile( - pathedFile.fileName, - Files.probeContentType(Path(pathedFile.fileName)).asMimeType() - ) -} - -suspend fun TelegramBot.convertToStorageFile( - pathedFile: PathedFile -): StorageFile = convertToStorageFile( - execute(DownloadFileStream(pathedFile.filePath)), - pathedFile -) - -suspend fun TelegramBot.convertToStorageFile( - fileId: FileId -): StorageFile = convertToStorageFile(execute(GetFile(fileId))) - -suspend fun TelegramBot.convertToStorageFile( - file: TelegramMediaFile -): StorageFile = file.asMimedMediaFile() ?.mimeType ?.let { - convertToStorageFile(file.fileId, it) -} ?: convertToStorageFile(file.fileId) - -suspend fun TelegramBot.convertToStorageFile( - content: MediaContent -): StorageFile = convertToStorageFile(content.media) From c90bcea42c79679acdc46ed0f1a1f34c004bd54c Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 13 Aug 2021 18:39:08 +0600 Subject: [PATCH 19/20] add additional mime types --- CHANGELOG.md | 2 ++ .../kotlin/dev/inmo/tgbotapi/utils/BuiltinMimeTypes.kt | 9 ++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ea7fb9a66..908a9149fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.35.5 +**MIME TYPES FOR REQUESTS HAVE BEEN DEPRECATED DUE TO REDUNDANCY OF MIME TYPES IN FILES SENDING** + * `Core`: * Several new extensions `ByteReadChannel#asStorageFile` and `ByteReadChannelAllocator#asStorageFile` * Several new extensions `ByteArray#asMultipartFile`, `ByteReadChannel#asMultipartFile` and diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/BuiltinMimeTypes.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/BuiltinMimeTypes.kt index be0dcb1f2f..340df5867d 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/BuiltinMimeTypes.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/BuiltinMimeTypes.kt @@ -1,6 +1,6 @@ package dev.inmo.tgbotapi.utils -object BuiltinMimeTypes { +sealed interface BuiltinMimeTypes { object Image { val Jpg = buildMimeType("image/jpeg") val Gif = buildMimeType("image/gif") @@ -8,4 +8,11 @@ object BuiltinMimeTypes { object Video { val MP4 = buildMimeType("video/mp4") } + object Text { + val Html = buildMimeType("text/html") + } + object Application { + val Zip = buildMimeType("application/zip") + val Pdf = buildMimeType("application/pdf") + } } From c4fbd2f1c6b16abb73447655807d848f4173d8e0 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Fri, 13 Aug 2021 18:39:46 +0600 Subject: [PATCH 20/20] revert type of BuiltinMimeTypes --- .../kotlin/dev/inmo/tgbotapi/utils/BuiltinMimeTypes.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/BuiltinMimeTypes.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/BuiltinMimeTypes.kt index 340df5867d..beb3d96f6e 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/BuiltinMimeTypes.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/utils/BuiltinMimeTypes.kt @@ -1,6 +1,6 @@ package dev.inmo.tgbotapi.utils -sealed interface BuiltinMimeTypes { +object BuiltinMimeTypes { object Image { val Jpg = buildMimeType("image/jpeg") val Gif = buildMimeType("image/gif")