mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-23 02:28:45 +00:00
commit
2e27b8b64d
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,5 +1,16 @@
|
|||||||
# TelegramBotAPI changelog
|
# TelegramBotAPI changelog
|
||||||
|
|
||||||
|
## 0.32.5
|
||||||
|
|
||||||
|
* `Core`:
|
||||||
|
* Add `mention` variants for user ids and receiver variants ([#294](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/294))
|
||||||
|
* Now `AbstractRequestCallFactory` will set up one-second delay for zero timeouts in `GetUpdate` requests
|
||||||
|
* Several extensions for `TelegramBotAPI` like `retrieveAccumulatedUpdates` have been added as a solution for
|
||||||
|
[#293](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/293)
|
||||||
|
* Links for `tg://user?id=<user_id>` have been updated ([#292](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/292))
|
||||||
|
* All usages of captions or texts in resends and same things have been replaced with `textSources`
|
||||||
|
* Global `defaultParseMode` has been added ([#291](https://github.com/InsanusMokrassar/TelegramBotAPI/issues/291))
|
||||||
|
|
||||||
## 0.32.4
|
## 0.32.4
|
||||||
|
|
||||||
* `Common`:
|
* `Common`:
|
||||||
|
@ -17,6 +17,6 @@ micro_utils_version=0.4.24
|
|||||||
javax_activation_version=1.1.1
|
javax_activation_version=1.1.1
|
||||||
|
|
||||||
library_group=dev.inmo
|
library_group=dev.inmo
|
||||||
library_version=0.32.4
|
library_version=0.32.5
|
||||||
|
|
||||||
github_release_plugin_version=2.2.12
|
github_release_plugin_version=2.2.12
|
||||||
|
@ -60,6 +60,7 @@ kotlin {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation kotlin('test-common')
|
implementation kotlin('test-common')
|
||||||
implementation kotlin('test-annotations-common')
|
implementation kotlin('test-annotations-common')
|
||||||
|
implementation project(":tgbotapi.extensions.utils")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,8 @@ import io.ktor.http.ContentType
|
|||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
|
var defaultUpdateTimeoutForZeroDelay = 1000L
|
||||||
|
|
||||||
abstract class AbstractRequestCallFactory : KtorCallFactory {
|
abstract class AbstractRequestCallFactory : KtorCallFactory {
|
||||||
private val methodsCache: MutableMap<String, String> = mutableMapOf()
|
private val methodsCache: MutableMap<String, String> = mutableMapOf()
|
||||||
override suspend fun <T : Any> makeCall(
|
override suspend fun <T : Any> makeCall(
|
||||||
@ -41,6 +43,11 @@ abstract class AbstractRequestCallFactory : KtorCallFactory {
|
|||||||
requestTimeoutMillis = customTimeoutMillis
|
requestTimeoutMillis = customTimeoutMillis
|
||||||
socketTimeoutMillis = customTimeoutMillis
|
socketTimeoutMillis = customTimeoutMillis
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
timeout {
|
||||||
|
requestTimeoutMillis = defaultUpdateTimeoutForZeroDelay
|
||||||
|
socketTimeoutMillis = defaultUpdateTimeoutForZeroDelay
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.types
|
package dev.inmo.tgbotapi.types
|
||||||
|
|
||||||
|
import dev.inmo.micro_utils.common.Warning
|
||||||
|
import dev.inmo.tgbotapi.types.chat.abstracts.Chat
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.encoding.Decoder
|
import kotlinx.serialization.encoding.Decoder
|
||||||
import kotlinx.serialization.encoding.Encoder
|
import kotlinx.serialization.encoding.Encoder
|
||||||
@ -17,9 +19,20 @@ data class ChatId(
|
|||||||
val chatId: Identifier
|
val chatId: Identifier
|
||||||
) : ChatIdentifier()
|
) : ChatIdentifier()
|
||||||
|
|
||||||
|
/**
|
||||||
val ChatId.link: String
|
* https://core.telegram.org/bots/api#formatting-options
|
||||||
get() = "tg://user?id=$chatId"
|
*/
|
||||||
|
@Warning("This API have restrictions in Telegram System")
|
||||||
|
val Identifier.link: String
|
||||||
|
get() = "tg://user?id=$this"
|
||||||
|
/**
|
||||||
|
* https://core.telegram.org/bots/api#formatting-options
|
||||||
|
*/
|
||||||
|
@Warning("This API have restrictions in Telegram System")
|
||||||
|
val UserId.link: String
|
||||||
|
get() = chatId.link
|
||||||
|
val User.link: String
|
||||||
|
get() = id.link
|
||||||
|
|
||||||
typealias UserId = ChatId
|
typealias UserId = ChatId
|
||||||
|
|
||||||
|
@ -74,3 +74,15 @@ fun AudioFile.toInputMediaAudio(
|
|||||||
title,
|
title,
|
||||||
thumb ?.fileId
|
thumb ?.fileId
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun AudioFile.toInputMediaAudio(
|
||||||
|
textSources: TextSourcesList = emptyList(),
|
||||||
|
title: String? = this.title
|
||||||
|
): InputMediaAudio = InputMediaAudio(
|
||||||
|
fileId,
|
||||||
|
textSources,
|
||||||
|
duration,
|
||||||
|
performer,
|
||||||
|
title,
|
||||||
|
thumb ?.fileId
|
||||||
|
)
|
||||||
|
@ -70,3 +70,11 @@ fun DocumentFile.toInputMediaDocument(
|
|||||||
parseMode,
|
parseMode,
|
||||||
thumb ?.fileId
|
thumb ?.fileId
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun DocumentFile.toInputMediaDocument(
|
||||||
|
textSources: TextSourcesList = emptyList()
|
||||||
|
) = InputMediaDocument(
|
||||||
|
fileId,
|
||||||
|
textSources,
|
||||||
|
thumb ?.fileId
|
||||||
|
)
|
||||||
|
@ -53,3 +53,10 @@ fun PhotoSize.toInputMediaPhoto(
|
|||||||
caption,
|
caption,
|
||||||
parseMode
|
parseMode
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun PhotoSize.toInputMediaPhoto(
|
||||||
|
textSources: TextSourcesList = emptyList()
|
||||||
|
): InputMediaPhoto = InputMediaPhoto(
|
||||||
|
fileId,
|
||||||
|
textSources
|
||||||
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
package dev.inmo.tgbotapi.types.MessageEntity.textsources
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||||
import dev.inmo.tgbotapi.types.User
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||||
import dev.inmo.tgbotapi.utils.internal.*
|
import dev.inmo.tgbotapi.utils.internal.*
|
||||||
|
|
||||||
@ -21,6 +21,26 @@ data class TextMentionTextSource @RiskFeature(DirectInvocationOfTextSourceConstr
|
|||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun mention(parts: List<TextSource>, user: User) = TextMentionTextSource(parts.makeString(), user, parts)
|
inline fun mention(parts: List<TextSource>, user: User) = TextMentionTextSource(parts.makeString(), user, parts)
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun User.mention(parts: List<TextSource>) = mention(parts, this)
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun mention(parts: List<TextSource>, userId: UserId) = mention(parts, CommonUser(userId, ""))
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun UserId.mention(parts: List<TextSource>) = mention(parts, this)
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun mention(parts: List<TextSource>, id: Identifier) = mention(parts, UserId(id))
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun Identifier.mention(parts: List<TextSource>) = mention(parts, this)
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun mention(user: User, vararg parts: TextSource) = mention(parts.toList(), user)
|
inline fun mention(user: User, vararg parts: TextSource) = mention(parts.toList(), user)
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
inline fun mention(text: String, user: User) = mention(user, regular(text))
|
inline fun mention(text: String, user: User) = mention(user, regular(text))
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun User.mention(text: String) = mention(this, regular(text))
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun mention(text: String, userId: UserId) = mention(text, CommonUser(userId, ""))
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun UserId.mention(text: String) = mention(text, this)
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun mention(text: String, id: Identifier) = mention(text, UserId(id))
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun Identifier.mention(text: String) = mention(text, this)
|
||||||
|
@ -35,12 +35,21 @@ typealias Markdown = MarkdownParseMode
|
|||||||
typealias MarkdownV2 = MarkdownV2ParseMode
|
typealias MarkdownV2 = MarkdownV2ParseMode
|
||||||
typealias HTML = HTMLParseMode
|
typealias HTML = HTMLParseMode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This variable respects to default parse mode used in places like next:
|
||||||
|
*
|
||||||
|
* * [dev.inmo.tgbotapi.types.message.content.TextContent.createResends]
|
||||||
|
* *
|
||||||
|
*/
|
||||||
|
var defaultParseMode: ParseMode = HTML
|
||||||
|
|
||||||
@Serializer(ParseMode::class)
|
@Serializer(ParseMode::class)
|
||||||
internal object ParseModeSerializerObject : KSerializer<ParseMode> {
|
internal object ParseModeSerializerObject : KSerializer<ParseMode> {
|
||||||
override fun deserialize(decoder: Decoder): ParseMode {
|
override fun deserialize(decoder: Decoder): ParseMode {
|
||||||
return when (decoder.decodeString()) {
|
return when (decoder.decodeString()) {
|
||||||
MarkdownParseMode.parseModeName -> MarkdownParseMode
|
Markdown.parseModeName -> Markdown
|
||||||
HTMLParseMode.parseModeName -> HTMLParseMode
|
MarkdownV2.parseModeName -> MarkdownV2
|
||||||
|
HTML.parseModeName -> HTML
|
||||||
else -> throw IllegalArgumentException("Unknown parse mode")
|
else -> throw IllegalArgumentException("Unknown parse mode")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.types.files
|
package dev.inmo.tgbotapi.types.files
|
||||||
|
|
||||||
|
import dev.inmo.tgbotapi.CommonAbstracts.TextSourcesList
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
import dev.inmo.tgbotapi.requests.abstracts.FileId
|
||||||
import dev.inmo.tgbotapi.types.*
|
import dev.inmo.tgbotapi.types.*
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaVideo
|
import dev.inmo.tgbotapi.types.InputMedia.InputMediaVideo
|
||||||
@ -44,3 +45,15 @@ inline fun VideoFile.toInputMediaVideo(
|
|||||||
duration,
|
duration,
|
||||||
thumb ?.fileId
|
thumb ?.fileId
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun VideoFile.toInputMediaVideo(
|
||||||
|
textSources: TextSourcesList
|
||||||
|
) = InputMediaVideo(
|
||||||
|
fileId,
|
||||||
|
textSources,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
duration,
|
||||||
|
thumb ?.fileId
|
||||||
|
)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content
|
package dev.inmo.tgbotapi.types.message.content
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextedInput
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.requests.send.SendTextMessage
|
import dev.inmo.tgbotapi.requests.send.SendTextMessage
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
@ -10,7 +9,6 @@ import dev.inmo.tgbotapi.types.ParseMode.*
|
|||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
|
||||||
import dev.inmo.tgbotapi.utils.internal.*
|
|
||||||
|
|
||||||
data class TextContent(
|
data class TextContent(
|
||||||
override val text: String,
|
override val text: String,
|
||||||
@ -24,8 +22,7 @@ data class TextContent(
|
|||||||
replyMarkup: KeyboardMarkup?
|
replyMarkup: KeyboardMarkup?
|
||||||
): Request<ContentMessage<TextContent>> = SendTextMessage(
|
): Request<ContentMessage<TextContent>> = SendTextMessage(
|
||||||
chatId,
|
chatId,
|
||||||
toHtmlTexts().first(),
|
textSources,
|
||||||
HTMLParseMode,
|
|
||||||
false,
|
false,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
@ -33,42 +30,36 @@ data class TextContent(
|
|||||||
replyMarkup
|
replyMarkup
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"Useless due to fact that createResend currently use textSource and that will guarantee correct sending of message",
|
||||||
|
ReplaceWith("createResend")
|
||||||
|
)
|
||||||
override fun createResends(
|
override fun createResends(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
disableNotification: Boolean,
|
disableNotification: Boolean,
|
||||||
replyToMessageId: MessageIdentifier?,
|
replyToMessageId: MessageIdentifier?,
|
||||||
allowSendingWithoutReply: Boolean?,
|
allowSendingWithoutReply: Boolean?,
|
||||||
replyMarkup: KeyboardMarkup?
|
replyMarkup: KeyboardMarkup?
|
||||||
): List<Request<ContentMessage<TextContent>>> = createResends(
|
): List<Request<ContentMessage<TextContent>>> = listOf(
|
||||||
chatId,
|
createResend(
|
||||||
disableNotification,
|
chatId,
|
||||||
replyToMessageId,
|
disableNotification,
|
||||||
allowSendingWithoutReply,
|
replyToMessageId,
|
||||||
replyMarkup,
|
allowSendingWithoutReply,
|
||||||
HTMLParseMode
|
replyMarkup
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Deprecated(
|
||||||
|
"Useless due to fact that createResend currently use textSource and that will guarantee correct sending of message",
|
||||||
|
ReplaceWith("createResend")
|
||||||
|
)
|
||||||
fun createResends(
|
fun createResends(
|
||||||
chatId: ChatIdentifier,
|
chatId: ChatIdentifier,
|
||||||
disableNotification: Boolean,
|
disableNotification: Boolean,
|
||||||
replyToMessageId: MessageIdentifier?,
|
replyToMessageId: MessageIdentifier?,
|
||||||
allowSendingWithoutReply: Boolean?,
|
allowSendingWithoutReply: Boolean?,
|
||||||
replyMarkup: KeyboardMarkup?,
|
replyMarkup: KeyboardMarkup?,
|
||||||
parseMode: ParseMode = HTMLParseMode
|
parseMode: ParseMode = defaultParseMode
|
||||||
): List<Request<ContentMessage<TextContent>>> = when (parseMode) {
|
): List<Request<ContentMessage<TextContent>>> = createResends(chatId, disableNotification, replyToMessageId, allowSendingWithoutReply, replyMarkup)
|
||||||
is MarkdownParseMode -> toMarkdownTexts()
|
|
||||||
is MarkdownV2ParseMode -> toMarkdownV2Texts()
|
|
||||||
is HTMLParseMode -> toHtmlTexts()
|
|
||||||
}.map {
|
|
||||||
SendTextMessage(
|
|
||||||
chatId,
|
|
||||||
it,
|
|
||||||
parseMode,
|
|
||||||
false,
|
|
||||||
disableNotification,
|
|
||||||
replyToMessageId,
|
|
||||||
allowSendingWithoutReply,
|
|
||||||
replyMarkup
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,16 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content.media
|
package dev.inmo.tgbotapi.types.message.content.media
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput
|
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.requests.send.media.SendAnimation
|
import dev.inmo.tgbotapi.requests.send.media.SendAnimation
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaAnimation
|
import dev.inmo.tgbotapi.types.InputMedia.InputMediaAnimation
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.AnimationFile
|
import dev.inmo.tgbotapi.types.files.AnimationFile
|
||||||
import dev.inmo.tgbotapi.types.files.DocumentFile
|
import dev.inmo.tgbotapi.types.files.DocumentFile
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
|
|
||||||
import dev.inmo.tgbotapi.utils.internal.toMarkdownV2Captions
|
|
||||||
|
|
||||||
data class AnimationContent(
|
data class AnimationContent(
|
||||||
override val media: AnimationFile,
|
override val media: AnimationFile,
|
||||||
@ -33,8 +28,7 @@ data class AnimationContent(
|
|||||||
chatId,
|
chatId,
|
||||||
media.fileId,
|
media.fileId,
|
||||||
media.thumb ?.fileId,
|
media.thumb ?.fileId,
|
||||||
toHtmlCaptions().firstOrNull(),
|
textSources,
|
||||||
HTMLParseMode,
|
|
||||||
media.duration,
|
media.duration,
|
||||||
media.width,
|
media.width,
|
||||||
media.height,
|
media.height,
|
||||||
@ -46,8 +40,7 @@ data class AnimationContent(
|
|||||||
|
|
||||||
override fun asInputMedia(): InputMediaAnimation = InputMediaAnimation(
|
override fun asInputMedia(): InputMediaAnimation = InputMediaAnimation(
|
||||||
media.fileId,
|
media.fileId,
|
||||||
toMarkdownV2Captions().firstOrNull(),
|
textSources,
|
||||||
MarkdownV2,
|
|
||||||
media.width,
|
media.width,
|
||||||
media.height,
|
media.height,
|
||||||
media.duration,
|
media.duration,
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content.media
|
package dev.inmo.tgbotapi.types.message.content.media
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
||||||
|
import dev.inmo.tgbotapi.CommonAbstracts.textSources
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.requests.send.media.SendAudio
|
import dev.inmo.tgbotapi.requests.send.media.SendAudio
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaAudio
|
import dev.inmo.tgbotapi.types.InputMedia.InputMediaAudio
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaAudio
|
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaAudio
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.AudioFile
|
import dev.inmo.tgbotapi.types.files.AudioFile
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.AudioMediaGroupContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.AudioMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
|
|
||||||
|
|
||||||
data class AudioContent(
|
data class AudioContent(
|
||||||
override val media: AudioFile,
|
override val media: AudioFile,
|
||||||
@ -29,8 +28,7 @@ data class AudioContent(
|
|||||||
chatId,
|
chatId,
|
||||||
media.fileId,
|
media.fileId,
|
||||||
media.thumb ?.fileId,
|
media.thumb ?.fileId,
|
||||||
toHtmlCaptions().firstOrNull(),
|
textSources,
|
||||||
HTMLParseMode,
|
|
||||||
media.duration,
|
media.duration,
|
||||||
media.performer,
|
media.performer,
|
||||||
media.title,
|
media.title,
|
||||||
@ -42,8 +40,5 @@ data class AudioContent(
|
|||||||
|
|
||||||
override fun toMediaGroupMemberInputMedia(): InputMediaAudio = asInputMedia()
|
override fun toMediaGroupMemberInputMedia(): InputMediaAudio = asInputMedia()
|
||||||
|
|
||||||
override fun asInputMedia(): InputMediaAudio = media.toInputMediaAudio(
|
override fun asInputMedia(): InputMediaAudio = media.toInputMediaAudio(textSources)
|
||||||
toHtmlCaptions().firstOrNull(),
|
|
||||||
HTMLParseMode
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,18 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content.media
|
package dev.inmo.tgbotapi.types.message.content.media
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput
|
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.requests.send.media.SendDocument
|
import dev.inmo.tgbotapi.requests.send.media.SendDocument
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaDocument
|
import dev.inmo.tgbotapi.types.InputMedia.InputMediaDocument
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaDocument
|
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaDocument
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.DocumentFile
|
import dev.inmo.tgbotapi.types.files.DocumentFile
|
||||||
import dev.inmo.tgbotapi.types.files.asDocumentFile
|
import dev.inmo.tgbotapi.types.files.asDocumentFile
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.DocumentMediaGroupContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.DocumentMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
|
|
||||||
|
|
||||||
data class DocumentContent(
|
data class DocumentContent(
|
||||||
override val media: DocumentFile,
|
override val media: DocumentFile,
|
||||||
@ -32,8 +29,7 @@ data class DocumentContent(
|
|||||||
chatId,
|
chatId,
|
||||||
media.fileId,
|
media.fileId,
|
||||||
media.thumb ?.fileId,
|
media.thumb ?.fileId,
|
||||||
toHtmlCaptions().firstOrNull(),
|
textSources,
|
||||||
HTMLParseMode,
|
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
allowSendingWithoutReply,
|
||||||
@ -42,10 +38,7 @@ data class DocumentContent(
|
|||||||
|
|
||||||
override fun toMediaGroupMemberInputMedia(): InputMediaDocument = asInputMedia()
|
override fun toMediaGroupMemberInputMedia(): InputMediaDocument = asInputMedia()
|
||||||
|
|
||||||
override fun asInputMedia(): InputMediaDocument = media.toInputMediaDocument(
|
override fun asInputMedia(): InputMediaDocument = media.toInputMediaDocument(textSources)
|
||||||
toHtmlCaptions().firstOrNull(),
|
|
||||||
HTMLParseMode
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("NOTHING_TO_INLINE")
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content.media
|
package dev.inmo.tgbotapi.types.message.content.media
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
||||||
|
import dev.inmo.tgbotapi.CommonAbstracts.textSources
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.requests.send.media.SendPhoto
|
import dev.inmo.tgbotapi.requests.send.media.SendPhoto
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaPhoto
|
import dev.inmo.tgbotapi.types.InputMedia.InputMediaPhoto
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaPhoto
|
import dev.inmo.tgbotapi.types.InputMedia.toInputMediaPhoto
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.*
|
import dev.inmo.tgbotapi.types.files.*
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaCollectionContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaCollectionContent
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
|
|
||||||
|
|
||||||
data class PhotoContent(
|
data class PhotoContent(
|
||||||
override val mediaCollection: Photo,
|
override val mediaCollection: Photo,
|
||||||
@ -31,8 +30,7 @@ data class PhotoContent(
|
|||||||
): Request<ContentMessage<PhotoContent>> = SendPhoto(
|
): Request<ContentMessage<PhotoContent>> = SendPhoto(
|
||||||
chatId,
|
chatId,
|
||||||
media.fileId,
|
media.fileId,
|
||||||
toHtmlCaptions().firstOrNull(),
|
textSources,
|
||||||
HTMLParseMode,
|
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
allowSendingWithoutReply,
|
allowSendingWithoutReply,
|
||||||
@ -41,8 +39,5 @@ data class PhotoContent(
|
|||||||
|
|
||||||
override fun toMediaGroupMemberInputMedia(): InputMediaPhoto = asInputMedia()
|
override fun toMediaGroupMemberInputMedia(): InputMediaPhoto = asInputMedia()
|
||||||
|
|
||||||
override fun asInputMedia(): InputMediaPhoto = media.toInputMediaPhoto(
|
override fun asInputMedia(): InputMediaPhoto = media.toInputMediaPhoto(textSources)
|
||||||
toHtmlCaptions().firstOrNull(),
|
|
||||||
HTMLParseMode
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content.media
|
package dev.inmo.tgbotapi.types.message.content.media
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
||||||
|
import dev.inmo.tgbotapi.CommonAbstracts.textSources
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.requests.send.media.SendVideo
|
import dev.inmo.tgbotapi.requests.send.media.SendVideo
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaVideo
|
import dev.inmo.tgbotapi.types.InputMedia.InputMediaVideo
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.VideoFile
|
import dev.inmo.tgbotapi.types.files.VideoFile
|
||||||
import dev.inmo.tgbotapi.types.files.toInputMediaVideo
|
import dev.inmo.tgbotapi.types.files.toInputMediaVideo
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
|
||||||
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
|
|
||||||
|
|
||||||
data class VideoContent(
|
data class VideoContent(
|
||||||
override val media: VideoFile,
|
override val media: VideoFile,
|
||||||
@ -29,8 +28,7 @@ data class VideoContent(
|
|||||||
chatId,
|
chatId,
|
||||||
media.fileId,
|
media.fileId,
|
||||||
media.thumb ?.fileId,
|
media.thumb ?.fileId,
|
||||||
toHtmlCaptions().firstOrNull(),
|
textSources,
|
||||||
HTMLParseMode,
|
|
||||||
media.duration,
|
media.duration,
|
||||||
media.width,
|
media.width,
|
||||||
media.height,
|
media.height,
|
||||||
@ -43,8 +41,5 @@ data class VideoContent(
|
|||||||
|
|
||||||
override fun toMediaGroupMemberInputMedia(): InputMediaVideo = asInputMedia()
|
override fun toMediaGroupMemberInputMedia(): InputMediaVideo = asInputMedia()
|
||||||
|
|
||||||
override fun asInputMedia(): InputMediaVideo = media.toInputMediaVideo(
|
override fun asInputMedia(): InputMediaVideo = media.toInputMediaVideo(textSources)
|
||||||
toHtmlCaptions().firstOrNull(),
|
|
||||||
HTMLParseMode
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,15 @@
|
|||||||
package dev.inmo.tgbotapi.types.message.content.media
|
package dev.inmo.tgbotapi.types.message.content.media
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.CaptionedInput
|
import dev.inmo.tgbotapi.CommonAbstracts.*
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextPart
|
|
||||||
import dev.inmo.tgbotapi.requests.abstracts.Request
|
import dev.inmo.tgbotapi.requests.abstracts.Request
|
||||||
import dev.inmo.tgbotapi.requests.send.media.SendVoice
|
import dev.inmo.tgbotapi.requests.send.media.SendVoice
|
||||||
import dev.inmo.tgbotapi.types.ChatIdentifier
|
import dev.inmo.tgbotapi.types.ChatIdentifier
|
||||||
import dev.inmo.tgbotapi.types.InputMedia.InputMediaAudio
|
import dev.inmo.tgbotapi.types.InputMedia.InputMediaAudio
|
||||||
import dev.inmo.tgbotapi.types.MessageIdentifier
|
import dev.inmo.tgbotapi.types.MessageIdentifier
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.HTMLParseMode
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.MarkdownV2
|
|
||||||
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
|
||||||
import dev.inmo.tgbotapi.types.files.VoiceFile
|
import dev.inmo.tgbotapi.types.files.VoiceFile
|
||||||
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
|
||||||
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
|
||||||
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
|
|
||||||
import dev.inmo.tgbotapi.utils.internal.toMarkdownV2Captions
|
|
||||||
|
|
||||||
data class VoiceContent(
|
data class VoiceContent(
|
||||||
override val media: VoiceFile,
|
override val media: VoiceFile,
|
||||||
@ -30,8 +25,7 @@ data class VoiceContent(
|
|||||||
): Request<ContentMessage<VoiceContent>> = SendVoice(
|
): Request<ContentMessage<VoiceContent>> = SendVoice(
|
||||||
chatId,
|
chatId,
|
||||||
media.fileId,
|
media.fileId,
|
||||||
toHtmlCaptions().firstOrNull(),
|
textSources,
|
||||||
HTMLParseMode,
|
|
||||||
media.duration,
|
media.duration,
|
||||||
disableNotification,
|
disableNotification,
|
||||||
replyToMessageId,
|
replyToMessageId,
|
||||||
@ -41,8 +35,7 @@ data class VoiceContent(
|
|||||||
|
|
||||||
override fun asInputMedia(): InputMediaAudio = InputMediaAudio(
|
override fun asInputMedia(): InputMediaAudio = InputMediaAudio(
|
||||||
media.fileId,
|
media.fileId,
|
||||||
toMarkdownV2Captions().firstOrNull(),
|
textSources,
|
||||||
MarkdownV2,
|
|
||||||
media.duration
|
media.duration
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,97 +0,0 @@
|
|||||||
package dev.inmo.tgbotapi.utils.internal
|
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.*
|
|
||||||
import dev.inmo.tgbotapi.types.ParseMode.*
|
|
||||||
import dev.inmo.tgbotapi.types.captionLength
|
|
||||||
import dev.inmo.tgbotapi.types.message.content.TextContent
|
|
||||||
import dev.inmo.tgbotapi.types.textLength
|
|
||||||
|
|
||||||
internal fun createFormattedText(
|
|
||||||
entities: TextSourcesList,
|
|
||||||
partLength: Int = textLength.last,
|
|
||||||
mode: ParseMode = MarkdownParseMode
|
|
||||||
): List<String> {
|
|
||||||
val texts = mutableListOf<String>()
|
|
||||||
val textBuilder = StringBuilder(partLength)
|
|
||||||
for (entity in entities) {
|
|
||||||
val string = when (mode) {
|
|
||||||
is MarkdownParseMode -> entity.markdown
|
|
||||||
is MarkdownV2ParseMode -> entity.markdownV2
|
|
||||||
is HTMLParseMode -> entity.html
|
|
||||||
}
|
|
||||||
if (textBuilder.length + string.length > partLength) {
|
|
||||||
if (textBuilder.isNotEmpty()) {
|
|
||||||
texts.add(textBuilder.toString())
|
|
||||||
textBuilder.clear()
|
|
||||||
}
|
|
||||||
val chunked = string.chunked(partLength)
|
|
||||||
val last = chunked.last()
|
|
||||||
textBuilder.append(last)
|
|
||||||
val listToAdd = if (chunked.size > 1) {
|
|
||||||
chunked.subList(0, chunked.size - 1)
|
|
||||||
} else {
|
|
||||||
emptyList()
|
|
||||||
}
|
|
||||||
listToAdd.forEach {
|
|
||||||
texts.add(it)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
textBuilder.append(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (textBuilder.isNotEmpty()) {
|
|
||||||
texts.add(textBuilder.toString())
|
|
||||||
textBuilder.clear()
|
|
||||||
}
|
|
||||||
return texts
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal fun createMarkdownText(
|
|
||||||
entities: TextSourcesList,
|
|
||||||
partLength: Int = textLength.last
|
|
||||||
): List<String> = createFormattedText(entities, partLength, MarkdownParseMode)
|
|
||||||
|
|
||||||
internal fun TextSourcesList.toMarkdownTexts(): List<String> = createMarkdownText(
|
|
||||||
this,
|
|
||||||
textLength.last
|
|
||||||
)
|
|
||||||
internal fun TextContent.toMarkdownTexts(): List<String> = textSources.toMarkdownTexts()
|
|
||||||
|
|
||||||
|
|
||||||
internal fun createMarkdownV2Text(
|
|
||||||
entities: TextSourcesList,
|
|
||||||
partLength: Int = textLength.last
|
|
||||||
): List<String> = createFormattedText(entities, partLength, MarkdownV2ParseMode)
|
|
||||||
|
|
||||||
internal fun TextSourcesList.toMarkdownV2Captions(): List<String> = createMarkdownV2Text(
|
|
||||||
this,
|
|
||||||
captionLength.last
|
|
||||||
)
|
|
||||||
internal fun CaptionedInput.toMarkdownV2Captions(): List<String> = textSources.toMarkdownV2Captions()
|
|
||||||
|
|
||||||
internal fun TextSourcesList.toMarkdownV2Texts(): List<String> = createMarkdownV2Text(
|
|
||||||
this,
|
|
||||||
textLength.last
|
|
||||||
)
|
|
||||||
internal fun TextContent.toMarkdownV2Texts(): List<String> = textSources.toMarkdownV2Texts()
|
|
||||||
|
|
||||||
|
|
||||||
internal fun createHtmlText(
|
|
||||||
entities: TextSourcesList,
|
|
||||||
partLength: Int = textLength.last
|
|
||||||
): List<String> = createFormattedText(entities, partLength, HTMLParseMode)
|
|
||||||
|
|
||||||
internal fun TextSourcesList.toHtmlCaptions(): List<String> = createHtmlText(
|
|
||||||
this,
|
|
||||||
captionLength.last
|
|
||||||
)
|
|
||||||
internal fun CaptionedInput.toHtmlCaptions(): List<String> = textSources.toHtmlCaptions()
|
|
||||||
|
|
||||||
internal fun TextSourcesList.toHtmlTexts(): List<String> = createHtmlText(
|
|
||||||
this,
|
|
||||||
textLength.last
|
|
||||||
)
|
|
||||||
internal fun TextContent.toHtmlTexts(): List<String> = textSources.toHtmlTexts()
|
|
||||||
|
|
||||||
|
|
@ -2,8 +2,8 @@ package dev.inmo.tgbotapi.types.MessageEntity
|
|||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.plus
|
import dev.inmo.tgbotapi.CommonAbstracts.plus
|
||||||
|
import dev.inmo.tgbotapi.extensions.utils.formatting.*
|
||||||
import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
|
import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
|
||||||
import dev.inmo.tgbotapi.utils.internal.*
|
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package dev.inmo.tgbotapi.types.MessageEntity
|
package dev.inmo.tgbotapi.types.MessageEntity
|
||||||
|
|
||||||
import dev.inmo.tgbotapi.CommonAbstracts.justTextSources
|
import dev.inmo.tgbotapi.CommonAbstracts.justTextSources
|
||||||
import dev.inmo.tgbotapi.utils.internal.toHtmlTexts
|
import dev.inmo.tgbotapi.extensions.utils.formatting.toHtmlTexts
|
||||||
import dev.inmo.tgbotapi.utils.internal.toMarkdownV2Texts
|
import dev.inmo.tgbotapi.extensions.utils.formatting.toMarkdownV2Texts
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@ -44,5 +44,23 @@ kotlin {
|
|||||||
api project(":tgbotapi.core")
|
api project(":tgbotapi.core")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commonTest {
|
||||||
|
dependencies {
|
||||||
|
implementation kotlin('test-common')
|
||||||
|
implementation kotlin('test-annotations-common')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jvmTest {
|
||||||
|
dependencies {
|
||||||
|
implementation kotlin('test-junit')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jsTest {
|
||||||
|
dependencies {
|
||||||
|
implementation kotlin('test-junit')
|
||||||
|
implementation kotlin('test-js')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,15 +8,15 @@ import dev.inmo.tgbotapi.types.message.content.TextContent
|
|||||||
fun createFormattedText(
|
fun createFormattedText(
|
||||||
entities: TextSourcesList,
|
entities: TextSourcesList,
|
||||||
partLength: Int = textLength.last,
|
partLength: Int = textLength.last,
|
||||||
mode: ParseMode = MarkdownParseMode
|
mode: ParseMode = defaultParseMode
|
||||||
): List<String> {
|
): List<String> {
|
||||||
val texts = mutableListOf<String>()
|
val texts = mutableListOf<String>()
|
||||||
val textBuilder = StringBuilder(partLength)
|
val textBuilder = StringBuilder(partLength)
|
||||||
for (entity in entities) {
|
for (entity in entities) {
|
||||||
val string = when (mode) {
|
val string = when (mode) {
|
||||||
is MarkdownParseMode -> entity.markdown
|
is Markdown -> entity.markdown
|
||||||
is MarkdownV2ParseMode -> entity.markdownV2
|
is MarkdownV2 -> entity.markdownV2
|
||||||
is HTMLParseMode -> entity.html
|
is HTML -> entity.html
|
||||||
}
|
}
|
||||||
if (textBuilder.length + string.length > partLength) {
|
if (textBuilder.length + string.length > partLength) {
|
||||||
if (textBuilder.isNotEmpty()) {
|
if (textBuilder.isNotEmpty()) {
|
||||||
@ -49,7 +49,7 @@ fun createFormattedText(
|
|||||||
fun createMarkdownText(
|
fun createMarkdownText(
|
||||||
entities: TextSourcesList,
|
entities: TextSourcesList,
|
||||||
partLength: Int = textLength.last
|
partLength: Int = textLength.last
|
||||||
): List<String> = createFormattedText(entities, partLength, MarkdownParseMode)
|
): List<String> = createFormattedText(entities, partLength, Markdown)
|
||||||
|
|
||||||
fun TextSourcesList.toMarkdownCaptions(): List<String> = createMarkdownText(
|
fun TextSourcesList.toMarkdownCaptions(): List<String> = createMarkdownText(
|
||||||
this,
|
this,
|
||||||
@ -73,7 +73,7 @@ fun ExplainedInput.toMarkdownExplanations(): List<String> = textSources.toMarkdo
|
|||||||
fun createMarkdownV2Text(
|
fun createMarkdownV2Text(
|
||||||
entities: TextSourcesList,
|
entities: TextSourcesList,
|
||||||
partLength: Int = textLength.last
|
partLength: Int = textLength.last
|
||||||
): List<String> = createFormattedText(entities, partLength, MarkdownV2ParseMode)
|
): List<String> = createFormattedText(entities, partLength, MarkdownV2)
|
||||||
|
|
||||||
fun TextSourcesList.toMarkdownV2Captions(): List<String> = createMarkdownV2Text(
|
fun TextSourcesList.toMarkdownV2Captions(): List<String> = createMarkdownV2Text(
|
||||||
this,
|
this,
|
||||||
@ -97,7 +97,7 @@ fun ExplainedInput.toMarkdownV2Explanations(): List<String> = textSources.toMark
|
|||||||
fun createHtmlText(
|
fun createHtmlText(
|
||||||
entities: TextSourcesList,
|
entities: TextSourcesList,
|
||||||
partLength: Int = textLength.last
|
partLength: Int = textLength.last
|
||||||
): List<String> = createFormattedText(entities, partLength, HTMLParseMode)
|
): List<String> = createFormattedText(entities, partLength, HTML)
|
||||||
|
|
||||||
fun TextSourcesList.toHtmlCaptions(): List<String> = createHtmlText(
|
fun TextSourcesList.toHtmlCaptions(): List<String> = createHtmlText(
|
||||||
this,
|
this,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
|
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
|
||||||
|
|
||||||
import dev.inmo.micro_utils.coroutines.ExceptionHandler
|
import dev.inmo.micro_utils.coroutines.*
|
||||||
import dev.inmo.micro_utils.coroutines.safely
|
|
||||||
import dev.inmo.tgbotapi.bot.RequestsExecutor
|
import dev.inmo.tgbotapi.bot.RequestsExecutor
|
||||||
import dev.inmo.tgbotapi.bot.TelegramBot
|
import dev.inmo.tgbotapi.bot.TelegramBot
|
||||||
import dev.inmo.tgbotapi.bot.exceptions.RequestException
|
import dev.inmo.tgbotapi.bot.exceptions.RequestException
|
||||||
@ -14,7 +13,11 @@ import dev.inmo.tgbotapi.types.update.MediaGroupUpdates.*
|
|||||||
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
import dev.inmo.tgbotapi.types.update.abstracts.Update
|
||||||
import dev.inmo.tgbotapi.updateshandlers.*
|
import dev.inmo.tgbotapi.updateshandlers.*
|
||||||
import dev.inmo.tgbotapi.utils.*
|
import dev.inmo.tgbotapi.utils.*
|
||||||
|
import io.ktor.client.features.HttpRequestTimeoutException
|
||||||
|
import io.ktor.utils.io.core.use
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
|
import kotlinx.coroutines.flow.*
|
||||||
|
import kotlin.coroutines.coroutineContext
|
||||||
|
|
||||||
fun TelegramBot.startGettingOfUpdatesByLongPolling(
|
fun TelegramBot.startGettingOfUpdatesByLongPolling(
|
||||||
timeoutSeconds: Seconds = 30,
|
timeoutSeconds: Seconds = 30,
|
||||||
@ -66,6 +69,70 @@ fun TelegramBot.startGettingOfUpdatesByLongPolling(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun TelegramBot.retrieveAccumulatedUpdates(
|
||||||
|
avoidInlineQueries: Boolean = false,
|
||||||
|
avoidCallbackQueries: Boolean = false,
|
||||||
|
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||||
|
exceptionsHandler: (ExceptionHandler<Unit>)? = null,
|
||||||
|
allowedUpdates: List<String>? = null,
|
||||||
|
updatesReceiver: UpdateReceiver<Update>
|
||||||
|
): Job = scope.launch {
|
||||||
|
safelyWithoutExceptions {
|
||||||
|
startGettingOfUpdatesByLongPolling(
|
||||||
|
0,
|
||||||
|
CoroutineScope(coroutineContext + SupervisorJob()),
|
||||||
|
{
|
||||||
|
if (it is HttpRequestTimeoutException) {
|
||||||
|
throw CancellationException("Cancel due to absence of new updates")
|
||||||
|
} else {
|
||||||
|
exceptionsHandler ?.invoke(it)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
allowedUpdates
|
||||||
|
) {
|
||||||
|
when {
|
||||||
|
it is InlineQueryUpdate && avoidInlineQueries ||
|
||||||
|
it is CallbackQueryUpdate && avoidCallbackQueries -> return@startGettingOfUpdatesByLongPolling
|
||||||
|
else -> updatesReceiver(it)
|
||||||
|
}
|
||||||
|
}.join()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return [kotlinx.coroutines.flow.Flow] which will emit updates to the collector while they will be accumulated. Works
|
||||||
|
* the same as [retrieveAccumulatedUpdates], but pass [kotlinx.coroutines.flow.FlowCollector.emit] as a callback
|
||||||
|
*/
|
||||||
|
fun TelegramBot.createAccumulatedUpdatesRetrieverFlow(
|
||||||
|
avoidInlineQueries: Boolean = false,
|
||||||
|
avoidCallbackQueries: Boolean = false,
|
||||||
|
exceptionsHandler: ExceptionHandler<Unit>? = null,
|
||||||
|
allowedUpdates: List<String>? = null
|
||||||
|
): Flow<Update> = channelFlow {
|
||||||
|
val parentContext = kotlin.coroutines.coroutineContext
|
||||||
|
channel.apply {
|
||||||
|
retrieveAccumulatedUpdates(
|
||||||
|
avoidInlineQueries,
|
||||||
|
avoidCallbackQueries,
|
||||||
|
CoroutineScope(parentContext),
|
||||||
|
exceptionsHandler,
|
||||||
|
allowedUpdates,
|
||||||
|
::send
|
||||||
|
).join()
|
||||||
|
close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun TelegramBot.retrieveAccumulatedUpdates(
|
||||||
|
flowsUpdatesFilter: FlowsUpdatesFilter,
|
||||||
|
avoidInlineQueries: Boolean = false,
|
||||||
|
avoidCallbackQueries: Boolean = false,
|
||||||
|
scope: CoroutineScope = CoroutineScope(Dispatchers.Default),
|
||||||
|
exceptionsHandler: ExceptionHandler<Unit>? = null
|
||||||
|
) = flowsUpdatesFilter.run {
|
||||||
|
retrieveAccumulatedUpdates(avoidInlineQueries, avoidCallbackQueries, scope, exceptionsHandler, allowedUpdates, asUpdateReceiver)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will [startGettingOfUpdatesByLongPolling] using incoming [flowsUpdatesFilter]. It is assumed that you ALREADY CONFIGURE
|
* Will [startGettingOfUpdatesByLongPolling] using incoming [flowsUpdatesFilter]. It is assumed that you ALREADY CONFIGURE
|
||||||
* all updates receivers, because this method will trigger getting of updates and.
|
* all updates receivers, because this method will trigger getting of updates and.
|
||||||
|
Loading…
Reference in New Issue
Block a user