mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 08:13:47 +00:00
commit
7b1344e9c8
20
CHANGELOG.md
20
CHANGELOG.md
@ -1,5 +1,25 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
|
## 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
|
||||||
|
`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
|
||||||
|
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`
|
||||||
|
* `Utils`:
|
||||||
|
* Add several functions `convertToStorageFile` and extensions `TelegramBot#convertToStorageFile`
|
||||||
|
|
||||||
## 0.35.4 Hotfix
|
## 0.35.4 Hotfix
|
||||||
|
|
||||||
* `Common`:
|
* `Common`:
|
||||||
|
@ -17,6 +17,6 @@ micro_utils_version=0.5.19
|
|||||||
javax_activation_version=1.1.1
|
javax_activation_version=1.1.1
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=0.35.4
|
library_version=0.35.5
|
||||||
|
|
||||||
github_release_plugin_version=2.2.12
|
github_release_plugin_version=2.2.12
|
||||||
|
@ -42,6 +42,14 @@ inline fun telegramBot(
|
|||||||
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
crossinline builder: KtorRequestsExecutorBuilder.() -> Unit = {}
|
||||||
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
|
): TelegramBot = telegramBot(TelegramAPIUrlsKeeper(token, apiUrl), builder)
|
||||||
|
|
||||||
|
@RiskFeature
|
||||||
|
fun createTelegramBotDefaultKtorCallRequestsFactories() = listOf(
|
||||||
|
SimpleRequestCallFactory(),
|
||||||
|
MultipartRequestCallFactory(),
|
||||||
|
DownloadFileRequestCallFactory,
|
||||||
|
DownloadFileChannelRequestCallFactory
|
||||||
|
)
|
||||||
|
|
||||||
class KtorRequestsExecutor(
|
class KtorRequestsExecutor(
|
||||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||||
client: HttpClient = HttpClient(),
|
client: HttpClient = HttpClient(),
|
||||||
@ -52,7 +60,7 @@ class KtorRequestsExecutor(
|
|||||||
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
|
||||||
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
|
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
|
||||||
if (!excludeDefaultFactories) {
|
if (!excludeDefaultFactories) {
|
||||||
this + listOf(SimpleRequestCallFactory(), MultipartRequestCallFactory(), DownloadFileRequestCallFactory)
|
this + createTelegramBotDefaultKtorCallRequestsFactories()
|
||||||
} else {
|
} else {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
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
|
||||||
|
import dev.inmo.tgbotapi.utils.ByteReadChannelAllocator
|
||||||
|
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 <T : Any> makeCall(
|
||||||
|
client: HttpClient,
|
||||||
|
urlsKeeper: TelegramAPIUrlsKeeper,
|
||||||
|
request: Request<T>,
|
||||||
|
jsonFormatter: Json
|
||||||
|
): T? = (request as? DownloadFileStream) ?.let {
|
||||||
|
val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath)
|
||||||
|
|
||||||
|
ByteReadChannelAllocator {
|
||||||
|
val scope = CoroutineScope(coroutineContext)
|
||||||
|
val outChannel = ByteChannel()
|
||||||
|
scope.launchSafelyWithoutExceptions {
|
||||||
|
client.get<HttpStatement>(fullUrl).execute { httpResponse ->
|
||||||
|
val channel: ByteReadChannel = httpResponse.receive()
|
||||||
|
channel.copyAndClose(outChannel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outChannel
|
||||||
|
} as T
|
||||||
|
}
|
||||||
|
}
|
@ -16,9 +16,9 @@ object DownloadFileRequestCallFactory : KtorCallFactory {
|
|||||||
request: Request<T>,
|
request: Request<T>,
|
||||||
jsonFormatter: Json
|
jsonFormatter: Json
|
||||||
): T? = (request as? DownloadFile) ?.let {
|
): T? = (request as? DownloadFile) ?.let {
|
||||||
val fullUrl = "${urlsKeeper.fileBaseUrl}/${it.filePath}"
|
val fullUrl = urlsKeeper.createFileLinkUrl(it.filePath)
|
||||||
|
|
||||||
return safely {
|
safely {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
client.get<ByteArray>(fullUrl) as T // always ByteArray
|
client.get<ByteArray>(fullUrl) as T // always ByteArray
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@ class MultipartRequestCallFactory : AbstractRequestCallFactory() {
|
|||||||
is MultipartFile -> appendInput(
|
is MultipartFile -> appendInput(
|
||||||
key,
|
key,
|
||||||
Headers.build {
|
Headers.build {
|
||||||
append(HttpHeaders.ContentType, value.mimeType)
|
|
||||||
append(HttpHeaders.ContentDisposition, "filename=${value.fileId}")
|
append(HttpHeaders.ContentDisposition, "filename=${value.fileId}")
|
||||||
},
|
},
|
||||||
block = value.file::input
|
block = value.file::input
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package dev.inmo.tgbotapi.requests
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
|
import dev.inmo.tgbotapi.utils.ByteReadChannelAllocator
|
||||||
|
import dev.inmo.tgbotapi.utils.ByteReadChannelAllocatorDeserializationStrategy
|
||||||
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
|
|
||||||
|
class DownloadFileStream(
|
||||||
|
val filePath: String
|
||||||
|
) : Request<ByteReadChannelAllocator> {
|
||||||
|
override fun method(): String = filePath
|
||||||
|
override val resultDeserializer: DeserializationStrategy<ByteReadChannelAllocator>
|
||||||
|
get() = ByteReadChannelAllocatorDeserializationStrategy
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.requests.abstracts
|
package dev.inmo.tgbotapi.requests.abstracts
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
import dev.inmo.tgbotapi.utils.*
|
||||||
import dev.inmo.tgbotapi.utils.StorageFile
|
import io.ktor.utils.io.ByteReadChannel
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.descriptors.*
|
import kotlinx.serialization.descriptors.*
|
||||||
@ -42,12 +42,36 @@ object InputFileSerializer : KSerializer<InputFile> {
|
|||||||
// TODO:: add checks for files size
|
// TODO:: add checks for files size
|
||||||
/**
|
/**
|
||||||
* Contains info about file for sending
|
* Contains info about file for sending
|
||||||
|
*
|
||||||
|
* @see asMultipartFile
|
||||||
*/
|
*/
|
||||||
@Serializable(InputFileSerializer::class)
|
@Serializable(InputFileSerializer::class)
|
||||||
data class MultipartFile (
|
data class MultipartFile (
|
||||||
val file: StorageFile,
|
val file: StorageFile,
|
||||||
val mimeType: String = file.storageFileInfo.contentType,
|
|
||||||
val filename: String = file.storageFileInfo.fileName
|
val filename: String = file.storageFileInfo.fileName
|
||||||
) : InputFile() {
|
) : InputFile() {
|
||||||
override val fileId: String = file.storageFileInfo.generateCustomName()
|
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))
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
|
suspend inline fun ByteReadChannel.asMultipartFile(
|
||||||
|
fileName: String
|
||||||
|
) = MultipartFile(asStorageFile(fileName))
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
|
suspend inline fun ByteReadChannelAllocator.asMultipartFile(
|
||||||
|
fileName: String
|
||||||
|
) = this.invoke().asMultipartFile(fileName)
|
||||||
|
@ -5,8 +5,7 @@ import dev.inmo.tgbotapi.types.FileUniqueId
|
|||||||
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
import dev.inmo.tgbotapi.types.fileUniqueIdField
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.*
|
import dev.inmo.tgbotapi.types.files.abstracts.*
|
||||||
import dev.inmo.tgbotapi.utils.*
|
import dev.inmo.tgbotapi.utils.*
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class PathedFile(
|
data class PathedFile(
|
||||||
@ -18,8 +17,14 @@ data class PathedFile(
|
|||||||
val filePath: String,
|
val filePath: String,
|
||||||
@SerialName(fileSizeField)
|
@SerialName(fileSizeField)
|
||||||
override val fileSize: Long? = null
|
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
|
val PathedFile.filename: FileName
|
||||||
get() = filePath.filenameFromUrl
|
get() = filePath.filenameFromUrl
|
||||||
fun TelegramAPIUrlsKeeper.resolveFileURL(file: PathedFile): String = "$fileBaseUrl/${file.filePath}"
|
fun TelegramAPIUrlsKeeper.resolveFileURL(file: PathedFile): String = "$fileBaseUrl/${file.filePath}"
|
||||||
|
@ -8,4 +8,11 @@ object BuiltinMimeTypes {
|
|||||||
object Video {
|
object Video {
|
||||||
val MP4 = buildMimeType("video/mp4")
|
val MP4 = buildMimeType("video/mp4")
|
||||||
}
|
}
|
||||||
|
object Text {
|
||||||
|
val Html = buildMimeType("text/html")
|
||||||
|
}
|
||||||
|
object Application {
|
||||||
|
val Zip = buildMimeType("application/zip")
|
||||||
|
val Pdf = buildMimeType("application/pdf")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
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
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
|
||||||
|
fun interface ByteReadChannelAllocator {
|
||||||
|
suspend operator fun invoke(): ByteReadChannel
|
||||||
|
}
|
||||||
|
|
||||||
|
object ByteReadChannelAllocatorDeserializationStrategy : DeserializationStrategy<ByteReadChannelAllocator> {
|
||||||
|
override val descriptor: SerialDescriptor = ByteArrayAllocatorSerializer.descriptor
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): ByteReadChannelAllocator {
|
||||||
|
val byteArrayAllocator = ByteArrayAllocatorSerializer.deserialize(decoder)
|
||||||
|
return ByteReadChannelAllocator { ByteReadChannel(byteArrayAllocator()) }
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
@ -1,6 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.utils
|
package dev.inmo.tgbotapi.utils
|
||||||
|
|
||||||
import com.benasher44.uuid.uuid4
|
import com.benasher44.uuid.uuid4
|
||||||
|
import io.ktor.utils.io.*
|
||||||
import io.ktor.utils.io.core.ByteReadPacket
|
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
|
||||||
@ -13,9 +14,14 @@ import kotlinx.serialization.Serializable
|
|||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
data class StorageFileInfo(
|
data class StorageFileInfo(
|
||||||
val contentType: String,
|
|
||||||
val fileName: 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
|
* This methods is required for random generation of name for keeping warranties about unique file name
|
||||||
*/
|
*/
|
||||||
@ -39,19 +45,55 @@ data class StorageFile(
|
|||||||
get() = inputSource()
|
get() = inputSource()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("This constructor is redundant. Use constructor without mime type")
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun StorageFile(
|
inline fun StorageFile(
|
||||||
fileName: String,
|
fileName: String,
|
||||||
bytes: ByteArray,
|
bytes: ByteArray,
|
||||||
mimeType: MimeType
|
mimeType: MimeType
|
||||||
) = StorageFile(
|
) = StorageFile(
|
||||||
StorageFileInfo(mimeType.raw, fileName)
|
StorageFileInfo(fileName)
|
||||||
) {
|
) {
|
||||||
ByteReadPacket(bytes)
|
ByteReadPacket(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
*
|
inline fun StorageFile(
|
||||||
*/
|
fileName: String,
|
||||||
|
bytes: ByteArray
|
||||||
|
) = StorageFile(
|
||||||
|
StorageFileInfo(fileName)
|
||||||
|
) {
|
||||||
|
ByteReadPacket(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
suspend inline fun StorageFile(
|
||||||
|
fileName: String,
|
||||||
|
byteReadChannel: ByteReadChannel
|
||||||
|
) = StorageFile(
|
||||||
|
StorageFileInfo(fileName),
|
||||||
|
byteReadChannel.asInput().let { { it } }
|
||||||
|
)
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE", "unused")
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
inline fun ByteArray.asStorageFile(fileName: String, mimeType: MimeType) = StorageFile(fileName, this, mimeType)
|
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
|
||||||
|
) = asStorageFile(fileName)
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
|
suspend inline fun ByteReadChannel.asStorageFile(
|
||||||
|
fileName: String
|
||||||
|
) = StorageFile(fileName, this)
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE", "unused")
|
||||||
|
suspend inline fun ByteReadChannelAllocator.asStorageFile(
|
||||||
|
fileName: String
|
||||||
|
) = this.invoke().asStorageFile(fileName)
|
||||||
|
@ -26,4 +26,6 @@ class TelegramAPIUrlsKeeper(
|
|||||||
commonAPIUrl = "$correctedHost/bot$token"
|
commonAPIUrl = "$correctedHost/bot$token"
|
||||||
fileBaseUrl = "$correctedHost/file/bot$token"
|
fileBaseUrl = "$correctedHost/file/bot$token"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createFileLinkUrl(filePath: String) = "${fileBaseUrl}/$filePath"
|
||||||
}
|
}
|
||||||
|
@ -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())
|
@ -7,10 +7,7 @@ import java.nio.file.Files
|
|||||||
fun StorageFile(
|
fun StorageFile(
|
||||||
file: File
|
file: File
|
||||||
) = StorageFile(
|
) = StorageFile(
|
||||||
StorageFileInfo(
|
StorageFileInfo(file.name)
|
||||||
Files.probeContentType(file.toPath()),
|
|
||||||
file.name
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
file.inputStream().asInput()
|
file.inputStream().asInput()
|
||||||
}
|
}
|
||||||
|
@ -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()
|
@ -1,39 +1,33 @@
|
|||||||
package dev.inmo.tgbotapi.extensions.api
|
package dev.inmo.tgbotapi.extensions.api
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.extensions.api.get.getFileAdditionalInfo
|
import dev.inmo.tgbotapi.extensions.api.files.downloadFile
|
||||||
import dev.inmo.tgbotapi.requests.DownloadFile
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.files.PathedFile
|
import dev.inmo.tgbotapi.types.files.PathedFile
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile"))
|
||||||
suspend fun TelegramBot.downloadFile(
|
suspend fun TelegramBot.downloadFile(
|
||||||
filePath: String
|
filePath: String
|
||||||
): ByteArray = execute(
|
): ByteArray = downloadFile(filePath)
|
||||||
DownloadFile(filePath)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile"))
|
||||||
suspend fun TelegramBot.downloadFile(
|
suspend fun TelegramBot.downloadFile(
|
||||||
pathedFile: PathedFile
|
pathedFile: PathedFile
|
||||||
): ByteArray = execute(
|
): ByteArray = downloadFile(pathedFile)
|
||||||
DownloadFile(pathedFile.filePath)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile"))
|
||||||
suspend fun TelegramBot.downloadFile(
|
suspend fun TelegramBot.downloadFile(
|
||||||
fileId: FileId
|
fileId: FileId
|
||||||
): ByteArray = downloadFile(
|
): ByteArray = downloadFile(fileId)
|
||||||
getFileAdditionalInfo(fileId)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile"))
|
||||||
suspend fun TelegramBot.downloadFile(
|
suspend fun TelegramBot.downloadFile(
|
||||||
file: TelegramMediaFile
|
file: TelegramMediaFile
|
||||||
): ByteArray = downloadFile(
|
): ByteArray = downloadFile(file)
|
||||||
getFileAdditionalInfo(file)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
@Deprecated("Replaced", ReplaceWith("downloadFile", "dev.inmo.tgbotapi.extensions.api.files.downloadFile"))
|
||||||
suspend fun TelegramBot.downloadFile(
|
suspend fun TelegramBot.downloadFile(
|
||||||
file: MediaContent
|
file: MediaContent
|
||||||
): ByteArray = downloadFile(
|
): ByteArray = downloadFile(file)
|
||||||
getFileAdditionalInfo(file.media)
|
|
||||||
)
|
|
||||||
|
@ -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)
|
||||||
|
)
|
@ -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))
|
@ -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))
|
@ -4,6 +4,7 @@ import dev.inmo.tgbotapi.bot.TelegramBot
|
|||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.requests.get.GetFile
|
import dev.inmo.tgbotapi.requests.get.GetFile
|
||||||
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
import dev.inmo.tgbotapi.types.files.abstracts.TelegramMediaFile
|
||||||
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
|
|
||||||
suspend fun TelegramBot.getFileAdditionalInfo(
|
suspend fun TelegramBot.getFileAdditionalInfo(
|
||||||
fileId: FileId
|
fileId: FileId
|
||||||
@ -14,3 +15,7 @@ suspend fun TelegramBot.getFileAdditionalInfo(
|
|||||||
suspend fun TelegramBot.getFileAdditionalInfo(
|
suspend fun TelegramBot.getFileAdditionalInfo(
|
||||||
file: TelegramMediaFile
|
file: TelegramMediaFile
|
||||||
) = getFileAdditionalInfo(file.fileId)
|
) = getFileAdditionalInfo(file.fileId)
|
||||||
|
|
||||||
|
suspend fun TelegramBot.getFileAdditionalInfo(
|
||||||
|
content: MediaContent
|
||||||
|
) = getFileAdditionalInfo(content.media)
|
||||||
|
@ -0,0 +1,64 @@
|
|||||||
|
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.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
|
||||||
|
import java.io.File
|
||||||
|
import kotlin.coroutines.coroutineContext
|
||||||
|
|
||||||
|
suspend fun TelegramBot.downloadFile(
|
||||||
|
filePath: String,
|
||||||
|
destFile: File
|
||||||
|
): File {
|
||||||
|
val readChannel = downloadFileStream(filePath)
|
||||||
|
|
||||||
|
destFile.deleteRecursively()
|
||||||
|
destFile.parentFile.mkdirs()
|
||||||
|
doOutsideOfCoroutine { destFile.createNewFile() }
|
||||||
|
|
||||||
|
destFile.writeChannel(coroutineContext.job).use {
|
||||||
|
readChannel.copyTo(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
@ -0,0 +1,38 @@
|
|||||||
|
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
|
||||||
|
): StorageFile {
|
||||||
|
return downloadStreamAllocator.asStorageFile(
|
||||||
|
pathedFile.fileName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
@ -9,6 +9,7 @@ fun PathedFile.asStream(
|
|||||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
|
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
|
||||||
): InputStream = URL(this.fullUrl(telegramAPIUrlsKeeper)).openStream()
|
): InputStream = URL(this.fullUrl(telegramAPIUrlsKeeper)).openStream()
|
||||||
|
|
||||||
|
@Deprecated("This api will be removed soon. Use `downloadFile` instead")
|
||||||
fun PathedFile.asFile(
|
fun PathedFile.asFile(
|
||||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
|
||||||
dest: File = File.createTempFile(this.fileUniqueId, this.filename),
|
dest: File = File.createTempFile(this.fileUniqueId, this.filename),
|
||||||
@ -22,6 +23,7 @@ fun PathedFile.asFile(
|
|||||||
return dest
|
return dest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated("This api will be removed soon. Use `downloadFile` instead")
|
||||||
fun PathedFile.asBytes(
|
fun PathedFile.asBytes(
|
||||||
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
|
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper
|
||||||
): ByteArray = this.asStream(telegramAPIUrlsKeeper)
|
): ByteArray = this.asStream(telegramAPIUrlsKeeper)
|
||||||
|
Loading…
Reference in New Issue
Block a user