generated from me/template-mit
qwen3.6:35b's first attempt, does not compile (yet).
This commit is contained in:
1 parent
eeda4a18c5
commit
337403721b
17 files changed
+1486
-40
No files matched your search
@@ -0,0 +1,97 @@
|
||||
package com.hyperling.weather
|
||||
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.call.body
|
||||
import io.ktor.client.engine.HttpClientEngine
|
||||
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
|
||||
import io.ktor.http.encodeURLParameter
|
||||
import io.ktor.serialization.kotlinx.json.json
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
/**
|
||||
* Repository for fetching weather data from OpenMeteo API.
|
||||
* OpenMeteo is free and does not require an API key for basic usage.
|
||||
*/
|
||||
object WeatherRepository {
|
||||
|
||||
private const val OPEN_METEO_URL = "https://api.open-meteo.com/v1/forecast"
|
||||
|
||||
private val json = Json {
|
||||
ignoreUnknownKeys = true
|
||||
prettyPrint = false
|
||||
}
|
||||
|
||||
private lateinit var httpClient: HttpClient
|
||||
|
||||
fun init(engine: HttpClientEngine) {
|
||||
httpClient = HttpClient(engine) {
|
||||
install(ContentNegotiation) {
|
||||
json(json)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch weather data for a location by coordinates.
|
||||
* Returns the parsed OpenMeteo daily forecast response.
|
||||
*/
|
||||
suspend fun fetchWeather(latitude: Double, longitude: Double): OpenMeteoResponse {
|
||||
return httpClient.get(OPEN_METEO_URL) {
|
||||
url {
|
||||
parameters.append("latitude", latitude.toString())
|
||||
parameters.append("longitude", longitude.toString())
|
||||
parameters.append("daily", "temperature_2m_max,temperature_2m_min")
|
||||
parameters.append("forecast_days", "7")
|
||||
parameters.append("timezone", "auto")
|
||||
}
|
||||
}.body()
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the raw API response into our domain models.
|
||||
*/
|
||||
fun parseDailyWeather(response: OpenMeteoResponse): List<DailyWeather> {
|
||||
val dates = response.daily.time ?: emptyList()
|
||||
val highs = response.daily.temperature_2m_max ?: emptyList()
|
||||
val lows = response.daily.temperature_2m_min ?: emptyList()
|
||||
|
||||
return dates.mapIndexed { index, date ->
|
||||
DailyWeather(
|
||||
date = date,
|
||||
tempMaxCelsius = if (index < highs.size) highs[index] else null,
|
||||
tempMinCelsius = if (index < lows.size) lows[index] else null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a location entry to weather data.
|
||||
*/
|
||||
suspend fun getWeatherForLocation(location: LocationEntry): Result<LocationWeather> {
|
||||
return try {
|
||||
val response = if (location.zipCode.isNotBlank()) {
|
||||
// OpenMeteo doesn't support zip code lookup directly,
|
||||
// but we can use the lat/long which should be populated
|
||||
fetchWeather(location.latitude, location.longitude)
|
||||
} else {
|
||||
fetchWeather(location.latitude, location.longitude)
|
||||
}
|
||||
|
||||
val daily = parseDailyWeather(response)
|
||||
|
||||
Result.success(
|
||||
LocationWeather(
|
||||
locationId = location.id,
|
||||
zipCode = location.zipCode,
|
||||
nickname = location.nickname,
|
||||
latitude = location.latitude,
|
||||
longitude = location.longitude,
|
||||
dailyWeather = daily,
|
||||
lastUpdatedMillis = System.currentTimeMillis(),
|
||||
)
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Result.failure(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user