first workting version
This commit is contained in:
1 parent
830765cb13
commit
d2048ea5b7
23 files changed
+292
-86
No files matched your search
@@ -0,0 +1,75 @@
|
||||
package ch.ergon.anytask.api
|
||||
|
||||
import ch.ergon.anytask.api.dto.CreateObjectRequest
|
||||
import ch.ergon.anytask.api.dto.CreateObjectResponse
|
||||
import ch.ergon.anytask.api.dto.Space
|
||||
import ch.ergon.anytask.api.dto.SpacesResponse
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.engine.cio.*
|
||||
import io.ktor.client.plugins.*
|
||||
import io.ktor.client.plugins.contentnegotiation.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.client.statement.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import kotlin.time.DurationUnit.MILLISECONDS
|
||||
import kotlin.time.toDuration
|
||||
|
||||
/**
|
||||
* Client for the local AnyType API (anytype-heart middleware).
|
||||
* The API runs on http://localhost:31007 by default.
|
||||
* apiKey and spaceId are loaded from anytask.yaml.
|
||||
*/
|
||||
class AnyTypeApi(
|
||||
private val baseUrl: String = "http://localhost:31009",
|
||||
private val apiKey: String = "",
|
||||
private val spaceId: String = "",
|
||||
) {
|
||||
private val logger = LogManager.getLogger(AnyTypeApi::class.java)
|
||||
|
||||
private val http = HttpClient(CIO) {
|
||||
install(ContentNegotiation) {
|
||||
json(Json { ignoreUnknownKeys = true })
|
||||
}
|
||||
}.also { client ->
|
||||
client.plugin(HttpSend).intercept { request ->
|
||||
val method = request.method.value
|
||||
val url = request.url.buildString()
|
||||
logger.info("→ $method $url")
|
||||
val start = System.currentTimeMillis()
|
||||
val call = execute(request)
|
||||
val duration = (System.currentTimeMillis() - start).toDuration(MILLISECONDS)
|
||||
val status = call.response.status
|
||||
logger.info("← ${status.value} (${status.description}) $duration")
|
||||
if (!status.isSuccess()) {
|
||||
logger.error("Response body: ${call.response.bodyAsText()}")
|
||||
}
|
||||
call
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getSpaces(): Result<List<Space>> =
|
||||
runCatching {
|
||||
val response = http.get("$baseUrl/v1/spaces") {
|
||||
header("Anytype-Version", "0.1")
|
||||
bearerAuth(apiKey)
|
||||
}
|
||||
response.body<SpacesResponse>().data
|
||||
}
|
||||
|
||||
suspend fun createTask(title: String, details: String = ""): Result<String> =
|
||||
runCatching {
|
||||
val response = http.post("$baseUrl/v1/spaces/$spaceId/objects") {
|
||||
contentType(ContentType.Application.Json)
|
||||
header("Anytype-Version", "0.1")
|
||||
bearerAuth(apiKey)
|
||||
setBody(CreateObjectRequest(name = title, body = details, typeKey = "ot-task"))
|
||||
}
|
||||
response.body<CreateObjectResponse>().objectId
|
||||
}
|
||||
|
||||
fun close() = http.close()
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package ch.ergon.anytask.api
|
||||
|
||||
import io.ktor.client.*
|
||||
import io.ktor.client.call.*
|
||||
import io.ktor.client.engine.cio.*
|
||||
import io.ktor.client.plugins.contentnegotiation.*
|
||||
import io.ktor.client.request.*
|
||||
import io.ktor.http.*
|
||||
import io.ktor.serialization.kotlinx.json.*
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
/**
|
||||
* Client für die lokale AnyType-API (anytype-heart Middleware).
|
||||
* Die API läuft standardmässig auf http://localhost:31007.
|
||||
*
|
||||
* TODO: App-Key via Einstellungen konfigurierbar machen.
|
||||
*/
|
||||
class AnyTypeClient(
|
||||
private val baseUrl: String = "http://localhost:31007",
|
||||
private val appKey: String = "", // wird nach erstem Login gesetzt
|
||||
) {
|
||||
private val http = HttpClient(CIO) {
|
||||
install(ContentNegotiation) {
|
||||
json(Json { ignoreUnknownKeys = true })
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun createTask(title: String, details: String = "", spaceId: String = ""): Result<String> =
|
||||
runCatching {
|
||||
val response = http.post("$baseUrl/v1/spaces/$spaceId/objects") {
|
||||
contentType(ContentType.Application.Json)
|
||||
header("Anytype-Version", "0.1")
|
||||
bearerAuth(appKey)
|
||||
setBody(CreateObjectRequest(title = title, details = details, typeKey = "ot-task"))
|
||||
}
|
||||
response.body<CreateObjectResponse>().objectId
|
||||
}
|
||||
|
||||
fun close() = http.close()
|
||||
}
|
||||
|
||||
@Serializable
|
||||
private data class CreateObjectRequest(
|
||||
val title: String,
|
||||
val details: String,
|
||||
val typeKey: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
private data class CreateObjectResponse(
|
||||
val objectId: String,
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
package ch.ergon.anytask.api.dto
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class CreateObjectRequest(
|
||||
val name: String,
|
||||
val body: String,
|
||||
@SerialName("type_key") val typeKey: String,
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
package ch.ergon.anytask.api.dto
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class CreateObjectResponse(
|
||||
val objectId: String,
|
||||
)
|
||||
@@ -0,0 +1,9 @@
|
||||
package ch.ergon.anytask.api.dto
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Space(
|
||||
val id: String,
|
||||
val name: String,
|
||||
)
|
||||
@@ -0,0 +1,8 @@
|
||||
package ch.ergon.anytask.api.dto
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class SpacesResponse(
|
||||
val data: List<Space>,
|
||||
)
|
||||