This commit is contained in:
InsanusMokrassar 2019-12-13 00:47:52 +06:00
parent ea9d76fa47
commit 1bab6417ed
14 changed files with 141 additions and 200 deletions

View File

@ -16,6 +16,11 @@
Hotfix for serializer of `SauceNaoAnswer` Hotfix for serializer of `SauceNaoAnswer`
### 0.4.4
* Uploading of file
* Updates of versions
### 0.4.2 ### 0.4.2
Hotfix for autostop for some time when there is no remaining quotas for requests Hotfix for autostop for some time when there is no remaining quotas for requests

View File

@ -1,4 +1,4 @@
project.version = "0.4.3" project.version = "0.4.4"
project.group = "com.github.insanusmokrassar" project.group = "com.github.insanusmokrassar"
buildscript { buildscript {
@ -32,7 +32,7 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$kotlin_serialisation_runtime_version" implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$kotlin_serialisation_runtime_version"
implementation "joda-time:joda-time:$joda_time_version" implementation "com.soywiz.korlibs.klock:klock:$klock_version"
implementation "io.ktor:ktor-client-core:$ktor_version" implementation "io.ktor:ktor-client-core:$ktor_version"
implementation "io.ktor:ktor-client-okhttp:$ktor_version" implementation "io.ktor:ktor-client-okhttp:$ktor_version"

View File

@ -1,9 +1,9 @@
kotlin.code.style=official kotlin.code.style=official
kotlin_version=1.3.50 kotlin_version=1.3.61
kotlin_coroutines_version=1.3.2 kotlin_coroutines_version=1.3.2
kotlin_serialisation_runtime_version=0.13.0 kotlin_serialisation_runtime_version=0.14.0
joda_time_version=2.10.4 klock_version=1.8.3
ktor_version=1.2.5 ktor_version=1.2.6
project_public_name=SauceNao API project_public_name=SauceNao API
project_public_description=SauceNao API library project_public_description=SauceNao API library

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-bin.zip

View File

@ -1,14 +1,33 @@
package com.github.insanusmokrassar.SauceNaoAPI package com.github.insanusmokrassar.SauceNaoAPI
import com.github.insanusmokrassar.SauceNaoAPI.utils.mimeType
import io.ktor.http.ContentType
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.io.core.readText
import kotlinx.io.streams.asInput
import java.io.File
import java.net.URLConnection
import java.nio.file.Files
suspend fun main(vararg args: String) { suspend fun main(vararg args: String) {
val (key, requestUrl) = args val (key, requestSubject) = args
val api = SauceNaoAPI(key, scope = GlobalScope) val scope = CoroutineScope(Dispatchers.Default)
api.use {
val api = SauceNaoAPI(key, scope = scope)
api.use { _ ->
println( println(
it.request(requestUrl) when {
requestSubject.startsWith("/") -> File(requestSubject).let {
api.request(
it.inputStream().asInput(),
ContentType.parse(Files.probeContentType(it.toPath()))
)
}
else -> api.request(requestSubject)
}
) )
} }
scope.cancel()
} }

View File

@ -1,29 +1,32 @@
package com.github.insanusmokrassar.SauceNaoAPI package com.github.insanusmokrassar.SauceNaoAPI
import com.github.insanusmokrassar.SauceNaoAPI.additional.LONG_TIME_RECALCULATING_MILLIS
import com.github.insanusmokrassar.SauceNaoAPI.additional.SHORT_TIME_RECALCULATING_MILLIS
import com.github.insanusmokrassar.SauceNaoAPI.exceptions.TooManyRequestsException import com.github.insanusmokrassar.SauceNaoAPI.exceptions.TooManyRequestsException
import com.github.insanusmokrassar.SauceNaoAPI.exceptions.sauceNaoAPIException import com.github.insanusmokrassar.SauceNaoAPI.exceptions.sauceNaoAPIException
import com.github.insanusmokrassar.SauceNaoAPI.models.SauceNaoAnswer import com.github.insanusmokrassar.SauceNaoAPI.models.SauceNaoAnswer
import com.github.insanusmokrassar.SauceNaoAPI.models.SauceNaoAnswerSerializer import com.github.insanusmokrassar.SauceNaoAPI.models.SauceNaoAnswerSerializer
import com.github.insanusmokrassar.SauceNaoAPI.utils.* import com.github.insanusmokrassar.SauceNaoAPI.utils.*
import com.github.insanusmokrassar.SauceNaoAPI.utils.calculateSleepTime
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.call.UnsupportedContentTypeException
import io.ktor.client.call.call
import io.ktor.client.engine.okhttp.OkHttp import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.features.ClientRequestException import io.ktor.client.features.ClientRequestException
import io.ktor.client.request.* import io.ktor.client.request.*
import io.ktor.client.request.forms.*
import io.ktor.client.response.readText import io.ktor.client.response.readText
import io.ktor.http.*
import io.ktor.http.content.OutgoingContent
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.io.core.Closeable import kotlinx.io.core.*
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.joda.time.DateTime
import java.util.logging.Logger import java.util.logging.Logger
import kotlin.coroutines.* import kotlin.coroutines.*
private const val API_TOKEN_FIELD = "api_key" private const val API_TOKEN_FIELD = "api_key"
private const val OUTPUT_TYPE_FIELD = "output_type" private const val OUTPUT_TYPE_FIELD = "output_type"
private const val URL_FIELD = "url" private const val URL_FIELD = "url"
private const val FILE_FIELD = "file"
private const val FILENAME_FIELD = "filename"
private const val DB_FIELD = "db" private const val DB_FIELD = "db"
private const val DBMASK_FIELD = "dbmask" private const val DBMASK_FIELD = "dbmask"
private const val DBMASKI_FIELD = "dbmaski" private const val DBMASKI_FIELD = "dbmaski"
@ -73,7 +76,18 @@ data class SauceNaoAPI(
resultsCount: Int? = null, resultsCount: Int? = null,
minSimilarity: Float? = null minSimilarity: Float? = null
): SauceNaoAnswer? = makeRequest( ): SauceNaoAnswer? = makeRequest(
url, url.asSauceRequestSubject,
resultsCount = resultsCount,
minSimilarity = minSimilarity
)
suspend fun request(
mediaInput: Input,
mimeType: ContentType = mediaInput.mimeType,
resultsCount: Int? = null,
minSimilarity: Float? = null
): SauceNaoAnswer? = makeRequest(
mediaInput.asSauceRequestSubject(mimeType),
resultsCount = resultsCount, resultsCount = resultsCount,
minSimilarity = minSimilarity minSimilarity = minSimilarity
) )
@ -84,7 +98,7 @@ data class SauceNaoAPI(
resultsCount: Int? = null, resultsCount: Int? = null,
minSimilarity: Float? = null minSimilarity: Float? = null
): SauceNaoAnswer? = makeRequest( ): SauceNaoAnswer? = makeRequest(
url, url.asSauceRequestSubject,
db = db, db = db,
resultsCount = resultsCount, resultsCount = resultsCount,
minSimilarity = minSimilarity minSimilarity = minSimilarity
@ -96,7 +110,7 @@ data class SauceNaoAPI(
resultsCount: Int? = null, resultsCount: Int? = null,
minSimilarity: Float? = null minSimilarity: Float? = null
): SauceNaoAnswer? = makeRequest( ): SauceNaoAnswer? = makeRequest(
url, url.asSauceRequestSubject,
dbmask = dbmask, dbmask = dbmask,
resultsCount = resultsCount, resultsCount = resultsCount,
minSimilarity = minSimilarity minSimilarity = minSimilarity
@ -108,7 +122,7 @@ data class SauceNaoAPI(
resultsCount: Int? = null, resultsCount: Int? = null,
minSimilarity: Float? = null minSimilarity: Float? = null
): SauceNaoAnswer? = makeRequest( ): SauceNaoAnswer? = makeRequest(
url, url.asSauceRequestSubject,
dbmaski = dbmaski, dbmaski = dbmaski,
resultsCount = resultsCount, resultsCount = resultsCount,
minSimilarity = minSimilarity minSimilarity = minSimilarity
@ -118,7 +132,7 @@ data class SauceNaoAPI(
builder: HttpRequestBuilder builder: HttpRequestBuilder
): SauceNaoAnswer { ): SauceNaoAnswer {
return try { return try {
val call = client.execute(builder) val call = client.call(builder)
val answerText = call.response.readText() val answerText = call.response.readText()
logger.info(answerText) logger.info(answerText)
timeManager.addTimeAndClear() timeManager.addTimeAndClear()
@ -132,7 +146,7 @@ data class SauceNaoAPI(
} }
private suspend fun makeRequest( private suspend fun makeRequest(
url: String, request: SauceRequestSubject,
db: Int? = null, db: Int? = null,
dbmask: Int? = null, dbmask: Int? = null,
dbmaski: Int? = null, dbmaski: Int? = null,
@ -143,7 +157,7 @@ data class SauceNaoAPI(
requestsChannel.offer( requestsChannel.offer(
it to HttpRequestBuilder().apply { it to HttpRequestBuilder().apply {
url(searchUrl) url(searchUrl)
parameter(URL_FIELD, url)
parameter(API_TOKEN_FIELD, apiToken) parameter(API_TOKEN_FIELD, apiToken)
parameter(OUTPUT_TYPE_FIELD, outputType.typeCode) parameter(OUTPUT_TYPE_FIELD, outputType.typeCode)
db ?.also { parameter(DB_FIELD, it) } db ?.also { parameter(DB_FIELD, it) }
@ -151,6 +165,37 @@ data class SauceNaoAPI(
dbmaski ?.also { parameter(DBMASKI_FIELD, it) } dbmaski ?.also { parameter(DBMASKI_FIELD, it) }
resultsCount ?.also { parameter(RESULTS_COUNT_FIELD, it) } resultsCount ?.also { parameter(RESULTS_COUNT_FIELD, it) }
minSimilarity ?.also { parameter(MINIMAL_SIMILARITY_FIELD, it) } minSimilarity ?.also { parameter(MINIMAL_SIMILARITY_FIELD, it) }
when (request) {
is UrlSauceRequestSubject -> {
parameter(URL_FIELD, request.url)
}
is InputRequestSubject -> {
val mimeType = request.mimeType
method = HttpMethod.Post
body = MultiPartFormDataContent(formData {
appendInput(
FILE_FIELD,
Headers.build {
append(HttpHeaders.ContentType, mimeType.toString())
val fakeFilename = "filename=file" + when (mimeType) {
ContentType.Image.GIF -> ".gif"
ContentType.Image.JPEG -> ".jpeg"
ContentType.Image.PNG -> ".png"
ContentType.Image.SVG -> ".svg"
else -> throw IllegalArgumentException(
"Currently supported formats for uploading in sauce: gif, jpeg, png, svg"
)
}
append(HttpHeaders.ContentDisposition, "filename=$fakeFilename")
},
block = request::input
)
})
}
}
} }
) )
} }

View File

@ -0,0 +1,16 @@
package com.github.insanusmokrassar.SauceNaoAPI
import io.ktor.http.ContentType
import kotlinx.io.core.Input
internal sealed class SauceRequestSubject
internal data class UrlSauceRequestSubject(val url: String) : SauceRequestSubject()
internal data class InputRequestSubject(val input: Input, val mimeType: ContentType) : SauceRequestSubject()
internal val String.asSauceRequestSubject
get() = UrlSauceRequestSubject(this)
internal fun Input.asSauceRequestSubject(mimeType: ContentType)
= InputRequestSubject(this, mimeType)

View File

@ -5,5 +5,5 @@ const val defaultAccountType: AccountType = 1 // "basic"
typealias UserId = Int typealias UserId = Int
const val SHORT_TIME_RECALCULATING_MILLIS = 30 * 1000 const val SHORT_TIME_RECALCULATING_MILLIS = 30.0 * 1000
const val LONG_TIME_RECALCULATING_MILLIS = 24 * 60 * 60 * 1000 const val LONG_TIME_RECALCULATING_MILLIS = 24.0 * 60 * 60 * 1000

View File

@ -1,9 +1,9 @@
package com.github.insanusmokrassar.SauceNaoAPI.models package com.github.insanusmokrassar.SauceNaoAPI.models
import com.github.insanusmokrassar.SauceNaoAPI.utils.JsonObjectSerializer
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.internal.StringDescriptor import kotlinx.serialization.internal.StringDescriptor
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObjectSerializer
@Serializable @Serializable
data class Header( data class Header(
@ -38,11 +38,11 @@ data class Header(
val userId: Int? = null val userId: Int? = null
) )
object IndexesSerializer : KSerializer<List<HeaderIndex?>> { internal object IndexesSerializer : KSerializer<List<HeaderIndex?>> {
override val descriptor: SerialDescriptor = StringDescriptor override val descriptor: SerialDescriptor = StringDescriptor
override fun deserialize(decoder: Decoder): List<HeaderIndex?> { override fun deserialize(decoder: Decoder): List<HeaderIndex?> {
val json = decoder.decodeSerializableValue(JsonObjectSerializer) val json = JsonObjectSerializer.deserialize(decoder)
val parsed = json.keys.mapNotNull { it.toIntOrNull() }.sorted().mapNotNull { val parsed = json.keys.mapNotNull { it.toIntOrNull() }.sorted().mapNotNull {
val jsonObject = json.getObjectOrNull(it.toString()) ?: return@mapNotNull null val jsonObject = json.getObjectOrNull(it.toString()) ?: return@mapNotNull null
val index = Json.nonstrict.parse(HeaderIndex.serializer(), Json.stringify(JsonObjectSerializer, jsonObject)) val index = Json.nonstrict.parse(HeaderIndex.serializer(), Json.stringify(JsonObjectSerializer, jsonObject))

View File

@ -1,162 +0,0 @@
package com.github.insanusmokrassar.SauceNaoAPI.utils
import kotlinx.serialization.*
import kotlinx.serialization.internal.*
import kotlinx.serialization.json.*
@Serializer(forClass = JsonElement::class)
internal object JsonElementSerializer : KSerializer<JsonElement> {
override val descriptor: SerialDescriptor = object : SerialClassDescImpl("JsonElementSerializer") {
override val kind: SerialKind
get() = UnionKind.SEALED
init {
addElement("JsonElement")
}
}
override fun serialize(encoder: Encoder, obj: JsonElement) {
when (obj) {
is JsonPrimitive -> JsonPrimitiveSerializer.serialize(encoder, obj)
is JsonObject -> JsonObjectSerializer.serialize(encoder, obj)
is JsonArray -> JsonArraySerializer.serialize(encoder, obj)
}
}
override fun deserialize(decoder: Decoder): JsonElement {
val input = decoder as? JsonInput ?: error("JsonElement is deserializable only when used by Json")
return input.decodeJson()
}
}
@Serializer(forClass = JsonPrimitive::class)
internal object JsonPrimitiveSerializer : KSerializer<JsonPrimitive> {
override val descriptor: SerialDescriptor =
JsonPrimitiveDescriptor
override fun serialize(encoder: Encoder, obj: JsonPrimitive) {
return if (obj is JsonNull) {
JsonNullSerializer.serialize(encoder, JsonNull)
} else {
JsonLiteralSerializer.serialize(encoder, obj as JsonLiteral)
}
}
override fun deserialize(decoder: Decoder): JsonPrimitive {
return if (decoder.decodeNotNullMark()) JsonPrimitive(decoder.decodeString())
else JsonNullSerializer.deserialize(decoder)
}
private object JsonPrimitiveDescriptor : SerialClassDescImpl("JsonPrimitive") {
override val kind: SerialKind
get() = PrimitiveKind.STRING
override val isNullable: Boolean
get() = true
init {
JsonPrimitiveSerializer.JsonPrimitiveDescriptor.addElement("JsonPrimitive")
}
}
}
@Serializer(forClass = JsonNull::class)
internal object JsonNullSerializer : KSerializer<JsonNull> {
override val descriptor: SerialDescriptor =
JsonNullDescriptor
override fun serialize(encoder: Encoder, obj: JsonNull) {
encoder.encodeNull()
}
override fun deserialize(decoder: Decoder): JsonNull {
decoder.decodeNull()
return JsonNull
}
private object JsonNullDescriptor : SerialClassDescImpl("JsonNull") {
override val kind: SerialKind
get() = UnionKind.OBJECT
override val isNullable: Boolean
get() = true
init {
JsonNullSerializer.JsonNullDescriptor.addElement("JsonNull")
}
}
}
@Serializer(forClass = JsonLiteral::class)
internal object JsonLiteralSerializer : KSerializer<JsonLiteral> {
override val descriptor: SerialDescriptor =
JsonLiteralDescriptor
override fun serialize(encoder: Encoder, obj: JsonLiteral) {
if (obj.isString) {
return encoder.encodeString(obj.content)
}
val integer = obj.intOrNull
if (integer != null) {
return encoder.encodeInt(integer)
}
val double = obj.doubleOrNull
if (double != null) {
return encoder.encodeDouble(double)
}
val boolean = obj.booleanOrNull
if (boolean != null) {
return encoder.encodeBoolean(boolean)
}
encoder.encodeString(obj.content)
}
override fun deserialize(decoder: Decoder): JsonLiteral {
return JsonLiteral(decoder.decodeString())
}
private object JsonLiteralDescriptor : SerialClassDescImpl("JsonLiteral") {
override val kind: SerialKind
get() = PrimitiveKind.STRING
init {
JsonLiteralSerializer.JsonLiteralDescriptor.addElement("JsonLiteral")
}
}
}
@Serializer(forClass = JsonObject::class)
internal object JsonObjectSerializer : KSerializer<JsonObject> {
override val descriptor: SerialDescriptor =
NamedMapClassDescriptor("JsonObject", StringSerializer.descriptor,
JsonElementSerializer.descriptor)
override fun serialize(encoder: Encoder, obj: JsonObject) {
LinkedHashMapSerializer(StringSerializer, JsonElementSerializer).serialize(encoder, obj.content)
}
override fun deserialize(decoder: Decoder): JsonObject {
return JsonObject(LinkedHashMapSerializer(StringSerializer, JsonElementSerializer).deserialize(decoder))
}
}
@Serializer(forClass = JsonArray::class)
internal object JsonArraySerializer : KSerializer<JsonArray> {
override val descriptor: SerialDescriptor = NamedListClassDescriptor("JsonArray",
JsonElementSerializer.descriptor)
override fun serialize(encoder: Encoder, obj: JsonArray) {
ArrayListSerializer(JsonElementSerializer).serialize(encoder, obj)
}
override fun deserialize(decoder: Decoder): JsonArray {
return JsonArray(ArrayListSerializer(JsonElementSerializer).deserialize(decoder))
}
}

View File

@ -0,0 +1,16 @@
package com.github.insanusmokrassar.SauceNaoAPI.utils
import io.ktor.http.ContentType
import io.ktor.util.asStream
import kotlinx.io.core.Input
import java.io.InputStream
import java.net.URLConnection
val InputStream.mimeType: ContentType
get() {
val contentType = URLConnection.guessContentTypeFromStream(this)
return ContentType.parse(contentType)
}
val Input.mimeType: ContentType
get() = asStream().mimeType

View File

@ -3,10 +3,10 @@ package com.github.insanusmokrassar.SauceNaoAPI.utils
import com.github.insanusmokrassar.SauceNaoAPI.additional.LONG_TIME_RECALCULATING_MILLIS import com.github.insanusmokrassar.SauceNaoAPI.additional.LONG_TIME_RECALCULATING_MILLIS
import com.github.insanusmokrassar.SauceNaoAPI.additional.SHORT_TIME_RECALCULATING_MILLIS import com.github.insanusmokrassar.SauceNaoAPI.additional.SHORT_TIME_RECALCULATING_MILLIS
import com.github.insanusmokrassar.SauceNaoAPI.models.Header import com.github.insanusmokrassar.SauceNaoAPI.models.Header
import com.soywiz.klock.DateTime
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.io.core.Closeable import kotlinx.io.core.Closeable
import org.joda.time.DateTime
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@ -43,11 +43,11 @@ class RequestQuotaManager (
shortQuota = min(newShortQuota, shortMaxQuota) shortQuota = min(newShortQuota, shortMaxQuota)
when { when {
longQuota < 1 -> (timeManager.getMostOldestInLongPeriod() ?: DateTime.now()).millis + LONG_TIME_RECALCULATING_MILLIS longQuota < 1 -> (timeManager.getMostOldestInLongPeriod() ?: DateTime.now()).unixMillisLong + LONG_TIME_RECALCULATING_MILLIS.toLong()
shortQuota < 1 -> (timeManager.getMostOldestInShortPeriod() ?: DateTime.now()).millis + SHORT_TIME_RECALCULATING_MILLIS shortQuota < 1 -> (timeManager.getMostOldestInShortPeriod() ?: DateTime.now()).unixMillisLong + SHORT_TIME_RECALCULATING_MILLIS.toLong()
else -> null else -> null
} ?.also { } ?.also {
delay(it - DateTime.now().millis) delay((it - DateTime.now().unixMillisLong))
shortQuota = max(shortQuota, 1) shortQuota = max(shortQuota, 1)
longQuota = max(longQuota, 1) longQuota = max(longQuota, 1)
} }

View File

@ -3,7 +3,8 @@ package com.github.insanusmokrassar.SauceNaoAPI.utils
import com.github.insanusmokrassar.SauceNaoAPI.additional.LONG_TIME_RECALCULATING_MILLIS import com.github.insanusmokrassar.SauceNaoAPI.additional.LONG_TIME_RECALCULATING_MILLIS
import com.github.insanusmokrassar.SauceNaoAPI.additional.SHORT_TIME_RECALCULATING_MILLIS import com.github.insanusmokrassar.SauceNaoAPI.additional.SHORT_TIME_RECALCULATING_MILLIS
import com.github.insanusmokrassar.SauceNaoAPI.models.Header import com.github.insanusmokrassar.SauceNaoAPI.models.Header
import org.joda.time.DateTime import com.soywiz.klock.DateTime
import com.soywiz.klock.TimeSpan
internal suspend fun calculateSleepTime( internal suspend fun calculateSleepTime(
header: Header, header: Header,
@ -11,8 +12,8 @@ internal suspend fun calculateSleepTime(
mostOldestInLongPeriodGetter: suspend () -> DateTime? mostOldestInLongPeriodGetter: suspend () -> DateTime?
): DateTime? { ): DateTime? {
return when { return when {
header.longRemaining < 1 -> mostOldestInLongPeriodGetter() ?.plusMillis(LONG_TIME_RECALCULATING_MILLIS) header.longRemaining < 1 -> mostOldestInLongPeriodGetter() ?.plus(TimeSpan(LONG_TIME_RECALCULATING_MILLIS))
header.shortRemaining < 1 -> mostOldestInShortPeriodGetter() ?.plusMillis(SHORT_TIME_RECALCULATING_MILLIS) header.shortRemaining < 1 -> mostOldestInShortPeriodGetter() ?.plus(TimeSpan(SHORT_TIME_RECALCULATING_MILLIS))
else -> null else -> null
} }
} }

View File

@ -2,16 +2,17 @@ package com.github.insanusmokrassar.SauceNaoAPI.utils
import com.github.insanusmokrassar.SauceNaoAPI.additional.LONG_TIME_RECALCULATING_MILLIS import com.github.insanusmokrassar.SauceNaoAPI.additional.LONG_TIME_RECALCULATING_MILLIS
import com.github.insanusmokrassar.SauceNaoAPI.additional.SHORT_TIME_RECALCULATING_MILLIS import com.github.insanusmokrassar.SauceNaoAPI.additional.SHORT_TIME_RECALCULATING_MILLIS
import com.soywiz.klock.DateTime
import com.soywiz.klock.TimeSpan
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.io.core.Closeable import kotlinx.io.core.Closeable
import org.joda.time.DateTime
import kotlin.coroutines.Continuation import kotlin.coroutines.Continuation
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
private fun MutableList<DateTime>.clearTooOldTimes(relatedTo: DateTime = DateTime.now()) { private fun MutableList<DateTime>.clearTooOldTimes(relatedTo: DateTime = DateTime.now()) {
val limitValue = relatedTo.minusMillis(LONG_TIME_RECALCULATING_MILLIS) val limitValue = relatedTo.minus(TimeSpan(LONG_TIME_RECALCULATING_MILLIS.toDouble()))
removeAll { removeAll {
it < limitValue it < limitValue
@ -55,7 +56,7 @@ private data class TimeManagerMostOldestInShortGetter(
val now = DateTime.now() val now = DateTime.now()
val limitTime = now.minusMillis(SHORT_TIME_RECALCULATING_MILLIS) val limitTime = now.minus(TimeSpan(SHORT_TIME_RECALCULATING_MILLIS.toDouble()))
continuation.resumeWith( continuation.resumeWith(
Result.success( Result.success(