diff --git a/.gradle/6.3/executionHistory/executionHistory.bin b/.gradle/6.3/executionHistory/executionHistory.bin index 02caba1..0d830a1 100644 Binary files a/.gradle/6.3/executionHistory/executionHistory.bin and b/.gradle/6.3/executionHistory/executionHistory.bin differ diff --git a/.gradle/6.3/executionHistory/executionHistory.lock b/.gradle/6.3/executionHistory/executionHistory.lock index 82ae48b..f0eecf3 100644 Binary files a/.gradle/6.3/executionHistory/executionHistory.lock and b/.gradle/6.3/executionHistory/executionHistory.lock differ diff --git a/.gradle/6.3/fileContent/fileContent.lock b/.gradle/6.3/fileContent/fileContent.lock index 49cb4d4..db489af 100644 Binary files a/.gradle/6.3/fileContent/fileContent.lock and b/.gradle/6.3/fileContent/fileContent.lock differ diff --git a/.gradle/6.3/fileHashes/fileHashes.bin b/.gradle/6.3/fileHashes/fileHashes.bin index 0b07bd0..447a3c2 100644 Binary files a/.gradle/6.3/fileHashes/fileHashes.bin and b/.gradle/6.3/fileHashes/fileHashes.bin differ diff --git a/.gradle/6.3/fileHashes/fileHashes.lock b/.gradle/6.3/fileHashes/fileHashes.lock index 53674f7..eef9329 100644 Binary files a/.gradle/6.3/fileHashes/fileHashes.lock and b/.gradle/6.3/fileHashes/fileHashes.lock differ diff --git a/.gradle/6.5.1/fileChanges/last-build.bin b/.gradle/6.5.1/fileChanges/last-build.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/.gradle/6.5.1/fileChanges/last-build.bin differ diff --git a/.gradle/6.5.1/fileHashes/fileHashes.lock b/.gradle/6.5.1/fileHashes/fileHashes.lock new file mode 100644 index 0000000..a67d2e3 Binary files /dev/null and b/.gradle/6.5.1/fileHashes/fileHashes.lock differ diff --git a/.gradle/6.5.1/gc.properties b/.gradle/6.5.1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 1ccae05..fa63a1b 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/cache.properties b/.gradle/buildOutputCleanup/cache.properties index da82781..da4f76d 100644 --- a/.gradle/buildOutputCleanup/cache.properties +++ b/.gradle/buildOutputCleanup/cache.properties @@ -1,2 +1,2 @@ -#Mon Oct 19 09:13:53 CEST 2020 +#Thu Oct 22 22:37:52 CEST 2020 gradle.version=6.3 diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin index b6ab2bc..fff4090 100644 Binary files a/.gradle/buildOutputCleanup/outputFiles.bin and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/.gradle/checksums/checksums.lock b/.gradle/checksums/checksums.lock index a7faeee..c1c077d 100644 Binary files a/.gradle/checksums/checksums.lock and b/.gradle/checksums/checksums.lock differ diff --git a/.gradle/checksums/md5-checksums.bin b/.gradle/checksums/md5-checksums.bin index a7c2e8c..605db4f 100644 Binary files a/.gradle/checksums/md5-checksums.bin and b/.gradle/checksums/md5-checksums.bin differ diff --git a/.gradle/checksums/sha1-checksums.bin b/.gradle/checksums/sha1-checksums.bin index b3eeb5b..746b278 100644 Binary files a/.gradle/checksums/sha1-checksums.bin and b/.gradle/checksums/sha1-checksums.bin differ diff --git a/build.gradle b/build.gradle index 5a697bc..dc3c2f0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id 'java' id 'org.jetbrains.kotlin.jvm' version '1.4.10' + id 'org.jetbrains.kotlin.plugin.serialization' version '1.4.10' } apply plugin: 'kotlin-kapt' // required @@ -16,13 +17,15 @@ repositories { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib" - implementation 'com.fasterxml.jackson.core:jackson-core: 2.9.8' - implementation 'com.fasterxml.jackson.core:jackson-databind: 2.9.8' - implementation 'com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8' implementation 'info.picocli:picocli:4.5.2' - implementation 'com.github.kittinunf.fuel:fuel:2.3.0' - implementation 'com.github.kittinunf.fuel:fuel-jackson:2.3.0' + implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.0' + implementation 'io.ktor:ktor-client-core:1.4.1' + implementation 'io.ktor:ktor-client-core-jvm:1.4.1' + implementation 'io.ktor:ktor-client-apache:1.4.1' + implementation 'io.ktor:ktor-client-logging-jvm:1.4.1' + implementation 'io.ktor:ktor-client-serialization-jvm:1.4.1' + testCompile group: 'junit', name: 'junit', version: '4.12' diff --git a/src/main/kotlin/nl/lengrand/swacli/Configuration.kt b/src/main/kotlin/nl/lengrand/swacli/Configuration.kt new file mode 100644 index 0000000..34b14d0 --- /dev/null +++ b/src/main/kotlin/nl/lengrand/swacli/Configuration.kt @@ -0,0 +1,18 @@ +package nl.lengrand.swacli + +import io.ktor.client.* +import io.ktor.client.engine.apache.* +import io.ktor.client.features.json.* +import io.ktor.client.features.json.serializer.* +import kotlinx.serialization.json.Json + +object Configuration { + + private val jsonSerializer = Json { ignoreUnknownKeys = true} + + fun getHttpClient() = HttpClient(Apache) { + install(JsonFeature) { + serializer = KotlinxSerializer(jsonSerializer) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/nl/lengrand/swacli/SwApi.kt b/src/main/kotlin/nl/lengrand/swacli/SwApi.kt index 2ce354d..86cc146 100644 --- a/src/main/kotlin/nl/lengrand/swacli/SwApi.kt +++ b/src/main/kotlin/nl/lengrand/swacli/SwApi.kt @@ -1,34 +1,31 @@ package nl.lengrand.swacli -import com.fasterxml.jackson.databind.DeserializationFeature -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.kotlin.registerKotlinModule -import com.github.kittinunf.fuel.Fuel -import com.github.kittinunf.fuel.jackson.responseObject - -val mapper: ObjectMapper = ObjectMapper().registerKotlinModule().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) +import io.ktor.client.request.* +import io.ktor.http.* +import kotlinx.serialization.Serializable const val BASE_URL = "https://swapi.dev/api" -class SwApi { - companion object{ - fun getPeople(query : String?) : Response { - return Fuel.get("$BASE_URL/people/${queryString(query)}") - .header("accept", "application/json") - .responseObject>(mapper).third.get() - } +object SwApi { + + private val httpClient = Configuration.getHttpClient() - fun getPlanets(query : String?) : Response { - return Fuel.get("$BASE_URL/planets/${queryString(query)}") - .header("accept", "application/json") - .responseObject>(mapper).third.get() + suspend fun getPeople(query : String?) : Response { + return httpClient.get("$BASE_URL/people/${queryString(query)}") { + header("Content-Type", ContentType.Application.Json.toString()) } + } - private fun queryString(query: String?) = if(query == null) "" else "?search=${query}" + suspend fun getPlanets(query : String?) : Response { + return httpClient.get("$BASE_URL/planets/${queryString(query)}") { + header("Content-Type", ContentType.Application.Json.toString()) + } } + + private fun queryString(query: String?) = if(query == null) "" else "?search=${query}" } -sealed class Data -data class Response(val count: Int, val next : String?, val previous : String?, val results : List) -data class Planet(val climate: String, val name: String, val gravity: String, val orbital_period: String, val diameter: String) : Data() -data class People(val name: String, val height: String, val mass: String, val hair_color: String, val homeworld: String, val birth_year: String) : Data() \ No newline at end of file +@Serializable sealed class Data +@Serializable data class Response(val count: Int, val next : String?, val previous : String?, val results : List) +@Serializable data class Planet(val climate: String, val name: String, val gravity: String, val orbital_period: String, val diameter: String) : Data() +@Serializable data class People(val name: String, val height: String, val mass: String, val hair_color: String, val homeworld: String, val birth_year: String) : Data() \ No newline at end of file diff --git a/src/main/kotlin/nl/lengrand/swacli/SwaCLIOptions.kt b/src/main/kotlin/nl/lengrand/swacli/SwaCLIOptions.kt index aa5acd7..af8c494 100644 --- a/src/main/kotlin/nl/lengrand/swacli/SwaCLIOptions.kt +++ b/src/main/kotlin/nl/lengrand/swacli/SwaCLIOptions.kt @@ -1,5 +1,6 @@ package nl.lengrand.swacli +import kotlinx.coroutines.runBlocking import picocli.CommandLine import picocli.CommandLine.* import java.util.concurrent.Callable @@ -28,10 +29,12 @@ class SwaCLIOptions : Callable { } override fun call(): Int { - if(exclusive.characters) - PrettyPrinter.print(SwApi.getPeople(searchQuery)) - if(exclusive.planets) - PrettyPrinter.print(SwApi.getPlanets(searchQuery)) + runBlocking { + if (exclusive.characters) + PrettyPrinter.print(SwApi.getPeople(searchQuery)) + if (exclusive.planets) + PrettyPrinter.print(SwApi.getPlanets(searchQuery)) + } return 0 } diff --git a/src/main/kotlin/nl/lengrand/swacli/SwaCLIProgrammatic.kt b/src/main/kotlin/nl/lengrand/swacli/SwaCLIProgrammatic.kt index 65ff103..81ed7e3 100644 --- a/src/main/kotlin/nl/lengrand/swacli/SwaCLIProgrammatic.kt +++ b/src/main/kotlin/nl/lengrand/swacli/SwaCLIProgrammatic.kt @@ -1,5 +1,6 @@ package nl.lengrand.swacli +import kotlinx.coroutines.runBlocking import picocli.CommandLine import picocli.CommandLine.IExecutionStrategy import picocli.CommandLine.Model.CommandSpec @@ -7,7 +8,7 @@ import picocli.CommandLine.Model.PositionalParamSpec import picocli.CommandLine.ParseResult import kotlin.system.exitProcess -object SwaCLIProgrammatic { +object SwaCLIProgrammatic { private fun run(parseResult: ParseResult): Int { val helpExitCode = CommandLine.executeHelpRequest(parseResult) @@ -17,10 +18,12 @@ object SwaCLIProgrammatic { val subResult = parseResult.subcommand() val searchQuery = if (subResult.hasMatchedPositional(0)) subResult.matchedPositional(0).stringValues()[0] else null - if (subResult.commandSpec().name() == "planets") - PrettyPrinter.print(SwApi.getPlanets(searchQuery)) - if (subResult.commandSpec().name() == "people") - PrettyPrinter.print(SwApi.getPeople(searchQuery)) + runBlocking { + if (subResult.commandSpec().name() == "planets") + PrettyPrinter.print(SwApi.getPlanets(searchQuery)) + if (subResult.commandSpec().name() == "people") + PrettyPrinter.print(SwApi.getPeople(searchQuery)) + } } return 0 } diff --git a/src/main/kotlin/nl/lengrand/swacli/SwaCLISubCommands.kt b/src/main/kotlin/nl/lengrand/swacli/SwaCLISubCommands.kt index 1a07787..7b4e362 100644 --- a/src/main/kotlin/nl/lengrand/swacli/SwaCLISubCommands.kt +++ b/src/main/kotlin/nl/lengrand/swacli/SwaCLISubCommands.kt @@ -1,5 +1,6 @@ package nl.lengrand.swacli +import kotlinx.coroutines.runBlocking import picocli.CommandLine import picocli.CommandLine.* import picocli.CommandLine.Model.* @@ -37,7 +38,9 @@ class PlanetsCommand : Callable { private var searchQuery : String? = null override fun call(): Int { - PrettyPrinter.print(SwApi.getPlanets(searchQuery)) + runBlocking { + PrettyPrinter.print(SwApi.getPlanets(searchQuery)) + } return 0 } } @@ -49,7 +52,9 @@ class PeopleCommand : Callable { private var searchQuery : String? = null override fun call(): Int { - PrettyPrinter.print(SwApi.getPeople(searchQuery)) + runBlocking { + PrettyPrinter.print(SwApi.getPeople(searchQuery)) + } return 0 } } \ No newline at end of file