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
|
2019-08-19 10:06:04 +00:00
|
|
|
import com.github.insanusmokrassar.TelegramBotAPI.types.Response
|
2019-02-05 04:55:46 +00:00
|
|
|
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
|
2019-02-05 04:55:46 +00:00
|
|
|
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,
|
2019-04-20 04:55:11 +00:00
|
|
|
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,
|
2019-02-05 04:30:09 +00:00
|
|
|
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,
|
2019-04-20 04:55:11 +00:00
|
|
|
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)
|
|
|
|
}
|
2019-08-19 10:06:04 +00:00
|
|
|
val responseObject = jsonFormatter.parse(Response.serializer(), content)
|
2019-08-17 05:50:46 +00:00
|
|
|
|
2019-08-19 10:03:01 +00:00
|
|
|
(responseObject.result ?.let {
|
2019-12-02 08:35:37 +00:00
|
|
|
jsonFormatter.fromJson(request.resultDeserializer, it)
|
2019-08-17 05:50:46 +00:00
|
|
|
} ?: responseObject.parameters ?.let {
|
2019-02-05 04:55:46 +00:00
|
|
|
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
|
|
|
)
|
2019-08-19 10:03:01 +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
|
|
|
}
|