add micro_utils and deprecate old coroutine methods

This commit is contained in:
InsanusMokrassar 2020-11-07 13:42:10 +06:00
parent 311512b5db
commit 1cf7ae7438
44 changed files with 101 additions and 46 deletions

View File

@ -7,6 +7,7 @@
* `Common`:
* `Version`:
* `Coroutine`: `1.4.0` -> `1.4.1`
* **NEW** `MicroUtils`: `0.2.7`
* `Core`:
* Support of `logOut` method (`LogOut` object as a `Request`)
* Support of `close` method (`Close` object as a `Request`)
@ -77,6 +78,7 @@
* `MultilevelTextSource#textParts` has been deprecated. Now each `MultilevelTextSource` have its own
`textSources` list
* New dsl for creating of `TextSource` lists
* Built-in `handleSafely` and `ExceptionHandler` is deprecated
* `API`:
* Extensions `TelegramBot#pinChatMessage` now support any `Chat` and `Message`s from any `Chat`
* New extensions `TelegramBot#unpinAllChatMessages`

View File

@ -12,6 +12,8 @@ klock_version=1.12.1
uuid_version=0.2.2
ktor_version=1.4.1
micro_utils_version=0.2.7
javax_activation_version=1.1.1
library_group=dev.inmo

View File

@ -47,6 +47,8 @@ kotlin {
api "com.soywiz.korlibs.klock:klock:$klock_version"
api "com.benasher44:uuid:$uuid_version"
api "dev.inmo:micro_utils.coroutines:$micro_utils_version"
api "io.ktor:ktor-client-core:$ktor_version"
}
}

View File

