1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2024-11-22 08:13:47 +00:00

Merge pull request #13 from InsanusMokrassar/0.9.3

0.9.3
This commit is contained in:
InsanusMokrassar 2019-02-05 16:01:26 +08:00 committed by GitHub
commit 6bdd17a186
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 103 additions and 43 deletions

View File

@ -27,6 +27,16 @@ must be regular text
* `RequestsExecutor#executeAsync(Request, CoroutineScope)` now will return `Deferred` for cases when you need result * `RequestsExecutor#executeAsync(Request, CoroutineScope)` now will return `Deferred` for cases when you need result
* `RequestsExecutor#executeUnsafe` will automatically retry request if it was unsuccessful and retries > 0 * `RequestsExecutor#executeUnsafe` will automatically retry request if it was unsuccessful and retries > 0
### 0.9.3
* `KtorRequestsExecutor` now can use custom `JSON` string formatter (by default - non strict)
* `ResponseParameters` renamed to `Response`
* Add `RequestError` sealed class and described in documentation known errors
* Add `ResponseParametersRaw` which can create error based on input parameters
* Add `parameters` field in `Response` and remove useless fields from `Response`
* Add `leftToRetry` parameter in `RetryAfterError`
* Add handling of `RetryAfterError` in `KtorRequestsExecutor`
### 0.8.5 ### 0.8.5
* Add extension `String#toMarkdown` * Add extension `String#toMarkdown`

View File

