mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 08:13:47 +00:00
fix of #556
This commit is contained in:
parent
8331d4edd7
commit
b5334c2b72
@ -10,6 +10,10 @@ __All the `tgbotapi.extensions.*` packages have been removed__
|
|||||||
* Constructor of `UnknownInlineKeyboardButton` is not internal and can be created with any `json` ([#563](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/563))
|
* Constructor of `UnknownInlineKeyboardButton` is not internal and can be created with any `json` ([#563](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/563))
|
||||||
* All the interfaces from `dev.inmo.tgbotapi.types.files.abstracts` have been replaced to `dev.inmo.tgbotapi.types.files` and converted to sealed ([#550](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/550))
|
* All the interfaces from `dev.inmo.tgbotapi.types.files.abstracts` have been replaced to `dev.inmo.tgbotapi.types.files` and converted to sealed ([#550](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/550))
|
||||||
* `PassportFile` has been replaced to `dev.inmo.tgbotapi.types.files`
|
* `PassportFile` has been replaced to `dev.inmo.tgbotapi.types.files`
|
||||||
|
* `StorageFile` has been deprecated (fix of [#556](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/556))
|
||||||
|
* `MultipartFile` do not require `StorageFile` anymore
|
||||||
|
* `InputFile` companion got functions to simplify creation of `InputFile`s
|
||||||
|
* New typealias `FileUrl` (represents `FileId` but declare that they are the same)
|
||||||
* `WebApps`:
|
* `WebApps`:
|
||||||
* Created 🎉
|
* Created 🎉
|
||||||
* `BehaviourBuilder`:
|
* `BehaviourBuilder`:
|
||||||
|
@ -12,7 +12,7 @@ klock_version=2.7.0
|
|||||||
uuid_version=0.4.0
|
uuid_version=0.4.0
|
||||||
ktor_version=1.6.8
|
ktor_version=1.6.8
|
||||||
|
|
||||||
micro_utils_version=0.9.20
|
micro_utils_version=0.9.24
|
||||||
|
|
||||||
javax_activation_version=1.1.1
|
javax_activation_version=1.1.1
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ kotlin {
|
|||||||
api "dev.inmo:micro_utils.serialization.base64:$micro_utils_version"
|
api "dev.inmo:micro_utils.serialization.base64:$micro_utils_version"
|
||||||
api "dev.inmo:micro_utils.serialization.encapsulator:$micro_utils_version"
|
api "dev.inmo:micro_utils.serialization.encapsulator:$micro_utils_version"
|
||||||
api "dev.inmo:micro_utils.serialization.typed_serializer:$micro_utils_version"
|
api "dev.inmo:micro_utils.serialization.typed_serializer:$micro_utils_version"
|
||||||
|
api "dev.inmo:micro_utils.ktor.common:$micro_utils_version"
|
||||||
api "dev.inmo:micro_utils.language_codes:$micro_utils_version"
|
api "dev.inmo:micro_utils.language_codes:$micro_utils_version"
|
||||||
|
|
||||||
api "io.ktor:ktor-client-core:$ktor_version"
|
api "io.ktor:ktor-client-core:$ktor_version"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package dev.inmo.tgbotapi.bot.Ktor.base
|
package dev.inmo.tgbotapi.bot.Ktor.base
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||||
import dev.inmo.tgbotapi.utils.mapWithCommonValues
|
import dev.inmo.tgbotapi.utils.mapWithCommonValues
|
||||||
@ -26,7 +25,7 @@ class MultipartRequestCallFactory : AbstractRequestCallFactory() {
|
|||||||
Headers.build {
|
Headers.build {
|
||||||
append(HttpHeaders.ContentDisposition, "filename=${value.filename}")
|
append(HttpHeaders.ContentDisposition, "filename=${value.filename}")
|
||||||
},
|
},
|
||||||
block = value.file::input
|
block = value::input
|
||||||
)
|
)
|
||||||
is FileId -> append(key, value.fileId)
|
is FileId -> append(key, value.fileId)
|
||||||
else -> append(key, value.toString())
|
else -> append(key, value.toString())
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package dev.inmo.tgbotapi.requests.abstracts
|
package dev.inmo.tgbotapi.requests.abstracts
|
||||||
|
|
||||||
|
import com.benasher44.uuid.uuid4
|
||||||
import dev.inmo.micro_utils.common.MPPFile
|
import dev.inmo.micro_utils.common.MPPFile
|
||||||
import dev.inmo.tgbotapi.utils.*
|
import dev.inmo.tgbotapi.utils.*
|
||||||
import io.ktor.utils.io.ByteReadChannel
|
import io.ktor.utils.io.ByteReadChannel
|
||||||
|
import io.ktor.utils.io.core.ByteReadPacket
|
||||||
import io.ktor.utils.io.core.Input
|
import io.ktor.utils.io.core.Input
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import kotlinx.serialization.descriptors.*
|
import kotlinx.serialization.descriptors.*
|
||||||
import kotlinx.serialization.encoding.Decoder
|
import kotlinx.serialization.encoding.Decoder
|
||||||
import kotlinx.serialization.encoding.Encoder
|
import kotlinx.serialization.encoding.Encoder
|
||||||
@ -24,6 +25,15 @@ import kotlinx.serialization.encoding.Encoder
|
|||||||
@Serializable(InputFileSerializer::class)
|
@Serializable(InputFileSerializer::class)
|
||||||
sealed class InputFile {
|
sealed class InputFile {
|
||||||
abstract val fileId: String
|
abstract val fileId: String
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
operator fun invoke(file: MPPFile) = file.asMultipartFile()
|
||||||
|
|
||||||
|
fun fromInput(filename: String, inputSource: () -> Input) = MultipartFile(filename, inputSource)
|
||||||
|
fun fromFile(file: MPPFile) = invoke(file)
|
||||||
|
fun fromId(id: String) = FileId(id)
|
||||||
|
fun fromUrl(url: String) = FileUrl(url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline val InputFile.attachFileId
|
internal inline val InputFile.attachFileId
|
||||||
@ -43,6 +53,8 @@ data class FileId(
|
|||||||
override val fileId: String
|
override val fileId: String
|
||||||
) : InputFile()
|
) : InputFile()
|
||||||
|
|
||||||
|
typealias FileUrl = FileId
|
||||||
|
|
||||||
fun String.toInputFile() = FileId(this)
|
fun String.toInputFile() = FileId(this)
|
||||||
|
|
||||||
@RiskFeature
|
@RiskFeature
|
||||||
@ -60,23 +72,49 @@ object InputFileSerializer : KSerializer<InputFile> {
|
|||||||
*/
|
*/
|
||||||
@Serializable(InputFileSerializer::class)
|
@Serializable(InputFileSerializer::class)
|
||||||
data class MultipartFile (
|
data class MultipartFile (
|
||||||
val file: StorageFile,
|
val filename: String,
|
||||||
val filename: String = file.fileName
|
private val inputSource: () -> Input
|
||||||
) : InputFile() {
|
) : InputFile() {
|
||||||
override val fileId: String = file.generateCustomName()
|
@Required
|
||||||
|
override val fileId: String = "${uuid4()}.${filename.fileExtension}"
|
||||||
|
val input: Input
|
||||||
|
get() = inputSource()
|
||||||
|
|
||||||
|
@Deprecated("Storage file now is not necessary")
|
||||||
|
constructor(
|
||||||
|
file: StorageFile,
|
||||||
|
filename: String = file.fileName
|
||||||
|
) : this(
|
||||||
|
filename,
|
||||||
|
file::input
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Storage file now is not necessary")
|
||||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
inline fun StorageFile.asMultipartFile() = MultipartFile(this)
|
inline fun StorageFile.asMultipartFile() = MultipartFile(fileName, ::input)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
suspend inline fun ByteReadChannel.asMultipartFile(
|
suspend inline fun ByteReadChannel.asMultipartFile(
|
||||||
fileName: String
|
fileName: String
|
||||||
) = MultipartFile(asStorageFile(fileName))
|
) = MultipartFile(
|
||||||
|
fileName,
|
||||||
|
inputSource = asInput().let { { it } }
|
||||||
|
)
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
|
inline fun ByteArray.asMultipartFile(
|
||||||
|
fileName: String
|
||||||
|
) = MultipartFile(
|
||||||
|
fileName,
|
||||||
|
inputSource = { ByteReadPacket(this) }
|
||||||
|
)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
suspend inline fun ByteReadChannelAllocator.asMultipartFile(
|
suspend inline fun ByteReadChannelAllocator.asMultipartFile(
|
||||||
fileName: String
|
fileName: String
|
||||||
) = this.invoke().asMultipartFile(fileName)
|
) = this.invoke().asMultipartFile(fileName)
|
||||||
|
|
||||||
expect suspend fun MPPFile.asMultipartFile(): MultipartFile
|
expect fun MPPFile.asMultipartFile(): MultipartFile
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun MPPFile.multipartFile() = asMultipartFile()
|
||||||
|
@ -8,23 +8,6 @@ import io.ktor.utils.io.core.ByteReadPacket
|
|||||||
import io.ktor.utils.io.core.Input
|
import io.ktor.utils.io.core.Input
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
/**
|
|
||||||
* Information about file for [StorageFile]
|
|
||||||
*
|
|
||||||
* @param contentType Raw type like "application/json"
|
|
||||||
* @param fileName This filename will be used in telegram system as name of file
|
|
||||||
*/
|
|
||||||
@Serializable
|
|
||||||
@Deprecated("Will be removed soon")
|
|
||||||
data class StorageFileInfo(
|
|
||||||
val fileName: String
|
|
||||||
) {
|
|
||||||
/**
|
|
||||||
* This methods is required for random generation of name for keeping warranties about unique file name
|
|
||||||
*/
|
|
||||||
fun generateCustomName() = "${uuid4()}.${fileName.fileExtension}"
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains info about file, which potentially can be sent to telegram system.
|
* Contains info about file, which potentially can be sent to telegram system.
|
||||||
*
|
*
|
||||||
@ -34,31 +17,22 @@ data class StorageFileInfo(
|
|||||||
* @see StorageFileInfo
|
* @see StorageFileInfo
|
||||||
* @see asStorageFile
|
* @see asStorageFile
|
||||||
*/
|
*/
|
||||||
|
@Deprecated("Storage file now is not necessary")
|
||||||
data class StorageFile(
|
data class StorageFile(
|
||||||
val fileName: String,
|
val fileName: String,
|
||||||
private val inputSource: () -> Input
|
private val inputSource: () -> Input
|
||||||
) {
|
) {
|
||||||
val input: Input
|
val input: Input
|
||||||
get() = inputSource()
|
get() = inputSource()
|
||||||
@Deprecated("This field will be removed soon. Use fileName instead of StorageFileInfo")
|
|
||||||
val storageFileInfo: StorageFileInfo
|
|
||||||
get() = StorageFileInfo(fileName)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This methods is required for random generation of name for keeping warranties about unique file name
|
* This methods is required for random generation of name for keeping warranties about unique file name
|
||||||
*/
|
*/
|
||||||
fun generateCustomName() = "${uuid4()}.${fileName.fileExtension}"
|
fun generateCustomName() = "${uuid4()}.${fileName.fileExtension}"
|
||||||
|
|
||||||
@Deprecated("This constructor will be removed soon. Use constructor with fileName instead of StorageFileInfo")
|
|
||||||
constructor(
|
|
||||||
storageFileInfo: StorageFileInfo,
|
|
||||||
inputSource: () -> Input
|
|
||||||
) : this(
|
|
||||||
storageFileInfo.fileName,
|
|
||||||
inputSource
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("Storage file now is not necessary")
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun StorageFile(
|
inline fun StorageFile(
|
||||||
fileName: String,
|
fileName: String,
|
||||||
@ -69,6 +43,7 @@ inline fun StorageFile(
|
|||||||
ByteReadPacket(bytes)
|
ByteReadPacket(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("StorageFile now is not necessary")
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
suspend inline fun StorageFile(
|
suspend inline fun StorageFile(
|
||||||
fileName: String,
|
fileName: String,
|
||||||
@ -78,16 +53,19 @@ suspend inline fun StorageFile(
|
|||||||
inputSource = byteReadChannel.asInput().let { { it } }
|
inputSource = byteReadChannel.asInput().let { { it } }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Deprecated("StorageFile now is not necessary")
|
||||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
inline fun ByteArray.asStorageFile(
|
inline fun ByteArray.asStorageFile(
|
||||||
fileName: String
|
fileName: String
|
||||||
) = StorageFile(fileName, this)
|
) = StorageFile(fileName, this)
|
||||||
|
|
||||||
|
@Deprecated("StorageFile now is not necessary")
|
||||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
suspend inline fun ByteReadChannel.asStorageFile(
|
suspend inline fun ByteReadChannel.asStorageFile(
|
||||||
fileName: String
|
fileName: String
|
||||||
) = StorageFile(fileName, this)
|
) = StorageFile(fileName, this)
|
||||||
|
|
||||||
|
@Deprecated("StorageFile now is not necessary")
|
||||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
suspend inline fun ByteReadChannelAllocator.asStorageFile(
|
suspend inline fun ByteReadChannelAllocator.asStorageFile(
|
||||||
fileName: String
|
fileName: String
|
||||||
|
@ -3,6 +3,6 @@ package dev.inmo.tgbotapi.requests.abstracts
|
|||||||
import dev.inmo.micro_utils.common.*
|
import dev.inmo.micro_utils.common.*
|
||||||
import io.ktor.utils.io.ByteReadChannel
|
import io.ktor.utils.io.ByteReadChannel
|
||||||
|
|
||||||
actual suspend fun MPPFile.asMultipartFile(): MultipartFile = ByteReadChannel(bytes()).asMultipartFile(
|
actual fun MPPFile.asMultipartFile(): MultipartFile = bytesSync().asMultipartFile(
|
||||||
filename.name
|
filename.name
|
||||||
)
|
)
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.requests.abstracts
|
package dev.inmo.tgbotapi.requests.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.utils.StorageFile
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
fun File.toInputFile() = if (exists()) {
|
@Deprecated("Duplacation of asMultipartFile", ReplaceWith("asMultipartFile", "dev.inmo.tgbotapi.requests.abstracts.asMultipartFile"))
|
||||||
MultipartFile(
|
fun File.toInputFile() = asMultipartFile()
|
||||||
StorageFile(this)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
error("Specified file $absolutePath does not exists")
|
|
||||||
}
|
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
package dev.inmo.tgbotapi.requests.abstracts
|
package dev.inmo.tgbotapi.requests.abstracts
|
||||||
|
|
||||||
import dev.inmo.micro_utils.common.MPPFile
|
import dev.inmo.micro_utils.common.MPPFile
|
||||||
|
import dev.inmo.micro_utils.common.filename
|
||||||
|
import dev.inmo.micro_utils.ktor.common.input
|
||||||
|
|
||||||
actual suspend fun MPPFile.asMultipartFile(): MultipartFile = toInputFile()
|
actual fun MPPFile.asMultipartFile(): MultipartFile = if (exists()) {
|
||||||
|
MultipartFile(
|
||||||
|
filename.string,
|
||||||
|
::input
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
error("Specified file $absolutePath does not exists")
|
||||||
|
}
|
||||||
|
@ -4,6 +4,7 @@ import io.ktor.utils.io.streams.asInput
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
|
||||||
|
@Deprecated("StorageFile now is not necessary")
|
||||||
fun StorageFile(
|
fun StorageFile(
|
||||||
file: File
|
file: File
|
||||||
) = StorageFile(
|
) = StorageFile(
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
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.*
|
||||||
|
import dev.inmo.tgbotapi.requests.get.GetFile
|
||||||
|
import dev.inmo.tgbotapi.types.files.PathedFile
|
||||||
|
import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
|
import dev.inmo.tgbotapi.utils.*
|
||||||
|
|
||||||
|
suspend fun multipartFile(
|
||||||
|
downloadStreamAllocator: ByteReadChannelAllocator,
|
||||||
|
pathedFile: PathedFile
|
||||||
|
): MultipartFile {
|
||||||
|
return downloadStreamAllocator.asMultipartFile(pathedFile.fileName)
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun TelegramBot.multipartFile(
|
||||||
|
pathedFile: PathedFile
|
||||||
|
): MultipartFile = multipartFile(
|
||||||
|
execute(DownloadFileStream(pathedFile.filePath)),
|
||||||
|
pathedFile
|
||||||
|
)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.multipartFile(
|
||||||
|
fileId: FileId
|
||||||
|
): MultipartFile = multipartFile(execute(GetFile(fileId)))
|
||||||
|
|
||||||
|
suspend fun TelegramBot.multipartFile(
|
||||||
|
file: TelegramMediaFile
|
||||||
|
): MultipartFile = multipartFile(file.fileId)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.multipartFile(
|
||||||
|
content: MediaContent
|
||||||
|
): MultipartFile = multipartFile(content.media)
|
@ -9,6 +9,7 @@ import dev.inmo.tgbotapi.types.files.TelegramMediaFile
|
|||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
import dev.inmo.tgbotapi.utils.*
|
import dev.inmo.tgbotapi.utils.*
|
||||||
|
|
||||||
|
@Deprecated("StorageFile now is not necessary")
|
||||||
suspend fun convertToStorageFile(
|
suspend fun convertToStorageFile(
|
||||||
downloadStreamAllocator: ByteReadChannelAllocator,
|
downloadStreamAllocator: ByteReadChannelAllocator,
|
||||||
pathedFile: PathedFile
|
pathedFile: PathedFile
|
||||||
@ -18,6 +19,7 @@ suspend fun convertToStorageFile(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("StorageFile now is not necessary")
|
||||||
suspend fun TelegramBot.convertToStorageFile(
|
suspend fun TelegramBot.convertToStorageFile(
|
||||||
pathedFile: PathedFile
|
pathedFile: PathedFile
|
||||||
): StorageFile = convertToStorageFile(
|
): StorageFile = convertToStorageFile(
|
||||||
@ -25,14 +27,17 @@ suspend fun TelegramBot.convertToStorageFile(
|
|||||||
pathedFile
|
pathedFile
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Deprecated("StorageFile now is not necessary")
|
||||||
suspend fun TelegramBot.convertToStorageFile(
|
suspend fun TelegramBot.convertToStorageFile(
|
||||||
fileId: FileId
|
fileId: FileId
|
||||||
): StorageFile = convertToStorageFile(execute(GetFile(fileId)))
|
): StorageFile = convertToStorageFile(execute(GetFile(fileId)))
|
||||||
|
|
||||||
|
@Deprecated("StorageFile now is not necessary")
|
||||||
suspend fun TelegramBot.convertToStorageFile(
|
suspend fun TelegramBot.convertToStorageFile(
|
||||||
file: TelegramMediaFile
|
file: TelegramMediaFile
|
||||||
): StorageFile = convertToStorageFile(file.fileId)
|
): StorageFile = convertToStorageFile(file.fileId)
|
||||||
|
|
||||||
|
@Deprecated("StorageFile now is not necessary")
|
||||||
suspend fun TelegramBot.convertToStorageFile(
|
suspend fun TelegramBot.convertToStorageFile(
|
||||||
content: MediaContent
|
content: MediaContent
|
||||||
): StorageFile = convertToStorageFile(content.media)
|
): StorageFile = convertToStorageFile(content.media)
|
||||||
|
Loading…
Reference in New Issue
Block a user