mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-12-22 16:47:13 +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))
|
||||
* 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`
|
||||
* `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`:
|
||||
* Created 🎉
|
||||
* `BehaviourBuilder`:
|
||||
|
@ -12,7 +12,7 @@ klock_version=2.7.0
|
||||
uuid_version=0.4.0
|
||||
ktor_version=1.6.8
|
||||
|
||||
micro_utils_version=0.9.20
|
||||
micro_utils_version=0.9.24
|
||||
|
||||
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.encapsulator:$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 "io.ktor:ktor-client-core:$ktor_version"
|
||||
|
@ -1,6 +1,5 @@
|
||||
package dev.inmo.tgbotapi.bot.Ktor.base
|
||||
|
||||
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
|
||||
import dev.inmo.tgbotapi.requests.abstracts.*
|
||||
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
|
||||
import dev.inmo.tgbotapi.utils.mapWithCommonValues
|
||||
@ -26,7 +25,7 @@ class MultipartRequestCallFactory : AbstractRequestCallFactory() {
|
||||
Headers.build {
|
||||
append(HttpHeaders.ContentDisposition, "filename=${value.filename}")
|
||||
},
|
||||
block = value.file::input
|
||||
block = value::input
|
||||
)
|
||||
is FileId -> append(key, value.fileId)
|
||||
else -> append(key, value.toString())
|
||||
|
@ -1,11 +1,12 @@
|
||||
package dev.inmo.tgbotapi.requests.abstracts
|
||||
|
||||
import com.benasher44.uuid.uuid4
|
||||
import dev.inmo.micro_utils.common.MPPFile
|
||||
import dev.inmo.tgbotapi.utils.*
|
||||
import io.ktor.utils.io.ByteReadChannel
|
||||
import io.ktor.utils.io.core.ByteReadPacket
|
||||
import io.ktor.utils.io.core.Input
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.descriptors.*
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
@ -24,6 +25,15 @@ import kotlinx.serialization.encoding.Encoder
|
||||
@Serializable(InputFileSerializer::class)
|
||||
sealed class InputFile {
|
||||
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
|
||||
@ -43,6 +53,8 @@ data class FileId(
|
||||
override val fileId: String
|
||||
) : InputFile()
|
||||
|
||||
typealias FileUrl = FileId
|
||||
|
||||
fun String.toInputFile() = FileId(this)
|
||||
|
||||
@RiskFeature
|
||||
@ -60,23 +72,49 @@ object InputFileSerializer : KSerializer<InputFile> {
|
||||
*/
|
||||
@Serializable(InputFileSerializer::class)
|
||||
data class MultipartFile (
|
||||
val file: StorageFile,
|
||||
val filename: String = file.fileName
|
||||
val filename: String,
|
||||
private val inputSource: () -> Input
|
||||
) : 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")
|
||||
inline fun StorageFile.asMultipartFile() = MultipartFile(this)
|
||||
inline fun StorageFile.asMultipartFile() = MultipartFile(fileName, ::input)
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||
suspend inline fun ByteReadChannel.asMultipartFile(
|
||||
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")
|
||||
suspend inline fun ByteReadChannelAllocator.asMultipartFile(
|
||||
fileName: String
|
||||
) = 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 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.
|
||||
*
|
||||
@ -34,31 +17,22 @@ data class StorageFileInfo(
|
||||
* @see StorageFileInfo
|
||||
* @see asStorageFile
|
||||
*/
|
||||
@Deprecated("Storage file now is not necessary")
|
||||
data class StorageFile(
|
||||
val fileName: String,
|
||||
private val inputSource: () -> Input
|
||||
) {
|
||||
val input: Input
|
||||
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
|
||||
*/
|
||||
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")
|
||||
inline fun StorageFile(
|
||||
fileName: String,
|
||||
@ -69,6 +43,7 @@ inline fun StorageFile(
|
||||
ByteReadPacket(bytes)
|
||||
}
|
||||
|
||||
@Deprecated("StorageFile now is not necessary")
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
suspend inline fun StorageFile(
|
||||
fileName: String,
|
||||
@ -78,16 +53,19 @@ suspend inline fun StorageFile(
|
||||
inputSource = byteReadChannel.asInput().let { { it } }
|
||||
)
|
||||
|
||||
@Deprecated("StorageFile now is not necessary")
|
||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||
inline fun ByteArray.asStorageFile(
|
||||
fileName: String
|
||||
) = StorageFile(fileName, this)
|
||||
|
||||
@Deprecated("StorageFile now is not necessary")
|
||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||
suspend inline fun ByteReadChannel.asStorageFile(
|
||||
fileName: String
|
||||
) = StorageFile(fileName, this)
|
||||
|
||||
@Deprecated("StorageFile now is not necessary")
|
||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||
suspend inline fun ByteReadChannelAllocator.asStorageFile(
|
||||
fileName: String
|
||||
|
@ -3,6 +3,6 @@ package dev.inmo.tgbotapi.requests.abstracts
|
||||
import dev.inmo.micro_utils.common.*
|
||||
import io.ktor.utils.io.ByteReadChannel
|
||||
|
||||
actual suspend fun MPPFile.asMultipartFile(): MultipartFile = ByteReadChannel(bytes()).asMultipartFile(
|
||||
actual fun MPPFile.asMultipartFile(): MultipartFile = bytesSync().asMultipartFile(
|
||||
filename.name
|
||||
)
|
||||
|
@ -1,12 +1,6 @@
|
||||
package dev.inmo.tgbotapi.requests.abstracts
|
||||
|
||||
import dev.inmo.tgbotapi.utils.StorageFile
|
||||
import java.io.File
|
||||
|
||||
fun File.toInputFile() = if (exists()) {
|
||||
MultipartFile(
|
||||
StorageFile(this)
|
||||
)
|
||||
} else {
|
||||
error("Specified file $absolutePath does not exists")
|
||||
}
|
||||
@Deprecated("Duplacation of asMultipartFile", ReplaceWith("asMultipartFile", "dev.inmo.tgbotapi.requests.abstracts.asMultipartFile"))
|
||||
fun File.toInputFile() = asMultipartFile()
|
||||
|
@ -1,5 +1,14 @@
|
||||
package dev.inmo.tgbotapi.requests.abstracts
|
||||
|
||||
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.nio.file.Files
|
||||
|
||||
@Deprecated("StorageFile now is not necessary")
|
||||
fun StorageFile(
|
||||
file: File
|
||||
) = 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.utils.*
|
||||
|
||||
@Deprecated("StorageFile now is not necessary")
|
||||
suspend fun convertToStorageFile(
|
||||
downloadStreamAllocator: ByteReadChannelAllocator,
|
||||
pathedFile: PathedFile
|
||||
@ -18,6 +19,7 @@ suspend fun convertToStorageFile(
|
||||
)
|
||||
}
|
||||
|
||||
@Deprecated("StorageFile now is not necessary")
|
||||
suspend fun TelegramBot.convertToStorageFile(
|
||||
pathedFile: PathedFile
|
||||
): StorageFile = convertToStorageFile(
|
||||
@ -25,14 +27,17 @@ suspend fun TelegramBot.convertToStorageFile(
|
||||
pathedFile
|
||||
)
|
||||
|
||||
@Deprecated("StorageFile now is not necessary")
|
||||
suspend fun TelegramBot.convertToStorageFile(
|
||||
fileId: FileId
|
||||
): StorageFile = convertToStorageFile(execute(GetFile(fileId)))
|
||||
|
||||
@Deprecated("StorageFile now is not necessary")
|
||||
suspend fun TelegramBot.convertToStorageFile(
|
||||
file: TelegramMediaFile
|
||||
): StorageFile = convertToStorageFile(file.fileId)
|
||||
|
||||
@Deprecated("StorageFile now is not necessary")
|
||||
suspend fun TelegramBot.convertToStorageFile(
|
||||
content: MediaContent
|
||||
): StorageFile = convertToStorageFile(content.media)
|
||||
|
Loading…
Reference in New Issue
Block a user