Move everything under kotlin-native folder
I was forced to manually do update the following files, because otherwise they would be ignored according .gitignore settings. Probably they should be deleted from repo. Interop/.idea/compiler.xml Interop/.idea/gradle.xml Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_3.xml Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_3.xml Interop/.idea/modules.xml Interop/.idea/modules/Indexer/Indexer.iml Interop/.idea/modules/Runtime/Runtime.iml Interop/.idea/modules/StubGenerator/StubGenerator.iml backend.native/backend.native.iml backend.native/bc.frontend/bc.frontend.iml backend.native/cli.bc/cli.bc.iml backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt backend.native/tests/link/lib/foo.kt backend.native/tests/link/lib/foo2.kt backend.native/tests/teamcity-test.property
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
FROM openjdk:8u171-jdk-stretch as builder
|
||||
WORKDIR /opt
|
||||
ENV kotlin_native_ver "0.7.1"
|
||||
ENV kotlin_native_home "/opt/kotlin-native-linux-$kotlin_native_ver"
|
||||
RUN wget "https://github.com/JetBrains/kotlin-native/releases/download/v$kotlin_native_ver/kotlin-native-linux-$kotlin_native_ver.tar.gz" \
|
||||
&& tar -xzf kotlin-native-linux-$kotlin_native_ver.tar.gz && rm kotlin-native-linux-$kotlin_native_ver.tar.gz \
|
||||
&& apt-get -qy update && apt-get install libcurl4-openssl-dev \
|
||||
&& mkdir -p /app/src/main/kotlin/org/example/weather_func \
|
||||
&& mkdir -p /app/lib/cJSON-1.7.7/include/cjson && mkdir -p /app/lib/cJSON-1.7.7/lib/x86_64-linux-gnu \
|
||||
&& mkdir -p /app/gradle/wrapper
|
||||
WORKDIR /app
|
||||
|
||||
COPY gradle/wrapper/gradle-wrapper.properties gradle/wrapper/gradle-wrapper.jar /app/gradle/wrapper/
|
||||
COPY gradlew openweathermap_key.txt /app/
|
||||
COPY .konan/ /root/.konan
|
||||
COPY *.def *.kts /app/
|
||||
COPY src/ /app/src
|
||||
COPY lib/cJSON-1.7.7/include/cjson/cJSON.h /app/lib/cJSON-1.7.7/include/cJSON.h
|
||||
COPY lib/cJSON-1.7.7/lib/x86_64-linux-gnu/libcjson.a /app/lib/cJSON-1.7.7/lib/libcjson.a
|
||||
RUN ./gradlew build && cp build/konan/bin/linux_x64/weather.kexe weather
|
||||
|
||||
FROM debian:stretch
|
||||
ADD https://github.com/openfaas/faas/releases/download/0.8.2/fwatchdog /usr/bin
|
||||
RUN apt-get update && apt-get -qy install libcurl4-openssl-dev \
|
||||
&& chmod +x /usr/bin/fwatchdog && mkdir -p /app
|
||||
WORKDIR /app
|
||||
COPY --from=builder /app/openweathermap_key.txt .
|
||||
COPY --from=builder /app/weather .
|
||||
RUN chmod +x weather
|
||||
ENV fprocess "./weather"
|
||||
HEALTHCHECK --interval=2s CMD [ -e /tmp/.lock ] || exit 1
|
||||
CMD ["fwatchdog"]
|
||||
@@ -0,0 +1,24 @@
|
||||
group = "org.example"
|
||||
version = "0.1-SNAPSHOT"
|
||||
|
||||
plugins {
|
||||
id("konan")
|
||||
}
|
||||
|
||||
konanArtifacts {
|
||||
interop("curl") {
|
||||
defFile("curl.def")
|
||||
}
|
||||
|
||||
interop("cjson") {
|
||||
defFile("cjson.def")
|
||||
}
|
||||
|
||||
program("weather") {
|
||||
entryPoint("org.example.weather_func.main")
|
||||
libraries {
|
||||
artifact("cjson")
|
||||
artifact("curl")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package = cjson
|
||||
headers = cJSON.h
|
||||
compilerOpts = -std=c89
|
||||
compilerOpts.linux = -I/app/lib/cJSON-1.7.7/include
|
||||
staticLibraries = libcjson.a
|
||||
libraryPaths = /app/lib/cJSON-1.7.7/lib
|
||||
@@ -0,0 +1,5 @@
|
||||
package = curl
|
||||
headers = curl.h
|
||||
linkerOpts.linux = -L/usr/lib/x86_64-linux-gnu -lcurl
|
||||
compilerOpts = -std=c89
|
||||
compilerOpts.linux = -I/usr/include/x86_64-linux-gnu/curl
|
||||
@@ -0,0 +1,20 @@
|
||||
rootProject.name = "weather-function"
|
||||
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
jcenter()
|
||||
maven("https://dl.bintray.com/jetbrains/kotlin-native-dependencies")
|
||||
}
|
||||
|
||||
// This way we can map plugin to standard maven artifact
|
||||
// for maven repositories without plugin descriptor
|
||||
resolutionStrategy {
|
||||
eachPlugin {
|
||||
if (requested.id.id == "konan") {
|
||||
val kotlinNativeVer = "0.7.1"
|
||||
useModule("org.jetbrains.kotlin:kotlin-native-gradle-plugin:$kotlinNativeVer")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.example.weather_func
|
||||
|
||||
/** Models the current weather for a location. */
|
||||
internal data class Weather(
|
||||
val placeName: String,
|
||||
val countryCode: String,
|
||||
val windSpeed: Double = 0.0,
|
||||
val windDegrees: Int = 0,
|
||||
val temp: Int,
|
||||
val minTemp: Int,
|
||||
val maxTemp: Int,
|
||||
val humidity: Int,
|
||||
val conditions: Array<Pair<String, String>>
|
||||
)
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.example.weather_func
|
||||
|
||||
import org.example.weather_func.Event
|
||||
import platform.posix.size_t
|
||||
|
||||
import curl.curl_easy_setopt
|
||||
import curl.CURLOPT_URL
|
||||
import curl.CURLOPT_HEADERFUNCTION
|
||||
import curl.CURLOPT_HEADERDATA
|
||||
import curl.CURLOPT_WRITEFUNCTION
|
||||
import curl.CURLOPT_WRITEDATA
|
||||
import curl.curl_easy_cleanup
|
||||
import curl.curl_easy_init
|
||||
import curl.CURLE_OK
|
||||
import curl.curl_easy_strerror
|
||||
import curl.curl_easy_perform
|
||||
|
||||
import kotlinx.cinterop.staticCFunction
|
||||
import kotlinx.cinterop.COpaquePointer
|
||||
import kotlinx.cinterop.CPointer
|
||||
import kotlinx.cinterop.StableRef
|
||||
import kotlinx.cinterop.asStableRef
|
||||
import kotlinx.cinterop.ByteVar
|
||||
import kotlinx.cinterop.readBytes
|
||||
|
||||
/**
|
||||
* Provides basic HTTP client functionality through the libCurl library.
|
||||
*/
|
||||
internal class CUrl(val url: String) {
|
||||
private val stableRef = StableRef.create(this)
|
||||
private val curlObj = curl_easy_init()
|
||||
val header = Event<String>()
|
||||
val body = Event<String>()
|
||||
|
||||
init {
|
||||
val header = staticCFunction(::headerCallback)
|
||||
val writeData = staticCFunction(::writeCallback)
|
||||
|
||||
// Setup Curl.
|
||||
curl_easy_setopt(curlObj, CURLOPT_URL, url)
|
||||
curl_easy_setopt(curlObj, CURLOPT_HEADERFUNCTION, header)
|
||||
curl_easy_setopt(curlObj, CURLOPT_HEADERDATA, stableRef.asCPointer())
|
||||
curl_easy_setopt(curlObj, CURLOPT_WRITEFUNCTION, writeData)
|
||||
curl_easy_setopt(curlObj, CURLOPT_WRITEDATA, stableRef.asCPointer())
|
||||
}
|
||||
|
||||
fun fetch() {
|
||||
// Have Curl do a HTTP/HTTPS request and store the response (status).
|
||||
val response = curl_easy_perform(curlObj)
|
||||
val maxChars = 50
|
||||
// utfCharSize in bytes.
|
||||
val utfCharSize = 4
|
||||
// length in bytes.
|
||||
val length = utfCharSize * maxChars
|
||||
// Print the error message if the Curl status code isn't OK (CURLE_OK).
|
||||
if (response != CURLE_OK) println("Curl HTTP/S request failed: ${curl_easy_strerror(response)?.toKString(length)}")
|
||||
}
|
||||
|
||||
fun close() {
|
||||
curl_easy_cleanup(curlObj)
|
||||
stableRef.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
fun headerCallback(buffer: CPointer<ByteVar>?, size: size_t, totalItems: size_t, userData: COpaquePointer?): size_t {
|
||||
var responseSize = 0L
|
||||
if (buffer != null && userData != null) {
|
||||
val header = buffer.toKString((size * totalItems).toInt()).trim()
|
||||
val curlRef = userData.asStableRef<CUrl>().get()
|
||||
|
||||
curlRef.header(header)
|
||||
responseSize = size * totalItems
|
||||
}
|
||||
return responseSize
|
||||
}
|
||||
|
||||
fun writeCallback(buffer: CPointer<ByteVar>?, size: size_t, totalItems: size_t, userData: COpaquePointer?): size_t {
|
||||
var responseSize = 0L
|
||||
if (buffer != null && userData != null) {
|
||||
val data = buffer.toKString((size * totalItems).toInt()).trim()
|
||||
val curlRef = userData.asStableRef<CUrl>().get()
|
||||
|
||||
curlRef.body(data)
|
||||
responseSize = size * totalItems
|
||||
}
|
||||
return responseSize
|
||||
}
|
||||
|
||||
private fun CPointer<ByteVar>.toKString(length: Int) = readBytes(length).decodeToString()
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.example.weather_func
|
||||
|
||||
internal typealias EventHandler<T> = (T) -> Unit
|
||||
|
||||
/**
|
||||
* Covers event handling for the program.
|
||||
*/
|
||||
internal class Event<T : Any?> {
|
||||
private var handlers = emptyList<EventHandler<T>>()
|
||||
|
||||
fun subscribe(handler: EventHandler<T>) {
|
||||
handlers += handler
|
||||
}
|
||||
|
||||
fun unsubscribe(handler: EventHandler<T>) {
|
||||
handlers -= handler
|
||||
}
|
||||
|
||||
operator fun plusAssign(handler: EventHandler<T>) = subscribe(handler)
|
||||
operator fun minusAssign(handler: EventHandler<T>) = unsubscribe(handler)
|
||||
|
||||
operator fun invoke(value: T) {
|
||||
var exception: Throwable? = null
|
||||
for (handler in handlers) {
|
||||
try { handler(value) }
|
||||
catch (ex: Throwable) { exception = ex }
|
||||
}
|
||||
// If the exception isn't null then throw it.
|
||||
exception?.let { throw it }
|
||||
}
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.example.weather_func
|
||||
|
||||
import cjson.cJSON_CreateObject as createJsonObject
|
||||
import cjson.cJSON_AddStringToObject as addStringToObject
|
||||
import cjson.cJSON_AddNumberToObject as addNumberToObject
|
||||
import cjson.cJSON_AddArrayToObject as addArrayToObject
|
||||
import cjson.cJSON_AddItemToArray as addItemToArray
|
||||
import cjson.cJSON_AddItemToObjectCS as addItemToObject
|
||||
|
||||
import cjson.cJSON_Delete as deleteObject
|
||||
import cjson.cJSON_Print as jsonString
|
||||
import cjson.cJSON_Parse as parseJson
|
||||
import cjson.cJSON_GetObjectItemCaseSensitive as jsonObjectItem
|
||||
import cjson.cJSON_IsString as jsonValueIsString
|
||||
|
||||
import cjson.cJSON_IsNumber as jsonValueIsNumber
|
||||
import cjson.cJSON_GetErrorPtr as getErrorPointer
|
||||
import cjson.cJSON_GetStringValue as jsonStringValue
|
||||
import cjson.cJSON_GetArraySize as jsonArraySize
|
||||
import cjson.cJSON_GetArrayItem as jsonArrayItem
|
||||
import cjson.cJSON
|
||||
|
||||
import kotlinx.cinterop.CPointer
|
||||
import kotlinx.cinterop.toKString
|
||||
import kotlinx.cinterop.pointed
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
private val trueValue = 1
|
||||
|
||||
internal fun createWeatherFromJson(jsonStr: String): Weather {
|
||||
val rootObj = parseJson(jsonStr)
|
||||
checkForError()
|
||||
val result = createWeather(
|
||||
placeName = jsonObjectItem(rootObj, "name").stringValue(),
|
||||
countryCode = extractCountryCode(rootObj),
|
||||
windInfo = extractWindInfo(rootObj),
|
||||
conditions = extractConditions(rootObj),
|
||||
tempInfo = extractTempInfo(rootObj),
|
||||
humidity = extractHumidity(rootObj)
|
||||
)
|
||||
if (rootObj != null) deleteObject(rootObj)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Weather object.
|
||||
* @param placeName Name of the place.
|
||||
* @param countryCode Unique country code.
|
||||
* @param windInfo A Pair with wind speed as 1st item, and wind degrees as 2nd item.
|
||||
* @param conditions A Array of Pair. Each Pair has name as 1st item, and desc as 2nd item.
|
||||
* @param humidity General humidity of the atmosphere.
|
||||
* @param tempInfo A Triple with temperature as 1st item, min temperature as 2nd item, and max temperature as 3rd item.
|
||||
* @return A instance of Weather.
|
||||
*/
|
||||
private fun createWeather(
|
||||
placeName: String,
|
||||
countryCode: String,
|
||||
windInfo: Pair<Double, Int>,
|
||||
conditions: Array<Pair<String, String>>,
|
||||
humidity: Int,
|
||||
tempInfo: Triple<Int, Int, Int>
|
||||
) = Weather(
|
||||
placeName = placeName,
|
||||
countryCode = countryCode,
|
||||
conditions = conditions,
|
||||
humidity = humidity,
|
||||
windSpeed = windInfo.first,
|
||||
windDegrees = windInfo.second,
|
||||
temp = tempInfo.first,
|
||||
minTemp = tempInfo.second,
|
||||
maxTemp = tempInfo.third
|
||||
)
|
||||
|
||||
private fun extractTempInfo(rootObj: CPointer<cJSON>?): Triple<Int, Int, Int> {
|
||||
val mainObj = jsonObjectItem(rootObj, "main")
|
||||
val temp = jsonObjectItem(mainObj, "temp").intValue()
|
||||
val minTemp = jsonObjectItem(mainObj, "temp_min").intValue()
|
||||
val maxTemp = jsonObjectItem(mainObj, "temp_max").intValue()
|
||||
|
||||
return Triple(temp, minTemp, maxTemp)
|
||||
}
|
||||
|
||||
private fun extractHumidity(rootObj: CPointer<cJSON>?): Int {
|
||||
val mainObj = jsonObjectItem(rootObj, "main")
|
||||
|
||||
return jsonObjectItem(mainObj, "humidity").intValue()
|
||||
}
|
||||
|
||||
private fun extractConditions(rootObj: CPointer<cJSON>?): Array<Pair<String, String>> {
|
||||
val tmp = mutableListOf<Pair<String, String>>()
|
||||
val weatherObj = jsonObjectItem(rootObj, "weather")
|
||||
|
||||
for (pos in 0..(jsonArraySize(weatherObj) - 1)) {
|
||||
val item = jsonArrayItem(weatherObj, pos)
|
||||
val name = jsonObjectItem(item, "main").stringValue()
|
||||
val desc = jsonObjectItem(item, "description").stringValue()
|
||||
|
||||
tmp += (name to desc)
|
||||
}
|
||||
return tmp.toTypedArray()
|
||||
}
|
||||
|
||||
private fun extractWindInfo(rootObj: CPointer<cJSON>?): Pair<Double, Int> {
|
||||
val windObj = jsonObjectItem(rootObj, "wind")
|
||||
val windSpeed = jsonObjectItem(windObj, "speed").doubleValue()
|
||||
val windDegrees = jsonObjectItem(windObj, "deg").intValue()
|
||||
|
||||
return (windSpeed to windDegrees)
|
||||
}
|
||||
|
||||
private fun extractCountryCode(rootObj: CPointer<cJSON>?): String {
|
||||
val sys = jsonObjectItem(rootObj, "sys")
|
||||
|
||||
return jsonObjectItem(sys, "country").stringValue()
|
||||
}
|
||||
|
||||
internal fun weatherToJsonString(weather: Weather) : String {
|
||||
val rootObj = createJsonObject()
|
||||
addStringToObject(rootObj, "placeName", weather.placeName)
|
||||
addStringToObject(rootObj, "countryCode", weather.countryCode)
|
||||
addNumberToObject(rootObj, "humidity", weather.humidity.toDouble())
|
||||
addTempInfoArray(rootObj, temp = weather.temp, minTemp = weather.minTemp, maxTemp = weather.maxTemp)
|
||||
addConditionsArray(rootObj, weather.conditions)
|
||||
val result = jsonString(rootObj)?.toKString() ?: ""
|
||||
deleteObject(rootObj)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun addTempInfoArray(rootObj: CPointer<cJSON>?, temp: Int, minTemp: Int, maxTemp: Int) {
|
||||
val tmpObj = createJsonObject()
|
||||
|
||||
addNumberToObject(tmpObj, "temp", temp.toDouble())
|
||||
addNumberToObject(tmpObj, "minTemp", minTemp.toDouble())
|
||||
addNumberToObject(tmpObj, "maxTemp", maxTemp.toDouble())
|
||||
addItemToObject(rootObj, "tempInfo", tmpObj)
|
||||
}
|
||||
|
||||
private fun addConditionsArray(rootObj: CPointer<cJSON>?, conditions: Array<Pair<String, String>>) {
|
||||
val tmpArr = addArrayToObject(rootObj, "conditions")
|
||||
|
||||
conditions.forEach { (name, desc) ->
|
||||
val tmpObj = createJsonObject()
|
||||
addStringToObject(tmpObj, "name", name)
|
||||
addStringToObject(tmpObj, "desc", desc)
|
||||
addItemToArray(tmpArr, tmpObj)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkForError() {
|
||||
val errorMsg = getErrorPointer()?.toKString() ?: ""
|
||||
|
||||
if (errorMsg.isNotEmpty()) {
|
||||
println("JSON error before: $errorMsg\n")
|
||||
exitProcess(-1)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CPointer<cJSON>?.intValue() = this?.pointed?.valueint ?: 0
|
||||
|
||||
private fun CPointer<cJSON>?.doubleValue() = this?.pointed?.valuedouble ?: 0.0
|
||||
|
||||
private fun CPointer<cJSON>?.stringValue() = jsonStringValue(this)?.toKString() ?: ""
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.example.weather_func
|
||||
|
||||
import platform.posix.*
|
||||
import kotlinx.cinterop.allocArray
|
||||
import kotlinx.cinterop.ByteVar
|
||||
import kotlinx.cinterop.memScoped
|
||||
import kotlinx.cinterop.toKString
|
||||
import kotlinx.cinterop.refTo
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
private val API_KEY by lazy { fetchApiKey() }
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val input = readLine()
|
||||
val location = fetchLocationArg(input)
|
||||
val jsonFile = fetchJsonFileArg(input)
|
||||
|
||||
if (location.isNotEmpty()) {
|
||||
printFromWeatherService(location)
|
||||
} else if (jsonFile.isNotEmpty()) {
|
||||
checkFile(jsonFile)
|
||||
printJsonFile(jsonFile)
|
||||
} else {
|
||||
handleEmptyInput()
|
||||
}
|
||||
println("Exiting...")
|
||||
}
|
||||
|
||||
private fun handleEmptyInput() {
|
||||
println(
|
||||
"""
|
||||
| Weather - A OpenFaaS Serverless Function that outputs weather information.
|
||||
| Usage examples (pass one of the following as input to the function):
|
||||
| * Location (uses the Open Weather Map service), eg:
|
||||
| -l="christchurch,nz"
|
||||
| * JSON File, eg: -f="weather.json"
|
||||
""".trimMargin()
|
||||
)
|
||||
exitProcess(0)
|
||||
}
|
||||
|
||||
private fun checkFile(file: String) {
|
||||
val error = -1
|
||||
if (access(file, F_OK) == error) {
|
||||
println("File $file doesn't exist!")
|
||||
exitProcess(error)
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchJson(jsonFile: String): String {
|
||||
var result = ""
|
||||
// Open the file using the fopen function and store the file handle.
|
||||
val file = fopen(jsonFile, "r")
|
||||
fseek(file, 0, SEEK_END)
|
||||
val fileSize = ftell(file)
|
||||
fseek(file, 0, SEEK_SET)
|
||||
|
||||
memScoped {
|
||||
val buffer = allocArray<ByteVar>(fileSize)
|
||||
// Read the entire file and store the contents into the buffer.
|
||||
fread(buffer, fileSize, 1, file)
|
||||
result = buffer.toKString()
|
||||
}
|
||||
// Close the file.
|
||||
fclose(file)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun printJsonFile(jsonFile: String) {
|
||||
println("Printing from JSON file ($jsonFile)...")
|
||||
val weather = createWeatherFromJson(fetchJson(jsonFile))
|
||||
println("Weather Object:\n$weather")
|
||||
println("Weather JSON:\n${weatherToJsonString(weather)}")
|
||||
}
|
||||
|
||||
private fun printFromWeatherService(location: String) {
|
||||
println("Fetching weather information (for $location)...")
|
||||
val curl = CUrl(createUrl(location)).apply {
|
||||
header += { if(it.startsWith("HTTP")) println("Response Status: $it") }
|
||||
body += { data ->
|
||||
val weather = createWeatherFromJson(data)
|
||||
println("Weather information:\n${weatherToJsonString(weather)}")
|
||||
}
|
||||
}
|
||||
curl.fetch()
|
||||
curl.close()
|
||||
}
|
||||
|
||||
private fun fetchJsonFileArg(input: String?): String {
|
||||
val flag = "-f"
|
||||
return if (input != null && input.startsWith("$flag=")) input.replace("$flag=", "").replace("\"", "")
|
||||
else ""
|
||||
}
|
||||
|
||||
private fun fetchLocationArg(input: String?): String {
|
||||
val flag = "-l"
|
||||
return if (input != null && input.startsWith("$flag=")) input.replace("$flag=", "").replace("\"", "")
|
||||
else ""
|
||||
}
|
||||
|
||||
private fun createUrl(location: String): String {
|
||||
val baseUrl = "http://api.openweathermap.org/data/2.5/weather"
|
||||
return "$baseUrl?q=$location&units=metric&appid=$API_KEY"
|
||||
}
|
||||
|
||||
private fun fetchApiKey(): String {
|
||||
var result = ""
|
||||
val maxChars = 50
|
||||
// utfCharSize in bytes.
|
||||
val utfCharSize = 4
|
||||
// Open the file using the fopen function and store the file handle.
|
||||
val file = fopen("openweathermap_key.txt", "r")
|
||||
val buffer = ByteArray(utfCharSize * maxChars)
|
||||
if (file != null) result = fgets(buffer.refTo(0), buffer.size, file)?.toKString()?.trim() ?: ""
|
||||
// Close the file.
|
||||
fclose(file)
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user