@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.utils.fullListOfSubSource
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
interface Captioned {
val caption: String?

View File

@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.utils.fullListOfSubSource
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
interface Explained {
val explanation: String?

View File

@ -1,7 +1,7 @@
package dev.inmo.tgbotapi.CommonAbstracts
import dev.inmo.tgbotapi.types.ParseMode.ParseMode
import dev.inmo.tgbotapi.utils.fullListOfSubSource
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
interface Texted {
val text: String?

View File

@ -1,5 +1,6 @@
package dev.inmo.tgbotapi.bot.Ktor
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.BaseRequestsExecutor
import dev.inmo.tgbotapi.bot.Ktor.base.*
import dev.inmo.tgbotapi.bot.exceptions.newRequestException
@ -36,7 +37,7 @@ class KtorRequestsExecutor(
}
override suspend fun <T : Any> execute(request: Request<T>): T {
return handleSafely(
return safely(
{ e ->
throw if (e is ClientRequestException) {
val content = e.response ?.readText() ?: throw e

View File

@ -1,10 +1,10 @@
package dev.inmo.tgbotapi.bot.Ktor.base
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.Ktor.KtorCallFactory
import dev.inmo.tgbotapi.requests.DownloadFile
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper
import dev.inmo.tgbotapi.utils.handleSafely
import io.ktor.client.HttpClient
import io.ktor.client.request.get
import kotlinx.serialization.json.Json
@ -18,7 +18,7 @@ object DownloadFileRequestCallFactory : KtorCallFactory {
): T? = (request as? DownloadFile) ?.let {
val fullUrl = "${urlsKeeper.fileBaseUrl}/${it.filePath}"
return handleSafely {
return safely {
@Suppress("UNCHECKED_CAST")
client.get<ByteArray>(fullUrl) as T // always ByteArray
}

View File

@ -3,8 +3,8 @@ package dev.inmo.tgbotapi.types.MessageEntity
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.utils.fullListOfSubSource
import dev.inmo.tgbotapi.utils.shiftSourcesToTheLeft
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
import dev.inmo.tgbotapi.utils.internal.shiftSourcesToTheLeft
import kotlinx.serialization.Serializable
@Serializable

View File

@ -1,8 +1,10 @@
package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.MessageEntity.toTextParts
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.boldMarkdown
import dev.inmo.tgbotapi.utils.internal.boldMarkdownV2
/**
* @see bold

View File

@ -1,8 +1,10 @@
package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.MessageEntity.removeLeading
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.commandMarkdown
import dev.inmo.tgbotapi.utils.internal.commandMarkdownV2
private val commandRegex = Regex("[/!][^@\\s]*")

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.cashTagMarkdown
import dev.inmo.tgbotapi.utils.internal.cashTagMarkdownV2
/**
* @see cashTag

View File

@ -3,6 +3,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.DirectInvocationOfTextSourceConstructor
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.codeMarkdown
import dev.inmo.tgbotapi.utils.internal.codeMarkdownV2
/**
* @see code

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.emailMarkdown
import dev.inmo.tgbotapi.utils.internal.emailMarkdownV2
/**
* @see email

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.hashTagMarkdown
import dev.inmo.tgbotapi.utils.internal.hashTagMarkdownV2
/**
* @see hashtag

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.italicMarkdown
import dev.inmo.tgbotapi.utils.internal.italicMarkdownV2
/**
* @see italic

View File

@ -1,8 +1,10 @@
package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.MessageEntity.removeLeading
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.mentionMarkdown
import dev.inmo.tgbotapi.utils.internal.mentionMarkdownV2
private val String.withoutCommercialAt
get() = if (startsWith("@")) {

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.phoneMarkdown
import dev.inmo.tgbotapi.utils.internal.phoneMarkdownV2
/**
* @see phone

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.preMarkdown
import dev.inmo.tgbotapi.utils.internal.preMarkdownV2
/**
* @see pre

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.regularMarkdown
import dev.inmo.tgbotapi.utils.internal.regularMarkdownV2
/**
* @see regular

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.strikethroughMarkdown
import dev.inmo.tgbotapi.utils.internal.strikethroughMarkdownV2
/**
* @see strikethrough

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.linkMarkdown
import dev.inmo.tgbotapi.utils.internal.linkMarkdownV2
/**
* @see link

View File

@ -3,6 +3,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.User
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.textMentionMarkdown
import dev.inmo.tgbotapi.utils.internal.textMentionMarkdownV2
/**
* @see mention

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.linkMarkdown
import dev.inmo.tgbotapi.utils.internal.linkMarkdownV2
/**
* @see link

View File

@ -2,6 +2,9 @@ package dev.inmo.tgbotapi.types.MessageEntity.textsources
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.underlineMarkdown
import dev.inmo.tgbotapi.utils.internal.underlineMarkdownV2
/**
* @see underline

View File

@ -22,7 +22,6 @@ import dev.inmo.tgbotapi.types.payments.Invoice
import dev.inmo.tgbotapi.types.payments.SuccessfulPayment
import dev.inmo.tgbotapi.types.polls.Poll
import dev.inmo.tgbotapi.types.venue.Venue
import dev.inmo.tgbotapi.utils.fullListOfSubSource
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlin.reflect.KClass

View File

@ -10,7 +10,9 @@ import dev.inmo.tgbotapi.types.ParseMode.*
import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MessageContent
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import dev.inmo.tgbotapi.utils.internal.fullListOfSubSource
import dev.inmo.tgbotapi.utils.internal.toMarkdownTexts
data class TextContent(
val text: String,

View File

@ -14,8 +14,8 @@ import dev.inmo.tgbotapi.types.files.AnimationFile
import dev.inmo.tgbotapi.types.files.DocumentFile
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
import dev.inmo.tgbotapi.utils.toHtmlCaptions
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
import dev.inmo.tgbotapi.utils.internal.toMarkdownV2Captions
data class AnimationContent(
override val media: AnimationFile,

View File

@ -12,7 +12,7 @@ import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.files.AudioFile
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.AudioMediaGroupContent
import dev.inmo.tgbotapi.utils.toHtmlCaptions
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
data class AudioContent(
override val media: AudioFile,

View File

@ -15,7 +15,7 @@ import dev.inmo.tgbotapi.types.files.asDocumentFile
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.MediaContent
import dev.inmo.tgbotapi.utils.toHtmlCaptions
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
data class DocumentContent(
override val media: DocumentFile,

View File

@ -13,7 +13,7 @@ import dev.inmo.tgbotapi.types.files.*
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.VisualMediaGroupContent
import dev.inmo.tgbotapi.utils.toHtmlCaptions
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
data class PhotoContent(
override val mediaCollection: Photo,

View File

@ -12,7 +12,7 @@ import dev.inmo.tgbotapi.types.files.VideoFile
import dev.inmo.tgbotapi.types.files.toInputMediaVideo
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.VisualMediaGroupContent
import dev.inmo.tgbotapi.utils.toHtmlCaptions
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
data class VideoContent(
override val media: VideoFile,

View File

@ -13,8 +13,8 @@ import dev.inmo.tgbotapi.types.buttons.KeyboardMarkup
import dev.inmo.tgbotapi.types.files.VoiceFile
import dev.inmo.tgbotapi.types.message.abstracts.ContentMessage
import dev.inmo.tgbotapi.types.message.content.abstracts.MediaContent
import dev.inmo.tgbotapi.utils.toHtmlCaptions
import dev.inmo.tgbotapi.utils.toMarkdownV2Captions
import dev.inmo.tgbotapi.utils.internal.toHtmlCaptions
import dev.inmo.tgbotapi.utils.internal.toMarkdownV2Captions
data class VoiceContent(
override val media: VoiceFile,

View File

@ -1,23 +1,21 @@
package dev.inmo.tgbotapi.utils
import dev.inmo.micro_utils.coroutines.ExceptionHandler
import dev.inmo.micro_utils.coroutines.safely
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.supervisorScope
typealias ExceptionHandler<T> = suspend (Throwable) -> T
@Deprecated("In future will be used typealias from micro_utils", ReplaceWith("ExceptionHandler", "dev.inmo.micro_utils.coroutines.ExceptionHandler"))
typealias ExceptionHandler<T> = ExceptionHandler<T>
/**
* It will run [block] inside of [supervisorScope] to avoid problems with catching of exceptions
*
* @param [onException] Will be called when happen exception inside of [block]. By default will throw exception - this
* exception will be available for catching
*/
@Deprecated("In future will be used typealias from micro_utils", ReplaceWith("safely", "dev.inmo.micro_utils.coroutines.safely"))
suspend inline fun <T> handleSafely(
noinline onException: ExceptionHandler<T> = { throw it },
noinline block: suspend CoroutineScope.() -> T
): T {
return try {
supervisorScope(block)
} catch (e: Throwable) {
onException(e)
}
}
): T = safely(onException, block)

View File

@ -1,4 +1,4 @@
package dev.inmo.tgbotapi.utils
package dev.inmo.tgbotapi.utils.internal
import dev.inmo.tgbotapi.types.MediaGroupIdentifier
import dev.inmo.tgbotapi.types.message.abstracts.MediaGroupMessage

View File

@ -1,4 +1,4 @@
package dev.inmo.tgbotapi.utils
package dev.inmo.tgbotapi.utils.internal
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.*

View File

@ -1,4 +1,4 @@
package dev.inmo.tgbotapi.utils
package dev.inmo.tgbotapi.utils.internal
import dev.inmo.tgbotapi.CommonAbstracts.*
import dev.inmo.tgbotapi.types.MessageEntity.textsources.RegularTextSource

View File

@ -1,4 +1,4 @@
package dev.inmo.tgbotapi.utils
package dev.inmo.tgbotapi.utils.internal
import dev.inmo.tgbotapi.types.ParseMode.*
import dev.inmo.tgbotapi.types.UserId

View File

@ -3,7 +3,7 @@ package dev.inmo.tgbotapi.types.MessageEntity
import dev.inmo.tgbotapi.CommonAbstracts.TextSource
import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
import dev.inmo.tgbotapi.CommonAbstracts.plus
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.*
import kotlin.test.Test
import kotlin.test.assertEquals

View File

@ -1,8 +1,8 @@
package dev.inmo.tgbotapi.types.MessageEntity
import dev.inmo.tgbotapi.CommonAbstracts.justTextSources
import dev.inmo.tgbotapi.types.MessageEntity.textsources.*
import dev.inmo.tgbotapi.utils.*
import dev.inmo.tgbotapi.utils.internal.toHtmlTexts
import dev.inmo.tgbotapi.utils.internal.toMarkdownV2Texts
import kotlin.test.*
class TextPartsCreatingTests {

View File

@ -1,16 +1,18 @@
package dev.inmo.tgbotapi.extensions.utils
import dev.inmo.micro_utils.coroutines.ExceptionHandler
import dev.inmo.tgbotapi.utils.*
import kotlinx.coroutines.CoroutineScope
/**
* Shortcut for [handleSafely]. It was created for more comfortable way of handling different things
* Shortcut for [dev.inmo.micro_utils.coroutines.safely]. It was created for more comfortable way of handling different things
*/
@PreviewFeature
@Deprecated("In future will be used typealias from micro_utils", ReplaceWith("safely", "dev.inmo.micro_utils.coroutines.safely"))
suspend inline fun <T> safely(
noinline onException: ExceptionHandler<T> = { throw it },
noinline block: suspend CoroutineScope.() -> T
): T = handleSafely(
): T = dev.inmo.micro_utils.coroutines.safely(
onException,
block
)

View File

@ -1,15 +1,15 @@
package dev.inmo.tgbotapi.extensions.utils.shortcuts
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.requests.abstracts.Request
import dev.inmo.tgbotapi.utils.handleSafely
import kotlinx.coroutines.*
fun <T: Any> RequestsExecutor.executeAsync(
request: Request<T>,
scope: CoroutineScope
): Deferred<T> = scope.async {
handleSafely {
safely {
execute(request)
}
}
@ -29,7 +29,7 @@ suspend fun <T: Any> RequestsExecutor.executeUnsafe(
var leftRetries = retries
val exceptions = onAllFailed ?.let { mutableListOf<Throwable>() }
do {
return handleSafely(
return safely (
{
leftRetries--
delay(retriesDelay)

View File

@ -1,5 +1,7 @@
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
import dev.inmo.micro_utils.coroutines.ExceptionHandler
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.bot.exceptions.RequestException
import dev.inmo.tgbotapi.extensions.utils.updates.convertWithMediaGroupUpdates
@ -23,7 +25,7 @@ fun RequestsExecutor.startGettingOfUpdatesByLongPolling(
var lastUpdateIdentifier: UpdateIdentifier? = null
while (isActive) {
handleSafely(
safely(
{ e ->
exceptionsHandler ?.invoke(e)
if (e is RequestException) {
@ -52,7 +54,7 @@ fun RequestsExecutor.startGettingOfUpdatesByLongPolling(
}
}
handleSafely {
safely {
for (update in updates) {
updatesReceiver(update)

View File

@ -1,5 +1,7 @@
package dev.inmo.tgbotapi.extensions.utils.updates.retrieving
import dev.inmo.micro_utils.coroutines.ExceptionHandler
import dev.inmo.micro_utils.coroutines.safely
import dev.inmo.tgbotapi.bot.RequestsExecutor
import dev.inmo.tgbotapi.extensions.utils.nonstrictJsonFormat
import dev.inmo.tgbotapi.extensions.utils.updates.flowsUpdatesFilter
@ -11,8 +13,6 @@ import dev.inmo.tgbotapi.types.update.abstracts.Update
import dev.inmo.tgbotapi.types.update.abstracts.UpdateDeserializationStrategy
import dev.inmo.tgbotapi.updateshandlers.*
import dev.inmo.tgbotapi.updateshandlers.webhook.WebhookPrivateKeyConfig
import dev.inmo.tgbotapi.utils.ExceptionHandler
import dev.inmo.tgbotapi.utils.handleSafely
import io.ktor.application.call
import io.ktor.request.receiveText
import io.ktor.response.respond
@ -41,7 +41,7 @@ fun Route.includeWebhookHandlingInRoute(
) {
val transformer = scope.updateHandlerWithMediaGroupsAdaptation(block)
post {
handleSafely(
safely(
exceptionsHandler ?: {}
) {
val asJson =