@ -1,4 +1,4 @@
project.version = "0.9.2" project.version = "0.9.3"
project.group = "com.github.insanusmokrassar" project.group = "com.github.insanusmokrassar"
buildscript { buildscript {

View File

@ -7,12 +7,14 @@ import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestException
import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.EmptyLimiter import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.EmptyLimiter
import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.RequestLimiter import com.github.insanusmokrassar.TelegramBotAPI.bot.settings.limiters.RequestLimiter
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
import com.github.insanusmokrassar.TelegramBotAPI.types.ResponseParameters import com.github.insanusmokrassar.TelegramBotAPI.types.Response
import com.github.insanusmokrassar.TelegramBotAPI.types.RetryAfterError
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.call.HttpClientCall import io.ktor.client.call.HttpClientCall
import io.ktor.client.engine.HttpClientEngine import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.engine.okhttp.OkHttp import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.util.cio.toByteArray import io.ktor.util.cio.toByteArray
import kotlinx.coroutines.delay
import kotlinx.io.charsets.Charset import kotlinx.io.charsets.Charset
import kotlinx.serialization.json.JSON import kotlinx.serialization.json.JSON
@ -22,7 +24,8 @@ class KtorRequestsExecutor(
hostUrl: String = "https://api.telegram.org", hostUrl: String = "https://api.telegram.org",
callsFactories: List<KtorCallFactory> = emptyList(), callsFactories: List<KtorCallFactory> = emptyList(),
excludeDefaultFactories: Boolean = false, excludeDefaultFactories: Boolean = false,
private val requestsLimiter: RequestLimiter = EmptyLimiter private val requestsLimiter: RequestLimiter = EmptyLimiter,
private val jsonFormatter: JSON = JSON.nonstrict
) : BaseRequestsExecutor(token, hostUrl) { ) : BaseRequestsExecutor(token, hostUrl) {
constructor( constructor(
token: String, token: String,
@ -59,11 +62,19 @@ class KtorRequestsExecutor(
throw IllegalArgumentException("Can't execute request: $request") throw IllegalArgumentException("Can't execute request: $request")
} }
val content = call.response.content.toByteArray().toString(Charset.defaultCharset()) val content = call.response.content.toByteArray().toString(Charset.defaultCharset())
val responseObject = JSON.parse( val responseObject = jsonFormatter.parse(
ResponseParameters.serializer(request.resultSerializer()), Response.serializer(request.resultSerializer()),
content content
) )
responseObject.result ?: call.let { responseObject.result ?: responseObject.parameters ?.let {
val error = it.error
if (error is RetryAfterError) {
delay(error.leftToRetry)
execute(request)
} else {
null
}
} ?: call.let {
throw RequestException( throw RequestException(
responseObject, responseObject,
"Can't get result object" "Can't get result object"

View File

@ -1,10 +1,10 @@
package com.github.insanusmokrassar.TelegramBotAPI.bot package com.github.insanusmokrassar.TelegramBotAPI.bot
import com.github.insanusmokrassar.TelegramBotAPI.types.ResponseParameters import com.github.insanusmokrassar.TelegramBotAPI.types.Response
import java.io.IOException import java.io.IOException
class RequestException( class RequestException(
val response: ResponseParameters<*>, val response: Response<*>,
message: String? = null, message: String? = null,
cause: Throwable? = null cause: Throwable? = null
) : IOException( ) : IOException(

View File

@ -1,6 +1,6 @@
package com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts package com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts
import com.github.insanusmokrassar.TelegramBotAPI.types.ResponseParameters import com.github.insanusmokrassar.TelegramBotAPI.types.Response
import com.github.insanusmokrassar.TelegramBotAPI.utils.toJsonWithoutNulls import com.github.insanusmokrassar.TelegramBotAPI.utils.toJsonWithoutNulls
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
@ -15,6 +15,6 @@ interface Request<T: Any> {
fun <T : Any> StringFormat.extractResult( fun <T : Any> StringFormat.extractResult(
from: String, from: String,
dataSerializer: KSerializer<T> dataSerializer: KSerializer<T>
): ResponseParameters<T> { ): Response<T> {
return parse(ResponseParameters.serializer(dataSerializer), from) return parse(Response.serializer(dataSerializer), from)
} }

View File

@ -0,0 +1,20 @@
package com.github.insanusmokrassar.TelegramBotAPI.types
import java.util.concurrent.TimeUnit
sealed class RequestError
data class RetryAfterError(
val seconds: Long,
val startCountingMillis: Long
) : RequestError() {
val canContinue = TimeUnit.SECONDS.toMillis(seconds) + startCountingMillis
val leftToRetry: Long
get() = canContinue - System.currentTimeMillis()
}
data class MigrateChatId(
val newChatId: ChatId
) : RequestError()

View File

@ -0,0 +1,25 @@
package com.github.insanusmokrassar.TelegramBotAPI.types
import kotlinx.serialization.*
import org.joda.time.DateTime
import java.util.concurrent.TimeUnit
@Deprecated(
"Deprecated because incorrect name",
ReplaceWith("Response")
)
typealias ResponseParameters<T> = Response<T>
@Serializable
data class Response<T : Any>(
val ok: Boolean = false,
@Optional
val description: String? = null,
@SerialName("error_code")
@Optional
val errorCode: Int? = null,
@Optional
val result: T? = null,
@Optional
val parameters: ResponseParametersRaw? = null
)

View File

@ -1,30 +0,0 @@
package com.github.insanusmokrassar.TelegramBotAPI.types
import kotlinx.serialization.*
import org.joda.time.DateTime
import java.util.concurrent.TimeUnit
@Serializable
data class ResponseParameters<T : Any>(
val ok: Boolean = false,
@Optional
val description: String? = null,
@SerialName("migrate_to_chat_id")
@Optional
val migrateToChatId: Identifier? = null,
@SerialName("retry_after")
@Optional
val retryAfter: Int? = null,
@SerialName("error_code")
@Optional
val errorCode: Int? = null,
@Optional
val result: T? = null
) {
@Transient
val waitUntil: DateTime? by lazy {
retryAfter ?.let {
DateTime.now().plus(TimeUnit.SECONDS.toMillis(it.toLong()))
}
}
}

View File

@ -0,0 +1,24 @@
package com.github.insanusmokrassar.TelegramBotAPI.types
import kotlinx.serialization.*
@Serializable
data class ResponseParametersRaw(
@SerialName("migrate_to_chat_id")
@Optional
private val migrateToChatId: ChatId? = null,
@SerialName("retry_after")
@Optional
private val retryAfter: Long? = null
) {
@Transient
private val createTime: Long = System.currentTimeMillis()
@Transient
val error: RequestError? by lazy {
when {
migrateToChatId != null -> MigrateChatId(migrateToChatId);
retryAfter != null -> RetryAfterError(retryAfter, createTime);
else -> null
}
}
}

View File

@ -4,7 +4,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestException
import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor import com.github.insanusmokrassar.TelegramBotAPI.bot.RequestsExecutor
import com.github.insanusmokrassar.TelegramBotAPI.requests.* import com.github.insanusmokrassar.TelegramBotAPI.requests.*
import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request
import com.github.insanusmokrassar.TelegramBotAPI.types.ResponseParameters import com.github.insanusmokrassar.TelegramBotAPI.types.Response
import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.UpdateIdentifier
import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.MediaGroupMessage import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.MediaGroupMessage
import com.github.insanusmokrassar.TelegramBotAPI.types.update.* import com.github.insanusmokrassar.TelegramBotAPI.types.update.*
@ -147,7 +147,7 @@ fun RequestsExecutor.startGettingOfUpdates(
fun <T: Any> RequestsExecutor.executeAsync( fun <T: Any> RequestsExecutor.executeAsync(
request: Request<T>, request: Request<T>,
onFail: (suspend (ResponseParameters<*>) -> Unit)? = null, onFail: (suspend (Response<*>) -> Unit)? = null,
scope: CoroutineScope = GlobalScope, scope: CoroutineScope = GlobalScope,
onSuccess: (suspend (T) -> Unit)? = null onSuccess: (suspend (T) -> Unit)? = null
): Job { ): Job {