tgbotapi/src/main/kotlin/com/github/insanusmokrassar/TelegramBotAPI/bot/Ktor/KtorRequestsExecutor.kt

103 lines
4.1 KiB
Kotlin
Raw Normal View History

2018-12-26 08:07:24 +00:00
package com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor
import com.github.insanusmokrassar.TelegramBotAPI.bot.BaseRequestsExecutor
import com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.base.MultipartRequestCallFactory
import com.github.insanusmokrassar.TelegramBotAPI.bot.Ktor.base.SimpleRequestCallFactory
2019-02-10 05:41:20 +00:00
import com.github.insanusmokrassar.TelegramBotAPI.bot.exceptions.newRequestException
2019-01-24 02:36:44 +00:00
import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.EmptyLimiter
import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.RequestLimiter
2018-12-26 08:07:24 +00:00
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
import com.github.insanusmokrassar.TelegramBotAPI.types.Response
import com.github.insanusmokrassar.TelegramBotAPI.types.RetryAfterError
2019-07-25 08:25:18 +00:00
import com.github.insanusmokrassar.TelegramBotAPI.utils.TelegramAPIUrlsKeeper
2018-12-26 08:07:24 +00:00
import io.ktor.client.HttpClient
import io.ktor.client.call.HttpClientCall
import io.ktor.client.engine.HttpClientEngine
import io.ktor.util.cio.toByteArray
import kotlinx.coroutines.delay
2019-02-21 06:21:33 +00:00
import kotlinx.serialization.json.Json
2018-12-26 08:07:24 +00:00
class KtorRequestsExecutor(
2019-07-25 08:25:18 +00:00
telegramAPIUrlsKeeper: TelegramAPIUrlsKeeper,
private val client: HttpClient = HttpClient(),
2018-12-26 08:07:24 +00:00
callsFactories: List<KtorCallFactory> = emptyList(),
2019-01-24 02:36:44 +00:00
excludeDefaultFactories: Boolean = false,
private val requestsLimiter: RequestLimiter = EmptyLimiter,
2019-02-21 06:21:33 +00:00
private val jsonFormatter: Json = Json.nonstrict
2019-07-25 08:25:18 +00:00
) : BaseRequestsExecutor(telegramAPIUrlsKeeper) {
@Deprecated("Deprecated due to new TelegramAPIUrlKeeper API")
constructor(
token: String,
client: HttpClient = HttpClient(),
hostUrl: String = "https://api.telegram.org",
callsFactories: List<KtorCallFactory> = emptyList(),
excludeDefaultFactories: Boolean = false,
requestsLimiter: RequestLimiter = EmptyLimiter,
jsonFormatter: Json = Json.nonstrict
) : this(TelegramAPIUrlsKeeper(token, hostUrl), client, callsFactories, excludeDefaultFactories, requestsLimiter, jsonFormatter)
@Deprecated("Deprecated due to new TelegramAPIUrlKeeper API")
2018-12-26 08:07:24 +00:00
constructor(
token: String,
engine: HttpClientEngine? = null,
2018-12-26 08:07:24 +00:00
hostUrl: String = "https://api.telegram.org"
) : this(
2019-07-25 08:25:18 +00:00
TelegramAPIUrlsKeeper(token, hostUrl),
engine ?.let { HttpClient(engine) } ?: HttpClient()
2018-12-26 08:07:24 +00:00
)
private val callsFactories: List<KtorCallFactory> = callsFactories.run {
if (!excludeDefaultFactories) {
asSequence().plus(SimpleRequestCallFactory()).plus(MultipartRequestCallFactory()).toList()
} else {
this
}
}
override suspend fun <T : Any> execute(request: Request<T>): T {
2019-01-24 02:36:44 +00:00
return requestsLimiter.limit {
var call: HttpClientCall? = null
for (factory in callsFactories) {
call = factory.prepareCall(
client,
2019-07-25 08:25:18 +00:00
telegramAPIUrlsKeeper.commonAPIUrl,
2019-01-24 02:36:44 +00:00
request
)
if (call != null) {
break
}
2018-12-26 08:07:24 +00:00
}
2019-01-24 02:36:44 +00:00
if (call == null) {
throw IllegalArgumentException("Can't execute request: $request")
}
2019-04-26 03:12:01 +00:00
val content = call.response.use {
it.content.toByteArray().toString(Charsets.UTF_8)
}
val responseObject = jsonFormatter.parse(Response.serializer(), content)
(responseObject.result ?.let {
2019-12-02 08:35:37 +00:00
jsonFormatter.fromJson(request.resultDeserializer, it)
} ?: responseObject.parameters ?.let {
val error = it.error
if (error is RetryAfterError) {
delay(error.leftToRetry)
execute(request)
} else {
null
}
} ?: call.let {
2019-02-10 05:41:20 +00:00
throw newRequestException(
2019-01-24 02:36:44 +00:00
responseObject,
2019-03-04 02:32:26 +00:00
content,
"Can't get result object from $content"
2019-01-24 02:36:44 +00:00
)
})
2018-12-26 08:07:24 +00:00
}
}
2019-07-22 23:46:19 +00:00
override fun close() {
client.close()
}
2018-12-26 08:07:24 +00:00
}